@lunora/codegen 1.0.0-alpha.18 → 1.0.0-alpha.19

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 CHANGED
@@ -363,6 +363,24 @@ interface WorkflowIR {
363
363
  * definition overrides it.
364
364
  */
365
365
  name: string;
366
+ /**
367
+ * Durable step labels lifted from the handler body — the first string-literal
368
+ * argument of every `ctx.step.do` / `.sleep` / `.sleepUntil` / `.waitForEvent`
369
+ * call. Feeds the duplicate-step-name lint, which flags a name used twice
370
+ * (Cloudflare memoizes by name, so the second call silently returns the
371
+ * first's cached result). Calls with a non-literal name are omitted (not
372
+ * statically comparable).
373
+ */
374
+ steps: ReadonlyArray<WorkflowStepIR>;
375
+ }
376
+ /** One durable step call lifted from a workflow handler body (the use side of {@link WorkflowIR.steps}). */
377
+ interface WorkflowStepIR {
378
+ /** 1-based line of the durable step call. */
379
+ line: number;
380
+ /** The native step method invoked: `do` / `sleep` / `sleepUntil` / `waitForEvent`. */
381
+ method: string;
382
+ /** The step's static label (the first string-literal argument). */
383
+ name: string;
366
384
  }
367
385
  /**
368
386
  * A queue lifted from a `defineQueue()` export in `lunora/queues.ts`. Carries
@@ -828,8 +846,9 @@ interface ProjectIR {
828
846
  * feed `table_without_insert`, authApi calls feed `auth_api_call_without_headers`,
829
847
  * rls procedure snapshots feed `rls_uncovered_table`, and mask procedure
830
848
  * snapshots feed `mask_uncovered_pii_column`; declared containers
831
- * feed the `container_*` lints; declared workflows + `ctx.workflows.get(...)` call
832
- * sites feed the `workflow_unused` / `workflow_unknown_target` lints; non-deterministic
849
+ * feed the `container_*` lints; declared workflows (with their durable step labels)
850
+ * + `ctx.workflows.get(...)` call sites feed the `workflow_unused` /
851
+ * `workflow_unknown_target` / duplicate-step-name lints; non-deterministic
833
852
  * calls inside query/mutation handlers feed the `nondeterministic_query_mutation` lint
834
853
  * (all default empty for callers that don't analyze functions/containers/workflows).
835
854
  * The IR types are structurally identical to the advisor's evidence types so they
package/dist/index.d.ts CHANGED
@@ -363,6 +363,24 @@ interface WorkflowIR {
363
363
  * definition overrides it.
364
364
  */
365
365
  name: string;
366
+ /**
367
+ * Durable step labels lifted from the handler body — the first string-literal
368
+ * argument of every `ctx.step.do` / `.sleep` / `.sleepUntil` / `.waitForEvent`
369
+ * call. Feeds the duplicate-step-name lint, which flags a name used twice
370
+ * (Cloudflare memoizes by name, so the second call silently returns the
371
+ * first's cached result). Calls with a non-literal name are omitted (not
372
+ * statically comparable).
373
+ */
374
+ steps: ReadonlyArray<WorkflowStepIR>;
375
+ }
376
+ /** One durable step call lifted from a workflow handler body (the use side of {@link WorkflowIR.steps}). */
377
+ interface WorkflowStepIR {
378
+ /** 1-based line of the durable step call. */
379
+ line: number;
380
+ /** The native step method invoked: `do` / `sleep` / `sleepUntil` / `waitForEvent`. */
381
+ method: string;
382
+ /** The step's static label (the first string-literal argument). */
383
+ name: string;
366
384
  }
