@lunora/codegen 1.0.0-alpha.7 → 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 (27) hide show
  1. package/__assets__/package-og.svg +1 -1
  2. package/dist/index.d.mts +26 -2
  3. package/dist/index.d.ts +26 -2
  4. package/dist/index.mjs +21 -21
  5. package/dist/packem_shared/{CONTAINERS_FILENAME-0K-pjNb8.mjs → CONTAINERS_FILENAME-DlP6YM_Q.mjs} +1 -1
  6. package/dist/packem_shared/{CodegenDiagnosticError-54jWDxA9.mjs → CodegenDiagnosticError-DeblMkzO.mjs} +3 -2
  7. package/dist/packem_shared/{GENERATED_HEADER-DF1hQcix.mjs → GENERATED_HEADER-LceqJ_qp.mjs} +200 -7
  8. package/dist/packem_shared/{OPENRPC_VERSION-C7zKVeKi.mjs → OPENRPC_VERSION-s7lhywUr.mjs} +1 -1
  9. package/dist/packem_shared/{SCHEMA_SNAPSHOT_FILENAME-g7kpX8hu.mjs → SCHEMA_SNAPSHOT_FILENAME-Ct0NDRLY.mjs} +35 -20
  10. package/dist/packem_shared/{WORKFLOWS_FILENAME-DRDQdhfq.mjs → WORKFLOWS_FILENAME-D62dcBGg.mjs} +1 -1
  11. package/dist/packem_shared/{buildOpenApiDocument-Cns1EkCQ.mjs → buildOpenApiDocument-DSPTssJI.mjs} +1 -1
  12. package/dist/packem_shared/{discoverAuthApiCalls-C35R6z0T.mjs → discoverAuthApiCalls-CoirYbg6.mjs} +1 -1
  13. package/dist/packem_shared/{discoverCrons-BL6iGuJ3.mjs → discoverCrons-Cev7RRAf.mjs} +20 -17
  14. package/dist/packem_shared/{discoverFunctions-DEgAcRuD.mjs → discoverFunctions-BWMczzBx.mjs} +7 -2
  15. package/dist/packem_shared/{discoverHttpRoutes-C978pBiG.mjs → discoverHttpRoutes-CfP6cMzt.mjs} +2 -2
  16. package/dist/packem_shared/{discoverInserts-pLBFsSAV.mjs → discoverInserts-C7zxXkUf.mjs} +1 -1
  17. package/dist/packem_shared/{discoverMaskProcedures-B64zA740.mjs → discoverMaskProcedures-Cm81kwrb.mjs} +1 -1
  18. package/dist/packem_shared/{discoverMigrations-Doj_-BAA.mjs → discoverMigrations-Bi5nJ0mJ.mjs} +10 -4
  19. package/dist/packem_shared/{discoverNondeterministicCalls-4KiPQxQU.mjs → discoverNondeterministicCalls-C4M8AXmQ.mjs} +1 -1
  20. package/dist/packem_shared/{discoverQueries-BkIi0dBD.mjs → discoverQueries-B0wGT-xe.mjs} +1 -1
  21. package/dist/packem_shared/{discoverR2sqlCalls-BpDqvcUn.mjs → discoverR2sqlCalls-BVNMd428.mjs} +1 -1
  22. package/dist/packem_shared/{discoverRlsMetadata-DpRB1HMe.mjs → discoverRlsMetadata-BS9GOGC5.mjs} +1 -1
  23. package/dist/packem_shared/{discoverSchema-DYl0QfDH.mjs → discoverSchema-BF6L4mrU.mjs} +22 -2
  24. package/dist/packem_shared/{discoverStorageRulesMetadata-DAqJUxUv.mjs → discoverStorageRulesMetadata-Da8BKXcI.mjs} +1 -1
  25. package/dist/packem_shared/{emitApp-Ci_hcJNO.mjs → emitApp-CDg72pVv.mjs} +1 -1
  26. package/dist/packem_shared/{parse-validator-tuQtHrsr.mjs → parse-validator-Cabb60UV.mjs} +2 -1
  27. package/package.json +4 -4
@@ -1,6 +1,7 @@
1
1
  import { isValidCronExpression, compileCronSchedule, CRON_SCHEDULE_KINDS } from '@lunora/scheduler';
2
2
  import { SyntaxKind, Node } from 'ts-morph';
3
- import { listLunoraSourceFiles } from './discoverFunctions-DEgAcRuD.mjs';
3
+ import { diagnosticAt } from './CodegenDiagnosticError-DeblMkzO.mjs';
4
+ import { listLunoraSourceFiles } from './discoverFunctions-BWMczzBx.mjs';
4
5
  import { s as sanitizeNamespace } from './paths-BRd6JHuF.mjs';
