primitive-admin 1.1.0-alpha.82 → 1.1.0-alpha.83
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/dist/src/commands/documents.js +333 -42
- package/dist/src/commands/documents.js.map +1 -1
- package/dist/src/commands/functions.js +302 -120
- package/dist/src/commands/functions.js.map +1 -1
- package/dist/src/commands/locks.js +15 -1
- package/dist/src/commands/locks.js.map +1 -1
- package/dist/src/commands/sync.d.ts +50 -0
- package/dist/src/commands/sync.js +560 -312
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/lib/api-client.d.ts +75 -2
- package/dist/src/lib/api-client.js +122 -7
- package/dist/src/lib/api-client.js.map +1 -1
- package/dist/src/lib/config-object-descriptor.js +5 -5
- package/dist/src/lib/config-object-descriptor.js.map +1 -1
- package/dist/src/lib/document-ingest-artifact.d.ts +120 -0
- package/dist/src/lib/document-ingest-artifact.js +505 -0
- package/dist/src/lib/document-ingest-artifact.js.map +1 -0
- package/dist/src/lib/document-ingest-input.d.ts +51 -0
- package/dist/src/lib/document-ingest-input.js +132 -0
- package/dist/src/lib/document-ingest-input.js.map +1 -0
- package/dist/src/lib/document-ingest.d.ts +78 -0
- package/dist/src/lib/document-ingest.js +231 -0
- package/dist/src/lib/document-ingest.js.map +1 -0
- package/dist/src/lib/function-bundle.d.ts +6 -0
- package/dist/src/lib/function-bundle.js +8 -0
- package/dist/src/lib/function-bundle.js.map +1 -1
- package/dist/src/lib/function-collect.d.ts +1 -1
- package/dist/src/lib/function-collect.js +16 -0
- package/dist/src/lib/function-collect.js.map +1 -1
- package/dist/src/lib/function-db-types.d.ts +4 -0
- package/dist/src/lib/function-db-types.js +31 -2
- package/dist/src/lib/function-db-types.js.map +1 -1
- package/dist/src/lib/function-document-types.d.ts +83 -0
- package/dist/src/lib/function-document-types.js +133 -0
- package/dist/src/lib/function-document-types.js.map +1 -1
- package/dist/src/lib/function-grants-preflight.js +5 -0
- package/dist/src/lib/function-grants-preflight.js.map +1 -1
- package/dist/src/lib/function-log-lines.d.ts +76 -0
- package/dist/src/lib/function-log-lines.js +160 -0
- package/dist/src/lib/function-log-lines.js.map +1 -0
- package/dist/src/lib/function-log-row.d.ts +29 -0
- package/dist/src/lib/function-log-row.js +73 -0
- package/dist/src/lib/function-log-row.js.map +1 -0
- package/dist/src/lib/function-run.d.ts +53 -35
- package/dist/src/lib/function-run.js +55 -44
- package/dist/src/lib/function-run.js.map +1 -1
- package/dist/src/lib/function-schema-codegen.d.ts +6 -9
- package/dist/src/lib/function-schema-codegen.js +22 -35
- package/dist/src/lib/function-schema-codegen.js.map +1 -1
- package/dist/src/lib/function-sync.d.ts +226 -35
- package/dist/src/lib/function-sync.js +731 -99
- package/dist/src/lib/function-sync.js.map +1 -1
- package/dist/src/lib/function-versions.d.ts +122 -0
- package/dist/src/lib/function-versions.js +182 -0
- package/dist/src/lib/function-versions.js.map +1 -0
- package/dist/src/lib/generated-config-surfaces.d.ts +390 -146
- package/dist/src/lib/generated-config-surfaces.js +1207 -401
- package/dist/src/lib/generated-config-surfaces.js.map +1 -1
- package/dist/src/lib/generated-sdk-types.d.ts +1 -1
- package/dist/src/lib/generated-sdk-types.js +1 -1
- package/dist/src/lib/generated-sdk-types.js.map +1 -1
- package/dist/src/lib/log-inspection.d.ts +2 -0
- package/dist/src/lib/log-inspection.js +4 -0
- package/dist/src/lib/log-inspection.js.map +1 -1
- package/dist/src/lib/output.d.ts +15 -0
- package/dist/src/lib/output.js +28 -0
- package/dist/src/lib/output.js.map +1 -1
- package/dist/src/lib/snapshot-audit-source.d.ts +45 -0
- package/dist/src/lib/snapshot-audit-source.js +58 -0
- package/dist/src/lib/snapshot-audit-source.js.map +1 -0
- package/dist/src/lib/snapshot-audit-store.d.ts +52 -0
- package/dist/src/lib/snapshot-audit-store.js +196 -0
- package/dist/src/lib/snapshot-audit-store.js.map +1 -0
- package/dist/src/lib/snapshot-audit.d.ts +207 -0
- package/dist/src/lib/snapshot-audit.js +431 -0
- package/dist/src/lib/snapshot-audit.js.map +1 -0
- package/dist/src/lib/snapshot-build-rows.d.ts +60 -0
- package/dist/src/lib/snapshot-build-rows.js +87 -0
- package/dist/src/lib/snapshot-build-rows.js.map +1 -0
- package/dist/src/lib/swift-codegen/functionGenerator.d.ts +23 -16
- package/dist/src/lib/swift-codegen/functionGenerator.js +34 -33
- package/dist/src/lib/swift-codegen/functionGenerator.js.map +1 -1
- package/dist/src/lib/sync-selectors.d.ts +45 -2
- package/dist/src/lib/sync-selectors.js +66 -5
- package/dist/src/lib/sync-selectors.js.map +1 -1
- package/package.json +2 -2
|
@@ -110,9 +110,19 @@ export interface ConfigField {
|
|
|
110
110
|
* `"src/workflows/config/workflow-field-handlers.ts#normalizeWorkflowStatus"`.
|
|
111
111
|
* `cli/tests/unit/config-surface-drift-guard.test.ts` fails when the module or
|
|
112
112
|
* the export is missing (#2644 behavior 2b).
|
|
113
|
+
*
|
|
114
|
+
* `stage` says WHEN the handler runs, with exactly the meaning `RuleStage`
|
|
115
|
+
* gives a cross-field rule (#3375). Until this issue the slot named an owner
|
|
116
|
+
* and never said when, so intent criterion 5 — "a rule declared `preflight`
|
|
117
|
+
* is provably reached before the first mutating call" — could not cover a
|
|
118
|
+
* single-field rule at all. It is REQUIRED, so a new field handler cannot be
|
|
119
|
+
* declared without answering the question, and
|
|
120
|
+
* `findMalformedFieldValidationStages` closes the key set at
|
|
121
|
+
* `handler`/`stage`: the slot stays declarative like the field entry itself.
|
|
113
122
|
*/
|
|
114
123
|
validation: "passthrough" | {
|
|
115
124
|
handler: string;
|
|
125
|
+
stage: RuleStage;
|
|
116
126
|
};
|
|
117
127
|
/**
|
|
118
128
|
* This field's declared type genuinely admits more than one TOML spelling
|
|
@@ -207,7 +217,18 @@ export interface ConfigTable {
|
|
|
207
217
|
* CLI call exists would make the registry promise a refusal that in fact lands
|
|
208
218
|
* mid-apply.
|
|
209
219
|
*/
|
|
210
|
-
export type
|
|
220
|
+
export type RuleStage = "preflight" | "apply";
|
|
221
|
+
/**
|
|
222
|
+
* The cross-field spelling of `RuleStage`, kept as an exported alias.
|
|
223
|
+
*
|
|
224
|
+
* #3373 named the type for the only slot that had a stage. #3375 gave
|
|
225
|
+
* `ConfigField.validation` one too, with the same meaning, so the canonical
|
|
226
|
+
* name is the general one — and this alias stays because it is part of the
|
|
227
|
+
* registry's published surface (`CrossFieldRule.stage`, the guard, every
|
|
228
|
+
* `crossFieldRulesForStage` caller) and renaming it would be a breaking change
|
|
229
|
+
* to buy a shorter name.
|
|
230
|
+
*/
|
|
231
|
+
export type CrossFieldRuleStage = RuleStage;
|
|
211
232
|
/**
|
|
212
233
|
* One rule of a configuration object that spans more than one field — `durable
|
|
213
234
|
* = true` beside a webhook trigger, `runAs = "system"` beside a non-empty
|
|
@@ -337,8 +358,15 @@ export declare const UPDATE_ONLY: readonly ("create" | "update")[];
|
|
|
337
358
|
* the definition never dispatches through it (#1976 decision of record); the
|
|
338
359
|
* guard asserts the export exists so a renamed handler fails the CLI unit suite
|
|
339
360
|
* instead of leaving a dangling reference (#2644 behavior 2b).
|
|
361
|
+
*
|
|
362
|
+
* `stage` is REQUIRED (#3375): a field handler that does not say when it runs
|
|
363
|
+
* makes the same empty promise the cross-field slot made before #3373 — it
|
|
364
|
+
* names an owner, and criterion 5 has nothing to check. A `preflight` handler
|
|
365
|
+
* is reached from `cli/src/commands/sync.ts#runConfigPushPreflight` before the
|
|
366
|
+
* first mutating call, which `findUnreachedPreflightRules` proves statically;
|
|
367
|
+
* an `apply` handler is everything else.
|
|
340
368
|
*/
|
|
341
|
-
export declare function handledBy(modulePath: string, exportName: string): ConfigField["validation"];
|
|
369
|
+
export declare function handledBy(modulePath: string, exportName: string, stage: RuleStage): ConfigField["validation"];
|
|
342
370
|
/**
|
|
343
371
|
* Name the ONE export that enforces a cross-field rule, as
|
|
344
372
|
* `"<repo-relative module>#<export>"` — the sibling of `handledBy` for a rule
|
|
@@ -739,6 +767,115 @@ export declare function hasDeclaredCrossFieldRules(surface: ConfigObjectSurface)
|
|
|
739
767
|
* `[]`: "not declared yet" must never be read as "has no rules" (principle 6).
|
|
740
768
|
*/
|
|
741
769
|
export declare function crossFieldRulesForStage(surface: ConfigObjectSurface, stage: CrossFieldRuleStage): readonly CrossFieldRule[];
|
|
770
|
+
/**
|
|
771
|
+
* Is a rule declared `preflight` actually reached before `config push` mutates
|
|
772
|
+
* anything? (issue #3375, project phase 3, intent §Success criteria 5.)
|
|
773
|
+
*
|
|
774
|
+
* #3373 gave a rule a `stage`; #3374 declared three surfaces' rules. Both left
|
|
775
|
+
* the string a PROMISE. "This runs before the first mutating call" was
|
|
776
|
+
* satisfied by typing `preflight` beside a rule that is not on the preflight
|
|
777
|
+
* path at all, because the push preflight was an inline block inside the
|
|
778
|
+
* command's `.action()` callback with no exported symbol — so "reached from the
|
|
779
|
+
* preflight" had nothing to resolve against.
|
|
780
|
+
*
|
|
781
|
+
* #3375 extracts that block into `cli/src/commands/sync.ts#runConfigPushPreflight`
|
|
782
|
+
* and this module answers the question statically, from the declared
|
|
783
|
+
* `<module>#<export>`:
|
|
784
|
+
*
|
|
785
|
+
* - `reachableExports` walks the call graph from one entry symbol over module
|
|
786
|
+
* SOURCE TEXT and returns what it reached — plus what it could NOT resolve,
|
|
787
|
+
* so silence is never a pass.
|
|
788
|
+
* - `findUnreachedPreflightRules` reports every `preflight` declaration,
|
|
789
|
+
* cross-field or single-field, whose handler is missing from that set.
|
|
790
|
+
* - `findMalformedFieldValidationStages` is the field-level twin of #3373's
|
|
791
|
+
* `findMalformedRuleDeclarations`: `ConfigField["validation"]` gained a
|
|
792
|
+
* `stage` here, and it must be well-formed to mean anything.
|
|
793
|
+
*
|
|
794
|
+
* Everything is a PURE function over values and over source text the caller
|
|
795
|
+
* passes in: `cli/tests/unit/config-surface-preflight-staging-3375.test.ts`
|
|
796
|
+
* does the filesystem walk, so this module stays vendorable (`types.ts`
|
|
797
|
+
* §Purity), exactly the split `rules.ts` already uses.
|
|
798
|
+
*
|
|
799
|
+
* ── Two things this check is NOT ──────────────────────────────────────────
|
|
800
|
+
*
|
|
801
|
+
* It is NECESSARY, not sufficient, and there is deliberately no converse. A
|
|
802
|
+
* handler reached on one surface's leg satisfies a `preflight` declaration on
|
|
803
|
+
* another (the residual the intent accepts and #3379 records), and asking "is
|
|
804
|
+
* this `apply` rule reached from the preflight?" would be wrong by
|
|
805
|
+
* construction: `validateSigningSecretDeclaration` IS reached on the function
|
|
806
|
+
* leg and IS correctly `apply` on the webhook surface, where no CLI call
|
|
807
|
+
* exists.
|
|
808
|
+
*
|
|
809
|
+
* The walk is identifier-based over masked source, so it over-approximates in
|
|
810
|
+
* the PASSING direction: a local variable shadowing an imported handler's name
|
|
811
|
+
* reads as a call. That is the safe direction for a guard whose failure mode
|
|
812
|
+
* must be "a promise you did not keep", not "a promise you did keep, reported
|
|
813
|
+
* as broken".
|
|
814
|
+
*/
|
|
815
|
+
/** A field's `validation` object may carry these keys and no others (#3375). */
|
|
816
|
+
export declare const FIELD_VALIDATION_KEYS: readonly string[];
|
|
817
|
+
/**
|
|
818
|
+
* The modules a walk may read, and how a specifier resolves between them.
|
|
819
|
+
*
|
|
820
|
+
* The caller owns resolution because it owns the filesystem: the CLI test maps
|
|
821
|
+
* both spellings of the vendored artifact onto the `src/config-surface/`
|
|
822
|
+
* modules it is a copy of, which is the whole point of DSO-3375-002 — the
|
|
823
|
+
* generator strips every intra-directory import before concatenating, so the
|
|
824
|
+
* artifact itself carries no edges between its sections.
|
|
825
|
+
*/
|
|
826
|
+
export interface StaticModuleGraph {
|
|
827
|
+
/** Repo-relative module path → that module's SOURCE TEXT. */
|
|
828
|
+
modules: ReadonlyMap<string, string>;
|
|
829
|
+
/**
|
|
830
|
+
* Candidate modules a specifier names, seen from `fromModule`.
|
|
831
|
+
*
|
|
832
|
+
* `null` = a bare package specifier: deliberately not followed, and never
|
|
833
|
+
* reported. `[]` = a relative specifier that resolves to no module in the
|
|
834
|
+
* graph, which IS reported — a guard that silently stops looking is worse
|
|
835
|
+
* than no guard.
|
|
836
|
+
*/
|
|
837
|
+
resolve(fromModule: string, specifier: string): readonly string[] | null;
|
|
838
|
+
}
|
|
839
|
+
/** What one walk found, and what it could not resolve on the way. */
|
|
840
|
+
export interface ReachabilityWalk {
|
|
841
|
+
/** `<module>#<export>` for every symbol reached, module = where it is DECLARED. */
|
|
842
|
+
reached: ReadonlySet<string>;
|
|
843
|
+
/** Specifiers and entry symbols the graph could not answer for, sorted. */
|
|
844
|
+
unresolved: string[];
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* Walk the call graph from `entry` and return every symbol it reaches.
|
|
848
|
+
*
|
|
849
|
+
* An identifier inside a reached declaration's span is followed when it names
|
|
850
|
+
* another top-level declaration of the same module, or a value import — which
|
|
851
|
+
* resolves through the graph to whichever candidate module DECLARES the name,
|
|
852
|
+
* following `export { x } from` and `export * from` on the way. A symbol is
|
|
853
|
+
* recorded under the module that declares it, never under a barrel that merely
|
|
854
|
+
* re-exports it: a declaration that names the barrel is reported unreached,
|
|
855
|
+
* because the point of the string is to name the one implementation.
|
|
856
|
+
*/
|
|
857
|
+
export declare function reachableExports(entry: string, graph: StaticModuleGraph): ReachabilityWalk;
|
|
858
|
+
/**
|
|
859
|
+
* Every fault in one surface's FIELD validation declarations, each naming the
|
|
860
|
+
* surface and the field. `[]` means every field is well-formed.
|
|
861
|
+
*
|
|
862
|
+
* Runs over every surface in the registry, migrated or not: field declarations
|
|
863
|
+
* exist independently of the cross-field slot, so the
|
|
864
|
+
* `CROSS_FIELD_RULES_UNMIGRATED` ratchet does not — and must not — stand
|
|
865
|
+
* between a field-level `preflight` declaration and this check (DSO-3375-001).
|
|
866
|
+
*/
|
|
867
|
+
export declare function findMalformedFieldValidationStages(surface: ConfigObjectSurface): string[];
|
|
868
|
+
/**
|
|
869
|
+
* Every `preflight` declaration on this surface whose handler the walk did not
|
|
870
|
+
* reach, each naming the surface, the rule (or field), the handler and the
|
|
871
|
+
* entry point.
|
|
872
|
+
*
|
|
873
|
+
* The FIELD half runs on every surface. The CROSS-FIELD half runs only where a
|
|
874
|
+
* surface has declared, because `crossFieldRulesForStage` throws for one that
|
|
875
|
+
* has not — "not declared yet" is never "rule-free" (#3373), and asking it
|
|
876
|
+
* here would turn an unmigrated surface into a crash rather than a skip.
|
|
877
|
+
*/
|
|
878
|
+
export declare function findUnreachedPreflightRules(surface: ConfigObjectSurface, reached: ReadonlySet<string>, entry: string): string[];
|
|
742
879
|
/**
|
|
743
880
|
* Request schemas generated from the configuration-object definitions
|
|
744
881
|
* (issue #2644, phase 5 / criterion 9).
|
|
@@ -1239,115 +1376,107 @@ export interface ParsedManifest {
|
|
|
1239
1376
|
*/
|
|
1240
1377
|
export declare function parseFunctionManifest(value: unknown): ParsedManifest;
|
|
1241
1378
|
/**
|
|
1242
|
-
* The
|
|
1243
|
-
* #
|
|
1244
|
-
*
|
|
1245
|
-
*
|
|
1246
|
-
*
|
|
1247
|
-
* function is a function
|
|
1248
|
-
*
|
|
1249
|
-
*
|
|
1250
|
-
*
|
|
1251
|
-
*
|
|
1252
|
-
*
|
|
1253
|
-
*
|
|
1254
|
-
*
|
|
1255
|
-
*
|
|
1256
|
-
*
|
|
1257
|
-
*
|
|
1258
|
-
*
|
|
1259
|
-
*
|
|
1260
|
-
*
|
|
1261
|
-
*
|
|
1262
|
-
*
|
|
1263
|
-
*
|
|
1264
|
-
*
|
|
1265
|
-
*
|
|
1266
|
-
*
|
|
1267
|
-
*
|
|
1268
|
-
*
|
|
1269
|
-
*
|
|
1270
|
-
*
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
* envelope's TOML, so it is `src/server-functions/legacy-mode.ts`'s job and
|
|
1278
|
-
* not this module's.
|
|
1279
|
-
*/
|
|
1280
|
-
export type FunctionMode = "request" | "task" | "any";
|
|
1281
|
-
/** The two runners a call may name. `any` is a version's mode, not a runner. */
|
|
1282
|
-
export type FunctionRunner = "request" | "task";
|
|
1283
|
-
export declare const FUNCTION_MODES: readonly FunctionMode[];
|
|
1284
|
-
/** The runners, for the doors where a caller states one (#3454, D3454-004). */
|
|
1285
|
-
export declare const FUNCTION_RUNNERS: readonly FunctionRunner[];
|
|
1286
|
-
/**
|
|
1287
|
-
* The rule ids this module owns, declared on the `function` surface (#3374).
|
|
1288
|
-
* The union below closes `refuseMode`'s id parameter: a fourth refusal cannot
|
|
1289
|
-
* compile without a fourth id, and a fourth id fails `cli-unit-tests` until the
|
|
1290
|
-
* surface declares it.
|
|
1291
|
-
*/
|
|
1292
|
-
export declare const FUNCTION_MODE_RULE_IDS: readonly ["mode-value", "durable-value", "mode-durable-agreement"];
|
|
1293
|
-
type FunctionModeRuleId = (typeof FUNCTION_MODE_RULE_IDS)[number];
|
|
1294
|
-
/** What a declaration resolved to, or why it could not. */
|
|
1295
|
-
export type DeclaredModeResolution = {
|
|
1296
|
-
ok: true;
|
|
1297
|
-
mode: FunctionMode;
|
|
1379
|
+
* The runtime keys a `functions/<key>.toml` no longer decides anything with —
|
|
1380
|
+
* #3482, project `server-functions` phase 4.
|
|
1381
|
+
*
|
|
1382
|
+
* The sponsor settled it on 2026-09-15 (the intent, "Mode vocabulary?",
|
|
1383
|
+
* amended again): the config says NOTHING about how a function runs. A
|
|
1384
|
+
* function is a function; the caller picks the runtime at each call, cron
|
|
1385
|
+
* fires always start a task run, webhook deliveries always run as a request,
|
|
1386
|
+
* and a function that must not run under one runtime tests for it in code with
|
|
1387
|
+
* `assertRuntime`.
|
|
1388
|
+
*
|
|
1389
|
+
* ── Why these keys are accepted, not refused ──────────────────────────────
|
|
1390
|
+
*
|
|
1391
|
+
* Every tree pushed since #3454 that declares a cron trigger carries
|
|
1392
|
+
* `mode = …` ON THE ENTRY, because `cron-trigger-mode-required` demanded it;
|
|
1393
|
+
* plenty carry a top-level `mode` or the older `durable`. Removing the keys
|
|
1394
|
+
* from the accepted set outright would refuse those trees with an unknown-key
|
|
1395
|
+
* error one day after the platform insisted on them, which is the opposite of
|
|
1396
|
+
* principle 5 inside a non-breaking phase.
|
|
1397
|
+
*
|
|
1398
|
+
* So through phase 4 they are ACCEPTED and IGNORED, with one warning per key
|
|
1399
|
+
* naming it and the line to delete; from phase 5 (#3188) they are refused with
|
|
1400
|
+
* the rest of the retirement matrix. The value is not validated — there is
|
|
1401
|
+
* nothing left to validate it against, and refusing a bad value for a key
|
|
1402
|
+
* nobody reads would be a refusal about spelling alone.
|
|
1403
|
+
*
|
|
1404
|
+
* Pure: no models, no tenant context, no `env` (see `types.ts` §Purity). Both
|
|
1405
|
+
* the CLI preflight (vendored by `cli/scripts/gen-config-surfaces.mjs`) and the
|
|
1406
|
+
* admin config-version route read this one scanner, so the warning an author
|
|
1407
|
+
* sees from `config push` is the sentence the API answers with.
|
|
1408
|
+
*/
|
|
1409
|
+
/** The two `[function]` keys that no longer say anything (#3482). */
|
|
1410
|
+
export declare const RETIRED_FUNCTION_RUNTIME_KEYS: readonly ["mode", "durable"];
|
|
1411
|
+
export type RetiredFunctionRuntimeKey = (typeof RETIRED_FUNCTION_RUNTIME_KEYS)[number];
|
|
1412
|
+
/** One ignored key met in a `[function]` table. */
|
|
1413
|
+
export interface IgnoredFunctionKey {
|
|
1298
1414
|
/**
|
|
1299
|
-
*
|
|
1300
|
-
*
|
|
1301
|
-
* reads
|
|
1415
|
+
* Where it was: `mode`, `durable`, or `triggers.cron.<name>.mode`. Never
|
|
1416
|
+
* rendered on its own — a reader that wants to branch reads this, and every
|
|
1417
|
+
* printer reads `message`.
|
|
1302
1418
|
*/
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
ruleId: FunctionModeRuleId;
|
|
1308
|
-
error: string;
|
|
1309
|
-
};
|
|
1419
|
+
path: string;
|
|
1420
|
+
/** The sentence the author is owed, with no file prefix (the caller adds it). */
|
|
1421
|
+
message: string;
|
|
1422
|
+
}
|
|
1310
1423
|
/**
|
|
1311
|
-
*
|
|
1424
|
+
* Every retired runtime key a `[function]` table still carries.
|
|
1425
|
+
*
|
|
1426
|
+
* Reads the table the way the author wrote it: the two top-level keys, and a
|
|
1427
|
+
* `mode` on each `[[function.triggers.cron]]` entry. A cron entry's sentence
|
|
1428
|
+
* says the extra thing its author needs to hear — that the schedule no longer
|
|
1429
|
+
* chooses, because every fire starts a task run (#3334's runner branch is
|
|
1430
|
+
* gone).
|
|
1312
1431
|
*
|
|
1313
|
-
*
|
|
1314
|
-
*
|
|
1315
|
-
* of the three words; `durable` must be a boolean. Both present and
|
|
1316
|
-
* disagreeing is refused naming both keys, so an author who half-migrated a
|
|
1317
|
-
* file hears which line to fix — and `durable` beside `mode = "any"` is one of
|
|
1318
|
-
* those disagreements, because a boolean cannot say "either".
|
|
1432
|
+
* Order is the order an author reads their file in: the top-level keys first,
|
|
1433
|
+
* then the cron entries in declaration order.
|
|
1319
1434
|
*/
|
|
1320
|
-
export declare function
|
|
1321
|
-
mode?: unknown;
|
|
1322
|
-
durable?: unknown;
|
|
1323
|
-
}): DeclaredModeResolution;
|
|
1435
|
+
export declare function ignoredFunctionKeys(functionTable: unknown): IgnoredFunctionKey[];
|
|
1324
1436
|
/**
|
|
1325
|
-
* The
|
|
1437
|
+
* The database types a `[function]` table's retired trigger block names —
|
|
1438
|
+
* #3483.
|
|
1439
|
+
*
|
|
1440
|
+
* Beside `ignoredFunctionKeys` because it answers the same question about the
|
|
1441
|
+
* same table, for the same reader: `config pull` writes a version's AUTHORED
|
|
1442
|
+
* bytes, and a version pushed before the removal carries the block. Without
|
|
1443
|
+
* this the pulled tree would be refused on its next push — a tree an author
|
|
1444
|
+
* cannot get back into a working state, which is the failure D3482-007 already
|
|
1445
|
+
* had to close for the runtime keys.
|
|
1446
|
+
*
|
|
1447
|
+
* This is NOT a refusal and shares nothing with one. The block is refused on
|
|
1448
|
+
* input by `normalizeTriggerDeclaration`; what a strip needs is the list of
|
|
1449
|
+
* entries it is taking out so it can say so, which is why an entry whose
|
|
1450
|
+
* `type` is unreadable still counts as one entry (the empty string). It is the
|
|
1451
|
+
* block's PRESENCE that goes, not its contents.
|
|
1326
1452
|
*
|
|
1327
|
-
*
|
|
1328
|
-
*
|
|
1329
|
-
*
|
|
1330
|
-
* is byte for byte what the row did before the change — and widening a
|
|
1331
|
-
* pre-change row to `any` needs its own authored declaration, which
|
|
1332
|
-
* `src/server-functions/legacy-mode.ts` recovers from the envelope's TOML and
|
|
1333
|
-
* records on the row once (D3454-002).
|
|
1453
|
+
* TOML spells the block three ways — an array of tables, a single table, and
|
|
1454
|
+
* an inline array — and a scan that missed one would leave a key behind
|
|
1455
|
+
* (CR3482-002's lesson, applied to a whole table).
|
|
1334
1456
|
*/
|
|
1335
|
-
export declare function
|
|
1336
|
-
mode?: unknown;
|
|
1337
|
-
durable?: unknown;
|
|
1338
|
-
} | null | undefined): FunctionMode;
|
|
1339
|
-
/** Is this mode the durable one? The adjective, for the paths that branch on it. */
|
|
1340
|
-
export declare function isDurableMode(mode: FunctionMode): boolean;
|
|
1457
|
+
export declare function retiredDatabaseTriggerTypes(functionTable: unknown): string[];
|
|
1341
1458
|
/**
|
|
1342
|
-
*
|
|
1459
|
+
* Whether the block is THERE at all — the question a strip has to ask, which
|
|
1460
|
+
* the type list above cannot answer (CR3483-001).
|
|
1343
1461
|
*
|
|
1344
|
-
*
|
|
1345
|
-
*
|
|
1346
|
-
*
|
|
1347
|
-
*
|
|
1348
|
-
*
|
|
1462
|
+
* `database = []` names no type, so the list is empty and a strip that decided
|
|
1463
|
+
* by its length left the key in the pulled file. That file then fails its own
|
|
1464
|
+
* next push: `normalizeTriggerDeclaration` refuses the key by PRESENCE, of any
|
|
1465
|
+
* shape, an empty array included — so the two halves disagreed about what the
|
|
1466
|
+
* block is, and the tree an author pulled was a tree they could not push.
|
|
1467
|
+
* Presence is the one rule both sides read now, spelled the way
|
|
1468
|
+
* `normalizeTriggerDeclaration` spells it — `!== undefined` — so a value one
|
|
1469
|
+
* of them would call a block and the other would not cannot exist.
|
|
1349
1470
|
*/
|
|
1350
|
-
export declare function
|
|
1471
|
+
export declare function hasRetiredDatabaseTriggerBlock(functionTable: unknown): boolean;
|
|
1472
|
+
/**
|
|
1473
|
+
* The same scan, rendered for one file — the shape `config push` and
|
|
1474
|
+
* `config diff` print and the admin route answers with.
|
|
1475
|
+
*
|
|
1476
|
+
* `label` is what the reader can act on: `functions/<key>.toml` from the CLI,
|
|
1477
|
+
* and the function's key from the API, which has no file to name.
|
|
1478
|
+
*/
|
|
1479
|
+
export declare function ignoredFunctionKeyWarnings(label: string, functionTable: unknown): string[];
|
|
1351
1480
|
/**
|
|
1352
1481
|
* The trigger blocks a function declares, derived from its authored TOML
|
|
1353
1482
|
* (#3181, project `server-functions`, criterion 4).
|
|
@@ -1394,29 +1523,20 @@ export declare function runnerFor(mode: FunctionMode, requested: FunctionRunner
|
|
|
1394
1523
|
* and the CLI has already parsed its own file by the time it asks.
|
|
1395
1524
|
*/
|
|
1396
1525
|
/**
|
|
1397
|
-
*
|
|
1526
|
+
* Why a webhook trigger is the request runtime, and a cron fire a task run —
|
|
1527
|
+
* #3482, the intent's "Mode vocabulary?" decision of 2026-09-15.
|
|
1398
1528
|
*
|
|
1399
|
-
*
|
|
1400
|
-
*
|
|
1401
|
-
*
|
|
1402
|
-
*
|
|
1403
|
-
*
|
|
1529
|
+
* Neither is a rule about the FUNCTION any more, so neither is a refusal: a
|
|
1530
|
+
* function is a function, and the DOOR decides which runtime runs it. A
|
|
1531
|
+
* webhook delivery runs inside the receiver because the provider is holding
|
|
1532
|
+
* the connection open waiting for an answer; a cron fire starts a task run
|
|
1533
|
+
* because it is waiting for nothing. A function that must not run under one of
|
|
1534
|
+
* them tests for it in code with `assertRuntime`, which is the only lock left.
|
|
1404
1535
|
*
|
|
1405
|
-
*
|
|
1406
|
-
*
|
|
1536
|
+
* What survives here is the SHAPE of a declaration — the keys, the names, the
|
|
1537
|
+
* cron expression, the caps. The retired `mode` keys are accepted and reported
|
|
1538
|
+
* as ignored by `ignoredFunctionKeys` in `function-retired-keys.ts`.
|
|
1407
1539
|
*/
|
|
1408
|
-
export interface TriggerModeOptions {
|
|
1409
|
-
mode?: FunctionMode;
|
|
1410
|
-
}
|
|
1411
|
-
/**
|
|
1412
|
-
* Why a webhook cannot drive a task function, and what to do instead (#3334).
|
|
1413
|
-
*
|
|
1414
|
-
* The first clause is verbatim what it has always been, so sibling pins on the
|
|
1415
|
-
* request-mode prefix (#3281's) keep holding; everything after the dash is the
|
|
1416
|
-
* half that was missing — an author who meets this at the push door could not
|
|
1417
|
-
* previously tell whether it was a limitation or a design, nor what to write.
|
|
1418
|
-
*/
|
|
1419
|
-
export declare const WEBHOOK_ON_TASK_REFUSAL: string;
|
|
1420
1540
|
/** A function's single webhook trigger, normalized. */
|
|
1421
1541
|
export interface WebhookTriggerDeclaration {
|
|
1422
1542
|
verificationScheme: string;
|
|
@@ -1433,29 +1553,13 @@ export interface WebhookTriggerDeclaration {
|
|
|
1433
1553
|
export interface CronTriggerDeclaration {
|
|
1434
1554
|
name: string;
|
|
1435
1555
|
cron: string;
|
|
1436
|
-
/**
|
|
1437
|
-
* Which runner THIS schedule's fires use (#3454, D3454-006).
|
|
1438
|
-
*
|
|
1439
|
-
* Required on an `any` function — nothing else in the system says whether a
|
|
1440
|
-
* given schedule means "run it inline" or "start a background run" — and
|
|
1441
|
-
* optional on a locked one, where the lock already answers. Absent on every
|
|
1442
|
-
* declaration stored before the key existed, which `cronEntryRunner` reads
|
|
1443
|
-
* as the request runner those fires already used.
|
|
1444
|
-
*/
|
|
1445
|
-
mode?: FunctionRunner;
|
|
1446
1556
|
timezone?: string;
|
|
1447
1557
|
overlapPolicy?: string;
|
|
1448
1558
|
rootInput?: unknown;
|
|
1449
1559
|
}
|
|
1450
|
-
/** One `[[function.triggers.database]]` entry, normalized (#3184). */
|
|
1451
|
-
export interface DatabaseTriggerDeclaration {
|
|
1452
|
-
/** The database type key whose writes fire this function. */
|
|
1453
|
-
type: string;
|
|
1454
|
-
}
|
|
1455
1560
|
export interface TriggerDeclaration {
|
|
1456
1561
|
webhook: WebhookTriggerDeclaration | null;
|
|
1457
1562
|
cron: CronTriggerDeclaration[];
|
|
1458
|
-
databases: DatabaseTriggerDeclaration[];
|
|
1459
1563
|
}
|
|
1460
1564
|
export declare const EMPTY_TRIGGER_DECLARATION: TriggerDeclaration;
|
|
1461
1565
|
/**
|
|
@@ -1467,21 +1571,13 @@ export declare const EMPTY_TRIGGER_DECLARATION: TriggerDeclaration;
|
|
|
1467
1571
|
* remaining slots for the other 40+ objects the cap is sized for.
|
|
1468
1572
|
*/
|
|
1469
1573
|
export declare const MAX_CRON_TRIGGERS_PER_FUNCTION = 10;
|
|
1470
|
-
/**
|
|
1471
|
-
* The most database types one function may watch (#3184, D-07).
|
|
1472
|
-
*
|
|
1473
|
-
* Per-OBJECT, like the cron cap above: a function watching more than a handful
|
|
1474
|
-
* of types is describing a fan-in the platform cannot bound per write, and
|
|
1475
|
-
* every extra type is another discovery read on somebody's write path.
|
|
1476
|
-
*/
|
|
1477
|
-
export declare const MAX_DATABASE_TRIGGERS_PER_FUNCTION = 5;
|
|
1478
1574
|
/**
|
|
1479
1575
|
* The rule ids this module owns — one per refusal, declared on the `function`
|
|
1480
1576
|
* surface (#3374). The union below closes `refuseTrigger`'s id parameter, so a
|
|
1481
1577
|
* twenty-seventh refusal cannot compile without a twenty-seventh id, and that
|
|
1482
1578
|
* id fails `cli-unit-tests` until the surface declares it (#3373's anchor).
|
|
1483
1579
|
*/
|
|
1484
|
-
export declare const TRIGGER_RULE_IDS: readonly ["triggers-table", "trigger-kind", "database-trigger-
|
|
1580
|
+
export declare const TRIGGER_RULE_IDS: readonly ["triggers-table", "trigger-kind", "database-trigger-removed", "webhook-trigger-single", "webhook-trigger-table", "webhook-trigger-keys", "webhook-trigger-scheme-required", "webhook-trigger-scheme-none", "webhook-trigger-number", "webhook-trigger-dedup-boolean", "webhook-trigger-verification-table", "cron-trigger-cap", "cron-trigger-entry", "cron-trigger-keys", "cron-trigger-name-required", "cron-trigger-name-charset", "cron-trigger-duplicate", "cron-trigger-expression-required", "cron-trigger-overlap-policy"];
|
|
1485
1581
|
export type TriggerRuleId = (typeof TRIGGER_RULE_IDS)[number];
|
|
1486
1582
|
/**
|
|
1487
1583
|
* A broken trigger rule. `ruleId` names which one, for a reader that wants to
|
|
@@ -1504,11 +1600,20 @@ export declare function hasDeclaredTriggers(declaration: TriggerDeclaration): bo
|
|
|
1504
1600
|
* push boundary can normalize a declaration it read from a stored row without
|
|
1505
1601
|
* re-parsing bytes.
|
|
1506
1602
|
*/
|
|
1507
|
-
export declare function normalizeTriggerDeclaration(functionTable: any
|
|
1603
|
+
export declare function normalizeTriggerDeclaration(functionTable: any): TriggerDeclaration;
|
|
1508
1604
|
/** The stored JSON for `ServerFunctionConfig.triggers`, or null when empty. */
|
|
1509
1605
|
export declare function serializeTriggerDeclaration(declaration: TriggerDeclaration): string | null;
|
|
1510
1606
|
/** Read a stored `ServerFunctionConfig.triggers` value back. */
|
|
1511
1607
|
export declare function parseStoredTriggerDeclaration(stored: unknown): TriggerDeclaration;
|
|
1608
|
+
/**
|
|
1609
|
+
* The database types a STORED declaration used to watch, for a reader that
|
|
1610
|
+
* wants to name them — #3483.
|
|
1611
|
+
*
|
|
1612
|
+
* Pure, and separate from the parse on purpose: the parse answers what the
|
|
1613
|
+
* version means NOW (nothing), and this answers what it said, which is only
|
|
1614
|
+
* ever used to write one log line. Nothing branches on it.
|
|
1615
|
+
*/
|
|
1616
|
+
export declare function storedDatabaseTriggerTypes(stored: unknown): string[];
|
|
1512
1617
|
/** The `CronTrigger.triggerKey` an entry owns. */
|
|
1513
1618
|
export declare function cronTriggerKeyFor(functionKey: string, name: string): string;
|
|
1514
1619
|
/** The entry name a `<functionKey>:<name>` trigger key carries. */
|
|
@@ -1762,6 +1867,145 @@ export declare function checkWorkflowSystemAccessRule(input: {
|
|
|
1762
1867
|
accessRule?: unknown;
|
|
1763
1868
|
}): WorkflowRuleViolation | null;
|
|
1764
1869
|
export declare const WORKFLOW_SURFACE: ConfigObjectSurface;
|
|
1870
|
+
/**
|
|
1871
|
+
* Cron-expression and timezone VALIDITY — the half of `src/cron-parser.ts`
|
|
1872
|
+
* both runners need (#3376, project `cli-server-rule-parity` phase 4).
|
|
1873
|
+
*
|
|
1874
|
+
* ── Why this module exists ───────────────────────────────────────────────
|
|
1875
|
+
*
|
|
1876
|
+
* A malformed cron expression and an unknown timezone are both decidable from
|
|
1877
|
+
* the authored file, so the intent lands both rules `preflight` — which under
|
|
1878
|
+
* this project's vocabulary means the implementation lives here, under
|
|
1879
|
+
* `src/config-surface/`, and is vendored into the CLI artifact.
|
|
1880
|
+
*
|
|
1881
|
+
* It got here by a SPLIT, not a move. `src/cron-parser.ts` is 415 lines, and
|
|
1882
|
+
* roughly 290 of them are timezone-aware scheduling arithmetic — "when does
|
|
1883
|
+
* this expression next fire?" — that only the cron Durable Object runs.
|
|
1884
|
+
* Vendoring is wholesale: the generator concatenates this whole directory, so
|
|
1885
|
+
* moving the file would have shipped that scheduler into the published CLI
|
|
1886
|
+
* package. The validator moved; the scheduler stayed; `src/cron-parser.ts`
|
|
1887
|
+
* re-exports what moved, so no server import changed.
|
|
1888
|
+
*
|
|
1889
|
+
* The scheduler's two entry points are deliberately not NAMED here: a CLI
|
|
1890
|
+
* unit test asserts the artifact does not contain either identifier, which is
|
|
1891
|
+
* how "the artifact carries the validator only" is kept true mechanically
|
|
1892
|
+
* rather than by review.
|
|
1893
|
+
*
|
|
1894
|
+
* ── Not a rules module ───────────────────────────────────────────────────
|
|
1895
|
+
*
|
|
1896
|
+
* `parseCron` THROWS, eight different sentences, and `tests/unit/
|
|
1897
|
+
* cron-parser.test.ts` pins that it throws. A module exporting a `*_RULE_IDS`
|
|
1898
|
+
* list may not contain a `throw` outside its one refusal constructor
|
|
1899
|
+
* (`findUnanchoredRefusals`, #3373), so the rule that renders these answers as
|
|
1900
|
+
* refusals is a separate module, `cron-rules.ts`, and this one is a plain
|
|
1901
|
+
* shared-predicate module — the `webhook-signing-secret.ts` / `function-mode.ts`
|
|
1902
|
+
* precedent.
|
|
1903
|
+
*
|
|
1904
|
+
* Pure: no models, no tenant context, no `env` (see `types.ts` §Purity).
|
|
1905
|
+
* `Intl.DateTimeFormat` is the one platform call, and it is the timezone
|
|
1906
|
+
* question itself.
|
|
1907
|
+
*
|
|
1908
|
+
* Supported fields (standard POSIX order):
|
|
1909
|
+
* minute (0-59)
|
|
1910
|
+
* hour (0-23)
|
|
1911
|
+
* day-of-month (1-31)
|
|
1912
|
+
* month (1-12)
|
|
1913
|
+
* day-of-week (0-6, where 0 = Sunday; 7 also accepted as Sunday)
|
|
1914
|
+
*
|
|
1915
|
+
* Supported syntax per field:
|
|
1916
|
+
* - "*" any value
|
|
1917
|
+
* - "5" exact value
|
|
1918
|
+
* - "5-10" range (inclusive)
|
|
1919
|
+
* - "star/step" every N values within the full range (e.g. "* /5" => 0,5,10,...)
|
|
1920
|
+
* - "a-b/step" every N values within a range
|
|
1921
|
+
* - "1,2,3" comma-separated list of values or ranges
|
|
1922
|
+
*
|
|
1923
|
+
* Not supported: month/day names, "?", "L", "W", "#", last-day modifiers.
|
|
1924
|
+
*/
|
|
1925
|
+
export interface ParsedCron {
|
|
1926
|
+
minutes: Set<number>;
|
|
1927
|
+
hours: Set<number>;
|
|
1928
|
+
daysOfMonth: Set<number>;
|
|
1929
|
+
months: Set<number>;
|
|
1930
|
+
daysOfWeek: Set<number>;
|
|
1931
|
+
dayOfMonthWild: boolean;
|
|
1932
|
+
dayOfWeekWild: boolean;
|
|
1933
|
+
}
|
|
1934
|
+
export declare function parseCron(expr: string): ParsedCron;
|
|
1935
|
+
/**
|
|
1936
|
+
* The message `parseCron` would throw for `expr`, or null when it parses.
|
|
1937
|
+
*
|
|
1938
|
+
* The same grammar, asked as a question instead of as an exception, because
|
|
1939
|
+
* both callers want the sentence rather than the control flow: the CLI's push
|
|
1940
|
+
* preflight collects one message per broken entry, and the standalone cron
|
|
1941
|
+
* routes render theirs into a 400 body. `expr` is typed `unknown` because it
|
|
1942
|
+
* arrives as an authored TOML value, where it can be anything at all.
|
|
1943
|
+
*/
|
|
1944
|
+
export declare function cronExpressionError(expr: unknown): string | null;
|
|
1945
|
+
/**
|
|
1946
|
+
* Whether `Intl.DateTimeFormat` accepts `name` as a timezone.
|
|
1947
|
+
*
|
|
1948
|
+
* This is THE timezone check — before #3376 the identical probe was written
|
|
1949
|
+
* out three times (the function push boundary and the standalone create and
|
|
1950
|
+
* update). Each of those sites keeps its own sentence and its own defaulting;
|
|
1951
|
+
* what they now share is this answer. A non-string is false rather than a
|
|
1952
|
+
* throw, for the same reason as above.
|
|
1953
|
+
*/
|
|
1954
|
+
export declare function isValidTimezone(name: unknown): boolean;
|
|
1955
|
+
/**
|
|
1956
|
+
* The cron schedule rules two runners share (#3376, project
|
|
1957
|
+
* `cli-server-rule-parity` phase 4; intent §Success criteria 6).
|
|
1958
|
+
*
|
|
1959
|
+
* ── One implementation, two runners ──────────────────────────────────────
|
|
1960
|
+
*
|
|
1961
|
+
* A cron expression the grammar refuses, and a timezone `Intl` does not know,
|
|
1962
|
+
* are both decidable from the authored file. Before this issue only the SERVER
|
|
1963
|
+
* decided them, inside the apply loop: a `functions/<key>.toml` carrying
|
|
1964
|
+
* either passed `config push`'s preflight, sibling entities were written, and
|
|
1965
|
+
* the function alone was refused — while the command promises that a refusal
|
|
1966
|
+
* means nothing was applied. Now `cli/src/lib/function-sync.ts` and
|
|
1967
|
+
* `src/services/function-trigger-validation.ts` both call the rule below, and
|
|
1968
|
+
* the sentence an author reads is the same on either side of the wire because
|
|
1969
|
+
* it is built in one place.
|
|
1970
|
+
*
|
|
1971
|
+
* ── Why this is a `*-rules.ts` module and the parser is not ──────────────
|
|
1972
|
+
*
|
|
1973
|
+
* The registry's unclaimed-export check (`findUnclaimedRuleModuleExports`)
|
|
1974
|
+
* keys on this name under `src/config-surface/`: every exported function here
|
|
1975
|
+
* is a rule, so one no surface declares fails `cli-unit-tests`. The anchor
|
|
1976
|
+
* also forbids a `throw` outside the one refusal constructor — and `parseCron`
|
|
1977
|
+
* throws eight different sentences, which `tests/unit/cron-parser.test.ts`
|
|
1978
|
+
* pins. So the grammar and the `Intl` probe live next door in
|
|
1979
|
+
* `cron-expression.ts`, which is a shared-predicate module rather than a rules
|
|
1980
|
+
* module, and this one only decides and renders.
|
|
1981
|
+
*
|
|
1982
|
+
* ── What is NOT shared ───────────────────────────────────────────────────
|
|
1983
|
+
*
|
|
1984
|
+
* The standalone cron routes ask the same two predicates and render their own
|
|
1985
|
+
* `Invalid cron expression: …` / `Invalid timezone: …`, with their own
|
|
1986
|
+
* defaulting (create reads an absent timezone as UTC, update does not). That
|
|
1987
|
+
* is intent assumption 2 in the form its own fallback describes, and the shape
|
|
1988
|
+
* `workflow-rules.ts` set in phase 2: one predicate, each site's message and
|
|
1989
|
+
* defaulting preserved. No refusal message changed anywhere.
|
|
1990
|
+
*/
|
|
1991
|
+
/** The rule ids this module owns — the union type below anchors them (#3373). */
|
|
1992
|
+
export declare const CRON_TRIGGER_RULE_IDS: readonly ["cron-trigger-expression", "cron-trigger-timezone"];
|
|
1993
|
+
type CronTriggerRuleId = (typeof CRON_TRIGGER_RULE_IDS)[number];
|
|
1994
|
+
/** A refused cron entry: the rule and the sentence the site renders. */
|
|
1995
|
+
export type CronTriggerRuleRefusal = RuleRefusal<CronTriggerRuleId>;
|
|
1996
|
+
/**
|
|
1997
|
+
* One `[[function.triggers.cron]]` entry's schedule, or null.
|
|
1998
|
+
*
|
|
1999
|
+
* Expression first, then timezone, which is the order the push boundary ran
|
|
2000
|
+
* them in — so an entry broken both ways still answers with the expression's
|
|
2001
|
+
* refusal, exactly as before. An unset or empty `timezone` reads as UTC, again
|
|
2002
|
+
* exactly as before: the boundary's `entry.timezone || "UTC"`.
|
|
2003
|
+
*/
|
|
2004
|
+
export declare function checkCronTriggerEntry(entry: {
|
|
2005
|
+
name: string;
|
|
2006
|
+
cron: string;
|
|
2007
|
+
timezone?: string;
|
|
2008
|
+
}): CronTriggerRuleRefusal | null;
|
|
1765
2009
|
/**
|
|
1766
2010
|
* The prompt config's reasoning controls, resolved onto each provider's own
|
|
1767
2011
|
* spelling — issue #3358.
|