primitive-admin 1.0.52 → 1.0.54

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 (141) hide show
  1. package/README.md +38 -10
  2. package/dist/bin/primitive.js +6 -0
  3. package/dist/bin/primitive.js.map +1 -1
  4. package/dist/src/commands/auth.js +16 -6
  5. package/dist/src/commands/auth.js.map +1 -1
  6. package/dist/src/commands/blob-buckets.js +84 -7
  7. package/dist/src/commands/blob-buckets.js.map +1 -1
  8. package/dist/src/commands/catalog.js +3 -3
  9. package/dist/src/commands/catalog.js.map +1 -1
  10. package/dist/src/commands/collections.js +12 -9
  11. package/dist/src/commands/collections.js.map +1 -1
  12. package/dist/src/commands/database-types.js +11 -1
  13. package/dist/src/commands/database-types.js.map +1 -1
  14. package/dist/src/commands/databases.js +197 -74
  15. package/dist/src/commands/databases.js.map +1 -1
  16. package/dist/src/commands/group-type-configs.js +1 -9
  17. package/dist/src/commands/group-type-configs.js.map +1 -1
  18. package/dist/src/commands/groups.js +12 -6
  19. package/dist/src/commands/groups.js.map +1 -1
  20. package/dist/src/commands/guides.d.ts +161 -0
  21. package/dist/src/commands/guides.js +502 -84
  22. package/dist/src/commands/guides.js.map +1 -1
  23. package/dist/src/commands/init.js +77 -45
  24. package/dist/src/commands/init.js.map +1 -1
  25. package/dist/src/commands/integrations.js +2 -2
  26. package/dist/src/commands/integrations.js.map +1 -1
  27. package/dist/src/commands/metadata.d.ts +2 -0
  28. package/dist/src/commands/metadata.js +344 -0
  29. package/dist/src/commands/metadata.js.map +1 -0
  30. package/dist/src/commands/prompts.js +2 -2
  31. package/dist/src/commands/prompts.js.map +1 -1
  32. package/dist/src/commands/rule-sets.d.ts +1 -0
  33. package/dist/src/commands/rule-sets.js +25 -3
  34. package/dist/src/commands/rule-sets.js.map +1 -1
  35. package/dist/src/commands/scripts.d.ts +2 -0
  36. package/dist/src/commands/scripts.js +667 -0
  37. package/dist/src/commands/scripts.js.map +1 -0
  38. package/dist/src/commands/sync.d.ts +212 -16
  39. package/dist/src/commands/sync.js +1688 -287
  40. package/dist/src/commands/sync.js.map +1 -1
  41. package/dist/src/commands/vars.d.ts +8 -0
  42. package/dist/src/commands/vars.js +110 -0
  43. package/dist/src/commands/vars.js.map +1 -0
  44. package/dist/src/commands/webhooks.js +17 -3
  45. package/dist/src/commands/webhooks.js.map +1 -1
  46. package/dist/src/commands/workflows.d.ts +30 -0
  47. package/dist/src/commands/workflows.js +651 -52
  48. package/dist/src/commands/workflows.js.map +1 -1
  49. package/dist/src/lib/api-client.d.ts +123 -19
  50. package/dist/src/lib/api-client.js +128 -4
  51. package/dist/src/lib/api-client.js.map +1 -1
  52. package/dist/src/lib/batch.d.ts +26 -0
  53. package/dist/src/lib/batch.js +32 -0
  54. package/dist/src/lib/batch.js.map +1 -0
  55. package/dist/src/lib/block-layout.d.ts +160 -0
  56. package/dist/src/lib/block-layout.js +451 -0
  57. package/dist/src/lib/block-layout.js.map +1 -0
  58. package/dist/src/lib/codegen-shared/generatedFiles.d.ts +61 -0
  59. package/dist/src/lib/codegen-shared/generatedFiles.js +127 -0
  60. package/dist/src/lib/codegen-shared/generatedFiles.js.map +1 -0
  61. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.d.ts +68 -0
  62. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js +168 -0
  63. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js.map +1 -0
  64. package/dist/src/lib/config-toml.d.ts +10 -0
  65. package/dist/src/lib/config-toml.js +42 -0
  66. package/dist/src/lib/config-toml.js.map +1 -0
  67. package/dist/src/lib/config.d.ts +16 -0
  68. package/dist/src/lib/config.js +41 -0
  69. package/dist/src/lib/config.js.map +1 -1
  70. package/dist/src/lib/constants.d.ts +9 -0
  71. package/dist/src/lib/constants.js +9 -0
  72. package/dist/src/lib/constants.js.map +1 -1
  73. package/dist/src/lib/csv.d.ts +1 -2
  74. package/dist/src/lib/csv.js +3 -8
  75. package/dist/src/lib/csv.js.map +1 -1
  76. package/dist/src/lib/db-codegen/dbGenerator.d.ts +35 -7
  77. package/dist/src/lib/db-codegen/dbGenerator.js +384 -125
  78. package/dist/src/lib/db-codegen/dbGenerator.js.map +1 -1
  79. package/dist/src/lib/db-codegen/dbNaming.d.ts +29 -0
  80. package/dist/src/lib/db-codegen/dbNaming.js +58 -0
  81. package/dist/src/lib/db-codegen/dbNaming.js.map +1 -1
  82. package/dist/src/lib/db-codegen/dbTemplates.d.ts +114 -5
  83. package/dist/src/lib/db-codegen/dbTemplates.js +163 -16
  84. package/dist/src/lib/db-codegen/dbTemplates.js.map +1 -1
  85. package/dist/src/lib/db-codegen/dbTsTypes.d.ts +7 -3
  86. package/dist/src/lib/db-codegen/dbTsTypes.js +23 -1
  87. package/dist/src/lib/db-codegen/dbTsTypes.js.map +1 -1
  88. package/dist/src/lib/generated-allowlist.js +52 -0
  89. package/dist/src/lib/generated-allowlist.js.map +1 -1
  90. package/dist/src/lib/init-config.d.ts +13 -0
  91. package/dist/src/lib/init-config.js +21 -2
  92. package/dist/src/lib/init-config.js.map +1 -1
  93. package/dist/src/lib/output.d.ts +42 -5
  94. package/dist/src/lib/output.js +70 -4
  95. package/dist/src/lib/output.js.map +1 -1
  96. package/dist/src/lib/query-operators.d.ts +43 -0
  97. package/dist/src/lib/query-operators.js +80 -0
  98. package/dist/src/lib/query-operators.js.map +1 -0
  99. package/dist/src/lib/template.d.ts +9 -5
  100. package/dist/src/lib/template.js +58 -45
  101. package/dist/src/lib/template.js.map +1 -1
  102. package/dist/src/lib/toml-database-config.d.ts +10 -19
  103. package/dist/src/lib/toml-database-config.js +28 -59
  104. package/dist/src/lib/toml-database-config.js.map +1 -1
  105. package/dist/src/lib/toml-metadata-config.d.ts +147 -0
  106. package/dist/src/lib/toml-metadata-config.js +463 -0
  107. package/dist/src/lib/toml-metadata-config.js.map +1 -0
  108. package/dist/src/lib/toml-native-form.d.ts +46 -0
  109. package/dist/src/lib/toml-native-form.js +78 -0
  110. package/dist/src/lib/toml-native-form.js.map +1 -0
  111. package/dist/src/lib/toml-params-validator.d.ts +34 -0
  112. package/dist/src/lib/toml-params-validator.js +118 -3
  113. package/dist/src/lib/toml-params-validator.js.map +1 -1
  114. package/dist/src/lib/workflow-apply.d.ts +86 -0
  115. package/dist/src/lib/workflow-apply.js +127 -0
  116. package/dist/src/lib/workflow-apply.js.map +1 -0
  117. package/dist/src/lib/workflow-codegen/generated-schema-descriptor.d.ts +129 -0
  118. package/dist/src/lib/workflow-codegen/generated-schema-descriptor.js +269 -0
  119. package/dist/src/lib/workflow-codegen/generated-schema-descriptor.js.map +1 -0
  120. package/dist/src/lib/workflow-codegen/generator.d.ts +74 -0
  121. package/dist/src/lib/workflow-codegen/generator.js +215 -0
  122. package/dist/src/lib/workflow-codegen/generator.js.map +1 -0
  123. package/dist/src/lib/workflow-codegen/naming.d.ts +33 -0
  124. package/dist/src/lib/workflow-codegen/naming.js +81 -0
  125. package/dist/src/lib/workflow-codegen/naming.js.map +1 -0
  126. package/dist/src/lib/workflow-codegen/schemaToTs.d.ts +64 -0
  127. package/dist/src/lib/workflow-codegen/schemaToTs.js +282 -0
  128. package/dist/src/lib/workflow-codegen/schemaToTs.js.map +1 -0
  129. package/dist/src/lib/workflow-fragments.js +3 -3
  130. package/dist/src/lib/workflow-fragments.js.map +1 -1
  131. package/dist/src/lib/workflow-payload.d.ts +68 -0
  132. package/dist/src/lib/workflow-payload.js +150 -0
  133. package/dist/src/lib/workflow-payload.js.map +1 -0
  134. package/dist/src/lib/workflow-toml-validator.d.ts +1 -1
  135. package/dist/src/lib/workflow-toml-validator.js +37 -1
  136. package/dist/src/lib/workflow-toml-validator.js.map +1 -1
  137. package/dist/src/types/index.d.ts +11 -0
  138. package/dist/src/validators.d.ts +4 -3
  139. package/dist/src/validators.js +6 -5
  140. package/dist/src/validators.js.map +1 -1
  141. package/package.json +5 -3
