@lunora/codegen 1.0.0-alpha.5 → 1.0.0-alpha.50

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 (42) hide show
  1. package/LICENSE.md +6 -0
  2. package/__assets__/package-og.svg +1 -1
  3. package/dist/index.d.mts +1950 -734
  4. package/dist/index.d.ts +1950 -734
  5. package/dist/index.mjs +32 -24
  6. package/dist/packem_shared/AGENTS_FILENAME-Cxx7wiSs.mjs +158 -0
  7. package/dist/packem_shared/{CONTAINERS_FILENAME-0K-pjNb8.mjs → CONTAINERS_FILENAME-DjpXMqhp.mjs} +1 -1
  8. package/dist/packem_shared/{CodegenDiagnosticError-54jWDxA9.mjs → CodegenDiagnosticError-DyQ5FwkM.mjs} +7 -5
  9. package/dist/packem_shared/FLAGS_FILENAME-Dg4mKUuz.mjs +139 -0
  10. package/dist/packem_shared/GENERATED_HEADER-C5paWNYO.mjs +4 -0
  11. package/dist/packem_shared/{LUNORA_ERROR_CODES-CySpQPD3.mjs → LUNORA_ERROR_CODES-DvTLozCu.mjs} +8 -1
  12. package/dist/packem_shared/MUTATORS_FILENAME-BZOfUhlY.mjs +81 -0
  13. package/dist/packem_shared/{OPENRPC_VERSION-C7zKVeKi.mjs → OPENRPC_VERSION-7A2weq2u.mjs} +2 -2
  14. package/dist/packem_shared/QUEUES_FILENAME-Xv6Vy-Ku.mjs +145 -0
  15. package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-G5dkcxPR.mjs +3502 -0
  16. package/dist/packem_shared/{SCHEMA_SNAPSHOT_VERSION-DzLDbWk3.mjs → SCHEMA_SNAPSHOT_VERSION-D0ARY6rL.mjs} +18 -2
  17. package/dist/packem_shared/SHAPES_FILENAME-DOhPGi-6.mjs +94 -0
  18. package/dist/packem_shared/WORKFLOWS_FILENAME-Dtuzvluc.mjs +158 -0
  19. package/dist/packem_shared/{buildOpenApiDocument-Cns1EkCQ.mjs → buildOpenApiDocument-B7mEdzA2.mjs} +2 -2
  20. package/dist/packem_shared/{discoverAuthApiCalls-C35R6z0T.mjs → discoverAuthApiCalls-Dx3K42rk.mjs} +1 -1
  21. package/dist/packem_shared/{discoverCrons-BL6iGuJ3.mjs → discoverCrons-DvqkEWdx.mjs} +68 -36
  22. package/dist/packem_shared/{discoverFunctions-DEgAcRuD.mjs → discoverFunctions-BJ-qR7Rg.mjs} +72 -14
  23. package/dist/packem_shared/{discoverHttpRoutes-C978pBiG.mjs → discoverHttpRoutes-daCzuTe8.mjs} +10 -2
  24. package/dist/packem_shared/{discoverInserts-CRQdXvHO.mjs → discoverInserts-DI4q5NxE.mjs} +24 -2
  25. package/dist/packem_shared/{discoverMaskProcedures-B64zA740.mjs → discoverMaskProcedures-BcTOEKNU.mjs} +58 -2
  26. package/dist/packem_shared/{discoverMigrations-Doj_-BAA.mjs → discoverMigrations-VNUFvCwr.mjs} +10 -4
  27. package/dist/packem_shared/{discoverNondeterministicCalls-4KiPQxQU.mjs → discoverNondeterministicCalls-S0N2xLCq.mjs} +1 -1
  28. package/dist/packem_shared/{discoverQueries-BkIi0dBD.mjs → discoverQueries-CJnnnLpd.mjs} +1 -1
  29. package/dist/packem_shared/{discoverR2sqlCalls-BpDqvcUn.mjs → discoverR2sqlCalls-pnpicWfz.mjs} +1 -1
  30. package/dist/packem_shared/{discoverRlsMetadata-DpRB1HMe.mjs → discoverRlsMetadata-DppniPUH.mjs} +1 -1
  31. package/dist/packem_shared/discoverSandboxUsage-BUM2r90k.mjs +38 -0
  32. package/dist/packem_shared/{discoverSchema-DB_QrIQe.mjs → discoverSchema-BaSAvooG.mjs} +326 -14
  33. package/dist/packem_shared/{discoverStorageRulesMetadata-DAqJUxUv.mjs → discoverStorageRulesMetadata-CnHl2rXD.mjs} +1 -1
  34. package/dist/packem_shared/{GENERATED_HEADER-DF1hQcix.mjs → emit-ClTbCLy4.mjs} +1458 -154
  35. package/dist/packem_shared/{emitApp-Ci_hcJNO.mjs → emitApp-CzzrjVqH.mjs} +129 -31
  36. package/dist/packem_shared/formatAdvisories-BmF7Mplc.mjs +115 -0
  37. package/dist/packem_shared/{parse-validator-tuQtHrsr.mjs → parse-validator-BSJo1HGP.mjs} +18 -6
  38. package/dist/packem_shared/redact-oTmsol5A.mjs +33 -0
  39. package/package.json +10 -7
  40. package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-BqOtU2lC.mjs +0 -922
  41. package/dist/packem_shared/WORKFLOWS_FILENAME-DRDQdhfq.mjs +0 -84
  42. package/dist/packem_shared/formatAdvisories-8NIv1k0I.mjs +0 -69
