@metaobjectsdev/runtime-ts 0.5.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/LICENSE +189 -0
  2. package/README.md +102 -0
  3. package/dist/constants.d.ts +5 -0
  4. package/dist/constants.d.ts.map +1 -0
  5. package/dist/constants.js +6 -0
  6. package/dist/constants.js.map +1 -0
  7. package/dist/drivers/drizzle-driver.d.ts +25 -0
  8. package/dist/drivers/drizzle-driver.d.ts.map +1 -0
  9. package/dist/drivers/drizzle-driver.js +405 -0
  10. package/dist/drivers/drizzle-driver.js.map +1 -0
  11. package/dist/drivers/in-memory-driver.d.ts +11 -0
  12. package/dist/drivers/in-memory-driver.d.ts.map +1 -0
  13. package/dist/drivers/in-memory-driver.js +232 -0
  14. package/dist/drivers/in-memory-driver.js.map +1 -0
  15. package/dist/drivers/index.d.ts +4 -0
  16. package/dist/drivers/index.d.ts.map +1 -0
  17. package/dist/drivers/index.js +4 -0
  18. package/dist/drivers/index.js.map +1 -0
  19. package/dist/drivers/kysely-driver.d.ts +12 -0
  20. package/dist/drivers/kysely-driver.d.ts.map +1 -0
  21. package/dist/drivers/kysely-driver.js +203 -0
  22. package/dist/drivers/kysely-driver.js.map +1 -0
  23. package/dist/drizzle-fastify/filter-allowlist.d.ts +19 -0
  24. package/dist/drizzle-fastify/filter-allowlist.d.ts.map +1 -0
  25. package/dist/drizzle-fastify/filter-allowlist.js +10 -0
  26. package/dist/drizzle-fastify/filter-allowlist.js.map +1 -0
  27. package/dist/drizzle-fastify/filter-parser.d.ts +28 -0
  28. package/dist/drizzle-fastify/filter-parser.d.ts.map +1 -0
  29. package/dist/drizzle-fastify/filter-parser.js +185 -0
  30. package/dist/drizzle-fastify/filter-parser.js.map +1 -0
  31. package/dist/drizzle-fastify/index.d.ts +48 -0
  32. package/dist/drizzle-fastify/index.d.ts.map +1 -0
  33. package/dist/drizzle-fastify/index.js +181 -0
  34. package/dist/drizzle-fastify/index.js.map +1 -0
  35. package/dist/drizzle-fastify/mount-read-only.d.ts +17 -0
  36. package/dist/drizzle-fastify/mount-read-only.d.ts.map +1 -0
  37. package/dist/drizzle-fastify/mount-read-only.js +159 -0
  38. package/dist/drizzle-fastify/mount-read-only.js.map +1 -0
  39. package/dist/drizzle-fastify/util.d.ts +5 -0
  40. package/dist/drizzle-fastify/util.d.ts.map +1 -0
  41. package/dist/drizzle-fastify/util.js +12 -0
  42. package/dist/drizzle-fastify/util.js.map +1 -0
  43. package/dist/errors.d.ts +68 -0
  44. package/dist/errors.d.ts.map +1 -0
  45. package/dist/errors.js +86 -0
  46. package/dist/errors.js.map +1 -0
  47. package/dist/fastify/index.d.ts +65 -0
  48. package/dist/fastify/index.d.ts.map +1 -0
  49. package/dist/fastify/index.js +118 -0
  50. package/dist/fastify/index.js.map +1 -0
  51. package/dist/identity-strategy.d.ts +10 -0
  52. package/dist/identity-strategy.d.ts.map +1 -0
  53. package/dist/identity-strategy.js +67 -0
  54. package/dist/identity-strategy.js.map +1 -0
  55. package/dist/index.d.ts +9 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +3 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/n2m-resolver.d.ts +27 -0
  60. package/dist/n2m-resolver.d.ts.map +1 -0
  61. package/dist/n2m-resolver.js +103 -0
  62. package/dist/n2m-resolver.js.map +1 -0
  63. package/dist/object-manager.d.ts +51 -0
  64. package/dist/object-manager.d.ts.map +1 -0
  65. package/dist/object-manager.js +355 -0
  66. package/dist/object-manager.js.map +1 -0
  67. package/dist/persistence-driver.d.ts +88 -0
  68. package/dist/persistence-driver.d.ts.map +1 -0
  69. package/dist/persistence-driver.js +5 -0
  70. package/dist/persistence-driver.js.map +1 -0
  71. package/dist/query-builder.d.ts +35 -0
  72. package/dist/query-builder.d.ts.map +1 -0
  73. package/dist/query-builder.js +178 -0
  74. package/dist/query-builder.js.map +1 -0
  75. package/dist/ref-codec.d.ts +8 -0
  76. package/dist/ref-codec.d.ts.map +1 -0
  77. package/dist/ref-codec.js +42 -0
  78. package/dist/ref-codec.js.map +1 -0
  79. package/dist/relation-resolver.d.ts +27 -0
  80. package/dist/relation-resolver.d.ts.map +1 -0
  81. package/dist/relation-resolver.js +136 -0
  82. package/dist/relation-resolver.js.map +1 -0
  83. package/dist/type-coercer.d.ts +5 -0
  84. package/dist/type-coercer.d.ts.map +1 -0
  85. package/dist/type-coercer.js +43 -0
  86. package/dist/type-coercer.js.map +1 -0
  87. package/dist/validator-runner.d.ts +14 -0
  88. package/dist/validator-runner.d.ts.map +1 -0
  89. package/dist/validator-runner.js +155 -0
  90. package/dist/validator-runner.js.map +1 -0
  91. package/dist/view.d.ts +19 -0
  92. package/dist/view.d.ts.map +1 -0
  93. package/dist/view.js +60 -0
  94. package/dist/view.js.map +1 -0
  95. package/package.json +87 -0
  96. package/src/constants.ts +7 -0
  97. package/src/drivers/drizzle-driver.ts +474 -0
  98. package/src/drivers/in-memory-driver.ts +256 -0
  99. package/src/drivers/index.ts +3 -0
  100. package/src/drivers/kysely-driver.ts +240 -0
  101. package/src/drizzle-fastify/filter-allowlist.ts +31 -0
  102. package/src/drizzle-fastify/filter-parser.ts +229 -0
  103. package/src/drizzle-fastify/index.ts +225 -0
  104. package/src/drizzle-fastify/mount-read-only.ts +187 -0
  105. package/src/drizzle-fastify/util.ts +10 -0
  106. package/src/errors.ts +114 -0
  107. package/src/fastify/index.ts +181 -0
  108. package/src/identity-strategy.ts +92 -0
  109. package/src/index.ts +24 -0
  110. package/src/n2m-resolver.ts +152 -0
  111. package/src/object-manager.ts +444 -0
  112. package/src/persistence-driver.ts +92 -0
  113. package/src/query-builder.ts +224 -0
  114. package/src/ref-codec.ts +64 -0
  115. package/src/relation-resolver.ts +171 -0
  116. package/src/type-coercer.ts +39 -0
  117. package/src/validator-runner.ts +168 -0
  118. package/src/view.ts +82 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fastify/index.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAMrD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEvE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,eAAe,CAAC;IACzB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,YAAY,EAAE,UAAU,CAAC;IACzB,yEAAyE;IACzE,YAAY,EAAE,UAAU,CAAC;IACzB;;;OAGG;IACH,EAAE,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IACjC;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC7B;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;CAChC;AAID;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAO7D;AAOD,KAAK,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;AAW3D,wBAAgB,cAAc,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAQ5D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAM3D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAY9D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CA4B9D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAM9D;AAMD;;;GAGG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAGpD"}
