@lunora/codegen 1.0.0-alpha.4 → 1.0.0-alpha.40
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/LICENSE.md +6 -0
- package/__assets__/package-og.svg +1 -1
- package/dist/index.d.mts +1175 -25
- package/dist/index.d.ts +1175 -25
- package/dist/index.mjs +30 -24
- package/dist/packem_shared/{CONTAINERS_FILENAME-0K-pjNb8.mjs → CONTAINERS_FILENAME-DjpXMqhp.mjs} +1 -1
- package/dist/packem_shared/{CodegenDiagnosticError-54jWDxA9.mjs → CodegenDiagnosticError-DyQ5FwkM.mjs} +7 -5
- package/dist/packem_shared/FLAGS_FILENAME-fEZtzWXi.mjs +139 -0
- package/dist/packem_shared/GENERATED_HEADER-cUyu5VOU.mjs +3 -0
- package/dist/packem_shared/{LUNORA_ERROR_CODES-CySpQPD3.mjs → LUNORA_ERROR_CODES-DvTLozCu.mjs} +8 -1
- package/dist/packem_shared/MUTATORS_FILENAME-BZOfUhlY.mjs +81 -0
- package/dist/packem_shared/{OPENRPC_VERSION-C7zKVeKi.mjs → OPENRPC_VERSION-DxbqafcJ.mjs} +2 -2
- package/dist/packem_shared/QUEUES_FILENAME-Xv6Vy-Ku.mjs +145 -0
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-C1yHg38Z.mjs +3438 -0
- package/dist/packem_shared/{SCHEMA_SNAPSHOT_VERSION-DzLDbWk3.mjs → SCHEMA_SNAPSHOT_VERSION-D0ARY6rL.mjs} +18 -2
- package/dist/packem_shared/SHAPES_FILENAME-DOhPGi-6.mjs +94 -0
- package/dist/packem_shared/{WORKFLOWS_FILENAME-DRDQdhfq.mjs → WORKFLOWS_FILENAME-B2By8S4s.mjs} +70 -2
- package/dist/packem_shared/{buildOpenApiDocument-Cns1EkCQ.mjs → buildOpenApiDocument-_mwWOc2N.mjs} +2 -2
- package/dist/packem_shared/{discoverAuthApiCalls-C35R6z0T.mjs → discoverAuthApiCalls-WMx8L2FG.mjs} +1 -1
- package/dist/packem_shared/{discoverCrons-BL6iGuJ3.mjs → discoverCrons-D-jrpm97.mjs} +22 -20
- package/dist/packem_shared/{discoverFunctions-DEgAcRuD.mjs → discoverFunctions-CZ91aenA.mjs} +72 -14
- package/dist/packem_shared/{discoverHttpRoutes-C978pBiG.mjs → discoverHttpRoutes-DNZLDCmm.mjs} +2 -2
- package/dist/packem_shared/{discoverInserts-CRQdXvHO.mjs → discoverInserts-DFRJhmCv.mjs} +24 -2
- package/dist/packem_shared/{discoverMaskProcedures-B64zA740.mjs → discoverMaskProcedures-B5iFnZ-X.mjs} +58 -2
- package/dist/packem_shared/{discoverMigrations-Doj_-BAA.mjs → discoverMigrations-CdKtMlBc.mjs} +10 -4
- package/dist/packem_shared/{discoverNondeterministicCalls-4KiPQxQU.mjs → discoverNondeterministicCalls-C_PrQPkA.mjs} +1 -1
- package/dist/packem_shared/{discoverQueries-BkIi0dBD.mjs → discoverQueries-B8W9UPrt.mjs} +1 -1
- package/dist/packem_shared/{discoverR2sqlCalls-BpDqvcUn.mjs → discoverR2sqlCalls-Bm7Rfnf4.mjs} +1 -1
- package/dist/packem_shared/{discoverRlsMetadata-DpRB1HMe.mjs → discoverRlsMetadata-B4GL4ZKm.mjs} +1 -1
- package/dist/packem_shared/{discoverSchema-BBulgGbH.mjs → discoverSchema-DFWVgU5o.mjs} +349 -17
- package/dist/packem_shared/{discoverStorageRulesMetadata-DAqJUxUv.mjs → discoverStorageRulesMetadata-nosjYcvN.mjs} +1 -1
- package/dist/packem_shared/{GENERATED_HEADER-DF1hQcix.mjs → emit-CFz-9dcD.mjs} +1100 -122
- package/dist/packem_shared/{emitApp-Ci_hcJNO.mjs → emitApp-D8rVuM__.mjs} +99 -30
- package/dist/packem_shared/formatAdvisories-DRhEiJUz.mjs +114 -0
- package/dist/packem_shared/{parse-validator-tuQtHrsr.mjs → parse-validator-BSJo1HGP.mjs} +18 -6
- package/dist/packem_shared/redact-oTmsol5A.mjs +33 -0
- package/package.json +9 -7
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-C5UlpWKF.mjs +0 -922
- package/dist/packem_shared/formatAdvisories-8NIv1k0I.mjs +0 -69
package/dist/packem_shared/{discoverMigrations-Doj_-BAA.mjs → discoverMigrations-CdKtMlBc.mjs}
RENAMED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { relative, sep } from 'node:path';
|
|
2
2
|
import { SyntaxKind, Node } from 'ts-morph';
|
|
3
|
-
import {
|
|
3
|
+
import { diagnosticAt } from './CodegenDiagnosticError-DyQ5FwkM.mjs';
|
|
4
|
+
import { listLunoraSourceFiles } from './discoverFunctions-CZ91aenA.mjs';
|
|
4
5
|
|
|
5
6
|
const TS_EXTENSION_RE = /\.ts$/u;
|
|
6
7
|
const isDefineMigration = (identifier) => {
|
|
@@ -43,9 +44,14 @@ const migrationFromDeclaration = (declaration, relativePath) => {
|
|
|
43
44
|
const id = stringProperty(argument, "id");
|
|
44
45
|
const exportName = declaration.getName();
|
|
45
46
|
if (id === void 0 || id.trim() === "") {
|
|
46
|
-
throw
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
throw diagnosticAt(
|
|
48
|
+
argument,
|
|
49
|
+
`Migration "${exportName}" in "${relativePath}" must declare \`id\` as a non-empty string literal so codegen can key the registry.`,
|
|
50
|
+
{
|
|
51
|
+
code: "MIGRATION_ID_NOT_STATIC",
|
|
52
|
+
name: "LunoraError",
|
|
53
|
+
status: 500
|
|
54
|
+
}
|
|
49
55
|
);
|
|
50
56
|
}
|
|
51
57
|
return { exportName, filePath: relativePath, id, table: stringProperty(argument, "table") ?? "" };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Node, SyntaxKind } from 'ts-morph';
|
|
2
|
-
import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-
|
|
2
|
+
import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-CZ91aenA.mjs';
|
|
3
3
|
|
|
4
4
|
const PROPERTY_CALLS = {
|
|
5
5
|
"crypto.getRandomValues": "crypto.getRandomValues",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SyntaxKind, Node } from 'ts-morph';
|
|
2
|
-
import { listLunoraSourceFiles, lunoraRelativePath } from './discoverFunctions-
|
|
2
|
+
import { listLunoraSourceFiles, lunoraRelativePath } from './discoverFunctions-CZ91aenA.mjs';
|
|
3
3
|
|
|
4
4
|
const INDEX_METHODS = /* @__PURE__ */ new Set(["withIndex", "withSearchIndex"]);
|
|
5
5
|
const isDatabaseQueryCall = (call) => {
|
package/dist/packem_shared/{discoverR2sqlCalls-BpDqvcUn.mjs → discoverR2sqlCalls-Bm7Rfnf4.mjs}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Node, SyntaxKind } from 'ts-morph';
|
|
2
|
-
import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-
|
|
2
|
+
import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-CZ91aenA.mjs';
|
|
3
3
|
|
|
4
4
|
const handlerOf = (call, receiver) => {
|
|
5
5
|
if (receiver) {
|
package/dist/packem_shared/{discoverRlsMetadata-DpRB1HMe.mjs → discoverRlsMetadata-B4GL4ZKm.mjs}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Node, SyntaxKind } from 'ts-morph';
|
|
2
|
-
import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-
|
|
2
|
+
import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-CZ91aenA.mjs';
|
|
3
3
|
|
|
4
4
|
const isRlsCall = (node) => {
|
|
5
5
|
if (!Node.isCallExpression(node)) {
|
|
@@ -1,6 +1,213 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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,54 @@ 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
|
+
hasTenantBy: first.getProperty("tenantBy") !== void 0,
|
|
432
|
+
idColumn: stringPropertyOf(first, "idColumn"),
|
|
433
|
+
mode: stringPropertyOf(first, "mode"),
|
|
434
|
+
query: stringPropertyOf(first, "query")
|
|
435
|
+
};
|
|
436
|
+
};
|
|
182
437
|
const applyTableMethod = (accumulator, method, args, name) => {
|
|
183
438
|
switch (method) {
|
|
184
439
|
case "externallyManaged": {
|
|
@@ -194,6 +449,10 @@ const applyTableMethod = (accumulator, method, args, name) => {
|
|
|
194
449
|
accumulator.indexes.push(parseIndexCall(args));
|
|
195
450
|
break;
|
|
196
451
|
}
|
|
452
|
+
case "public": {
|
|
453
|
+
accumulator.isPublic = true;
|
|
454
|
+
break;
|
|
455
|
+
}
|
|
197
456
|
case "rankIndex": {
|
|
198
457
|
accumulator.rankIndexes.push(parseRankIndexCall(args));
|
|
199
458
|
break;
|
|
@@ -214,6 +473,15 @@ const applyTableMethod = (accumulator, method, args, name) => {
|
|
|
214
473
|
accumulator.shardMode = { field: field && Node.isStringLiteral(field) ? field.getLiteralText() : "_unknown_", kind: "shardBy" };
|
|
215
474
|
break;
|
|
216
475
|
}
|
|
476
|
+
case "softDelete": {
|
|
477
|
+
accumulator.softDelete = { field: softDeleteFieldOf(args[0]) };
|
|
478
|
+
break;
|
|
479
|
+
}
|
|
480
|
+
case "source": {
|
|
481
|
+
accumulator.externalSource = parseSourceCall(args);
|
|
482
|
+
accumulator.externallyManaged = true;
|
|
483
|
+
break;
|
|
484
|
+
}
|
|
217
485
|
case "vectorize": {
|
|
218
486
|
const vectorIndex = parseVectorizeCall(args, name);
|
|
219
487
|
if (vectorIndex) {
|
|
@@ -227,6 +495,7 @@ const parseTableBuilder = (expression, name) => {
|
|
|
227
495
|
const accumulator = {
|
|
228
496
|
externallyManaged: false,
|
|
229
497
|
indexes: [],
|
|
498
|
+
isPublic: false,
|
|
230
499
|
rankIndexes: [],
|
|
231
500
|
relations: [],
|
|
232
501
|
searchIndexes: [],
|
|
@@ -251,16 +520,22 @@ const parseTableBuilder = (expression, name) => {
|
|
|
251
520
|
break;
|
|
252
521
|
}
|
|
253
522
|
}
|
|
523
|
+
if (accumulator.softDelete && !(accumulator.softDelete.field in shape)) {
|
|
524
|
+
shape = { ...shape, [accumulator.softDelete.field]: { inner: { kind: "number" }, kind: "optional" } };
|
|
525
|
+
}
|
|
254
526
|
return {
|
|
255
527
|
externallyManaged: accumulator.externallyManaged,
|
|
528
|
+
externalSource: accumulator.externalSource,
|
|
256
529
|
globalBackend: accumulator.shardMode === "global" ? accumulator.globalBackend ?? "d1" : void 0,
|
|
257
530
|
indexes: accumulator.indexes,
|
|
531
|
+
isPublic: accumulator.isPublic,
|
|
258
532
|
name,
|
|
259
533
|
rankIndexes: accumulator.rankIndexes,
|
|
260
534
|
relations: accumulator.relations,
|
|
261
535
|
searchIndexes: accumulator.searchIndexes,
|
|
262
536
|
shape,
|
|
263
537
|
shardMode: accumulator.shardMode,
|
|
538
|
+
softDelete: accumulator.softDelete,
|
|
264
539
|
vectorIndexes: accumulator.vectorIndexes
|
|
265
540
|
};
|
|
266
541
|
};
|
|
@@ -354,7 +629,27 @@ const extensionTargetIdentifier = (argument) => {
|
|
|
354
629
|
return argument;
|
|
355
630
|
}
|
|
356
631
|
if (Node.isPropertyAccessExpression(argument)) {
|
|
357
|
-
|
|
632
|
+
const receiver = argument.getExpression();
|
|
633
|
+
return Node.isIdentifier(receiver) ? receiver : void 0;
|
|
634
|
+
}
|
|
635
|
+
return void 0;
|
|
636
|
+
};
|
|
637
|
+
const pluginConfigObject = (expression) => {
|
|
638
|
+
if (Node.isObjectLiteralExpression(expression)) {
|
|
639
|
+
return expression;
|
|
640
|
+
}
|
|
641
|
+
if (Node.isCallExpression(expression)) {
|
|
642
|
+
const callee = expression.getExpression();
|
|
643
|
+
let name;
|
|
644
|
+
if (Node.isIdentifier(callee)) {
|
|
645
|
+
name = callee.getText();
|
|
646
|
+
} else if (Node.isPropertyAccessExpression(callee)) {
|
|
647
|
+
name = callee.getName();
|
|
648
|
+
}
|
|
649
|
+
if (name === "definePlugin") {
|
|
650
|
+
const configArgument = expression.getArguments()[1];
|
|
651
|
+
return configArgument && Node.isObjectLiteralExpression(configArgument) ? configArgument : void 0;
|
|
652
|
+
}
|
|
358
653
|
}
|
|
359
654
|
return void 0;
|
|
360
655
|
};
|
|
@@ -363,8 +658,9 @@ const nextExpressionFromDeclaration = (declaration, argument) => {
|
|
|
363
658
|
if (!initializer) {
|
|
364
659
|
return void 0;
|
|
365
660
|
}
|
|
366
|
-
if (Node.isPropertyAccessExpression(argument)
|
|
367
|
-
|
|
661
|
+
if (Node.isPropertyAccessExpression(argument)) {
|
|
662
|
+
const configObject = pluginConfigObject(initializer);
|
|
663
|
+
return configObject ? objectPropertyInitializer(configObject, argument.getName()) : void 0;
|
|
368
664
|
}
|
|
369
665
|
return initializer;
|
|
370
666
|
};
|
|
@@ -434,24 +730,30 @@ const parseExtensionVectorIndexes = (options) => {
|
|
|
434
730
|
}
|
|
435
731
|
return parseStandaloneVectorIndexes(object);
|
|
436
732
|
};
|
|
437
|
-
const
|
|
438
|
-
const bareTables = parseExtensionTables(options);
|
|
733
|
+
const namespaceExtension = (key, bareTables, bareVectorIndexes) => {
|
|
439
734
|
const bareNames = new Set(bareTables.map((table) => table.name));
|
|
440
735
|
const tables = bareTables.map((table) => namespaceExtensionTable(table, key, bareNames));
|
|
441
|
-
const vectorIndexes =
|
|
736
|
+
const vectorIndexes = bareVectorIndexes.map((index) => {
|
|
442
737
|
return { ...index, name: prefixTableName(key, index.name), table: rewriteReference(index.table, key, bareNames) };
|
|
443
738
|
});
|
|
444
739
|
return { tables, vectorIndexes };
|
|
445
740
|
};
|
|
446
|
-
const
|
|
741
|
+
const mergeExtension = (key, options) => namespaceExtension(key, parseExtensionTables(options), parseExtensionVectorIndexes(options));
|
|
742
|
+
const mergeExtendCall = (extendCall, projectRoot) => {
|
|
447
743
|
const extendArgument = extendCall.getArguments()[0];
|
|
448
744
|
if (!extendArgument) {
|
|
449
745
|
return void 0;
|
|
450
746
|
}
|
|
451
747
|
const resolved = resolveSchemaExtensionCall(extendArgument);
|
|
452
748
|
if (!resolved) {
|
|
749
|
+
if (projectRoot !== void 0) {
|
|
750
|
+
const fromPackage = resolvePackageExtension(extendArgument, projectRoot);
|
|
751
|
+
if (fromPackage) {
|
|
752
|
+
return namespaceExtension(fromPackage.key, fromPackage.bareTables, fromPackage.bareVectorIndexes);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
453
755
|
console.warn(
|
|
454
|
-
`@lunora/codegen: skipping \`.extend(${extendArgument.getText()})\` — its \`defineSchemaExtension(...)\`
|
|
756
|
+
`@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.`
|
|
455
757
|
);
|
|
456
758
|
return void 0;
|
|
457
759
|
}
|
|
@@ -481,6 +783,36 @@ const extendCallsOf = (defineSchemaCall) => {
|
|
|
481
783
|
}
|
|
482
784
|
return calls;
|
|
483
785
|
};
|
|
786
|
+
const chainedStringLiteralArgument = (defineSchemaCall, methodName, noun, allowed, expected) => {
|
|
787
|
+
let current = defineSchemaCall;
|
|
788
|
+
for (; ; ) {
|
|
789
|
+
const parent = current.getParent();
|
|
790
|
+
if (!parent || !Node.isPropertyAccessExpression(parent)) {
|
|
791
|
+
break;
|
|
792
|
+
}
|
|
793
|
+
const callParent = parent.getParent();
|
|
794
|
+
if (!callParent || !Node.isCallExpression(callParent)) {
|
|
795
|
+
break;
|
|
796
|
+
}
|
|
797
|
+
if (parent.getName() === methodName) {
|
|
798
|
+
const argument = callParent.getArguments()[0];
|
|
799
|
+
if (!argument || !Node.isStringLiteral(argument)) {
|
|
800
|
+
throw diagnosticAt(callParent, `\`.${methodName}(...)\` expects a string literal (${expected})`);
|
|
801
|
+
}
|
|
802
|
+
const value = argument.getLiteralText();
|
|
803
|
+
if (!allowed.has(value)) {
|
|
804
|
+
throw diagnosticAt(argument, `unknown ${noun} ${JSON.stringify(value)} — expected ${expected}`);
|
|
805
|
+
}
|
|
806
|
+
return value;
|
|
807
|
+
}
|
|
808
|
+
current = callParent;
|
|
809
|
+
}
|
|
810
|
+
return void 0;
|
|
811
|
+
};
|
|
812
|
+
const JURISDICTIONS = /* @__PURE__ */ new Set(["eu", "fedramp", "us"]);
|
|
813
|
+
const jurisdictionOf = (defineSchemaCall) => chainedStringLiteralArgument(defineSchemaCall, "jurisdiction", "jurisdiction", JURISDICTIONS, '"eu", "us", or "fedramp"');
|
|
814
|
+
const RLS_MODES = /* @__PURE__ */ new Set(["required"]);
|
|
815
|
+
const rlsModeOf = (defineSchemaCall) => chainedStringLiteralArgument(defineSchemaCall, "rls", "rls mode", RLS_MODES, '"required"');
|
|
484
816
|
const parseBaseTables = (object) => {
|
|
485
817
|
const tables = [];
|
|
486
818
|
for (const property of object.getProperties()) {
|
|
@@ -496,11 +828,11 @@ const parseBaseTables = (object) => {
|
|
|
496
828
|
}
|
|
497
829
|
return tables;
|
|
498
830
|
};
|
|
499
|
-
const applyExtensions = (defineSchemaCall, tables) => {
|
|
831
|
+
const applyExtensions = (defineSchemaCall, tables, projectRoot) => {
|
|
500
832
|
const existingTableNames = new Set(tables.map((table) => table.name));
|
|
501
833
|
const vectorIndexes = [];
|
|
502
834
|
for (const extendCall of extendCallsOf(defineSchemaCall)) {
|
|
503
|
-
const merged = mergeExtendCall(extendCall);
|
|
835
|
+
const merged = mergeExtendCall(extendCall, projectRoot);
|
|
504
836
|
if (!merged) {
|
|
505
837
|
continue;
|
|
506
838
|
}
|
|
@@ -518,14 +850,14 @@ const applyExtensions = (defineSchemaCall, tables) => {
|
|
|
518
850
|
}
|
|
519
851
|
return vectorIndexes;
|
|
520
852
|
};
|
|
521
|
-
const discoverSchema = (project, schemaPath) => {
|
|
853
|
+
const discoverSchema = (project, schemaPath, projectRoot) => {
|
|
522
854
|
const file = project.addSourceFileAtPath(schemaPath);
|
|
523
855
|
const defineSchemaCall = file.getDescendantsOfKind(SyntaxKind.CallExpression).find((call) => {
|
|
524
856
|
const callee = call.getExpression();
|
|
525
857
|
return Node.isIdentifier(callee) && callee.getText() === "defineSchema";
|
|
526
858
|
});
|
|
527
859
|
if (!defineSchemaCall) {
|
|
528
|
-
throw new
|
|
860
|
+
throw new LunoraError("INTERNAL", `defineSchema() not found in ${schemaPath}`);
|
|
529
861
|
}
|
|
530
862
|
const argument = defineSchemaCall.getArguments()[0];
|
|
531
863
|
if (!argument || !Node.isObjectLiteralExpression(argument)) {
|
|
@@ -534,9 +866,9 @@ const discoverSchema = (project, schemaPath) => {
|
|
|
534
866
|
const tables = parseBaseTables(argument);
|
|
535
867
|
const standaloneArgument = defineSchemaCall.getArguments()[1];
|
|
536
868
|
const standaloneVectorIndexes = standaloneArgument && Node.isObjectLiteralExpression(standaloneArgument) ? parseStandaloneVectorIndexes(standaloneArgument) : [];
|
|
537
|
-
const extensionStandaloneVectorIndexes = applyExtensions(defineSchemaCall, tables);
|
|
869
|
+
const extensionStandaloneVectorIndexes = applyExtensions(defineSchemaCall, tables, projectRoot);
|
|
538
870
|
const vectorIndexes = [...tables.flatMap((table) => table.vectorIndexes), ...standaloneVectorIndexes, ...extensionStandaloneVectorIndexes];
|
|
539
|
-
return { tables, vectorIndexes };
|
|
871
|
+
return { jurisdiction: jurisdictionOf(defineSchemaCall), rlsMode: rlsModeOf(defineSchemaCall), tables, vectorIndexes };
|
|
540
872
|
};
|
|
541
873
|
|
|
542
874
|
export { discoverSchema as default };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Node } from 'ts-morph';
|
|
2
|
-
import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-
|
|
2
|
+
import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-CZ91aenA.mjs';
|
|
3
3
|
|
|
4
4
|
const STORAGE_OPERATIONS = /* @__PURE__ */ new Set(["delete", "list", "read", "write"]);
|
|
5
5
|
const isStorageRulesCall = (node) => {
|