@lunora/codegen 1.0.0-alpha.8 → 1.0.0-alpha.9

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 (24) hide show
  1. package/__assets__/package-og.svg +1 -1
  2. package/dist/index.d.mts +14 -1
  3. package/dist/index.d.ts +14 -1
  4. package/dist/index.mjs +18 -18
  5. package/dist/packem_shared/{GENERATED_HEADER-DF1hQcix.mjs → GENERATED_HEADER-LceqJ_qp.mjs} +200 -7
  6. package/dist/packem_shared/{OPENRPC_VERSION-C7zKVeKi.mjs → OPENRPC_VERSION-s7lhywUr.mjs} +1 -1
  7. package/dist/packem_shared/{SCHEMA_SNAPSHOT_FILENAME-Ic_wUaIc.mjs → SCHEMA_SNAPSHOT_FILENAME-Ct0NDRLY.mjs} +18 -18
  8. package/dist/packem_shared/{buildOpenApiDocument-Cns1EkCQ.mjs → buildOpenApiDocument-DSPTssJI.mjs} +1 -1
  9. package/dist/packem_shared/{discoverAuthApiCalls-C35R6z0T.mjs → discoverAuthApiCalls-CoirYbg6.mjs} +1 -1
  10. package/dist/packem_shared/{discoverCrons-nHPo3UeE.mjs → discoverCrons-Cev7RRAf.mjs} +1 -1
  11. package/dist/packem_shared/{discoverFunctions-DEgAcRuD.mjs → discoverFunctions-BWMczzBx.mjs} +7 -2
  12. package/dist/packem_shared/{discoverHttpRoutes-C978pBiG.mjs → discoverHttpRoutes-CfP6cMzt.mjs} +2 -2
  13. package/dist/packem_shared/{discoverInserts-pLBFsSAV.mjs → discoverInserts-C7zxXkUf.mjs} +1 -1
  14. package/dist/packem_shared/{discoverMaskProcedures-B64zA740.mjs → discoverMaskProcedures-Cm81kwrb.mjs} +1 -1
  15. package/dist/packem_shared/{discoverMigrations-Dy24kmeD.mjs → discoverMigrations-Bi5nJ0mJ.mjs} +1 -1
  16. package/dist/packem_shared/{discoverNondeterministicCalls-4KiPQxQU.mjs → discoverNondeterministicCalls-C4M8AXmQ.mjs} +1 -1
  17. package/dist/packem_shared/{discoverQueries-BkIi0dBD.mjs → discoverQueries-B0wGT-xe.mjs} +1 -1
  18. package/dist/packem_shared/{discoverR2sqlCalls-BpDqvcUn.mjs → discoverR2sqlCalls-BVNMd428.mjs} +1 -1
  19. package/dist/packem_shared/{discoverRlsMetadata-DpRB1HMe.mjs → discoverRlsMetadata-BS9GOGC5.mjs} +1 -1
  20. package/dist/packem_shared/{discoverSchema-fVmAXacI.mjs → discoverSchema-BF6L4mrU.mjs} +21 -1
  21. package/dist/packem_shared/{discoverStorageRulesMetadata-DAqJUxUv.mjs → discoverStorageRulesMetadata-Da8BKXcI.mjs} +1 -1
  22. package/dist/packem_shared/{emitApp-Ci_hcJNO.mjs → emitApp-CDg72pVv.mjs} +1 -1
  23. package/dist/packem_shared/{parse-validator-tuQtHrsr.mjs → parse-validator-Cabb60UV.mjs} +2 -1
  24. package/package.json +4 -4
package/dist/index.d.mts CHANGED
@@ -25,6 +25,15 @@ interface ValidatorIR {
25
25
  bucket?: string;
26
26
  /** Column modifiers (`.unique()`, `.default()`, `.nullable()`, …) when present. */
27
27
  column?: ColumnMetaIR;
28
+ /**
29
+ * `true` when this validator carries a `.check(...)` refinement. The predicate
30
+ * is a runtime closure the AST→IR step can't represent, so the node keeps its
31
+ * base `kind` but records the refinement's presence here. The AOT args-validator
32
+ * compiler declines any node with this flag (compiling it would silently skip
33
+ * the predicate). `.meta(...)` is pure metadata with no parse effect and does
34
+ * NOT set this.
35
+ */
36
+ hasRefinement?: boolean;
28
37
  /** For `v.optional(inner)` / `v.array(inner)`. */
29
38
  inner?: ValidatorIR;
30
39
  /** For `v.record(key, value)`. */
@@ -126,6 +135,10 @@ interface TableIR {
126
135
  field: string;
127
136
  kind: "shardBy";
128
137
  };
138
+ /** Set when the chain carried `.softDelete()` — the marker column's name (default `deletedAt`). The column is injected into `shape` so `Doc_*` carries it. */
139
+ softDelete?: {
140
+ field: string;
141
+ };
129
142
  /** Vector indexes declared inline via `.vectorize()` (DSL Shape A). */
130
143
  vectorIndexes: ReadonlyArray<VectorIndexIR>;
131
144
  }
@@ -940,7 +953,7 @@ declare const emitServer: ({
940
953
  useUmbrella,
941
954
  workflows
942
955
  }?: EmitServerOptions) => string;