@@ -1,6 +1,213 @@
1
- import { SyntaxKind, Node } from 'ts-morph';
2
- import { diagnosticAt } from './CodegenDiagnosticError-54jWDxA9.mjs';
3
- import { a as parseObjectShape } from './parse-validator-tuQtHrsr.mjs';
1
+ import { LunoraError } from '@lunora/errors';
2
+ import { Node, SyntaxKind } from 'ts-morph';
3
+ import { diagnosticAt } from './CodegenDiagnosticError-DyQ5FwkM.mjs';
4
+ import { a as parseObjectShape } from './parse-validator-BSJo1HGP.mjs';
5
+ import { createRequire } from 'node:module';
6
+ import { join } from 'node:path';
7
+
8
+ const renderLiteralValue = (value) => {
9
+ switch (typeof value) {
10
+ case "bigint": {
11
+ return value.toString();
12
+ }
13
+ case "boolean":
14
+ case "number": {
15
+ return String(value);
16
+ }
17
+ case "string": {
18
+ return JSON.stringify(value);
19
+ }
20
+ default: {
21
+ return value === null ? "null" : void 0;
22
+ }
23
+ }
24
+ };
25
+ const columnMetaToIR = (column) => {
26
+ const hasDefault = column?.["defaultValue"] !== void 0 || column?.["defaultFn"] !== void 0 || column?.["serverDefault"] !== void 0;
27
+ return {
28
+ ...hasDefault ? { hasDefault: true } : {},
29
+ ...column?.["onUpdateFn"] === void 0 ? {} : { hasOnUpdate: true },
30
+ notNull: column?.["notNull"] ?? true,
31
+ ...column?.["unique"] === true ? { unique: true } : {}
32
+ };
33
+ };
34
+ const runtimeValidatorToIR = (validator) => {
35
+ const meta = validator?._meta ?? {};
36
+ const kind = validator?.kind ?? "unknown";
37
+ const ir = { column: columnMetaToIR(meta["column"]), kind };
38
+ switch (kind) {
39
+ case "array":
40
+ case "optional": {
41
+ ir.inner = runtimeValidatorToIR(meta["inner"]);
42
+ break;
43
+ }
44
+ case "id": {
45
+ ir.tableName = meta["tableName"];
46
+ break;
47
+ }
48
+ case "literal": {
49
+ ir.literalValue = renderLiteralValue(meta["value"]);
50
+ break;
51
+ }
52
+ case "object": {
53
+ const shape = meta["shape"] ?? {};
54
+ ir.shape = Object.fromEntries(Object.entries(shape).map(([name, child]) => [name, runtimeValidatorToIR(child)]));
55
+ break;
56
+ }
57
+ case "record": {
58
+ ir.valueType = runtimeValidatorToIR(meta["valueValidator"]);
59
+ if (meta["keyValidator"] !== void 0) {
60
+ ir.keyType = runtimeValidatorToIR(meta["keyValidator"]);
61
+ }
62
+ break;
63
+ }
64
+ case "storage": {
65
+ if (typeof meta["bucket"] === "string") {
66
+ ir.bucket = meta["bucket"];
67
+ }
68
+ break;
69
+ }
70
+ case "union": {
71
+ const members = meta["members"] ?? [];
72
+ ir.members = members.map((member) => runtimeValidatorToIR(member));
73
+ break;
74
+ }
75
+ }
76
+ return ir;
77
+ };
78
+ const shardModeToIR = (shardMode) => {
79
+ if (shardMode?.kind === "global") {
80
+ return "global";
81
+ }
82
+ if (shardMode?.kind === "shardBy" && typeof shardMode.field === "string") {
83
+ return { field: shardMode.field, kind: "shardBy" };
84
+ }
85
+ return "root";
86
+ };
87
+ const warnDroppedTableFeatures = (builder, bareName) => {
88
+ const dropped = [];
89
+ if (builder.relationMap && Object.keys(builder.relationMap).length > 0) {
90
+ dropped.push("relations");
91
+ }
92
+ if (builder.rankIndexes && builder.rankIndexes.length > 0) {
93
+ dropped.push("rank indexes");
94
+ }
95
+ if (builder.vectorIndexes && builder.vectorIndexes.length > 0) {
96
+ dropped.push("vector indexes");
97
+ }
98
+ if (dropped.length > 0) {
99
+ console.warn(
100
+ `@lunora/codegen: package schema-extension table "${bareName}" declares ${dropped.join(" + ")}, which are not yet introspected from a node_modules extension — they will be absent from the generated types.`
101
+ );
102
+ }
103
+ };
104
+ const runtimeTableToIR = (builder, bareName) => {
105
+ const shape = builder.shape ?? {};
106
+ const indexes = (builder.indexes ?? []).map((index) => {
107
+ return { fields: index.fields, name: index.name, ...index.unique ? { unique: true } : {} };
108
+ });
109
+ warnDroppedTableFeatures(builder, bareName);
110
+ return {
111
+ ...builder.isExternallyManaged ? { externallyManaged: true } : {},
112
+ indexes,
113
+ name: bareName,
114
+ rankIndexes: [],
115
+ relations: [],
116
+ searchIndexes: (builder.searchIndexes ?? []).map((index) => {
117
+ return {
118
+ field: index.field,
119
+ ...index.filterFields ? { filterFields: index.filterFields } : {},
120
+ name: index.name
121
+ };
122
+ }),
123
+ shape: Object.fromEntries(Object.entries(shape).map(([name, validator]) => [name, runtimeValidatorToIR(validator)])),
124
+ shardMode: shardModeToIR(builder.shardMode),
125
+ // Inline vector/rank indexes and relations are not yet introspected from a
126
+ // package extension; their presence is surfaced via `warnDroppedTableFeatures`.
127
+ vectorIndexes: []
128
+ };
129
+ };
130
+ const resolvedExtensionToIR = (value) => {
131
+ const { key, tables } = value;
132
+ if (typeof key !== "string" || typeof tables !== "object" || tables === null) {
133
+ return void 0;
134
+ }
135
+ const bareTables = Object.entries(tables).map(([bareName, builder]) => runtimeTableToIR(builder, bareName));
136
+ const vectorIndexes = value["vectorIndexes"] ?? {};
137
+ const bareVectorIndexes = Object.entries(vectorIndexes ?? {}).map(([name, index]) => {
138
+ return {
139
+ ...index.dimensions === void 0 ? {} : { dimensions: index.dimensions },
140
+ ...index.field === void 0 ? {} : { field: index.field },
141
+ ...index.metadata === void 0 ? {} : { metadata: index.metadata },
142
+ ...index.metric === void 0 ? {} : { metric: index.metric },
143
+ name,
144
+ table: index.table ?? ""
145
+ };
146
+ });
147
+ return { bareTables, bareVectorIndexes, key };
148
+ };
149
+ const receiverIdentifierText = (argument) => {
150
+ if (Node.isIdentifier(argument)) {
151
+ return argument.getText();
152
+ }
153
+ if (Node.isPropertyAccessExpression(argument)) {
154
+ const receiver = argument.getExpression();
155
+ return Node.isIdentifier(receiver) ? receiver.getText() : void 0;
156
+ }
157
+ return void 0;
158
+ };
159
+ const accessPathOf = (argument) => {
160
+ const receiverName = receiverIdentifierText(argument);
161
+ if (receiverName === void 0) {
162
+ return void 0;
163
+ }
164
+ const property = Node.isPropertyAccessExpression(argument) ? argument.getName() : void 0;
165
+ const propertyPath = property === void 0 ? [] : [property];
166
+ for (const declaration of argument.getSourceFile().getImportDeclarations()) {
167
+ const moduleSpecifier = declaration.getModuleSpecifierValue();
168
+ for (const named of declaration.getNamedImports()) {
169
+ const localName = named.getAliasNode()?.getText() ?? named.getName();
170
+ if (localName === receiverName) {
171
+ return { importedName: named.getName(), moduleSpecifier, propertyPath };
172
+ }
173
+ }
174
+ if (declaration.getDefaultImport()?.getText() === receiverName) {
175
+ return { importedName: "default", moduleSpecifier, propertyPath };
176
+ }
177
+ if (declaration.getNamespaceImport()?.getText() === receiverName && property !== void 0) {
178
+ return { importedName: property, moduleSpecifier, propertyPath: [] };
179
+ }
180
+ }
181
+ return void 0;
182
+ };
183
+ const readExtensionValue = (module_, access) => {
184
+ let current = module_[access.importedName];
185
+ for (const segment of access.propertyPath) {
186
+ if (typeof current !== "object" || current === null) {
187
+ return void 0;
188
+ }
189
+ current = current[segment];
190
+ }
191
+ return current;
192
+ };
193
+ const resolvePackageExtension = (argument, projectRoot) => {
194
+ const access = accessPathOf(argument);
195
+ if (!access) {
196
+ return void 0;
197
+ }
198
+ try {
199
+ const projectRequire = createRequire(join(projectRoot, "noop.cjs"));
200
+ const resolved = projectRequire.resolve(access.moduleSpecifier);
201
+ const loadedModule = projectRequire(resolved);
202
+ const value = readExtensionValue(loadedModule, access);
203
+ if (typeof value !== "object" || value === null) {
204
+ return void 0;
205
+ }
206
+ return resolvedExtensionToIR(value);
207
+ } catch {
208
+ return void 0;
209
+ }
210
+ };
4
211
 
