dopespec 0.0.1

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 (179) hide show
  1. package/README.md +195 -0
  2. package/bin/dopespec.mjs +26 -0
  3. package/dist/__tests__/codegen.test.d.ts +2 -0
  4. package/dist/__tests__/codegen.test.d.ts.map +1 -0
  5. package/dist/__tests__/codegen.test.js +713 -0
  6. package/dist/__tests__/codegen.test.js.map +1 -0
  7. package/dist/__tests__/e2e-proof.test.d.ts +2 -0
  8. package/dist/__tests__/e2e-proof.test.d.ts.map +1 -0
  9. package/dist/__tests__/e2e-proof.test.js +153 -0
  10. package/dist/__tests__/e2e-proof.test.js.map +1 -0
  11. package/dist/__tests__/schema.test.d.ts +2 -0
  12. package/dist/__tests__/schema.test.d.ts.map +1 -0
  13. package/dist/__tests__/schema.test.js +822 -0
  14. package/dist/__tests__/schema.test.js.map +1 -0
  15. package/dist/__tests__/type-errors.d.ts +2 -0
  16. package/dist/__tests__/type-errors.d.ts.map +1 -0
  17. package/dist/__tests__/type-errors.js +128 -0
  18. package/dist/__tests__/type-errors.js.map +1 -0
  19. package/dist/cli/generate.d.ts +2 -0
  20. package/dist/cli/generate.d.ts.map +1 -0
  21. package/dist/cli/generate.js +250 -0
  22. package/dist/cli/generate.js.map +1 -0
  23. package/dist/codegen/commands.d.ts +4 -0
  24. package/dist/codegen/commands.d.ts.map +1 -0
  25. package/dist/codegen/commands.js +25 -0
  26. package/dist/codegen/commands.js.map +1 -0
  27. package/dist/codegen/decisions-evaluate.d.ts +3 -0
  28. package/dist/codegen/decisions-evaluate.d.ts.map +1 -0
  29. package/dist/codegen/decisions-evaluate.js +50 -0
  30. package/dist/codegen/decisions-evaluate.js.map +1 -0
  31. package/dist/codegen/decisions-table.d.ts +3 -0
  32. package/dist/codegen/decisions-table.d.ts.map +1 -0
  33. package/dist/codegen/decisions-table.js +27 -0
  34. package/dist/codegen/decisions-table.js.map +1 -0
  35. package/dist/codegen/decisions-tests.d.ts +3 -0
  36. package/dist/codegen/decisions-tests.d.ts.map +1 -0
  37. package/dist/codegen/decisions-tests.js +43 -0
  38. package/dist/codegen/decisions-tests.js.map +1 -0
  39. package/dist/codegen/e2e-stubs.d.ts +4 -0
  40. package/dist/codegen/e2e-stubs.d.ts.map +1 -0
  41. package/dist/codegen/e2e-stubs.js +21 -0
  42. package/dist/codegen/e2e-stubs.js.map +1 -0
  43. package/dist/codegen/events.d.ts +8 -0
  44. package/dist/codegen/events.d.ts.map +1 -0
  45. package/dist/codegen/events.js +36 -0
  46. package/dist/codegen/events.js.map +1 -0
  47. package/dist/codegen/index.d.ts +18 -0
  48. package/dist/codegen/index.d.ts.map +1 -0
  49. package/dist/codegen/index.js +18 -0
  50. package/dist/codegen/index.js.map +1 -0
  51. package/dist/codegen/invariants.d.ts +4 -0
  52. package/dist/codegen/invariants.d.ts.map +1 -0
  53. package/dist/codegen/invariants.js +53 -0
  54. package/dist/codegen/invariants.js.map +1 -0
  55. package/dist/codegen/mermaid.d.ts +4 -0
  56. package/dist/codegen/mermaid.d.ts.map +1 -0
  57. package/dist/codegen/mermaid.js +21 -0
  58. package/dist/codegen/mermaid.js.map +1 -0
  59. package/dist/codegen/orchestrators.d.ts +7 -0
  60. package/dist/codegen/orchestrators.d.ts.map +1 -0
  61. package/dist/codegen/orchestrators.js +32 -0
  62. package/dist/codegen/orchestrators.js.map +1 -0
  63. package/dist/codegen/policy-index.d.ts +7 -0
  64. package/dist/codegen/policy-index.d.ts.map +1 -0
  65. package/dist/codegen/policy-index.js +40 -0
  66. package/dist/codegen/policy-index.js.map +1 -0
  67. package/dist/codegen/policy-mermaid.d.ts +7 -0
  68. package/dist/codegen/policy-mermaid.d.ts.map +1 -0
  69. package/dist/codegen/policy-mermaid.js +30 -0
  70. package/dist/codegen/policy-mermaid.js.map +1 -0
  71. package/dist/codegen/policy-tests.d.ts +8 -0
  72. package/dist/codegen/policy-tests.d.ts.map +1 -0
  73. package/dist/codegen/policy-tests.js +167 -0
  74. package/dist/codegen/policy-tests.js.map +1 -0
  75. package/dist/codegen/policy-validator.d.ts +8 -0
  76. package/dist/codegen/policy-validator.d.ts.map +1 -0
  77. package/dist/codegen/policy-validator.js +69 -0
  78. package/dist/codegen/policy-validator.js.map +1 -0
  79. package/dist/codegen/tests.d.ts +4 -0
  80. package/dist/codegen/tests.d.ts.map +1 -0
  81. package/dist/codegen/tests.js +125 -0
  82. package/dist/codegen/tests.js.map +1 -0
  83. package/dist/codegen/transitions.d.ts +4 -0
  84. package/dist/codegen/transitions.d.ts.map +1 -0
  85. package/dist/codegen/transitions.js +41 -0
  86. package/dist/codegen/transitions.js.map +1 -0
  87. package/dist/codegen/types.d.ts +4 -0
  88. package/dist/codegen/types.d.ts.map +1 -0
  89. package/dist/codegen/types.js +48 -0
  90. package/dist/codegen/types.js.map +1 -0
  91. package/dist/codegen/utils.d.ts +85 -0
  92. package/dist/codegen/utils.d.ts.map +1 -0
  93. package/dist/codegen/utils.js +357 -0
  94. package/dist/codegen/utils.js.map +1 -0
  95. package/dist/codegen/zod.d.ts +4 -0
  96. package/dist/codegen/zod.d.ts.map +1 -0
  97. package/dist/codegen/zod.js +32 -0
  98. package/dist/codegen/zod.js.map +1 -0
  99. package/dist/examples/generated/customer.types.d.ts +7 -0
  100. package/dist/examples/generated/customer.types.d.ts.map +1 -0
  101. package/dist/examples/generated/customer.types.js +2 -0
  102. package/dist/examples/generated/customer.types.js.map +1 -0
  103. package/dist/examples/generated/order.types.d.ts +9 -0
  104. package/dist/examples/generated/order.types.d.ts.map +1 -0
  105. package/dist/examples/generated/order.types.js +2 -0
  106. package/dist/examples/generated/order.types.js.map +1 -0
  107. package/dist/examples/generated/pet.types.d.ts +11 -0
  108. package/dist/examples/generated/pet.types.d.ts.map +1 -0
  109. package/dist/examples/generated/pet.types.js +2 -0
  110. package/dist/examples/generated/pet.types.js.map +1 -0
  111. package/dist/examples/pet-store.d.ts +137 -0
  112. package/dist/examples/pet-store.d.ts.map +1 -0
  113. package/dist/examples/pet-store.js +139 -0
  114. package/dist/examples/pet-store.js.map +1 -0
  115. package/dist/examples/src/customer.e2e.d.ts +2 -0
  116. package/dist/examples/src/customer.e2e.d.ts.map +1 -0
  117. package/dist/examples/src/customer.e2e.js +17 -0
  118. package/dist/examples/src/customer.e2e.js.map +1 -0
  119. package/dist/examples/src/customer.orchestrators.d.ts +5 -0
  120. package/dist/examples/src/customer.orchestrators.d.ts.map +1 -0
  121. package/dist/examples/src/customer.orchestrators.js +5 -0
  122. package/dist/examples/src/customer.orchestrators.js.map +1 -0
  123. package/dist/examples/src/order.e2e.d.ts +2 -0
  124. package/dist/examples/src/order.e2e.d.ts.map +1 -0
  125. package/dist/examples/src/order.e2e.js +22 -0
  126. package/dist/examples/src/order.e2e.js.map +1 -0
  127. package/dist/examples/src/order.orchestrators.d.ts +9 -0
  128. package/dist/examples/src/order.orchestrators.d.ts.map +1 -0
  129. package/dist/examples/src/order.orchestrators.js +10 -0
  130. package/dist/examples/src/order.orchestrators.js.map +1 -0
  131. package/dist/examples/src/pet.e2e.d.ts +2 -0
  132. package/dist/examples/src/pet.e2e.d.ts.map +1 -0
  133. package/dist/examples/src/pet.e2e.js +17 -0
  134. package/dist/examples/src/pet.e2e.js.map +1 -0
  135. package/dist/examples/src/pet.orchestrators.d.ts +8 -0
  136. package/dist/examples/src/pet.orchestrators.d.ts.map +1 -0
  137. package/dist/examples/src/pet.orchestrators.js +9 -0
  138. package/dist/examples/src/pet.orchestrators.js.map +1 -0
  139. package/dist/schema/actions.d.ts +37 -0
  140. package/dist/schema/actions.d.ts.map +1 -0
  141. package/dist/schema/actions.js +35 -0
  142. package/dist/schema/actions.js.map +1 -0
  143. package/dist/schema/constraints.d.ts +20 -0
  144. package/dist/schema/constraints.d.ts.map +1 -0
  145. package/dist/schema/constraints.js +15 -0
  146. package/dist/schema/constraints.js.map +1 -0
  147. package/dist/schema/decisions.d.ts +29 -0
  148. package/dist/schema/decisions.d.ts.map +1 -0
  149. package/dist/schema/decisions.js +56 -0
  150. package/dist/schema/decisions.js.map +1 -0
  151. package/dist/schema/index.d.ts +17 -0
  152. package/dist/schema/index.d.ts.map +1 -0
  153. package/dist/schema/index.js +8 -0
  154. package/dist/schema/index.js.map +1 -0
  155. package/dist/schema/model.d.ts +65 -0
  156. package/dist/schema/model.d.ts.map +1 -0
  157. package/dist/schema/model.js +30 -0
  158. package/dist/schema/model.js.map +1 -0
  159. package/dist/schema/policy.d.ts +25 -0
  160. package/dist/schema/policy.d.ts.map +1 -0
  161. package/dist/schema/policy.js +53 -0
  162. package/dist/schema/policy.js.map +1 -0
  163. package/dist/schema/props.d.ts +57 -0
  164. package/dist/schema/props.d.ts.map +1 -0
  165. package/dist/schema/props.js +53 -0
  166. package/dist/schema/props.js.map +1 -0
  167. package/dist/schema/relations.d.ts +9 -0
  168. package/dist/schema/relations.d.ts.map +1 -0
  169. package/dist/schema/relations.js +9 -0
  170. package/dist/schema/relations.js.map +1 -0
  171. package/dist/schema/transitions.d.ts +34 -0
  172. package/dist/schema/transitions.d.ts.map +1 -0
  173. package/dist/schema/transitions.js +25 -0
  174. package/dist/schema/transitions.js.map +1 -0
  175. package/dist/schema/types.d.ts +18 -0
  176. package/dist/schema/types.d.ts.map +1 -0
  177. package/dist/schema/types.js +11 -0
  178. package/dist/schema/types.js.map +1 -0
  179. package/package.json +55 -0
