primitive-admin 1.1.0-alpha.78 → 1.1.0-alpha.79

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 (105) hide show
  1. package/README.md +38 -17
  2. package/assets/skill/skills/primitive-platform/SKILL.md +39 -52
  3. package/dist/bin/primitive.js +14 -25
  4. package/dist/bin/primitive.js.map +1 -1
  5. package/dist/src/commands/admins.js +8 -18
  6. package/dist/src/commands/admins.js.map +1 -1
  7. package/dist/src/commands/analytics.js +46 -5
  8. package/dist/src/commands/analytics.js.map +1 -1
  9. package/dist/src/commands/auth.js +16 -1
  10. package/dist/src/commands/auth.js.map +1 -1
  11. package/dist/src/commands/collection-type-configs.js +1 -9
  12. package/dist/src/commands/collection-type-configs.js.map +1 -1
  13. package/dist/src/commands/config.js +11 -29
  14. package/dist/src/commands/config.js.map +1 -1
  15. package/dist/src/commands/database-type-configs.js +1 -9
  16. package/dist/src/commands/database-type-configs.js.map +1 -1
  17. package/dist/src/commands/databases.js +8 -38
  18. package/dist/src/commands/databases.js.map +1 -1
  19. package/dist/src/commands/env.js +27 -32
  20. package/dist/src/commands/env.js.map +1 -1
  21. package/dist/src/commands/functions.js +197 -23
  22. package/dist/src/commands/functions.js.map +1 -1
  23. package/dist/src/commands/groups.js +1 -9
  24. package/dist/src/commands/groups.js.map +1 -1
  25. package/dist/src/commands/init.js +6 -0
  26. package/dist/src/commands/init.js.map +1 -1
  27. package/dist/src/commands/rule-sets.js +1 -9
  28. package/dist/src/commands/rule-sets.js.map +1 -1
  29. package/dist/src/commands/scripts.js +12 -28
  30. package/dist/src/commands/scripts.js.map +1 -1
  31. package/dist/src/commands/sync.d.ts +119 -0
  32. package/dist/src/commands/sync.js +387 -196
  33. package/dist/src/commands/sync.js.map +1 -1
  34. package/dist/src/commands/workflows.js +2 -14
  35. package/dist/src/commands/workflows.js.map +1 -1
  36. package/dist/src/lib/api-client.d.ts +46 -11
  37. package/dist/src/lib/api-client.js +21 -11
  38. package/dist/src/lib/api-client.js.map +1 -1
  39. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.d.ts +24 -57
  40. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js +30 -204
  41. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js.map +1 -1
  42. package/dist/src/lib/config-json-field.d.ts +28 -0
  43. package/dist/src/lib/config-json-field.js +56 -0
  44. package/dist/src/lib/config-json-field.js.map +1 -0
  45. package/dist/src/lib/config-object-descriptor.js +4 -3
  46. package/dist/src/lib/config-object-descriptor.js.map +1 -1
  47. package/dist/src/lib/config-surface.js +1 -1
  48. package/dist/src/lib/config-surface.js.map +1 -1
  49. package/dist/src/lib/config.d.ts +21 -14
  50. package/dist/src/lib/config.js +25 -44
  51. package/dist/src/lib/config.js.map +1 -1
  52. package/dist/src/lib/credentials-store.d.ts +31 -8
  53. package/dist/src/lib/credentials-store.js +52 -13
  54. package/dist/src/lib/credentials-store.js.map +1 -1
  55. package/dist/src/lib/env-resolver-core.d.ts +18 -0
  56. package/dist/src/lib/env-resolver-core.js +26 -3
  57. package/dist/src/lib/env-resolver-core.js.map +1 -1
  58. package/dist/src/lib/env-resolver.d.ts +15 -0
  59. package/dist/src/lib/env-resolver.js +21 -1
  60. package/dist/src/lib/env-resolver.js.map +1 -1
  61. package/dist/src/lib/function-collect.d.ts +1 -1
  62. package/dist/src/lib/function-collect.js +138 -7
  63. package/dist/src/lib/function-collect.js.map +1 -1
  64. package/dist/src/lib/function-db-types.d.ts +49 -11
  65. package/dist/src/lib/function-db-types.js +234 -39
  66. package/dist/src/lib/function-db-types.js.map +1 -1
  67. package/dist/src/lib/function-document-types.d.ts +50 -0
  68. package/dist/src/lib/function-document-types.js +163 -0
  69. package/dist/src/lib/function-document-types.js.map +1 -0
  70. package/dist/src/lib/function-log-tail.d.ts +83 -0
  71. package/dist/src/lib/function-log-tail.js +115 -0
  72. package/dist/src/lib/function-log-tail.js.map +1 -0
  73. package/dist/src/lib/function-schema-codegen.d.ts +118 -0
  74. package/dist/src/lib/function-schema-codegen.js +402 -0
  75. package/dist/src/lib/function-schema-codegen.js.map +1 -0
  76. package/dist/src/lib/function-sync.d.ts +85 -2
  77. package/dist/src/lib/function-sync.js +196 -27
  78. package/dist/src/lib/function-sync.js.map +1 -1
  79. package/dist/src/lib/function-triggers.d.ts +9 -3
  80. package/dist/src/lib/function-triggers.js +12 -9
  81. package/dist/src/lib/function-triggers.js.map +1 -1
  82. package/dist/src/lib/function-typecheck.d.ts +86 -0
  83. package/dist/src/lib/function-typecheck.js +370 -0
  84. package/dist/src/lib/function-typecheck.js.map +1 -0
  85. package/dist/src/lib/generated-allowlist.js +4 -0
  86. package/dist/src/lib/generated-allowlist.js.map +1 -1
  87. package/dist/src/lib/generated-config-surfaces.d.ts +422 -0
  88. package/dist/src/lib/generated-config-surfaces.js +838 -9
  89. package/dist/src/lib/generated-config-surfaces.js.map +1 -1
  90. package/dist/src/lib/generated-sdk-types.d.ts +1 -1
  91. package/dist/src/lib/generated-sdk-types.js +1 -1
  92. package/dist/src/lib/generated-sdk-types.js.map +1 -1
  93. package/dist/src/lib/log-inspection.d.ts +116 -4
  94. package/dist/src/lib/log-inspection.js +147 -2
  95. package/dist/src/lib/log-inspection.js.map +1 -1
  96. package/dist/src/lib/snapshots.d.ts +6 -7
  97. package/dist/src/lib/snapshots.js +18 -81
  98. package/dist/src/lib/snapshots.js.map +1 -1
  99. package/dist/src/lib/sync-paths.d.ts +29 -53
  100. package/dist/src/lib/sync-paths.js +46 -97
  101. package/dist/src/lib/sync-paths.js.map +1 -1
  102. package/dist/src/lib/workflow-toml-validator.d.ts +8 -3
  103. package/dist/src/lib/workflow-toml-validator.js +8 -3
  104. package/dist/src/lib/workflow-toml-validator.js.map +1 -1
  105. package/package.json +3 -3