367
385
  /**
368
386
  * A queue lifted from a `defineQueue()` export in `lunora/queues.ts`. Carries
@@ -828,8 +846,9 @@ interface ProjectIR {
828
846
  * feed `table_without_insert`, authApi calls feed `auth_api_call_without_headers`,
829
847
  * rls procedure snapshots feed `rls_uncovered_table`, and mask procedure
830
848
  * snapshots feed `mask_uncovered_pii_column`; declared containers
831
- * feed the `container_*` lints; declared workflows + `ctx.workflows.get(...)` call
832
- * sites feed the `workflow_unused` / `workflow_unknown_target` lints; non-deterministic
849
+ * feed the `container_*` lints; declared workflows (with their durable step labels)
850
+ * + `ctx.workflows.get(...)` call sites feed the `workflow_unused` /
851
+ * `workflow_unknown_target` / duplicate-step-name lints; non-deterministic
833
852
  * calls inside query/mutation handlers feed the `nondeterministic_query_mutation` lint
834
853
  * (all default empty for callers that don't analyze functions/containers/workflows).
835
854
  * The IR types are structurally identical to the advisor's evidence types so they
package/dist/index.mjs CHANGED
@@ -18,12 +18,12 @@ export { discoverRlsMetadata, default as discoverRlsProcedures } from './packem_
18
18
  export { default as discoverSchema } from './packem_shared/discoverSchema-BnWHHJ4T.mjs';
19
19
  export { SHAPES_FILENAME, discoverShapes } from './packem_shared/SHAPES_FILENAME-ChV7MqgE.mjs';
20
20
  export { default as discoverStorageRulesMetadata } from './packem_shared/discoverStorageRulesMetadata-Da8BKXcI.mjs';
21
- export { WORKFLOWS_FILENAME, discoverWorkflows } from './packem_shared/WORKFLOWS_FILENAME-D62dcBGg.mjs';
21
+ export { WORKFLOWS_FILENAME, discoverWorkflows } from './packem_shared/WORKFLOWS_FILENAME-CCisG0Vy.mjs';
22
22
  export { GENERATED_HEADER, emitApi, emitCollections, emitContainers, emitCrons, emitDataModel, emitDrizzleSchema, emitFunctions, emitServer, emitShard, emitVectors, emitWorkflows, emitWranglerCronTriggers } from './packem_shared/GENERATED_HEADER-D-AbhmRh.mjs';
23
23
  export { emitApp } from './packem_shared/emitApp-CV81L74c.mjs';
24
24
  export { buildOpenApiDocument, emitOpenApi, emitOpenApiModule } from './packem_shared/buildOpenApiDocument-DoK7_x1g.mjs';
25
25
  export { OPENRPC_VERSION, buildOpenRpcDocument, emitOpenRpc, emitOpenRpcModule } from './packem_shared/OPENRPC_VERSION-DDT4mIzD.mjs';
26
- export { SCHEMA_SNAPSHOT_FILENAME, createCodegenProject, refreshCodegenProject, runCodegen } from './packem_shared/SCHEMA_SNAPSHOT_FILENAME-ExbveiC6.mjs';
26
+ export { SCHEMA_SNAPSHOT_FILENAME, createCodegenProject, refreshCodegenProject, runCodegen } from './packem_shared/SCHEMA_SNAPSHOT_FILENAME-BZH-O4uh.mjs';
27
27
  export { SCHEMA_SNAPSHOT_VERSION, SchemaSnapshotParseError, buildSchemaSnapshot, diffSchemaSnapshots, evaluateSchemaDrift, parseSchemaSnapshot, serializeSchemaSnapshot } from './packem_shared/SCHEMA_SNAPSHOT_VERSION-wWGP2_5E.mjs';
28
28
  export { schemaFromIr } from './packem_shared/schemaFromIr-DTYsLBaA.mjs';
29
29
  export { LUNORA_ERROR_CODES, validatorIrToJsonSchema } from './packem_shared/LUNORA_ERROR_CODES-CySpQPD3.mjs';
@@ -22,7 +22,7 @@ import discoverSchema from './discoverSchema-BnWHHJ4T.mjs';
22
22
  import { discoverShapes } from './SHAPES_FILENAME-ChV7MqgE.mjs';
23
23
  import discoverStorageRulesMetadata from './discoverStorageRulesMetadata-Da8BKXcI.mjs';
24
24
  import { e as enclosingExportName$1 } from './discover-ast-CT6BgBr4.mjs';
25
- import { discoverWorkflows } from './WORKFLOWS_FILENAME-D62dcBGg.mjs';
25
+ import { discoverWorkflows } from './WORKFLOWS_FILENAME-CCisG0Vy.mjs';
26
26
  import { buildStorageColumns, emitDataModel, emitApi, emitServer, emitFunctions, emitShard, emitCollections, emitContainers, emitWorkflows, emitQueues, emitCrons, emitVectors, emitDrizzleSchema, emitSeed, emitWranglerCronTriggers } from './GENERATED_HEADER-D-AbhmRh.mjs';
27
27
  import { emitApp } from './emitApp-CV81L74c.mjs';
28
28
  import { buildOpenApiDocument, emitOpenApiModule } from './buildOpenApiDocument-DoK7_x1g.mjs';
@@ -5,6 +5,7 @@ import { SyntaxKind, Node } from 'ts-morph';
5
5
  import { diagnosticAt } from './CodegenDiagnosticError-DeblMkzO.mjs';
6
6
 
7
7
  const WORKFLOWS_FILENAME = "workflows.ts";
8
+ const STEP_METHODS = /* @__PURE__ */ new Set(["do", "sleep", "sleepUntil", "waitForEvent"]);
8
9
  const isDefineWorkflow = (identifier) => {
9
10
  const symbol = identifier.getSymbol();
10
11
  if (!symbol) {
@@ -30,6 +31,44 @@ const stringProperty = (expression, exportName, property) => {
30
31
  `workflow "${exportName}": \`${property}\` must be a static string literal — it is deploy configuration codegen writes into wrangler.jsonc`
31
32
  );
32
33
  };
34
+ const isStepCall = (call) => {
35
+ const callee = call.getExpression();
36
+ if (!Node.isPropertyAccessExpression(callee) || !STEP_METHODS.has(callee.getName())) {
37
+ return false;
38
+ }
39
+ const receiver = callee.getExpression();
40
+ if (Node.isPropertyAccessExpression(receiver) && receiver.getName() === "step") {
41
+ return true;
42
+ }
43
+ return Node.isIdentifier(receiver) && receiver.getText() === "step";
44
+ };
45
+ const stepsFromHandler = (argument) => {
46
+ const handlerProperty = argument.getProperty("handler");
47
+ if (!handlerProperty) {
48
+ return [];
49
+ }
50
+ const body = Node.isPropertyAssignment(handlerProperty) ? handlerProperty.getInitializer() : handlerProperty;
51
+ if (!body) {
52
+ return [];
53
+ }
54
+ const steps = [];
55
+ for (const call of body.getDescendantsOfKind(SyntaxKind.CallExpression)) {
56
+ if (!isStepCall(call)) {
57
+ continue;
58
+ }
59
+ const nameArgument = call.getArguments()[0];
60
+ if (!nameArgument || !(Node.isStringLiteral(nameArgument) || Node.isNoSubstitutionTemplateLiteral(nameArgument))) {
61
+ continue;
62
+ }
63
+ steps.push({
64
+ line: call.getStartLineNumber(),
65
+ // `isStepCall` already proved the callee is a `.<method>` property access.
66
+ method: call.getExpression().getName(),
67
+ name: nameArgument.getLiteralValue()
68
+ });
69
+ }
70
+ return steps;
71
+ };
33
72
  const workflowFromCall = (call, exportName) => {
34
73
  const argument = call.getArguments()[0];
35
74
  if (!argument || !Node.isObjectLiteralExpression(argument)) {
@@ -39,7 +78,8 @@ const workflowFromCall = (call, exportName) => {
39
78
  bindingName: workflowBindingName(exportName),
40
79
  className: workflowClassName(exportName),
41
80
  exportName,
42
- name: workflowDefaultName(exportName)
81
+ name: workflowDefaultName(exportName),
82
+ steps: stepsFromHandler(argument)
43
83
  };
44
84
  const nameProperty = argument.getProperty("name");
45
85
  if (nameProperty && Node.isPropertyAssignment(nameProperty)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/codegen",
3
- "version": "1.0.0-alpha.18",
3
+ "version": "1.0.0-alpha.19",
4
4
  "description": "Code generator for Lunora: emits _generated/{api,server,dataModel}.ts from your schema",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -46,12 +46,12 @@
46
46
  "access": "public"
47
47
  },
48
48
  "dependencies": {
49
- "@lunora/advisor": "1.0.0-alpha.8",
49
+ "@lunora/advisor": "1.0.0-alpha.9",
50
50
  "@lunora/container": "1.0.0-alpha.5",
51
51
  "@lunora/queue": "1.0.0-alpha.1",
52
52
  "@lunora/scheduler": "1.0.0-alpha.3",
53
53
  "@lunora/values": "1.0.0-alpha.3",
54
- "@lunora/workflow": "1.0.0-alpha.3",
54
+ "@lunora/workflow": "1.0.0-alpha.4",
55
55
  "ts-morph": "^28.0.0"
56
56
  },
57
57
  "engines": {