@@ -0,0 +1,269 @@
1
+ /**
2
+ * GENERATED FILE — DO NOT EDIT BY HAND.
3
+ *
4
+ * Vendored byte-for-byte from the canonical server module
5
+ * `src/workflows/schema-descriptor.ts` — the SAME interpretation the server
6
+ * validator (`validateValue`) enforces. The CLI cannot import server `src/`
7
+ * at runtime, so `workflows codegen`'s type converter imports this committed
8
+ * copy instead.
9
+ *
10
+ * Regenerate with:
11
+ * node cli/scripts/gen-workflow-schema-descriptor.mjs (runs at CLI prebuild)
12
+ *
13
+ * A CI freshness guard
14
+ * (`cli/scripts/gen-workflow-schema-descriptor.mjs --check`, also asserted by
15
+ * `cli/tests/unit/workflow-codegen-descriptor-drift-guard.test.ts`) fails if
16
+ * this committed copy does not match the source — see issue #1442 / #998.
17
+ */
18
+ /**
19
+ * Canonical interpretation of the JSON-Schema subset the workflow platform
20
+ * supports (issue #1442).
21
+ *
22
+ * The server validator (`validateValue` in `schema-validation.ts`) and the CLI
23
+ * `workflows codegen` type converter (`workflow-codegen/schemaToTs.ts`) must
24
+ * agree EXACTLY on how a workflow `inputSchema`/`outputSchema` is interpreted —
25
+ * otherwise a generated `<Key>Input` type promises a shape the runtime does not
26
+ * enforce (or rejects a value the runtime accepts). Previously the converter
27
+ * re-derived those interpretation decisions by hand, which drifts from the
28
+ * validator over time.
29
+ *
30
+ * This module is the single source of that interpretation. Both consumers read
31
+ * from `describeSchema` + `isType`:
32
+ *
33
+ * - the type gate is checked before `enum` (a value failing `type` is
34
+ * rejected before `enum` is consulted);
35
+ * - a type UNION (`type: ["string","null"]`) never descends into
36
+ * `properties`/`items` — only the exact string types `"object"`/`"array"`
37
+ * do;
38
+ * - `integer` means `Number.isInteger`;
39
+ * - `additionalProperties` only closes an object; it is not a nested schema.
40
+ *
41
+ * It is deliberately dependency-free (no imports) so the CLI can vendor a
42
+ * byte-for-byte copy as a committed artifact via
43
+ * `cli/scripts/gen-workflow-schema-descriptor.mjs` (the #998 gen-allowlist
44
+ * pattern). A drift-guard test runs that generator in `--check` mode, so a
45
+ * change here that isn't regenerated into the CLI artifact fails CI. The CLI
46
+ * never imports server `src/` at runtime — only the build-time generator reads
47
+ * this file.
48
+ */
49
+ /** Does a value satisfy a JSON-schema `type` name? `integer` = `Number.isInteger`. */
50
+ export function isType(value, type) {
51
+ if (type === "array")
52
+ return Array.isArray(value);
53
+ if (type === "object")
54
+ return !!value && typeof value === "object" && !Array.isArray(value);
55
+ if (type === "string")
56
+ return typeof value === "string";
57
+ if (type === "number")
58
+ return typeof value === "number" && !Number.isNaN(value);
59
+ if (type === "integer")
60
+ return Number.isInteger(value);
61
+ if (type === "boolean")
62
+ return typeof value === "boolean";
63
+ if (type === "null")
64
+ return value === null;
65
+ // Unknown type name: nothing to enforce, so treat as a match (the validator
66
+ // must not reject a value against a keyword it does not model).
67
+ return true;
68
+ }
69
+ const EMPTY_DESCRIPTOR = {
70
+ isUnion: false,
71
+ singularType: null,
72
+ types: [],
73
+ enumValues: null,
74
+ object: null,
75
+ array: null,
76
+ oneOf: null,
77
+ };
78
+ /**
79
+ * Sibling constraint keywords that make a `oneOf` node a MIXED schema rather
80
+ * than a clean tagged union (#1511). A clean discriminated union carries only
81
+ * the `oneOf` keyword (plus annotations like `description`/`title`); it never
82
+ * combines with a top-level `type`/`properties`/`required`/`additionalProperties`/
83
+ * `items`/`enum`. When any of these co-occur with `oneOf`, the validator's
84
+ * branch-select would early-return and skip those sibling constraints, silently
85
+ * loosening validation. So a mixed node is NOT treated as a clean tagged union.
86
+ */
87
+ const ONEOF_SIBLING_CONSTRAINT_KEYS = [
88
+ "type",
89
+ "properties",
90
+ "required",
91
+ "additionalProperties",
92
+ "items",
93
+ "enum",
94
+ ];
95
+ function hasOneOfSiblingConstraints(schema) {
96
+ return ONEOF_SIBLING_CONSTRAINT_KEYS.some((k) => Object.prototype.hasOwnProperty.call(schema, k));
97
+ }
98
+ /**
99
+ * A discriminator tag must be a comparable scalar (string/number/boolean) so
100
+ * the validator's strict-`===` branch-select can match it against a JSON-parsed
101
+ * value (#1511). An object/array literal is structurally identical after a JSON
102
+ * round-trip but never the same reference, so it would always "match no case".
103
+ * Restricting the auto-detected discriminator to scalars keeps a non-scalar tag
104
+ * from being treated as a (never-matchable) discriminator.
105
+ */
106
+ function isScalarDiscriminatorLiteral(value) {
107
+ return (typeof value === "string" ||
108
+ typeof value === "number" ||
109
+ typeof value === "boolean");
110
+ }
111
+ /**
112
+ * Interpret a `oneOf`/`anyOf` node as a discriminated (tagged) union (#1511).
113
+ *
114
+ * The tagged-union interpretation is scoped to a clearly-intended tagged union:
115
+ * EVERY member must be `type: "object"`. Anything else (a mixed/scalar `oneOf`)
116
+ * returns `null` and is ignored downstream, exactly as before.
117
+ *
118
+ * Within that scope:
119
+ * - `anyOf` is not supported in v1 → `invalid` (codegen error suggests `oneOf`);
120
+ * - a `oneOf` with fewer than 2 members → `invalid`;
121
+ * - the discriminator is auto-detected: the single property present in EVERY
122
+ * member as a single-literal `enum` whose literal is a comparable scalar
123
+ * (string/number/boolean), with distinct literals across members (a
124
+ * non-scalar literal is not a candidate — see `isScalarDiscriminatorLiteral`);
125
+ * - zero or more-than-one candidate discriminator → `invalid` (ambiguity).
126
+ *
127
+ * Pure and dependency-free so the CLI can vendor a byte-for-byte copy.
128
+ */
129
+ function describeOneOf(schema) {
130
+ const rawOneOf = Array.isArray(schema.oneOf) ? schema.oneOf : null;
131
+ const rawAnyOf = Array.isArray(schema.anyOf) ? schema.anyOf : null;
132
+ // `oneOf` takes precedence; only one keyword is interpreted per node.
133
+ const keyword = rawOneOf
134
+ ? "oneOf"
135
+ : rawAnyOf
136
+ ? "anyOf"
137
+ : null;
138
+ const members = rawOneOf ?? rawAnyOf;
139
+ if (!keyword || !members)
140
+ return null;
141
+ // Scope to a clearly-intended tagged union: every member is `type: "object"`.
142
+ // A member that is not a plain object type means this is NOT a tagged union;
143
+ // leave it to the existing ignore-and-render-`unknown` path (backward compat).
144
+ const allObjects = members.length >= 1 &&
145
+ members.every((m) => !!m &&
146
+ typeof m === "object" &&
147
+ !Array.isArray(m) &&
148
+ m.type === "object");
149
+ if (!allObjects)
150
+ return null;
151
+ // `anyOf` is not supported in v1 (resolved Fork 1 = oneOf only). An all-object
152
+ // `anyOf` that looks like a tagged union gets a clear error suggesting oneOf.
153
+ if (keyword === "anyOf") {
154
+ return {
155
+ kind: "invalid",
156
+ reason: "anyOf is not supported for discriminated unions (issue #1511). Use oneOf instead.",
157
+ };
158
+ }
159
+ if (members.length < 2) {
160
+ return {
161
+ kind: "invalid",
162
+ reason: "A discriminated-union oneOf needs at least 2 object members (issue #1511).",
163
+ };
164
+ }
165
+ // For each member, collect its single-literal-enum properties → { name: literal }.
166
+ // The literal must be a comparable scalar (string/number/boolean): the
167
+ // validator branch-selects with strict `===`, so a non-scalar tag (object or
168
+ // array) on a JSON-parsed value is never the same reference as the schema
169
+ // literal and would always "match no case". Restricting the auto-detected
170
+ // discriminator to scalars means a non-scalar tag is not a candidate, so the
171
+ // union routes through the normal not-a-tagged-union path (below) instead of
172
+ // being accepted as a union that can never validate.
173
+ const memberLiteralProps = members.map((m) => {
174
+ const map = new Map();
175
+ const props = m.properties;
176
+ if (props && typeof props === "object" && !Array.isArray(props)) {
177
+ for (const [name, sub] of Object.entries(props)) {
178
+ if (sub &&
179
+ typeof sub === "object" &&
180
+ Array.isArray(sub.enum) &&
181
+ sub.enum.length === 1 &&
182
+ isScalarDiscriminatorLiteral(sub.enum[0])) {
183
+ map.set(name, sub.enum[0]);
184
+ }
185
+ }
186
+ }
187
+ return map;
188
+ });
189
+ // A candidate discriminator is present as a single-literal enum in EVERY
190
+ // member, with distinct literals across members (so a value's tag selects
191
+ // exactly one branch).
192
+ const candidates = [];
193
+ for (const name of memberLiteralProps[0].keys()) {
194
+ if (!memberLiteralProps.every((mp) => mp.has(name)))
195
+ continue;
196
+ const literals = memberLiteralProps.map((mp) => mp.get(name));
197
+ const distinct = new Set(literals.map((l) => JSON.stringify(l)));
198
+ if (distinct.size === literals.length)
199
+ candidates.push(name);
200
+ }
201
+ if (candidates.length !== 1) {
202
+ return {
203
+ kind: "invalid",
204
+ reason: candidates.length === 0
205
+ ? "No discriminator found for the oneOf tagged union (issue #1511): every member must share exactly one property declared as a distinct single-literal enum."
206
+ : `Ambiguous discriminator for the oneOf tagged union (issue #1511): multiple candidate properties (${candidates.join(", ")}). Exactly one is required.`,
207
+ };
208
+ }
209
+ // A clean tagged union carries ONLY `oneOf`. If it co-occurs with sibling
210
+ // top-level constraints (`type`, `properties`, `required`,
211
+ // `additionalProperties`, `items`, `enum`), it is a MIXED schema, not a clean
212
+ // tagged union: the validator's branch-select would early-return and skip
213
+ // those siblings, loosening validation. Reject-mixed keeps all three
214
+ // consumers fail-closed — the validator falls through to the normal
215
+ // type/object gates (still enforcing the siblings, exactly as before #1511),
216
+ // codegen throws this `reason`, and the request guard flags `unsupported-oneof`.
217
+ if (hasOneOfSiblingConstraints(schema)) {
218
+ return {
219
+ kind: "invalid",
220
+ reason: "A discriminated-union oneOf must be the only top-level constraint (issue #1511): it cannot be combined with sibling type/properties/required/additionalProperties/items/enum. Move the shared constraints into each member instead.",
221
+ };
222
+ }
223
+ const discriminant = candidates[0];
224
+ return {
225
+ kind: "valid",
226
+ discriminant,
227
+ members: members.map((m, i) => ({
228
+ discriminantValue: memberLiteralProps[i].get(discriminant),
229
+ schema: m,
230
+ })),
231
+ };
232
+ }
233
+ /**
234
+ * Interpret a parsed schema node. A non-object schema (null, array, scalar)
235
+ * enforces nothing → the empty descriptor.
236
+ */
237
+ export function describeSchema(schema) {
238
+ if (!schema || typeof schema !== "object" || Array.isArray(schema)) {
239
+ return EMPTY_DESCRIPTOR;
240
+ }
241
+ const typeSpec = schema.type;
242
+ const isUnion = Array.isArray(typeSpec);
243
+ const singularType = typeof typeSpec === "string" ? typeSpec : null;
244
+ // Mirror the validator's normalization exactly: an array stays an array; a
245
+ // truthy non-array becomes `[typeSpec]`; anything falsy is `[]`.
246
+ const types = isUnion ? typeSpec : typeSpec ? [typeSpec] : [];
247
+ const enumValues = Array.isArray(schema.enum)
248
+ ? schema.enum
249
+ : null;
250
+ const props = schema.properties;
251
+ const object = singularType === "object" &&
252
+ props &&
253
+ typeof props === "object" &&
254
+ !Array.isArray(props)
255
+ ? {
256
+ properties: props,
257
+ required: Array.isArray(schema.required)
258
+ ? schema.required
259
+ : [],
260
+ additionalPropertiesClosed: schema.additionalProperties === false,
261
+ }
262
+ : null;
263
+ const array = singularType === "array" && schema.items
264
+ ? { items: schema.items }
265
+ : null;
266
+ const oneOf = describeOneOf(schema);
267
+ return { isUnion, singularType, types, enumValues, object, array, oneOf };
268
+ }
269
+ //# sourceMappingURL=generated-schema-descriptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generated-schema-descriptor.js","sourceRoot":"","sources":["../../../../src/lib/workflow-codegen/generated-schema-descriptor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * `workflows codegen` orchestrator (issue #1442).
3
+ *
4
+ * Reads synced workflow TOMLs (`.primitive/sync/<env>/<appId>/workflows/*.toml`)
5
+ * and emits ONE generated file per workflow —
6
+ * `workflows/generated/<key>.generated.ts` — each containing the workflow's
7
+ * `<Key>Input`/`<Key>Output` types plus a typed `<key>(client)` invoker factory
8
+ * returning `{ runSync?, start, getStatus }`. This mirrors `databases codegen`'s per-type
9
+ * `<Type>.generated.ts` layout (#1441's `<type>Ops`): per-file artifacts keep
10
+ * team merges conflict-free and let a `[workflow-key]` filter regenerate exactly
11
+ * one file.
12
+ *
13
+ * Design decisions (see the plan of record on #1442, post-pivot):
14
+ * - Schemas are interpreted through the SHARED descriptor
15
+ * (`generated-schema-descriptor.ts`, a vendored copy of the server's
16
+ * `schema-validation` descriptor) so the generated types match runtime
17
+ * validation exactly. A malformed schema throws (fail-and-exit).
18
+ * - `.runSync` is emitted only for `syncCallable: true` workflows (the server
19
+ * rejects run-sync otherwise); `.start` and `.getStatus` for every
20
+ * non-reserved workflow (the typed async path, issue #1512 — async-only
21
+ * workflows are exactly the ones that need a typed `getStatus`). No
22
+ * `.terminate` member is emitted (the factory stays a start/status helper;
23
+ * typed termination is available via the client's explicit `terminate<O>`).
24
+ * - `input` is a REQUIRED option iff the schema rejects `{}` (the client's
25
+ * `input ?? {}` fallback would fail validation); otherwise `input?`.
26
+ * - The runtime call always passes the ORIGINAL key string; only identifiers
27
+ * are sanitized. `workflowKey` is set AFTER spreading `opts`, so a caller
28
+ * cannot override it.
29
+ * - Disk lifecycle (write / `--check` / suffix-based cleanup) delegates to the
30
+ * shared `writeOrCheckGeneratedFiles`, exactly like `databases codegen`.
31
+ */
32
+ import { type WriteOrCheckResult } from "../codegen-shared/generatedFiles.js";
33
+ /** Suffix identifying a generated file (shared with `databases codegen`). */
34
+ export declare const GENERATED_FILE_SUFFIX = ".generated.ts";
35
+ export interface WorkflowCodegenInput {
36
+ /** Source `.toml` filename stem (fallback key when `[workflow].key` is absent). */
37
+ fileStem: string;
38
+ /** Path to the source `workflows/<key>.toml` file. */
39
+ tomlPath: string;
40
+ /** Raw TOML content (already read from disk). */
41
+ tomlContent: string;
42
+ }
43
+ export interface GenerateWorkflowTypesOptions {
44
+ inputs: WorkflowCodegenInput[];
45
+ /** Directory where the `<key>.generated.ts` files are written. */
46
+ outputDir: string;
47
+ /** `--check`: compare against disk, do not write. */
48
+ check?: boolean;
49
+ /**
50
+ * Set when the run was filtered to a single workflow key (the
51
+ * `primitive workflows codegen <key>` argument). The `inputs` set is then
52
+ * PARTIAL — it does not represent the full set of owned generated files — so
53
+ * stale-output cleanup (and `--check` stale detection) is scoped to the
54
+ * filtered workflow's own file and must NOT touch / flag sibling workflows'
55
+ * `*.generated.ts` files. The unfiltered "generate all" run leaves this unset
56
+ * and keeps full orphan cleanup. Mirrors `databases codegen`'s `singleType`.
57
+ */
58
+ singleWorkflow?: boolean;
59
+ }
60
+ /**
61
+ * Render the full `<key>.generated.ts` content for a single workflow TOML input.
62
+ * Returns null for a reserved (`__internal.*`) workflow. Pure — exported so
63
+ * tests can assert on the string directly.
64
+ */
65
+ export declare function renderWorkflowFile(input: WorkflowCodegenInput): {
66
+ key: string;
67
+ content: string;
68
+ } | null;
69
+ /**
70
+ * Run workflow codegen end-to-end. One `<key>.generated.ts` per workflow;
71
+ * delegates the disk lifecycle to the shared writer/checker, exactly like
72
+ * `databases codegen`.
73
+ */
74
+ export declare function generateWorkflowTypes(options: GenerateWorkflowTypesOptions): Promise<WriteOrCheckResult>;
@@ -0,0 +1,215 @@
1
+ /**
2
+ * `workflows codegen` orchestrator (issue #1442).
3
+ *
4
+ * Reads synced workflow TOMLs (`.primitive/sync/<env>/<appId>/workflows/*.toml`)
5
+ * and emits ONE generated file per workflow —
6
+ * `workflows/generated/<key>.generated.ts` — each containing the workflow's
7
+ * `<Key>Input`/`<Key>Output` types plus a typed `<key>(client)` invoker factory
8
+ * returning `{ runSync?, start, getStatus }`. This mirrors `databases codegen`'s per-type
9
+ * `<Type>.generated.ts` layout (#1441's `<type>Ops`): per-file artifacts keep
10
+ * team merges conflict-free and let a `[workflow-key]` filter regenerate exactly
11
+ * one file.
12
+ *
13
+ * Design decisions (see the plan of record on #1442, post-pivot):
14
+ * - Schemas are interpreted through the SHARED descriptor
15
+ * (`generated-schema-descriptor.ts`, a vendored copy of the server's
16
+ * `schema-validation` descriptor) so the generated types match runtime
17
+ * validation exactly. A malformed schema throws (fail-and-exit).
18
+ * - `.runSync` is emitted only for `syncCallable: true` workflows (the server
19
+ * rejects run-sync otherwise); `.start` and `.getStatus` for every
20
+ * non-reserved workflow (the typed async path, issue #1512 — async-only
21
+ * workflows are exactly the ones that need a typed `getStatus`). No
22
+ * `.terminate` member is emitted (the factory stays a start/status helper;
23
+ * typed termination is available via the client's explicit `terminate<O>`).
24
+ * - `input` is a REQUIRED option iff the schema rejects `{}` (the client's
25
+ * `input ?? {}` fallback would fail validation); otherwise `input?`.
26
+ * - The runtime call always passes the ORIGINAL key string; only identifiers
27
+ * are sanitized. `workflowKey` is set AFTER spreading `opts`, so a caller
28
+ * cannot override it.
29
+ * - Disk lifecycle (write / `--check` / suffix-based cleanup) delegates to the
30
+ * shared `writeOrCheckGeneratedFiles`, exactly like `databases codegen`.
31
+ */
32
+ import * as path from "path";
33
+ import { parseConfigToml } from "../config-toml.js";
34
+ import { safeJsonParse } from "../workflow-payload.js";
35
+ import { writeOrCheckGeneratedFiles, } from "../codegen-shared/generatedFiles.js";
36
+ import { fingerprintToml } from "../db-codegen/dbFingerprint.js";
37
+ import { schemaToTsType, schemaRejectsEmptyObject } from "./schemaToTs.js";
38
+ import { describeSchema } from "./generated-schema-descriptor.js";
39
+ import { workflowInputTypeName, workflowOutputTypeName, workflowFactoryName, } from "./naming.js";
40
+ /** Prefix marking a platform-owned workflow key (mirrors the server's
41
+ * `INTERNAL_WORKFLOW_KEY_PREFIX`; inlined because the CLI cannot import from
42
+ * `src/`). Such workflows are never client-invocable and are skipped. */
43
+ const INTERNAL_WORKFLOW_KEY_PREFIX = "__internal.";
44
+ /** Suffix identifying a generated file (shared with `databases codegen`). */
45
+ export const GENERATED_FILE_SUFFIX = ".generated.ts";
46
+ /** The client package the generated file imports its types from. */
47
+ const CLIENT_PACKAGE = "js-bao-wss-client";
48
+ /** True for a platform-owned workflow key. */
49
+ function isReservedKey(key) {
50
+ return (typeof key === "string" &&
51
+ key.trim().toLowerCase().startsWith(INTERNAL_WORKFLOW_KEY_PREFIX));
52
+ }
53
+ /**
54
+ * Render a top-level `<Name>Input`/`<Name>Output` declaration. An absent schema
55
+ * → `unknown`. A plain object type → an `interface`; anything else → a `type`
56
+ * alias.
57
+ *
58
+ * A discriminated-union (`oneOf`) output renders as `{…} | {…}`, which begins
59
+ * with `{` too — but it must be a `type` alias, not `interface Foo {…} | {…}`
60
+ * (invalid TS). Decide via the shared descriptor (`describeSchema(...).oneOf`),
61
+ * not the `startsWith("{")` heuristic (#1511).
62
+ */
63
+ function renderTypeDecl(name, schema) {
64
+ if (schema === undefined) {
65
+ return `export type ${name} = unknown;`;
66
+ }
67
+ const expr = schemaToTsType(schema, 0);
68
+ if (expr.startsWith("{") && !describeSchema(schema).oneOf) {
69
+ return `export interface ${name} ${expr}`;
70
+ }
71
+ return `export type ${name} = ${expr};`;
72
+ }
73
+ /**
74
+ * Parse a single workflow TOML into the data the emitter needs. Throws on
75
+ * malformed schema JSON (fail-and-exit) — the honest `unknown` fallback is for
76
+ * valid-but-untypeable schemas only. Returns null for a reserved workflow.
77
+ */
78
+ function parseWorkflow(input) {
79
+ // #1464 removed `@iarna/toml`; #1446 makes `sync pull` emit schemas as native
80
+ // TOML tables (incl. mixed-type enums like `enum = ["ok", 1]`, TOML 1.0). The
81
+ // `parseConfigToml` facade parses both. `safeJsonParse` still owns the
82
+ // string-vs-inline-table schema handling.
83
+ const data = parseConfigToml(input.tomlContent);
84
+ const workflow = data?.workflow ?? {};
85
+ const key = typeof workflow.key === "string" && workflow.key.length > 0
86
+ ? workflow.key
87
+ : input.fileStem;
88
+ if (isReservedKey(key))
89
+ return null;
90
+ // safeJsonParse throws on invalid JSON in a schema string — let it bubble.
91
+ const inputSchema = safeJsonParse(workflow.inputSchema);
92
+ const outputSchema = safeJsonParse(workflow.outputSchema);
93
+ const inputTypeName = workflowInputTypeName(key);
94
+ const outputTypeName = workflowOutputTypeName(key);
95
+ return {
96
+ key,
97
+ syncCallable: workflow.syncCallable === true,
98
+ inputTypeName,
99
+ outputTypeName,
100
+ factoryName: workflowFactoryName(key),
101
+ inputDecl: renderTypeDecl(inputTypeName, inputSchema),
102
+ outputDecl: renderTypeDecl(outputTypeName, outputSchema),
103
+ // `input` is required iff the schema rejects the client's `{}` fallback.
104
+ // A schema-less workflow (`undefined`) accepts anything → optional.
105
+ inputRequired: inputSchema !== undefined && schemaRejectsEmptyObject(inputSchema),
106
+ };
107
+ }
108
+ /** Render the typed invoker factory for one workflow. */
109
+ function renderFactory(wf) {
110
+ const keyLiteral = JSON.stringify(wf.key);
111
+ const inputMember = wf.inputRequired
112
+ ? `input: ${wf.inputTypeName}`
113
+ : `input?: ${wf.inputTypeName}`;
114
+ const lines = [
115
+ `export function ${wf.factoryName}(client: JsBaoClient) {`,
116
+ ` return {`,
117
+ ];
118
+ // Spread `opts` FIRST, then set `workflowKey` LAST, so the factory's intended
119
+ // key always wins. `Omit<..., "workflowKey">` only rejects an excess
120
+ // `workflowKey` on object literals; a caller passing an options *variable*
121
+ // carrying an extra `workflowKey` (or any untyped JS caller) would otherwise
122
+ // override the key and invoke the wrong workflow if the spread came last.
123
+ if (wf.syncCallable) {
124
+ lines.push(` runSync: (\n` +
125
+ ` opts: { ${inputMember} } & Omit<RunSyncWorkflowOptions, "workflowKey" | "input">\n` +
126
+ ` ) =>\n` +
127
+ ` client.workflows.runSync<${wf.inputTypeName}, ${wf.outputTypeName}>({\n` +
128
+ ` ...opts,\n` +
129
+ ` workflowKey: ${keyLiteral},\n` +
130
+ ` }),`);
131
+ }
132
+ lines.push(` start: (\n` +
133
+ ` opts: { ${inputMember} } & Omit<StartWorkflowOptions, "workflowKey" | "input">\n` +
134
+ ` ) =>\n` +
135
+ ` client.workflows.start<${wf.inputTypeName}>({\n` +
136
+ ` ...opts,\n` +
137
+ ` workflowKey: ${keyLiteral},\n` +
138
+ ` }),`);
139
+ // Typed status fetch (#1512), emitted for EVERY non-reserved workflow — not
140
+ // gated on `syncCallable`, since async-only workflows are exactly the ones
141
+ // that need a typed `status.output`. `output` is bound to `<Key>Output` from
142
+ // the workflow's `outputSchema` (schema-less → `unknown`, same as the sync
143
+ // path). `runKey` stays required (unlike start/runSync, which auto-generate
144
+ // it — you cannot fetch a run's status without knowing which run). Same
145
+ // spread-first / key-last ordering so an untyped caller cannot override the
146
+ // key and read the wrong workflow's status.
147
+ lines.push(` getStatus: (opts: Omit<GetWorkflowStatusOptions, "workflowKey">) =>\n` +
148
+ ` client.workflows.getStatus<${wf.outputTypeName}>({\n` +
149
+ ` ...opts,\n` +
150
+ ` workflowKey: ${keyLiteral},\n` +
151
+ ` }),`);
152
+ lines.push(` };`, `}`);
153
+ return lines.join("\n");
154
+ }
155
+ /**
156
+ * Render the full `<key>.generated.ts` content for a single workflow TOML input.
157
+ * Returns null for a reserved (`__internal.*`) workflow. Pure — exported so
158
+ * tests can assert on the string directly.
159
+ */
160
+ export function renderWorkflowFile(input) {
161
+ const wf = parseWorkflow(input);
162
+ if (!wf)
163
+ return null;
164
+ const fingerprint = fingerprintToml(input.tomlContent);
165
+ // Only import the option types actually referenced, so the generated file
166
+ // compiles under a consumer's `noUnusedLocals`. `GetWorkflowStatusOptions` is
167
+ // always referenced now — every factory emits a `getStatus` member (#1512).
168
+ const imports = [
169
+ "GetWorkflowStatusOptions",
170
+ "JsBaoClient",
171
+ "StartWorkflowOptions",
172
+ ];
173
+ if (wf.syncCallable)
174
+ imports.push("RunSyncWorkflowOptions");
175
+ imports.sort();
176
+ const blocks = [];
177
+ blocks.push([
178
+ `// AUTO-GENERATED FROM workflows/${wf.key}.toml — DO NOT EDIT.`,
179
+ "// Run `primitive workflows codegen` to regenerate.",
180
+ `// fingerprint: ${fingerprint}`,
181
+ ].join("\n"));
182
+ blocks.push(`import type {\n${imports
183
+ .map((i) => ` ${i},`)
184
+ .join("\n")}\n} from "${CLIENT_PACKAGE}";`);
185
+ blocks.push(wf.inputDecl);
186
+ blocks.push(wf.outputDecl);
187
+ blocks.push(renderFactory(wf));
188
+ return { key: wf.key, content: blocks.join("\n\n") + "\n" };
189
+ }
190
+ /**
191
+ * Run workflow codegen end-to-end. One `<key>.generated.ts` per workflow;
192
+ * delegates the disk lifecycle to the shared writer/checker, exactly like
193
+ * `databases codegen`.
194
+ */
195
+ export async function generateWorkflowTypes(options) {
196
+ const outAbs = path.resolve(options.outputDir);
197
+ const filesToWrite = new Map();
198
+ for (const input of options.inputs) {
199
+ const rendered = renderWorkflowFile(input);
200
+ if (!rendered)
201
+ continue; // reserved workflow — no file
202
+ const filePath = path.join(outAbs, `${rendered.key}${GENERATED_FILE_SUFFIX}`);
203
+ filesToWrite.set(filePath, rendered.content);
204
+ }
205
+ return await writeOrCheckGeneratedFiles({
206
+ outputDir: outAbs,
207
+ filesToWrite,
208
+ check: options.check,
209
+ // A single-workflow filter run owns only a subset of the generated files,
210
+ // so orphan cleanup / stale detection must be scoped to the filtered file.
211
+ fullOwnership: options.singleWorkflow !== true,
212
+ generatedSuffix: GENERATED_FILE_SUFFIX,
213
+ });
214
+ }
215
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../src/lib/workflow-codegen/generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Identifier-naming helpers for `workflows codegen` (issue #1442).
3
+ *
4
+ * Workflow keys resolve case-insensitively server-side and may contain
5
+ * characters that aren't valid TS identifiers (`.`, `-`). Only the emitted
6
+ * identifiers are sanitized — the runtime call always passes the ORIGINAL key
7
+ * string.
8
+ *
9
+ * Type names: `pascalCase(key) + "Input" | "Output"` (reuses `pascalCase` from
10
+ * the database codegen so the two commands share one PascalCase rule).
11
+ * Factory property: a camelCase form of the key.
12
+ */
13
+ /**
14
+ * `create-checkout-session` / `createCheckoutSession` → `CreateCheckoutSession`.
15
+ * A digit-leading key (`123-job` → `_123Job`) is prefixed with `_` so the
16
+ * emitted type name is a valid TS identifier.
17
+ */
18
+ export declare function workflowTypeBaseName(key: string): string;
19
+ /** PascalCase base + `Input` (e.g. `CreateCheckoutSessionInput`). */
20
+ export declare function workflowInputTypeName(key: string): string;
21
+ /** PascalCase base + `Output` (e.g. `CreateCheckoutSessionOutput`). */
22
+ export declare function workflowOutputTypeName(key: string): string;
23
+ /**
24
+ * camelCase factory function name for a workflow key: PascalCase, then lowercase
25
+ * the first character (`create-checkout-session` → `createCheckoutSession`,
26
+ * `refresh-sheet` → `refreshSheet`). Used as the top-level exported factory
27
+ * function name in the per-workflow generated file, so it must be a legal
28
+ * function identifier: a digit-leading key (`123-job` → `_123Job`) is
29
+ * underscore-prefixed, and a key that lands on a JS reserved word (`delete`,
30
+ * `new`, `import`) is underscore-suffixed (`delete_`). Only the emitted
31
+ * identifier changes; the runtime call still passes the ORIGINAL key string.
32
+ */
33
+ export declare function workflowFactoryName(key: string): string;