@lunora/codegen 1.0.0-alpha.5 → 1.0.0-alpha.6
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.
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +2 -2
- package/dist/packem_shared/{SCHEMA_SNAPSHOT_FILENAME-BqOtU2lC.mjs → SCHEMA_SNAPSHOT_FILENAME-TeOosleN.mjs} +2 -2
- package/dist/packem_shared/{discoverSchema-DB_QrIQe.mjs → discoverSchema-DYl0QfDH.mjs} +222 -10
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -855,7 +855,7 @@ declare const discoverRlsMetadata: (project: Project, lunoraDirectory: string) =
|
|
|
855
855
|
* Load `<projectRoot>/lunora/schema.ts`, find `defineSchema({...})`, and
|
|
856
856
|
* return a structural IR. Throws if the file or call cannot be found.
|
|
857
857
|
*/
|
|
858
|
-
declare const discoverSchema: (project: Project, schemaPath: string) => SchemaIR;
|
|
858
|
+
declare const discoverSchema: (project: Project, schemaPath: string, projectRoot?: string) => SchemaIR;
|
|
859
859
|
/**
|
|
860
860
|
* Aggregate the schema-wide storage-rule metadata the studio's inspector reads:
|
|
861
861
|
* every statically-discovered `(bucket, on, prefix, procedure)` entry across all
|
package/dist/index.d.ts
CHANGED
|
@@ -855,7 +855,7 @@ declare const discoverRlsMetadata: (project: Project, lunoraDirectory: string) =
|
|
|
855
855
|
* Load `<projectRoot>/lunora/schema.ts`, find `defineSchema({...})`, and
|
|
856
856
|
* return a structural IR. Throws if the file or call cannot be found.
|
|
857
857
|
*/
|
|
858
|
-
declare const discoverSchema: (project: Project, schemaPath: string) => SchemaIR;
|
|
858
|
+
declare const discoverSchema: (project: Project, schemaPath: string, projectRoot?: string) => SchemaIR;
|
|
859
859
|
/**
|
|
860
860
|
* Aggregate the schema-wide storage-rule metadata the studio's inspector reads:
|
|
861
861
|
* every statically-discovered `(bucket, on, prefix, procedure)` entry across all
|
package/dist/index.mjs
CHANGED
|
@@ -12,14 +12,14 @@ export { default as discoverNondeterministicCalls } from './packem_shared/discov
|
|
|
12
12
|
export { default as discoverQueries } from './packem_shared/discoverQueries-BkIi0dBD.mjs';
|
|
13
13
|
export { default as discoverR2sqlCalls } from './packem_shared/discoverR2sqlCalls-BpDqvcUn.mjs';
|
|
14
14
|
export { discoverRlsMetadata, default as discoverRlsProcedures } from './packem_shared/discoverRlsMetadata-DpRB1HMe.mjs';
|
|
15
|
-
export { default as discoverSchema } from './packem_shared/discoverSchema-
|
|
15
|
+
export { default as discoverSchema } from './packem_shared/discoverSchema-DYl0QfDH.mjs';
|
|
16
16
|
export { default as discoverStorageRulesMetadata } from './packem_shared/discoverStorageRulesMetadata-DAqJUxUv.mjs';
|
|
17
17
|
export { WORKFLOWS_FILENAME, discoverWorkflows } from './packem_shared/WORKFLOWS_FILENAME-DRDQdhfq.mjs';
|
|
18
18
|
export { GENERATED_HEADER, emitApi, emitContainers, emitCrons, emitDataModel, emitDrizzleSchema, emitFunctions, emitServer, emitShard, emitVectors, emitWorkflows, emitWranglerCronTriggers } from './packem_shared/GENERATED_HEADER-DF1hQcix.mjs';
|
|
19
19
|
export { emitApp } from './packem_shared/emitApp-Ci_hcJNO.mjs';
|
|
20
20
|
export { buildOpenApiDocument, emitOpenApi, emitOpenApiModule } from './packem_shared/buildOpenApiDocument-Cns1EkCQ.mjs';
|
|
21
21
|
export { OPENRPC_VERSION, buildOpenRpcDocument, emitOpenRpc, emitOpenRpcModule } from './packem_shared/OPENRPC_VERSION-C7zKVeKi.mjs';
|
|
22
|
-
export { SCHEMA_SNAPSHOT_FILENAME, createCodegenProject, refreshCodegenProject, runCodegen } from './packem_shared/SCHEMA_SNAPSHOT_FILENAME-
|
|
22
|
+
export { SCHEMA_SNAPSHOT_FILENAME, createCodegenProject, refreshCodegenProject, runCodegen } from './packem_shared/SCHEMA_SNAPSHOT_FILENAME-TeOosleN.mjs';
|
|
23
23
|
export { SCHEMA_SNAPSHOT_VERSION, SchemaSnapshotParseError, buildSchemaSnapshot, diffSchemaSnapshots, evaluateSchemaDrift, parseSchemaSnapshot, serializeSchemaSnapshot } from './packem_shared/SCHEMA_SNAPSHOT_VERSION-DzLDbWk3.mjs';
|
|
24
24
|
export { schemaFromIr } from './packem_shared/schemaFromIr-DTYsLBaA.mjs';
|
|
25
25
|
export { LUNORA_ERROR_CODES, validatorIrToJsonSchema } from './packem_shared/LUNORA_ERROR_CODES-CySpQPD3.mjs';
|
|
@@ -14,7 +14,7 @@ import discoverNondeterministicCalls from './discoverNondeterministicCalls-4KiPQ
|
|
|
14
14
|
import discoverQueries from './discoverQueries-BkIi0dBD.mjs';
|
|
15
15
|
import discoverR2sqlCalls from './discoverR2sqlCalls-BpDqvcUn.mjs';
|
|
16
16
|
import discoverRlsProcedures, { discoverRlsMetadata } from './discoverRlsMetadata-DpRB1HMe.mjs';
|
|
17
|
-
import discoverSchema from './discoverSchema-
|
|
17
|
+
import discoverSchema from './discoverSchema-DYl0QfDH.mjs';
|
|
18
18
|
import discoverStorageRulesMetadata from './discoverStorageRulesMetadata-DAqJUxUv.mjs';
|
|
19
19
|
import { e as enclosingExportName$1 } from './discover-ast-CT6BgBr4.mjs';
|
|
20
20
|
import { discoverWorkflows } from './WORKFLOWS_FILENAME-DRDQdhfq.mjs';
|
|
@@ -723,7 +723,7 @@ const runCodegen = (options) => {
|
|
|
723
723
|
throw new Error(`schema.ts not found at ${schemaPath}`);
|
|
724
724
|
}
|
|
725
725
|
const project = options.project ?? createCodegenProject(lunoraDirectory);
|
|
726
|
-
const schema = discoverSchema(project, schemaPath);
|
|
726
|
+
const schema = discoverSchema(project, schemaPath, options.projectRoot);
|
|
727
727
|
const functions = discoverFunctions(project, lunoraDirectory);
|
|
728
728
|
const httpRoutes = discoverHttpRoutes(project, lunoraDirectory);
|
|
729
729
|
const migrations = discoverMigrations(project, lunoraDirectory);
|
|
@@ -1,6 +1,212 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Node, SyntaxKind } from 'ts-morph';
|
|
2
2
|
import { diagnosticAt } from './CodegenDiagnosticError-54jWDxA9.mjs';
|
|
3
3
|
import { a as parseObjectShape } from './parse-validator-tuQtHrsr.mjs';
|
|
4
|
+
import { createRequire } from 'node:module';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
|
|
7
|
+
const renderLiteralValue = (value) => {
|
|
8
|
+
switch (typeof value) {
|
|
9
|
+
case "bigint": {
|
|
10
|
+
return value.toString();
|
|
11
|
+
}
|
|
12
|
+
case "boolean":
|
|
13
|
+
case "number": {
|
|
14
|
+
return String(value);
|
|
15
|
+
}
|
|
16
|
+
case "string": {
|
|
17
|
+
return JSON.stringify(value);
|
|
18
|
+
}
|
|
19
|
+
default: {
|
|
20
|
+
return value === null ? "null" : void 0;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
const columnMetaToIR = (column) => {
|
|
25
|
+
const hasDefault = column?.["defaultValue"] !== void 0 || column?.["defaultFn"] !== void 0 || column?.["serverDefault"] !== void 0;
|
|
26
|
+
return {
|
|
27
|
+
...hasDefault ? { hasDefault: true } : {},
|
|
28
|
+
...column?.["onUpdateFn"] === void 0 ? {} : { hasOnUpdate: true },
|
|
29
|
+
notNull: column?.["notNull"] ?? true,
|
|
30
|
+
...column?.["unique"] === true ? { unique: true } : {}
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
const runtimeValidatorToIR = (validator) => {
|
|
34
|
+
const meta = validator?._meta ?? {};
|
|
35
|
+
const kind = validator?.kind ?? "unknown";
|
|
36
|
+
const ir = { column: columnMetaToIR(meta["column"]), kind };
|
|
37
|
+
switch (kind) {
|
|
38
|
+
case "array":
|
|
39
|
+
case "optional": {
|
|
40
|
+
ir.inner = runtimeValidatorToIR(meta["inner"]);
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
case "id": {
|
|
44
|
+
ir.tableName = meta["tableName"];
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
case "literal": {
|
|
48
|
+
ir.literalValue = renderLiteralValue(meta["value"]);
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
case "object": {
|
|
52
|
+
const shape = meta["shape"] ?? {};
|
|
53
|
+
ir.shape = Object.fromEntries(Object.entries(shape).map(([name, child]) => [name, runtimeValidatorToIR(child)]));
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
case "record": {
|
|
57
|
+
ir.valueType = runtimeValidatorToIR(meta["valueValidator"]);
|
|
58
|
+
if (meta["keyValidator"] !== void 0) {
|
|
59
|
+
ir.keyType = runtimeValidatorToIR(meta["keyValidator"]);
|
|
60
|
+
}
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
case "storage": {
|
|
64
|
+
if (typeof meta["bucket"] === "string") {
|
|
65
|
+
ir.bucket = meta["bucket"];
|
|
66
|
+
}
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
case "union": {
|
|
70
|
+
const members = meta["members"] ?? [];
|
|
71
|
+
ir.members = members.map((member) => runtimeValidatorToIR(member));
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return ir;
|
|
76
|
+
};
|
|
77
|
+
const shardModeToIR = (shardMode) => {
|
|
78
|
+
if (shardMode?.kind === "global") {
|
|
79
|
+
return "global";
|
|
80
|
+
}
|
|
81
|
+
if (shardMode?.kind === "shardBy" && typeof shardMode.field === "string") {
|
|
82
|
+
return { field: shardMode.field, kind: "shardBy" };
|
|
83
|
+
}
|
|
84
|
+
return "root";
|
|
85
|
+
};
|
|
86
|
+
const warnDroppedTableFeatures = (builder, bareName) => {
|
|
87
|
+
const dropped = [];
|
|
88
|
+
if (builder.relationMap && Object.keys(builder.relationMap).length > 0) {
|
|
89
|
+
dropped.push("relations");
|
|
90
|
+
}
|
|
91
|
+
if (builder.rankIndexes && builder.rankIndexes.length > 0) {
|
|
92
|
+
dropped.push("rank indexes");
|
|
93
|
+
}
|
|
94
|
+
if (builder.vectorIndexes && builder.vectorIndexes.length > 0) {
|
|
95
|
+
dropped.push("vector indexes");
|
|
96
|
+
}
|
|
97
|
+
if (dropped.length > 0) {
|
|
98
|
+
console.warn(
|
|
99
|
+
`@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.`
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
const runtimeTableToIR = (builder, bareName) => {
|
|
104
|
+
const shape = builder.shape ?? {};
|
|
105
|
+
const indexes = (builder.indexes ?? []).map((index) => {
|
|
106
|
+
return { fields: index.fields, name: index.name, ...index.unique ? { unique: true } : {} };
|
|
107
|
+
});
|
|
108
|
+
warnDroppedTableFeatures(builder, bareName);
|
|
109
|
+
return {
|
|
110
|
+
...builder.isExternallyManaged ? { externallyManaged: true } : {},
|
|
111
|
+
indexes,
|
|
112
|
+
name: bareName,
|
|
113
|
+
rankIndexes: [],
|
|
114
|
+
relations: [],
|
|
115
|
+
searchIndexes: (builder.searchIndexes ?? []).map((index) => {
|
|
116
|
+
return {
|
|
117
|
+
field: index.field,
|
|
118
|
+
...index.filterFields ? { filterFields: index.filterFields } : {},
|
|
119
|
+
name: index.name
|
|
120
|
+
};
|
|
121
|
+
}),
|
|
122
|
+
shape: Object.fromEntries(Object.entries(shape).map(([name, validator]) => [name, runtimeValidatorToIR(validator)])),
|
|
123
|
+
shardMode: shardModeToIR(builder.shardMode),
|
|
124
|
+
// Inline vector/rank indexes and relations are not yet introspected from a
|
|
125
|
+
// package extension; their presence is surfaced via `warnDroppedTableFeatures`.
|
|
126
|
+
vectorIndexes: []
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
const resolvedExtensionToIR = (value) => {
|
|
130
|
+
const { key, tables } = value;
|
|
131
|
+
if (typeof key !== "string" || typeof tables !== "object" || tables === null) {
|
|
132
|
+
return void 0;
|
|
133
|
+
}
|
|
134
|
+
const bareTables = Object.entries(tables).map(([bareName, builder]) => runtimeTableToIR(builder, bareName));
|
|
135
|
+
const vectorIndexes = value["vectorIndexes"] ?? {};
|
|
136
|
+
const bareVectorIndexes = Object.entries(vectorIndexes ?? {}).map(([name, index]) => {
|
|
137
|
+
return {
|
|
138
|
+
...index.dimensions === void 0 ? {} : { dimensions: index.dimensions },
|
|
139
|
+
...index.field === void 0 ? {} : { field: index.field },
|
|
140
|
+
...index.metadata === void 0 ? {} : { metadata: index.metadata },
|
|
141
|
+
...index.metric === void 0 ? {} : { metric: index.metric },
|
|
142
|
+
name,
|
|
143
|
+
table: index.table ?? ""
|
|
144
|
+
};
|
|
145
|
+
});
|
|
146
|
+
return { bareTables, bareVectorIndexes, key };
|
|
147
|
+
};
|
|
148
|
+
const receiverIdentifierText = (argument) => {
|
|
149
|
+
if (Node.isIdentifier(argument)) {
|
|
150
|
+
return argument.getText();
|
|
151
|
+
}
|
|
152
|
+
if (Node.isPropertyAccessExpression(argument)) {
|
|
153
|
+
const receiver = argument.getExpression();
|
|
154
|
+
return Node.isIdentifier(receiver) ? receiver.getText() : void 0;
|
|
155
|
+
}
|
|
156
|
+
return void 0;
|
|
157
|
+
};
|
|
158
|
+
const accessPathOf = (argument) => {
|
|
159
|
+
const receiverName = receiverIdentifierText(argument);
|
|
160
|
+
if (receiverName === void 0) {
|
|
161
|
+
return void 0;
|
|
162
|
+
}
|
|
163
|
+
const property = Node.isPropertyAccessExpression(argument) ? argument.getName() : void 0;
|
|
164
|
+
const propertyPath = property === void 0 ? [] : [property];
|
|
165
|
+
for (const declaration of argument.getSourceFile().getImportDeclarations()) {
|
|
166
|
+
const moduleSpecifier = declaration.getModuleSpecifierValue();
|
|
167
|
+
for (const named of declaration.getNamedImports()) {
|
|
168
|
+
const localName = named.getAliasNode()?.getText() ?? named.getName();
|
|
169
|
+
if (localName === receiverName) {
|
|
170
|
+
return { importedName: named.getName(), moduleSpecifier, propertyPath };
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (declaration.getDefaultImport()?.getText() === receiverName) {
|
|
174
|
+
return { importedName: "default", moduleSpecifier, propertyPath };
|
|
175
|
+
}
|
|
176
|
+
if (declaration.getNamespaceImport()?.getText() === receiverName && property !== void 0) {
|
|
177
|
+
return { importedName: property, moduleSpecifier, propertyPath: [] };
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return void 0;
|
|
181
|
+
};
|
|
182
|
+
const readExtensionValue = (module_, access) => {
|
|
183
|
+
let current = module_[access.importedName];
|
|
184
|
+
for (const segment of access.propertyPath) {
|
|
185
|
+
if (typeof current !== "object" || current === null) {
|
|
186
|
+
return void 0;
|
|
187
|
+
}
|
|
188
|
+
current = current[segment];
|
|
189
|
+
}
|
|
190
|
+
return current;
|
|
191
|
+
};
|
|
192
|
+
const resolvePackageExtension = (argument, projectRoot) => {
|
|
193
|
+
const access = accessPathOf(argument);
|
|
194
|
+
if (!access) {
|
|
195
|
+
return void 0;
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
const projectRequire = createRequire(join(projectRoot, "noop.cjs"));
|
|
199
|
+
const resolved = projectRequire.resolve(access.moduleSpecifier);
|
|
200
|
+
const loadedModule = projectRequire(resolved);
|
|
201
|
+
const value = readExtensionValue(loadedModule, access);
|
|
202
|
+
if (typeof value !== "object" || value === null) {
|
|
203
|
+
return void 0;
|
|
204
|
+
}
|
|
205
|
+
return resolvedExtensionToIR(value);
|
|
206
|
+
} catch {
|
|
207
|
+
return void 0;
|
|
208
|
+
}
|
|
209
|
+
};
|
|
4
210
|
|
|
5
211
|
const VECTOR_METRICS = /* @__PURE__ */ new Set(["cosine", "dot-product", "euclidean"]);
|
|
6
212
|
const ON_DELETE_ACTIONS = /* @__PURE__ */ new Set(["cascade", "restrict", "set null"]);
|
|
@@ -455,24 +661,30 @@ const parseExtensionVectorIndexes = (options) => {
|
|
|
455
661
|
}
|
|
456
662
|
return parseStandaloneVectorIndexes(object);
|
|
457
663
|
};
|
|
458
|
-
const
|
|
459
|
-
const bareTables = parseExtensionTables(options);
|
|
664
|
+
const namespaceExtension = (key, bareTables, bareVectorIndexes) => {
|
|
460
665
|
const bareNames = new Set(bareTables.map((table) => table.name));
|
|
461
666
|
const tables = bareTables.map((table) => namespaceExtensionTable(table, key, bareNames));
|
|
462
|
-
const vectorIndexes =
|
|
667
|
+
const vectorIndexes = bareVectorIndexes.map((index) => {
|
|
463
668
|
return { ...index, name: prefixTableName(key, index.name), table: rewriteReference(index.table, key, bareNames) };
|
|
464
669
|
});
|
|
465
670
|
return { tables, vectorIndexes };
|
|
466
671
|
};
|
|
467
|
-
const
|
|
672
|
+
const mergeExtension = (key, options) => namespaceExtension(key, parseExtensionTables(options), parseExtensionVectorIndexes(options));
|
|
673
|
+
const mergeExtendCall = (extendCall, projectRoot) => {
|
|
468
674
|
const extendArgument = extendCall.getArguments()[0];
|
|
469
675
|
if (!extendArgument) {
|
|
470
676
|
return void 0;
|
|
471
677
|
}
|
|
472
678
|
const resolved = resolveSchemaExtensionCall(extendArgument);
|
|
473
679
|
if (!resolved) {
|
|
680
|
+
if (projectRoot !== void 0) {
|
|
681
|
+
const fromPackage = resolvePackageExtension(extendArgument, projectRoot);
|
|
682
|
+
if (fromPackage) {
|
|
683
|
+
return namespaceExtension(fromPackage.key, fromPackage.bareTables, fromPackage.bareVectorIndexes);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
474
686
|
console.warn(
|
|
475
|
-
`@lunora/codegen: skipping \`.extend(${extendArgument.getText()})\` — its \`defineSchemaExtension(...)\`
|
|
687
|
+
`@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
688
|
);
|
|
477
689
|
return void 0;
|
|
478
690
|
}
|
|
@@ -517,11 +729,11 @@ const parseBaseTables = (object) => {
|
|
|
517
729
|
}
|
|
518
730
|
return tables;
|
|
519
731
|
};
|
|
520
|
-
const applyExtensions = (defineSchemaCall, tables) => {
|
|
732
|
+
const applyExtensions = (defineSchemaCall, tables, projectRoot) => {
|
|
521
733
|
const existingTableNames = new Set(tables.map((table) => table.name));
|
|
522
734
|
const vectorIndexes = [];
|
|
523
735
|
for (const extendCall of extendCallsOf(defineSchemaCall)) {
|
|
524
|
-
const merged = mergeExtendCall(extendCall);
|
|
736
|
+
const merged = mergeExtendCall(extendCall, projectRoot);
|
|
525
737
|
if (!merged) {
|
|
526
738
|
continue;
|
|
527
739
|
}
|
|
@@ -539,7 +751,7 @@ const applyExtensions = (defineSchemaCall, tables) => {
|
|
|
539
751
|
}
|
|
540
752
|
return vectorIndexes;
|
|
541
753
|
};
|
|
542
|
-
const discoverSchema = (project, schemaPath) => {
|
|
754
|
+
const discoverSchema = (project, schemaPath, projectRoot) => {
|
|
543
755
|
const file = project.addSourceFileAtPath(schemaPath);
|
|
544
756
|
const defineSchemaCall = file.getDescendantsOfKind(SyntaxKind.CallExpression).find((call) => {
|
|
545
757
|
const callee = call.getExpression();
|
|
@@ -555,7 +767,7 @@ const discoverSchema = (project, schemaPath) => {
|
|
|
555
767
|
const tables = parseBaseTables(argument);
|
|
556
768
|
const standaloneArgument = defineSchemaCall.getArguments()[1];
|
|
557
769
|
const standaloneVectorIndexes = standaloneArgument && Node.isObjectLiteralExpression(standaloneArgument) ? parseStandaloneVectorIndexes(standaloneArgument) : [];
|
|
558
|
-
const extensionStandaloneVectorIndexes = applyExtensions(defineSchemaCall, tables);
|
|
770
|
+
const extensionStandaloneVectorIndexes = applyExtensions(defineSchemaCall, tables, projectRoot);
|
|
559
771
|
const vectorIndexes = [...tables.flatMap((table) => table.vectorIndexes), ...standaloneVectorIndexes, ...extensionStandaloneVectorIndexes];
|
|
560
772
|
return { tables, vectorIndexes };
|
|
561
773
|
};
|