943
- declare const emitFunctions: (functions: ReadonlyArray<FunctionIR>, migrations?: ReadonlyArray<MigrationIR>) => string;
956
+ declare const emitFunctions: (functions: ReadonlyArray<FunctionIR>, migrations?: ReadonlyArray<MigrationIR>, useUmbrella?: boolean) => string;
944
957
  /**
945
958
  * Storage-column map per table for the file browser: `{ table: [field, …] }` for
946
959
  * every field declared `v.storage(...)` (unwrapping `v.optional(...)`). The
package/dist/index.d.ts CHANGED
@@ -25,6 +25,15 @@ interface ValidatorIR {
25
25
  bucket?: string;
26
26
  /** Column modifiers (`.unique()`, `.default()`, `.nullable()`, …) when present. */
27
27
  column?: ColumnMetaIR;
28
+ /**
29
+ * `true` when this validator carries a `.check(...)` refinement. The predicate
30
+ * is a runtime closure the AST→IR step can't represent, so the node keeps its
31
+ * base `kind` but records the refinement's presence here. The AOT args-validator
32
+ * compiler declines any node with this flag (compiling it would silently skip
33
+ * the predicate). `.meta(...)` is pure metadata with no parse effect and does
34
+ * NOT set this.
35
+ */
36
+ hasRefinement?: boolean;
28
37
  /** For `v.optional(inner)` / `v.array(inner)`. */
29
38
  inner?: ValidatorIR;
30
39
  /** For `v.record(key, value)`. */
@@ -126,6 +135,10 @@ interface TableIR {
126
135
  field: string;
127
136
  kind: "shardBy";
128
137
  };
138
+ /** Set when the chain carried `.softDelete()` — the marker column's name (default `deletedAt`). The column is injected into `shape` so `Doc_*` carries it. */
139
+ softDelete?: {
140
+ field: string;
141
+ };
129
142
  /** Vector indexes declared inline via `.vectorize()` (DSL Shape A). */
130
143
  vectorIndexes: ReadonlyArray<VectorIndexIR>;
131
144
  }
@@ -940,7 +953,7 @@ declare const emitServer: ({
940
953
  useUmbrella,
941
954
  workflows
942
955
  }?: EmitServerOptions) => string;
