Feature Request: Helper Type to Extract Entity Types from Schema object
bestickley opened this issue · 9 comments
Given the following schema I'd like to have a helper types that's exported from electrodb
that allows me to extract types so that I can use them in my frontend:
import { Putable, Getable, Schema, Updateable } from "electrodb";
const userSchema: Schema<string, string, string> = {
model: {
entity: "user",
version: "1",
service: "main",
},
attributes: {
userId: {
type: "string",
readOnly: true,
required: true,
},
email: {
type: "string",
required: true,
},
firstName: {
type: "string",
required: true,
},
lastName: {
type: "string",
required: true,
},
createdDate: {
type: "string",
default: () => new Date().toISOString(),
readOnly: true,
},
updatedDate: {
type: "string",
readOnly: true,
set: () => new Date().toISOString(),
watch: "*",
},
},
indexes: {
primary: {
pk: {
field: "pk",
composite: [],
},
sk: {
field: "sk",
composite: [],
},
},
},
};
export type User = Getable<typeof userSchema>;
export type CreateUser = Putable<typeof userSchema>;
export type UpdateUser = Updateable<typeof userSchema>;
Requested types: Getable
, Putable
, Updateable
.
Inspiration from kysely:
import type { ColumnType, Insertable, Selectable, Updateable } from "kysely";
import type { ManagementRoleName } from "./management-role.js";
import type { ProductRoleName } from "./product-role.js";
import type { NullableColumn } from "./helper-types.js";
export interface UserTable {
accessExpirationDate: string;
adOid: string; // PK UUID
altEmail: NullableColumn<string>;
createdDate: ColumnType<string, never, never>;
department: string;
edipi: string;
email: string;
firstName: string;
iaCompletionDate: string;
jobTitle: string;
lastName: string;
middleInitial: NullableColumn<string>;
organization: string;
phone: string;
updatedDate: ColumnType<string, never, never>;
}
export type User = Selectable<UserTable>;
export type CreateUser = Insertable<UserTable>;
export type UpdateUser = Updateable<UserTable>;
Earlier issue: #165
There are already some helper types https://electrodb.dev/en/reference/typscript/#createentityitem-type and https://electrodb.dev/en/reference/typscript/#updateentityitem-type
Hi @bestickley, 2.4.0
introduces createSchema
which will allow you to create (and validate) a schema outside of Entity creation
Here is a playground!
This will now actually be found in 2.4.1
because I made a foolish mistake. Let me know if you have any issues 👍
Awesome, thanks @tywalch.
Is it possible to have something like below? My key question is: is it possible to get the interface of a create, update, etc entity from the schema
? It seems like you have to have the entity defined first.
/* Model queries, see results, share with friends */
import { Entity, createSchema, CreateEntityItem } from "electrodb";
const table = "your_table_name";
const schema = createSchema({
model: {
entity: "task",
version: "1",
service: "taskapp"
},
attributes: {
team: {
type: "string",
required: true
},
task: {
type: "string",
required: true
},
project: {
type: "string",
required: true
},
user: {
type: "string",
required: true
},
title: {
type: "string",
required: true,
},
description: {
type: "string"
},
status: {
// use an array to type an enum
type: ["open", "in-progress", "on-hold", "closed"] as const,
default: "open"
},
},
indexes: {
projects: {
pk: {
field: "pk",
composite: ["team"]
},
sk: {
field: "sk",
// create composite keys for partial sort key queries
composite: ["project", "task"]
}
}
}
});
// this errors out because it wants an entity. how can I create a `CreateEntityType` from schema?
type CreateEntityType = CreateEntityItem<typeof schema>;
const task = new Entity(
schema,
{ table }
);
task.query.projects({team: 'abc'}).go();
The docs say:
The createSchema function allows you to define a schema independent of instantiating a new entity. This can be useful if the model definition needs to be portable or dynamic. This function will also validate your schema, and will throw if it is not a valid format.
I would think a portable model definition is only useful if you can get the interface or type of the entity from it. When I say entity, I don't mean electrodb's entity, but an entity like:
inteface User {
id: string;
firstName: string;
lastName: string;
}
I cannot create the Entity
in my common package where I define my types because I don't know the table name there (only at run time). If I try I end up getting: https://electrodb.dev/en/reference/errors/#missing-table
You can also add table
to your execution options in .go()
const results = await task.query
.projects({team: 'abc'})
.go({table: 'your_table_name'});
I didn't know entity's have .setTableName
method! This is a working example of what I was looking for. Thank you!