5
212
  const VECTOR_METRICS = /* @__PURE__ */ new Set(["cosine", "dot-product", "euclidean"]);
6
213
  const ON_DELETE_ACTIONS = /* @__PURE__ */ new Set(["cascade", "restrict", "set null"]);
@@ -179,6 +386,55 @@ const parseGlobalBackend = (args) => {
179
386
  }
180
387
  return "d1";
181
388
  };
389
+ const softDeleteFieldOf = (optionsArgument) => {
390
+ if (optionsArgument && Node.isObjectLiteralExpression(optionsArgument)) {
391
+ const fieldProperty = optionsArgument.getProperty("field");
392
+ if (fieldProperty && Node.isPropertyAssignment(fieldProperty)) {
393
+ const initializer = fieldProperty.getInitializer();
394
+ if (initializer && Node.isStringLiteral(initializer)) {
395
+ return initializer.getLiteralText();
396
+ }
397
+ }
398
+ }
399
+ return "deletedAt";
400
+ };
401
+ const stringPropertyOf = (object, property) => {
402
+ const node = object.getProperty(property);
403
+ if (node && Node.isPropertyAssignment(node)) {
404
+ const initializer = node.getInitializer();
405
+ if (initializer && Node.isStringLiteral(initializer)) {
406
+ return initializer.getLiteralText();
407
+ }
408
+ }
409
+ return void 0;
410
+ };
411
+ const stringArrayPropertyOf = (object, property) => {
412
+ const node = object.getProperty(property);
413
+ if (node && Node.isPropertyAssignment(node)) {
414
+ const initializer = node.getInitializer();
415
+ if (initializer && Node.isArrayLiteralExpression(initializer)) {
416
+ const items = initializer.getElements().filter((element) => Node.isStringLiteral(element)).map((element) => element.getLiteralText());
417
+ return items.length > 0 ? items : void 0;
418
+ }
419
+ }
420
+ return void 0;
421
+ };
422
+ const parseSourceCall = (args) => {
423
+ const first = args[0];
424
+ if (!first || !Node.isObjectLiteralExpression(first)) {
425
+ return { binding: "", hasTenantBy: false, unanalyzable: true };
426
+ }
427
+ return {
428
+ binding: stringPropertyOf(first, "binding") ?? "",
429
+ columns: stringArrayPropertyOf(first, "columns"),
430
+ hasReconcile: first.getProperty("reconcileEveryMs") !== void 0,
431
+ hasSoftDelete: first.getProperty("softDeleteColumn") !== void 0,
432
+ hasTenantBy: first.getProperty("tenantBy") !== void 0,
433
+ idColumn: stringPropertyOf(first, "idColumn"),
434
+ mode: stringPropertyOf(first, "mode"),
435
+ query: stringPropertyOf(first, "query")
436
+ };
437
+ };
182
438
  const applyTableMethod = (accumulator, method, args, name) => {
183
439
  switch (method) {
184
440
  case "externallyManaged": {
@@ -194,6 +450,10 @@ const applyTableMethod = (accumulator, method, args, name) => {
194
450
  accumulator.indexes.push(parseIndexCall(args));
195
451
  break;
196
452
  }
453
+ case "public": {
454
+ accumulator.isPublic = true;
455
+ break;
456
+ }
197
457
  case "rankIndex": {
198
458
  accumulator.rankIndexes.push(parseRankIndexCall(args));
199
459
  break;
@@ -214,6 +474,15 @@ const applyTableMethod = (accumulator, method, args, name) => {
214
474
  accumulator.shardMode = { field: field && Node.isStringLiteral(field) ? field.getLiteralText() : "_unknown_", kind: "shardBy" };
215
475
  break;
216
476
  }
477
+ case "softDelete": {
478
+ accumulator.softDelete = { field: softDeleteFieldOf(args[0]) };
479
+ break;
480
+ }
481
+ case "source": {
482
+ accumulator.externalSource = parseSourceCall(args);
483
+ accumulator.externallyManaged = true;
484
+ break;
485
+ }
217
486
  case "vectorize": {
218
487
  const vectorIndex = parseVectorizeCall(args, name);
219
488
  if (vectorIndex) {
@@ -227,6 +496,7 @@ const parseTableBuilder = (expression, name) => {
227
496
  const accumulator = {
228
497
  externallyManaged: false,
229
498
  indexes: [],
499
+ isPublic: false,
230
500
  rankIndexes: [],
231
501
  relations: [],
232
502
  searchIndexes: [],
@@ -251,16 +521,22 @@ const parseTableBuilder = (expression, name) => {
251
521
  break;
252
522
  }
253
523
  }
524
+ if (accumulator.softDelete && !(accumulator.softDelete.field in shape)) {
525
+ shape = { ...shape, [accumulator.softDelete.field]: { inner: { kind: "number" }, kind: "optional" } };
526
+ }
254
527
  return {
255
528
  externallyManaged: accumulator.externallyManaged,
529
+ externalSource: accumulator.externalSource,
256
530
  globalBackend: accumulator.shardMode === "global" ? accumulator.globalBackend ?? "d1" : void 0,
257
531
  indexes: accumulator.indexes,
532
+ isPublic: accumulator.isPublic,
258
533
  name,
259
534
  rankIndexes: accumulator.rankIndexes,
260
535
  relations: accumulator.relations,
261
536
  searchIndexes: accumulator.searchIndexes,
262
537
  shape,
263
538
  shardMode: accumulator.shardMode,
539
+ softDelete: accumulator.softDelete,
264
540
  vectorIndexes: accumulator.vectorIndexes
265
541
  };
266
542
  };
@@ -455,24 +731,30 @@ const parseExtensionVectorIndexes = (options) => {
455
731
  }
456
732
  return parseStandaloneVectorIndexes(object);
457
733
  };
458
- const mergeExtension = (key, options) => {
459
- const bareTables = parseExtensionTables(options);
734
+ const namespaceExtension = (key, bareTables, bareVectorIndexes) => {
460
735
  const bareNames = new Set(bareTables.map((table) => table.name));
461
736
  const tables = bareTables.map((table) => namespaceExtensionTable(table, key, bareNames));
462
- const vectorIndexes = parseExtensionVectorIndexes(options).map((index) => {
737
+ const vectorIndexes = bareVectorIndexes.map((index) => {
463
738
  return { ...index, name: prefixTableName(key, index.name), table: rewriteReference(index.table, key, bareNames) };
464
739
  });
465
740
  return { tables, vectorIndexes };
466
741
  };
467
- const mergeExtendCall = (extendCall) => {
742
+ const mergeExtension = (key, options) => namespaceExtension(key, parseExtensionTables(options), parseExtensionVectorIndexes(options));
743
+ const mergeExtendCall = (extendCall, projectRoot) => {
468
744
  const extendArgument = extendCall.getArguments()[0];
469
745
  if (!extendArgument) {
470
746
  return void 0;
471
747
  }
472
748
  const resolved = resolveSchemaExtensionCall(extendArgument);
473
749
  if (!resolved) {
750
+ if (projectRoot !== void 0) {
751
+ const fromPackage = resolvePackageExtension(extendArgument, projectRoot);
752
+ if (fromPackage) {
753
+ return namespaceExtension(fromPackage.key, fromPackage.bareTables, fromPackage.bareVectorIndexes);
754
+ }
755
+ }
474
756
  console.warn(
475
- `@lunora/codegen: skipping \`.extend(${extendArgument.getText()})\` — its \`defineSchemaExtension(...)\` definition could not be resolved from local sources (cross-package node_modules/.d.ts resolution is a deferred phase). Extension tables will be absent from the generated types.`
757
+ `@lunora/codegen: skipping \`.extend(${extendArgument.getText()})\` — its \`defineSchemaExtension(...)\` could not be resolved from local sources, and ${projectRoot === void 0 ? "no project root was available to resolve the package" : "the package could not be imported/introspected"}. Extension tables will be absent from the generated types.`
476
758
  );
477
759
  return void 0;
478
760
  }
@@ -502,6 +784,36 @@ const extendCallsOf = (defineSchemaCall) => {
502
784
  }
503
785
  return calls;
504
786
  };
787
+ const chainedStringLiteralArgument = (defineSchemaCall, methodName, noun, allowed, expected) => {
788
+ let current = defineSchemaCall;
789
+ for (; ; ) {
790
+ const parent = current.getParent();
791
+ if (!parent || !Node.isPropertyAccessExpression(parent)) {
792
+ break;
793
+ }
794
+ const callParent = parent.getParent();
795
+ if (!callParent || !Node.isCallExpression(callParent)) {
796
+ break;
797
+ }
798
+ if (parent.getName() === methodName) {
799
+ const argument = callParent.getArguments()[0];
800
+ if (!argument || !Node.isStringLiteral(argument)) {
801
+ throw diagnosticAt(callParent, `\`.${methodName}(...)\` expects a string literal (${expected})`);
802
+ }
803
+ const value = argument.getLiteralText();
804
+ if (!allowed.has(value)) {
805
+ throw diagnosticAt(argument, `unknown ${noun} ${JSON.stringify(value)} — expected ${expected}`);
806
+ }
807
+ return value;
808
+ }
809
+ current = callParent;
810
+ }
811
+ return void 0;
812
+ };
813
+ const JURISDICTIONS = /* @__PURE__ */ new Set(["eu", "fedramp", "us"]);
814
+ const jurisdictionOf = (defineSchemaCall) => chainedStringLiteralArgument(defineSchemaCall, "jurisdiction", "jurisdiction", JURISDICTIONS, '"eu", "us", or "fedramp"');
815
+ const RLS_MODES = /* @__PURE__ */ new Set(["required"]);
816
+ const rlsModeOf = (defineSchemaCall) => chainedStringLiteralArgument(defineSchemaCall, "rls", "rls mode", RLS_MODES, '"required"');
505
817
  const parseBaseTables = (object) => {
506
818
  const tables = [];
507
819
  for (const property of object.getProperties()) {
@@ -517,11 +829,11 @@ const parseBaseTables = (object) => {
517
829
  }
518
830
  return tables;
519
831
  };
520
- const applyExtensions = (defineSchemaCall, tables) => {
832
+ const applyExtensions = (defineSchemaCall, tables, projectRoot) => {
521
833
  const existingTableNames = new Set(tables.map((table) => table.name));
522
834
  const vectorIndexes = [];
523
835
  for (const extendCall of extendCallsOf(defineSchemaCall)) {
524
- const merged = mergeExtendCall(extendCall);
836
+ const merged = mergeExtendCall(extendCall, projectRoot);
525
837
  if (!merged) {
526
838
  continue;
527
839
  }
@@ -539,14 +851,14 @@ const applyExtensions = (defineSchemaCall, tables) => {
539
851
  }
540
852
  return vectorIndexes;
541
853
  };
542
- const discoverSchema = (project, schemaPath) => {
854
+ const discoverSchema = (project, schemaPath, projectRoot) => {
543
855
  const file = project.addSourceFileAtPath(schemaPath);
544
856
  const defineSchemaCall = file.getDescendantsOfKind(SyntaxKind.CallExpression).find((call) => {
545
857
  const callee = call.getExpression();
546
858
  return Node.isIdentifier(callee) && callee.getText() === "defineSchema";
547
859
  });
548
860
  if (!defineSchemaCall) {
549
- throw new Error(`defineSchema() not found in ${schemaPath}`);
861
+ throw new LunoraError("INTERNAL", `defineSchema() not found in ${schemaPath}`);
550
862
  }
551
863
  const argument = defineSchemaCall.getArguments()[0];
552
864
  if (!argument || !Node.isObjectLiteralExpression(argument)) {
@@ -555,9 +867,9 @@ const discoverSchema = (project, schemaPath) => {
555
867
  const tables = parseBaseTables(argument);
556
868
  const standaloneArgument = defineSchemaCall.getArguments()[1];
557
869
  const standaloneVectorIndexes = standaloneArgument && Node.isObjectLiteralExpression(standaloneArgument) ? parseStandaloneVectorIndexes(standaloneArgument) : [];
558
- const extensionStandaloneVectorIndexes = applyExtensions(defineSchemaCall, tables);
870
+ const extensionStandaloneVectorIndexes = applyExtensions(defineSchemaCall, tables, projectRoot);
559
871
  const vectorIndexes = [...tables.flatMap((table) => table.vectorIndexes), ...standaloneVectorIndexes, ...extensionStandaloneVectorIndexes];
560
- return { tables, vectorIndexes };
872
+ return { jurisdiction: jurisdictionOf(defineSchemaCall), rlsMode: rlsModeOf(defineSchemaCall), tables, vectorIndexes };
561
873
  };
562
874
 
563
875
  export { discoverSchema as default };
@@ -1,5 +1,5 @@
1
1
  import { Node } from 'ts-morph';
2
- import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-DEgAcRuD.mjs';
2
+ import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-BJ-qR7Rg.mjs';
3
3
 
4
4
  const STORAGE_OPERATIONS = /* @__PURE__ */ new Set(["delete", "list", "read", "write"]);
5
5
  const isStorageRulesCall = (node) => {