@@ -0,0 +1,402 @@
1
+ /**
2
+ * Schema-typed codegen for server functions — #3281, project
3
+ * `server-functions` phase 4.
4
+ *
5
+ * The intent's "Schema-typed codegen on every push": `<Key>Input` and
6
+ * `<Key>Output` from the declared schemas, a handler helper so function code
7
+ * is typed from the declaration, and a typed per-key invoker with the MODE
8
+ * fixed at generation time so a mismatch is a compile error. Two artifacts,
9
+ * both rendered from the same `functions/<key>.toml` and both regenerated by
10
+ * `config push`, `config pull` and `primitive functions codegen`:
11
+ *
12
+ * - `functions/primitive-function-types.d.ts` — every key's input and
13
+ * output types, and a `FunctionSchemas` augmentation keyed by function
14
+ * key (the `DatabaseSchemas` shape `primitive-db-types.d.ts` uses), which
15
+ * is what types `defineFunction("<key>", handler)`: `input` is the
16
+ * declared input, the return is checked against the declared output, and
17
+ * a key the tree does not declare is a compile error.
18
+ * - `functions/generated/<key>.generated.ts` — the client invoker, the
19
+ * `workflows codegen` layout: imports only from `js-bao-wss-client`,
20
+ * exports the two types and a `<key>(client)` factory whose members are
21
+ * the verbs the MODE allows and nothing else. A request function's
22
+ * invoker has exactly `invoke`; a task function's exactly `start`,
23
+ * `getStatus`, `waitFor` and `terminate`. The task `waitFor` binds
24
+ * `<Key>Output`, so the completion path is typed too (D3281-SO-003).
25
+ *
26
+ * ── The same descriptor the platform validates with ──────────────────────
27
+ *
28
+ * Schemas are interpreted through the vendored descriptor `workflows codegen`
29
+ * already reads (`workflow-codegen/schemaToTs.ts`, a byte copy of the server's
30
+ * `schema-descriptor.ts`), so what compiles is what every invocation door
31
+ * accepts: `input` is a REQUIRED option iff the schema rejects `{}` (the
32
+ * client sends `rootInput` only when `input !== undefined`, and the server
33
+ * defaults an absent one to `{}`), an absent schema is `unknown`, and a
34
+ * malformed schema fails naming the file rather than typing something false.
35
+ *
36
+ * ── Identifiers ──────────────────────────────────────────────────────────
37
+ *
38
+ * Names come from the workflow naming helpers (PascalCase, the digit-leading
39
+ * and reserved-word rules), and the runtime call always passes the ORIGINAL
40
+ * key. Two keys that sanitize to one identifier would render one file over the
41
+ * other, so that is refused naming both.
42
+ *
43
+ * FORMATTING CONTRACT (#1565): the invoker is emitted as a fixed point of
44
+ * Prettier's default config through `codegen-shared/prettierStable.ts`, like
45
+ * the other two generators, because `--check` byte-compares.
46
+ */
47
+ import { existsSync, readdirSync, readFileSync } from "fs";
48
+ import { basename, join } from "path";
49
+ import { parseConfigToml } from "./config-toml.js";
50
+ import { safeJsonParse } from "./workflow-payload.js";
51
+ import { resolveDeclaredMode, } from "./generated-config-surfaces.js";
52
+ import { schemaRejectsEmptyObject, schemaToTypeNode, } from "./workflow-codegen/schemaToTs.js";
53
+ import { describeSchema } from "./workflow-codegen/generated-schema-descriptor.js";
54
+ import { workflowFactoryName, workflowTypeBaseName, } from "./workflow-codegen/naming.js";
55
+ import { fingerprintToml } from "./db-codegen/dbFingerprint.js";
56
+ import { atom, generic, indent, intersection, objectType, printType, renderArrowCall, renderArrowProperty, renderParenList, renderTypeAlias, tsStringLiteral, union, } from "./codegen-shared/prettierStable.js";
57
+ /** The regenerated declaration beside `primitive-db-types.d.ts`. */
58
+ export const FUNCTION_TYPES_DECLARATION_FILE = "primitive-function-types.d.ts";
59
+ /** Where the per-key invokers go, under `functions/`, unless `-o` says otherwise. */
60
+ export const FUNCTION_INVOKERS_DIR = "generated";
61
+ /** Suffix identifying a generated invoker (shared with the other generators). */
62
+ export const GENERATED_FILE_SUFFIX = ".generated.ts";
63
+ /** The client package the invoker imports its types from. */
64
+ const CLIENT_PACKAGE = "js-bao-wss-client";
65
+ export class FunctionSchemaCodegenError extends Error {
66
+ }
67
+ /**
68
+ * The key push will identify this file by, resolved exactly the way push
69
+ * resolves it (CR3281-001).
70
+ *
71
+ * Push reads `tomlData.function?.key || basename(file, ".toml")`, so a file
72
+ * named `local.toml` carrying `key = "remote"` is pushed, collected and
73
+ * key-checked as `remote`. Reading only the stem here would have generated a
74
+ * `remote`-less declaration and an invoker calling a function that does not
75
+ * exist, while the collect step compared the exported handler against
76
+ * `remote` — three spellings of one identity. The file stem stays the
77
+ * fallback, which is what a pulled tree always uses.
78
+ *
79
+ * Same rule, same reason as `databaseTypeSources` (SO3182-003): the generator
80
+ * reads the key the platform will hear about, never the file name alone.
81
+ */
82
+ function resolveFunctionKey(source, table) {
83
+ return table?.key ? String(table.key) : source.key;
84
+ }
85
+ /**
86
+ * Every `functions/*.toml` in a tree, read once. The key is the one push
87
+ * uses: the file name (push takes the identity from it and attaches
88
+ * `functionKey` itself).
89
+ */
90
+ export function functionSchemaSources(configDir) {
91
+ const dir = join(configDir, "functions");
92
+ if (!existsSync(dir))
93
+ return [];
94
+ const sources = [];
95
+ for (const file of readdirSync(dir).filter((f) => f.endsWith(".toml"))) {
96
+ const tomlPath = join(dir, file);
97
+ let tomlContent;
98
+ try {
99
+ tomlContent = readFileSync(tomlPath, "utf-8");
100
+ }
101
+ catch {
102
+ continue;
103
+ }
104
+ sources.push({ key: basename(file, ".toml"), tomlPath, tomlContent });
105
+ }
106
+ return sources;
107
+ }
108
+ /** The tree-relative spelling of a source, for a message an author acts on. */
109
+ function fileLabel(source) {
110
+ const at = source.tomlPath.lastIndexOf("/functions/");
111
+ return at >= 0 ? source.tomlPath.slice(at + 1) : source.tomlPath;
112
+ }
113
+ /**
114
+ * Parse one file into the data both renderers need. Throws a
115
+ * `FunctionSchemaCodegenError` naming the file for malformed schema JSON or an
116
+ * unresolvable mode — the honest `unknown` is for an ABSENT schema, never a
117
+ * broken one.
118
+ */
119
+ export function describeFunctionSchemas(source) {
120
+ let table;
121
+ try {
122
+ table = parseConfigToml(source.tomlContent)?.function ?? {};
123
+ }
124
+ catch (error) {
125
+ throw new FunctionSchemaCodegenError(`${fileLabel(source)}: the file does not parse as TOML (${error?.message ?? error})`);
126
+ }
127
+ // The key push identifies this file by — an authored `[function] key` when
128
+ // there is one, the file stem otherwise (CR3281-001).
129
+ const key = resolveFunctionKey(source, table);
130
+ const mode = resolveDeclaredMode({ mode: table.mode, durable: table.durable });
131
+ if (mode.ok === false) {
132
+ throw new FunctionSchemaCodegenError(`${fileLabel(source)}: ${mode.error}`);
133
+ }
134
+ const schema = (field) => {
135
+ try {
136
+ return safeJsonParse(table[field]);
137
+ }
138
+ catch (error) {
139
+ throw new FunctionSchemaCodegenError(`${fileLabel(source)}: \`${field}\` is not valid JSON (${error?.message ?? error})`);
140
+ }
141
+ };
142
+ const inputSchema = schema("inputSchema");
143
+ const outputSchema = schema("outputSchema");
144
+ const typeBaseName = workflowTypeBaseName(key);
145
+ return {
146
+ key,
147
+ mode: mode.mode,
148
+ fileLabel: fileLabel(source),
149
+ inputSchema,
150
+ outputSchema,
151
+ inputRequired: inputSchema !== undefined && schemaRejectsEmptyObject(inputSchema),
152
+ typeBaseName,
153
+ inputTypeName: `${typeBaseName}Input`,
154
+ outputTypeName: `${typeBaseName}Output`,
155
+ factoryName: workflowFactoryName(key),
156
+ };
157
+ }
158
+ /**
159
+ * Describe every source, sorted by key, refusing two keys that sanitize to
160
+ * one identifier: they would render one file over the other and one type
161
+ * name for two schemas.
162
+ */
163
+ function describeAll(sources) {
164
+ const described = sources.map((source) => ({ fn: describeFunctionSchemas(source), source }));
165
+ described.sort((a, b) => (a.fn.key < b.fn.key ? -1 : a.fn.key > b.fn.key ? 1 : 0));
166
+ // Two files resolving to ONE key — only reachable through an authored
167
+ // `[function] key` (CR3281-001), since file stems are unique by
168
+ // construction. They would render one invoker over the other and push one
169
+ // function twice, so name both files rather than pick a winner.
170
+ const byKey = new Map();
171
+ for (const { fn, source } of described) {
172
+ const other = byKey.get(fn.key);
173
+ if (other !== undefined) {
174
+ throw new FunctionSchemaCodegenError(`${fileLabel(other)} and ${fileLabel(source)} both declare the function ` +
175
+ `key '${fn.key}' — one file is one function, so rename or remove one ` +
176
+ `\`[function] key\``);
177
+ }
178
+ byKey.set(fn.key, source);
179
+ }
180
+ const byBaseName = new Map();
181
+ for (const { fn } of described) {
182
+ const other = byBaseName.get(fn.typeBaseName);
183
+ if (other !== undefined && other !== fn.key) {
184
+ throw new FunctionSchemaCodegenError(`function keys '${other}' and '${fn.key}' both name the generated type ` +
185
+ `\`${fn.typeBaseName}Input\` — rename one so the two do not collide after sanitizing`);
186
+ }
187
+ byBaseName.set(fn.typeBaseName, fn.key);
188
+ }
189
+ return described;
190
+ }
191
+ /**
192
+ * A top-level `<Name>Input`/`<Name>Output` declaration: an absent schema →
193
+ * `unknown`, a plain object → an `interface`, anything else (a `oneOf` above
194
+ * all, which begins with `{` too) → a `type` alias. Same decision as the
195
+ * workflow generator, through the shared descriptor rather than a heuristic.
196
+ */
197
+ function renderTypeDecl(name, schema) {
198
+ if (schema === undefined)
199
+ return renderTypeAlias(name, atom("unknown"));
200
+ const node = schemaToTypeNode(schema);
201
+ if (node.kind === "block" && !describeSchema(schema).oneOf) {
202
+ return `export interface ${name} ${printType(node, 0, 0)}`;
203
+ }
204
+ return renderTypeAlias(name, node);
205
+ }
206
+ /**
207
+ * `renderTypeDecl` for one declared field, with a failure that names the file
208
+ * and the field (CR3281-004).
209
+ *
210
+ * The shared renderer refuses a schema it cannot type — a `oneOf` of objects
211
+ * with no usable discriminator, above all — by throwing a plain `Error` that
212
+ * says "workflows codegen" and names neither. Push catches
213
+ * `FunctionSchemaCodegenError` per tree and lets the rest of it land, so an
214
+ * unconverted throw took the whole command down before a single healthy
215
+ * function was sent, over a file the author could not identify from the
216
+ * message.
217
+ */
218
+ function renderDeclaredType(fn, field) {
219
+ const name = field === "inputSchema" ? fn.inputTypeName : fn.outputTypeName;
220
+ const schema = field === "inputSchema" ? fn.inputSchema : fn.outputSchema;
221
+ try {
222
+ return renderTypeDecl(name, schema);
223
+ }
224
+ catch (error) {
225
+ if (error instanceof FunctionSchemaCodegenError)
226
+ throw error;
227
+ throw new FunctionSchemaCodegenError(`${fn.fileLabel}: \`${field}\` cannot be rendered as a TypeScript type ` +
228
+ `(${error?.message ?? error})`);
229
+ }
230
+ }
231
+ const DECLARATION_HEADER = `// GENERATED by \`primitive config push\` from functions/*.toml.
232
+ // DO NOT EDIT — your changes are overwritten on the next push.
233
+ //
234
+ // It gives \`defineFunction("<key>", handler)\` its types: \`input\` is the
235
+ // function's declared inputSchema and the return is checked against its
236
+ // declared outputSchema. A key this tree does not declare is a compile error.
237
+ // The client-side invokers are the \`generated/<key>.generated.ts\` files beside
238
+ // this one.
239
+ `;
240
+ /**
241
+ * The declaration for a whole tree's functions. Sorted by key so the bytes
242
+ * depend on the files and not on the order they were read in. The
243
+ * augmentation is emitted even when the tree has no function yet: an empty
244
+ * `FunctionSchemas` keeps `FunctionKeys` open (`string`), so nothing breaks.
245
+ */
246
+ export function renderFunctionSchemasDeclaration(sources) {
247
+ const functions = describeAll(sources).map((entry) => entry.fn);
248
+ const lines = [DECLARATION_HEADER];
249
+ for (const fn of functions) {
250
+ lines.push(renderDeclaredType(fn, "inputSchema"));
251
+ lines.push("");
252
+ lines.push(renderDeclaredType(fn, "outputSchema"));
253
+ lines.push("");
254
+ }
255
+ if (functions.length === 0) {
256
+ lines.push("export interface PrimitiveFunctionSchemas {}");
257
+ }
258
+ else {
259
+ lines.push("export interface PrimitiveFunctionSchemas {");
260
+ for (const fn of functions) {
261
+ lines.push(` ${JSON.stringify(fn.key)}: {`);
262
+ lines.push(` input: ${fn.inputTypeName};`);
263
+ lines.push(` output: ${fn.outputTypeName};`);
264
+ lines.push(` mode: ${JSON.stringify(fn.mode)};`);
265
+ lines.push(` };`);
266
+ }
267
+ lines.push("}");
268
+ }
269
+ lines.push("");
270
+ lines.push(`declare module "primitive-functions" {`);
271
+ lines.push(` interface FunctionSchemas extends PrimitiveFunctionSchemas {}`);
272
+ lines.push(`}`);
273
+ lines.push("");
274
+ return lines.join("\n");
275
+ }
276
+ /**
277
+ * The invoker factory for one function — the verbs its mode allows and
278
+ * nothing else, so the wrong verb is a compile error, not a runtime
279
+ * `FUNCTION_MODE_MISMATCH`.
280
+ *
281
+ * `invoke`/`start` take the key POSITIONALLY (`client.functions.<verb>(key,
282
+ * opts)`), so the key cannot ride in through `opts`; `terminate` addresses a
283
+ * run by a ref object, where the spread comes first and the pinned key last —
284
+ * a caller passing a ref variable carrying another key still terminates this
285
+ * function's run.
286
+ */
287
+ function renderFactory(fn) {
288
+ const keyLiteral = tsStringLiteral(fn.key);
289
+ const inputMember = fn.inputRequired
290
+ ? `input: ${fn.inputTypeName}`
291
+ : `input?: ${fn.inputTypeName}`;
292
+ const lines = [
293
+ renderParenList(`export function ${fn.factoryName}`, ["client: JsBaoClient"], " {", 0),
294
+ ` return {`,
295
+ ];
296
+ // `opts: { input: X } & Omit<<Options><X>, "input">` — always broken onto its
297
+ // own line: the shortest possible form is already wider than 80 columns.
298
+ const optsParam = (optionsTypeName) => {
299
+ const node = intersection([
300
+ objectType([inputMember]),
301
+ generic("Omit", [
302
+ generic(optionsTypeName, [atom(fn.inputTypeName)]),
303
+ union([atom(`"input"`)]),
304
+ ]),
305
+ ]);
306
+ const head = `${indent(3)}opts: `;
307
+ return `${head}${printType(node, head.length, 3, 1)},`;
308
+ };
309
+ const invocation = (method, typeArgs, optionsTypeName) => renderArrowCall({
310
+ head: [`${indent(2)}${method}: (`, optsParam(optionsTypeName), `${indent(2)}) =>`].join("\n"),
311
+ callee: generic(`client.functions.${method}`, typeArgs.map(atom)),
312
+ leadingArgs: [keyLiteral],
313
+ objectMembers: ["...opts"],
314
+ level: 3,
315
+ tail: ",",
316
+ });
317
+ if (fn.mode === "request") {
318
+ lines.push(invocation("invoke", [fn.outputTypeName, fn.inputTypeName], "FunctionInvokeOptions"));
319
+ }
320
+ else {
321
+ lines.push(invocation("start", [fn.inputTypeName], "FunctionStartOptions"));
322
+ lines.push(renderArrowProperty({
323
+ level: 2,
324
+ key: "getStatus",
325
+ params: ["runId: string"],
326
+ signatureTail: " =>",
327
+ callee: generic("client.functions.getStatus", [atom(fn.outputTypeName)]),
328
+ leadingArgs: ["runId"],
329
+ tail: ",",
330
+ }));
331
+ lines.push(renderArrowProperty({
332
+ level: 2,
333
+ key: "waitFor",
334
+ params: ["runId: string", "options?: WaitForWorkflowOptions"],
335
+ signatureTail: " =>",
336
+ callee: generic("client.functions.waitFor", [atom(fn.outputTypeName)]),
337
+ leadingArgs: ["runId", "options"],
338
+ tail: ",",
339
+ }));
340
+ lines.push(renderArrowProperty({
341
+ level: 2,
342
+ key: "terminate",
343
+ params: [`ref: Omit<FunctionRunRef, "functionKey">`],
344
+ signatureTail: " =>",
345
+ callee: generic("client.functions.terminate", [atom(fn.outputTypeName)]),
346
+ leadingArgs: [],
347
+ objectMembers: ["...ref", { key: "functionKey", value: keyLiteral }],
348
+ tail: ",",
349
+ }));
350
+ }
351
+ lines.push(` };`, `}`);
352
+ return lines.join("\n");
353
+ }
354
+ /**
355
+ * `import type { … } from "js-bao-wss-client"`, the way Prettier prints it:
356
+ * on one line when it fits, one specifier per line (trailing comma) when not.
357
+ */
358
+ function renderImport(names) {
359
+ const inline = `import type { ${names.join(", ")} } from "${CLIENT_PACKAGE}";`;
360
+ if (inline.length <= 80)
361
+ return inline;
362
+ return `import type {\n${names.map((i) => ` ${i},`).join("\n")}\n} from "${CLIENT_PACKAGE}";`;
363
+ }
364
+ /**
365
+ * The full `<key>.generated.ts` for one function. Pure — exported so tests
366
+ * can assert on the string directly.
367
+ */
368
+ export function renderFunctionInvokerFile(source) {
369
+ const fn = describeFunctionSchemas(source);
370
+ const fingerprint = fingerprintToml(source.tomlContent);
371
+ // Only the option types the mode's verbs reference, so the file compiles
372
+ // under a consumer's `noUnusedLocals`.
373
+ const imports = fn.mode === "request"
374
+ ? ["FunctionInvokeOptions", "JsBaoClient"]
375
+ : ["FunctionRunRef", "FunctionStartOptions", "JsBaoClient", "WaitForWorkflowOptions"];
376
+ const blocks = [
377
+ [
378
+ `// AUTO-GENERATED FROM ${fn.fileLabel} — DO NOT EDIT.`,
379
+ "// Run `primitive functions codegen` to regenerate.",
380
+ `// fingerprint: ${fingerprint}`,
381
+ ].join("\n"),
382
+ renderImport(imports),
383
+ renderDeclaredType(fn, "inputSchema"),
384
+ renderDeclaredType(fn, "outputSchema"),
385
+ renderFactory(fn),
386
+ ];
387
+ return { key: fn.key, content: blocks.join("\n\n") + "\n" };
388
+ }
389
+ /**
390
+ * Every invoker for a tree, keyed by the file name the generator writes
391
+ * (`<key>.generated.ts`), with the identifier-collision refusal applied
392
+ * across the set.
393
+ */
394
+ export function renderFunctionInvokers(sources) {
395
+ // `describeAll` is the collision check; the per-file render repeats the
396
+ // (cheap) parse rather than threading the IR through.
397
+ return describeAll(sources).map(({ fn, source }) => ({
398
+ fileName: `${fn.key}${GENERATED_FILE_SUFFIX}`,
399
+ content: renderFunctionInvokerFile(source).content,
400
+ }));
401
+ }
402
+ //# sourceMappingURL=function-schema-codegen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"function-schema-codegen.js","sourceRoot":"","sources":["../../../src/lib/function-schema-codegen.ts"],"names":[],"mappings":"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"}
@@ -31,6 +31,7 @@
31
31
  * directory inside the tree, so the write step resolves the real path one last