5
6
 
6
7
  const CRON_METHODS = /* @__PURE__ */ new Set([...CRON_SCHEDULE_KINDS, "cron"]);
@@ -71,7 +72,7 @@ const literalValue = (node, jobName) => {
71
72
  if (Node.isArrayLiteralExpression(node)) {
72
73
  return node.getElements().map((element) => literalValue(element, jobName));
73
74
  }
74
- throw Object.assign(new Error(`Cron job "${jobName}" passes a non-static value where a literal is required; codegen can only read literals.`), {
75
+ throw diagnosticAt(node, `Cron job "${jobName}" passes a non-static value where a literal is required; codegen can only read literals.`, {
75
76
  code: "CRON_NON_STATIC_VALUE",
76
77
  name: "LunoraError",
77
78
  status: 500
@@ -81,8 +82,9 @@ const objectLiteralValue = (object, jobName) => {
81
82
  const result = {};
82
83
  for (const property of object.getProperties()) {
83
84
  if (!Node.isPropertyAssignment(property)) {
84
- throw Object.assign(
85
- new Error(`Cron job "${jobName}" uses an unsupported object property (shorthand/spread/method) where a static literal is required.`),
85
+ throw diagnosticAt(
86
+ property,
87
+ `Cron job "${jobName}" uses an unsupported object property (shorthand/spread/method) where a static literal is required.`,
86
88
  {
87
89
  code: "CRON_NON_STATIC_VALUE",
88
90
  name: "LunoraError",
@@ -100,8 +102,9 @@ const objectLiteralValue = (object, jobName) => {
100
102
  const functionPathFromArgument = (call, index, jobName) => {
101
103
  const argument = call.getArguments()[index];
102
104
  if (!argument || !Node.isPropertyAccessExpression(argument)) {
103
- throw Object.assign(
104
- new Error(`Cron job "${jobName}" must reference a function statically (e.g. internal.email.digest); codegen cannot resolve a dynamic reference.`),
105
+ throw diagnosticAt(
106
+ call,
107
+ `Cron job "${jobName}" must reference a function statically (e.g. internal.email.digest); codegen cannot resolve a dynamic reference.`,
105
108
  {
106
109
  code: "CRON_NON_STATIC_FN",
107
110
  name: "LunoraError",
@@ -112,7 +115,7 @@ const functionPathFromArgument = (call, index, jobName) => {
112
115
  const functionName = argument.getName();
113
116
  const receiver = argument.getExpression();
114
117
  if (!Node.isPropertyAccessExpression(receiver)) {
115
- throw Object.assign(new Error(`Cron job "${jobName}" function reference must be of the form internal.file.fn (two property accesses).`), {
118
+ throw diagnosticAt(argument, `Cron job "${jobName}" function reference must be of the form internal.file.fn (two property accesses).`, {
116
119
  code: "CRON_NON_STATIC_FN",
117
120
  name: "LunoraError",
118
121
  status: 500
@@ -133,8 +136,9 @@ const resolveTarget = (call, index, jobName, workflowsByName) => {
133
136
  if (workflow) {
134
137
  return workflowTarget(workflow);
135
138
  }
136
- throw Object.assign(
137
- new Error(`Cron job "${jobName}" targets workflows.${argument.getName()}, but no such workflow is declared in lunora/workflows.ts.`),
139
+ throw diagnosticAt(
140
+ argument,
141
+ `Cron job "${jobName}" targets workflows.${argument.getName()}, but no such workflow is declared in lunora/workflows.ts.`,
138
142
  {
139
143
  code: "CRON_NON_STATIC_FN",
140
144
  name: "LunoraError",
@@ -149,10 +153,9 @@ const resolveTarget = (call, index, jobName, workflowsByName) => {
149
153
  if (workflow) {
150
154
  return workflowTarget(workflow);
151
155
  }
152
- throw Object.assign(
153
- new Error(
154
- `Cron job "${jobName}" references "${argument.getText()}", which is neither a function (internal.file.fn / api.file.fn) nor a declared workflow in lunora/workflows.ts.`
155
- ),
156
+ throw diagnosticAt(
157
+ argument,
158
+ `Cron job "${jobName}" references "${argument.getText()}", which is neither a function (internal.file.fn / api.file.fn) nor a declared workflow in lunora/workflows.ts.`,
156
159
  {
157
160
  code: "CRON_NON_STATIC_FN",
158
161
  name: "LunoraError",
@@ -172,7 +175,7 @@ const cronFromCall = (call, callee, builderNames, workflowsByName) => {
172
175
  }
173
176
  const name = stringArgument(call, 0);
174
177
  if (name === void 0 || name.trim() === "") {
175
- throw Object.assign(new Error(`A cron ".${method}(...)" registration must pass a non-empty string-literal name as its first argument.`), {
178
+ throw diagnosticAt(call, `A cron ".${method}(...)" registration must pass a non-empty string-literal name as its first argument.`, {
176
179
  code: "CRON_NAME_NOT_STATIC",
177
180
  name: "LunoraError",
178
181
  status: 500
@@ -182,14 +185,14 @@ const cronFromCall = (call, callee, builderNames, workflowsByName) => {
182
185
  if (method === "cron") {
183
186
  const expression = stringArgument(call, 1);
184
187
  if (expression === void 0) {
185
- throw Object.assign(new Error(`Cron job "${name}" must pass a string-literal cron expression to ".cron(...)".`), {
188
+ throw diagnosticAt(call, `Cron job "${name}" must pass a string-literal cron expression to ".cron(...)".`, {
186
189
  code: "CRON_EXPR_NOT_STATIC",
187
190
  name: "LunoraError",
188
191
  status: 500
189
192
  });
190
193
  }
191
194
  if (!isValidCronExpression(expression)) {
192
- throw Object.assign(new Error(`Cron job "${name}" has an invalid cron expression "${expression}" — expected 5 or 6 space-separated fields.`), {
195
+ throw diagnosticAt(call, `Cron job "${name}" has an invalid cron expression "${expression}" — expected 5 or 6 space-separated fields.`, {
193
196
  code: "CRON_EXPR_INVALID",
194
197
  name: "LunoraError",
195
198
  status: 500
@@ -199,7 +202,7 @@ const cronFromCall = (call, callee, builderNames, workflowsByName) => {
199
202
  } else {
200
203
  const scheduleArgument = call.getArguments()[1];
201
204
  if (!scheduleArgument || !Node.isObjectLiteralExpression(scheduleArgument)) {
202
- throw Object.assign(new Error(`Cron job "${name}" must pass an object-literal schedule to ".${method}(...)".`), {
205
+ throw diagnosticAt(call, `Cron job "${name}" must pass an object-literal schedule to ".${method}(...)".`, {
203
206
  code: "CRON_SCHEDULE_NOT_STATIC",
204
207
  name: "LunoraError",
205
208
  status: 500
@@ -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,6 +1,7 @@
1
1
  import { relative, sep } from 'node:path';
2
2
  import { SyntaxKind, Node } from 'ts-morph';
3
- import { listLunoraSourceFiles } from './discoverFunctions-DEgAcRuD.mjs';
3
+ import { diagnosticAt } from './CodegenDiagnosticError-DeblMkzO.mjs';
4
+ import { listLunoraSourceFiles } from './discoverFunctions-BWMczzBx.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 Object.assign(
47
- new Error(`Migration "${exportName}" in "${relativePath}" must declare \`id\` as a non-empty string literal so codegen can key the registry.`),
48
- { code: "MIGRATION_ID_NOT_STATIC", name: "LunoraError", status: 500 }
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-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
- import { diagnosticAt } from './CodegenDiagnosticError-54jWDxA9.mjs';
3
- import { a as parseObjectShape } from './parse-validator-tuQtHrsr.mjs';
2
+ import { diagnosticAt } from './CodegenDiagnosticError-DeblMkzO.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
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/codegen",
3
- "version": "1.0.0-alpha.7",
3
+ "version": "1.0.0-alpha.9",
4
4
  "description": "Code generator for Lunora: emits _generated/{api,server,dataModel}.ts from your schema",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -46,11 +46,11 @@
46
46
  "access": "public"
47
47
  },
48
48
  "dependencies": {
49
- "@lunora/advisor": "1.0.0-alpha.3",
49
+ "@lunora/advisor": "1.0.0-alpha.4",
50
50
  "@lunora/container": "1.0.0-alpha.1",
51
51
  "@lunora/scheduler": "1.0.0-alpha.1",
52
- "@lunora/values": "1.0.0-alpha.1",
53
- "@lunora/workflow": "1.0.0-alpha.1",
52
+ "@lunora/values": "1.0.0-alpha.2",
53
+ "@lunora/workflow": "1.0.0-alpha.2",
54
54
  "ts-morph": "^28.0.0"
55
55
  },
56
56
  "engines": {