primitive-admin 1.0.54 → 1.0.56
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/assets/skill/skills/primitive-platform/SKILL.md +230 -2
- package/dist/bin/primitive.js +3 -1
- package/dist/bin/primitive.js.map +1 -1
- package/dist/src/commands/apps.js +54 -2
- package/dist/src/commands/apps.js.map +1 -1
- package/dist/src/commands/database-types.js +4 -4
- package/dist/src/commands/database-types.js.map +1 -1
- package/dist/src/commands/databases.js +35 -14
- package/dist/src/commands/databases.js.map +1 -1
- package/dist/src/commands/documents.js +77 -0
- package/dist/src/commands/documents.js.map +1 -1
- package/dist/src/commands/guides.d.ts +15 -12
- package/dist/src/commands/guides.js +22 -15
- package/dist/src/commands/guides.js.map +1 -1
- package/dist/src/commands/metadata.js +48 -3
- package/dist/src/commands/metadata.js.map +1 -1
- package/dist/src/commands/scripts.d.ts +18 -0
- package/dist/src/commands/scripts.js +59 -5
- package/dist/src/commands/scripts.js.map +1 -1
- package/dist/src/commands/settings.d.ts +15 -0
- package/dist/src/commands/settings.js +102 -0
- package/dist/src/commands/settings.js.map +1 -0
- package/dist/src/commands/sync-app-settings.d.ts +115 -0
- package/dist/src/commands/sync-app-settings.js +379 -0
- package/dist/src/commands/sync-app-settings.js.map +1 -0
- package/dist/src/commands/sync.d.ts +134 -19
- package/dist/src/commands/sync.js +1949 -600
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/commands/workflows.js +54 -15
- package/dist/src/commands/workflows.js.map +1 -1
- package/dist/src/lib/api-client.d.ts +29 -1
- package/dist/src/lib/api-client.js +31 -2
- package/dist/src/lib/api-client.js.map +1 -1
- package/dist/src/lib/app-settings-descriptor.d.ts +108 -0
- package/dist/src/lib/app-settings-descriptor.js +254 -0
- package/dist/src/lib/app-settings-descriptor.js.map +1 -0
- package/dist/src/lib/codegen-shared/generatedFiles.d.ts +36 -0
- package/dist/src/lib/codegen-shared/generatedFiles.js +67 -10
- package/dist/src/lib/codegen-shared/generatedFiles.js.map +1 -1
- package/dist/src/lib/codegen-shared/prettierStable.d.ts +262 -0
- package/dist/src/lib/codegen-shared/prettierStable.js +610 -0
- package/dist/src/lib/codegen-shared/prettierStable.js.map +1 -0
- package/dist/src/lib/db-codegen/dbGenerator.d.ts +11 -83
- package/dist/src/lib/db-codegen/dbGenerator.js +96 -556
- package/dist/src/lib/db-codegen/dbGenerator.js.map +1 -1
- package/dist/src/lib/db-codegen/dbNaming.d.ts +20 -7
- package/dist/src/lib/db-codegen/dbNaming.js +31 -13
- package/dist/src/lib/db-codegen/dbNaming.js.map +1 -1
- package/dist/src/lib/db-codegen/dbTemplates.d.ts +70 -4
- package/dist/src/lib/db-codegen/dbTemplates.js +244 -70
- package/dist/src/lib/db-codegen/dbTemplates.js.map +1 -1
- package/dist/src/lib/db-codegen/dbTsTypes.d.ts +13 -22
- package/dist/src/lib/db-codegen/dbTsTypes.js +33 -28
- package/dist/src/lib/db-codegen/dbTsTypes.js.map +1 -1
- package/dist/src/lib/db-codegen/dbTypeIR.d.ts +146 -0
- package/dist/src/lib/db-codegen/dbTypeIR.js +517 -0
- package/dist/src/lib/db-codegen/dbTypeIR.js.map +1 -0
- package/dist/src/lib/db-codegen/generated-operation-def-descriptor.d.ts +112 -0
- package/dist/src/lib/db-codegen/generated-operation-def-descriptor.js +211 -0
- package/dist/src/lib/db-codegen/generated-operation-def-descriptor.js.map +1 -0
- package/dist/src/lib/generated-allowlist.js +7 -0
- package/dist/src/lib/generated-allowlist.js.map +1 -1
- package/dist/src/lib/platform-owned.d.ts +37 -0
- package/dist/src/lib/platform-owned.js +46 -0
- package/dist/src/lib/platform-owned.js.map +1 -0
- package/dist/src/lib/swift-codegen/dbGenerator.d.ts +100 -0
- package/dist/src/lib/swift-codegen/dbGenerator.js +682 -0
- package/dist/src/lib/swift-codegen/dbGenerator.js.map +1 -0
- package/dist/src/lib/swift-codegen/dbSwiftTypes.d.ts +42 -0
- package/dist/src/lib/swift-codegen/dbSwiftTypes.js +100 -0
- package/dist/src/lib/swift-codegen/dbSwiftTypes.js.map +1 -0
- package/dist/src/lib/swift-codegen/generator.d.ts +85 -0
- package/dist/src/lib/swift-codegen/generator.js +266 -0
- package/dist/src/lib/swift-codegen/generator.js.map +1 -0
- package/dist/src/lib/swift-codegen/schemaToSwift.d.ts +72 -0
- package/dist/src/lib/swift-codegen/schemaToSwift.js +644 -0
- package/dist/src/lib/swift-codegen/schemaToSwift.js.map +1 -0
- package/dist/src/lib/swift-codegen/siblingSymbols.d.ts +90 -0
- package/dist/src/lib/swift-codegen/siblingSymbols.js +152 -0
- package/dist/src/lib/swift-codegen/siblingSymbols.js.map +1 -0
- package/dist/src/lib/swift-codegen/swiftNaming.d.ts +85 -0
- package/dist/src/lib/swift-codegen/swiftNaming.js +198 -0
- package/dist/src/lib/swift-codegen/swiftNaming.js.map +1 -0
- package/dist/src/lib/sync-resource-types.d.ts +437 -0
- package/dist/src/lib/sync-resource-types.js +781 -0
- package/dist/src/lib/sync-resource-types.js.map +1 -0
- package/dist/src/lib/template.d.ts +1 -1
- package/dist/src/lib/template.js +6 -3
- package/dist/src/lib/template.js.map +1 -1
- package/dist/src/lib/toml-metadata-config.js +18 -0
- package/dist/src/lib/toml-metadata-config.js.map +1 -1
- package/dist/src/lib/workflow-apply.js +12 -2
- package/dist/src/lib/workflow-apply.js.map +1 -1
- package/dist/src/lib/workflow-codegen/generator.d.ts +27 -5
- package/dist/src/lib/workflow-codegen/generator.js +214 -68
- package/dist/src/lib/workflow-codegen/generator.js.map +1 -1
- package/dist/src/lib/workflow-codegen/invokerIR.d.ts +83 -0
- package/dist/src/lib/workflow-codegen/invokerIR.js +71 -0
- package/dist/src/lib/workflow-codegen/invokerIR.js.map +1 -0
- package/dist/src/lib/workflow-codegen/schemaToTs.d.ts +17 -1
- package/dist/src/lib/workflow-codegen/schemaToTs.js +59 -38
- package/dist/src/lib/workflow-codegen/schemaToTs.js.map +1 -1
- package/dist/src/lib/workflow-payload.d.ts +19 -0
- package/dist/src/lib/workflow-payload.js +21 -0
- package/dist/src/lib/workflow-payload.js.map +1 -1
- package/dist/src/lib/workflow-toml-validator.d.ts +30 -0
- package/dist/src/lib/workflow-toml-validator.js +206 -0
- package/dist/src/lib/workflow-toml-validator.js.map +1 -1
- package/dist/src/types/index.d.ts +1 -0
- package/package.json +5 -2
|
@@ -16,11 +16,24 @@
|
|
|
16
16
|
* `schema-validation` descriptor) so the generated types match runtime
|
|
17
17
|
* validation exactly. A malformed schema throws (fail-and-exit).
|
|
18
18
|
* - `.runSync` is emitted only for `syncCallable: true` workflows (the server
|
|
19
|
-
* rejects run-sync otherwise); `.start
|
|
20
|
-
* non-reserved workflow (the typed async path, issue #1512 —
|
|
21
|
-
* workflows are exactly the ones that need a typed `getStatus`
|
|
22
|
-
* `.terminate`
|
|
23
|
-
*
|
|
19
|
+
* rejects run-sync otherwise); `.start`, `.getStatus`, and `.terminate` for
|
|
20
|
+
* every non-reserved workflow (the typed async path, issue #1512 —
|
|
21
|
+
* async-only workflows are exactly the ones that need a typed `getStatus` /
|
|
22
|
+
* `terminate`). `.terminate` binds `<Key>Output` (a terminated run can carry
|
|
23
|
+
* partial output); issue #1543 added the member, reversing #1512's
|
|
24
|
+
* start/status-only decision.
|
|
25
|
+
* - `.define` is emitted only for an apply-mode workflow
|
|
26
|
+
* (`requiresClientApply !== false`, the server's default). It binds
|
|
27
|
+
* `<Key>Output` so the `onApply` handler's `output` is the workflow's real
|
|
28
|
+
* output type rather than `any` (issue #1543, on top of #1542's
|
|
29
|
+
* `define<O>` / `WorkflowDefineOptions<O>` generics). `getPendingApplies`
|
|
30
|
+
* gets no member — #1542 made it a concrete `PendingApply[]` with no output
|
|
31
|
+
* to bind, and it is scoped to a document rather than a workflow.
|
|
32
|
+
* - `.cronTriggers.{create,update}` bind `<Key>Input` to the trigger's
|
|
33
|
+
* `rootInput` and pin `workflowKey`, so a cron helper can't be redirected at
|
|
34
|
+
* another workflow (issue #1543). `rootInput` is `Partial<<Key>Input>` for
|
|
35
|
+
* an object-shaped input schema (an `inputMapping` may supply the rest) and
|
|
36
|
+
* the full `<Key>Input` otherwise.
|
|
24
37
|
* - `input` is a REQUIRED option iff the schema rejects `{}` (the client's
|
|
25
38
|
* `input ?? {}` fallback would fail validation); otherwise `input?`.
|
|
26
39
|
* - The runtime call always passes the ORIGINAL key string; only identifiers
|
|
@@ -28,28 +41,28 @@
|
|
|
28
41
|
* cannot override it.
|
|
29
42
|
* - Disk lifecycle (write / `--check` / suffix-based cleanup) delegates to the
|
|
30
43
|
* shared `writeOrCheckGeneratedFiles`, exactly like `databases codegen`.
|
|
44
|
+
*
|
|
45
|
+
* FORMATTING CONTRACT (#1565): the emitted TypeScript must be a fixed point of
|
|
46
|
+
* Prettier's DEFAULT config — `prettier --write` over a generated file must
|
|
47
|
+
* leave it byte-for-byte unchanged, because `--check` byte-compares. There is
|
|
48
|
+
* no Prettier dependency and no automated round-trip test to catch a
|
|
49
|
+
* regression, so any edit here that changes line shapes must be verified by
|
|
50
|
+
* hand (regenerate a representative output, run Prettier over it, confirm no
|
|
51
|
+
* diff). Wrap long constructs through `codegen-shared/prettierStable.ts` rather
|
|
52
|
+
* than hand-joining strings — see that file's header for the full contract.
|
|
31
53
|
*/
|
|
32
54
|
import * as path from "path";
|
|
33
|
-
import { parseConfigToml } from "../config-toml.js";
|
|
34
|
-
import { safeJsonParse } from "../workflow-payload.js";
|
|
35
55
|
import { writeOrCheckGeneratedFiles, } from "../codegen-shared/generatedFiles.js";
|
|
36
56
|
import { fingerprintToml } from "../db-codegen/dbFingerprint.js";
|
|
37
|
-
import {
|
|
57
|
+
import { atom, generic, indent, intersection, objectType, printType, renderArrowCall, renderArrowProperty, renderParenList, renderTypeAlias, tsStringLiteral, union, } from "../codegen-shared/prettierStable.js";
|
|
58
|
+
import { schemaToTypeNode } from "./schemaToTs.js";
|
|
38
59
|
import { describeSchema } from "./generated-schema-descriptor.js";
|
|
60
|
+
import { describeWorkflowInvoker } from "./invokerIR.js";
|
|
39
61
|
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
62
|
/** Suffix identifying a generated file (shared with `databases codegen`). */
|
|
45
63
|
export const GENERATED_FILE_SUFFIX = ".generated.ts";
|
|
46
64
|
/** The client package the generated file imports its types from. */
|
|
47
65
|
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
66
|
/**
|
|
54
67
|
* Render a top-level `<Name>Input`/`<Name>Output` declaration. An absent schema
|
|
55
68
|
* → `unknown`. A plain object type → an `interface`; anything else → a `type`
|
|
@@ -62,80 +75,108 @@ function isReservedKey(key) {
|
|
|
62
75
|
*/
|
|
63
76
|
function renderTypeDecl(name, schema) {
|
|
64
77
|
if (schema === undefined) {
|
|
65
|
-
|
|
78
|
+
// Through `renderTypeAlias`, not hand-joined: a long enough workflow key
|
|
79
|
+
// pushes `export type <Key>Output = unknown;` past the print width, and
|
|
80
|
+
// Prettier then moves the `unknown` below the `=` (#1565).
|
|
81
|
+
return renderTypeAlias(name, atom("unknown"));
|
|
66
82
|
}
|
|
67
|
-
const
|
|
68
|
-
if (
|
|
69
|
-
return `export interface ${name} ${
|
|
83
|
+
const node = schemaToTypeNode(schema);
|
|
84
|
+
if (node.kind === "block" && !describeSchema(schema).oneOf) {
|
|
85
|
+
return `export interface ${name} ${printType(node, 0, 0)}`;
|
|
70
86
|
}
|
|
71
|
-
return
|
|
87
|
+
return renderTypeAlias(name, node);
|
|
72
88
|
}
|
|
73
89
|
/**
|
|
74
90
|
* Parse a single workflow TOML into the data the emitter needs. Throws on
|
|
75
91
|
* malformed schema JSON (fail-and-exit) — the honest `unknown` fallback is for
|
|
76
92
|
* valid-but-untypeable schemas only. Returns null for a reserved workflow.
|
|
93
|
+
*
|
|
94
|
+
* The operation metadata (key, `syncCallable`, required-vs-optional `input`,
|
|
95
|
+
* parsed schemas) comes from the SHARED `describeWorkflowInvoker` IR so the TS
|
|
96
|
+
* and Swift invokers can never disagree (#1547 binding item 5). Only the
|
|
97
|
+
* TS-specific naming + type-declaration rendering happens here.
|
|
77
98
|
*/
|
|
78
99
|
function parseWorkflow(input) {
|
|
79
100
|
// #1464 removed `@iarna/toml`; #1446 makes `sync pull` emit schemas as native
|
|
80
101
|
// TOML tables (incl. mixed-type enums like `enum = ["ok", 1]`, TOML 1.0). The
|
|
81
|
-
// `parseConfigToml`
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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);
|
|
102
|
+
// shared IR uses `parseConfigToml` + `safeJsonParse` under the hood.
|
|
103
|
+
const ir = describeWorkflowInvoker({
|
|
104
|
+
fileStem: input.fileStem,
|
|
105
|
+
tomlContent: input.tomlContent,
|
|
106
|
+
});
|
|
107
|
+
if (!ir)
|
|
108
|
+
return null; // reserved workflow
|
|
109
|
+
const inputTypeName = workflowInputTypeName(ir.key);
|
|
110
|
+
const outputTypeName = workflowOutputTypeName(ir.key);
|
|
95
111
|
return {
|
|
96
|
-
key,
|
|
97
|
-
syncCallable:
|
|
112
|
+
key: ir.key,
|
|
113
|
+
syncCallable: ir.syncCallable,
|
|
98
114
|
inputTypeName,
|
|
99
115
|
outputTypeName,
|
|
100
|
-
factoryName: workflowFactoryName(key),
|
|
101
|
-
inputDecl: renderTypeDecl(inputTypeName, inputSchema),
|
|
102
|
-
outputDecl: renderTypeDecl(outputTypeName, outputSchema),
|
|
103
|
-
|
|
104
|
-
//
|
|
105
|
-
|
|
116
|
+
factoryName: workflowFactoryName(ir.key),
|
|
117
|
+
inputDecl: renderTypeDecl(inputTypeName, ir.inputSchema),
|
|
118
|
+
outputDecl: renderTypeDecl(outputTypeName, ir.outputSchema),
|
|
119
|
+
inputRequired: ir.inputRequired,
|
|
120
|
+
// Object-shaped only when the schema declares exactly `type: "object"` —
|
|
121
|
+
// the one case where `Partial<<Key>Input>` is a sound cron `rootInput`
|
|
122
|
+
// type. Schema-less / union / scalar / array → not object-shaped.
|
|
123
|
+
inputIsObjectShaped: ir.inputSchema !== undefined &&
|
|
124
|
+
describeSchema(ir.inputSchema).singularType === "object",
|
|
125
|
+
requiresClientApply: ir.requiresClientApply,
|
|
106
126
|
};
|
|
107
127
|
}
|
|
108
|
-
/**
|
|
128
|
+
/**
|
|
129
|
+
* Render the typed invoker factory for one workflow.
|
|
130
|
+
*
|
|
131
|
+
* Every line shape here is emitted the way Prettier's default config would
|
|
132
|
+
* print it (#1565) — see `codegen-shared/prettierStable.ts`. `runSync`/`start`
|
|
133
|
+
* always break their parameter list: the shortest possible
|
|
134
|
+
* `opts: {…} & Omit<…>` parameter is already wider than the 80-column budget,
|
|
135
|
+
* so there is no width decision to make there.
|
|
136
|
+
*/
|
|
109
137
|
function renderFactory(wf) {
|
|
110
|
-
const keyLiteral =
|
|
138
|
+
const keyLiteral = tsStringLiteral(wf.key);
|
|
111
139
|
const inputMember = wf.inputRequired
|
|
112
140
|
? `input: ${wf.inputTypeName}`
|
|
113
141
|
: `input?: ${wf.inputTypeName}`;
|
|
114
142
|
const lines = [
|
|
115
|
-
`export function ${wf.factoryName}
|
|
143
|
+
renderParenList(`export function ${wf.factoryName}`, ["client: JsBaoClient"], " {", 0),
|
|
116
144
|
` return {`,
|
|
117
145
|
];
|
|
146
|
+
// `opts: { input: X } & Omit<<Options>, "workflowKey" | "input">` — the
|
|
147
|
+
// intersection breaks inside the `Omit<...>` when it overflows.
|
|
148
|
+
const optsParam = (optionsTypeName) => {
|
|
149
|
+
const node = intersection([
|
|
150
|
+
objectType([inputMember]),
|
|
151
|
+
generic("Omit", [
|
|
152
|
+
atom(optionsTypeName),
|
|
153
|
+
union([atom(`"workflowKey"`), atom(`"input"`)]),
|
|
154
|
+
]),
|
|
155
|
+
]);
|
|
156
|
+
const head = `${indent(3)}opts: `;
|
|
157
|
+
return `${head}${printType(node, head.length, 3, 1)},`;
|
|
158
|
+
};
|
|
118
159
|
// Spread `opts` FIRST, then set `workflowKey` LAST, so the factory's intended
|
|
119
160
|
// key always wins. `Omit<..., "workflowKey">` only rejects an excess
|
|
120
161
|
// `workflowKey` on object literals; a caller passing an options *variable*
|
|
121
162
|
// carrying an extra `workflowKey` (or any untyped JS caller) would otherwise
|
|
122
163
|
// override the key and invoke the wrong workflow if the spread came last.
|
|
164
|
+
const invocation = (method, typeArgs, optionsTypeName) => renderArrowCall({
|
|
165
|
+
head: [
|
|
166
|
+
`${indent(2)}${method}: (`,
|
|
167
|
+
optsParam(optionsTypeName),
|
|
168
|
+
`${indent(2)}) =>`,
|
|
169
|
+
].join("\n"),
|
|
170
|
+
callee: generic(`client.workflows.${method}`, typeArgs.map(atom)),
|
|
171
|
+
leadingArgs: [],
|
|
172
|
+
objectMembers: ["...opts", { key: "workflowKey", value: keyLiteral }],
|
|
173
|
+
level: 3,
|
|
174
|
+
tail: ",",
|
|
175
|
+
});
|
|
123
176
|
if (wf.syncCallable) {
|
|
124
|
-
lines.push(
|
|
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
|
-
` }),`);
|
|
177
|
+
lines.push(invocation("runSync", [wf.inputTypeName, wf.outputTypeName], "RunSyncWorkflowOptions"));
|
|
131
178
|
}
|
|
132
|
-
lines.push(
|
|
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
|
-
` }),`);
|
|
179
|
+
lines.push(invocation("start", [wf.inputTypeName], "StartWorkflowOptions"));
|
|
139
180
|
// Typed status fetch (#1512), emitted for EVERY non-reserved workflow — not
|
|
140
181
|
// gated on `syncCallable`, since async-only workflows are exactly the ones
|
|
141
182
|
// that need a typed `status.output`. `output` is bound to `<Key>Output` from
|
|
@@ -144,11 +185,107 @@ function renderFactory(wf) {
|
|
|
144
185
|
// it — you cannot fetch a run's status without knowing which run). Same
|
|
145
186
|
// spread-first / key-last ordering so an untyped caller cannot override the
|
|
146
187
|
// key and read the wrong workflow's status.
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
188
|
+
//
|
|
189
|
+
// Its `opts` parameter carries no generated names, so it always fits on one
|
|
190
|
+
// line — unlike start/runSync above.
|
|
191
|
+
lines.push(renderArrowCall({
|
|
192
|
+
head: `${indent(2)}getStatus: (opts: Omit<GetWorkflowStatusOptions, "workflowKey">) =>`,
|
|
193
|
+
callee: generic("client.workflows.getStatus", [atom(wf.outputTypeName)]),
|
|
194
|
+
leadingArgs: [],
|
|
195
|
+
objectMembers: ["...opts", { key: "workflowKey", value: keyLiteral }],
|
|
196
|
+
level: 3,
|
|
197
|
+
tail: ",",
|
|
198
|
+
}));
|
|
199
|
+
// Typed termination (#1543), emitted for EVERY non-reserved workflow — any
|
|
200
|
+
// run can be terminated. `output` is bound to `<Key>Output` (a terminated run
|
|
201
|
+
// can carry partial output), same schema-less → `unknown` rule as getStatus.
|
|
202
|
+
// `runKey` stays required. Same spread-first / key-last ordering so an untyped
|
|
203
|
+
// caller cannot override the key and terminate the wrong workflow's run. This
|
|
204
|
+
// member reverses #1512's start/status-only decision.
|
|
205
|
+
lines.push(renderArrowProperty({
|
|
206
|
+
level: 2,
|
|
207
|
+
key: "terminate",
|
|
208
|
+
params: [`opts: Omit<TerminateWorkflowOptions, "workflowKey">`],
|
|
209
|
+
signatureTail: " =>",
|
|
210
|
+
callee: generic("client.workflows.terminate", [atom(wf.outputTypeName)]),
|
|
211
|
+
leadingArgs: [],
|
|
212
|
+
objectMembers: ["...opts", { key: "workflowKey", value: keyLiteral }],
|
|
213
|
+
tail: ",",
|
|
214
|
+
}));
|
|
215
|
+
// Typed apply handler (#1543 Phase 2), emitted ONLY for an apply-mode
|
|
216
|
+
// workflow (`requiresClientApply !== false` — the same default the server
|
|
217
|
+
// uses to decide a completed run needs a client apply). `WorkflowDefineOptions<O>`
|
|
218
|
+
// and `WorkflowApplyHandler<O>` come from #1542; binding `<Key>Output` here
|
|
219
|
+
// makes the `onApply` callback's `output` the workflow's real output type
|
|
220
|
+
// instead of `any`. The key is passed as a positional argument, so there is
|
|
221
|
+
// no spread a caller could use to override it.
|
|
222
|
+
//
|
|
223
|
+
// No `getPendingApplies` member: #1542 shipped it as a concrete
|
|
224
|
+
// `PendingApply[]` (the server element carries no `output`, so there is no
|
|
225
|
+
// output generic to bind), and the call is scoped to a DOCUMENT rather than
|
|
226
|
+
// a workflow — a per-workflow member would bind nothing and would wrongly
|
|
227
|
+
// suggest the result only covers this workflow.
|
|
228
|
+
if (wf.requiresClientApply) {
|
|
229
|
+
lines.push(renderArrowProperty({
|
|
230
|
+
level: 2,
|
|
231
|
+
key: "define",
|
|
232
|
+
params: [`options: WorkflowDefineOptions<${wf.outputTypeName}>`],
|
|
233
|
+
signatureTail: " =>",
|
|
234
|
+
callee: generic("client.workflows.define", [atom(wf.outputTypeName)]),
|
|
235
|
+
leadingArgs: [keyLiteral, "options"],
|
|
236
|
+
tail: ",",
|
|
237
|
+
}));
|
|
238
|
+
}
|
|
239
|
+
// Typed cron-trigger create/update (#1543), folded INTO the factory (not a
|
|
240
|
+
// separate export). The client's own `rootInput` generic (#1542) is bound to
|
|
241
|
+
// `<Key>Input`: `Partial<...>` for an object-shaped schema (an `inputMapping`
|
|
242
|
+
// may supply the rest), the full type otherwise. Binding the generic rather
|
|
243
|
+
// than restating the field keeps the caller-facing params in step with the
|
|
244
|
+
// client contract — notably `update` accepts `rootInput: null` to clear a
|
|
245
|
+
// stored root input, while `create` does not (the server rejects a null there
|
|
246
|
+
// with a 400). `workflowKey` is Omit-ted from the caller-facing params and
|
|
247
|
+
// pinned LAST so a caller can't redirect the trigger at another workflow.
|
|
248
|
+
// Nothing is spread after `workflowKey` — `rootInput` rides in via `...params`
|
|
249
|
+
// — preserving the key-last convention.
|
|
250
|
+
// `rootInput` is `Partial<<Key>Input>` for an object-shaped schema (an
|
|
251
|
+
// `inputMapping` may supply the rest) and the full `<Key>Input` otherwise.
|
|
252
|
+
// Built as a `TypeNode` so `printType` can break the nested type-argument
|
|
253
|
+
// lists Prettier opens up at long key lengths (e.g.
|
|
254
|
+
// `Omit<CreateCronTriggerParams<Partial<...>>, "workflowKey">`).
|
|
255
|
+
const rootInputNode = wf.inputIsObjectShaped
|
|
256
|
+
? generic("Partial", [atom(wf.inputTypeName)])
|
|
257
|
+
: atom(wf.inputTypeName);
|
|
258
|
+
const cronParam = (paramsGeneric) => ({
|
|
259
|
+
name: "params",
|
|
260
|
+
type: generic("Omit", [
|
|
261
|
+
generic(paramsGeneric, [rootInputNode]),
|
|
262
|
+
atom(`"workflowKey"`),
|
|
263
|
+
]),
|
|
264
|
+
});
|
|
265
|
+
lines.push([
|
|
266
|
+
` cronTriggers: {`,
|
|
267
|
+
renderArrowProperty({
|
|
268
|
+
level: 3,
|
|
269
|
+
key: "create",
|
|
270
|
+
params: [cronParam("CreateCronTriggerParams")],
|
|
271
|
+
signatureTail: " =>",
|
|
272
|
+
callee: generic("client.cronTriggers.create", [rootInputNode]),
|
|
273
|
+
leadingArgs: [],
|
|
274
|
+
objectMembers: ["...params", { key: "workflowKey", value: keyLiteral }],
|
|
275
|
+
tail: ",",
|
|
276
|
+
}),
|
|
277
|
+
renderArrowProperty({
|
|
278
|
+
level: 3,
|
|
279
|
+
key: "update",
|
|
280
|
+
params: ["triggerId: string", cronParam("UpdateCronTriggerParams")],
|
|
281
|
+
signatureTail: " =>",
|
|
282
|
+
callee: generic("client.cronTriggers.update", [rootInputNode]),
|
|
283
|
+
leadingArgs: ["triggerId"],
|
|
284
|
+
objectMembers: ["...params", { key: "workflowKey", value: keyLiteral }],
|
|
285
|
+
tail: ",",
|
|
286
|
+
}),
|
|
287
|
+
` },`,
|
|
288
|
+
].join("\n"));
|
|
152
289
|
lines.push(` };`, `}`);
|
|
153
290
|
return lines.join("\n");
|
|
154
291
|
}
|
|
@@ -163,15 +300,24 @@ export function renderWorkflowFile(input) {
|
|
|
163
300
|
return null;
|
|
164
301
|
const fingerprint = fingerprintToml(input.tomlContent);
|
|
165
302
|
// Only import the option types actually referenced, so the generated file
|
|
166
|
-
// compiles under a consumer's `noUnusedLocals`. `GetWorkflowStatusOptions
|
|
167
|
-
//
|
|
303
|
+
// compiles under a consumer's `noUnusedLocals`. `GetWorkflowStatusOptions`,
|
|
304
|
+
// `TerminateWorkflowOptions`, and the two cron-param types are always
|
|
305
|
+
// referenced now — every factory emits `getStatus`, `terminate` (#1512 /
|
|
306
|
+
// #1543), and `cronTriggers.{create,update}` (#1543).
|
|
168
307
|
const imports = [
|
|
308
|
+
"CreateCronTriggerParams",
|
|
169
309
|
"GetWorkflowStatusOptions",
|
|
170
310
|
"JsBaoClient",
|
|
171
311
|
"StartWorkflowOptions",
|
|
312
|
+
"TerminateWorkflowOptions",
|
|
313
|
+
"UpdateCronTriggerParams",
|
|
172
314
|
];
|
|
173
315
|
if (wf.syncCallable)
|
|
174
316
|
imports.push("RunSyncWorkflowOptions");
|
|
317
|
+
// Only an apply-mode workflow emits `define`, so its option type is imported
|
|
318
|
+
// only then — a non-apply-mode file would otherwise fail `noUnusedLocals`.
|
|
319
|
+
if (wf.requiresClientApply)
|
|
320
|
+
imports.push("WorkflowDefineOptions");
|
|
175
321
|
imports.sort();
|
|
176
322
|
const blocks = [];
|
|
177
323
|
blocks.push([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../src/lib/workflow-codegen/generator.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../src/lib/workflow-codegen/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared workflow-invoker IR (issue #1547, Phase 3).
|
|
3
|
+
*
|
|
4
|
+
* The typed invoker factory is generated on BOTH the TypeScript side
|
|
5
|
+
* (`workflow-codegen/generator.ts`) and the Swift side
|
|
6
|
+
* (`swift-codegen/generator.ts`). The maintainer decision (item 5, binding)
|
|
7
|
+
* requires that invoker generation reuse ONE description of the workflow's
|
|
8
|
+
* operation metadata — the runtime key, whether `runSync` is emitted
|
|
9
|
+
* (`syncCallable`), whether `input` is a required argument, and whether the
|
|
10
|
+
* workflow is apply-mode (`requiresClientApply`) — rather than each language
|
|
11
|
+
* renderer re-deriving it from the TOML. This module is that
|
|
12
|
+
* single source: both renderers call `describeWorkflowInvoker` and read the
|
|
13
|
+
* SAME `WorkflowInvokerIR`, so the two clients can never disagree on which
|
|
14
|
+
* operations a workflow exposes or whether its input is required.
|
|
15
|
+
*
|
|
16
|
+
* What stays language-specific (and is therefore NOT in the IR): the emitted
|
|
17
|
+
* identifiers (the TS and Swift base names come from different naming helpers)
|
|
18
|
+
* and the rendered type declarations. The IR carries only the parsed schemas +
|
|
19
|
+
* the neutral operation flags; each renderer turns the schemas into its own
|
|
20
|
+
* syntax.
|
|
21
|
+
*/
|
|
22
|
+
import { INTERNAL_WORKFLOW_KEY_PREFIX } from "../platform-owned.js";
|
|
23
|
+
export { INTERNAL_WORKFLOW_KEY_PREFIX };
|
|
24
|
+
/** Raw inputs a renderer already has on hand for one workflow TOML. */
|
|
25
|
+
export interface WorkflowInvokerSource {
|
|
26
|
+
/** Source `.toml` filename stem (fallback key when `[workflow].key` is absent). */
|
|
27
|
+
fileStem: string;
|
|
28
|
+
/** Raw TOML content (already read from disk). */
|
|
29
|
+
tomlContent: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Language-neutral description of one workflow's invoker surface. Consumed by
|
|
33
|
+
* both the TS and Swift invoker renderers; neither reconstructs these decisions
|
|
34
|
+
* on its own.
|
|
35
|
+
*/
|
|
36
|
+
export interface WorkflowInvokerIR {
|
|
37
|
+
/**
|
|
38
|
+
* The ORIGINAL workflow key. The runtime call always passes this verbatim —
|
|
39
|
+
* only emitted identifiers are sanitized (per language).
|
|
40
|
+
*/
|
|
41
|
+
key: string;
|
|
42
|
+
/**
|
|
43
|
+
* Whether the workflow is sync-callable. `runSync` is emitted ONLY when this
|
|
44
|
+
* is true (the server rejects run-sync for non-sync-callable workflows), on
|
|
45
|
+
* both clients.
|
|
46
|
+
*/
|
|
47
|
+
syncCallable: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Whether `input` is a REQUIRED argument. True iff the input schema rejects
|
|
50
|
+
* the empty object `{}` (the client's `input ?? {}` fallback would then fail
|
|
51
|
+
* validation). A schema-less workflow accepts anything → optional. Computed
|
|
52
|
+
* ONCE here via `schemaRejectsEmptyObject`, shared with both renderers.
|
|
53
|
+
*/
|
|
54
|
+
inputRequired: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Whether the workflow is apply-mode — its completed run waits for a client
|
|
57
|
+
* to apply the output. Mirrors the server's default: apply-mode unless the
|
|
58
|
+
* TOML sets `requiresClientApply = false` (`src/workflows/app-workflow.ts`).
|
|
59
|
+
* Only an apply-mode workflow gets a `define` member on the generated
|
|
60
|
+
* invoker (issue #1543). Parsed here, alongside `syncCallable`, so no
|
|
61
|
+
* renderer reparses the TOML for it.
|
|
62
|
+
*/
|
|
63
|
+
requiresClientApply: boolean;
|
|
64
|
+
/** Parsed input schema, or `undefined` when absent. */
|
|
65
|
+
inputSchema: unknown;
|
|
66
|
+
/** Parsed output schema, or `undefined` when absent. */
|
|
67
|
+
outputSchema: unknown;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* True for a platform-owned (reserved) workflow key. Thin alias over the shared
|
|
71
|
+
* `isPlatformOwnedWorkflowKey` (#1660) kept for existing callers of this name.
|
|
72
|
+
*/
|
|
73
|
+
export declare function isReservedWorkflowKey(key: string): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Parse one workflow TOML into the shared invoker IR. Returns `null` for a
|
|
76
|
+
* reserved (`__internal.*`) workflow (no invoker is generated). Throws on
|
|
77
|
+
* malformed schema JSON (fail-and-exit) — the honest `undefined`/`unknown`
|
|
78
|
+
* fallback is for valid-but-untypeable schemas only.
|
|
79
|
+
*
|
|
80
|
+
* This is the ONE place that reads `syncCallable` / `requiresClientApply` and
|
|
81
|
+
* computes required-vs-optional `input`; both language generators call it.
|
|
82
|
+
*/
|
|
83
|
+
export declare function describeWorkflowInvoker(source: WorkflowInvokerSource): WorkflowInvokerIR | null;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared workflow-invoker IR (issue #1547, Phase 3).
|
|
3
|
+
*
|
|
4
|
+
* The typed invoker factory is generated on BOTH the TypeScript side
|
|
5
|
+
* (`workflow-codegen/generator.ts`) and the Swift side
|
|
6
|
+
* (`swift-codegen/generator.ts`). The maintainer decision (item 5, binding)
|
|
7
|
+
* requires that invoker generation reuse ONE description of the workflow's
|
|
8
|
+
* operation metadata — the runtime key, whether `runSync` is emitted
|
|
9
|
+
* (`syncCallable`), whether `input` is a required argument, and whether the
|
|
10
|
+
* workflow is apply-mode (`requiresClientApply`) — rather than each language
|
|
11
|
+
* renderer re-deriving it from the TOML. This module is that
|
|
12
|
+
* single source: both renderers call `describeWorkflowInvoker` and read the
|
|
13
|
+
* SAME `WorkflowInvokerIR`, so the two clients can never disagree on which
|
|
14
|
+
* operations a workflow exposes or whether its input is required.
|
|
15
|
+
*
|
|
16
|
+
* What stays language-specific (and is therefore NOT in the IR): the emitted
|
|
17
|
+
* identifiers (the TS and Swift base names come from different naming helpers)
|
|
18
|
+
* and the rendered type declarations. The IR carries only the parsed schemas +
|
|
19
|
+
* the neutral operation flags; each renderer turns the schemas into its own
|
|
20
|
+
* syntax.
|
|
21
|
+
*/
|
|
22
|
+
import { parseConfigToml } from "../config-toml.js";
|
|
23
|
+
import { safeJsonParse } from "../workflow-payload.js";
|
|
24
|
+
import { schemaRejectsEmptyObject } from "./schemaToTs.js";
|
|
25
|
+
import { INTERNAL_WORKFLOW_KEY_PREFIX, isPlatformOwnedWorkflowKey, } from "../platform-owned.js";
|
|
26
|
+
// Re-export so existing importers of these codegen symbols keep working; the
|
|
27
|
+
// single source of truth is now `../platform-owned.js` (#1660), shared with the
|
|
28
|
+
// `sync` pull/diff/push filters so codegen and sync can never drift.
|
|
29
|
+
export { INTERNAL_WORKFLOW_KEY_PREFIX };
|
|
30
|
+
/**
|
|
31
|
+
* True for a platform-owned (reserved) workflow key. Thin alias over the shared
|
|
32
|
+
* `isPlatformOwnedWorkflowKey` (#1660) kept for existing callers of this name.
|
|
33
|
+
*/
|
|
34
|
+
export function isReservedWorkflowKey(key) {
|
|
35
|
+
return isPlatformOwnedWorkflowKey(key);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Parse one workflow TOML into the shared invoker IR. Returns `null` for a
|
|
39
|
+
* reserved (`__internal.*`) workflow (no invoker is generated). Throws on
|
|
40
|
+
* malformed schema JSON (fail-and-exit) — the honest `undefined`/`unknown`
|
|
41
|
+
* fallback is for valid-but-untypeable schemas only.
|
|
42
|
+
*
|
|
43
|
+
* This is the ONE place that reads `syncCallable` / `requiresClientApply` and
|
|
44
|
+
* computes required-vs-optional `input`; both language generators call it.
|
|
45
|
+
*/
|
|
46
|
+
export function describeWorkflowInvoker(source) {
|
|
47
|
+
const data = parseConfigToml(source.tomlContent);
|
|
48
|
+
const workflow = data?.workflow ?? {};
|
|
49
|
+
const key = typeof workflow.key === "string" && workflow.key.length > 0
|
|
50
|
+
? workflow.key
|
|
51
|
+
: source.fileStem;
|
|
52
|
+
if (isReservedWorkflowKey(key))
|
|
53
|
+
return null;
|
|
54
|
+
// safeJsonParse throws on invalid JSON in a schema string — let it bubble.
|
|
55
|
+
const inputSchema = safeJsonParse(workflow.inputSchema);
|
|
56
|
+
const outputSchema = safeJsonParse(workflow.outputSchema);
|
|
57
|
+
return {
|
|
58
|
+
key,
|
|
59
|
+
syncCallable: workflow.syncCallable === true,
|
|
60
|
+
// `input` is required iff the schema rejects the client's `{}` fallback.
|
|
61
|
+
// A schema-less workflow (`undefined`) accepts anything → optional.
|
|
62
|
+
inputRequired: inputSchema !== undefined && schemaRejectsEmptyObject(inputSchema),
|
|
63
|
+
// Apply-mode unless explicitly disabled — the same `!== false` default the
|
|
64
|
+
// server applies when it decides whether a completed run needs a client
|
|
65
|
+
// apply. An absent key means apply-mode.
|
|
66
|
+
requiresClientApply: workflow.requiresClientApply !== false,
|
|
67
|
+
inputSchema,
|
|
68
|
+
outputSchema,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=invokerIR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invokerIR.js","sourceRoot":"","sources":["../../../../src/lib/workflow-codegen/invokerIR.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAE9B,6EAA6E;AAC7E,gFAAgF;AAChF,qEAAqE;AACrE,OAAO,EAAE,4BAA4B,EAAE,CAAC;AAiDxC;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAC/C,OAAO,0BAA0B,CAAC,GAAG,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CACrC,MAA6B;IAE7B,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,CAAC,WAAW,CAAQ,CAAC;IACxD,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC;IACtC,MAAM,GAAG,GACP,OAAO,QAAQ,CAAC,GAAG,KAAK,QAAQ,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC;QACzD,CAAC,CAAC,QAAQ,CAAC,GAAG;QACd,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;IAEtB,IAAI,qBAAqB,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAE5C,2EAA2E;IAC3E,MAAM,WAAW,GAAG,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACxD,MAAM,YAAY,GAAG,aAAa,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAE1D,OAAO;QACL,GAAG;QACH,YAAY,EAAE,QAAQ,CAAC,YAAY,KAAK,IAAI;QAC5C,yEAAyE;QACzE,oEAAoE;QACpE,aAAa,EACX,WAAW,KAAK,SAAS,IAAI,wBAAwB,CAAC,WAAW,CAAC;QACpE,2EAA2E;QAC3E,wEAAwE;QACxE,yCAAyC;QACzC,mBAAmB,EAAE,QAAQ,CAAC,mBAAmB,KAAK,KAAK;QAC3D,WAAW;QACX,YAAY;KACb,CAAC;AACJ,CAAC"}
|
|
@@ -38,13 +38,29 @@
|
|
|
38
38
|
* Errors are NOT swallowed here — a malformed schema fails upstream at parse
|
|
39
39
|
* time, and a defective tagged union throws — this walker otherwise returns
|
|
40
40
|
* `unknown` for anything it does not recognize.
|
|
41
|
+
*
|
|
42
|
+
* FORMATTING CONTRACT (#1565): the types emitted here must be a fixed point of
|
|
43
|
+
* Prettier's DEFAULT config, since `workflows codegen --check` byte-compares
|
|
44
|
+
* the emission against disk. Long unions therefore render through
|
|
45
|
+
* `codegen-shared/prettierStable.ts` (which reproduces Prettier's width
|
|
46
|
+
* decision) instead of being joined with `" | "`. There is no Prettier
|
|
47
|
+
* dependency and no automated round-trip test, so verify any change to these
|
|
48
|
+
* shapes by hand — see that module's header.
|
|
41
49
|
*/
|
|
50
|
+
import { type TypeNode } from "../codegen-shared/prettierStable.js";
|
|
42
51
|
/**
|
|
43
52
|
* Convert a parsed JSON Schema node to a TypeScript type expression. Object
|
|
44
53
|
* types render multi-line (2-space indent per level); everything else renders
|
|
45
|
-
* on a single line
|
|
54
|
+
* on a single line unless it is too wide for Prettier's default print width
|
|
55
|
+
* (#1565). `indent` is the current indentation depth.
|
|
46
56
|
*/
|
|
47
57
|
export declare function schemaToTsType(schema: any, indent?: number): string;
|
|
58
|
+
/**
|
|
59
|
+
* `schemaToTsType` as a wrappable node — the emitters print it at the position
|
|
60
|
+
* it actually occupies so long unions/objects wrap exactly as Prettier would
|
|
61
|
+
* (#1565). See `codegen-shared/prettierStable.ts`.
|
|
62
|
+
*/
|
|
63
|
+
export declare function schemaToTypeNode(schema: any): TypeNode;
|
|
48
64
|
/**
|
|
49
65
|
* True when the schema REJECTS an empty object `{}` — i.e. the client's
|
|
50
66
|
* `rootInput: options.input ?? {}` fallback would fail validation, so `input`
|