@@ -0,0 +1,118 @@
1
+ // Fastify adapter for ObjectManager-driven CRUD.
2
+ //
3
+ // Generated route files call `mountCrudRoutes(...)` from here so all the
4
+ // boilerplate (validation, 404 mapping, id parsing, pagination) lives in
5
+ // one tested place rather than being duplicated per entity.
6
+ //
7
+ // Fastify is an OPTIONAL peer dependency. Consumers that don't expose REST
8
+ // pay no runtime cost — this subpath is only loaded when imported.
9
+ //
10
+ // Type-only Fastify imports keep the optional-peer story clean: the .d.ts
11
+ // reference is needed for the public API, but at runtime there's no
12
+ // `require("fastify")`.
13
+ const ALL_VERBS = ["list", "get", "create", "update", "delete"];
14
+ /**
15
+ * Mount the 5 standard REST endpoints for an entity:
16
+ *
17
+ * GET {path} → list, with ?limit & ?offset query params
18
+ * GET {path}/:id → findById
19
+ * POST {path} → create (validated via insertSchema)
20
+ * PATCH {path}/:id → partial update (validated via updateSchema)
21
+ * DELETE {path}/:id → delete
22
+ */
23
+ export function mountCrudRoutes(opts) {
24
+ const verbs = new Set(opts.expose ?? ALL_VERBS);
25
+ if (verbs.has("list"))
26
+ mountListRoute(opts);
27
+ if (verbs.has("get"))
28
+ mountGetRoute(opts);
29
+ if (verbs.has("create"))
30
+ mountCreateRoute(opts);
31
+ if (verbs.has("update"))
32
+ mountUpdateRoute(opts);
33
+ if (verbs.has("delete"))
34
+ mountDeleteRoute(opts);
35
+ }
36
+ /**
37
+ * Build the route options Fastify wants. Just the consumer's routeOptions
38
+ * (typed loosely to avoid Fastify's elaborate route-options union here).
39
+ * Returns an empty object if nothing was provided.
40
+ */
41
+ function routeOpts(opts) {
42
+ return opts.routeOptions ?? {};
43
+ }
44
+ export function mountListRoute(opts) {
45
+ opts.fastify.get(opts.path, routeOpts(opts), async (req) => {
46
+ const { limit, offset } = req.query;
47
+ const readOpts = {};
48
+ if (limit !== undefined)
49
+ readOpts.limit = Number(limit);
50
+ if (offset !== undefined)
51
+ readOpts.offset = Number(offset);
52
+ return (await opts.om()).findMany(opts.entity, undefined, readOpts);
53
+ });
54
+ }
55
+ export function mountGetRoute(opts) {
56
+ opts.fastify.get(`${opts.path}/:id`, routeOpts(opts), async (req, reply) => {
57
+ const { id } = req.params;
58
+ const row = await (await opts.om()).findById(opts.entity, parseId(id));
59
+ return row ?? reply.code(404).send({ error: "not_found" });
60
+ });
61
+ }
62
+ export function mountCreateRoute(opts) {
63
+ opts.fastify.post(opts.path, routeOpts(opts), async (req, reply) => {
64
+ const parsed = opts.insertSchema.safeParse(req.body);
65
+ if (!parsed.success) {
66
+ return reply.code(400).send({ error: "validation", issues: parsed.error.issues });
67
+ }
68
+ // Zod returns `unknown` for parsed.data; the schema is authored from the
69
+ // same metadata that drives ObjectManager, so the shape is guaranteed
70
+ // compatible — cast at the trust boundary.
71
+ const row = await (await opts.om()).create(opts.entity, parsed.data);
72
+ return reply.code(201).send(row);
73
+ });
74
+ }
75
+ export function mountUpdateRoute(opts) {
76
+ const handler = async (req, reply) => {
77
+ const { id } = req.params;
78
+ const parsed = opts.updateSchema.safeParse(req.body);
79
+ if (!parsed.success) {
80
+ return reply.code(400).send({ error: "validation", issues: parsed.error.issues });
81
+ }
82
+ // Use ifMissing: "ignore" so the helper itself owns the 404 mapping
83
+ // (consistent with mountDeleteRoute). ObjectManager's default behavior
84
+ // throws NotFoundError, which Fastify would surface as 500.
85
+ const row = await (await opts.om()).update(opts.entity, parseId(id), parsed.data, {
86
+ ifMissing: "ignore",
87
+ });
88
+ return row ?? reply.code(404).send({ error: "not_found" });
89
+ };
90
+ const path = `${opts.path}/:id`;
91
+ const ro = routeOpts(opts);
92
+ // biome-ignore lint/suspicious/noExplicitAny: handler signature is generic by design
93
+ if (opts.updateMethod === "put") {
94
+ opts.fastify.put(path, ro, handler);
95
+ }
96
+ else {
97
+ opts.fastify.patch(path, ro, handler);
98
+ }
99
+ }
100
+ export function mountDeleteRoute(opts) {
101
+ opts.fastify.delete(`${opts.path}/:id`, routeOpts(opts), async (req, reply) => {
102
+ const { id } = req.params;
103
+ const deleted = await (await opts.om()).delete(opts.entity, parseId(id));
104
+ return deleted ? reply.code(204).send() : reply.code(404).send({ error: "not_found" });
105
+ });
106
+ }
107
+ // ---------------------------------------------------------------------------
108
+ // Helpers
109
+ // ---------------------------------------------------------------------------
110
+ /**
111
+ * Coerce a `:id` path param. Numeric strings parse as Number (covers long/int
112
+ * PKs); anything else passes through as a string (UUIDs, string keys).
113
+ */
114
+ export function parseId(raw) {
115
+ const n = Number(raw);
116
+ return Number.isFinite(n) && raw.trim() !== "" ? n : raw;
117
+ }
118
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/fastify/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { MetaData } from "@metaobjectsdev/metadata";
2
+ export type IdentityResolution = {
3
+ kind: "driver-generated";
4
+ values: Record<string, unknown>;
5
+ } | {
6
+ kind: "preset";
7
+ values: Record<string, unknown>;
8
+ };
9
+ export declare function resolveIdentity(entity: MetaData, data: Record<string, unknown>): IdentityResolution;
10
+ //# sourceMappingURL=identity-strategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-strategy.d.ts","sourceRoot":"","sources":["../src/identity-strategy.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAQzD,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC;AAExD,wBAAgB,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,kBAAkB,CAyEnG"}
@@ -0,0 +1,67 @@
1
+ // Generation strategies:
2
+ // increment → driver-generated by default; caller MAY supply PK (e.g., seeding fixtures, importing legacy data).
3
+ // uuid → generated here via crypto.randomUUID() unless caller supplies one.
4
+ // assigned → caller must provide PK.
5
+ // composite → always treated as 'assigned' regardless of the @generation hint.
6
+ import { TYPE_IDENTITY, IDENTITY_SUBTYPE_PRIMARY, IDENTITY_ATTR_FIELDS, IDENTITY_ATTR_GENERATION, GENERATION_INCREMENT, GENERATION_UUID, GENERATION_ASSIGNED, } from "@metaobjectsdev/metadata";
7
+ import { MetadataError, ValidationError } from "./errors.js";
8
+ export function resolveIdentity(entity, data) {
9
+ const primary = entity.ownChildren().find((c) => c.type === TYPE_IDENTITY && c.subType === IDENTITY_SUBTYPE_PRIMARY);
10
+ if (!primary) {
11
+ throw new MetadataError(`Entity '${entity.name}' has no primary identity — cannot resolve PK for create`, { entity: entity.name });
12
+ }
13
+ const fieldsAttr = primary.ownAttr(IDENTITY_ATTR_FIELDS);
14
+ if (!Array.isArray(fieldsAttr) || fieldsAttr.length === 0) {
15
+ throw new MetadataError(`Entity '${entity.name}' primary identity has no @fields`, { entity: entity.name });
16
+ }
17
+ const pkFields = fieldsAttr.map(String);
18
+ const isComposite = pkFields.length > 1;
19
+ const generation = primary.ownAttr(IDENTITY_ATTR_GENERATION);
20
+ if (isComposite || generation === undefined || generation === GENERATION_ASSIGNED) {
21
+ const missing = pkFields.filter((f) => data[f] === undefined || data[f] === null);
22
+ if (missing.length > 0) {
23
+ throw new ValidationError(`Missing required PK field(s) on '${entity.name}': ${missing.join(", ")}`, {
24
+ entity: entity.name,
25
+ errors: missing.map((field) => ({
26
+ field,
27
+ rule: "required",
28
+ message: `PK field '${field}' must be provided when @generation is 'assigned' (or unset, or composite)`,
29
+ })),
30
+ });
31
+ }
32
+ const values = {};
33
+ for (const f of pkFields)
34
+ values[f] = data[f];
35
+ return { kind: "preset", values };
36
+ }
37
+ if (generation === GENERATION_INCREMENT) {
38
+ const provided = pkFields.filter((f) => data[f] !== undefined && data[f] !== null);
39
+ if (provided.length === pkFields.length) {
40
+ const values = {};
41
+ for (const f of pkFields)
42
+ values[f] = data[f];
43
+ return { kind: "preset", values };
44
+ }
45
+ return { kind: "driver-generated", values: {} };
46
+ }
47
+ if (generation === GENERATION_UUID) {
48
+ const values = {};
49
+ for (const f of pkFields) {
50
+ values[f] = data[f] !== undefined && data[f] !== null ? data[f] : crypto.randomUUID();
51
+ }
52
+ return { kind: "preset", values };
53
+ }
54
+ // Unknown @generation values fall back to assigned-style: require the caller to supply the PK.
55
+ const missing = pkFields.filter((f) => data[f] === undefined || data[f] === null);
56
+ if (missing.length > 0) {
57
+ throw new ValidationError(`Missing PK field(s) on '${entity.name}': ${missing.join(", ")}`, {
58
+ entity: entity.name,
59
+ errors: missing.map((field) => ({ field, rule: "required", message: `PK field '${field}' is required` })),
60
+ });
61
+ }
62
+ const values = {};
63
+ for (const f of pkFields)
64
+ values[f] = data[f];
65
+ return { kind: "preset", values };
66
+ }
67
+ //# sourceMappingURL=identity-strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-strategy.js","sourceRoot":"","sources":["../src/identity-strategy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export { ObjectManager } from "./object-manager.js";
2
+ export type { ObjectManagerOptions, ReadOpts, WriteOpts } from "./object-manager.js";
3
+ export type { PersistenceDriver, Dialect, Row, PrimitiveValue, WhereClause, OrderBy, SelectSpec, CountSpec, InsertSpec, InsertManySpec, UpdateSpec, UpdateManySpec, DeleteSpec, DeleteManySpec, } from "./persistence-driver.js";
4
+ export type { Filter, FilterValue, QueryOpts } from "./query-builder.js";
5
+ export type { FieldViewSpec, EntityViewSpec } from "./view.js";
6
+ export type { ValidationResult } from "./validator-runner.js";
7
+ export type { ValidationFailure } from "./errors.js";
8
+ export { RuntimeError, ValidationError, NotFoundError, ConstraintViolationError, MetadataError, UnsafeNameError, } from "./errors.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErF,YAAY,EACV,iBAAiB,EAAE,OAAO,EAAE,GAAG,EAAE,cAAc,EAC/C,WAAW,EAAE,OAAO,EACpB,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EACjD,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,GACvD,MAAM,yBAAyB,CAAC;AAEjC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEzE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE/D,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EACL,YAAY,EACZ,eAAe,EACf,aAAa,EACb,wBAAwB,EACxB,aAAa,EACb,eAAe,GAChB,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { ObjectManager } from "./object-manager.js";
2
+ export { RuntimeError, ValidationError, NotFoundError, ConstraintViolationError, MetadataError, UnsafeNameError, } from "./errors.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAgBpD,OAAO,EACL,YAAY,EACZ,eAAe,EACf,aAAa,EACb,wBAAwB,EACxB,aAAa,EACb,eAAe,GAChB,MAAM,aAAa,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { MetaData } from "@metaobjectsdev/metadata";
2
+ import type { SelectSpec, Row } from "./persistence-driver.js";
3
+ export interface N2mDescriptor {
4
+ /** Entity that declares the relationship (source of the lookup; its PK feeds sourceJoinField). */
5
+ sourceEntityName: string;
6
+ targetEntityName: string;
7
+ joinEntityName: string;
8
+ /** Field name on the join entity holding the source-side FK. */
9
+ sourceJoinField: string;
10
+ /** Field name on the join entity holding the target-side FK. */
11
+ targetJoinField: string;
12
+ }
13
+ export interface N2mLazyOutput {
14
+ joinSpec: SelectSpec;
15
+ /** Caller runs joinSpec, then passes the rows here to build the target spec. */
16
+ makeTargetSpec: (joinRows: Row[]) => SelectSpec | null;
17
+ }
18
+ export interface N2mBatchOutput {
19
+ joinSpec: SelectSpec;
20
+ makeTargetSpec: (joinRows: Row[]) => SelectSpec | null;
21
+ }
22
+ /** Returns null if the named relationship is not N:M — caller should try resolveRelationDescriptor. */
23
+ export declare function resolveN2mDescriptor(sourceEntity: MetaData, relationName: string, root: MetaData): N2mDescriptor | null;
24
+ export declare function buildN2mLazySpecs(desc: N2mDescriptor, sourceRecord: Row, root: MetaData): N2mLazyOutput;
25
+ export declare function buildN2mBatchSpecs(desc: N2mDescriptor, sourceRecords: Row[], root: MetaData): N2mBatchOutput;
26
+ export declare function resolveJoinColumnName(joinEntity: MetaData, fieldName: string): string;
27
+ //# sourceMappingURL=n2m-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"n2m-resolver.d.ts","sourceRoot":"","sources":["../src/n2m-resolver.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAUzD,OAAO,KAAK,EAAE,UAAU,EAAkB,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAE/E,MAAM,WAAW,aAAa;IAC5B,kGAAkG;IAClG,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,eAAe,EAAE,MAAM,CAAC;IACxB,gEAAgE;IAChE,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,UAAU,CAAC;IACrB,gFAAgF;IAChF,cAAc,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,UAAU,GAAG,IAAI,CAAC;CACxD;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,UAAU,CAAC;IACrB,cAAc,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,UAAU,GAAG,IAAI,CAAC;CACxD;AAED,uGAAuG;AACvG,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,QAAQ,EACtB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,QAAQ,GACb,aAAa,GAAG,IAAI,CA+BtB;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,aAAa,EACnB,YAAY,EAAE,GAAG,EACjB,IAAI,EAAE,QAAQ,GACb,aAAa,CAgBf;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,aAAa,EACnB,aAAa,EAAE,GAAG,EAAE,EACpB,IAAI,EAAE,QAAQ,GACb,cAAc,CAgBhB;AA8BD,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAIrF"}
@@ -0,0 +1,103 @@
1
+ // Two-stage N:M: first query the join entity for FK pairs, then query the target entity for the rows.
2
+ // The relationship declares @joinEntity + @joinFields: [sourceJoinField, targetJoinField].
3
+ import { TYPE_OBJECT, TYPE_FIELD, TYPE_RELATIONSHIP, RELATIONSHIP_ATTR_CARDINALITY, RELATIONSHIP_ATTR_OBJECT_REF, RELATIONSHIP_ATTR_JOIN_ENTITY, RELATIONSHIP_ATTR_JOIN_FIELDS, CARDINALITY_MANY, resolveColumnName, } from "@metaobjectsdev/metadata";
4
+ import { MetadataError } from "./errors.js";
5
+ import { buildSelectSpec, resolvePkFields } from "./query-builder.js";
6
+ /** Returns null if the named relationship is not N:M — caller should try resolveRelationDescriptor. */
7
+ export function resolveN2mDescriptor(sourceEntity, relationName, root) {
8
+ for (const child of sourceEntity.ownChildren()) {
9
+ if (child.type !== TYPE_RELATIONSHIP)
10
+ continue;
11
+ if (child.name !== relationName)
12
+ continue;
13
+ if (child.ownAttr(RELATIONSHIP_ATTR_CARDINALITY) !== CARDINALITY_MANY)
14
+ continue;
15
+ const targetEntityName = child.ownAttr(RELATIONSHIP_ATTR_OBJECT_REF);
16
+ const joinEntityName = child.ownAttr(RELATIONSHIP_ATTR_JOIN_ENTITY);
17
+ const joinFields = child.ownAttr(RELATIONSHIP_ATTR_JOIN_FIELDS);
18
+ if (!targetEntityName || !joinEntityName || !Array.isArray(joinFields) || joinFields.length !== 2) {
19
+ throw new MetadataError(`N:M relationship '${relationName}' on '${sourceEntity.name}' requires @objectRef + @joinEntity + @joinFields: [sourceFk, targetFk]`, { entity: sourceEntity.name });
20
+ }
21
+ const targetExists = root.ownChildren().some((c) => c.type === TYPE_OBJECT && c.name === targetEntityName);
22
+ if (!targetExists) {
23
+ throw new MetadataError(`Target entity '${targetEntityName}' not found`, { entity: sourceEntity.name });
24
+ }
25
+ const joinExists = root.ownChildren().some((c) => c.type === TYPE_OBJECT && c.name === joinEntityName);
26
+ if (!joinExists) {
27
+ throw new MetadataError(`Join entity '${joinEntityName}' not found`, { entity: sourceEntity.name });
28
+ }
29
+ return {
30
+ sourceEntityName: sourceEntity.name,
31
+ targetEntityName,
32
+ joinEntityName,
33
+ sourceJoinField: String(joinFields[0]),
34
+ targetJoinField: String(joinFields[1]),
35
+ };
36
+ }
37
+ return null;
38
+ }
39
+ export function buildN2mLazySpecs(desc, sourceRecord, root) {
40
+ const joinEntity = mustGetEntity(root, desc.joinEntityName);
41
+ const targetEntity = mustGetEntity(root, desc.targetEntityName);
42
+ const sourcePkField = resolvePkFields(mustGetEntity(root, desc.sourceEntityName))[0];
43
+ const sourcePkValue = sourceRecord[sourcePkField];
44
+ const joinSpec = buildSelectSpec(joinEntity, { [desc.sourceJoinField]: sourcePkValue }, {});
45
+ const makeTargetSpec = (joinRows) => {
46
+ const targetIds = collectTargetIds(joinRows, desc.targetJoinField, joinEntity);
47
+ if (targetIds.length === 0)
48
+ return null;
49
+ const targetPkField = resolvePkFields(targetEntity)[0];
50
+ return buildSelectSpec(targetEntity, { [targetPkField]: targetIds }, {});
51
+ };
52
+ return { joinSpec, makeTargetSpec };
53
+ }
54
+ export function buildN2mBatchSpecs(desc, sourceRecords, root) {
55
+ const joinEntity = mustGetEntity(root, desc.joinEntityName);
56
+ const targetEntity = mustGetEntity(root, desc.targetEntityName);
57
+ const sourcePkField = resolvePkFields(mustGetEntity(root, desc.sourceEntityName))[0];
58
+ const sourceIds = collectIds(sourceRecords, sourcePkField);
59
+ const joinSpec = buildSelectSpec(joinEntity, { [desc.sourceJoinField]: sourceIds }, {});
60
+ const makeTargetSpec = (joinRows) => {
61
+ const targetIds = collectTargetIds(joinRows, desc.targetJoinField, joinEntity);
62
+ if (targetIds.length === 0)
63
+ return null;
64
+ const targetPkField = resolvePkFields(targetEntity)[0];
65
+ return buildSelectSpec(targetEntity, { [targetPkField]: targetIds }, {});
66
+ };
67
+ return { joinSpec, makeTargetSpec };
68
+ }
69
+ function mustGetEntity(root, name) {
70
+ const e = root.ownChildren().find((c) => c.type === TYPE_OBJECT && c.name === name);
71
+ if (!e)
72
+ throw new MetadataError(`Entity '${name}' not found`, { entity: name });
73
+ return e;
74
+ }
75
+ function collectIds(records, pkField) {
76
+ const seen = new Set();
77
+ for (const r of records) {
78
+ const v = r[pkField];
79
+ if (v === null || v === undefined)
80
+ continue;
81
+ seen.add(v);
82
+ }
83
+ return [...seen];
84
+ }
85
+ function collectTargetIds(joinRows, targetJoinField, joinEntity) {
86
+ // joinRows are raw column-keyed (driver hasn't been to-JS-row'd yet); resolve the metadata field name to its DB column.
87
+ const dbColumn = resolveJoinColumnName(joinEntity, targetJoinField);
88
+ const seen = new Set();
89
+ for (const r of joinRows) {
90
+ const v = r[dbColumn];
91
+ if (v === null || v === undefined)
92
+ continue;
93
+ seen.add(v);
94
+ }
95
+ return [...seen];
96
+ }
97
+ export function resolveJoinColumnName(joinEntity, fieldName) {
98
+ const field = joinEntity.ownChildren().find((c) => c.type === TYPE_FIELD && c.name === fieldName);
99
+ if (!field)
100
+ throw new MetadataError(`Join field '${fieldName}' not on '${joinEntity.name}'`);
101
+ return resolveColumnName(field);
102
+ }
103
+ //# sourceMappingURL=n2m-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"n2m-resolver.js","sourceRoot":"","sources":["../src/n2m-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import type { MetaData } from "@metaobjectsdev/metadata";
2
+ import type { PersistenceDriver, Row } from "./persistence-driver.js";
3
+ import { type Filter, type QueryOpts } from "./query-builder.js";
4
+ import { type FieldViewSpec, type EntityViewSpec } from "./view.js";
5
+ import type { ValidationResult } from "./validator-runner.js";
6
+ export interface ObjectManagerOptions {
7
+ metadata: MetaData;
8
+ driver: PersistenceDriver;
9
+ }
10
+ export interface ReadOpts extends QueryOpts {
11
+ view?: string;
12
+ include?: string[];
13
+ tx?: PersistenceDriver;
14
+ }
15
+ export interface WriteOpts {
16
+ view?: string;
17
+ tx?: PersistenceDriver;
18
+ ifMissing?: "throw" | "ignore";
19
+ }
20
+ export declare class ObjectManager {
21
+ private readonly metadata;
22
+ private readonly driver;
23
+ private readonly nameMapCache;
24
+ constructor(opts: ObjectManagerOptions);
25
+ private nameMap;
26
+ findById(entityName: string, id: unknown, opts?: ReadOpts): Promise<Row | null>;
27
+ findFirst(entityName: string, filter: Filter, opts?: ReadOpts): Promise<Row | null>;
28
+ findMany(entityName: string, filter?: Filter, opts?: ReadOpts): Promise<Row[]>;
29
+ count(entityName: string, filter?: Filter, opts?: Pick<ReadOpts, "tx">): Promise<number>;
30
+ load(refString: string): Promise<Row | null>;
31
+ refOf(entityName: string, record: Row): string;
32
+ create(entityName: string, data: Row, opts?: WriteOpts): Promise<Row>;
33
+ update(entityName: string, id: unknown, data: Row, opts?: WriteOpts): Promise<Row | null>;
34
+ delete(entityName: string, id: unknown, opts?: WriteOpts): Promise<boolean>;
35
+ createMany(entityName: string, dataArray: Row[], opts?: WriteOpts): Promise<Row[]>;
36
+ updateMany(entityName: string, filter: Filter, partial: Row, opts?: WriteOpts): Promise<number>;
37
+ deleteMany(entityName: string, filter: Filter, opts?: WriteOpts): Promise<number>;
38
+ transaction<T>(fn: (txOm: ObjectManager) => Promise<T>): Promise<T>;
39
+ relate(entityName: string, record: Row, relationName: string, opts?: ReadOpts): Promise<Row | Row[] | null>;
40
+ viewFields(entityName: string, viewName: string): string[];
41
+ fieldView(entityName: string, fieldName: string, viewName: string): FieldViewSpec | null;
42
+ entityView(entityName: string, viewName: string): EntityViewSpec;
43
+ validate(entityName: string, data: Row): ValidationResult;
44
+ private attachIncludes;
45
+ private toDbRow;
46
+ private allDbColumns;
47
+ private applyViewRestriction;
48
+ private requireEntity;
49
+ private toJsRow;
50
+ }
51
+ //# sourceMappingURL=object-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object-manager.d.ts","sourceRoot":"","sources":["../src/object-manager.ts"],"names":[],"mappings":"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"}