943
- declare const emitFunctions: (functions: ReadonlyArray<FunctionIR>, migrations?: ReadonlyArray<MigrationIR>) => string;
956
+ declare const emitFunctions: (functions: ReadonlyArray<FunctionIR>, migrations?: ReadonlyArray<MigrationIR>, useUmbrella?: boolean) => string;
944
957
  /**
945
958
  * Storage-column map per table for the file browser: `{ table: [field, …] }` for
946
959
  * every field declared `v.storage(...)` (unwrapping `v.optional(...)`). The
package/dist/index.mjs CHANGED
@@ -1,25 +1,25 @@
1
1
  export { formatAdvisories, lintSchema } from './packem_shared/formatAdvisories-8NIv1k0I.mjs';
2
2
  export { CodegenDiagnosticError, diagnosticAt } from './packem_shared/CodegenDiagnosticError-DeblMkzO.mjs';
3
- export { default as discoverAuthApiCalls } from './packem_shared/discoverAuthApiCalls-C35R6z0T.mjs';
3
+ export { default as discoverAuthApiCalls } from './packem_shared/discoverAuthApiCalls-CoirYbg6.mjs';
4
4
  export { CONTAINERS_FILENAME, discoverContainers } from './packem_shared/CONTAINERS_FILENAME-DlP6YM_Q.mjs';
5
- export { default as discoverCrons } from './packem_shared/discoverCrons-nHPo3UeE.mjs';
6
- export { discoverFunctions } from './packem_shared/discoverFunctions-DEgAcRuD.mjs';
7
- export { default as discoverHttpRoutes } from './packem_shared/discoverHttpRoutes-C978pBiG.mjs';
8
- export { default as discoverInserts } from './packem_shared/discoverInserts-pLBFsSAV.mjs';
9
- export { default as discoverMaskProcedures } from './packem_shared/discoverMaskProcedures-B64zA740.mjs';
10
- export { default as discoverMigrations } from './packem_shared/discoverMigrations-Dy24kmeD.mjs';
11
- export { default as discoverNondeterministicCalls } from './packem_shared/discoverNondeterministicCalls-4KiPQxQU.mjs';
12
- export { default as discoverQueries } from './packem_shared/discoverQueries-BkIi0dBD.mjs';
13
- export { default as discoverR2sqlCalls } from './packem_shared/discoverR2sqlCalls-BpDqvcUn.mjs';
14
- export { discoverRlsMetadata, default as discoverRlsProcedures } from './packem_shared/discoverRlsMetadata-DpRB1HMe.mjs';
15
- export { default as discoverSchema } from './packem_shared/discoverSchema-fVmAXacI.mjs';
16
- export { default as discoverStorageRulesMetadata } from './packem_shared/discoverStorageRulesMetadata-DAqJUxUv.mjs';
5
+ export { default as discoverCrons } from './packem_shared/discoverCrons-Cev7RRAf.mjs';
6
+ export { discoverFunctions } from './packem_shared/discoverFunctions-BWMczzBx.mjs';
7
+ export { default as discoverHttpRoutes } from './packem_shared/discoverHttpRoutes-CfP6cMzt.mjs';
8
+ export { default as discoverInserts } from './packem_shared/discoverInserts-C7zxXkUf.mjs';
9
+ export { default as discoverMaskProcedures } from './packem_shared/discoverMaskProcedures-Cm81kwrb.mjs';
10
+ export { default as discoverMigrations } from './packem_shared/discoverMigrations-Bi5nJ0mJ.mjs';
11
+ export { default as discoverNondeterministicCalls } from './packem_shared/discoverNondeterministicCalls-C4M8AXmQ.mjs';
12
+ export { default as discoverQueries } from './packem_shared/discoverQueries-B0wGT-xe.mjs';
13
+ export { default as discoverR2sqlCalls } from './packem_shared/discoverR2sqlCalls-BVNMd428.mjs';
14
+ export { discoverRlsMetadata, default as discoverRlsProcedures } from './packem_shared/discoverRlsMetadata-BS9GOGC5.mjs';
15
+ export { default as discoverSchema } from './packem_shared/discoverSchema-BF6L4mrU.mjs';
16
+ export { default as discoverStorageRulesMetadata } from './packem_shared/discoverStorageRulesMetadata-Da8BKXcI.mjs';
17
17
  export { WORKFLOWS_FILENAME, discoverWorkflows } from './packem_shared/WORKFLOWS_FILENAME-D62dcBGg.mjs';
18
- export { GENERATED_HEADER, emitApi, emitContainers, emitCrons, emitDataModel, emitDrizzleSchema, emitFunctions, emitServer, emitShard, emitVectors, emitWorkflows, emitWranglerCronTriggers } from './packem_shared/GENERATED_HEADER-DF1hQcix.mjs';
19
- export { emitApp } from './packem_shared/emitApp-Ci_hcJNO.mjs';
20
- export { buildOpenApiDocument, emitOpenApi, emitOpenApiModule } from './packem_shared/buildOpenApiDocument-Cns1EkCQ.mjs';
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-Ic_wUaIc.mjs';
18
+ export { GENERATED_HEADER, emitApi, emitContainers, emitCrons, emitDataModel, emitDrizzleSchema, emitFunctions, emitServer, emitShard, emitVectors, emitWorkflows, emitWranglerCronTriggers } from './packem_shared/GENERATED_HEADER-LceqJ_qp.mjs';
19
+ export { emitApp } from './packem_shared/emitApp-CDg72pVv.mjs';
20
+ export { buildOpenApiDocument, emitOpenApi, emitOpenApiModule } from './packem_shared/buildOpenApiDocument-DSPTssJI.mjs';
21
+ export { OPENRPC_VERSION, buildOpenRpcDocument, emitOpenRpc, emitOpenRpcModule } from './packem_shared/OPENRPC_VERSION-s7lhywUr.mjs';
22
+ export { SCHEMA_SNAPSHOT_FILENAME, createCodegenProject, refreshCodegenProject, runCodegen } from './packem_shared/SCHEMA_SNAPSHOT_FILENAME-Ct0NDRLY.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';
@@ -1,5 +1,174 @@
1
1
  import { s as sanitizeNamespace } from './paths-BRd6JHuF.mjs';
2
2
 
3
+ const LITERAL_VALUE_RE = /^(?:"[^"\\]*"|'[^'\\]*'|-?\d+(?:\.\d+)?|true|false|null)$/u;
4
+
5
+ const PASS_THROUGH_KINDS = /* @__PURE__ */ new Set(["any", "bigint", "boolean", "date", "id", "null", "number", "storage", "string", "timestamp"]);
6
+ const hasColumnModifier = (node) => node.column !== void 0;
7
+ const emitScalarGuard = (kind, inExpr) => {
8
+ switch (kind) {
9
+ case "bigint": {
10
+ return `if (typeof ${inExpr} !== "bigint") return DEFER;
11
+ `;
12
+ }
13
+ case "boolean": {
14
+ return `if (typeof ${inExpr} !== "boolean") return DEFER;
15
+ `;
16
+ }
17
+ case "date":
18
+ case "number":
19
+ case "timestamp": {
20
+ return `if (typeof ${inExpr} !== "number" || !Number.isFinite(${inExpr})) return DEFER;
21
+ `;
22
+ }
23
+ case "null": {
24
+ return `if (${inExpr} !== null) return DEFER;
25
+ `;
26
+ }
27
+ // string / id / storage all parse as a bare string at runtime.
28
+ default: {
29
+ return `if (typeof ${inExpr} !== "string") return DEFER;
30
+ `;
31
+ }
32
+ }
33
+ };
34
+ const compileLiteral = (node, inExpr) => {
35
+ const literal = node.literalValue?.trim();
36
+ if (literal === void 0 || !LITERAL_VALUE_RE.test(literal)) {
37
+ return void 0;
38
+ }
39
+ return { out: inExpr, pre: `if (${inExpr} !== ${literal}) return DEFER;
40
+ ` };
41
+ };
42
+ const compileNode = (node, inExpr, context) => {
43
+ if (hasColumnModifier(node)) {
44
+ return void 0;
45
+ }
46
+ if (node.hasRefinement || node.sourceText !== void 0) {
47
+ return void 0;
48
+ }
49
+ if (PASS_THROUGH_KINDS.has(node.kind)) {
50
+ if (node.kind === "any") {
51
+ return { out: inExpr, pre: "" };
52
+ }
53
+ return { out: inExpr, pre: emitScalarGuard(node.kind, inExpr) };
54
+ }
55
+ switch (node.kind) {
56
+ case "array": {
57
+ return compileArray(node, inExpr, context);
58
+ }
59
+ case "literal": {
60
+ return compileLiteral(node, inExpr);
61
+ }
62
+ case "object": {
63
+ return compileObject(node, inExpr, context);
64
+ }
65
+ default: {
66
+ return void 0;
67
+ }
68
+ }
69
+ };
70
+ const compileArray = (node, inExpr, context) => {
71
+ const { inner } = node;
72
+ if (!inner) {
73
+ return void 0;
74
+ }
75
+ const id = context.next();
76
+ const array = `__arr${String(id)}`;
77
+ const index = `__i${String(id)}`;
78
+ const element = `__e${String(id)}`;
79
+ const innerEmit = compileNode(inner, element, context);
80
+ if (!innerEmit) {
81
+ return void 0;
82
+ }
83
+ const pre = `if (!Array.isArray(${inExpr})) return DEFER;
84
+ const ${array} = new Array(${inExpr}.length);
85
+ for (let ${index} = 0; ${index} < ${inExpr}.length; ${index}++) {
86
+ const ${element} = ${inExpr}[${index}];
87
+ ${innerEmit.pre}${array}[${index}] = ${innerEmit.out};
88
+ }
89
+ `;
90
+ return { out: array, pre };
91
+ };
92
+ const compileField = (key, node, access, context) => {
93
+ const keyLiteral = JSON.stringify(key);
94
+ if (node.kind === "optional") {
95
+ if (node.hasRefinement || node.sourceText !== void 0 || hasColumnModifier(node)) {
96
+ return void 0;
97
+ }
98
+ const { inner } = node;
99
+ if (!inner) {
100
+ return void 0;
101
+ }
102
+ const innerEmit = compileNode(inner, access, context);
103
+ if (!innerEmit) {
104
+ return void 0;
105
+ }
106
+ const id = context.next();
107
+ const has = `__has${String(id)}`;
108
+ const value = `__val${String(id)}`;
109
+ const pre = `let ${has} = false;
110
+ let ${value};
111
+ if (${access} !== undefined) {
112
+ ${innerEmit.pre}${value} = ${innerEmit.out};
113
+ ${has} = true;
114
+ }
115
+ `;
116
+ return { entry: `...(${has} ? { ${keyLiteral}: ${value} } : {})`, pre };
117
+ }
118
+ const emit = compileNode(node, access, context);
119
+ if (!emit) {
120
+ return void 0;
121
+ }
122
+ return { entry: `${keyLiteral}: ${emit.out}`, pre: emit.pre };
123
+ };
124
+ const compileFields = (shape, accessFor, context) => {
125
+ let pre = "";
126
+ const entries = [];
127
+ for (const key of Object.keys(shape)) {
128
+ const node = shape[key];
129
+ if (!node) {
130
+ return void 0;
131
+ }
132
+ const field = compileField(key, node, accessFor(key), context);
133
+ if (!field) {
134
+ return void 0;
135
+ }
136
+ pre += field.pre;
137
+ entries.push(field.entry);
138
+ }
139
+ return { entries: entries.join(", "), pre };
140
+ };
141
+ const compileObject = (node, inExpr, context) => {
142
+ const shape = node.shape ?? {};
143
+ const fields = compileFields(shape, (key) => `${inExpr}[${JSON.stringify(key)}]`, context);
144
+ if (!fields) {
145
+ return void 0;
146
+ }
147
+ const id = context.next();
148
+ const object = `__obj${String(id)}`;
149
+ const pre = `if (typeof ${inExpr} !== "object" || ${inExpr} === null || Array.isArray(${inExpr})) return DEFER;
150
+ ${fields.pre}const ${object} = { ${fields.entries} };
151
+ `;
152
+ return { out: object, pre };
153
+ };
154
+ const compileArgsValidator = (args) => {
155
+ let counter = 0;
156
+ const context = {
157
+ next: () => {
158
+ counter += 1;
159
+ return counter;
160
+ }
161
+ };
162
+ const fields = compileFields(args, (key) => `source[${JSON.stringify(key)}]`, context);
163
+ if (!fields) {
164
+ return void 0;
165
+ }
166
+ return `(source) => {
167
+ if (typeof source !== "object" || source === null || Array.isArray(source)) return DEFER;
168
+ ${fields.pre}return { ${fields.entries} };
169
+ }`;
170
+ };
171
+
3
172
  const GENERATED_HEADER = "// GENERATED by @lunora/codegen — do not edit.\n// Run `lunora codegen` to regenerate.\n\n";
