@danceroutine/tango-schema 1.1.3 → 1.2.0

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 (38) hide show
  1. package/dist/domain/Model.d.ts +7 -1
  2. package/dist/domain/index.d.ts +1 -1
  3. package/dist/domain-Cufz6y1q.js.map +1 -1
  4. package/dist/index.d.ts +2 -2
  5. package/dist/index.js +1 -1
  6. package/dist/model/Model.d.ts +1 -1
  7. package/dist/model/ModelDefinition.d.ts +5 -3
  8. package/dist/model/decorators/Decorators.d.ts +46 -6
  9. package/dist/model/decorators/domain/DecoratedFieldKind.d.ts +6 -0
  10. package/dist/model/decorators/domain/ManyToManyDecoratedSchema.d.ts +4 -0
  11. package/dist/model/decorators/domain/ModelRef.d.ts +2 -0
  12. package/dist/model/decorators/domain/RelationDecoratedSchema.d.ts +9 -0
  13. package/dist/model/decorators/domain/RelationDecoratorConfig.d.ts +35 -0
  14. package/dist/model/decorators/{types.d.ts → domain/TangoFieldMeta.d.ts} +6 -5
  15. package/dist/model/decorators/domain/ZodTypeAny.d.ts +2 -0
  16. package/dist/model/decorators/index.d.ts +5 -2
  17. package/dist/model/{internal → fields}/FieldMetadataStore.d.ts +2 -1
  18. package/dist/model/fields/FinalizedStorageArtifacts.d.ts +11 -0
  19. package/dist/model/{inferFields.d.ts → fields/inferFieldsFromSchema.d.ts} +7 -2
  20. package/dist/model/index.d.ts +12 -3
  21. package/dist/model/index.js +2 -2
  22. package/dist/model/internal/InternalSchemaModel.d.ts +31 -0
  23. package/dist/model/registry/ModelRegistry.d.ts +35 -2
  24. package/dist/model/registry/index.d.ts +4 -0
  25. package/dist/model/relations/NormalizedRelationStorageDescriptor.d.ts +36 -0
  26. package/dist/model/relations/RelationBuilder.d.ts +19 -0
  27. package/dist/model/relations/RelationDescriptorNormalizer.d.ts +30 -0
  28. package/dist/model/relations/RelationSpec.d.ts +48 -0
  29. package/dist/model/relations/ResolvedRelationGraph.d.ts +43 -0
  30. package/dist/model/relations/ResolvedRelationGraphBuilder.d.ts +48 -0
  31. package/dist/model/relations/SchemaNaming.d.ts +11 -0
  32. package/dist/model/relations/index.d.ts +13 -0
  33. package/dist/model-CJbsYdkM.js +1124 -0
  34. package/dist/model-CJbsYdkM.js.map +1 -0
  35. package/package.json +3 -2
  36. package/dist/model/RelationBuilder.d.ts +0 -12
  37. package/dist/model-DI8lQH1W.js +0 -585
  38. package/dist/model-DI8lQH1W.js.map +0 -1
