primitive-admin 1.1.0-alpha.73 → 1.1.0-alpha.74
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/README.md +18 -25
- package/assets/skill/skills/primitive-platform/SKILL.md +30 -14
- package/dist/bin/primitive.js +14 -11
- package/dist/bin/primitive.js.map +1 -1
- package/dist/src/commands/analytics.js +117 -2
- package/dist/src/commands/analytics.js.map +1 -1
- package/dist/src/commands/auth.js +13 -107
- package/dist/src/commands/auth.js.map +1 -1
- package/dist/src/commands/collection-type-configs.js +1 -1
- package/dist/src/commands/collection-type-configs.js.map +1 -1
- package/dist/src/commands/database-type-configs.js +1 -1
- package/dist/src/commands/database-type-configs.js.map +1 -1
- package/dist/src/commands/databases.js +1 -1
- package/dist/src/commands/databases.js.map +1 -1
- package/dist/src/commands/documents.js +749 -29
- package/dist/src/commands/documents.js.map +1 -1
- package/dist/src/commands/env.js +44 -6
- package/dist/src/commands/env.js.map +1 -1
- package/dist/src/commands/functions.d.ts +20 -0
- package/dist/src/commands/functions.js +329 -0
- package/dist/src/commands/functions.js.map +1 -0
- package/dist/src/commands/groups.js +1 -1
- package/dist/src/commands/groups.js.map +1 -1
- package/dist/src/commands/init.js +2 -15
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/integrations.js +5 -3
- package/dist/src/commands/integrations.js.map +1 -1
- package/dist/src/commands/prompts.js +5 -7
- package/dist/src/commands/prompts.js.map +1 -1
- package/dist/src/commands/rule-sets.js +1 -1
- package/dist/src/commands/rule-sets.js.map +1 -1
- package/dist/src/commands/scripts.js +6 -7
- package/dist/src/commands/scripts.js.map +1 -1
- package/dist/src/commands/sync.d.ts +63 -0
- package/dist/src/commands/sync.js +650 -2
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/commands/workflows.js +5 -7
- package/dist/src/commands/workflows.js.map +1 -1
- package/dist/src/lib/api-client.d.ts +156 -1
- package/dist/src/lib/api-client.js +219 -3
- package/dist/src/lib/api-client.js.map +1 -1
- package/dist/src/lib/app-settings-descriptor.js +4 -0
- package/dist/src/lib/app-settings-descriptor.js.map +1 -1
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js +5 -7
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js.map +1 -1
- package/dist/src/lib/config-object-descriptor.js +39 -0
- package/dist/src/lib/config-object-descriptor.js.map +1 -1
- package/dist/src/lib/config-surface.d.ts +10 -0
- package/dist/src/lib/config-surface.js +17 -0
- package/dist/src/lib/config-surface.js.map +1 -1
- package/dist/src/lib/config.d.ts +13 -2
- package/dist/src/lib/config.js +20 -37
- package/dist/src/lib/config.js.map +1 -1
- package/dist/src/lib/credentials-store.d.ts +4 -12
- package/dist/src/lib/credentials-store.js +49 -82
- package/dist/src/lib/credentials-store.js.map +1 -1
- package/dist/src/lib/env-resolver-core.d.ts +23 -7
- package/dist/src/lib/env-resolver-core.js +44 -4
- package/dist/src/lib/env-resolver-core.js.map +1 -1
- package/dist/src/lib/function-bundle.d.ts +131 -0
- package/dist/src/lib/function-bundle.js +321 -0
- package/dist/src/lib/function-bundle.js.map +1 -0
- package/dist/src/lib/function-sync.d.ts +157 -0
- package/dist/src/lib/function-sync.js +371 -0
- package/dist/src/lib/function-sync.js.map +1 -0
- package/dist/src/lib/function-triggers.d.ts +54 -0
- package/dist/src/lib/function-triggers.js +223 -0
- package/dist/src/lib/function-triggers.js.map +1 -0
- package/dist/src/lib/generated-config-surfaces.d.ts +1 -0
- package/dist/src/lib/generated-config-surfaces.js +279 -1
- package/dist/src/lib/generated-config-surfaces.js.map +1 -1
- package/dist/src/lib/init-ios-links.d.ts +6 -5
- package/dist/src/lib/init-ios-links.js +8 -7
- package/dist/src/lib/init-ios-links.js.map +1 -1
- package/dist/src/lib/init-xcode.d.ts +4 -3
- package/dist/src/lib/init-xcode.js +28 -5
- package/dist/src/lib/init-xcode.js.map +1 -1
- package/dist/src/lib/ios-app-id.d.ts +34 -0
- package/dist/src/lib/ios-app-id.js +69 -0
- package/dist/src/lib/ios-app-id.js.map +1 -0
- package/dist/src/lib/project-config.d.ts +15 -1
- package/dist/src/lib/project-config.js +31 -3
- package/dist/src/lib/project-config.js.map +1 -1
- package/dist/src/lib/sync-resource-types.d.ts +21 -2
- package/dist/src/lib/sync-resource-types.js +104 -6
- package/dist/src/lib/sync-resource-types.js.map +1 -1
- package/dist/src/lib/test-case-variables.d.ts +14 -0
- package/dist/src/lib/test-case-variables.js +42 -0
- package/dist/src/lib/test-case-variables.js.map +1 -1
- package/dist/src/lib/workflow-usage.d.ts +198 -0
- package/dist/src/lib/workflow-usage.js +312 -0
- package/dist/src/lib/workflow-usage.js.map +1 -0
- package/dist/src/types/index.d.ts +12 -2
- package/package.json +2 -1
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `[function.triggers.*]`, read and checked locally (#3181).
|
|
3
|
+
*
|
|
4
|
+
* The SERVER is the authority: it derives the declaration from the TOML bytes
|
|
5
|
+
* inside the version envelope and validates it there, so a direct API push
|
|
6
|
+
* cannot ship a trigger the authored file does not declare (D3181-005). What
|
|
7
|
+
* this file buys is the other half of the `entry` dual-validation shape #3179
|
|
8
|
+
* established — an author who mistypes a key hears about it against their own
|
|
9
|
+
* file, by name, before a request is made.
|
|
10
|
+
*
|
|
11
|
+
* It is deliberately a VENDORED copy of the shape rules in
|
|
12
|
+
* `src/server-functions/trigger-declaration.ts` rather than an import: the CLI
|
|
13
|
+
* compiles with `rootDir: "."` and cannot reach the worker sources, which is
|
|
14
|
+
* the same constraint that made `generated-config-surfaces.ts` a vendored
|
|
15
|
+
* artifact. `cli/tests/unit/function-triggers-3181.test.ts` drives both copies
|
|
16
|
+
* from one fixture list so they cannot drift apart silently.
|
|
17
|
+
*
|
|
18
|
+
* Everything that needs the APP's state stays on the server: whether a
|
|
19
|
+
* referenced secret exists, whether the scheme-specific config is valid under
|
|
20
|
+
* this environment's JWKS policy, whether the app is at its webhook or cron
|
|
21
|
+
* cap, whether a standalone webhook holds the key. A local copy of those would
|
|
22
|
+
* be a preflight that can give a false all-clear.
|
|
23
|
+
*/
|
|
24
|
+
export const MAX_CRON_TRIGGERS_PER_FUNCTION = 10;
|
|
25
|
+
const CRON_NAME_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]*$/;
|
|
26
|
+
const WEBHOOK_KEYS = [
|
|
27
|
+
"verificationScheme",
|
|
28
|
+
"signingSecret",
|
|
29
|
+
"toleranceSeconds",
|
|
30
|
+
"deduplicationEnabled",
|
|
31
|
+
"deduplicationWindowMs",
|
|
32
|
+
"maxBodyBytes",
|
|
33
|
+
"secretGracePeriodMs",
|
|
34
|
+
"verification",
|
|
35
|
+
];
|
|
36
|
+
const CRON_KEYS = ["name", "cron", "timezone", "overlapPolicy", "rootInput"];
|
|
37
|
+
const VALID_OVERLAP_POLICIES = ["skip", "allow"];
|
|
38
|
+
export class TriggerDeclarationError extends Error {
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Normalize (and check) the `triggers` table of a parsed `[function]` table.
|
|
42
|
+
* Returns null when nothing is declared, so a caller can skip the work.
|
|
43
|
+
*/
|
|
44
|
+
export function normalizeFunctionTriggers(functionTable, options = {}) {
|
|
45
|
+
const triggers = functionTable?.triggers;
|
|
46
|
+
if (triggers === undefined || triggers === null)
|
|
47
|
+
return null;
|
|
48
|
+
if (typeof triggers !== "object" || Array.isArray(triggers)) {
|
|
49
|
+
throw new TriggerDeclarationError("[function.triggers] must be a table declaring `webhook` and/or `cron`");
|
|
50
|
+
}
|
|
51
|
+
for (const key of Object.keys(triggers)) {
|
|
52
|
+
if (key !== "webhook" && key !== "cron") {
|
|
53
|
+
throw new TriggerDeclarationError(`unknown trigger kind '${key}' under [function.triggers]: the kinds are ` +
|
|
54
|
+
"`webhook` and `cron`");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const webhook = normalizeWebhook(triggers.webhook, options);
|
|
58
|
+
const cron = normalizeCron(triggers.cron, options);
|
|
59
|
+
if (!webhook && cron.length === 0)
|
|
60
|
+
return null;
|
|
61
|
+
return { webhook, cron };
|
|
62
|
+
}
|
|
63
|
+
function normalizeWebhook(raw, options) {
|
|
64
|
+
if (raw === undefined || raw === null)
|
|
65
|
+
return null;
|
|
66
|
+
if (Array.isArray(raw)) {
|
|
67
|
+
throw new TriggerDeclarationError("[function.triggers.webhook] is a single table: one webhook trigger per " +
|
|
68
|
+
'function (the intent, "Webhook trigger URL and scheme?")');
|
|
69
|
+
}
|
|
70
|
+
if (typeof raw !== "object") {
|
|
71
|
+
throw new TriggerDeclarationError("[function.triggers.webhook] must be a table");
|
|
72
|
+
}
|
|
73
|
+
const table = raw;
|
|
74
|
+
for (const key of Object.keys(table)) {
|
|
75
|
+
if (!WEBHOOK_KEYS.includes(key)) {
|
|
76
|
+
throw new TriggerDeclarationError(`unknown key '${key}' under [function.triggers.webhook]: accepted keys ` +
|
|
77
|
+
`are ${WEBHOOK_KEYS.join(", ")}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (options.durable) {
|
|
81
|
+
throw new TriggerDeclarationError("webhook triggers require sync mode: remove `durable = true` or remove " +
|
|
82
|
+
"[function.triggers.webhook]");
|
|
83
|
+
}
|
|
84
|
+
const scheme = String(table.verificationScheme ?? "").trim();
|
|
85
|
+
if (!scheme) {
|
|
86
|
+
throw new TriggerDeclarationError("[function.triggers.webhook] verificationScheme is required");
|
|
87
|
+
}
|
|
88
|
+
if (scheme === "none") {
|
|
89
|
+
throw new TriggerDeclarationError("verification scheme 'none' is not allowed for function triggers: an " +
|
|
90
|
+
"unauthenticated caller could run the function");
|
|
91
|
+
}
|
|
92
|
+
const declaration = { verificationScheme: scheme };
|
|
93
|
+
if (table.signingSecret !== undefined) {
|
|
94
|
+
declaration.signingSecret = String(table.signingSecret);
|
|
95
|
+
}
|
|
96
|
+
for (const key of [
|
|
97
|
+
"toleranceSeconds",
|
|
98
|
+
"deduplicationWindowMs",
|
|
99
|
+
"maxBodyBytes",
|
|
100
|
+
"secretGracePeriodMs",
|
|
101
|
+
]) {
|
|
102
|
+
if (table[key] === undefined)
|
|
103
|
+
continue;
|
|
104
|
+
const value = Number(table[key]);
|
|
105
|
+
if (!Number.isFinite(value)) {
|
|
106
|
+
throw new TriggerDeclarationError(`[function.triggers.webhook] ${key} must be a number`);
|
|
107
|
+
}
|
|
108
|
+
declaration[key] = value;
|
|
109
|
+
}
|
|
110
|
+
if (table.deduplicationEnabled !== undefined) {
|
|
111
|
+
if (typeof table.deduplicationEnabled !== "boolean") {
|
|
112
|
+
throw new TriggerDeclarationError("[function.triggers.webhook] deduplicationEnabled must be a boolean");
|
|
113
|
+
}
|
|
114
|
+
declaration.deduplicationEnabled = table.deduplicationEnabled;
|
|
115
|
+
}
|
|
116
|
+
if (table.verification !== undefined) {
|
|
117
|
+
const verification = table.verification;
|
|
118
|
+
if (verification === null ||
|
|
119
|
+
typeof verification !== "object" ||
|
|
120
|
+
Array.isArray(verification)) {
|
|
121
|
+
throw new TriggerDeclarationError("[function.triggers.webhook.verification] must be a table");
|
|
122
|
+
}
|
|
123
|
+
declaration.verification = jsonSafe(verification);
|
|
124
|
+
}
|
|
125
|
+
return declaration;
|
|
126
|
+
}
|
|
127
|
+
function normalizeCron(raw, options) {
|
|
128
|
+
if (raw === undefined || raw === null)
|
|
129
|
+
return [];
|
|
130
|
+
const entries = Array.isArray(raw) ? raw : [raw];
|
|
131
|
+
if (entries.length === 0)
|
|
132
|
+
return [];
|
|
133
|
+
if (options.durable) {
|
|
134
|
+
throw new TriggerDeclarationError("cron triggers require sync mode in this release: remove `durable = " +
|
|
135
|
+
"true` or remove the [[function.triggers.cron]] entries");
|
|
136
|
+
}
|
|
137
|
+
if (entries.length > MAX_CRON_TRIGGERS_PER_FUNCTION) {
|
|
138
|
+
throw new TriggerDeclarationError(`a function may declare at most ${MAX_CRON_TRIGGERS_PER_FUNCTION} cron ` +
|
|
139
|
+
`trigger entries, and this one declares ${entries.length}`);
|
|
140
|
+
}
|
|
141
|
+
const seen = new Set();
|
|
142
|
+
const normalized = [];
|
|
143
|
+
for (const entry of entries) {
|
|
144
|
+
if (entry === null || typeof entry !== "object" || Array.isArray(entry)) {
|
|
145
|
+
throw new TriggerDeclarationError("each [[function.triggers.cron]] entry must be a table");
|
|
146
|
+
}
|
|
147
|
+
const table = entry;
|
|
148
|
+
for (const key of Object.keys(table)) {
|
|
149
|
+
if (!CRON_KEYS.includes(key)) {
|
|
150
|
+
throw new TriggerDeclarationError(`unknown key '${key}' in a [[function.triggers.cron]] entry: accepted ` +
|
|
151
|
+
`keys are ${CRON_KEYS.join(", ")}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const name = String(table.name ?? "").trim();
|
|
155
|
+
if (!name) {
|
|
156
|
+
throw new TriggerDeclarationError("each [[function.triggers.cron]] entry needs a `name`: it is required " +
|
|
157
|
+
"because it is half of the trigger's key, `<functionKey>:<name>`");
|
|
158
|
+
}
|
|
159
|
+
if (!CRON_NAME_PATTERN.test(name)) {
|
|
160
|
+
throw new TriggerDeclarationError(`cron trigger name '${name}' must start with a letter or digit and ` +
|
|
161
|
+
"contain only letters, digits, '-' or '_'");
|
|
162
|
+
}
|
|
163
|
+
if (seen.has(name)) {
|
|
164
|
+
throw new TriggerDeclarationError(`duplicate cron trigger name '${name}': names are the trigger's key ` +
|
|
165
|
+
"within the function, so each must appear once");
|
|
166
|
+
}
|
|
167
|
+
seen.add(name);
|
|
168
|
+
const cron = String(table.cron ?? "").trim();
|
|
169
|
+
if (!cron) {
|
|
170
|
+
throw new TriggerDeclarationError(`cron trigger '${name}' needs a \`cron\` expression`);
|
|
171
|
+
}
|
|
172
|
+
// Shape only. The full grammar is the server's `parseCron` — the CLI
|
|
173
|
+
// refuses the mistake that is obvious from the text and leaves the
|
|
174
|
+
// authority where the DO's own parser is.
|
|
175
|
+
if (cron.trim().split(/\s+/).length !== 5) {
|
|
176
|
+
throw new TriggerDeclarationError(`cron trigger '${name}': a cron expression has exactly 5 fields, and ` +
|
|
177
|
+
`'${cron}' has ${cron.trim().split(/\s+/).length}`);
|
|
178
|
+
}
|
|
179
|
+
const declaration = { name, cron };
|
|
180
|
+
if (table.timezone !== undefined) {
|
|
181
|
+
declaration.timezone = String(table.timezone);
|
|
182
|
+
}
|
|
183
|
+
if (table.overlapPolicy !== undefined) {
|
|
184
|
+
const policy = String(table.overlapPolicy);
|
|
185
|
+
if (!VALID_OVERLAP_POLICIES.includes(policy)) {
|
|
186
|
+
throw new TriggerDeclarationError(`cron trigger '${name}': overlapPolicy must be one of ` +
|
|
187
|
+
VALID_OVERLAP_POLICIES.join(", "));
|
|
188
|
+
}
|
|
189
|
+
declaration.overlapPolicy = policy;
|
|
190
|
+
}
|
|
191
|
+
if (table.rootInput !== undefined) {
|
|
192
|
+
declaration.rootInput = jsonSafe(table.rootInput);
|
|
193
|
+
}
|
|
194
|
+
normalized.push(declaration);
|
|
195
|
+
}
|
|
196
|
+
// Sorted by name, matching the server, so `config diff` compares the same
|
|
197
|
+
// canonical shape whichever order the file lists its entries in.
|
|
198
|
+
normalized.sort((a, b) => a.name.localeCompare(b.name));
|
|
199
|
+
return normalized;
|
|
200
|
+
}
|
|
201
|
+
function jsonSafe(value) {
|
|
202
|
+
if (value === null || value === undefined)
|
|
203
|
+
return value;
|
|
204
|
+
if (typeof value === "bigint")
|
|
205
|
+
return Number(value);
|
|
206
|
+
if (value instanceof Date)
|
|
207
|
+
return value.toISOString();
|
|
208
|
+
if (Array.isArray(value))
|
|
209
|
+
return value.map(jsonSafe);
|
|
210
|
+
if (typeof value === "object") {
|
|
211
|
+
const anyValue = value;
|
|
212
|
+
if (typeof anyValue.toISOString === "function") {
|
|
213
|
+
return String(anyValue.toISOString());
|
|
214
|
+
}
|
|
215
|
+
const out = {};
|
|
216
|
+
for (const [key, child] of Object.entries(anyValue)) {
|
|
217
|
+
out[key] = jsonSafe(child);
|
|
218
|
+
}
|
|
219
|
+
return out;
|
|
220
|
+
}
|
|
221
|
+
return value;
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=function-triggers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"function-triggers.js","sourceRoot":"","sources":["../../../src/lib/function-triggers.ts"],"names":[],"mappings":"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"}
|
|
@@ -645,6 +645,7 @@ export declare const METADATA_CATEGORY_CONFIG_SURFACE: ConfigObjectSurface;
|
|
|
645
645
|
* exists to end.
|
|
646
646
|
*/
|
|
647
647
|
export declare const TRANSFORM_SURFACE: ConfigObjectSurface;
|
|
648
|
+
export declare const SERVER_FUNCTION_SURFACE: ConfigObjectSurface;
|
|
648
649
|
export declare const TEST_CASE_SURFACE: ConfigObjectSurface;
|
|
649
650
|
export declare const APP_SETTINGS_SURFACE: ConfigObjectSurface;
|
|
650
651
|
/**
|
|
@@ -774,6 +774,24 @@ export const RETIRED_CONFIG_KEYS = {
|
|
|
774
774
|
"`primitive webhooks archive` to retire the webhook (#2907).",
|
|
775
775
|
},
|
|
776
776
|
},
|
|
777
|
+
// #3179 — server functions are the SIXTH status-carrying type, and they take
|
|
778
|
+
// the rule at birth rather than inheriting it: a function's whole point is
|
|
779
|
+
// that it runs code on request, so a `config push` that re-enabled a function
|
|
780
|
+
// an operator had disabled would put that code back on a public endpoint as a
|
|
781
|
+
// side effect of a code change.
|
|
782
|
+
function: {
|
|
783
|
+
status: {
|
|
784
|
+
toml: "`status` is no longer authored in TOML (#2803). Availability is " +
|
|
785
|
+
"server-owned: use `primitive functions enable|disable`. Retiring the " +
|
|
786
|
+
"function is `primitive functions archive` (#2907) — the archived row " +
|
|
787
|
+
"keeps its key in the app's single key namespace. Delete the line and " +
|
|
788
|
+
"push again; pushing new code to a disabled function is allowed and " +
|
|
789
|
+
"leaves it out of service.",
|
|
790
|
+
request: "`status` is server-owned (#2803). Use " +
|
|
791
|
+
"`primitive functions enable|disable` to change availability, or " +
|
|
792
|
+
"`primitive functions archive` to retire the function (#2907).",
|
|
793
|
+
},
|
|
794
|
+
},
|
|
777
795
|
// #2803 — availability is one server-owned `status`. As a TOML key it made
|
|
778
796
|
// `config push` a second writer: pushing a file pulled before an operator ran
|
|
779
797
|
// `workflows disable` put the workflow back in service as a side effect.
|
|
@@ -1301,13 +1319,23 @@ export const PROMPT_SURFACE = {
|
|
|
1301
1319
|
// server still runs. Update-only: create hard-codes "active" and
|
|
1302
1320
|
// ignores a supplied status, same statement `writableOn` makes for
|
|
1303
1321
|
// every create-assigned field.
|
|
1322
|
+
//
|
|
1323
|
+
// #3201 — emitted only when it is NOT the create default, so a pulled
|
|
1324
|
+
// file says `status = "archived"` about a retired config and says
|
|
1325
|
+
// nothing about the rest. `active` was information-free and actively
|
|
1326
|
+
// misleading: a prompt's OBJECT-level availability is the server-owned
|
|
1327
|
+
// `status` that left TOML at #2803, and a `status = "active"` line in
|
|
1328
|
+
// the file reads exactly like it. `serverDefault` is what makes the
|
|
1329
|
+
// omission lossless — push sends it for an absent key and `config
|
|
1330
|
+
// diff` reads both spellings as one value.
|
|
1304
1331
|
{
|
|
1305
1332
|
field: "status",
|
|
1306
1333
|
tomlKey: "status",
|
|
1307
1334
|
type: "string",
|
|
1308
|
-
emit: "
|
|
1335
|
+
emit: "whenSet",
|
|
1309
1336
|
writableOn: UPDATE_ONLY,
|
|
1310
1337
|
validation: handledBy(PROMPT_HANDLER, "AdminAPI"),
|
|
1338
|
+
serverDefault: "active",
|
|
1311
1339
|
},
|
|
1312
1340
|
{
|
|
1313
1341
|
field: "description",
|
|
@@ -1774,6 +1802,25 @@ export const WEBHOOK_SURFACE = {
|
|
|
1774
1802
|
kind: "server-owned",
|
|
1775
1803
|
note: "ULID assigned on create; never author-authored.",
|
|
1776
1804
|
},
|
|
1805
|
+
// #3181 — the two fields a FUNCTION-owned row carries. Neither is ever
|
|
1806
|
+
// authored on a `[webhook]` table: a function declares its trigger in
|
|
1807
|
+
// its own `functions/<key>.toml`, and this file's whole surface is the
|
|
1808
|
+
// standalone object. A hidden row is written only by
|
|
1809
|
+
// `function-trigger-reconcile.ts`.
|
|
1810
|
+
functionId: {
|
|
1811
|
+
kind: "server-owned",
|
|
1812
|
+
note: "The server function whose config owns this row (#3181). Set only " +
|
|
1813
|
+
"by the trigger reconcile; a standalone webhook never has one, and " +
|
|
1814
|
+
"its presence is what every hiding filter branches on.",
|
|
1815
|
+
},
|
|
1816
|
+
declaredSigningSecret: {
|
|
1817
|
+
kind: "secret",
|
|
1818
|
+
note: "The authored `{{secrets.KEY}}` reference the last function-trigger " +
|
|
1819
|
+
"reconcile applied (#3181, D3181-004). Server-owned bookkeeping " +
|
|
1820
|
+
"that makes an operational `rotate-secret` survive later pushes: " +
|
|
1821
|
+
"the secret fields move only when THIS marker and the authored " +
|
|
1822
|
+
"value disagree. Never authored, and never on a standalone row.",
|
|
1823
|
+
},
|
|
1777
1824
|
// #2803 — availability is server-owned. As a `[webhook]` key it made
|
|
1778
1825
|
// `config push` a second writer: a file pulled before an operator
|
|
1779
1826
|
// paused the webhook put the endpoint back in service on the next
|
|
@@ -1999,6 +2046,15 @@ export const CRON_TRIGGER_SURFACE = {
|
|
|
1999
2046
|
},
|
|
2000
2047
|
],
|
|
2001
2048
|
notExposed: {
|
|
2049
|
+
// #3181 — a function-declared cron entry creates a hidden row keyed
|
|
2050
|
+
// `<functionKey>:<name>`, and this is the discriminator every standalone
|
|
2051
|
+
// surface hides on. Never authored on a `[cronTrigger]` table: the
|
|
2052
|
+
// declaration lives in the function's own file.
|
|
2053
|
+
functionId: {
|
|
2054
|
+
kind: "server-owned",
|
|
2055
|
+
note: "The server function whose config owns this row (#3181). Written " +
|
|
2056
|
+
"only by the trigger reconcile; a standalone trigger never has one.",
|
|
2057
|
+
},
|
|
2002
2058
|
// #2803 — the ONE availability control, server-owned. Written only by
|
|
2003
2059
|
// `cron-triggers enable|disable`, the delete flow (the `archived`
|
|
2004
2060
|
// tombstone) and the alarm's error-pause path. `server-owned` keeps it
|
|
@@ -3093,6 +3149,194 @@ export const TRANSFORM_SURFACE = {
|
|
|
3093
3149
|
"(`transforms/<name>.tests/`) are the separate `test-case` surface.",
|
|
3094
3150
|
},
|
|
3095
3151
|
};
|
|
3152
|
+
// ── src/config-surface/server-function.ts ────────────────────────────────
|
|
3153
|
+
/**
|
|
3154
|
+
* The `function` configuration object's definition (#3179, project
|
|
3155
|
+
* `server-functions`).
|
|
3156
|
+
*
|
|
3157
|
+
* `functions/<key>.toml` carries a single `[function]` table, and the TypeScript
|
|
3158
|
+
* the function runs lives beside it in the same tree — the file names its
|
|
3159
|
+
* `entry` and `config push` builds the bundle from there.
|
|
3160
|
+
*
|
|
3161
|
+
* ── One table, two models ────────────────────────────────────────────────
|
|
3162
|
+
*
|
|
3163
|
+
* The authored surface spans the header (`ServerFunction`) and the immutable
|
|
3164
|
+
* config version (`ServerFunctionConfig`), but it is ONE table in the file: an
|
|
3165
|
+
* author does not write a version, they write a function and push it. The
|
|
3166
|
+
* definition therefore declares the header's field surface and lists the
|
|
3167
|
+
* version-carried keys (`entry`, `durable`, `limits`) in `tomlOnlyKeys` beside
|
|
3168
|
+
* `key` — they are authored, they are not fields of the header model, and they
|
|
3169
|
+
* travel on the config-version route rather than in the header body. Declaring
|
|
3170
|
+
* a second table over `ServerFunctionConfig` at the same `tomlPath` is not
|
|
3171
|
+
* possible (a table is addressed by its path) and would in any case claim the
|
|
3172
|
+
* version is a table an author writes, which is exactly what F-002 removed.
|
|
3173
|
+
*
|
|
3174
|
+
* ── The phase-1 key set is narrower than the models ──────────────────────
|
|
3175
|
+
*
|
|
3176
|
+
* `capabilities` (#3182/#3183) is declared on the models now so that child
|
|
3177
|
+
* touches only the surface, and is deliberately NOT accepted here: a file
|
|
3178
|
+
* carrying it today is rejected as an unknown key rather than accepted and
|
|
3179
|
+
* dropped, which is the silent-200 failure the whole registry exists to end.
|
|
3180
|
+
*
|
|
3181
|
+
* The trigger blocks joined the accepted set with #3181. They are `structural`
|
|
3182
|
+
* for the same reason `entry` is: they are authored, they are not fields of
|
|
3183
|
+
* the header model, and they travel inside the version envelope's TOML bytes
|
|
3184
|
+
* rather than as a payload field of their own.
|
|
3185
|
+
*
|
|
3186
|
+
* ── `status` ─────────────────────────────────────────────────────────────
|
|
3187
|
+
*
|
|
3188
|
+
* A server function is the SIXTH status-carrying type. `status` is server-owned
|
|
3189
|
+
* (#2803): only creation initializes it, the verbs are the only writers, and a
|
|
3190
|
+
* push to a disabled function takes the code without putting it back in
|
|
3191
|
+
* service. Its retired-key guidance lives in `retired-keys.ts` under this
|
|
3192
|
+
* table's prefix.
|
|
3193
|
+
*/
|
|
3194
|
+
const FUNCTION_HANDLER = "src/admin-api/controllers/server-functions-controller.ts";
|
|
3195
|
+
export const SERVER_FUNCTION_SURFACE = {
|
|
3196
|
+
label: "function",
|
|
3197
|
+
tables: [
|
|
3198
|
+
{
|
|
3199
|
+
tomlPath: ["function"],
|
|
3200
|
+
repeated: false,
|
|
3201
|
+
model: "ServerFunction",
|
|
3202
|
+
fields: [
|
|
3203
|
+
{
|
|
3204
|
+
field: "description",
|
|
3205
|
+
tomlKey: "description",
|
|
3206
|
+
type: "string",
|
|
3207
|
+
emit: "whenSet",
|
|
3208
|
+
writableOn: BOTH,
|
|
3209
|
+
validation: "passthrough",
|
|
3210
|
+
},
|
|
3211
|
+
{
|
|
3212
|
+
field: "runAs",
|
|
3213
|
+
tomlKey: "runAs",
|
|
3214
|
+
type: "string",
|
|
3215
|
+
emit: "always",
|
|
3216
|
+
writableOn: BOTH,
|
|
3217
|
+
// `caller | system` — the identity the function's own API calls run
|
|
3218
|
+
// as (the intent, "Who may invoke a function, and as whom?").
|
|
3219
|
+
validation: handledBy(FUNCTION_HANDLER, "ServerFunctionsController"),
|
|
3220
|
+
},
|
|
3221
|
+
{
|
|
3222
|
+
field: "access",
|
|
3223
|
+
tomlKey: "access",
|
|
3224
|
+
type: "string",
|
|
3225
|
+
emit: "always",
|
|
3226
|
+
writableOn: BOTH,
|
|
3227
|
+
// A CEL expression, and REQUIRED before code can be pushed: a
|
|
3228
|
+
// function with no gate fails closed at invoke, so accepting a bundle
|
|
3229
|
+
// for one would report a successful push of something that can never
|
|
3230
|
+
// run.
|
|
3231
|
+
validation: handledBy(FUNCTION_HANDLER, "ServerFunctionsController"),
|
|
3232
|
+
},
|
|
3233
|
+
{
|
|
3234
|
+
field: "inputSchema",
|
|
3235
|
+
tomlKey: "inputSchema",
|
|
3236
|
+
type: "json",
|
|
3237
|
+
emit: "whenSet",
|
|
3238
|
+
writableOn: BOTH,
|
|
3239
|
+
validation: handledBy(FUNCTION_HANDLER, "ServerFunctionsController"),
|
|
3240
|
+
},
|
|
3241
|
+
{
|
|
3242
|
+
field: "outputSchema",
|
|
3243
|
+
tomlKey: "outputSchema",
|
|
3244
|
+
type: "json",
|
|
3245
|
+
emit: "whenSet",
|
|
3246
|
+
writableOn: BOTH,
|
|
3247
|
+
validation: handledBy(FUNCTION_HANDLER, "ServerFunctionsController"),
|
|
3248
|
+
},
|
|
3249
|
+
],
|
|
3250
|
+
notExposed: {
|
|
3251
|
+
functionId: {
|
|
3252
|
+
kind: "server-owned",
|
|
3253
|
+
note: "ULID assigned on create; never author-authored.",
|
|
3254
|
+
},
|
|
3255
|
+
appId: {
|
|
3256
|
+
kind: "server-owned",
|
|
3257
|
+
note: "Tenant scope, taken from the route; never on the wire.",
|
|
3258
|
+
},
|
|
3259
|
+
functionKey: {
|
|
3260
|
+
kind: "structural",
|
|
3261
|
+
// Create carries it in the body; update does not — the key is the
|
|
3262
|
+
// function's identity in the single per-app key namespace, and the
|
|
3263
|
+
// URL already names the row.
|
|
3264
|
+
requestModes: ["create"],
|
|
3265
|
+
note: "The function's identity, and its claim on the app's single key " +
|
|
3266
|
+
"namespace (workflows, functions, scripts and webhooks share it). " +
|
|
3267
|
+
"Comes from the TOML file name and is attached by the caller; its " +
|
|
3268
|
+
"TOML spelling is declared in tomlOnlyKeys as `key`.",
|
|
3269
|
+
},
|
|
3270
|
+
status: {
|
|
3271
|
+
kind: "server-owned",
|
|
3272
|
+
note: "#2803 — availability is server-owned on all six carrying types. " +
|
|
3273
|
+
"Only creation initializes `active`; `primitive functions " +
|
|
3274
|
+
"enable|disable` and `archive` are the only writers, so a push to " +
|
|
3275
|
+
"a disabled function takes the code and stays out of service.",
|
|
3276
|
+
},
|
|
3277
|
+
activeConfigId: {
|
|
3278
|
+
kind: "server-owned",
|
|
3279
|
+
note: "Points at the immutable ServerFunctionConfig the function runs. " +
|
|
3280
|
+
"Repointed by a config-version push; versions are nameless, so " +
|
|
3281
|
+
"there is no `activeConfigName` for an author to write.",
|
|
3282
|
+
},
|
|
3283
|
+
createdBy: {
|
|
3284
|
+
kind: "server-owned",
|
|
3285
|
+
note: "Admin who created the function; assigned server-side.",
|
|
3286
|
+
},
|
|
3287
|
+
createdAt: {
|
|
3288
|
+
kind: "server-owned",
|
|
3289
|
+
note: "Timestamp, assigned server-side.",
|
|
3290
|
+
},
|
|
3291
|
+
modifiedAt: {
|
|
3292
|
+
kind: "server-owned",
|
|
3293
|
+
note: "Timestamp, assigned server-side.",
|
|
3294
|
+
},
|
|
3295
|
+
},
|
|
3296
|
+
tomlOnlyKeys: {
|
|
3297
|
+
key: {
|
|
3298
|
+
kind: "structural",
|
|
3299
|
+
note: "The function key. `config pull` writes it for readability; push " +
|
|
3300
|
+
"takes the identity from the file name and attaches `functionKey` " +
|
|
3301
|
+
"itself.",
|
|
3302
|
+
},
|
|
3303
|
+
entry: {
|
|
3304
|
+
kind: "structural",
|
|
3305
|
+
note: "The TypeScript entry point, relative to the config tree root. A " +
|
|
3306
|
+
"field of the immutable ServerFunctionConfig, not of the header: " +
|
|
3307
|
+
"it travels on the config-version push together with the built " +
|
|
3308
|
+
"bundle and the authored sources.",
|
|
3309
|
+
},
|
|
3310
|
+
durable: {
|
|
3311
|
+
kind: "structural",
|
|
3312
|
+
note: "Whether this version runs durably (#3186). Stored on the config " +
|
|
3313
|
+
"version and pushed with it, so it is versioned with the code it " +
|
|
3314
|
+
"describes rather than mutable on the header.",
|
|
3315
|
+
},
|
|
3316
|
+
limits: {
|
|
3317
|
+
kind: "structural",
|
|
3318
|
+
note: "`[function.limits]` — per-version ceilings, stored as JSON on the " +
|
|
3319
|
+
"config version. Free-form inside the table (the server validates " +
|
|
3320
|
+
"the members it knows), and pushed with the version.",
|
|
3321
|
+
},
|
|
3322
|
+
triggers: {
|
|
3323
|
+
kind: "structural",
|
|
3324
|
+
note: "`[function.triggers.webhook]` and `[[function.triggers.cron]]` " +
|
|
3325
|
+
"(#3181) — what fires this function besides an HTTP call. " +
|
|
3326
|
+
"Validated by dedicated code on both sides, and carried by NO " +
|
|
3327
|
+
"payload field: the server derives the declaration from the " +
|
|
3328
|
+
"authored TOML bytes inside the version envelope, so trigger " +
|
|
3329
|
+
"behavior is covered by `envelopeHash` and cannot disagree with " +
|
|
3330
|
+
"the file even for a direct API caller (D3181-005).",
|
|
3331
|
+
},
|
|
3332
|
+
},
|
|
3333
|
+
responseOnlyKeys: {},
|
|
3334
|
+
},
|
|
3335
|
+
],
|
|
3336
|
+
// The file is the `[function]` table and nothing else. The function's code is
|
|
3337
|
+
// in the source files `entry` reaches, not in a TOML table.
|
|
3338
|
+
tomlDocumentKeys: {},
|
|
3339
|
+
};
|
|
3096
3340
|
// ── src/config-surface/test-case.ts ──────────────────────────────────────
|
|
3097
3341
|
/**
|
|
3098
3342
|
* The `test-case` configuration object's definition (issue #2644, phase 3).
|
|
@@ -3419,6 +3663,20 @@ export const APP_SETTINGS_SURFACE = {
|
|
|
3419
3663
|
// `validateTestAccountBaseEmails`.
|
|
3420
3664
|
validation: handledBy(SETTINGS_HANDLER, "SettingsController"),
|
|
3421
3665
|
},
|
|
3666
|
+
{
|
|
3667
|
+
field: "largeDocumentWindowDays",
|
|
3668
|
+
tomlKey: "largeDocumentWindowDays",
|
|
3669
|
+
type: "number",
|
|
3670
|
+
// Whenever the app set one. An app on the deployment's window must
|
|
3671
|
+
// not grow a key that pins it to whatever that window is today
|
|
3672
|
+
// (#2816).
|
|
3673
|
+
emit: "whenSet",
|
|
3674
|
+
writableOn: UPDATE_ONLY,
|
|
3675
|
+
// Refused rather than clamped: answering 200 to a 30-day window the
|
|
3676
|
+
// server does not keep would have the caller plan a month of
|
|
3677
|
+
// offline work around it (`parseLargeDocumentWindowSetting`).
|
|
3678
|
+
validation: handledBy(SETTINGS_HANDLER, "SettingsController"),
|
|
3679
|
+
},
|
|
3422
3680
|
],
|
|
3423
3681
|
notExposed: {
|
|
3424
3682
|
appId: {
|
|
@@ -3756,6 +4014,7 @@ export const CONFIG_SURFACES = [
|
|
|
3756
4014
|
COLLECTION_TYPE_CONFIG_SURFACE,
|
|
3757
4015
|
METADATA_CATEGORY_CONFIG_SURFACE,
|
|
3758
4016
|
TRANSFORM_SURFACE,
|
|
4017
|
+
SERVER_FUNCTION_SURFACE,
|
|
3759
4018
|
TEST_CASE_SURFACE,
|
|
3760
4019
|
APP_SETTINGS_SURFACE,
|
|
3761
4020
|
];
|
|
@@ -3825,6 +4084,7 @@ export const GENERATED_CONFIG_MODEL_FIELDS = {
|
|
|
3825
4084
|
"directLlmEnabled",
|
|
3826
4085
|
"memberInvitationsEnabled",
|
|
3827
4086
|
"memberInvitationLimit",
|
|
4087
|
+
"largeDocumentWindowDays",
|
|
3828
4088
|
"createdAt",
|
|
3829
4089
|
"modifiedAt",
|
|
3830
4090
|
],
|
|
@@ -3900,6 +4160,8 @@ export const GENERATED_CONFIG_MODEL_FIELDS = {
|
|
|
3900
4160
|
"signingSecret",
|
|
3901
4161
|
"previousSigningSecret",
|
|
3902
4162
|
"secretRotatedAt",
|
|
4163
|
+
"functionId",
|
|
4164
|
+
"declaredSigningSecret",
|
|
3903
4165
|
"secretGracePeriodMs",
|
|
3904
4166
|
"toleranceSeconds",
|
|
3905
4167
|
"deduplicationEnabled",
|
|
@@ -3969,6 +4231,7 @@ export const GENERATED_CONFIG_MODEL_FIELDS = {
|
|
|
3969
4231
|
"cron",
|
|
3970
4232
|
"timezone",
|
|
3971
4233
|
"workflowKey",
|
|
4234
|
+
"functionId",
|
|
3972
4235
|
"overlapPolicy",
|
|
3973
4236
|
"rootInput",
|
|
3974
4237
|
"inputMapping",
|
|
@@ -4039,6 +4302,21 @@ export const GENERATED_CONFIG_MODEL_FIELDS = {
|
|
|
4039
4302
|
"modifiedAt",
|
|
4040
4303
|
"createdBy",
|
|
4041
4304
|
],
|
|
4305
|
+
"ServerFunction": [
|
|
4306
|
+
"functionId",
|
|
4307
|
+
"appId",
|
|
4308
|
+
"functionKey",
|
|
4309
|
+
"description",
|
|
4310
|
+
"status",
|
|
4311
|
+
"activeConfigId",
|
|
4312
|
+
"runAs",
|
|
4313
|
+
"access",
|
|
4314
|
+
"inputSchema",
|
|
4315
|
+
"outputSchema",
|
|
4316
|
+
"createdBy",
|
|
4317
|
+
"createdAt",
|
|
4318
|
+
"modifiedAt",
|
|
4319
|
+
],
|
|
4042
4320
|
"WorkflowDefinition": [
|
|
4043
4321
|
"workflowId",
|
|
4044
4322
|
"appId",
|