@@ -0,0 +1,357 @@
1
+ /**
2
+ * Compile-time exhaustiveness check. Pass the narrowed-to-never value here;
3
+ * if a new variant is added to PropKind (or any union) without updating the
4
+ * switch, TypeScript will error because the value won't be `never`.
5
+ */
6
+ const assertExhaustive = (value) => {
7
+ throw new Error(`Unhandled value: ${String(value)}`);
8
+ };
9
+ const guardParseError = (message) => Object.assign(new Error(message), {
10
+ guardParse: true,
11
+ name: "GuardParseError",
12
+ });
13
+ const isGuardParseError = (err) => err instanceof Error && "guardParse" in err;
14
+ /**
15
+ * ModelDef's default generics use structural bases (TransitionDefBase, ConstraintDefBase)
16
+ * that omit guard/scenarios/preventedAction fields. At runtime, model() always stores the
17
+ * full TransitionData/ConstraintData/ActionDef objects. These accessors centralize the
18
+ * single unavoidable cast so all generators can work with properly typed data.
19
+ */
20
+ export const getTransitions = (model) => {
21
+ if (!model.transitions)
22
+ return [];
23
+ return Object.entries(model.transitions);
24
+ };
25
+ export const getConstraints = (model) => {
26
+ if (!model.constraints)
27
+ return [];
28
+ return Object.entries(model.constraints);
29
+ };
30
+ export const getActions = (model) => {
31
+ if (!model.actions)
32
+ return [];
33
+ return Object.entries(model.actions);
34
+ };
35
+ export const getRelations = (model) => {
36
+ if (!model.relations)
37
+ return [];
38
+ return Object.entries(model.relations);
39
+ };
40
+ export const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
41
+ /** Converts PascalCase to kebab-case: "ContrastThresholds" → "contrast-thresholds" */
42
+ export const toKebabCase = (name) => name
43
+ .replace(/([a-z0-9])([A-Z])/g, "$1-$2")
44
+ .replace(/([A-Z])([A-Z][a-z])/g, "$1-$2")
45
+ .toLowerCase();
46
+ /**
47
+ * Derive the id field name for a relation key. Appends Id/Ids to key as-is.
48
+ * belongsTo "customer" → "customerId"
49
+ * hasMany "item" → "itemIds"
50
+ *
51
+ * Use singular relation keys for clean output (e.g. `item: hasMany(Pet)` not `items`).
52
+ */
53
+ export const relationIdField = (key, kind) => {
54
+ if (kind === "belongsTo")
55
+ return `${key}Id`;
56
+ return `${key}Ids`;
57
+ };
58
+ /**
59
+ * Extracts the values array from a lifecycle or oneOf PropDef.
60
+ * PropDef<K, V> defaults V to unknown, so switch narrowing on `kind` doesn't
61
+ * narrow `values` to `readonly string[]`. This helper centralizes the cast.
62
+ */
63
+ const getEnumValues = (prop) => prop.values;
64
+ const formatUnionValues = (values) => values.map((v) => `'${v}'`).join(" | ");
65
+ /** Map a PropDef kind to its TypeScript type string. */
66
+ export const propKindToTS = (prop) => {
67
+ switch (prop.kind) {
68
+ case "boolean":
69
+ return "boolean";
70
+ case "date":
71
+ return "Date";
72
+ case "lifecycle":
73
+ return formatUnionValues(getEnumValues(prop));
74
+ case "number":
75
+ return "number";
76
+ case "oneOf":
77
+ return formatUnionValues(getEnumValues(prop));
78
+ case "string":
79
+ return "string";
80
+ default:
81
+ return assertExhaustive(prop.kind);
82
+ }
83
+ };
84
+ const formatZodEnum = (values) => {
85
+ const items = values.map((v) => `'${v}'`).join(", ");
86
+ return `z.enum([${items}])`;
87
+ };
88
+ /** Map a PropDef kind to its Zod validator string. */
89
+ export const propKindToZod = (prop) => {
90
+ switch (prop.kind) {
91
+ case "boolean":
92
+ return "z.boolean()";
93
+ case "date":
94
+ return "z.date()";
95
+ case "lifecycle":
96
+ return formatZodEnum(getEnumValues(prop));
97
+ case "number":
98
+ return "z.number()";
99
+ case "oneOf":
100
+ return formatZodEnum(getEnumValues(prop));
101
+ case "string":
102
+ return "z.string()";
103
+ default:
104
+ return assertExhaustive(prop.kind);
105
+ }
106
+ };
107
+ /** Find the single lifecycle prop in a model. Returns null if none. */
108
+ export const getLifecycleProp = (model) => {
109
+ if (!model.props)
110
+ return null;
111
+ for (const [key, prop] of Object.entries(model.props)) {
112
+ if (prop.kind === "lifecycle") {
113
+ return { key, values: getEnumValues(prop) };
114
+ }
115
+ }
116
+ return null;
117
+ };
118
+ /**
119
+ * Extract the body of a guard function as source code via Function.toString().
120
+ *
121
+ * Only single-expression arrow functions are supported:
122
+ * `(ctx) => ctx.total > 0` → `"ctx.total > 0"`
123
+ *
124
+ * Throws on block-body arrows `(ctx) => { ... }` and non-arrow functions.
125
+ *
126
+ * Relies on Function.prototype.toString() returning source text, which is
127
+ * guaranteed by the ECMAScript spec for user-defined functions (not built-ins).
128
+ */
129
+ // Matches `(ctx) =>` or `ctx =>` at the start, capturing param name.
130
+ // Two explicit alternatives avoid backtracking from optional parens + whitespace.
131
+ const GUARD_ARROW_RE = /^(?:\((\w+)\)|(\w+))\s*=>\s*/;
132
+ export const guardToSource = (guard) => {
133
+ try {
134
+ const src = guard.toString();
135
+ const match = GUARD_ARROW_RE.exec(src);
136
+ if (!match) {
137
+ throw guardParseError("Guard must be a single-parameter arrow function: (ctx) => expr. " +
138
+ "Got: " +
139
+ src.slice(0, 80));
140
+ }
141
+ const paramName = match[1] ?? match[2];
142
+ if (paramName !== "ctx") {
143
+ throw guardParseError(`Guard parameter must be named "ctx": (ctx) => expr. ` +
144
+ `Got: "${paramName}". ` +
145
+ "Destructured or renamed parameters are not supported by codegen.");
146
+ }
147
+ const rawBody = src.slice(match[0].length).trim();
148
+ // Normalize operator spacing in guard bodies.
149
+ // Function.toString() preserves original formatting which may lack spaces.
150
+ // Insert spaces around operators, then collapse any duplicate spaces.
151
+ const body = rawBody
152
+ .replace(/(\w)([><=!]=?=?)(\w)/g, "$1 $2 $3")
153
+ .replace(/(\w)(&&|\|\|)(\w)/g, "$1 $2 $3")
154
+ .replace(/ {2,}/g, " ");
155
+ if (!body.includes("ctx")) {
156
+ throw guardParseError("Guard function body does not reference 'ctx'. " +
157
+ "This may indicate minified code — codegen requires unminified source. " +
158
+ `Got: "${body.slice(0, 80)}"`);
159
+ }
160
+ if (body.startsWith("{")) {
161
+ throw guardParseError("Block-body arrow functions not supported, use single-expression: " +
162
+ "(ctx) => ctx.total > 0");
163
+ }
164
+ return body;
165
+ }
166
+ catch (err) {
167
+ if (isGuardParseError(err)) {
168
+ throw err;
169
+ }
170
+ const message = err instanceof Error ? err.message : String(err);
171
+ throw guardParseError(`Failed to serialize guard function: ${message}`);
172
+ }
173
+ };
174
+ /**
175
+ * Resolve external closure references in a guard body by probing the guard
176
+ * function with known enum/lifecycle values from the model.
177
+ *
178
+ * Guards like `(ctx) => ctx.status === orderStates.cancelled` serialize to a
179
+ * body containing `orderStates.cancelled` — an identifier that doesn't exist
180
+ * in generated code. This function detects such references and replaces them
181
+ * with their resolved string literal values.
182
+ *
183
+ * Works by finding `ctx.prop === ref` or `ref === ctx.prop` patterns, then
184
+ * calling the guard with each possible enum value until one matches.
185
+ *
186
+ * Limitations:
187
+ * - Only matches single-dot refs like `states.cancelled`, not deeper paths.
188
+ * This is intentional — lifecycle.states() produces `{ name: name }` objects.
189
+ * - Only matches `===` / `==` operators. `!==` / `!=` are not matched by the
190
+ * regex and will pass through unchanged (the external ref stays in the body).
191
+ */
192
+ export const resolveGuardBody = (guard, body, model) => {
193
+ // Match `ctx.prop === externalRef` — negative lookaheads prevent matching
194
+ // ctx.x === ctx.y, ctx.x === 'literal', and ctx.x === 42.
195
+ const CTX_EQ_REF = /ctx\.(\w+)\s*={2,3}\s*(?!ctx\.|['"`\d])([a-zA-Z_$]\w*\.\w+)/g;
196
+ // Match `externalRef === ctx.prop` (reversed operand order).
197
+ // eslint-disable-next-line sonarjs/slow-regex -- input is a short guard body, not user-supplied
198
+ const REF_EQ_CTX = /(?!ctx\.)([a-zA-Z_$]\w*\.\w+)\s*={2,3}\s*ctx\.(\w+)/g;
199
+ // Build once, reuse across all tryResolve calls.
200
+ const defaults = buildModelDefaults(model);
201
+ const tryResolve = (propName) => {
202
+ const prop = model.props?.[propName];
203
+ if (!prop || (prop.kind !== "lifecycle" && prop.kind !== "oneOf"))
204
+ return undefined;
205
+ const values = prop.values;
206
+ for (const value of values) {
207
+ try {
208
+ if (guard({ ...defaults, [propName]: value }) === true) {
209
+ return `'${value}'`;
210
+ }
211
+ }
212
+ catch {
213
+ /* guard may access missing props, skip */
214
+ }
215
+ }
216
+ return undefined;
217
+ };
218
+ let resolved = body;
219
+ // ctx.prop === externalRef
220
+ resolved = resolved.replace(CTX_EQ_REF, (match, propName, refStr) => {
221
+ const value = tryResolve(propName);
222
+ return value ? match.replace(refStr, value) : match;
223
+ });
224
+ // externalRef === ctx.prop
225
+ resolved = resolved.replace(REF_EQ_CTX, (match, refStr, propName) => {
226
+ const value = tryResolve(propName);
227
+ return value ? match.replace(refStr, value) : match;
228
+ });
229
+ return resolved;
230
+ };
231
+ /** Serialize a JS value to embeddable source code (string literal, number, boolean). */
232
+ export const valueToSource = (value) => {
233
+ if (typeof value === "string")
234
+ return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
235
+ if (typeof value === "number" || typeof value === "boolean")
236
+ return String(value);
237
+ if (value instanceof Date)
238
+ return `new Date('${value.toISOString()}')`;
239
+ return JSON.stringify(value);
240
+ };
241
+ /** Return a sensible default value (as source code) for a PropDef kind. */
242
+ export const defaultValueForProp = (prop) => {
243
+ switch (prop.kind) {
244
+ case "boolean":
245
+ return "false";
246
+ case "date":
247
+ return "new Date(0)";
248
+ case "lifecycle": // fall through
249
+ case "oneOf": {
250
+ const values = prop.values;
251
+ return `'${values[0]}'`;
252
+ }
253
+ case "number":
254
+ return "0";
255
+ case "string":
256
+ return "''";
257
+ default:
258
+ return assertExhaustive(prop.kind);
259
+ }
260
+ };
261
+ /** Convert action fields (Record<string, PropDef>) to a TypeScript type literal. */
262
+ export const fieldsToTSType = (fields) => {
263
+ if (!fields)
264
+ return "unknown";
265
+ const entries = Object.entries(fields);
266
+ if (entries.length === 0)
267
+ return "{}";
268
+ const props = entries
269
+ .map(([key, prop]) => `${key}: ${propKindToTS(prop)}`)
270
+ .join("; ");
271
+ return `{ ${props} }`;
272
+ };
273
+ /**
274
+ * Build default values for all props in a model (as runtime JS values, not source).
275
+ * Used by resolvePolicyGuardBody to probe guard functions.
276
+ */
277
+ export const buildModelDefaults = (model) => {
278
+ const defaults = {};
279
+ if (!model.props)
280
+ return defaults;
281
+ for (const [key, prop] of Object.entries(model.props)) {
282
+ switch (prop.kind) {
283
+ case "boolean":
284
+ defaults[key] = false;
285
+ break;
286
+ case "date":
287
+ defaults[key] = new Date(0);
288
+ break;
289
+ case "lifecycle":
290
+ // fall through
291
+ case "oneOf":
292
+ defaults[key] = prop.values[0] ?? "";
293
+ break;
294
+ case "number":
295
+ defaults[key] = 0;
296
+ break;
297
+ case "string":
298
+ defaults[key] = "";
299
+ break;
300
+ }
301
+ }
302
+ return defaults;
303
+ };
304
+ /**
305
+ * Resolve external closure references in a policy guard body.
306
+ *
307
+ * Policy guards access nested ctx: `ctx.customer.status === customerStates.suspended`.
308
+ * This function resolves `customerStates.suspended` to `'suspended'` by probing the
309
+ * guard function with known enum values from the required models.
310
+ *
311
+ * @param guard - The guard function (closure with captured variables)
312
+ * @param body - Raw guard body from guardToSource
313
+ * @param requiresModels - Map of requires key → resolved ModelDef
314
+ */
315
+ export const resolvePolicyGuardBody = (guard, body, requiresModels) => {
316
+ // Match ctx.KEY.PROP === externalRef (not ctx., not literal)
317
+ const CTX_NESTED_EQ_REF = /ctx\.(\w+)\.(\w+)\s*={2,3}\s*(?!ctx\.|['"`\d])([a-zA-Z_$]\w*\.\w+)/g;
318
+ // Match externalRef === ctx.KEY.PROP (reversed operand order)
319
+ const REF_EQ_CTX_NESTED =
320
+ // eslint-disable-next-line sonarjs/slow-regex -- input is a short guard body, not user-supplied
321
+ /(?!ctx\.)([a-zA-Z_$]\w*\.\w+)\s*={2,3}\s*ctx\.(\w+)\.(\w+)/g;
322
+ const tryResolve = (reqKey, propName) => {
323
+ const model = requiresModels[reqKey];
324
+ if (!model?.props)
325
+ return undefined;
326
+ const prop = model.props[propName];
327
+ if (!prop || (prop.kind !== "lifecycle" && prop.kind !== "oneOf"))
328
+ return undefined;
329
+ const values = prop.values;
330
+ const defaults = buildModelDefaults(model);
331
+ for (const value of values) {
332
+ try {
333
+ const ctx = { [reqKey]: { ...defaults, [propName]: value } };
334
+ if (guard(ctx) === true) {
335
+ return `'${value}'`;
336
+ }
337
+ }
338
+ catch {
339
+ /* guard may access missing props, skip */
340
+ }
341
+ }
342
+ return undefined;
343
+ };
344
+ let resolved = body;
345
+ // ctx.key.prop === externalRef
346
+ resolved = resolved.replace(CTX_NESTED_EQ_REF, (match, reqKey, propName, refStr) => {
347
+ const value = tryResolve(reqKey, propName);
348
+ return value ? match.replace(refStr, value) : match;
349
+ });
350
+ // externalRef === ctx.key.prop
351
+ resolved = resolved.replace(REF_EQ_CTX_NESTED, (match, refStr, reqKey, propName) => {
352
+ const value = tryResolve(reqKey, propName);
353
+ return value ? match.replace(refStr, value) : match;
354
+ });
355
+ return resolved;
356
+ };
357
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/codegen/utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { ModelDef } from "../schema/model.js";
2
+ /** Generate Zod validation schema from a model's props and relations. Targets Zod v3.x / v4.x (z.object, z.enum). */
3
+ export declare const generateZod: (model: ModelDef) => string;
4
+ //# sourceMappingURL=zod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod.d.ts","sourceRoot":"","sources":["../../src/codegen/zod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAUnD,qHAAqH;AACrH,eAAO,MAAM,WAAW,GAAI,OAAO,QAAQ,KAAG,MAsC7C,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { isOptional } from "../schema/props.js";
2
+ import { capitalize, getRelations, propKindToZod, relationIdField, } from "./utils.js";
3
+ /** Generate Zod validation schema from a model's props and relations. Targets Zod v3.x / v4.x (z.object, z.enum). */
4
+ export const generateZod = (model) => {
5
+ const hasProps = model.props && Object.keys(model.props).length > 0;
6
+ const relations = getRelations(model);
7
+ if (!hasProps && relations.length === 0)
8
+ return "";
9
+ const typeName = capitalize(model.name);
10
+ const lines = [];
11
+ lines.push(`import { z } from 'zod';`);
12
+ lines.push("");
13
+ const fields = [];
14
+ if (model.props) {
15
+ for (const [key, prop] of Object.entries(model.props)) {
16
+ const zodType = propKindToZod(prop) + (isOptional(prop) ? ".optional()" : "");
17
+ fields.push(` ${key}: ${zodType},`);
18
+ }
19
+ }
20
+ // Relations: belongsTo → z.string() (foreign key id), hasMany → z.array(z.string()) (ids)
21
+ for (const [key, rel] of relations) {
22
+ const fieldName = relationIdField(key, rel.kind);
23
+ const zodType = rel.kind === "belongsTo" ? "z.string()" : "z.array(z.string())";
24
+ fields.push(` ${fieldName}: ${zodType},`);
25
+ }
26
+ lines.push(`export const ${typeName}Schema = z.object({`);
27
+ lines.push(...fields);
28
+ lines.push(`});`);
29
+ lines.push("");
30
+ return lines.join("\n");
31
+ };
32
+ //# sourceMappingURL=zod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod.js","sourceRoot":"","sources":["../../src/codegen/zod.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EACL,UAAU,EACV,YAAY,EACZ,aAAa,EACb,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,qHAAqH;AACrH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAe,EAAU,EAAE;IACrD,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAEtC,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEnD,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACvC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACtD,MAAM,OAAO,GACX,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAEhE,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,OAAO,GAAG,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,0FAA0F;IAC1F,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,SAAS,EAAE,CAAC;QACnC,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QACjD,MAAM,OAAO,GACX,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,qBAAqB,CAAC;QAElE,MAAM,CAAC,IAAI,CAAC,KAAK,SAAS,KAAK,OAAO,GAAG,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,gBAAgB,QAAQ,qBAAqB,CAAC,CAAC;IAC1D,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;IACtB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ export type CustomerStatus = "active" | "suspended" | "deleted";
2
+ export type CustomerProps = {
3
+ email: string;
4
+ name: string;
5
+ status: CustomerStatus;
6
+ };
7
+ //# sourceMappingURL=customer.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"customer.types.d.ts","sourceRoot":"","sources":["../../../src/examples/generated/customer.types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;AAEhE,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=customer.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"customer.types.js","sourceRoot":"","sources":["../../../src/examples/generated/customer.types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ export type OrderStatus = "pending" | "paid" | "shipped" | "delivered" | "cancelled";
2
+ export type OrderProps = {
3
+ createdAt: Date;
4
+ status: OrderStatus;
5
+ total: number;
6
+ customerId: string;
7
+ itemIds: string[];
8
+ };
9
+ //# sourceMappingURL=order.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"order.types.d.ts","sourceRoot":"","sources":["../../../src/examples/generated/order.types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GACnB,SAAS,GACT,MAAM,GACN,SAAS,GACT,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,IAAI,CAAC;IAChB,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=order.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"order.types.js","sourceRoot":"","sources":["../../../src/examples/generated/order.types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ export type PetSpecies = "dog" | "cat" | "bird" | "fish";
2
+ export type PetStatus = "available" | "reserved" | "sold";
3
+ export type PetProps = {
4
+ name: string;
5
+ nickname?: string;
6
+ price: number;
7
+ species: PetSpecies;
8
+ status: PetStatus;
9
+ vaccinated: boolean;
10
+ };
11
+ //# sourceMappingURL=pet.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pet.types.d.ts","sourceRoot":"","sources":["../../../src/examples/generated/pet.types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AACzD,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAAC;AAE1D,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,CAAC;IACpB,MAAM,EAAE,SAAS,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pet.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pet.types.js","sourceRoot":"","sources":["../../../src/examples/generated/pet.types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,137 @@
1
+ declare const Customer: import("../schema/model.js").ModelDef<"Customer", {
2
+ readonly email: import("../schema/props.js").StringProp;
3
+ readonly name: import("../schema/props.js").StringProp;
4
+ readonly status: import("../schema/props.js").LifecycleProp<readonly ["active", "suspended", "deleted"]>;
5
+ }, {
6
+ readonly updateEmail: import("../schema/actions.js").ActionDef<{
7
+ email: string;
8
+ }>;
9
+ }, Record<string, never>, {
10
+ delete: import("../schema/transitions.js").TransitionBuilder<"active", "deleted", {
11
+ readonly email: string;
12
+ readonly name: string;
13
+ readonly status: "active" | "suspended" | "deleted";
14
+ }, "active" | "suspended" | "deleted">;
15
+ reactivate: import("../schema/transitions.js").TransitionBuilder<"suspended", "active", {
16
+ readonly email: string;
17
+ readonly name: string;
18
+ readonly status: "active" | "suspended" | "deleted";
19
+ }, "active" | "suspended" | "deleted">;
20
+ suspend: import("../schema/transitions.js").TransitionBuilder<"active", "suspended", {
21
+ readonly email: string;
22
+ readonly name: string;
23
+ readonly status: "active" | "suspended" | "deleted";
24
+ }, "active" | "suspended" | "deleted">;
25
+ }, Record<string, never>>;
26
+ declare const Pet: import("../schema/model.js").ModelDef<"Pet", {
27
+ readonly name: import("../schema/props.js").StringProp;
28
+ readonly nickname: import("../schema/props.js").OptionalPropDef<import("../schema/props.js").StringProp>;
29
+ readonly price: import("../schema/props.js").NumberProp;
30
+ readonly species: import("../schema/props.js").OneOfProp<readonly ["dog", "cat", "bird", "fish"]>;
31
+ readonly status: import("../schema/props.js").LifecycleProp<readonly ["available", "reserved", "sold"]>;
32
+ readonly vaccinated: import("../schema/props.js").BooleanProp;
33
+ }, {
34
+ readonly updatePrice: import("../schema/actions.js").ActionDef<{
35
+ price: number;
36
+ }>;
37
+ readonly vaccinate: import("../schema/actions.js").ActionDef<{
38
+ date: string;
39
+ }>;
40
+ }, Record<string, never>, {
41
+ release: import("../schema/transitions.js").TransitionBuilder<"reserved", "available", {
42
+ readonly nickname?: string;
43
+ readonly name: string;
44
+ readonly price: number;
45
+ readonly species: "dog" | "cat" | "bird" | "fish";
46
+ readonly status: "available" | "reserved" | "sold";
47
+ readonly vaccinated: boolean;
48
+ }, "available" | "reserved" | "sold">;
49
+ reserve: import("../schema/transitions.js").TransitionBuilder<"available", "reserved", {
50
+ readonly nickname?: string;
51
+ readonly name: string;
52
+ readonly price: number;
53
+ readonly species: "dog" | "cat" | "bird" | "fish";
54
+ readonly status: "available" | "reserved" | "sold";
55
+ readonly vaccinated: boolean;
56
+ }, "available" | "reserved" | "sold">;
57
+ sell: import("../schema/transitions.js").TransitionBuilder<"reserved", "sold", {
58
+ readonly nickname?: string;
59
+ readonly name: string;
60
+ readonly price: number;
61
+ readonly species: "dog" | "cat" | "bird" | "fish";
62
+ readonly status: "available" | "reserved" | "sold";
63
+ readonly vaccinated: boolean;
64
+ }, "available" | "reserved" | "sold">;
65
+ }, {
66
+ nicknameTooLong: import("../schema/constraints.js").ConstraintBuilder<{
67
+ readonly nickname?: string;
68
+ readonly name: string;
69
+ readonly price: number;
70
+ readonly species: "dog" | "cat" | "bird" | "fish";
71
+ readonly status: "available" | "reserved" | "sold";
72
+ readonly vaccinated: boolean;
73
+ }, "updatePrice" | "vaccinate">;
74
+ }>;
75
+ declare const Order: import("../schema/model.js").ModelDef<"Order", {
76
+ readonly createdAt: import("../schema/props.js").DateProp;
77
+ readonly status: import("../schema/props.js").LifecycleProp<readonly ["pending", "paid", "shipped", "delivered", "cancelled"]>;
78
+ readonly total: import("../schema/props.js").NumberProp;
79
+ }, {
80
+ readonly addItem: import("../schema/actions.js").ActionDef<{
81
+ productId: string;
82
+ quantity: number;
83
+ }>;
84
+ readonly removeItem: import("../schema/actions.js").ActionDef<{
85
+ itemId: string;
86
+ }>;
87
+ }, {
88
+ readonly customer: import("../schema/relations.js").RelationDef<"belongsTo">;
89
+ readonly item: import("../schema/relations.js").RelationDef<"hasMany">;
90
+ }, {
91
+ cancel: import("../schema/transitions.js").TransitionBuilder<"pending", "cancelled", {
92
+ readonly createdAt: Date;
93
+ readonly status: "pending" | "paid" | "shipped" | "delivered" | "cancelled";
94
+ readonly total: number;
95
+ }, "pending" | "paid" | "shipped" | "delivered" | "cancelled">;
96
+ deliver: import("../schema/transitions.js").TransitionBuilder<"shipped", "delivered", {
97
+ readonly createdAt: Date;
98
+ readonly status: "pending" | "paid" | "shipped" | "delivered" | "cancelled";
99
+ readonly total: number;
100
+ }, "pending" | "paid" | "shipped" | "delivered" | "cancelled">;
101
+ pay: import("../schema/transitions.js").TransitionBuilder<"pending", "paid", {
102
+ readonly createdAt: Date;
103
+ readonly status: "pending" | "paid" | "shipped" | "delivered" | "cancelled";
104
+ readonly total: number;
105
+ }, "pending" | "paid" | "shipped" | "delivered" | "cancelled">;
106
+ ship: import("../schema/transitions.js").TransitionBuilder<"paid", "shipped", {
107
+ readonly createdAt: Date;
108
+ readonly status: "pending" | "paid" | "shipped" | "delivered" | "cancelled";
109
+ readonly total: number;
110
+ }, "pending" | "paid" | "shipped" | "delivered" | "cancelled">;
111
+ }, {
112
+ cannotAddWhenCancelled: import("../schema/constraints.js").ConstraintBuilder<{
113
+ readonly createdAt: Date;
114
+ readonly status: "pending" | "paid" | "shipped" | "delivered" | "cancelled";
115
+ readonly total: number;
116
+ }, "addItem" | "removeItem">;
117
+ cannotRemoveWhenEmpty: import("../schema/constraints.js").ConstraintBuilder<{
118
+ readonly createdAt: Date;
119
+ readonly status: "pending" | "paid" | "shipped" | "delivered" | "cancelled";
120
+ readonly total: number;
121
+ }, "addItem" | "removeItem">;
122
+ }>;
123
+ declare const CreditTier: import("../schema/decisions.js").DecisionDef<"CreditTier", {
124
+ readonly amount: import("../schema/props.js").NumberProp;
125
+ readonly extraItemId: import("../schema/props.js").StringProp;
126
+ }, {
127
+ readonly credits: import("../schema/props.js").NumberProp;
128
+ }>;
129
+ declare const PetAdoptionFee: import("../schema/decisions.js").DecisionDef<"PetAdoptionFee", {
130
+ readonly species: import("../schema/props.js").OneOfProp<readonly ["dog", "cat", "bird", "fish"]>;
131
+ readonly vaccinated: import("../schema/props.js").BooleanProp;
132
+ }, {
133
+ readonly fee: import("../schema/props.js").NumberProp;
134
+ }>;
135
+ declare const NoSuspendedCustomerOrders: import("../schema/policy.js").PolicyDef<"NoSuspendedCustomerOrders">;
136
+ export { CreditTier, Customer, NoSuspendedCustomerOrders, Order, Pet, PetAdoptionFee, };
137
+ //# sourceMappingURL=pet-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pet-store.d.ts","sourceRoot":"","sources":["../../src/examples/pet-store.ts"],"names":[],"mappings":"AAoBA,QAAA,MAAM,QAAQ;;;;;;eAEmB,MAAM;;;;;;;;;;;;;;;;;;yBAYrC,CAAC;AAeH,QAAA,MAAM,GAAG;;;;;;;;;eAEwB,MAAM;;;cACT,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBlC,CAAC;AAYH,QAAA,MAAM,KAAK;;;;;;mBAEsB,MAAM;kBAAY,MAAM;;;gBAIxB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BrC,CAAC;AAIH,QAAA,MAAM,UAAU;;;;;EAQd,CAAC;AAOH,QAAA,MAAM,cAAc;;;;;EAWlB,CAAC;AAKH,QAAA,MAAM,yBAAyB,sEAe7B,CAAC;AAEH,OAAO,EACL,UAAU,EACV,QAAQ,EACR,yBAAyB,EACzB,KAAK,EACL,GAAG,EACH,cAAc,GACf,CAAC"}