32
32
  * time and refuses a destination that lands outside the real root.
33
33
  */
34
+ import { type FunctionMode, type TriggerDeclaration } from "./generated-config-surfaces.js";
34
35
  import { type FunctionManifest as CollectedManifest } from "./function-collect.js";
35
36
  /**
36
37
  * Collect one function's manifest, or answer from this command's memo.
@@ -47,6 +48,26 @@ export declare function collectManifestForBundle(options: {
47
48
  /** The built bundle's source, for the static scan (#3279). */
48
49
  bundle?: string;
49
50
  }): Promise<CollectedManifest>;
51
+ /**
52
+ * The server's own `[function.triggers.*]` rules, applied to a parsed
53
+ * `[function]` table, with "nothing declared" spelled as null so a caller can
54
+ * skip the work.
55
+ *
56
+ * `normalizeTriggerDeclaration` comes from `generated-config-surfaces.ts` —
57
+ * `src/config-surface/trigger-declaration.ts` vendored verbatim. Until #3320
58
+ * the CLI ran a hand-written restatement of those rules
59
+ * (`cli/src/lib/function-triggers.ts`), kept in step only by a paired-fixture
60
+ * test; the artifact's `--check` makes drift a build failure instead.
61
+ *
62
+ * One check is the CLI's OWN and is deliberately not on that path: the cron
63
+ * expression's field count. The authority for cron grammar is the server's
64
+ * `src/cron-parser.ts` (`parseCron`, run at the push boundary), which the
65
+ * declaration rules never call — so this is a shape precheck that turns the
66
+ * commonest typo into a named local error, not a second copy of a rule.
67
+ */
68
+ export declare function normalizeFunctionTriggers(functionTable: any, options?: {
69
+ mode?: FunctionMode;
70
+ }): TriggerDeclaration | null;
50
71
  export interface FunctionConfigPush {
51
72
  entry: string;
52
73
  /** base64 of the authored `functions/<key>.toml` bytes. */
@@ -65,15 +86,62 @@ export interface FunctionConfigPush {
65
86
  manifest: string | null;
66
87
  /** The number BOTH sides compare to decide "is this a no-op?". */
67
88
  envelopeHash: string;
89
+ /** `mode = "request" | "task"` (#3281), resolved from the file's two spellings. */
90
+ mode: FunctionMode;
91
+ /**
92
+ * The same resolution as `mode`, in the alias's spelling: a new CLI against
93
+ * a server that predates `mode` still pushes a task function as a task.
94
+ */
68
95
  durable: boolean;
69
96
  limits?: Record<string, unknown>;
70
97
  }
98
+ /**
99
+ * Resolve the file's mode — `mode`, its alias `durable`, or neither — through
100
+ * the ONE vendored rule (#3281). A disagreement or an unknown word is a
101
+ * `FunctionBuildError` naming the function, like every other preflight
102
+ * refusal, so nothing is built or sent for that file.
103
+ */
104
+ export declare function resolveFunctionMode(functionKey: string, table: any): FunctionMode;
105
+ /**
106
+ * Everything about one `functions/<key>.toml` that `config push` can decide
107
+ * from the file alone (#3320).
108
+ *
109
+ * This is the seam the issue is about. These checks used to run inside the
110
+ * APPLY loop, so a `durable = true` beside a webhook block — or a missing
111
+ * `entry`, or a signed scheme with no `signingSecret` — was raised after app
112
+ * settings, vars, integrations, webhooks, cron triggers and database types had
113
+ * already been written, while the command's own framing promised that a
114
+ * refusal meant nothing was applied. Running them in the front-loaded pass
115
+ * (#976) makes that framing true for this class of error.
116
+ *
117
+ * Every rule here is the SERVER's, reached through the generated surface
118
+ * artifact (#3320 part 0), not a local imitation of it. What is deliberately
119
+ * absent is app-state-dependent by construction: whether the referenced secret
120
+ * exists, whether the scheme's `config` is valid under this environment's JWKS
121
+ * policy, per-app caps, key collisions, archived tombstones. A local guess at
122
+ * any of those would be a preflight that gives a false all-clear.
123
+ *
124
+ * Returns the messages the apply loop would have raised, verbatim — so the
125
+ * author reads the same sentence wherever it reaches them, and `config diff`
126
+ * can report it under Invalid (#2880 symmetry).
127
+ */
128
+ export declare function functionTomlPreflightErrors(options: {
129
+ filePath: string;
130
+ functionKey: string;
131
+ /** The already-parsed document, so the file is read once. */
132
+ tomlData: any;
133
+ }): string[];
71
134
  /**
72
135
  * Build everything the config-version route needs for one function file.
73
136
  *
74
137
  * Throws `FunctionBuildError` for a missing `entry`, a missing entry file, a
75
138
  * build error, or an import that escapes the config tree — one class, so the
76
139
  * push loop has one thing to report and pushes nothing for that function.
140
+ *
141
+ * The file-decidable checks are `functionTomlPreflightErrors`', kept here as
142
+ * defense in depth (#3179's dual-validation shape): `config push` runs them in
143
+ * its preflight now, but `functions` commands and a direct caller reach this
144
+ * function without one.
77
145
  */
78
146
  export declare function buildFunctionConfigPush(options: {
79
147
  configDir: string;
@@ -93,11 +161,21 @@ export declare function buildFunctionCreatePayload(functionKey: string, table: a
93
161
  * The update body. The key is NOT re-sent — it is the function's claim on the
94
162
  * app's single key namespace and the URL already names the row — and `status`
95
163
  * is server-owned on the sixth carrying type as on the other five.
164
+ *
165
+ * #3317 — the schemas are TOML-owned on exactly the terms `description` is
166
+ * (#1567), which is what prompts have sent since then: the update handler
167
+ * preserves a field the body omits, so dropping the key would leave a schema
168
+ * live that the file no longer declares, and the comparison — which reads an
169
+ * absent schema as `null` — would report that difference again on every run.
170
+ * Removing `[function.inputSchema]` clears it, and the next diff is Synced.
96
171
  */
97
172
  export declare function buildFunctionUpdatePayload(table: any): Record<string, any>;
98
173
  /** The version-carried keys, as the config-version row holds them. */
99
174
  export interface ActiveFunctionVersion {
100
175
  entry?: string;
176
+ /** #3281 — serialized beside `durable` by a server that knows the word. */
177
+ mode?: string;
178
+ /** The stored column; the only thing an older server serializes. */
101
179
  durable?: boolean;
102
180
  /** JSON string on the row; an object is accepted too. */
103
181
  limits?: unknown;
@@ -109,10 +187,15 @@ export interface ActiveFunctionVersion {
109
187
  * created through the API that has never had code pushed. When bytes exist,
110
188
  * pull writes THOSE; this is the fallback that still produces a pushable file.
111
189
  */
112
- export declare function serializeFunction(record: any, active?: ActiveFunctionVersion): string;
190
+ export declare function serializeFunction(record: any, active?: ActiveFunctionVersion, log?: (message: string) => void): string;
191
+ /**
192
+ * The mode a server's config-version row is in, whichever of the two fields
193
+ * this server serializes: `mode` since #3281, `durable` before it.
194
+ */
195
+ export declare function activeVersionMode(active?: ActiveFunctionVersion | null): FunctionMode;
113
196
  /**
114
197
  * The entity both sides of `config diff` are projected onto: the header's
115
- * authored fields plus the three keys the VERSION carries. Stated once so a
198
+ * authored fields plus the keys the VERSION carries. Stated once so a
116
199
  * local file and a server record cannot be read into different shapes.
117
200
  *
118
201
  * Text the server rewrites on the way in is read the same way it will come