diff --git a/app/__test__/app/repro.spec.ts b/app/__test__/app/repro.spec.ts index 0d025b9..c76d55f 100644 --- a/app/__test__/app/repro.spec.ts +++ b/app/__test__/app/repro.spec.ts @@ -70,4 +70,34 @@ describe("repros", async () => { expect(app.em.entities.map((e) => e.name)).toEqual(["media", "test"]); }); + + test.only("verify inversedBy", async () => { + const schema = proto.em( + { + products: proto.entity("products", { + title: proto.text() + }), + product_likes: proto.entity("product_likes", { + created_at: proto.date() + }), + users: proto.entity("users", {}) + }, + (fns, schema) => { + fns.relation(schema.product_likes).manyToOne(schema.products, { inversedBy: "likes" }); + fns.relation(schema.product_likes).manyToOne(schema.users); + } + ); + const app = createApp({ initialConfig: { data: schema.toJSON() } }); + await app.build(); + + const info = (await (await app.server.request("/api/data/info/products")).json()) as any; + + expect(info.fields).toEqual(["id", "title"]); + expect(info.relations.listable).toEqual([ + { + entity: "product_likes", + ref: "likes" + } + ]); + }); }); diff --git a/app/src/data/api/DataApi.ts b/app/src/data/api/DataApi.ts index 2861403..abb710b 100644 --- a/app/src/data/api/DataApi.ts +++ b/app/src/data/api/DataApi.ts @@ -1,10 +1,10 @@ import type { DB } from "core"; -import type { EntityData, RepoQuery, RepoQueryIn, RepositoryResponse } from "data"; +import type { EntityData, RepoQueryIn, RepositoryResponse } from "data"; import { type BaseModuleApiOptions, ModuleApi, type PrimaryFieldType } from "modules"; export type DataApiOptions = BaseModuleApiOptions & { queryLengthLimit: number; - defaultQuery: Partial; + defaultQuery: Partial; }; export class DataApi extends ModuleApi { @@ -78,7 +78,7 @@ export class DataApi extends ModuleApi { return this.delete>(["entity", entity as any, id]); } - count(entity: E, where: RepoQuery["where"] = {}) { + count(entity: E, where: RepoQueryIn["where"] = {}) { return this.post>( ["entity", entity as any, "fn", "count"], where diff --git a/app/src/data/api/DataController.ts b/app/src/data/api/DataController.ts index bd78f68..1a44912 100644 --- a/app/src/data/api/DataController.ts +++ b/app/src/data/api/DataController.ts @@ -165,6 +165,34 @@ export class DataController extends Controller { // entity endpoints hono.route("/entity", this.getEntityRoutes()); + /** + * Info endpoints + */ + hono.get("/info/:entity", async (c) => { + const { entity } = c.req.param(); + if (!this.entityExists(entity)) { + return c.notFound(); + } + const _entity = this.em.entity(entity); + const fields = _entity.fields.map((f) => f.name); + const $rels = (r: any) => + r.map((r: any) => ({ + entity: r.other(_entity).entity.name, + ref: r.other(_entity).reference + })); + + return c.json({ + name: _entity.name, + fields, + relations: { + all: $rels(this.em.relations.relationsOf(_entity)), + listable: $rels(this.em.relations.listableRelationsOf(_entity)), + source: $rels(this.em.relations.sourceRelationsOf(_entity)), + target: $rels(this.em.relations.targetRelationsOf(_entity)) + } + }); + }); + return hono.all("*", (c) => c.notFound()); } diff --git a/app/src/ui/client/index.ts b/app/src/ui/client/index.ts index 168d127..0d9711c 100644 --- a/app/src/ui/client/index.ts +++ b/app/src/ui/client/index.ts @@ -10,3 +10,4 @@ export * from "./api/use-api"; export * from "./api/use-entity"; export { useAuth } from "./schema/auth/use-auth"; export { Api, type TApiUser, type AuthState, type ApiOptions } from "../../Api"; +export type { RepoQueryIn } from "data";