4
173
  const baseSpecifiers = (useUmbrella = false) => useUmbrella ? {
5
174
  client: "lunorash/client",
@@ -7,17 +176,18 @@ const baseSpecifiers = (useUmbrella = false) => useUmbrella ? {
7
176
  server: "lunorash/server",
8
177
  serverDataModel: "lunorash/server/data-model",
9
178
  serverDrizzle: "lunorash/server/drizzle",
10
- serverTypes: "lunorash/server/types"
179
+ serverTypes: "lunorash/server/types",
180
+ values: "lunorash/values"
11
181
  } : {
12
182
  client: "@lunora/client",
13
183
  do: "@lunora/do",
14
184
  server: "@lunora/server",
15
185
  serverDataModel: "@lunora/server/data-model",
16
186
  serverDrizzle: "@lunora/server/drizzle",
17
- serverTypes: "@lunora/server/types"
187
+ serverTypes: "@lunora/server/types",
188
+ values: "@lunora/values"
18
189
  };
19
190
  const IDENTIFIER_RE = /^[A-Za-z_$][\w$]*$/u;
20
- const LITERAL_VALUE_RE = /^(?:"[^"\\]*"|'[^'\\]*'|-?\d+(?:\.\d+)?|true|false|null)$/u;
21
191
  const IMPORT_PATH_RE = /^[\w./-]+$/u;
22
192
  const assertIdentifier = (value, context) => {
23
193
  if (!IDENTIFIER_RE.test(value)) {
@@ -469,6 +639,17 @@ const renderFunctionRegistry = (functions, migrations) => {
469
639
  const migrationEntries = migrations.map(
470
640
  (migration) => ` ${JSON.stringify(migration.id)}: ${aliasByPath.get(migration.filePath) ?? ""}.${migration.exportName} as unknown as RegisteredDataMigration,`
471
641
  ).join("\n");
642
+ const installLines = functions.map((definition) => {
643
+ if (definition.lifecycle || Object.keys(definition.args).length === 0) {
644
+ return void 0;
645
+ }
646
+ const compiled = compileArgsValidator(definition.args);
647
+ if (compiled === void 0) {
648
+ return void 0;
649
+ }
650
+ const alias = aliasByPath.get(definition.filePath) ?? "";
651
+ return `installCompiledValidatorMap(${alias}.${definition.exportName}.args, ${compiled});`;
652
+ }).filter((line) => line !== void 0).join("\n");
472
653
  return {
473
654
  dispatchBody: dispatchEntries.length > 0 ? `
474
655
  ${dispatchEntries}
@@ -476,6 +657,7 @@ ${dispatchEntries}
476
657
  importBlock: importLines.length > 0 ? `${importLines}
477
658
 
478
659
  ` : "",
660
+ installBlock: installLines,
479
661
  migrationBody: migrationEntries.length > 0 ? `
480
662
  ${migrationEntries}
481
663
  ` : ""
@@ -777,10 +959,21 @@ const renderLifecycleManifest = (functions) => {
777
959
  }
778
960
  return manifest;
779
961
  };
780
- const emitFunctions = (functions, migrations = []) => {
962
+ const emitFunctions = (functions, migrations = [], useUmbrella = false) => {
781
963
  const hasFunctions = functions.length > 0;
782
- const { dispatchBody, importBlock, migrationBody } = renderFunctionRegistry(functions, migrations);
964
+ const base = baseSpecifiers(useUmbrella);
965
+ const { dispatchBody, importBlock, installBlock, migrationBody } = renderFunctionRegistry(functions, migrations);
783
966
  const lifecycleHooks = renderLifecycleManifest(functions);
967
+ const compiledArgsImport = installBlock.length > 0 ? `import { DEFER_VALIDATION as DEFER, installCompiledValidatorMap } from "${base.values}";
968
+ ` : "";
969
+ const compiledArgsInstall = installBlock.length > 0 ? `
970
+ /**
971
+ * AOT-compiled argument validators (Worker-safe, no \`eval\`). Each is installed
972
+ * onto its function's live \`.args\` object and consulted by the interpreted
973
+ * parser as a zero-allocation fast path; anything it can't model is deferred.
974
+ */
975
+ ${installBlock}
976
+ ` : "";
784
977
  const caller = renderCaller(functions);
785
978
  const callerTypes = caller.types ? `
786
979
  ${caller.types}
@@ -795,7 +988,7 @@ ${caller.implementation}
795
988
  const callRegisteredHelper = hasFunctions ? `${CALL_REGISTERED_HELPER}
796
989
 
797
990
  ` : "";
798
- return `${GENERATED_HEADER}${importBlock}import type { ActionCtx, MutationCtx, QueryCtx } from "./server.js";
991
+ return `${GENERATED_HEADER}${importBlock}${compiledArgsImport}import type { ActionCtx, MutationCtx, QueryCtx } from "./server.js";
799
992
  ${dataModelImport}
800
993
  /**
801
994
  * Single registered function, narrowed to the shape \`handleRpc\` needs.
@@ -821,7 +1014,7 @@ export interface RegisteredLunoraFunction {
821
1014
  * emits (\`api[namespace][fn].__lunoraRef === "namespace:fn"\`).
822
1015
  */
823
1016
  export const LUNORA_FUNCTIONS: Record<string, RegisteredLunoraFunction> = {${dispatchBody}};
824
-
1017
+ ${compiledArgsInstall}
825
1018
  /**
826
1019
  * Connection-lifecycle manifest: the function paths the generated ShardDO
827
1020
  * dispatches when a client's WebSocket connects (\`connect\`) or disconnects
@@ -1,4 +1,4 @@
1
- import { GENERATED_HEADER } from './GENERATED_HEADER-DF1hQcix.mjs';
1
+ import { GENERATED_HEADER } from './GENERATED_HEADER-LceqJ_qp.mjs';
2
2
  import { s as sanitizeNamespace } from './paths-BRd6JHuF.mjs';
3
3
  import { argsObjectSchema, LUNORA_ERROR_CODES } from './LUNORA_ERROR_CODES-CySpQPD3.mjs';
4
4
 
@@ -3,26 +3,26 @@ import { join, dirname } from 'node:path';
3
3
  import { performance } from 'node:perf_hooks';
4
4
  import { Node, SyntaxKind, Project } from 'ts-morph';
5
5
  import { lintSchema } from './formatAdvisories-8NIv1k0I.mjs';
6
- import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall, discoverFunctions } from './discoverFunctions-DEgAcRuD.mjs';
7
- import discoverAuthApiCalls from './discoverAuthApiCalls-C35R6z0T.mjs';
6
+ import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall, discoverFunctions } from './discoverFunctions-BWMczzBx.mjs';
7
+ import discoverAuthApiCalls from './discoverAuthApiCalls-CoirYbg6.mjs';
8
8
  import { discoverContainers } from './CONTAINERS_FILENAME-DlP6YM_Q.mjs';
9
- import discoverCrons from './discoverCrons-nHPo3UeE.mjs';
10
- import discoverHttpRoutes from './discoverHttpRoutes-C978pBiG.mjs';
11
- import discoverInserts from './discoverInserts-pLBFsSAV.mjs';
12
- import discoverMaskProcedures, { discoverMaskMetadata } from './discoverMaskProcedures-B64zA740.mjs';
13
- import discoverMigrations from './discoverMigrations-Dy24kmeD.mjs';
14
- import discoverNondeterministicCalls from './discoverNondeterministicCalls-4KiPQxQU.mjs';
15
- import discoverQueries from './discoverQueries-BkIi0dBD.mjs';
16
- import discoverR2sqlCalls from './discoverR2sqlCalls-BpDqvcUn.mjs';
17
- import discoverRlsProcedures, { discoverRlsMetadata } from './discoverRlsMetadata-DpRB1HMe.mjs';
18
- import discoverSchema from './discoverSchema-fVmAXacI.mjs';
19
- import discoverStorageRulesMetadata from './discoverStorageRulesMetadata-DAqJUxUv.mjs';
9
+ import discoverCrons from './discoverCrons-Cev7RRAf.mjs';
10
+ import discoverHttpRoutes from './discoverHttpRoutes-CfP6cMzt.mjs';
11
+ import discoverInserts from './discoverInserts-C7zxXkUf.mjs';
12
+ import discoverMaskProcedures, { discoverMaskMetadata } from './discoverMaskProcedures-Cm81kwrb.mjs';
13
+ import discoverMigrations from './discoverMigrations-Bi5nJ0mJ.mjs';
14
+ import discoverNondeterministicCalls from './discoverNondeterministicCalls-C4M8AXmQ.mjs';
15
+ import discoverQueries from './discoverQueries-B0wGT-xe.mjs';
16
+ import discoverR2sqlCalls from './discoverR2sqlCalls-BVNMd428.mjs';
17
+ import discoverRlsProcedures, { discoverRlsMetadata } from './discoverRlsMetadata-BS9GOGC5.mjs';
18
+ import discoverSchema from './discoverSchema-BF6L4mrU.mjs';
19
+ import discoverStorageRulesMetadata from './discoverStorageRulesMetadata-Da8BKXcI.mjs';
20
20
  import { e as enclosingExportName$1 } from './discover-ast-CT6BgBr4.mjs';
21
21
  import { discoverWorkflows } from './WORKFLOWS_FILENAME-D62dcBGg.mjs';
22
- import { buildStorageColumns, emitDataModel, emitApi, emitServer, emitFunctions, emitShard, emitContainers, emitWorkflows, emitCrons, emitVectors, emitDrizzleSchema, emitSeed, emitWranglerCronTriggers } from './GENERATED_HEADER-DF1hQcix.mjs';
23
- import { emitApp } from './emitApp-Ci_hcJNO.mjs';
24
- import { buildOpenApiDocument, emitOpenApiModule } from './buildOpenApiDocument-Cns1EkCQ.mjs';
25
- import { buildOpenRpcDocument, emitOpenRpcModule } from './OPENRPC_VERSION-C7zKVeKi.mjs';
22
+ import { buildStorageColumns, emitDataModel, emitApi, emitServer, emitFunctions, emitShard, emitContainers, emitWorkflows, emitCrons, emitVectors, emitDrizzleSchema, emitSeed, emitWranglerCronTriggers } from './GENERATED_HEADER-LceqJ_qp.mjs';
23
+ import { emitApp } from './emitApp-CDg72pVv.mjs';
24
+ import { buildOpenApiDocument, emitOpenApiModule } from './buildOpenApiDocument-DSPTssJI.mjs';
25
+ import { buildOpenRpcDocument, emitOpenRpcModule } from './OPENRPC_VERSION-s7lhywUr.mjs';
26
26
  import { buildSchemaSnapshot, serializeSchemaSnapshot } from './SCHEMA_SNAPSHOT_VERSION-DzLDbWk3.mjs';
27
27
 
28
28
  const HTTP_VERBS = /* @__PURE__ */ new Set(["delete", "get", "head", "options", "patch", "post", "put"]);
@@ -797,7 +797,7 @@ const runCodegen = (options) => {
797
797
  useUmbrella,
798
798
  workflows
799
799
  });
800
- const functionsContent = emitFunctions(functions, migrations);
800
+ const functionsContent = emitFunctions(functions, migrations, useUmbrella);
801
801
  const shardContent = emitShard({
802
802
  advisories,
803
803
  containers,
@@ -1,4 +1,4 @@
1
- import { GENERATED_HEADER } from './GENERATED_HEADER-DF1hQcix.mjs';
1
+ import { GENERATED_HEADER } from './GENERATED_HEADER-LceqJ_qp.mjs';
2
2
  import { s as sanitizeNamespace } from './paths-BRd6JHuF.mjs';
3
3
  import { LUNORA_ERROR_CODES, objectSchema, argsObjectSchema, validatorIrToJsonSchema } from './LUNORA_ERROR_CODES-CySpQPD3.mjs';
4
4
 
@@ -1,7 +1,7 @@
1
1
  import { relative, sep } from 'node:path';
2
2
  import { SyntaxKind, Node } from 'ts-morph';
3
3
  import { T as TS_EXTENSION_RE, e as enclosingExportName } from './discover-ast-CT6BgBr4.mjs';
4
- import { listLunoraSourceFiles } from './discoverFunctions-DEgAcRuD.mjs';
4
+ import { listLunoraSourceFiles } from './discoverFunctions-BWMczzBx.mjs';
5
5
 
6
6
  const isAuthApiCall = (call) => {
7
7
  const callee = call.getExpression();
@@ -1,7 +1,7 @@
1
1
  import { isValidCronExpression, compileCronSchedule, CRON_SCHEDULE_KINDS } from '@lunora/scheduler';
2
2
  import { SyntaxKind, Node } from 'ts-morph';
3
3
  import { diagnosticAt } from './CodegenDiagnosticError-DeblMkzO.mjs';
4
- import { listLunoraSourceFiles } from './discoverFunctions-DEgAcRuD.mjs';
4
+ import { listLunoraSourceFiles } from './discoverFunctions-BWMczzBx.mjs';
5
5
  import { s as sanitizeNamespace } from './paths-BRd6JHuF.mjs';
6
6
 
7
7
  const CRON_METHODS = /* @__PURE__ */ new Set([...CRON_SCHEDULE_KINDS, "cron"]);
@@ -1,7 +1,7 @@
1
1
  import { readdirSync, lstatSync } from 'node:fs';
2
2
  import { join, extname, relative, sep } from 'node:path';
3
3
  import { Node, SyntaxKind } from 'ts-morph';
4
- import { a as parseObjectShape } from './parse-validator-tuQtHrsr.mjs';
4
+ import { a as parseObjectShape } from './parse-validator-Cabb60UV.mjs';
5
5
  import { s as sanitizeNamespace } from './paths-BRd6JHuF.mjs';
6
6
 
7
7
  const FUNCTION_KINDS = /* @__PURE__ */ new Set(["action", "mutation", "query", "stream"]);
@@ -344,7 +344,12 @@ const discoverFromCall = (call) => {
344
344
  if (classified.lifecycle) {
345
345
  return { args: {}, kind: classified.kind, lifecycle: classified.lifecycle, returnType: "void", visibility: classified.visibility };
346
346
  }
347
- return { args: argsFromCall(call), kind: classified.kind, returnType: returnTypeFromCall(call), visibility: classified.visibility };
347
+ return {
348
+ args: argsFromCall(call),
349
+ kind: classified.kind,
350
+ returnType: returnTypeFromCall(call),
351
+ visibility: classified.visibility
352
+ };
348
353
  };
349
354
  const RE_EXPORT_RESOLVE_LIMIT = 8;
350
355
  const resolveExpressionToCall = (node, depth = 0) => {
@@ -1,7 +1,7 @@
1
1
  import { relative, sep } from 'node:path';
2
2
  import { Node } from 'ts-morph';
3
- import { listLunoraSourceFiles } from './discoverFunctions-DEgAcRuD.mjs';
4
- import { p as parseValidator, a as parseObjectShape } from './parse-validator-tuQtHrsr.mjs';
3
+ import { listLunoraSourceFiles } from './discoverFunctions-BWMczzBx.mjs';
4
+ import { p as parseValidator, a as parseObjectShape } from './parse-validator-Cabb60UV.mjs';
5
5
 
6
6
  const TS_EXTENSION_RE = /\.ts$/u;
7
7
  const HTTP_VERBS = /* @__PURE__ */ new Set(["delete", "get", "head", "options", "patch", "post", "put"]);
@@ -1,6 +1,6 @@
1
1
  import { SyntaxKind, Node } from 'ts-morph';
2
2
  import { e as enclosingExportName } from './discover-ast-CT6BgBr4.mjs';
3
- import { listLunoraSourceFiles, lunoraRelativePath } from './discoverFunctions-DEgAcRuD.mjs';
3
+ import { listLunoraSourceFiles, lunoraRelativePath } from './discoverFunctions-BWMczzBx.mjs';
4
4
 
5
5
  const isDatabaseInsertCall = (call) => {
6
6
  const callee = call.getExpression();
@@ -1,5 +1,5 @@
1
1
  import { Node, SyntaxKind } from 'ts-morph';
2
- import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-DEgAcRuD.mjs';
2
+ import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-BWMczzBx.mjs';
3
3
 
4
4
  const isMaskCall = (node) => {
5
5
  if (!Node.isCallExpression(node)) {
@@ -1,7 +1,7 @@
1
1
  import { relative, sep } from 'node:path';
2
2
  import { SyntaxKind, Node } from 'ts-morph';
3
3
  import { diagnosticAt } from './CodegenDiagnosticError-DeblMkzO.mjs';
4
- import { listLunoraSourceFiles } from './discoverFunctions-DEgAcRuD.mjs';
4
+ import { listLunoraSourceFiles } from './discoverFunctions-BWMczzBx.mjs';
5
5
 
6
6
  const TS_EXTENSION_RE = /\.ts$/u;
7
7
  const isDefineMigration = (identifier) => {
@@ -1,5 +1,5 @@
1
1
  import { Node, SyntaxKind } from 'ts-morph';
2
- import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-DEgAcRuD.mjs';
2
+ import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-BWMczzBx.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-DEgAcRuD.mjs';
2
+ import { listLunoraSourceFiles, lunoraRelativePath } from './discoverFunctions-BWMczzBx.mjs';
3
3
 
4
4
  const INDEX_METHODS = /* @__PURE__ */ new Set(["withIndex", "withSearchIndex"]);
5
5
  const isDatabaseQueryCall = (call) => {
@@ -1,5 +1,5 @@
1
1
  import { Node, SyntaxKind } from 'ts-morph';
2
- import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-DEgAcRuD.mjs';
2
+ import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-BWMczzBx.mjs';
3
3
 
4
4
  const handlerOf = (call, receiver) => {
5
5
  if (receiver) {
@@ -1,5 +1,5 @@
1
1
  import { Node, SyntaxKind } from 'ts-morph';
2
- import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-DEgAcRuD.mjs';
2
+ import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-BWMczzBx.mjs';
3
3
 
4
4
  const isRlsCall = (node) => {
5
5
  if (!Node.isCallExpression(node)) {
@@ -1,6 +1,6 @@
1
1
  import { Node, SyntaxKind } from 'ts-morph';
2
2
  import { diagnosticAt } from './CodegenDiagnosticError-DeblMkzO.mjs';
3
- import { a as parseObjectShape } from './parse-validator-tuQtHrsr.mjs';
3
+ import { a as parseObjectShape } from './parse-validator-Cabb60UV.mjs';
4
4
  import { createRequire } from 'node:module';
5
5
  import { join } from 'node:path';
6
6
 
@@ -385,6 +385,18 @@ const parseGlobalBackend = (args) => {
385
385
  }
386
386
  return "d1";
387
387
  };
388
+ const softDeleteFieldOf = (optionsArgument) => {
389
+ if (optionsArgument && Node.isObjectLiteralExpression(optionsArgument)) {
390
+ const fieldProperty = optionsArgument.getProperty("field");
391
+ if (fieldProperty && Node.isPropertyAssignment(fieldProperty)) {
392
+ const initializer = fieldProperty.getInitializer();
393
+ if (initializer && Node.isStringLiteral(initializer)) {
394
+ return initializer.getLiteralText();
395
+ }
396
+ }
397
+ }
398
+ return "deletedAt";
399
+ };
388
400
  const applyTableMethod = (accumulator, method, args, name) => {
389
401
  switch (method) {
390
402
  case "externallyManaged": {
@@ -420,6 +432,10 @@ const applyTableMethod = (accumulator, method, args, name) => {
420
432
  accumulator.shardMode = { field: field && Node.isStringLiteral(field) ? field.getLiteralText() : "_unknown_", kind: "shardBy" };
421
433
  break;
422
434
  }
435
+ case "softDelete": {
436
+ accumulator.softDelete = { field: softDeleteFieldOf(args[0]) };
437
+ break;
438
+ }
423
439
  case "vectorize": {
424
440
  const vectorIndex = parseVectorizeCall(args, name);
425
441
  if (vectorIndex) {
@@ -457,6 +473,9 @@ const parseTableBuilder = (expression, name) => {
457
473
  break;
458
474
  }
459
475
  }
476
+ if (accumulator.softDelete && !(accumulator.softDelete.field in shape)) {
477
+ shape = { ...shape, [accumulator.softDelete.field]: { inner: { kind: "number" }, kind: "optional" } };
478
+ }
460
479
  return {
461
480
  externallyManaged: accumulator.externallyManaged,
462
481
  globalBackend: accumulator.shardMode === "global" ? accumulator.globalBackend ?? "d1" : void 0,
@@ -467,6 +486,7 @@ const parseTableBuilder = (expression, name) => {
467
486
  searchIndexes: accumulator.searchIndexes,
468
487
  shape,
469
488
  shardMode: accumulator.shardMode,
489
+ softDelete: accumulator.softDelete,
470
490
  vectorIndexes: accumulator.vectorIndexes
471
491
  };
472
492
  };
@@ -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-BWMczzBx.mjs';
3
3
 
4
4
  const STORAGE_OPERATIONS = /* @__PURE__ */ new Set(["delete", "list", "read", "write"]);
5
5
  const isStorageRulesCall = (node) => {
@@ -1,4 +1,4 @@
1
- import { GENERATED_HEADER } from './GENERATED_HEADER-DF1hQcix.mjs';
1
+ import { GENERATED_HEADER } from './GENERATED_HEADER-LceqJ_qp.mjs';
2
2
 
3
3
  const LONG_TAIL = [
4
4
  ["hasAi", "ai", "ai", "Override the Workers AI binding backing `ctx.ai` (defaults to `env.AI`)."],
@@ -124,7 +124,8 @@ const parseValidatorCall = (call) => {
124
124
  }
125
125
  if (TRANSPARENT_MODIFIERS.has(member)) {
126
126
  const receiver = callee.getExpression();
127
- return Node.isExpression(receiver) ? parseValidator(receiver) : { kind: "any" };
127
+ const base = Node.isExpression(receiver) ? parseValidator(receiver) : { kind: "any" };
128
+ return member === "check" ? { ...base, hasRefinement: true } : base;
128
129
  }
129
130
  return parseBuilderMember(member, args);
130
131
  };