@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,178 @@
1
+ import { TYPE_FIELD, TYPE_IDENTITY, IDENTITY_SUBTYPE_PRIMARY, IDENTITY_ATTR_FIELDS, resolveTableName, resolveColumnName, } from "@metaobjectsdev/metadata";
2
+ import { MetadataError } from "./errors.js";
3
+ export { resolveTableName } from "@metaobjectsdev/metadata";
4
+ export function resolvePkFields(entity) {
5
+ const primary = entity.ownChildren().find((c) => c.type === TYPE_IDENTITY && c.subType === IDENTITY_SUBTYPE_PRIMARY);
6
+ if (!primary) {
7
+ throw new MetadataError(`Entity '${entity.name}' has no primary identity`, { entity: entity.name });
8
+ }
9
+ const attr = primary.ownAttr(IDENTITY_ATTR_FIELDS);
10
+ if (!Array.isArray(attr) || attr.length === 0) {
11
+ throw new MetadataError(`Entity '${entity.name}' primary identity has no @fields`, { entity: entity.name });
12
+ }
13
+ return attr.map(String);
14
+ }
15
+ function listFieldNames(entity) {
16
+ const out = [];
17
+ for (const child of entity.ownChildren()) {
18
+ if (child.type === TYPE_FIELD)
19
+ out.push(child.name);
20
+ }
21
+ return out;
22
+ }
23
+ function getField(entity, fieldName) {
24
+ const f = entity.ownChildren().find((c) => c.type === TYPE_FIELD && c.name === fieldName);
25
+ if (!f) {
26
+ throw new MetadataError(`Unknown field '${fieldName}' on entity '${entity.name}'`, { entity: entity.name });
27
+ }
28
+ return f;
29
+ }
30
+ function rowToColumns(entity, data) {
31
+ const out = {};
32
+ for (const [k, v] of Object.entries(data)) {
33
+ const field = getField(entity, k);
34
+ out[resolveColumnName(field)] = v;
35
+ }
36
+ return out;
37
+ }
38
+ /**
39
+ * Returns null when `filter` has no clauses ({} or { $and: [] }) — meaning "match all"
40
+ * (callers should treat null the same as omitting the where clause entirely).
41
+ */
42
+ export function compileFilter(entity, filter) {
43
+ if ("$and" in filter && Array.isArray(filter.$and)) {
44
+ // TS can't narrow $and away from the Record branch, so the runtime check above
45
+ // proves it's a Filter[] but the element type still needs a bridge cast.
46
+ const andFilters = filter.$and;
47
+ const clauses = andFilters.map((f) => compileFilter(entity, f)).filter((c) => c !== null);
48
+ if (clauses.length === 0)
49
+ return null;
50
+ return clauses.length === 1 ? clauses[0] : { kind: "and", clauses };
51
+ }
52
+ const entries = Object.entries(filter);
53
+ if (entries.length === 0)
54
+ return null;
55
+ if (entries.length === 1) {
56
+ return compileEntry(entity, entries[0][0], entries[0][1]);
57
+ }
58
+ return {
59
+ kind: "and",
60
+ clauses: entries.map(([k, v]) => compileEntry(entity, k, v)),
61
+ };
62
+ }
63
+ function compileEntry(entity, fieldName, value) {
64
+ const field = getField(entity, fieldName);
65
+ const column = resolveColumnName(field);
66
+ if (value === null)
67
+ return { kind: "isNull", column, not: false };
68
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
69
+ return { kind: "eq", column, value };
70
+ }
71
+ if (Array.isArray(value)) {
72
+ return { kind: "in", column, values: value };
73
+ }
74
+ // If multiple operators are set on one field ({ $gte: 5, $lte: 10 }), the FIRST match wins
75
+ // and later operators are silently ignored. Range queries must use $and: [...] explicitly.
76
+ const op = value;
77
+ if ("$eq" in op && op.$eq !== undefined) {
78
+ if (op.$eq === null)
79
+ return { kind: "isNull", column, not: false };
80
+ return { kind: "eq", column, value: op.$eq };
81
+ }
82
+ if ("$ne" in op && op.$ne !== undefined) {
83
+ if (op.$ne === null)
84
+ return { kind: "isNull", column, not: true };
85
+ return { kind: "ne", column, value: op.$ne };
86
+ }
87
+ if ("$gt" in op && op.$gt !== undefined)
88
+ return { kind: "gt", column, value: op.$gt };
89
+ if ("$gte" in op && op.$gte !== undefined)
90
+ return { kind: "gte", column, value: op.$gte };
91
+ if ("$lt" in op && op.$lt !== undefined)
92
+ return { kind: "lt", column, value: op.$lt };
93
+ if ("$lte" in op && op.$lte !== undefined)
94
+ return { kind: "lte", column, value: op.$lte };
95
+ if ("$like" in op && op.$like !== undefined)
96
+ return { kind: "like", column, pattern: op.$like };
97
+ if ("$in" in op && op.$in !== undefined)
98
+ return { kind: "in", column, values: op.$in };
99
+ if ("$isNull" in op && op.$isNull !== undefined) {
100
+ return { kind: "isNull", column, not: !op.$isNull };
101
+ }
102
+ throw new MetadataError(`No recognized operator on filter for field '${fieldName}'`);
103
+ }
104
+ function normalizeOrderBy(input, entity) {
105
+ if (input === undefined)
106
+ return undefined;
107
+ const arr = Array.isArray(input[0]) ? input : [input];
108
+ return arr.map(([fieldName, dir]) => {
109
+ const field = getField(entity, fieldName);
110
+ return { column: resolveColumnName(field), direction: dir };
111
+ });
112
+ }
113
+ /** If `projectedFields` is provided, only those fields are selected (PK is auto-added). */
114
+ export function buildSelectSpec(entity, filter, opts, projectedFields) {
115
+ const allFields = projectedFields ?? listFieldNames(entity);
116
+ const pkFields = resolvePkFields(entity);
117
+ const fieldSet = new Set(allFields);
118
+ for (const pk of pkFields)
119
+ fieldSet.add(pk);
120
+ const columns = [...fieldSet].map((f) => resolveColumnName(getField(entity, f)));
121
+ const orderBy = normalizeOrderBy(opts.orderBy, entity);
122
+ const spec = {
123
+ table: resolveTableName(entity),
124
+ columns,
125
+ };
126
+ const where = filter !== undefined ? compileFilter(entity, filter) : null;
127
+ if (where !== null)
128
+ spec.where = where;
129
+ if (orderBy !== undefined)
130
+ spec.orderBy = orderBy;
131
+ if (opts.limit !== undefined)
132
+ spec.limit = opts.limit;
133
+ if (opts.offset !== undefined)
134
+ spec.offset = opts.offset;
135
+ return spec;
136
+ }
137
+ export function buildCountSpec(entity, filter) {
138
+ const spec = { table: resolveTableName(entity) };
139
+ const where = filter !== undefined ? compileFilter(entity, filter) : null;
140
+ if (where !== null)
141
+ spec.where = where;
142
+ return spec;
143
+ }
144
+ export function buildInsertSpec(entity, data) {
145
+ const values = rowToColumns(entity, data);
146
+ const allFields = listFieldNames(entity);
147
+ return {
148
+ table: resolveTableName(entity),
149
+ values,
150
+ returning: allFields.map((f) => resolveColumnName(getField(entity, f))),
151
+ };
152
+ }
153
+ export function buildUpdateSpec(entity, data, id) {
154
+ const values = rowToColumns(entity, data);
155
+ const pkFields = resolvePkFields(entity);
156
+ if (pkFields.length !== 1) {
157
+ throw new MetadataError(`update-by-id requires single-column PK on '${entity.name}'; use updateMany for composite PKs`, { entity: entity.name });
158
+ }
159
+ const pkColumn = resolveColumnName(getField(entity, pkFields[0]));
160
+ return {
161
+ table: resolveTableName(entity),
162
+ values,
163
+ where: { kind: "eq", column: pkColumn, value: id },
164
+ returning: listFieldNames(entity).map((f) => resolveColumnName(getField(entity, f))),
165
+ };
166
+ }
167
+ export function buildDeleteSpec(entity, id) {
168
+ const pkFields = resolvePkFields(entity);
169
+ if (pkFields.length !== 1) {
170
+ throw new MetadataError(`delete-by-id requires single-column PK on '${entity.name}'; use deleteMany for composite PKs`, { entity: entity.name });
171
+ }
172
+ const pkColumn = resolveColumnName(getField(entity, pkFields[0]));
173
+ return {
174
+ table: resolveTableName(entity),
175
+ where: { kind: "eq", column: pkColumn, value: id },
176
+ };
177
+ }
178
+ //# sourceMappingURL=query-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-builder.js","sourceRoot":"","sources":["../src/query-builder.ts"],"names":[],"mappings":"AACA,OAAO,EACL,UAAU,EAAE,aAAa,EACzB,wBAAwB,EACxB,oBAAoB,EACpB,gBAAgB,EAAE,iBAAiB,GACpC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAM5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAyB5D,MAAM,UAAU,eAAe,CAAC,MAAgB;IAC9C,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,IAAI,CACvC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,IAAI,CAAC,CAAC,OAAO,KAAK,wBAAwB,CAC1E,CAAC;IACF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,aAAa,CAAC,WAAW,MAAM,CAAC,IAAI,2BAA2B,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACtG,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,aAAa,CAAC,WAAW,MAAM,CAAC,IAAI,mCAAmC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9G,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,cAAc,CAAC,MAAgB;IACtC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;QACzC,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;YAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,QAAQ,CAAC,MAAgB,EAAE,SAAiB;IACnD,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;IAC1F,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,aAAa,CACrB,kBAAkB,SAAS,gBAAgB,MAAM,CAAC,IAAI,GAAG,EACzD,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,CACxB,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,YAAY,CAAC,MAAgB,EAAE,IAAS;IAC/C,MAAM,GAAG,GAAQ,EAAE,CAAC;IACpB,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAClC,GAAG,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,MAAgB,EAAE,MAAc;IAC5D,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,+EAA+E;QAC/E,yEAAyE;QACzE,MAAM,UAAU,GAAG,MAAM,CAAC,IAAgB,CAAC;QAC3C,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAoB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QAC5G,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACtC,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACvE,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAE,CAAC,CAAC,CAAgB,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO;QACL,IAAI,EAAE,KAAK;QACX,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,CAAgB,CAAC,CAAC;KAC5E,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,MAAgB,EAAE,SAAiB,EAAE,KAAkB;IAC3E,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAExC,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;IAClE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QACzF,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACvC,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAyB,EAAE,CAAC;IACnE,CAAC;IAED,2FAA2F;IAC3F,2FAA2F;IAC3F,MAAM,EAAE,GAAG,KAAK,CAAC;IACjB,IAAI,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QACxC,IAAI,EAAE,CAAC,GAAG,KAAK,IAAI;YAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QACnE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC;IAC/C,CAAC;IACD,IAAI,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QACxC,IAAI,EAAE,CAAC,GAAG,KAAK,IAAI;YAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;QAClE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC;IAC/C,CAAC;IACD,IAAI,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC;IACtF,IAAI,MAAM,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;IAC1F,IAAI,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC;IACtF,IAAI,MAAM,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;IAC1F,IAAI,OAAO,IAAI,EAAE,IAAI,EAAE,CAAC,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC;IAChG,IAAI,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC;IACvF,IAAI,SAAS,IAAI,EAAE,IAAI,EAAE,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAChD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC;IACtD,CAAC;IACD,MAAM,IAAI,aAAa,CAAC,+CAA+C,SAAS,GAAG,CAAC,CAAC;AACvF,CAAC;AAED,SAAS,gBAAgB,CAAC,KAA2B,EAAE,MAAgB;IACrE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,KAAoC,CAAC,CAAC,CAAC,CAAC,KAAiC,CAAC,CAAC;IAClH,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,EAAE;QAClC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC1C,OAAO,EAAE,MAAM,EAAE,iBAAiB,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;IAC9D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,eAAe,CAC7B,MAAgB,EAChB,MAA0B,EAC1B,IAAe,EACf,eAA0B;IAE1B,MAAM,SAAS,GAAG,eAAe,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAS,SAAS,CAAC,CAAC;IAC5C,KAAK,MAAM,EAAE,IAAI,QAAQ;QAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAE5C,MAAM,OAAO,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACjF,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAEvD,MAAM,IAAI,GAAe;QACvB,KAAK,EAAE,gBAAgB,CAAC,MAAM,CAAC;QAC/B,OAAO;KACR,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1E,IAAI,KAAK,KAAK,IAAI;QAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvC,IAAI,OAAO,KAAK,SAAS;QAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAClD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;QAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IACtD,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;QAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACzD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAgB,EAAE,MAA0B;IACzE,MAAM,IAAI,GAAc,EAAE,KAAK,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;IAC5D,MAAM,KAAK,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1E,IAAI,KAAK,KAAK,IAAI;QAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAgB,EAAE,IAAS;IACzD,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACzC,OAAO;QACL,KAAK,EAAE,gBAAgB,CAAC,MAAM,CAAC;QAC/B,MAAM;QACN,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;KACxE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAgB,EAAE,IAAS,EAAE,EAAW;IACtE,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,aAAa,CACrB,8CAA8C,MAAM,CAAC,IAAI,qCAAqC,EAC9F,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,CACxB,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC;IACnE,OAAO;QACL,KAAK,EAAE,gBAAgB,CAAC,MAAM,CAAC;QAC/B,MAAM;QACN,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAoB,EAAE;QACpE,SAAS,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;KACrF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAgB,EAAE,EAAW;IAC3D,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,aAAa,CACrB,8CAA8C,MAAM,CAAC,IAAI,qCAAqC,EAC9F,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,CACxB,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC;IACnE,OAAO;QACL,KAAK,EAAE,gBAAgB,CAAC,MAAM,CAAC;QAC/B,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAoB,EAAE;KACrE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ export interface DecodedRef {
2
+ entity: string;
3
+ /** PK values come back as strings; caller coerces back to number/etc. per metadata. */
4
+ pkValues: string[];
5
+ }
6
+ export declare function encodeRef(entity: string, record: Record<string, unknown>, pkFields: string[]): string;
7
+ export declare function decodeRef(refString: string): DecodedRef;
8
+ //# sourceMappingURL=ref-codec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ref-codec.d.ts","sourceRoot":"","sources":["../src/ref-codec.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,uFAAuF;IACvF,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CA6BrG;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAoBvD"}
@@ -0,0 +1,42 @@
1
+ // Reference-string format ("Entity:pk" or "Entity:pk1,pk2") mirrors Java's getObjectByRef.
2
+ // PK values containing commas are not supported in v0.1 — commas are the composite separator.
3
+ import { MetadataError, UnsafeNameError } from "./errors.js";
4
+ import { REF_SEPARATOR, REF_PK_SEPARATOR, VALID_ENTITY_NAME } from "./constants.js";
5
+ export function encodeRef(entity, record, pkFields) {
6
+ if (!VALID_ENTITY_NAME.test(entity)) {
7
+ throw new UnsafeNameError(`Unsafe entity name '${entity}' — must match ${VALID_ENTITY_NAME}`, { value: entity });
8
+ }
9
+ if (pkFields.length === 0) {
10
+ throw new MetadataError(`No primary-key fields declared for entity '${entity}'`, { entity });
11
+ }
12
+ const values = [];
13
+ for (const field of pkFields) {
14
+ const value = record[field];
15
+ if (value === undefined || value === null) {
16
+ throw new MetadataError(`Missing PK field '${field}' on record while encoding ref for '${entity}'`, { entity });
17
+ }
18
+ const str = String(value);
19
+ if (str.includes(REF_PK_SEPARATOR)) {
20
+ throw new MetadataError(`PK value for '${field}' on '${entity}' contains '${REF_PK_SEPARATOR}' — reserved as the composite-PK separator in ref strings`, { entity });
21
+ }
22
+ values.push(str);
23
+ }
24
+ return `${entity}${REF_SEPARATOR}${values.join(REF_PK_SEPARATOR)}`;
25
+ }
26
+ export function decodeRef(refString) {
27
+ const sepIdx = refString.indexOf(REF_SEPARATOR);
28
+ if (sepIdx <= 0) {
29
+ throw new MetadataError(`Reference string '${refString}' missing '${REF_SEPARATOR}' separator`);
30
+ }
31
+ const entity = refString.slice(0, sepIdx);
32
+ const pkPart = refString.slice(sepIdx + 1);
33
+ if (!VALID_ENTITY_NAME.test(entity)) {
34
+ throw new UnsafeNameError(`Unsafe entity name '${entity}' in reference '${refString}'`, { value: entity });
35
+ }
36
+ if (pkPart.length === 0) {
37
+ throw new MetadataError(`Reference string '${refString}' has empty PK part`, { entity });
38
+ }
39
+ const pkValues = pkPart.split(REF_PK_SEPARATOR);
40
+ return { entity, pkValues };
41
+ }
42
+ //# sourceMappingURL=ref-codec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ref-codec.js","sourceRoot":"","sources":["../src/ref-codec.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,8FAA8F;AAE9F,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAQpF,MAAM,UAAU,SAAS,CAAC,MAAc,EAAE,MAA+B,EAAE,QAAkB;IAC3F,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,eAAe,CACvB,uBAAuB,MAAM,kBAAkB,iBAAiB,EAAE,EAClE,EAAE,KAAK,EAAE,MAAM,EAAE,CAClB,CAAC;IACJ,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,aAAa,CAAC,8CAA8C,MAAM,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/F,CAAC;IACD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC1C,MAAM,IAAI,aAAa,CACrB,qBAAqB,KAAK,uCAAuC,MAAM,GAAG,EAC1E,EAAE,MAAM,EAAE,CACX,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,aAAa,CACrB,iBAAiB,KAAK,SAAS,MAAM,eAAe,gBAAgB,2DAA2D,EAC/H,EAAE,MAAM,EAAE,CACX,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,MAAM,GAAG,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,SAAiB;IACzC,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAChD,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,aAAa,CACrB,qBAAqB,SAAS,cAAc,aAAa,aAAa,CACvE,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,eAAe,CACvB,uBAAuB,MAAM,mBAAmB,SAAS,GAAG,EAC5D,EAAE,KAAK,EAAE,MAAM,EAAE,CAClB,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,aAAa,CAAC,qBAAqB,SAAS,qBAAqB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3F,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAChD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { MetaData } from "@metaobjectsdev/metadata";
2
+ import { CARDINALITY_ONE, CARDINALITY_MANY } from "@metaobjectsdev/metadata";
3
+ import type { SelectSpec, Row } from "./persistence-driver.js";
4
+ export interface RelationDescriptor {
5
+ /** "one" = source holds the FK pointing at target. "many" = target holds the FK pointing back at source. */
6
+ cardinality: typeof CARDINALITY_ONE | typeof CARDINALITY_MANY;
7
+ /** Entity name we're loading rows OF. */
8
+ targetEntityName: string;
9
+ /** Field on the source record to read the lookup value from (one-side: FK column; many-side: source PK). */
10
+ sourceField: string;
11
+ /** Field on the target table to filter by (one-side: target PK; many-side: back-pointing FK). */
12
+ targetField: string;
13
+ }
14
+ /**
15
+ * Walks one-side (relationship children of `sourceEntity`) then many-side (relationship
16
+ * children of any OTHER entity pointing to `sourceEntity`). The inverse-side relation name
17
+ * is computed via the same convention as SP2's relation-resolver: variableNameFromEntity
18
+ * (lower-camel + plural) of the declaring source.
19
+ *
20
+ * FK direction is sourced from identity.reference declarations, not relationship attrs.
21
+ */
22
+ export declare function resolveRelationDescriptor(sourceEntity: MetaData, relationName: string, root: MetaData): RelationDescriptor;
23
+ /** Returns null when the source-side lookup value is null — caller returns null/[]. */
24
+ export declare function buildLazyRelateSpec(desc: RelationDescriptor, sourceRecord: Row, root: MetaData): SelectSpec | null;
25
+ /** Builds one batched IN(...) lookup. Returns null when there are no non-null source values. */
26
+ export declare function buildIncludeBatchSpec(desc: RelationDescriptor, sourceRecords: Row[], root: MetaData): SelectSpec | null;
27
+ //# sourceMappingURL=relation-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation-resolver.d.ts","sourceRoot":"","sources":["../src/relation-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAML,eAAe,EAAE,gBAAgB,EAClC,MAAM,0BAA0B,CAAC;AAKlC,OAAO,KAAK,EAAE,UAAU,EAAkB,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAE/E,MAAM,WAAW,kBAAkB;IACjC,4GAA4G;IAC5G,WAAW,EAAE,OAAO,eAAe,GAAG,OAAO,gBAAgB,CAAC;IAC9D,yCAAyC;IACzC,gBAAgB,EAAE,MAAM,CAAC;IACzB,4GAA4G;IAC5G,WAAW,EAAE,MAAM,CAAC;IACpB,iGAAiG;IACjG,WAAW,EAAE,MAAM,CAAC;CACrB;AAyBD;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,QAAQ,EACtB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,QAAQ,GACb,kBAAkB,CAkEpB;AAUD,uFAAuF;AACvF,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,kBAAkB,EACxB,YAAY,EAAE,GAAG,EACjB,IAAI,EAAE,QAAQ,GACb,UAAU,GAAG,IAAI,CAKnB;AAED,gGAAgG;AAChG,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,kBAAkB,EACxB,aAAa,EAAE,GAAG,EAAE,EACpB,IAAI,EAAE,QAAQ,GACb,UAAU,GAAG,IAAI,CAUnB"}
@@ -0,0 +1,136 @@
1
+ import { TYPE_OBJECT, TYPE_RELATIONSHIP, TYPE_IDENTITY, IDENTITY_SUBTYPE_REFERENCE, IDENTITY_ATTR_FIELDS, IDENTITY_REFERENCE_ATTR_REFERENCES, RELATIONSHIP_ATTR_CARDINALITY, RELATIONSHIP_ATTR_OBJECT_REF, CARDINALITY_ONE, CARDINALITY_MANY, } from "@metaobjectsdev/metadata";
2
+ import { MetadataError } from "./errors.js";
3
+ import { buildSelectSpec, resolvePkFields, } from "./query-builder.js";
4
+ /**
5
+ * Find an identity.reference declared on `holder` whose @references targets `targetName`.
6
+ * Returns the FK field name (first field on the identity) or undefined.
7
+ */
8
+ function findReferenceFkField(holder, targetName) {
9
+ for (const child of holder.ownChildren()) {
10
+ if (child.type !== TYPE_IDENTITY)
11
+ continue;
12
+ if (child.subType !== IDENTITY_SUBTYPE_REFERENCE)
13
+ continue;
14
+ const ref = child.ownAttr(IDENTITY_REFERENCE_ATTR_REFERENCES);
15
+ if (typeof ref !== "string")
16
+ continue;
17
+ const dotIdx = ref.indexOf(".");
18
+ const entityName = dotIdx === -1 ? ref : ref.slice(0, dotIdx);
19
+ if (entityName !== targetName)
20
+ continue;
21
+ const fields = child.ownAttr(IDENTITY_ATTR_FIELDS);
22
+ if (Array.isArray(fields) && fields.length > 0)
23
+ return String(fields[0]);
24
+ if (typeof fields === "string") {
25
+ const first = fields.split(",")[0]?.trim();
26
+ if (first)
27
+ return first;
28
+ }
29
+ }
30
+ return undefined;
31
+ }
32
+ /**
33
+ * Walks one-side (relationship children of `sourceEntity`) then many-side (relationship
34
+ * children of any OTHER entity pointing to `sourceEntity`). The inverse-side relation name
35
+ * is computed via the same convention as SP2's relation-resolver: variableNameFromEntity
36
+ * (lower-camel + plural) of the declaring source.
37
+ *
38
+ * FK direction is sourced from identity.reference declarations, not relationship attrs.
39
+ */
40
+ export function resolveRelationDescriptor(sourceEntity, relationName, root) {
41
+ for (const child of sourceEntity.ownChildren()) {
42
+ if (child.type !== TYPE_RELATIONSHIP)
43
+ continue;
44
+ if (child.name !== relationName)
45
+ continue;
46
+ const card = child.ownAttr(RELATIONSHIP_ATTR_CARDINALITY);
47
+ if (card !== CARDINALITY_ONE)
48
+ continue;
49
+ const targetEntityName = child.ownAttr(RELATIONSHIP_ATTR_OBJECT_REF);
50
+ if (!targetEntityName) {
51
+ throw new MetadataError(`Relationship '${relationName}' on '${sourceEntity.name}' missing @objectRef`, { entity: sourceEntity.name });
52
+ }
53
+ const fkField = findReferenceFkField(sourceEntity, targetEntityName);
54
+ if (!fkField) {
55
+ throw new MetadataError(`Relationship '${relationName}' on '${sourceEntity.name}' has no identity.reference targeting '${targetEntityName}'`, { entity: sourceEntity.name });
56
+ }
57
+ const target = root.ownChildren().find((c) => c.type === TYPE_OBJECT && c.name === targetEntityName);
58
+ if (!target) {
59
+ throw new MetadataError(`Target entity '${targetEntityName}' not found for relation '${relationName}' on '${sourceEntity.name}'`, { entity: sourceEntity.name });
60
+ }
61
+ return {
62
+ cardinality: "one",
63
+ targetEntityName,
64
+ sourceField: fkField,
65
+ targetField: resolvePkFields(target)[0],
66
+ };
67
+ }
68
+ for (const other of root.ownChildren()) {
69
+ if (other.type !== TYPE_OBJECT)
70
+ continue;
71
+ if (other.name === sourceEntity.name)
72
+ continue;
73
+ for (const child of other.ownChildren()) {
74
+ if (child.type !== TYPE_RELATIONSHIP)
75
+ continue;
76
+ const card = child.ownAttr(RELATIONSHIP_ATTR_CARDINALITY);
77
+ if (card !== CARDINALITY_ONE)
78
+ continue;
79
+ const targetEntityName = child.ownAttr(RELATIONSHIP_ATTR_OBJECT_REF);
80
+ if (targetEntityName !== sourceEntity.name)
81
+ continue;
82
+ const inverseName = inversePluralName(other.name);
83
+ if (inverseName !== relationName)
84
+ continue;
85
+ const fkField = findReferenceFkField(other, sourceEntity.name);
86
+ if (!fkField) {
87
+ throw new MetadataError(`Inverse relationship for '${relationName}' on '${sourceEntity.name}': entity '${other.name}' has no identity.reference targeting '${sourceEntity.name}'`, { entity: sourceEntity.name });
88
+ }
89
+ return {
90
+ cardinality: "many",
91
+ targetEntityName: other.name,
92
+ sourceField: resolvePkFields(sourceEntity)[0],
93
+ targetField: fkField,
94
+ };
95
+ }
96
+ }
97
+ throw new MetadataError(`Unknown relation '${relationName}' on entity '${sourceEntity.name}'`, { entity: sourceEntity.name });
98
+ }
99
+ // Mirrors codegen-ts's variableNameFromEntity: lower-camel + plural.
100
+ function inversePluralName(entityName) {
101
+ const camel = entityName.charAt(0).toLowerCase() + entityName.slice(1);
102
+ if (/(s|x|z|ch|sh)$/i.test(camel))
103
+ return camel + "es";
104
+ if (/[^aeiou]y$/i.test(camel))
105
+ return camel.slice(0, -1) + "ies";
106
+ return camel + "s";
107
+ }
108
+ /** Returns null when the source-side lookup value is null — caller returns null/[]. */
109
+ export function buildLazyRelateSpec(desc, sourceRecord, root) {
110
+ const lookup = sourceRecord[desc.sourceField];
111
+ if (lookup === null || lookup === undefined)
112
+ return null;
113
+ const target = mustGetEntity(root, desc.targetEntityName);
114
+ return buildSelectSpec(target, { [desc.targetField]: lookup }, {});
115
+ }
116
+ /** Builds one batched IN(...) lookup. Returns null when there are no non-null source values. */
117
+ export function buildIncludeBatchSpec(desc, sourceRecords, root) {
118
+ const seen = new Set();
119
+ for (const rec of sourceRecords) {
120
+ const v = rec[desc.sourceField];
121
+ if (v === null || v === undefined)
122
+ continue;
123
+ seen.add(v);
124
+ }
125
+ if (seen.size === 0)
126
+ return null;
127
+ const target = mustGetEntity(root, desc.targetEntityName);
128
+ return buildSelectSpec(target, { [desc.targetField]: [...seen] }, {});
129
+ }
130
+ function mustGetEntity(root, name) {
131
+ const e = root.ownChildren().find((c) => c.type === TYPE_OBJECT && c.name === name);
132
+ if (!e)
133
+ throw new MetadataError(`Entity '${name}' not found`, { entity: name });
134
+ return e;
135
+ }
136
+ //# sourceMappingURL=relation-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation-resolver.js","sourceRoot":"","sources":["../src/relation-resolver.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAC7C,0BAA0B,EAC1B,oBAAoB,EACpB,kCAAkC,EAClC,6BAA6B,EAAE,4BAA4B,EAC3D,eAAe,EAAE,gBAAgB,GAClC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACL,eAAe,EAAE,eAAe,GACjC,MAAM,oBAAoB,CAAC;AAc5B;;;GAGG;AACH,SAAS,oBAAoB,CAAC,MAAgB,EAAE,UAAkB;IAChE,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;QACzC,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa;YAAE,SAAS;QAC3C,IAAI,KAAK,CAAC,OAAO,KAAK,0BAA0B;YAAE,SAAS;QAC3D,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;QAC9D,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,SAAS;QACtC,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAC9D,IAAI,UAAU,KAAK,UAAU;YAAE,SAAS;QACxC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QACnD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACzE,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;YAC3C,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,yBAAyB,CACvC,YAAsB,EACtB,YAAoB,EACpB,IAAc;IAEd,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,WAAW,EAAE,EAAE,CAAC;QAC/C,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB;YAAE,SAAS;QAC/C,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;YAAE,SAAS;QAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;QAC1D,IAAI,IAAI,KAAK,eAAe;YAAE,SAAS;QACvC,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC,4BAA4B,CAAuB,CAAC;QAC3F,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,MAAM,IAAI,aAAa,CACrB,iBAAiB,YAAY,SAAS,YAAY,CAAC,IAAI,sBAAsB,EAC7E,EAAE,MAAM,EAAE,YAAY,CAAC,IAAI,EAAE,CAC9B,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,oBAAoB,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;QACrE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,aAAa,CACrB,iBAAiB,YAAY,SAAS,YAAY,CAAC,IAAI,0CAA0C,gBAAgB,GAAG,EACpH,EAAE,MAAM,EAAE,YAAY,CAAC,IAAI,EAAE,CAC9B,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,IAAI,KAAK,gBAAgB,CAAC,CAAC;QACrG,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,aAAa,CACrB,kBAAkB,gBAAgB,6BAA6B,YAAY,SAAS,YAAY,CAAC,IAAI,GAAG,EACxG,EAAE,MAAM,EAAE,YAAY,CAAC,IAAI,EAAE,CAC9B,CAAC;QACJ,CAAC;QACD,OAAO;YACL,WAAW,EAAE,KAAK;YAClB,gBAAgB;YAChB,WAAW,EAAE,OAAO;YACpB,WAAW,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE;SACzC,CAAC;IACJ,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACvC,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;YAAE,SAAS;QACzC,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,IAAI;YAAE,SAAS;QAC/C,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxC,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB;gBAAE,SAAS;YAC/C,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;YAC1D,IAAI,IAAI,KAAK,eAAe;gBAAE,SAAS;YACvC,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC,4BAA4B,CAAuB,CAAC;YAC3F,IAAI,gBAAgB,KAAK,YAAY,CAAC,IAAI;gBAAE,SAAS;YACrD,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAClD,IAAI,WAAW,KAAK,YAAY;gBAAE,SAAS;YAC3C,MAAM,OAAO,GAAG,oBAAoB,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;YAC/D,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,aAAa,CACrB,6BAA6B,YAAY,SAAS,YAAY,CAAC,IAAI,cAAc,KAAK,CAAC,IAAI,0CAA0C,YAAY,CAAC,IAAI,GAAG,EACzJ,EAAE,MAAM,EAAE,YAAY,CAAC,IAAI,EAAE,CAC9B,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,WAAW,EAAE,MAAM;gBACnB,gBAAgB,EAAE,KAAK,CAAC,IAAI;gBAC5B,WAAW,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC,CAAC,CAAE;gBAC9C,WAAW,EAAE,OAAO;aACrB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,IAAI,aAAa,CACrB,qBAAqB,YAAY,gBAAgB,YAAY,CAAC,IAAI,GAAG,EACrE,EAAE,MAAM,EAAE,YAAY,CAAC,IAAI,EAAE,CAC9B,CAAC;AACJ,CAAC;AAED,qEAAqE;AACrE,SAAS,iBAAiB,CAAC,UAAkB;IAC3C,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACvE,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,GAAG,IAAI,CAAC;IACvD,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;IACjE,OAAO,KAAK,GAAG,GAAG,CAAC;AACrB,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,mBAAmB,CACjC,IAAwB,EACxB,YAAiB,EACjB,IAAc;IAEd,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC9C,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACzD,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC1D,OAAO,eAAe,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,MAAwB,EAAE,EAAE,EAAE,CAAC,CAAC;AACvF,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,qBAAqB,CACnC,IAAwB,EACxB,aAAoB,EACpB,IAAc;IAEd,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAChC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS;YAAE,SAAS;QAC5C,IAAI,CAAC,GAAG,CAAC,CAAmB,CAAC,CAAC;IAChC,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC1D,OAAO,eAAe,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,GAAG,IAAI,CAAwB,EAAE,EAAE,EAAE,CAAC,CAAC;AAC/F,CAAC;AAED,SAAS,aAAa,CAAC,IAAc,EAAE,IAAY;IACjD,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IACpF,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,aAAa,CAAC,WAAW,IAAI,aAAa,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAChF,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { MetaData } from "@metaobjectsdev/metadata";
2
+ import type { Dialect, Row } from "./persistence-driver.js";
3
+ export declare function coerceRowOnRead(entity: MetaData, row: Row, dialect: Dialect): Row;
4
+ export declare function coerceRowOnWrite(entity: MetaData, row: Row, dialect: Dialect): Row;
5
+ //# sourceMappingURL=type-coercer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-coercer.d.ts","sourceRoot":"","sources":["../src/type-coercer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEzD,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAE5D,wBAAgB,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,GAAG,GAAG,CAGjF;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,GAAG,GAAG,CAGlF"}
@@ -0,0 +1,43 @@
1
+ // v0.1 only handles SQLite's int↔boolean. Date/timestamp coercion (ISO string ↔ Date) is deferred.
2
+ import { TYPE_FIELD, FIELD_SUBTYPE_BOOLEAN } from "@metaobjectsdev/metadata";
3
+ export function coerceRowOnRead(entity, row, dialect) {
4
+ if (dialect !== "sqlite")
5
+ return row;
6
+ return mapBooleansFromInt(entity, row);
7
+ }
8
+ export function coerceRowOnWrite(entity, row, dialect) {
9
+ if (dialect !== "sqlite")
10
+ return row;
11
+ return mapBooleansToInt(entity, row);
12
+ }
13
+ function mapBooleansFromInt(entity, row) {
14
+ const out = { ...row };
15
+ for (const child of entity.ownChildren()) {
16
+ if (child.type !== TYPE_FIELD)
17
+ continue;
18
+ if (child.subType !== FIELD_SUBTYPE_BOOLEAN)
19
+ continue;
20
+ const v = out[child.name];
21
+ if (v === 0)
22
+ out[child.name] = false;
23
+ else if (v === 1)
24
+ out[child.name] = true;
25
+ }
26
+ return out;
27
+ }
28
+ function mapBooleansToInt(entity, row) {
29
+ const out = { ...row };
30
+ for (const child of entity.ownChildren()) {
31
+ if (child.type !== TYPE_FIELD)
32
+ continue;
33
+ if (child.subType !== FIELD_SUBTYPE_BOOLEAN)
34
+ continue;
35
+ const v = out[child.name];
36
+ if (v === true)
37
+ out[child.name] = 1;
38
+ else if (v === false)
39
+ out[child.name] = 0;
40
+ }
41
+ return out;
42
+ }
43
+ //# sourceMappingURL=type-coercer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-coercer.js","sourceRoot":"","sources":["../src/type-coercer.ts"],"names":[],"mappings":"AAAA,mGAAmG;AAGnG,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAG7E,MAAM,UAAU,eAAe,CAAC,MAAgB,EAAE,GAAQ,EAAE,OAAgB;IAC1E,IAAI,OAAO,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IACrC,OAAO,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAgB,EAAE,GAAQ,EAAE,OAAgB;IAC3E,IAAI,OAAO,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IACrC,OAAO,gBAAgB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,kBAAkB,CAAC,MAAgB,EAAE,GAAQ;IACpD,MAAM,GAAG,GAAQ,EAAE,GAAG,GAAG,EAAE,CAAC;IAC5B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;QACzC,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;YAAE,SAAS;QACxC,IAAI,KAAK,CAAC,OAAO,KAAK,qBAAqB;YAAE,SAAS;QACtD,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,KAAK,CAAC;YAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;aAChC,IAAI,CAAC,KAAK,CAAC;YAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC3C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAgB,EAAE,GAAQ;IAClD,MAAM,GAAG,GAAQ,EAAE,GAAG,GAAG,EAAE,CAAC;IAC5B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;QACzC,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;YAAE,SAAS;QACxC,IAAI,KAAK,CAAC,OAAO,KAAK,qBAAqB;YAAE,SAAS;QACtD,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,KAAK,IAAI;YAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;aAC/B,IAAI,CAAC,KAAK,KAAK;YAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { MetaData } from "@metaobjectsdev/metadata";
2
+ import type { ValidationFailure } from "./errors.js";
3
+ export type ValidationResult = {
4
+ ok: true;
5
+ } | {
6
+ ok: false;
7
+ errors: ValidationFailure[];
8
+ };
9
+ export interface RunValidatorsOpts {
10
+ /** Partial-update mode: required-checks only fire for fields whose key is present in `data`. */
11
+ partial?: boolean;
12
+ }
13
+ export declare function runValidators(entity: MetaData, data: Record<string, unknown>, opts?: RunValidatorsOpts): ValidationResult;
14
+ //# sourceMappingURL=validator-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator-runner.d.ts","sourceRoot":"","sources":["../src/validator-runner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAUzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GACZ;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,iBAAiB,EAAE,CAAA;CAAE,CAAC;AAO/C,MAAM,WAAW,iBAAiB;IAChC,gGAAgG;IAChG,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,QAAQ,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,IAAI,GAAE,iBAAsB,GAC3B,gBAAgB,CA6FlB"}