mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-17 21:06:04 +00:00
added chainable functions in em()
This commit is contained in:
@@ -186,7 +186,7 @@ describe("Mutator simple", async () => {
|
|||||||
const newCount = (await em.repo(items).count()).count;
|
const newCount = (await em.repo(items).count()).count;
|
||||||
expect(newCount).toBe(oldCount + inserts.length);
|
expect(newCount).toBe(oldCount + inserts.length);
|
||||||
|
|
||||||
const { data: data2 } = await em.repo(items).findMany();
|
const { data: data2 } = await em.repo(items).findMany({ offset: oldCount });
|
||||||
expect(data2).toEqual(data);
|
expect(data2).toEqual(data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
BooleanField,
|
BooleanField,
|
||||||
DateField,
|
DateField,
|
||||||
Entity,
|
Entity,
|
||||||
|
EntityIndex,
|
||||||
EntityManager,
|
EntityManager,
|
||||||
EnumField,
|
EnumField,
|
||||||
JsonField,
|
JsonField,
|
||||||
@@ -278,23 +279,32 @@ describe("prototype", () => {
|
|||||||
test("schema", async () => {
|
test("schema", async () => {
|
||||||
const _em = em(
|
const _em = em(
|
||||||
{
|
{
|
||||||
posts: entity("posts", { name: text() }),
|
posts: entity("posts", { name: text(), slug: text().required() }),
|
||||||
comments: entity("comments", { some: text() })
|
comments: entity("comments", { some: text() }),
|
||||||
|
users: entity("users", { email: text() })
|
||||||
},
|
},
|
||||||
(relation, { posts, comments }) => {
|
({ relation, index }, { posts, comments, users }) => {
|
||||||
relation(posts).manyToOne(comments);
|
relation(posts).manyToOne(comments).manyToOne(users);
|
||||||
|
index(posts).on(["name"]).on(["slug"], true);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
type LocalDb = (typeof _em)["DB"];
|
type LocalDb = (typeof _em)["DB"];
|
||||||
|
|
||||||
const es = [
|
const es = [
|
||||||
new Entity("posts", [new TextField("name")]),
|
new Entity("posts", [new TextField("name"), new TextField("slug", { required: true })]),
|
||||||
new Entity("comments", [new TextField("some")])
|
new Entity("comments", [new TextField("some")]),
|
||||||
|
new Entity("users", [new TextField("email")])
|
||||||
];
|
];
|
||||||
const _em2 = new EntityManager(es, new DummyConnection(), [
|
const _em2 = new EntityManager(
|
||||||
new ManyToOneRelation(es[0], es[1])
|
es,
|
||||||
]);
|
new DummyConnection(),
|
||||||
|
[new ManyToOneRelation(es[0], es[1]), new ManyToOneRelation(es[0], es[2])],
|
||||||
|
[
|
||||||
|
new EntityIndex(es[0], [es[0].field("name")!]),
|
||||||
|
new EntityIndex(es[0], [es[0].field("slug")!], true)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
expect(_em2.toJSON()).toEqual(_em.toJSON());
|
expect(_em2.toJSON()).toEqual(_em.toJSON());
|
||||||
|
|||||||
@@ -220,7 +220,8 @@ export class Entity<
|
|||||||
readOnly: !field.isFillable("update") ? true : undefined,
|
readOnly: !field.isFillable("update") ? true : undefined,
|
||||||
writeOnly: !field.isFillable("create") ? true : undefined,
|
writeOnly: !field.isFillable("create") ? true : undefined,
|
||||||
...field.toJsonSchema()
|
...field.toJsonSchema()
|
||||||
}))
|
})),
|
||||||
|
{ additionalProperties: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
return clean ? JSON.parse(JSON.stringify(schema)) : schema;
|
return clean ? JSON.parse(JSON.stringify(schema)) : schema;
|
||||||
|
|||||||
@@ -104,6 +104,12 @@ export class TextField<Required extends true | false = false> extends Field<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.config.pattern && value && !new RegExp(this.config.pattern).test(value)) {
|
||||||
|
throw new TransformPersistFailedException(
|
||||||
|
`Field "${this.name}" must match the pattern ${this.config.pattern}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
type DateFieldConfig,
|
type DateFieldConfig,
|
||||||
Entity,
|
Entity,
|
||||||
type EntityConfig,
|
type EntityConfig,
|
||||||
|
EntityIndex,
|
||||||
type EntityRelation,
|
type EntityRelation,
|
||||||
EnumField,
|
EnumField,
|
||||||
type EnumFieldConfig,
|
type EnumFieldConfig,
|
||||||
@@ -244,47 +245,83 @@ export function relation<Local extends Entity>(local: Local) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function index<E extends Entity>(entity: E) {
|
||||||
|
return {
|
||||||
|
on: (fields: (keyof InsertSchema<E>)[], unique?: boolean) => {
|
||||||
|
const _fields = fields.map((f) => {
|
||||||
|
const field = entity.field(f as any);
|
||||||
|
if (!field) {
|
||||||
|
throw new Error(`Field "${String(f)}" not found on entity "${entity.name}"`);
|
||||||
|
}
|
||||||
|
return field;
|
||||||
|
});
|
||||||
|
return new EntityIndex(entity, _fields, unique);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
class EntityManagerPrototype<Entities extends Record<string, Entity>> extends EntityManager<
|
class EntityManagerPrototype<Entities extends Record<string, Entity>> extends EntityManager<
|
||||||
Schema<Entities>
|
Schema<Entities>
|
||||||
> {
|
> {
|
||||||
constructor(
|
constructor(
|
||||||
public __entities: Entities,
|
public __entities: Entities,
|
||||||
relations: EntityRelation[]
|
relations: EntityRelation[] = [],
|
||||||
|
indices: EntityIndex[] = []
|
||||||
) {
|
) {
|
||||||
super(Object.values(__entities), new DummyConnection(), relations);
|
super(Object.values(__entities), new DummyConnection(), relations, indices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Chained<Fn extends (...args: any[]) => any, Rt = ReturnType<Fn>> = <E extends Entity>(
|
||||||
|
e: E
|
||||||
|
) => {
|
||||||
|
[K in keyof Rt]: Rt[K] extends (...args: any[]) => any
|
||||||
|
? (...args: Parameters<Rt[K]>) => Rt
|
||||||
|
: never;
|
||||||
|
};
|
||||||
|
|
||||||
export function em<Entities extends Record<string, Entity>>(
|
export function em<Entities extends Record<string, Entity>>(
|
||||||
entities: Entities,
|
entities: Entities,
|
||||||
schema?: (rel: typeof relation, entities: Entities) => void
|
schema?: (
|
||||||
|
fns: { relation: Chained<typeof relation>; index: Chained<typeof index> },
|
||||||
|
entities: Entities
|
||||||
|
) => void
|
||||||
) {
|
) {
|
||||||
const relations: EntityRelation[] = [];
|
const relations: EntityRelation[] = [];
|
||||||
const relationProxy = (local: Entity) => {
|
const indices: EntityIndex[] = [];
|
||||||
return new Proxy(relation(local), {
|
|
||||||
|
const relationProxy = (e: Entity) => {
|
||||||
|
return new Proxy(relation(e), {
|
||||||
get(target, prop) {
|
get(target, prop) {
|
||||||
if (typeof target[prop] === "function") {
|
|
||||||
return (...args: any[]) => {
|
return (...args: any[]) => {
|
||||||
const result = target[prop](...args);
|
relations.push(target[prop](...args));
|
||||||
relations.push(result);
|
return relationProxy(e);
|
||||||
return result;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return target[prop];
|
}) as any;
|
||||||
|
};
|
||||||
|
|
||||||
|
const indexProxy = (e: Entity) => {
|
||||||
|
return new Proxy(index(e), {
|
||||||
|
get(target, prop) {
|
||||||
|
return (...args: any[]) => {
|
||||||
|
indices.push(target[prop](...args));
|
||||||
|
return indexProxy(e);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
});
|
}) as any;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (schema) {
|
if (schema) {
|
||||||
schema(relationProxy, entities);
|
schema({ relation: relationProxy, index: indexProxy }, entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
const e = new EntityManagerPrototype(entities, relations);
|
const e = new EntityManagerPrototype(entities, relations, indices);
|
||||||
return {
|
return {
|
||||||
DB: e.__entities as unknown as Schemas<Entities>,
|
DB: e.__entities as unknown as Schemas<Entities>,
|
||||||
entities: e.__entities,
|
entities: e.__entities,
|
||||||
relations,
|
relations,
|
||||||
indices: [],
|
indices,
|
||||||
toJSON: () =>
|
toJSON: () =>
|
||||||
e.toJSON() as unknown as Pick<ModuleConfigs["data"], "entities" | "relations" | "indices">
|
e.toJSON() as unknown as Pick<ModuleConfigs["data"], "entities" | "relations" | "indices">
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user