@@ -0,0 +1,1124 @@
1
+ import { getLogger } from "@danceroutine/tango-core";
2
+ import { z } from "zod";
3
+ import { AsyncLocalStorage } from "node:async_hooks";
4
+
5
+ //#region rolldown:runtime
6
+ var __defProp = Object.defineProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all) __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
+ };
13
+
14
+ //#endregion
15
+ //#region src/model/fields/FieldMetadataStore.ts
16
+ const fieldMetadataStore = new WeakMap();
17
+ function getFieldMetadata(schema) {
18
+ return fieldMetadataStore.get(schema);
19
+ }
20
+ function setFieldMetadata(schema, meta) {
21
+ const existing = fieldMetadataStore.get(schema);
22
+ fieldMetadataStore.set(schema, {
23
+ ...existing,
24
+ ...meta
25
+ });
26
+ }
27
+
28
+ //#endregion
29
+ //#region src/model/decorators/domain/DecoratedFieldKind.ts
30
+ const INTERNAL_DECORATED_FIELD_KIND = {
31
+ FOREIGN_KEY: "foreignKey",
32
+ ONE_TO_ONE: "oneToOne",
33
+ MANY_TO_MANY: "manyToMany"
34
+ };
35
+
36
+ //#endregion
37
+ //#region src/model/decorators/Decorators.ts
38
+ function isZodType(value) {
39
+ return !!value && typeof value === "object" && "safeParse" in value && typeof value.safeParse === "function";
40
+ }
41
+ function decorate(schema, meta) {
42
+ setFieldMetadata(schema, meta);
43
+ return schema;
44
+ }
45
+ const warnedDecoratorKinds = new Set();
46
+ function warnDeprecatedSchemaOverload(kind, replacement) {
47
+ if (warnedDecoratorKinds.has(kind)) return;
48
+ warnedDecoratorKinds.add(kind);
49
+ getLogger("tango.schema.decorators").warn(`Deprecated positional schema overload used for t.${kind}(...). Prefer ${replacement} instead.`);
50
+ }
51
+ function maybeDecorator(schemaOrUndefined, meta) {
52
+ if (schemaOrUndefined) return decorate(schemaOrUndefined, meta);
53
+ return (schema) => decorate(schema, meta);
54
+ }
55
+ function primaryKey(schema) {
56
+ return maybeDecorator(schema, {
57
+ primaryKey: true,
58
+ notNull: true
59
+ });
60
+ }
61
+ function unique(schema) {
62
+ return maybeDecorator(schema, { unique: true });
63
+ }
64
+ function nullValue(schema) {
65
+ return maybeDecorator(schema, { notNull: false });
66
+ }
67
+ function notNull(schema) {
68
+ return maybeDecorator(schema, { notNull: true });
69
+ }
70
+ function defaultValue(schema, value) {
71
+ return decorate(schema, { default: value });
72
+ }
73
+ function dbDefault(schema, value) {
74
+ return decorate(schema, { dbDefault: value });
75
+ }
76
+ function dbColumn(schema, name) {
77
+ return decorate(schema, { dbColumn: name });
78
+ }
79
+ function dbIndex(schema) {
80
+ return decorate(schema, { dbIndex: true });
81
+ }
82
+ function choices(schema, values) {
83
+ return decorate(schema, { choices: values });
84
+ }
85
+ function validators(schema, ...values) {
86
+ return decorate(schema, { validators: values });
87
+ }
88
+ function helpText(schema, text) {
89
+ return decorate(schema, { helpText: text });
90
+ }
91
+ function errorMessages(schema, map) {
92
+ return decorate(schema, { errorMessages: map });
93
+ }
94
+ var FieldDecoratorBuilderImpl = class {
95
+ constructor(schema) {
96
+ this.schema = schema;
97
+ }
98
+ defaultValue(value) {
99
+ decorate(this.schema, { default: value });
100
+ return this;
101
+ }
102
+ dbDefault(value) {
103
+ decorate(this.schema, { dbDefault: value });
104
+ return this;
105
+ }
106
+ dbColumn(name) {
107
+ decorate(this.schema, { dbColumn: name });
108
+ return this;
109
+ }
110
+ dbIndex() {
111
+ decorate(this.schema, { dbIndex: true });
112
+ return this;
113
+ }
114
+ choices(values) {
115
+ decorate(this.schema, { choices: values });
116
+ return this;
117
+ }
118
+ validators(...values) {
119
+ decorate(this.schema, { validators: values });
120
+ return this;
121
+ }
122
+ helpText(text) {
123
+ decorate(this.schema, { helpText: text });
124
+ return this;
125
+ }
126
+ errorMessages(map) {
127
+ decorate(this.schema, { errorMessages: map });
128
+ return this;
129
+ }
130
+ build() {
131
+ return this.schema;
132
+ }
133
+ };
134
+ function field(schema) {
135
+ return new FieldDecoratorBuilderImpl(schema);
136
+ }
137
+ function applyRelationMetadata(schema, meta, config) {
138
+ return decorate(schema, {
139
+ ...meta,
140
+ forwardName: config?.name,
141
+ reverseName: config?.relatedName
142
+ });
143
+ }
144
+ function toReferentialOptions(config) {
145
+ if (!config) return undefined;
146
+ if (config.column === undefined && config.onDelete === undefined && config.onUpdate === undefined) return undefined;
147
+ return {
148
+ column: config.column,
149
+ onDelete: config.onDelete,
150
+ onUpdate: config.onUpdate
151
+ };
152
+ }
153
+ function foreignKey(target, schemaOrOptions, maybeOptions) {
154
+ if (isZodType(schemaOrOptions)) {
155
+ warnDeprecatedSchemaOverload(INTERNAL_DECORATED_FIELD_KIND.FOREIGN_KEY, "t.foreignKey(target, { field: schema, ...options })");
156
+ return applyRelationMetadata(schemaOrOptions, {
157
+ relationKind: INTERNAL_DECORATED_FIELD_KIND.FOREIGN_KEY,
158
+ references: {
159
+ target,
160
+ options: maybeOptions
161
+ }
162
+ });
163
+ }
164
+ const config = schemaOrOptions;
165
+ const schema = config?.field ?? z.number().int();
166
+ return applyRelationMetadata(schema, {
167
+ relationKind: INTERNAL_DECORATED_FIELD_KIND.FOREIGN_KEY,
168
+ references: {
169
+ target,
170
+ options: toReferentialOptions(config)
171
+ },
172
+ notNull: config?.field ? undefined : true
173
+ }, config);
174
+ }
175
+ function oneToOne(target, schemaOrOptions, maybeOptions) {
176
+ if (isZodType(schemaOrOptions)) {
177
+ warnDeprecatedSchemaOverload(INTERNAL_DECORATED_FIELD_KIND.ONE_TO_ONE, "t.oneToOne(target, { field: schema, ...options })");
178
+ return applyRelationMetadata(schemaOrOptions, {
179
+ relationKind: INTERNAL_DECORATED_FIELD_KIND.ONE_TO_ONE,
180
+ unique: true,
181
+ references: {
182
+ target,
183
+ options: maybeOptions
184
+ }
185
+ });
186
+ }
187
+ const config = schemaOrOptions;
188
+ const schema = config?.field ?? z.number().int();
189
+ return applyRelationMetadata(schema, {
190
+ relationKind: INTERNAL_DECORATED_FIELD_KIND.ONE_TO_ONE,
191
+ unique: true,
192
+ references: {
193
+ target,
194
+ options: toReferentialOptions(config)
195
+ },
196
+ notNull: config?.field ? undefined : true
197
+ }, config);
198
+ }
199
+ function manyToMany(target, schemaOrConfig) {
200
+ if (isZodType(schemaOrConfig)) {
201
+ warnDeprecatedSchemaOverload(INTERNAL_DECORATED_FIELD_KIND.MANY_TO_MANY, "t.manyToMany(target, { field: schema, name })");
202
+ return applyRelationMetadata(schemaOrConfig, {
203
+ relationKind: INTERNAL_DECORATED_FIELD_KIND.MANY_TO_MANY,
204
+ references: { target }
205
+ });
206
+ }
207
+ if (schemaOrConfig?.relatedName !== undefined) throw new Error("t.manyToMany(...) does not support relatedName yet.");
208
+ const config = schemaOrConfig;
209
+ const schema = config?.field ?? z.array(z.number().int());
210
+ return applyRelationMetadata(schema, {
211
+ relationKind: INTERNAL_DECORATED_FIELD_KIND.MANY_TO_MANY,
212
+ references: { target }
213
+ }, config);
214
+ }
215
+ const Decorators = {
216
+ field,
217
+ primaryKey,
218
+ unique,
219
+ null: nullValue,
220
+ notNull,
221
+ default: defaultValue,
222
+ dbDefault,
223
+ dbColumn,
224
+ dbIndex,
225
+ choices,
226
+ validators,
227
+ helpText,
228
+ errorMessages,
229
+ foreignKey,
230
+ oneToOne,
231
+ manyToMany
232
+ };
233
+
234
+ //#endregion
235
+ //#region src/model/decorators/index.ts
236
+ var decorators_exports = {};
237
+ __export(decorators_exports, {
238
+ Decorators: () => Decorators,
239
+ t: () => Decorators
240
+ });
241
+
242
+ //#endregion
243
+ //#region src/model/meta/Meta.ts
244
+ const Meta = {
245
+ ordering(...fields) {
246
+ return { ordering: fields };
247
+ },
248
+ managed(value) {
249
+ return { managed: value };
250
+ },
251
+ defaultRelatedName(value) {
252
+ return { defaultRelatedName: value };
253
+ },
254
+ indexes(...indexes) {
255
+ return { indexes };
256
+ },
257
+ constraints(...constraints) {
258
+ return { constraints };
259
+ },
260
+ uniqueTogether(...sets) {
261
+ return { constraints: sets.map((fields) => ({
262
+ kind: "uniqueTogether",
263
+ fields
264
+ })) };
265
+ },
266
+ indexTogether(...sets) {
267
+ return { indexes: sets.map((on, index) => ({
268
+ name: `idx_${on.join("_")}_${index}`,
269
+ on
270
+ })) };
271
+ },
272
+ merge(...fragments) {
273
+ return fragments.reduce((acc, fragment) => ({
274
+ ordering: fragment.ordering ?? acc.ordering,
275
+ managed: fragment.managed ?? acc.managed,
276
+ defaultRelatedName: fragment.defaultRelatedName ?? acc.defaultRelatedName,
277
+ indexes: [...acc.indexes ?? [], ...fragment.indexes ?? []],
278
+ constraints: [...acc.constraints ?? [], ...fragment.constraints ?? []]
279
+ }), {});
280
+ }
281
+ };
282
+
283
+ //#endregion
284
+ //#region src/model/meta/index.ts
285
+ var meta_exports = {};
286
+ __export(meta_exports, {
287
+ Meta: () => Meta,
288
+ m: () => Meta
289
+ });
290
+
291
+ //#endregion
292
+ //#region src/model/constraints/Constraints.ts
293
+ const Constraints = {
294
+ unique(fields, options) {
295
+ return {
296
+ kind: "unique",
297
+ fields,
298
+ ...options
299
+ };
300
+ },
301
+ check(condition, options) {
302
+ return {
303
+ kind: "check",
304
+ condition,
305
+ ...options
306
+ };
307
+ },
308
+ exclusion(definition) {
309
+ return {
310
+ kind: "exclusion",
311
+ ...definition
312
+ };
313
+ }
314
+ };
315
+
316
+ //#endregion
317
+ //#region src/model/constraints/Indexes.ts
318
+ const Indexes = { index(on, options) {
319
+ const suffix = on.join("_");
320
+ return {
321
+ name: options?.name ?? `idx_${suffix}`,
322
+ on,
323
+ unique: options?.unique,
324
+ where: options?.where
325
+ };
326
+ } };
327
+
328
+ //#endregion
329
+ //#region src/model/constraints/index.ts
330
+ var constraints_exports = {};
331
+ __export(constraints_exports, {
332
+ Constraints: () => Constraints,
333
+ Indexes: () => Indexes,
334
+ c: () => Constraints,
335
+ i: () => Indexes
336
+ });
337
+
338
+ //#endregion
339
+ //#region src/domain/internal/InternalFieldType.ts
340
+ const InternalFieldType = {
341
+ SERIAL: "serial",
342
+ INT: "int",
343
+ BIGINT: "bigint",
344
+ TEXT: "text",
345
+ BOOL: "bool",
346
+ TIMESTAMPTZ: "timestamptz",
347
+ JSONB: "jsonb",
348
+ UUID: "uuid"
349
+ };
350
+
351
+ //#endregion
352
+ //#region src/domain/internal/zod/isDate.ts
353
+ function isDate(value) {
354
+ return value !== null && value !== undefined && Object.prototype.toString.call(value) === "[object Date]";
355
+ }
356
+
357
+ //#endregion
358
+ //#region src/domain/internal/zod/hasConstructorName.ts
359
+ function hasConstructorName(value, name) {
360
+ return !!value && typeof value === "object" && value.constructor?.name === name;
361
+ }
362
+
363
+ //#endregion
364
+ //#region src/domain/internal/zod/isZodArray.ts
365
+ function isZodArray(value) {
366
+ return hasConstructorName(value, "ZodArray");
367
+ }
368
+
369
+ //#endregion
370
+ //#region src/domain/internal/zod/isZodBoolean.ts
371
+ function isZodBoolean(value) {
372
+ return hasConstructorName(value, "ZodBoolean");
373
+ }
374
+
375
+ //#endregion
376
+ //#region src/domain/internal/zod/isZodDate.ts
377
+ function isZodDate(value) {
378
+ return hasConstructorName(value, "ZodDate");
379
+ }
380
+
381
+ //#endregion
382
+ //#region src/domain/internal/zod/isZodDefault.ts
383
+ function isZodDefault(value) {
384
+ return hasConstructorName(value, "ZodDefault");
385
+ }
386
+
387
+ //#endregion
388
+ //#region src/domain/internal/zod/isZodNullable.ts
389
+ function isZodNullable(value) {
390
+ return hasConstructorName(value, "ZodNullable");
391
+ }
392
+
393
+ //#endregion
394
+ //#region src/domain/internal/zod/isZodNumber.ts
395
+ function isZodNumber(value) {
396
+ return hasConstructorName(value, "ZodNumber");
397
+ }
398
+
399
+ //#endregion
400
+ //#region src/domain/internal/zod/isZodObject.ts
401
+ function isZodObject(value) {
402
+ return hasConstructorName(value, "ZodObject");
403
+ }
404
+
405
+ //#endregion
406
+ //#region src/domain/internal/zod/isZodOptional.ts
407
+ function isZodOptional(value) {
408
+ return hasConstructorName(value, "ZodOptional");
409
+ }
410
+
411
+ //#endregion
412
+ //#region src/domain/internal/zod/isZodString.ts
413
+ function isZodString(value) {
414
+ return hasConstructorName(value, "ZodString");
415
+ }
416
+
417
+ //#endregion
418
+ //#region src/model/fields/inferFieldsFromSchema.ts
419
+ /**
420
+ * Infer one storage field from a Zod schema member plus any Tango decorator metadata.
421
+ *
422
+ * The registry and optional target resolver are used only when the field carries
423
+ * reference metadata that must be translated into concrete table/primary-key names.
424
+ */
425
+ function inferField(name, zodType, meta, registry, resolveReferenceTarget) {
426
+ let type;
427
+ let notNull$1 = true;
428
+ let defaultValue$1 = undefined;
429
+ let unwrapped = zodType;
430
+ if (isZodOptional(unwrapped)) {
431
+ notNull$1 = false;
432
+ unwrapped = unwrapped.unwrap();
433
+ }
434
+ if (isZodNullable(unwrapped)) {
435
+ notNull$1 = false;
436
+ unwrapped = unwrapped.unwrap();
437
+ }
438
+ if (isZodDefault(unwrapped)) {
439
+ const def = unwrapped._zod.def.defaultValue;
440
+ if (isDate(def)) defaultValue$1 = { now: true };
441
+ else if (typeof def === "string" || typeof def === "number") defaultValue$1 = String(def);
442
+ unwrapped = unwrapped.removeDefault();
443
+ }
444
+ if (isZodString(unwrapped)) type = InternalFieldType.TEXT;
445
+ else if (isZodNumber(unwrapped)) {
446
+ const checks = unwrapped._zod.def.checks ?? [];
447
+ const isInt = checks.some((c) => "format" in c._zod.def && c._zod.def.format === "safeint");
448
+ type = isInt ? InternalFieldType.INT : InternalFieldType.BIGINT;
449
+ } else if (isZodBoolean(unwrapped)) type = InternalFieldType.BOOL;
450
+ else if (isZodDate(unwrapped)) type = InternalFieldType.TIMESTAMPTZ;
451
+ else if (isZodObject(unwrapped) || isZodArray(unwrapped)) type = InternalFieldType.JSONB;
452
+ else return null;
453
+ const field$1 = {
454
+ name,
455
+ type,
456
+ notNull: notNull$1,
457
+ default: defaultValue$1
458
+ };
459
+ if (!meta) return field$1;
460
+ if (meta.dbColumn) field$1.name = meta.dbColumn;
461
+ if (typeof meta.notNull === "boolean") field$1.notNull = meta.notNull;
462
+ if (meta.default !== undefined) field$1.default = meta.default;
463
+ if (meta.primaryKey) field$1.primaryKey = true;
464
+ if (meta.unique) field$1.unique = true;
465
+ if (meta.relationKind === INTERNAL_DECORATED_FIELD_KIND.MANY_TO_MANY) return null;
466
+ if (meta.references) {
467
+ const targetMetadata = resolveReferenceTarget ? resolveReferenceTarget(meta.references.target) : resolveReferenceTargetFromRegistry(meta.references.target, registry, meta.references.options?.column);
468
+ field$1.references = {
469
+ table: targetMetadata.table,
470
+ column: meta.references.options?.column ?? targetMetadata.pk,
471
+ onDelete: meta.references.options?.onDelete,
472
+ onUpdate: meta.references.options?.onUpdate
473
+ };
474
+ }
475
+ return field$1;
476
+ }
477
+ function resolveReferenceTargetFromRegistry(target, registry, explicitColumn) {
478
+ const targetModel = registry.resolveRef(target);
479
+ const primaryKey$1 = explicitColumn ?? targetModel.metadata.fields.find((candidate) => candidate.primaryKey)?.name ?? "id";
480
+ return {
481
+ table: targetModel.metadata.table,
482
+ pk: primaryKey$1
483
+ };
484
+ }
485
+ function inferFieldsFromSchema(schema, options) {
486
+ const registry = options?.registry ?? ModelRegistry.global();
487
+ const shape = schema.shape;
488
+ const fields = [];
489
+ for (const [name, zodType] of Object.entries(shape)) {
490
+ const field$1 = inferField(name, zodType, getFieldMetadata(zodType), registry, options?.resolveReferenceTarget);
491
+ if (field$1) fields.push(field$1);
492
+ }
493
+ return fields;
494
+ }
495
+
496
+ //#endregion
497
+ //#region src/domain/internal/InternalRelationType.ts
498
+ const InternalRelationType = {
499
+ HAS_MANY: "hasMany",
500
+ BELONGS_TO: "belongsTo",
501
+ HAS_ONE: "hasOne"
502
+ };
503
+
504
+ //#endregion
505
+ //#region src/model/relations/RelationBuilder.ts
506
+ var RelationBuilder = class {
507
+ /** Declare a one-to-many relation from this model to `target`. */
508
+ hasMany(target, foreignKey$1) {
509
+ return {
510
+ type: InternalRelationType.HAS_MANY,
511
+ target,
512
+ foreignKey: foreignKey$1
513
+ };
514
+ }
515
+ /** Declare an owning relation to a parent model. */
516
+ belongsTo(target, foreignKey$1, localKey) {
517
+ return {
518
+ type: InternalRelationType.BELONGS_TO,
519
+ target,
520
+ foreignKey: foreignKey$1,
521
+ localKey
522
+ };
523
+ }
524
+ /** Declare a one-to-one relation from this model to `target`. */
525
+ hasOne(target, foreignKey$1) {
526
+ return {
527
+ type: InternalRelationType.HAS_ONE,
528
+ target,
529
+ foreignKey: foreignKey$1
530
+ };
531
+ }
532
+ };
533
+
534
+ //#endregion
535
+ //#region src/model/relations/RelationDescriptorNormalizer.ts
536
+ var RelationDescriptorNormalizer = class RelationDescriptorNormalizer {
537
+ constructor(sourceModelKey, schema) {
538
+ this.sourceModelKey = sourceModelKey;
539
+ this.schema = schema;
540
+ }
541
+ static normalize(sourceModelKey, schema) {
542
+ return new RelationDescriptorNormalizer(sourceModelKey, schema).normalize();
543
+ }
544
+ /**
545
+ * Run the field-authored relation normalization pipeline for one model
546
+ * schema and emit descriptors that later relation stages can resolve.
547
+ */
548
+ normalize() {
549
+ const descriptors = [];
550
+ for (const candidate of this.collectRelationCandidates()) {
551
+ const descriptor = this.normalizeCandidate(candidate);
552
+ if (descriptor) descriptors.push(descriptor);
553
+ }
554
+ return descriptors;
555
+ }
556
+ collectRelationCandidates() {
557
+ return Object.entries(this.schema.shape).map(([sourceSchemaFieldKey, zodType]) => ({
558
+ sourceSchemaFieldKey,
559
+ zodType
560
+ }));
561
+ }
562
+ normalizeCandidate(candidate) {
563
+ const meta = getFieldMetadata(candidate.zodType);
564
+ if (!meta?.references || !meta.relationKind) return undefined;
565
+ return {
566
+ edgeId: this.buildEdgeId(candidate.sourceSchemaFieldKey, meta.relationKind),
567
+ sourceModelKey: this.sourceModelKey,
568
+ sourceSchemaFieldKey: candidate.sourceSchemaFieldKey,
569
+ targetRef: meta.references.target,
570
+ origin: meta.relationKind,
571
+ localFieldName: candidate.sourceSchemaFieldKey,
572
+ dbColumnName: meta.dbColumn ?? candidate.sourceSchemaFieldKey,
573
+ referencedTargetColumn: meta.references.options?.column,
574
+ onDelete: meta.references.options?.onDelete,
575
+ onUpdate: meta.references.options?.onUpdate,
576
+ unique: meta.unique || meta.relationKind === INTERNAL_DECORATED_FIELD_KIND.ONE_TO_ONE,
577
+ explicitForwardName: meta.forwardName,
578
+ explicitReverseName: meta.reverseName,
579
+ namingHint: this.deriveNamingHint(candidate.sourceSchemaFieldKey),
580
+ provenance: "field-decorator"
581
+ };
582
+ }
583
+ buildEdgeId(sourceSchemaFieldKey, origin) {
584
+ return `${this.sourceModelKey}:${sourceSchemaFieldKey}:${origin}`;
585
+ }
586
+ deriveNamingHint(fieldKey) {
587
+ if (fieldKey.endsWith("Id") && fieldKey.length > 2) return fieldKey.slice(0, -2);
588
+ if (fieldKey.endsWith("_id") && fieldKey.length > 3) return fieldKey.slice(0, -3);
589
+ return fieldKey;
590
+ }
591
+ };
592
+
593
+ //#endregion
594
+ //#region src/model/relations/SchemaNaming.ts
595
+ function toSnakeCase(value) {
596
+ return value.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[\s-]+/g, "_").toLowerCase();
597
+ }
598
+ function pluralize(value) {
599
+ if (/(s|x|z|ch|sh)$/.test(value)) return `${value}es`;
600
+ if (/[^aeiou]y$/.test(value)) return `${value.slice(0, -1)}ies`;
601
+ return `${value}s`;
602
+ }
603
+ function deriveTableName(name) {
604
+ return pluralize(toSnakeCase(name));
605
+ }
606
+
607
+ //#endregion
608
+ //#region src/model/internal/InternalSchemaModel.ts
609
+ var InternalSchemaModel = class InternalSchemaModel {
610
+ static BRAND = "tango.schema.internal_schema_model";
611
+ __tangoBrand = InternalSchemaModel.BRAND;
612
+ metadata;
613
+ schema;
614
+ hooks;
615
+ registry;
616
+ normalizedRelations;
617
+ explicitFields;
618
+ explicitRelations;
619
+ constructor(registry, metadata, schema, hooks, normalizedRelations, explicitFields, explicitRelations) {
620
+ this.registry = registry;
621
+ this.metadata = metadata;
622
+ this.schema = schema;
623
+ this.hooks = hooks;
624
+ this.normalizedRelations = Object.freeze([...normalizedRelations]);
625
+ this.explicitFields = explicitFields ? Object.freeze([...explicitFields]) : undefined;
626
+ this.explicitRelations = explicitRelations;
627
+ }
628
+ static create(definition, registry) {
629
+ InternalSchemaModel.validateDefinition(definition);
630
+ const builder = new RelationBuilder();
631
+ const relations = definition.relations ? Object.freeze(definition.relations(builder)) : undefined;
632
+ const key = `${definition.namespace}/${definition.name}`;
633
+ const table = definition.table?.trim() || deriveTableName(definition.name);
634
+ const normalizedRelations = RelationDescriptorNormalizer.normalize(key, definition.schema);
635
+ const metadata = {
636
+ namespace: definition.namespace,
637
+ name: definition.name,
638
+ key,
639
+ table,
640
+ fields: [],
641
+ indexes: definition.indexes,
642
+ relations,
643
+ ordering: definition.ordering,
644
+ managed: definition.managed,
645
+ defaultRelatedName: definition.defaultRelatedName,
646
+ constraints: definition.constraints
647
+ };
648
+ Object.defineProperty(metadata, "fields", {
649
+ enumerable: true,
650
+ configurable: false,
651
+ get: () => registry.getFinalizedFields(key)
652
+ });
653
+ Object.freeze(metadata);
654
+ return new InternalSchemaModel(registry, metadata, definition.schema, definition.hooks, normalizedRelations, definition.fields, relations);
655
+ }
656
+ static isInternalSchemaModel(value) {
657
+ return typeof value === "object" && value !== null && value.__tangoBrand === InternalSchemaModel.BRAND;
658
+ }
659
+ static getRegistryOwner(model) {
660
+ return InternalSchemaModel.require(model).registry;
661
+ }
662
+ static getNormalizedRelations(model) {
663
+ return InternalSchemaModel.require(model).normalizedRelations;
664
+ }
665
+ static getExplicitFields(model) {
666
+ return InternalSchemaModel.require(model).explicitFields;
667
+ }
668
+ static getExplicitRelations(model) {
669
+ return InternalSchemaModel.require(model).explicitRelations;
670
+ }
671
+ static validateDefinition(definition) {
672
+ if (!definition.namespace.trim()) throw new Error("Model.namespace is required and cannot be empty.");
673
+ if (!definition.name.trim()) throw new Error("Model.name is required and cannot be empty.");
674
+ if (definition.table !== undefined && !definition.table.trim()) throw new Error("Model.table cannot be empty when provided.");
675
+ }
676
+ static require(model) {
677
+ if (!InternalSchemaModel.isInternalSchemaModel(model)) throw new Error(`Model '${model.metadata.key}' is missing internal registry ownership metadata.`);
678
+ return model;
679
+ }
680
+ };
681
+
682
+ //#endregion
683
+ //#region src/model/relations/RelationSpec.ts
684
+ const INTERNAL_RELATION_PUBLIC_KIND = {
685
+ BELONGS_TO: "belongsTo",
686
+ HAS_ONE: "hasOne",
687
+ HAS_MANY: "hasMany",
688
+ MANY_TO_MANY: "manyToMany"
689
+ };
690
+ const INTERNAL_RELATION_STORAGE_STRATEGY = {
691
+ REFERENCE: "reference",
692
+ REVERSE_REFERENCE: "reverse_reference",
693
+ MANY_TO_MANY: "many_to_many"
694
+ };
695
+ const INTERNAL_RELATION_CARDINALITY = {
696
+ SINGLE: "single",
697
+ MANY: "many"
698
+ };
699
+ const INTERNAL_RELATION_PROVENANCE = {
700
+ FIELD_DECORATOR: "field-decorator",
701
+ RELATIONS_API: "relations-api",
702
+ SYNTHESIZED_REVERSE: "synthesized-reverse"
703
+ };
704
+
705
+ //#endregion
706
+ //#region src/model/relations/ResolvedRelationGraphBuilder.ts
707
+ const REFERENCE_CAPABILITIES = Object.freeze({
708
+ migratable: true,
709
+ queryable: true,
710
+ hydratable: true
711
+ });
712
+ const MANY_TO_MANY_CAPABILITIES = Object.freeze({
713
+ migratable: false,
714
+ queryable: false,
715
+ hydratable: false
716
+ });
717
+ const RELATION_NAME_SEPARATOR = ":";
718
+ var ResolvedRelationGraphBuilder = class ResolvedRelationGraphBuilder {
719
+ byModel = new Map();
720
+ byEdgeId = new Map();
721
+ matchedOverrides = new Set();
722
+ constructor(options) {
723
+ this.options = options;
724
+ }
725
+ static build(options) {
726
+ return new ResolvedRelationGraphBuilder(options).build();
727
+ }
728
+ /**
729
+ * Resolve every model's normalized relation descriptors into a single
730
+ * registry-scoped graph and fail when authoring ambiguity remains.
731
+ */
732
+ build() {
733
+ for (const model of this.options.models) this.addModelRelations(model);
734
+ for (const model of this.options.models) this.assertAllOverridesMatched(model);
735
+ return {
736
+ version: this.options.version,
737
+ byModel: this.byModel,
738
+ byEdgeId: this.byEdgeId
739
+ };
740
+ }
741
+ addModelRelations(model) {
742
+ const explicitRelations = InternalSchemaModel.getExplicitRelations(model) ?? {};
743
+ for (const descriptor of InternalSchemaModel.getNormalizedRelations(model)) {
744
+ const targetModel = this.options.resolveRef(descriptor.targetRef);
745
+ if (descriptor.origin === "manyToMany") {
746
+ const relationName = descriptor.explicitForwardName ?? descriptor.namingHint;
747
+ this.addResolvedRelation({
748
+ edgeId: descriptor.edgeId,
749
+ sourceModelKey: model.metadata.key,
750
+ targetModelKey: targetModel.metadata.key,
751
+ name: relationName,
752
+ kind: INTERNAL_RELATION_PUBLIC_KIND.MANY_TO_MANY,
753
+ storageStrategy: INTERNAL_RELATION_STORAGE_STRATEGY.MANY_TO_MANY,
754
+ cardinality: INTERNAL_RELATION_CARDINALITY.MANY,
755
+ capabilities: MANY_TO_MANY_CAPABILITIES,
756
+ provenance: INTERNAL_RELATION_PROVENANCE.FIELD_DECORATOR,
757
+ alias: `${toSnakeCase(model.metadata.name)}_${relationName}`
758
+ });
759
+ continue;
760
+ }
761
+ this.addReferenceRelations(model, descriptor, targetModel, explicitRelations);
762
+ }
763
+ }
764
+ addReferenceRelations(sourceModel, descriptor, targetModel, explicitRelations) {
765
+ const forwardOverride = this.findForwardOverride(sourceModel, targetModel, descriptor, explicitRelations);
766
+ if (forwardOverride) this.markOverrideMatched(sourceModel.metadata.key, forwardOverride[0]);
767
+ const forwardName = forwardOverride?.[0] ?? descriptor.explicitForwardName ?? descriptor.namingHint;
768
+ const targetPrimaryKey = this.getPrimaryKey(targetModel.metadata.key);
769
+ this.addResolvedRelation({
770
+ edgeId: descriptor.edgeId,
771
+ sourceModelKey: sourceModel.metadata.key,
772
+ targetModelKey: targetModel.metadata.key,
773
+ name: forwardName,
774
+ inverseEdgeId: `${descriptor.edgeId}:inverse`,
775
+ kind: INTERNAL_RELATION_PUBLIC_KIND.BELONGS_TO,
776
+ storageStrategy: INTERNAL_RELATION_STORAGE_STRATEGY.REFERENCE,
777
+ cardinality: INTERNAL_RELATION_CARDINALITY.SINGLE,
778
+ localFieldName: descriptor.dbColumnName,
779
+ targetFieldName: descriptor.referencedTargetColumn ?? targetPrimaryKey,
780
+ capabilities: REFERENCE_CAPABILITIES,
781
+ provenance: INTERNAL_RELATION_PROVENANCE.FIELD_DECORATOR,
782
+ alias: `${toSnakeCase(targetModel.metadata.name)}_${forwardName}`
783
+ });
784
+ const reverseOverride = this.findReverseOverride(sourceModel, targetModel, descriptor);
785
+ if (reverseOverride) this.markOverrideMatched(targetModel.metadata.key, reverseOverride[0]);
786
+ const reverseKind = descriptor.unique ? INTERNAL_RELATION_PUBLIC_KIND.HAS_ONE : INTERNAL_RELATION_PUBLIC_KIND.HAS_MANY;
787
+ const reverseCardinality = descriptor.unique ? INTERNAL_RELATION_CARDINALITY.SINGLE : INTERNAL_RELATION_CARDINALITY.MANY;
788
+ const reverseName = reverseOverride?.[0] ?? descriptor.explicitReverseName ?? this.deriveReverseName(sourceModel, reverseCardinality);
789
+ this.addResolvedRelation({
790
+ edgeId: `${descriptor.edgeId}:inverse`,
791
+ sourceModelKey: targetModel.metadata.key,
792
+ targetModelKey: sourceModel.metadata.key,
793
+ name: reverseName,
794
+ inverseEdgeId: descriptor.edgeId,
795
+ kind: reverseKind,
796
+ storageStrategy: INTERNAL_RELATION_STORAGE_STRATEGY.REVERSE_REFERENCE,
797
+ cardinality: reverseCardinality,
798
+ localFieldName: descriptor.dbColumnName,
799
+ targetFieldName: descriptor.referencedTargetColumn ?? targetPrimaryKey,
800
+ capabilities: REFERENCE_CAPABILITIES,
801
+ provenance: reverseOverride ? INTERNAL_RELATION_PROVENANCE.RELATIONS_API : INTERNAL_RELATION_PROVENANCE.SYNTHESIZED_REVERSE,
802
+ alias: `${toSnakeCase(sourceModel.metadata.name)}_${reverseName}`
803
+ });
804
+ }
805
+ findForwardOverride(sourceModel, targetModel, descriptor, explicitRelations) {
806
+ return Object.entries(explicitRelations).find(([, relation]) => {
807
+ const relationTargetKey = this.resolveRelationTargetKey(sourceModel, relation.target);
808
+ return relation.type === INTERNAL_RELATION_PUBLIC_KIND.BELONGS_TO && relationTargetKey === targetModel.metadata.key && relation.foreignKey === descriptor.sourceSchemaFieldKey;
809
+ });
810
+ }
811
+ findReverseOverride(sourceModel, targetModel, descriptor) {
812
+ const reverseModelRelations = InternalSchemaModel.getExplicitRelations(targetModel) ?? {};
813
+ const reverseKind = descriptor.unique ? INTERNAL_RELATION_PUBLIC_KIND.HAS_ONE : INTERNAL_RELATION_PUBLIC_KIND.HAS_MANY;
814
+ return Object.entries(reverseModelRelations).find(([, relation]) => {
815
+ const relationTargetKey = this.resolveRelationTargetKey(targetModel, relation.target);
816
+ return relationTargetKey === sourceModel.metadata.key && relation.type === reverseKind && relation.foreignKey === descriptor.sourceSchemaFieldKey;
817
+ });
818
+ }
819
+ assertAllOverridesMatched(model) {
820
+ const explicitRelations = InternalSchemaModel.getExplicitRelations(model);
821
+ if (!explicitRelations) return;
822
+ for (const relationName of Object.keys(explicitRelations)) {
823
+ const marker = this.buildOverrideMarker(model.metadata.key, relationName);
824
+ if (!this.matchedOverrides.has(marker)) throw new Error(`Relation override '${relationName}' on model '${model.metadata.key}' does not match a field-authored relation.`);
825
+ }
826
+ }
827
+ addResolvedRelation(descriptor) {
828
+ const modelRelations = this.byModel.get(descriptor.sourceModelKey) ?? new Map();
829
+ const existing = modelRelations.get(descriptor.name);
830
+ if (existing) throw new Error(`Ambiguous relation name '${descriptor.name}' on model '${descriptor.sourceModelKey}'. Add an explicit relations override.`);
831
+ modelRelations.set(descriptor.name, descriptor);
832
+ this.byModel.set(descriptor.sourceModelKey, modelRelations);
833
+ this.byEdgeId.set(descriptor.edgeId, descriptor);
834
+ }
835
+ getPrimaryKey(modelKey) {
836
+ return this.options.storage.byModel.get(modelKey).pk;
837
+ }
838
+ markOverrideMatched(modelKey, relationName) {
839
+ this.matchedOverrides.add(this.buildOverrideMarker(modelKey, relationName));
840
+ }
841
+ buildOverrideMarker(modelKey, relationName) {
842
+ return `${modelKey}${RELATION_NAME_SEPARATOR}${relationName}`;
843
+ }
844
+ resolveRelationTargetKey(sourceModel, target) {
845
+ if (target.includes("/")) return target;
846
+ return `${sourceModel.metadata.namespace}/${target}`;
847
+ }
848
+ deriveReverseName(sourceModel, cardinality) {
849
+ if (sourceModel.metadata.defaultRelatedName) return sourceModel.metadata.defaultRelatedName;
850
+ const snake = toSnakeCase(sourceModel.metadata.name);
851
+ return cardinality === INTERNAL_RELATION_CARDINALITY.MANY ? pluralize(snake) : snake;
852
+ }
853
+ };
854
+
855
+ //#endregion
856
+ //#region src/model/registry/ModelRegistry.ts
857
+ const DEFAULT_IDENTIFIER_NAME = "id";
858
+ const activeRegistryStorage = new AsyncLocalStorage();
859
+ var ModelRegistry = class ModelRegistry {
860
+ static globalRegistry;
861
+ models = new Map();
862
+ version = 0;
863
+ storageCache;
864
+ relationGraphCache;
865
+ /**
866
+ * Return the shared process-wide registry used by `Model(...)`.
867
+ */
868
+ static global() {
869
+ if (!ModelRegistry.globalRegistry) ModelRegistry.globalRegistry = new ModelRegistry();
870
+ return ModelRegistry.globalRegistry;
871
+ }
872
+ /**
873
+ * Return the registry currently bound to model construction work.
874
+ */
875
+ static active() {
876
+ return activeRegistryStorage.getStore() ?? ModelRegistry.global();
877
+ }
878
+ /**
879
+ * Run work with a specific registry bound as the active construction target.
880
+ */
881
+ static async runWithRegistry(registry, work) {
882
+ return await activeRegistryStorage.run(registry, work);
883
+ }
884
+ /**
885
+ * Register a model on the shared global registry.
886
+ */
887
+ static register(model) {
888
+ ModelRegistry.global().register(model);
889
+ }
890
+ /**
891
+ * Register several models on the shared global registry.
892
+ */
893
+ static registerMany(models) {
894
+ ModelRegistry.global().registerMany(models);
895
+ }
896
+ /**
897
+ * Resolve a model from the shared registry by namespace and name.
898
+ */
899
+ static get(namespace, name) {
900
+ return ModelRegistry.global().get(namespace, name);
901
+ }
902
+ /**
903
+ * Resolve a model from the shared registry by its `namespace/name` key.
904
+ */
905
+ static getByKey(key) {
906
+ return ModelRegistry.global().getByKey(key);
907
+ }
908
+ /**
909
+ * Resolve any supported model reference form against the shared registry.
910
+ */
911
+ static resolveRef(ref) {
912
+ return ModelRegistry.global().resolveRef(ref);
913
+ }
914
+ /**
915
+ * Clear the shared registry, which is mainly useful in tests.
916
+ */
917
+ static clear() {
918
+ ModelRegistry.global().clear();
919
+ }
920
+ /**
921
+ * Return the owning registry for a model.
922
+ */
923
+ static getOwner(model) {
924
+ return InternalSchemaModel.getRegistryOwner(model);
925
+ }
926
+ /**
927
+ * Register a model on this registry instance.
928
+ */
929
+ register(model) {
930
+ const owner = InternalSchemaModel.getRegistryOwner(model);
931
+ if (owner !== this) throw new Error(`Model '${model.metadata.key}' belongs to a different registry and cannot be registered here.`);
932
+ const existing = this.models.get(model.metadata.key);
933
+ if (existing && existing !== model) throw new Error(`Model '${model.metadata.key}' is already registered in this registry.`);
934
+ this.models.set(model.metadata.key, model);
935
+ this.bumpVersion();
936
+ }
937
+ /**
938
+ * Register several models on this registry instance.
939
+ */
940
+ registerMany(models) {
941
+ for (const model of models) this.register(model);
942
+ }
943
+ /**
944
+ * Resolve a model from this registry instance by namespace and name.
945
+ */
946
+ get(namespace, name) {
947
+ return this.getByKey(`${namespace}/${name}`);
948
+ }
949
+ /**
950
+ * Resolve a model from this registry instance by its `namespace/name` key.
951
+ */
952
+ getByKey(key) {
953
+ return this.models.get(key);
954
+ }
955
+ /**
956
+ * Resolve a string, callback, or direct model reference into a model object.
957
+ */
958
+ resolveRef(ref) {
959
+ if (typeof ref === "string") {
960
+ const model$1 = this.getByKey(ref);
961
+ if (!model$1) throw new Error(`Unable to resolve model reference '${ref}'. Ensure it is registered in ModelRegistry.`);
962
+ return model$1;
963
+ }
964
+ const model = typeof ref === "function" ? ref() : ref;
965
+ if (InternalSchemaModel.getRegistryOwner(model) !== this) throw new Error(`Model reference '${model.metadata.key}' belongs to a different registry and cannot be resolved here.`);
966
+ return model;
967
+ }
968
+ /**
969
+ * Finalize storage-only artifacts for all models in this registry.
970
+ */
971
+ finalizeStorageArtifacts() {
972
+ if (this.storageCache?.version === this.version) return this.storageCache;
973
+ const primaryKeyByModel = new Map();
974
+ for (const model of this.models.values()) primaryKeyByModel.set(model.metadata.key, this.inferPrimaryKeyName(model));
975
+ const byModel = new Map();
976
+ for (const model of this.models.values()) {
977
+ const explicitFields = InternalSchemaModel.getExplicitFields(model);
978
+ const inferredFields = inferFieldsFromSchema(model.schema, {
979
+ registry: this,
980
+ resolveReferenceTarget: (target) => {
981
+ const targetModel = this.resolveRef(target);
982
+ return {
983
+ table: targetModel.metadata.table,
984
+ pk: primaryKeyByModel.get(targetModel.metadata.key)
985
+ };
986
+ }
987
+ });
988
+ const fields = this.freezeFields(this.mergeStorageFields(inferredFields, explicitFields));
989
+ const primaryKey$1 = fields.find((field$1) => field$1.primaryKey)?.name ?? DEFAULT_IDENTIFIER_NAME;
990
+ byModel.set(model.metadata.key, {
991
+ key: model.metadata.key,
992
+ table: model.metadata.table,
993
+ fields,
994
+ pk: primaryKey$1
995
+ });
996
+ }
997
+ const finalized = {
998
+ version: this.version,
999
+ byModel
1000
+ };
1001
+ this.storageCache = finalized;
1002
+ return finalized;
1003
+ }
1004
+ /**
1005
+ * Return finalized storage fields for a specific model.
1006
+ */
1007
+ getFinalizedFields(model) {
1008
+ const key = typeof model === "string" ? model : model.metadata.key;
1009
+ const fields = this.finalizeStorageArtifacts().byModel.get(key)?.fields;
1010
+ if (!fields) throw new Error(`No finalized storage fields are available for model '${key}'.`);
1011
+ return fields;
1012
+ }
1013
+ /**
1014
+ * Resolve the registry's relation graph from finalized storage artifacts.
1015
+ */
1016
+ getResolvedRelationGraph() {
1017
+ if (this.relationGraphCache?.version === this.version) return this.relationGraphCache;
1018
+ const finalized = ResolvedRelationGraphBuilder.build({
1019
+ version: this.version,
1020
+ models: this.values(),
1021
+ storage: this.finalizeStorageArtifacts(),
1022
+ resolveRef: (ref) => this.resolveRef(ref)
1023
+ });
1024
+ this.relationGraphCache = finalized;
1025
+ return finalized;
1026
+ }
1027
+ /**
1028
+ * Remove all registered models from this registry instance.
1029
+ */
1030
+ clear() {
1031
+ this.models.clear();
1032
+ this.bumpVersion();
1033
+ }
1034
+ /**
1035
+ * Return all registered models in insertion order.
1036
+ */
1037
+ values() {
1038
+ return Array.from(this.models.values());
1039
+ }
1040
+ bumpVersion() {
1041
+ this.version += 1;
1042
+ this.storageCache = undefined;
1043
+ this.relationGraphCache = undefined;
1044
+ }
1045
+ freezeFields(fields) {
1046
+ return Object.freeze(fields.map((field$1) => Object.freeze({ ...field$1 })));
1047
+ }
1048
+ inferPrimaryKeyName(model) {
1049
+ for (const [fieldKey, zodType] of Object.entries(model.schema.shape)) {
1050
+ const meta = getFieldMetadata(zodType);
1051
+ if (meta?.primaryKey) return meta.dbColumn ?? fieldKey;
1052
+ }
1053
+ const explicitFields = InternalSchemaModel.getExplicitFields(model);
1054
+ if (explicitFields) return explicitFields.find((field$1) => field$1.primaryKey)?.name ?? DEFAULT_IDENTIFIER_NAME;
1055
+ return DEFAULT_IDENTIFIER_NAME;
1056
+ }
1057
+ mergeStorageFields(inferredFields, explicitFields) {
1058
+ if (!explicitFields?.length) return inferredFields;
1059
+ const mergedFields = new Map(inferredFields.map((field$1) => [field$1.name, field$1]));
1060
+ for (const explicitField of explicitFields) mergedFields.set(explicitField.name, explicitField);
1061
+ return Array.from(mergedFields.values());
1062
+ }
1063
+ };
1064
+
1065
+ //#endregion
1066
+ //#region src/model/registry/index.ts
1067
+ var registry_exports = {};
1068
+ __export(registry_exports, { ModelRegistry: () => ModelRegistry });
1069
+
1070
+ //#endregion
1071
+ //#region src/model/relations/index.ts
1072
+ var relations_exports = {};
1073
+ __export(relations_exports, { RelationBuilder: () => RelationBuilder });
1074
+
1075
+ //#endregion
1076
+ //#region src/model/ModelAugmentorRegistry.ts
1077
+ const modelAugmentors = new Set();
1078
+ function registerModelAugmentor(augmentor) {
1079
+ modelAugmentors.add(augmentor);
1080
+ for (const model of ModelRegistry.global().values()) augmentor(model);
1081
+ return () => {
1082
+ modelAugmentors.delete(augmentor);
1083
+ };
1084
+ }
1085
+ function applyModelAugmentors(model) {
1086
+ for (const augmentor of modelAugmentors) augmentor(model);
1087
+ return model;
1088
+ }
1089
+
1090
+ //#endregion
1091
+ //#region src/model/Model.ts
1092
+ function Model(definition) {
1093
+ const registry = definition.registry ?? ModelRegistry.active();
1094
+ const model = applyModelAugmentors(InternalSchemaModel.create(definition, registry));
1095
+ registry.register(model);
1096
+ return model;
1097
+ }
1098
+
1099
+ //#endregion
1100
+ //#region src/model/index.ts
1101
+ var model_exports = {};
1102
+ __export(model_exports, {
1103
+ Constraints: () => Constraints,
1104
+ Decorators: () => Decorators,
1105
+ Indexes: () => Indexes,
1106
+ Meta: () => Meta,
1107
+ Model: () => Model,
1108
+ ModelRegistry: () => ModelRegistry,
1109
+ RelationBuilder: () => RelationBuilder,
1110
+ c: () => Constraints,
1111
+ constraints: () => constraints_exports,
1112
+ decorators: () => decorators_exports,
1113
+ i: () => Indexes,
1114
+ m: () => Meta,
1115
+ meta: () => meta_exports,
1116
+ registerModelAugmentor: () => registerModelAugmentor,
1117
+ registry: () => registry_exports,
1118
+ relations: () => relations_exports,
1119
+ t: () => Decorators
1120
+ });
1121
+
1122
+ //#endregion
1123
+ export { Constraints, Decorators, Indexes, Meta, Model, ModelRegistry, RelationBuilder, constraints_exports, decorators_exports, meta_exports, model_exports, registerModelAugmentor, registry_exports, relations_exports };
1124
+ //# sourceMappingURL=model-CJbsYdkM.js.map