@sanity/workflow-engine 0.29.0 → 0.30.0
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/CHANGELOG.md +51 -0
- package/DATAMODEL.md +67 -22
- package/dist/_chunks-cjs/invariants.cjs +286 -87
- package/dist/_chunks-es/invariants.js +281 -88
- package/dist/define.d.cts +289 -276
- package/dist/define.d.ts +289 -276
- package/dist/index.cjs +1297 -914
- package/dist/index.d.cts +915 -1053
- package/dist/index.d.ts +915 -1053
- package/dist/index.js +1116 -749
- package/package.json +3 -3
package/dist/define.d.cts
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
import * as v from "valibot";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* A stored action. `semantics` is engine-owned advisory meaning, independent
|
|
5
|
+
* of execution and presentation — an array so the vocabulary can grow without
|
|
6
|
+
* reshaping this field. `when`'s presence makes the action CASCADE-FIRED: the
|
|
7
|
+
* engine fires it the moment the condition turns true, at most once per stage
|
|
8
|
+
* visit, and it is never invocable via `fireAction`; absent, the action must
|
|
9
|
+
* be invoked via `fireAction` by any caller holding a token (fire-on-entry is
|
|
10
|
+
* `when: 'true'`). `filter` is existence with GROQ semantics — a non-matching
|
|
11
|
+
* action might as well not exist (invisible to UI and LLMs, never merely
|
|
12
|
+
* disabled); on a `when` action it composes: `filter` scopes whether the
|
|
13
|
+
* automation exists, `when` is its firing trigger. `roles` is kept VERBATIM
|
|
14
|
+
* only when cascade-fired (the pin on which identities may execute the
|
|
15
|
+
* trigger); a fireAction-fired action's `roles` folds into `filter` at
|
|
16
|
+
* desugar instead.
|
|
17
|
+
*/
|
|
3
18
|
declare type Action = ActionFields<Op, string[]> & {
|
|
4
19
|
roles?: string[] | undefined;
|
|
5
20
|
};
|
|
@@ -20,14 +35,14 @@ declare type ActionFields<TOp, TGroup> = {
|
|
|
20
35
|
spawn?: Subworkflows | undefined;
|
|
21
36
|
};
|
|
22
37
|
|
|
23
|
-
declare type ActionParam = v.InferOutput<typeof ActionParamSchema>;
|
|
24
|
-
|
|
25
38
|
/**
|
|
26
|
-
* Caller-supplied params declared on an action
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
39
|
+
* Caller-supplied params declared on an action, validated before running ops
|
|
40
|
+
* or queuing effects: a missing required param throws
|
|
41
|
+
* `ActionParamsInvalidError` and the action does not commit. Resolved values
|
|
42
|
+
* feed `ValueExpr.param` lookups.
|
|
30
43
|
*/
|
|
44
|
+
declare type ActionParam = v.InferOutput<typeof ActionParamSchema>;
|
|
45
|
+
|
|
31
46
|
declare const ActionParamSchema: v.SchemaWithPipe<
|
|
32
47
|
readonly [
|
|
33
48
|
v.StrictObjectSchema<
|
|
@@ -157,6 +172,20 @@ declare const ActionParamSchema: v.SchemaWithPipe<
|
|
|
157
172
|
|
|
158
173
|
declare type ActionSemantic = DecisionSemantic | Semantic;
|
|
159
174
|
|
|
175
|
+
/**
|
|
176
|
+
* A unit of work carrying no payload of its own — every op, effect, and
|
|
177
|
+
* spawn lives on an action; an activity contributes scoped `fields`
|
|
178
|
+
* (resolved at stage entry), existence (`filter`), advisory readiness
|
|
179
|
+
* (`requirements`), and the off-system marker (`target`, a BPMN Manual Task
|
|
180
|
+
* deep-link, render-only and never gating). All in-scope activities are
|
|
181
|
+
* ACTIVE from stage entry until an action's terminal `status` resolves them —
|
|
182
|
+
* there is no activation moment. `filter` is existence with GROQ semantics,
|
|
183
|
+
* evaluated once against the stage's entry state: a definite `false`
|
|
184
|
+
* excludes the activity from UI, LLMs, and `$allActivitiesDone`.
|
|
185
|
+
* `requirements` are readiness gates orthogonal to `filter` — an unmet one
|
|
186
|
+
* keeps the activity visible but disables its actions with a
|
|
187
|
+
* `requirements-unmet` verdict; distinct from ACL and guards.
|
|
188
|
+
*/
|
|
160
189
|
declare type Activity = ActivityFields<
|
|
161
190
|
FieldEntry,
|
|
162
191
|
Action,
|
|
@@ -179,6 +208,18 @@ declare type ActivityFields<TField, TAction, TTarget, TGroup> = {
|
|
|
179
208
|
fields?: TField[] | undefined;
|
|
180
209
|
};
|
|
181
210
|
|
|
211
|
+
/**
|
|
212
|
+
* The stored action fields plus two authoring sugars, or the
|
|
213
|
+
* {@link ClaimAction} pair-half. `roles`: on a fireAction-fired action (no
|
|
214
|
+
* `when`) it desugars into a `count($actor.roles[@ in [...]]) > 0` condition
|
|
215
|
+
* ANDed with `filter`; on a CASCADE-FIRED action it stores VERBATIM instead —
|
|
216
|
+
* the pin on which identities may execute the trigger, since folding it into
|
|
217
|
+
* `filter` would make the action's existence depend on whose token cascades.
|
|
218
|
+
* `roleAliases` widens the membership either way. `status` compiles to a
|
|
219
|
+
* `status.set` op on the firing activity, appended AFTER the authored ops —
|
|
220
|
+
* deliberately never implied, so a forgotten `status` is a visible stall
|
|
221
|
+
* rather than a silently completed action.
|
|
222
|
+
*/
|
|
182
223
|
declare type AuthoringAction = AuthoringRawAction | ClaimAction;
|
|
183
224
|
|
|
184
225
|
declare type AuthoringActivity = ActivityFields<
|
|
@@ -188,14 +229,14 @@ declare type AuthoringActivity = ActivityFields<
|
|
|
188
229
|
GroupMembership
|
|
189
230
|
>;
|
|
190
231
|
|
|
191
|
-
declare type AuthoringEditable = v.InferOutput<typeof AuthoringEditableSchema>;
|
|
192
|
-
|
|
193
232
|
/**
|
|
194
233
|
* Authoring editability adds the `role[]` convenience: a non-empty role list
|
|
195
234
|
* desugars to the same `count($actor.roles[@ in [...]]) > 0` membership
|
|
196
235
|
* predicate `action.roles` produces. `true` opens the field to anyone in its
|
|
197
236
|
* window; a bare string is a raw predicate.
|
|
198
237
|
*/
|
|
238
|
+
declare type AuthoringEditable = v.InferOutput<typeof AuthoringEditableSchema>;
|
|
239
|
+
|
|
199
240
|
declare const AuthoringEditableSchema: v.UnionSchema<
|
|
200
241
|
[
|
|
201
242
|
v.LiteralSchema<true, undefined>,
|
|
@@ -224,6 +265,8 @@ declare type AuthoringFieldEntry =
|
|
|
224
265
|
| TodoListField
|
|
225
266
|
| NotesField;
|
|
226
267
|
|
|
268
|
+
/** A field reference with `scope` optional; desugar resolves it lexically
|
|
269
|
+
* (activity → stage → workflow) into {@link StoredFieldRef}. */
|
|
227
270
|
declare type AuthoringFieldRef = v.InferOutput<typeof AuthoringFieldRefSchema>;
|
|
228
271
|
|
|
229
272
|
declare const AuthoringFieldRefSchema: v.StrictObjectSchema<
|
|
@@ -242,15 +285,12 @@ declare const AuthoringFieldRefSchema: v.StrictObjectSchema<
|
|
|
242
285
|
undefined
|
|
243
286
|
>;
|
|
244
287
|
|
|
288
|
+
/** {@link Guard}'s contract as authored: `match.idRefs` and `metadata` carry
|
|
289
|
+
* typed {@link GuardRead} values that deploy resolves to bare ones. */
|
|
245
290
|
declare type AuthoringGuard = v.InferOutput<typeof AuthoringGuardSchema>;
|
|
246
291
|
|
|
247
292
|
declare const AuthoringGuardSchema: v.StrictObjectSchema<
|
|
248
293
|
{
|
|
249
|
-
/**
|
|
250
|
-
* Lake-id-segment grammar (`^[a-z0-9][a-z0-9-]*$`, deploy-enforced): the
|
|
251
|
-
* guard's lake `_id` derives from `(instanceId, name)` at stage entry.
|
|
252
|
-
* Unique per definition.
|
|
253
|
-
*/
|
|
254
294
|
name: v.SchemaWithPipe<
|
|
255
295
|
readonly [
|
|
256
296
|
v.StringSchema<undefined>,
|
|
@@ -261,7 +301,6 @@ declare const AuthoringGuardSchema: v.StrictObjectSchema<
|
|
|
261
301
|
description: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
262
302
|
match: v.StrictObjectSchema<
|
|
263
303
|
{
|
|
264
|
-
/** Subject `_type`(s); empty matches any type. */
|
|
265
304
|
types: v.OptionalSchema<
|
|
266
305
|
v.ArraySchema<
|
|
267
306
|
v.SchemaWithPipe<
|
|
@@ -274,7 +313,6 @@ declare const AuthoringGuardSchema: v.StrictObjectSchema<
|
|
|
274
313
|
>,
|
|
275
314
|
undefined
|
|
276
315
|
>;
|
|
277
|
-
/** Target docs as field reads (or the instance itself), resolved at deploy to bare ids + the resource. */
|
|
278
316
|
idRefs: v.OptionalSchema<
|
|
279
317
|
v.ArraySchema<
|
|
280
318
|
v.VariantSchema<
|
|
@@ -377,7 +415,6 @@ declare const AuthoringGuardSchema: v.StrictObjectSchema<
|
|
|
377
415
|
>,
|
|
378
416
|
undefined
|
|
379
417
|
>;
|
|
380
|
-
/** Glob id patterns (bare, resource-local). */
|
|
381
418
|
idPatterns: v.OptionalSchema<
|
|
382
419
|
v.ArraySchema<
|
|
383
420
|
v.SchemaWithPipe<
|
|
@@ -409,22 +446,7 @@ declare const AuthoringGuardSchema: v.StrictObjectSchema<
|
|
|
409
446
|
},
|
|
410
447
|
undefined
|
|
411
448
|
>;
|
|
412
|
-
/**
|
|
413
|
-
* Lake GROQ predicate — a distinct eval context: delta-mode GROQ
|
|
414
|
-
* reading the `before()`/`after()` natives, `mutation`, `guard`, and
|
|
415
|
-
* `identity()`. Bare ids/fields only. Polarity: a result of strictly
|
|
416
|
-
* `true` ALLOWS the matched mutation; anything else (false, null, an
|
|
417
|
-
* evaluation error) DENIES. Omitted or empty means UNCONDITIONAL DENY.
|
|
418
|
-
*/
|
|
419
449
|
predicate: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
420
|
-
/**
|
|
421
|
-
* Projected workflow fields the predicate reads as `guard.metadata.*` —
|
|
422
|
-
* the only bridge from the lake eval context (which cannot see `$fields`)
|
|
423
|
-
* to workflow fields. Each value is a deploy-time read — a typed
|
|
424
|
-
* {@link GuardRead} when authoring, the printed string spelling once
|
|
425
|
-
* stored — resolved into a bare value at deploy and re-synced by the
|
|
426
|
-
* post-field-op guard refresh.
|
|
427
|
-
*/
|
|
428
450
|
metadata: v.OptionalSchema<
|
|
429
451
|
v.RecordSchema<
|
|
430
452
|
v.SchemaWithPipe<
|
|
@@ -534,6 +556,8 @@ declare const AuthoringGuardSchema: v.StrictObjectSchema<
|
|
|
534
556
|
undefined
|
|
535
557
|
>;
|
|
536
558
|
|
|
559
|
+
/** Like {@link ManualTarget}, but the `field` variant also accepts a bare
|
|
560
|
+
* field name; desugar normalises it into {@link AuthoringFieldRef}. */
|
|
537
561
|
declare type AuthoringManualTarget = v.InferOutput<
|
|
538
562
|
typeof AuthoringManualTargetSchema
|
|
539
563
|
>;
|
|
@@ -593,6 +617,9 @@ declare const AuthoringManualTargetSchema: v.VariantSchema<
|
|
|
593
617
|
undefined
|
|
594
618
|
>;
|
|
595
619
|
|
|
620
|
+
/** Like {@link Op}, plus: `status.set`'s `activity` is optional (desugar fills
|
|
621
|
+
* the firing activity), and the `audit` sugar — a stamped append merging
|
|
622
|
+
* `actor`/`at` {@link ValueExpr} fields into its own value. */
|
|
596
623
|
declare type AuthoringOp = v.InferOutput<typeof AuthoringOpSchema>;
|
|
597
624
|
|
|
598
625
|
declare const AuthoringOpSchema: v.VariantSchema<
|
|
@@ -888,27 +915,6 @@ declare const AuthoringOpSchema: v.VariantSchema<
|
|
|
888
915
|
undefined
|
|
889
916
|
>;
|
|
890
917
|
|
|
891
|
-
/**
|
|
892
|
-
* Authoring action — the stored fields plus two field sugars with one
|
|
893
|
-
* defined expansion each:
|
|
894
|
-
*
|
|
895
|
-
* - `roles` — on a fireAction-fired action (no `when`) it desugars to a
|
|
896
|
-
* `count($actor.roles[@ in [...]]) > 0` membership condition ANDed with
|
|
897
|
-
* the authored `filter` (for a caller, "not yours to fire" and "doesn't
|
|
898
|
-
* exist for you" are the same advisory answer). On a CASCADE-FIRED
|
|
899
|
-
* action it stores VERBATIM — the pin on which identities may execute
|
|
900
|
-
* the trigger; folding it into `filter` would make the action's
|
|
901
|
-
* existence depend on whose token happens to cascade. The definition's
|
|
902
|
-
* `roleAliases` ({@link RoleAliasesSchema}) widen the membership either
|
|
903
|
-
* way.
|
|
904
|
-
* - `status` → a `status.set` op on the firing activity, appended **after**
|
|
905
|
-
* the authored ops (deliberately never implied: a forgotten explicit
|
|
906
|
-
* `status` is a visible stall, an implied default silently completes
|
|
907
|
-
* claim-like actions). Status is the health axis: a decision action
|
|
908
|
-
* (decline, send back) resolves `done` and writes the decision into a
|
|
909
|
-
* field the transition trigger reads — `failed` is for work that
|
|
910
|
-
* genuinely could not complete.
|
|
911
|
-
*/
|
|
912
918
|
declare type AuthoringRawAction = ActionFields<AuthoringOp, GroupMembership> & {
|
|
913
919
|
roles?: string[] | undefined;
|
|
914
920
|
status?: TerminalActivityStatus | undefined;
|
|
@@ -958,14 +964,8 @@ declare interface ChoiceOptions {
|
|
|
958
964
|
|
|
959
965
|
declare type ChoiceValue = string | number;
|
|
960
966
|
|
|
961
|
-
/**
|
|
962
|
-
*
|
|
963
|
-
* author-declared actor-valued entry (the pair's other half), resolved
|
|
964
|
-
* lexically. Expansion, strictly within this action: a no-steal
|
|
965
|
-
* `!defined($fields.<field>)` filter ANDed with `roles`/`filter`, plus a
|
|
966
|
-
* `field.set` ← actor op. `ops` and `status` are reserved (the expansion
|
|
967
|
-
* owns them) — strictObject rejects them as unknown keys.
|
|
968
|
-
*/
|
|
967
|
+
/** The action half of the mirrored claim pair: `field` names the actor-valued entry this action claims, resolved lexically, and the expansion
|
|
968
|
+
* adds a no-steal `!defined($fields.<field>)` filter ANDed with `roles`/`filter` plus a `field.set` ← actor op. `ops`/`status` are reserved (strictObject rejects them). */
|
|
969
969
|
declare type ClaimAction = {
|
|
970
970
|
type: "claim";
|
|
971
971
|
name: string;
|
|
@@ -979,12 +979,8 @@ declare type ClaimAction = {
|
|
|
979
979
|
effects?: Effect[] | undefined;
|
|
980
980
|
};
|
|
981
981
|
|
|
982
|
-
/**
|
|
983
|
-
*
|
|
984
|
-
* field half of the mirrored claim pair. Expansion: an `actor` working-
|
|
985
|
-
* memory field (no `initialValue`; the claim action's op fills it), strictly
|
|
986
|
-
* within this entry.
|
|
987
|
-
*/
|
|
982
|
+
/** The field half of the mirrored claim pair, expanding strictly within this entry: an `actor`
|
|
983
|
+
* working-memory field with no `initialValue` — the paired {@link ClaimAction}'s op fills it. */
|
|
988
984
|
declare type ClaimField = {
|
|
989
985
|
type: "claim";
|
|
990
986
|
name: string;
|
|
@@ -994,10 +990,23 @@ declare type ClaimField = {
|
|
|
994
990
|
};
|
|
995
991
|
|
|
996
992
|
/**
|
|
997
|
-
* Every variable the engine binds for
|
|
998
|
-
*
|
|
999
|
-
*
|
|
1000
|
-
*
|
|
993
|
+
* Every variable the engine binds for the RENDERED condition scope (every
|
|
994
|
+
* condition site: transition `when`s, activity filters, action
|
|
995
|
+
* `when`s/filters, effect bindings, `spawn` reads, where-op `where`s,
|
|
996
|
+
* editability predicates, author predicates) — the deploy-time shadow check
|
|
997
|
+
* ({@link RESERVED_CONDITION_VARS}) and the docs on {@link Condition} derive
|
|
998
|
+
* from this list; extend it here when the engine grows a binding, never in
|
|
999
|
+
* a comment elsewhere.
|
|
1000
|
+
*
|
|
1001
|
+
* Three other GROQ contexts read a definition and do NOT share this
|
|
1002
|
+
* inventory: cascade gates (transition/activity/cascade-action gates, which
|
|
1003
|
+
* must resolve identically regardless of caller — only the `'always'`-bound
|
|
1004
|
+
* subset carries values, {@link FILTER_SCOPE_VARS}); the start contexts
|
|
1005
|
+
* (`start.filter` is browse-time-pure over a candidate document,
|
|
1006
|
+
* {@link START_FILTER_VARS}; a start `groq` requirement binds `$fields`
|
|
1007
|
+
* instead, {@link START_REQUIREMENT_VARS}); and lake guard predicates, which
|
|
1008
|
+
* are not conditions at all — delta-mode GROQ over a mutation, binding
|
|
1009
|
+
* {@link GUARD_PREDICATE_VARS} instead.
|
|
1001
1010
|
*/
|
|
1002
1011
|
export declare const CONDITION_VARS: readonly ConditionVar[];
|
|
1003
1012
|
|
|
@@ -1011,43 +1020,6 @@ export declare interface ConditionVar {
|
|
|
1011
1020
|
label: string;
|
|
1012
1021
|
}
|
|
1013
1022
|
|
|
1014
|
-
/**
|
|
1015
|
-
* The condition-variable inventory — the single source of truth for every
|
|
1016
|
-
* `$var` the engine binds when it evaluates a {@link Condition}.
|
|
1017
|
-
*
|
|
1018
|
-
* Four evaluation contexts read a definition's GROQ:
|
|
1019
|
-
*
|
|
1020
|
-
* 1. **Rendered condition scope** — every condition site in a definition
|
|
1021
|
-
* (transition `when`s, activity filters, action `when`s/filters, effect
|
|
1022
|
-
* bindings, `spawn` reads, where-op `where`s, editability predicates,
|
|
1023
|
-
* author predicates). {@link CONDITION_VARS} is its inventory; each
|
|
1024
|
-
* entry's `binding` says when the var actually holds a value. The
|
|
1025
|
-
* where-op context is the one closed subset — its bound set is statically
|
|
1026
|
-
* fixed and deploy-enforced (see the op-where scope's param-name list in
|
|
1027
|
-
* the op applier).
|
|
1028
|
-
* 2. **Cascade gates** — transition `when`s, activity filters, and a
|
|
1029
|
-
* cascade-fired action's `when`/`filter` must resolve identically no
|
|
1030
|
-
* matter whose token drives the cascade, so only the `'always'`-bound
|
|
1031
|
-
* subset carries values there ({@link FILTER_SCOPE_VARS}). Caller-bound
|
|
1032
|
-
* vars fail closed — `$assigned` binds its caller-free constant `false`,
|
|
1033
|
-
* the rest evaluate to `undefined` — and deploy rejects them at these
|
|
1034
|
-
* sites; a cascade-fired action's per-token gate is `roles`, never its
|
|
1035
|
-
* conditions.
|
|
1036
|
-
* 3. **The start contexts** — a definition's `start.filter` and start GROQ
|
|
1037
|
-
* requirements evaluate against a CANDIDATE (no instance exists yet):
|
|
1038
|
-
* `*[...]` reads the engine-owned `{definition, subject, completedAt}`
|
|
1039
|
-
* projection of the tag's instances and none of the rendered
|
|
1040
|
-
* condition vars exist. The two split on what a surface can know:
|
|
1041
|
-
* `filter` is browse-time-pure (candidate document as root,
|
|
1042
|
-
* {@link START_FILTER_VARS} — no `$fields`, which cannot exist before
|
|
1043
|
-
* inputs do), a `groq` requirement is the start-time readiness predicate
|
|
1044
|
-
* ({@link START_REQUIREMENT_VARS} — `$fields` bound, never a root).
|
|
1045
|
-
* 4. **Guard predicates** — NOT conditions. A lake mutation guard's
|
|
1046
|
-
* `predicate` is groq-js **delta-mode** GROQ over a document mutation:
|
|
1047
|
-
* `before()`/`after()`/`identity()` are dialect natives, and the wire
|
|
1048
|
-
* format binds the identifiers in {@link GUARD_PREDICATE_VARS}. None of
|
|
1049
|
-
* the condition vars exist there.
|
|
1050
|
-
*/
|
|
1051
1023
|
/**
|
|
1052
1024
|
* When a condition var holds a value:
|
|
1053
1025
|
*
|
|
@@ -1063,15 +1035,6 @@ export declare type ConditionVarBinding = "always" | "caller" | "spawn";
|
|
|
1063
1035
|
/** A define-time validated `custom.<camelCaseMeaning>` value. */
|
|
1064
1036
|
declare type CustomSemantic = `custom.${string}`;
|
|
1065
1037
|
|
|
1066
|
-
/**
|
|
1067
|
-
* The maximum reader floor this writer can emit. Individual documents derive
|
|
1068
|
-
* their `minReaderModel` from the compatibility-bearing features actually
|
|
1069
|
-
* present; a document written at {@link DATA_MODEL_VERSION} may therefore
|
|
1070
|
-
* carry a lower floor. Raising this maximum is a declared, DATAMODEL.md-logged
|
|
1071
|
-
* decision that requires readers-first fleet sequencing.
|
|
1072
|
-
*/
|
|
1073
|
-
declare const DATA_MODEL_MIN_READER = 4;
|
|
1074
|
-
|
|
1075
1038
|
declare const DECISION_SEMANTICS: readonly [
|
|
1076
1039
|
"decision.accept",
|
|
1077
1040
|
"decision.decline",
|
|
@@ -1140,21 +1103,42 @@ export declare function defineWorkflow(
|
|
|
1140
1103
|
* deployment's bindings via {@link resourceAliasesToMap} into the
|
|
1141
1104
|
* `resourceAliases` map `deployDefinitions` expands against.
|
|
1142
1105
|
*
|
|
1143
|
-
* Validates shape only
|
|
1144
|
-
*
|
|
1145
|
-
*
|
|
1146
|
-
*
|
|
1147
|
-
*
|
|
1148
|
-
*
|
|
1149
|
-
*
|
|
1150
|
-
*
|
|
1106
|
+
* Validates shape only; reader-floor acknowledgement belongs to paths that
|
|
1107
|
+
* submit definitions (`deployDefinitions`, the CLI deploy and definition-diff
|
|
1108
|
+
* commands, and blueprint provision). Other commands may load a selected
|
|
1109
|
+
* deployment with a missing floor.
|
|
1110
|
+
*
|
|
1111
|
+
* Each `WorkflowDeploymentInput` carries an acknowledgement; definition-submission
|
|
1112
|
+
* paths compare it with the submitted definitions. The returned {@link WorkflowConfig}
|
|
1113
|
+
* is the looser parsed shape.
|
|
1151
1114
|
*/
|
|
1152
1115
|
export declare function defineWorkflowConfig(
|
|
1153
1116
|
config: WorkflowConfigInput,
|
|
1154
1117
|
): WorkflowConfig;
|
|
1155
1118
|
|
|
1119
|
+
/**
|
|
1120
|
+
* Declared editability of a field — the generic edit seam's gate. Default
|
|
1121
|
+
* (absent) is NOT editable: a field is op-only engine working memory unless the
|
|
1122
|
+
* modeler opens it. The stored form is `true` (editable by anyone within the
|
|
1123
|
+
* field's scope window) or an EDIT CONDITION — rendered-scope GROQ (`$actor`,
|
|
1124
|
+
* `$can`, `$attributes`, `$fields`, `$assigned`), checked like an action filter
|
|
1125
|
+
* to decide who-may-edit. ADVISORY like every engine gate — it disables the
|
|
1126
|
+
* inline field and explains; a {@link Guard} declares the intended write-lock.
|
|
1127
|
+
*/
|
|
1156
1128
|
declare type Editable = v.InferOutput<typeof StoredEditableSchema>;
|
|
1157
1129
|
|
|
1130
|
+
/**
|
|
1131
|
+
* A registered effect: `name` is its only identity (unique per definition,
|
|
1132
|
+
* read downstream as `$effects.<name>`) — the host app registers a handler
|
|
1133
|
+
* against it 1:1, and the stored definition never references code.
|
|
1134
|
+
* `bindings` are GROQ reads over the rendered scope, resolved to concrete
|
|
1135
|
+
* JSON at queue time; `input` is static config passed through verbatim.
|
|
1136
|
+
* `outputs` (typed {@link FieldShape}s) is a STRICT allowlist: at completion
|
|
1137
|
+
* an undeclared output key, or a value that doesn't fit its shape, fails the
|
|
1138
|
+
* completion and nothing is stored. Omitting `outputs` is an EMPTY allowlist,
|
|
1139
|
+
* so ANY returned output is rejected and fails the completion — the bound is
|
|
1140
|
+
* universal, not opt-in.
|
|
1141
|
+
*/
|
|
1158
1142
|
declare type Effect = v.InferOutput<typeof EffectSchema>;
|
|
1159
1143
|
|
|
1160
1144
|
/**
|
|
@@ -1189,7 +1173,6 @@ declare const EffectSchema: v.StrictObjectSchema<
|
|
|
1189
1173
|
v.StringSchema<undefined>,
|
|
1190
1174
|
undefined
|
|
1191
1175
|
>;
|
|
1192
|
-
/** GROQ reads over the rendered scope, resolved to concrete JSON at queue time. */
|
|
1193
1176
|
readonly bindings: v.OptionalSchema<
|
|
1194
1177
|
v.RecordSchema<
|
|
1195
1178
|
v.StringSchema<undefined>,
|
|
@@ -1203,28 +1186,10 @@ declare const EffectSchema: v.StrictObjectSchema<
|
|
|
1203
1186
|
>,
|
|
1204
1187
|
undefined
|
|
1205
1188
|
>;
|
|
1206
|
-
/** Static config, passed through to the handler verbatim. */
|
|
1207
1189
|
readonly input: v.OptionalSchema<
|
|
1208
1190
|
v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>,
|
|
1209
1191
|
undefined
|
|
1210
1192
|
>;
|
|
1211
|
-
/**
|
|
1212
|
-
* The outputs this effect is allowed to produce, as typed {@link FieldShape}s
|
|
1213
|
-
* (each `name` is an output key, read downstream as `$effects['<name>'].<key>`;
|
|
1214
|
-
* an `array` output is an array of objects shaped by `of`).
|
|
1215
|
-
*
|
|
1216
|
-
* A STRICT allowlist: at completion the handler's returned `outputs` are
|
|
1217
|
-
* validated against these shapes and an undeclared key — or a value that
|
|
1218
|
-
* doesn't fit its shape — fails the completion (nothing is stored). Omitting
|
|
1219
|
-
* `outputs` is an EMPTY allowlist: the effect produces nothing, so any returned
|
|
1220
|
-
* output is rejected — the bound is universal, not opt-in.
|
|
1221
|
-
* Why strict: outputs land on the instance document's `effectHistory`, so
|
|
1222
|
-
* the allowlist keeps it bounded — a handler can't accidentally spread a
|
|
1223
|
-
* whole API response
|
|
1224
|
-
* into the instance — and the declared shapes let tooling (e.g. the simulator's
|
|
1225
|
-
* drain UI) suggest an effect's exact output keys. Declaring outputs also
|
|
1226
|
-
* powers the advisory deploy-time producer/consumer lint.
|
|
1227
|
-
*/
|
|
1228
1193
|
readonly outputs: v.OptionalSchema<
|
|
1229
1194
|
v.ArraySchema<v.GenericSchema<FieldShape>, undefined>,
|
|
1230
1195
|
undefined
|
|
@@ -1237,7 +1202,10 @@ declare const EffectSchema: v.StrictObjectSchema<
|
|
|
1237
1202
|
* The kinds a VALUE can take — scalars aligned to Sanity's names, the
|
|
1238
1203
|
* reference kinds, the actor/assignee identities, and the two compositional
|
|
1239
1204
|
* kinds (`object` with named `fields`, `array` of objects shaped by `of`).
|
|
1240
|
-
* This is also the set a nested {@link FieldShape} sub-field may use.
|
|
1205
|
+
* This is also the set a nested {@link FieldShape} sub-field may use. Kinds
|
|
1206
|
+
* are bare (unique within their union); namespacing lives only on
|
|
1207
|
+
* engine-owned lake document `_type`s ({@link WORKFLOW_DEFINITION_TYPE}, the
|
|
1208
|
+
* instance type).
|
|
1241
1209
|
*
|
|
1242
1210
|
* Exported (module-level, not package API) for the model-surface gate's
|
|
1243
1211
|
* enum-value coverage test.
|
|
@@ -1276,6 +1244,7 @@ declare type FieldBase<TEditable, TGroup> = {
|
|
|
1276
1244
|
editable?: TEditable | undefined;
|
|
1277
1245
|
};
|
|
1278
1246
|
|
|
1247
|
+
/** One declared field entry as authored and stored: name, value kind, and its scope's sourcing and editability. */
|
|
1279
1248
|
declare type FieldEntry = FieldEntryFields<Editable, string[]>;
|
|
1280
1249
|
|
|
1281
1250
|
/** Type-mirror of {@link fieldEntryFields}: a raw field entry of the given
|
|
@@ -1288,6 +1257,8 @@ declare type FieldEntryFields<TEditable, TGroup> = FieldBase<
|
|
|
1288
1257
|
options?: ChoiceOptions | undefined;
|
|
1289
1258
|
validation?: ScalarValidation | undefined;
|
|
1290
1259
|
types?: string[] | undefined;
|
|
1260
|
+
/** Non-empty assignment eligibility constraint. User roles apply aliases; collective roles match literally. */
|
|
1261
|
+
roles?: string[] | undefined;
|
|
1291
1262
|
fields?: FieldShape[] | undefined;
|
|
1292
1263
|
of?: FieldShape[] | undefined;
|
|
1293
1264
|
};
|
|
@@ -1299,6 +1270,14 @@ declare type FieldReadExpr = {
|
|
|
1299
1270
|
path?: string | undefined;
|
|
1300
1271
|
};
|
|
1301
1272
|
|
|
1273
|
+
/**
|
|
1274
|
+
* A sub-field shape used inside an `object`'s `fields` or an `array`'s `of` —
|
|
1275
|
+
* lighter than {@link FieldEntry}: no `initialValue`/`editable`/`required`,
|
|
1276
|
+
* since a sub-field's value comes from the parent. An `object` kind requires
|
|
1277
|
+
* non-empty `fields` and no `of`; an `array` kind requires non-empty `of` and
|
|
1278
|
+
* no `fields`; every other kind requires neither — enforced at parse, not
|
|
1279
|
+
* visible in this type.
|
|
1280
|
+
*/
|
|
1302
1281
|
declare interface FieldShape {
|
|
1303
1282
|
type: FieldValueKind;
|
|
1304
1283
|
name: string;
|
|
@@ -1306,10 +1285,19 @@ declare interface FieldShape {
|
|
|
1306
1285
|
description?: string | undefined;
|
|
1307
1286
|
options?: ChoiceOptions | undefined;
|
|
1308
1287
|
validation?: ScalarValidation | undefined;
|
|
1288
|
+
/** Non-empty assignment eligibility constraint. User roles apply aliases; collective roles match literally. */
|
|
1289
|
+
roles?: string[] | undefined;
|
|
1309
1290
|
fields?: FieldShape[] | undefined;
|
|
1310
1291
|
of?: FieldShape[] | undefined;
|
|
1311
1292
|
}
|
|
1312
1293
|
|
|
1294
|
+
/**
|
|
1295
|
+
* How a field seeds its `initialValue`, once at materialisation (advisory
|
|
1296
|
+
* after — the field stays freely editable). Absent means working memory: the
|
|
1297
|
+
* field starts empty and an op fills it later, spelled by omission rather
|
|
1298
|
+
* than an arm. Distinct from {@link ValueExpr}, an op's write payload; they
|
|
1299
|
+
* overlap only on the literal and field-read arms.
|
|
1300
|
+
*/
|
|
1313
1301
|
declare type FieldSource = FieldSourceInternal;
|
|
1314
1302
|
|
|
1315
1303
|
declare type FieldSourceInternal =
|
|
@@ -1352,12 +1340,22 @@ export declare function groq(
|
|
|
1352
1340
|
...values: unknown[]
|
|
1353
1341
|
): string;
|
|
1354
1342
|
|
|
1343
|
+
/** A named readiness condition. Activities accept only `'groq'`; workflow
|
|
1344
|
+
* `start.requirements` also accepts `'singleSubject'` — see {@link StartRequirement}. */
|
|
1355
1345
|
declare type GroqRequirement = RequirementBase & {
|
|
1356
1346
|
type: "groq";
|
|
1357
1347
|
query: string;
|
|
1358
1348
|
};
|
|
1359
1349
|
|
|
1360
|
-
/**
|
|
1350
|
+
/**
|
|
1351
|
+
* A declared "what belongs together" tag: the workflow root, a stage, or an
|
|
1352
|
+
* activity declares named groups, and field entries, activities, and actions
|
|
1353
|
+
* opt in via `group`. Purely advisory — the engine stores and validates names
|
|
1354
|
+
* (unique per level, every reference resolves) and never acts on them; a
|
|
1355
|
+
* consumer decides what a group means for its medium. The same name declared
|
|
1356
|
+
* at several levels is intentional nesting, addressed per level; the engine
|
|
1357
|
+
* never merges them.
|
|
1358
|
+
*/
|
|
1361
1359
|
declare type Group = {
|
|
1362
1360
|
name: string;
|
|
1363
1361
|
title?: string | undefined;
|
|
@@ -1365,6 +1363,14 @@ declare type Group = {
|
|
|
1365
1363
|
kind?: GroupKind | undefined;
|
|
1366
1364
|
};
|
|
1367
1365
|
|
|
1366
|
+
/**
|
|
1367
|
+
* Advisory classification of a declared {@link Group} by its informational
|
|
1368
|
+
* ROLE, never a rendering treatment: `'core'` marks content central to
|
|
1369
|
+
* understanding the workflow (condensed views include these first);
|
|
1370
|
+
* `'details'` marks depth on demand. Unset = a plain group. Consumers
|
|
1371
|
+
* reading a definition as data MUST treat an unknown kind as unset — growing
|
|
1372
|
+
* this list is an engine version bump, like every stored enum.
|
|
1373
|
+
*/
|
|
1368
1374
|
declare const GROUP_KINDS: readonly ["core", "details"];
|
|
1369
1375
|
|
|
1370
1376
|
declare type GroupKind = (typeof GROUP_KINDS)[number];
|
|
@@ -1381,6 +1387,27 @@ declare type GroupKind = (typeof GROUP_KINDS)[number];
|
|
|
1381
1387
|
*/
|
|
1382
1388
|
declare type GroupMembership = string | string[];
|
|
1383
1389
|
|
|
1390
|
+
/**
|
|
1391
|
+
* A lake mutation guard. A FOREIGN CONTRACT mirrored 1:1: `match`,
|
|
1392
|
+
* `predicate`, and `metadata` are the content lake's persisted guard-document
|
|
1393
|
+
* API, not engine-invented surface — the stored form keeps the lake's
|
|
1394
|
+
* vocabulary verbatim. The engine adds exactly two things: `name` (a
|
|
1395
|
+
* lake-id-segment, `^[a-z0-9][a-z0-9-]*$`, unique per definition — the lake
|
|
1396
|
+
* `_id` derives from `(instanceId, name)` at stage entry) and the deploy-time
|
|
1397
|
+
* read VALUES on `match.idRefs` / `metadata` (a typed {@link GuardRead} when
|
|
1398
|
+
* authoring, resolved to bare values at deploy). `match` selects mutations by
|
|
1399
|
+
* `types` (empty matches any), `idRefs` (field reads resolved to bare ids),
|
|
1400
|
+
* `idPatterns` (bare glob ids), and `actions` (at least one). `predicate` is
|
|
1401
|
+
* lake GROQ in a distinct delta-mode eval context (`before()`/`after()`,
|
|
1402
|
+
* `mutation`, `guard`, `identity()`, bare ids/fields only): strictly `true`
|
|
1403
|
+
* ALLOWS the mutation; anything else — false, null, an evaluation error, or
|
|
1404
|
+
* an omitted/empty predicate — DENIES. `metadata` is the only bridge from
|
|
1405
|
+
* that eval context (which cannot see `$fields`) to workflow fields, read as
|
|
1406
|
+
* `guard.metadata.*` and re-synced by the post-field-op guard refresh. The
|
|
1407
|
+
* lake does not enforce the guard document type yet: a deployed guard denies
|
|
1408
|
+
* optimistically engine-side, and the lake ACL is the only hard gate until
|
|
1409
|
+
* guard enforcement ships.
|
|
1410
|
+
*/
|
|
1384
1411
|
declare type Guard = v.InferOutput<typeof GuardSchema>;
|
|
1385
1412
|
|
|
1386
1413
|
/**
|
|
@@ -1395,14 +1422,8 @@ export declare const GUARD_PREDICATE_VARS: readonly {
|
|
|
1395
1422
|
description: string;
|
|
1396
1423
|
}[];
|
|
1397
1424
|
|
|
1398
|
-
/** Stored guards carry the printed string reads (the deploy resolver's input). */
|
|
1399
1425
|
declare const GuardSchema: v.StrictObjectSchema<
|
|
1400
1426
|
{
|
|
1401
|
-
/**
|
|
1402
|
-
* Lake-id-segment grammar (`^[a-z0-9][a-z0-9-]*$`, deploy-enforced): the
|
|
1403
|
-
* guard's lake `_id` derives from `(instanceId, name)` at stage entry.
|
|
1404
|
-
* Unique per definition.
|
|
1405
|
-
*/
|
|
1406
1427
|
name: v.SchemaWithPipe<
|
|
1407
1428
|
readonly [
|
|
1408
1429
|
v.StringSchema<undefined>,
|
|
@@ -1413,7 +1434,6 @@ declare const GuardSchema: v.StrictObjectSchema<
|
|
|
1413
1434
|
description: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1414
1435
|
match: v.StrictObjectSchema<
|
|
1415
1436
|
{
|
|
1416
|
-
/** Subject `_type`(s); empty matches any type. */
|
|
1417
1437
|
types: v.OptionalSchema<
|
|
1418
1438
|
v.ArraySchema<
|
|
1419
1439
|
v.SchemaWithPipe<
|
|
@@ -1426,7 +1446,6 @@ declare const GuardSchema: v.StrictObjectSchema<
|
|
|
1426
1446
|
>,
|
|
1427
1447
|
undefined
|
|
1428
1448
|
>;
|
|
1429
|
-
/** Target docs as field reads (or the instance itself), resolved at deploy to bare ids + the resource. */
|
|
1430
1449
|
idRefs: v.OptionalSchema<
|
|
1431
1450
|
v.ArraySchema<
|
|
1432
1451
|
v.SchemaWithPipe<
|
|
@@ -1439,7 +1458,6 @@ declare const GuardSchema: v.StrictObjectSchema<
|
|
|
1439
1458
|
>,
|
|
1440
1459
|
undefined
|
|
1441
1460
|
>;
|
|
1442
|
-
/** Glob id patterns (bare, resource-local). */
|
|
1443
1461
|
idPatterns: v.OptionalSchema<
|
|
1444
1462
|
v.ArraySchema<
|
|
1445
1463
|
v.SchemaWithPipe<
|
|
@@ -1471,22 +1489,7 @@ declare const GuardSchema: v.StrictObjectSchema<
|
|
|
1471
1489
|
},
|
|
1472
1490
|
undefined
|
|
1473
1491
|
>;
|
|
1474
|
-
/**
|
|
1475
|
-
* Lake GROQ predicate — a distinct eval context: delta-mode GROQ
|
|
1476
|
-
* reading the `before()`/`after()` natives, `mutation`, `guard`, and
|
|
1477
|
-
* `identity()`. Bare ids/fields only. Polarity: a result of strictly
|
|
1478
|
-
* `true` ALLOWS the matched mutation; anything else (false, null, an
|
|
1479
|
-
* evaluation error) DENIES. Omitted or empty means UNCONDITIONAL DENY.
|
|
1480
|
-
*/
|
|
1481
1492
|
predicate: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
1482
|
-
/**
|
|
1483
|
-
* Projected workflow fields the predicate reads as `guard.metadata.*` —
|
|
1484
|
-
* the only bridge from the lake eval context (which cannot see `$fields`)
|
|
1485
|
-
* to workflow fields. Each value is a deploy-time read — a typed
|
|
1486
|
-
* {@link GuardRead} when authoring, the printed string spelling once
|
|
1487
|
-
* stored — resolved into a bare value at deploy and re-synced by the
|
|
1488
|
-
* post-field-op guard refresh.
|
|
1489
|
-
*/
|
|
1490
1493
|
metadata: v.OptionalSchema<
|
|
1491
1494
|
v.RecordSchema<
|
|
1492
1495
|
v.SchemaWithPipe<
|
|
@@ -1514,17 +1517,22 @@ declare type LiteralExpr = {
|
|
|
1514
1517
|
value: unknown;
|
|
1515
1518
|
};
|
|
1516
1519
|
|
|
1517
|
-
declare type ManualTarget = v.InferOutput<typeof StoredManualTargetSchema>;
|
|
1518
|
-
|
|
1519
1520
|
/**
|
|
1520
|
-
*
|
|
1521
|
-
*
|
|
1522
|
-
*
|
|
1521
|
+
* Off-system deep-link target — render-only metadata whose presence marks an
|
|
1522
|
+
* activity as off-system (BPMN Manual Task). Either a static URL, or a field
|
|
1523
|
+
* reference whose resolved document the consumer opens; deploy checks the
|
|
1524
|
+
* `field` variant points at a doc-valued entry.
|
|
1523
1525
|
*/
|
|
1526
|
+
declare type ManualTarget = v.InferOutput<typeof StoredManualTargetSchema>;
|
|
1527
|
+
|
|
1528
|
+
/** An append-only audit/comment log: sugar over `array of object {body, actor, at}` — the `actor`/`at`
|
|
1529
|
+
* names match the `audit` op's stamp fields, so it pairs with it. Never a stored kind. */
|
|
1524
1530
|
declare type NotesField = FieldBase<AuthoringEditable, GroupMembership> & {
|
|
1525
1531
|
type: "notes";
|
|
1526
1532
|
};
|
|
1527
1533
|
|
|
1534
|
+
/** A `field.updateWhere` / `field.removeWhere` op's `where` selects rows to
|
|
1535
|
+
* mutate with rendered-scope GROQ (`$row`, `$params` bound) — row selection, not a gate; an unevaluable row never matches. */
|
|
1528
1536
|
declare type Op = v.InferOutput<typeof StoredOpSchema>;
|
|
1529
1537
|
|
|
1530
1538
|
declare type RequirementBase = {
|
|
@@ -1541,35 +1549,15 @@ declare type RequirementBase = {
|
|
|
1541
1549
|
*/
|
|
1542
1550
|
export declare const RESERVED_CONDITION_VARS: readonly string[];
|
|
1543
1551
|
|
|
1544
|
-
declare type RoleAliases = v.InferOutput<typeof RoleAliasesSchema>;
|
|
1545
|
-
|
|
1546
1552
|
/**
|
|
1547
|
-
*
|
|
1548
|
-
*
|
|
1549
|
-
*
|
|
1550
|
-
*
|
|
1551
|
-
*
|
|
1552
|
-
* in each gate — or fork the definition per deployment — declare once here
|
|
1553
|
-
* which other roles also fulfill it.
|
|
1554
|
-
*
|
|
1555
|
-
* Each key is a role a gate/assignee names; its value lists the roles that
|
|
1556
|
-
* also satisfy it. The reserved key `"*"` lists roles that fulfill ANY gate
|
|
1557
|
-
* (e.g. `"*": ["administrator"]` — whatever this deployment's broad role is).
|
|
1558
|
-
* `"*"` is the spelling authors write; it is rewritten to a lake-safe stored
|
|
1559
|
-
* key before the definition is persisted, since the Content Lake rejects `"*"`
|
|
1560
|
-
* as a document attribute name (see {@link normalizeRoleAliases}).
|
|
1561
|
-
*
|
|
1562
|
-
* Applied as an in-place expansion of the REQUIRED side, never the actor's
|
|
1563
|
-
* roles: the `roles` gate bakes the expanded membership into its desugared
|
|
1564
|
-
* GROQ at define time; `$assigned` expands the assignee's role at match time
|
|
1565
|
-
* (see {@link expandRequiredRoles}). Carried into the stored definition for
|
|
1566
|
-
* that runtime half.
|
|
1567
|
-
*
|
|
1568
|
-
* Advisory, like every engine gate — an alias only predicts what the
|
|
1569
|
-
* deployment's Content Lake ACLs already allow, it never grants access. An
|
|
1570
|
-
* alias the lake won't honor makes the gate predict "allowed" for a write the
|
|
1571
|
-
* lake then rejects, so keep it true to what's actually deployed.
|
|
1553
|
+
* Roles that may fulfil each authored role. Aliases widen action gates,
|
|
1554
|
+
* `$assigned`, and assignment-field user eligibility by expanding the required
|
|
1555
|
+
* side; they never alter an actor's roles. Collective role assignees remain
|
|
1556
|
+
* literal ownership values and are not widened by this map. The authored `"*"`
|
|
1557
|
+
* key lists universal fulfillers and is normalized before persistence.
|
|
1572
1558
|
*/
|
|
1559
|
+
declare type RoleAliases = v.InferOutput<typeof RoleAliasesSchema>;
|
|
1560
|
+
|
|
1573
1561
|
declare const RoleAliasesSchema: v.RecordSchema<
|
|
1574
1562
|
v.SchemaWithPipe<
|
|
1575
1563
|
readonly [
|
|
@@ -1619,6 +1607,18 @@ declare type SingleSubjectRequirement = RequirementBase & {
|
|
|
1619
1607
|
type: "singleSubject";
|
|
1620
1608
|
};
|
|
1621
1609
|
|
|
1610
|
+
/**
|
|
1611
|
+
* A pure container — name, fields, guards, activities, transitions, no
|
|
1612
|
+
* behaviour of its own. Activities own enter, transitions own exit and
|
|
1613
|
+
* arrival; a stage with no transitions IS terminal (structural, nothing to
|
|
1614
|
+
* declare or mis-declare). `guards` are lake mutation guards active while
|
|
1615
|
+
* the stage holds, each compiling to a persisted guard document deployed on
|
|
1616
|
+
* stage entry and retracted on exit. `editable` is a tighten-only override
|
|
1617
|
+
* for the time the stage holds, keyed by an in-scope field name: the field's
|
|
1618
|
+
* own `editable` is the ceiling, ANDed with the stage value at runtime, so an
|
|
1619
|
+
* override can only NARROW — never open a field the baseline left closed. An
|
|
1620
|
+
* unlisted field inherits its baseline.
|
|
1621
|
+
*/
|
|
1622
1622
|
declare type Stage = StageFields<
|
|
1623
1623
|
FieldEntry,
|
|
1624
1624
|
Activity,
|
|
@@ -1643,13 +1643,23 @@ declare type StageFields<TField, TActivity, TTransition, TGuard, TEditable> = {
|
|
|
1643
1643
|
|
|
1644
1644
|
declare const START_KINDS: readonly ["interactive", "autonomous"];
|
|
1645
1645
|
|
|
1646
|
+
/**
|
|
1647
|
+
* How standalone runs of this workflow begin. `filter` is a READ-SIDE
|
|
1648
|
+
* visibility predicate — "should a start surface offer this workflow for
|
|
1649
|
+
* this document?" — evaluated by `definitionsForDocument`/applicability in
|
|
1650
|
+
* the browse-time-pure start-filter context (`$tag`/`$definition`/`$now`
|
|
1651
|
+
* bound; `$fields` cannot exist before inputs do, so a `$fields` read here
|
|
1652
|
+
* is deploy-rejected). It is NOT a `startInstance` gate; the verb never
|
|
1653
|
+
* reads it. `requirements` are named readiness checks evaluated in author
|
|
1654
|
+
* order in the start-time context (GROQ nodes add `$fields`; `singleSubject`
|
|
1655
|
+
* is the one-in-flight-run-per-subject rule) — every node must pass before
|
|
1656
|
+
* `startInstance` commits. Both are advisory like every engine-side check;
|
|
1657
|
+
* the Content Lake remains the only enforcement point.
|
|
1658
|
+
*/
|
|
1646
1659
|
declare type StartBlock = StartFields & {
|
|
1647
1660
|
kind: StartKind;
|
|
1648
1661
|
};
|
|
1649
1662
|
|
|
1650
|
-
/** Type-mirror of {@link startFields}: how standalone runs of this workflow
|
|
1651
|
-
* begin. Stored requires `kind` (desugar fills the `'interactive'` default);
|
|
1652
|
-
* authoring may omit it — so each variant declares it. */
|
|
1653
1663
|
declare type StartFields = {
|
|
1654
1664
|
filter?: string | undefined;
|
|
1655
1665
|
requirements?: StartRequirement[] | undefined;
|
|
@@ -1666,17 +1676,9 @@ declare type StartFields = {
|
|
|
1666
1676
|
*/
|
|
1667
1677
|
declare type StartKind = (typeof START_KINDS)[number];
|
|
1668
1678
|
|
|
1679
|
+
/** Every named readiness requirement accepted by workflow `start.requirements`. */
|
|
1669
1680
|
declare type StartRequirement = GroqRequirement | SingleSubjectRequirement;
|
|
1670
1681
|
|
|
1671
|
-
/**
|
|
1672
|
-
* Declared editability of a field — the generic edit seam's gate. Default
|
|
1673
|
-
* (absent) is NOT editable: a field is op-only engine working memory unless the
|
|
1674
|
-
* modeler opens it. The stored form is `true` (editable by anyone within the
|
|
1675
|
-
* field's scope window) or an EDIT CONDITION — rendered-scope GROQ (`$actor`,
|
|
1676
|
-
* `$can`, `$attributes`, `$fields`, `$assigned`), checked like an action filter
|
|
1677
|
-
* to decide who-may-edit. ADVISORY like every engine gate — it disables the
|
|
1678
|
-
* inline field and explains; a {@link Guard} declares the intended write-lock.
|
|
1679
|
-
*/
|
|
1680
1682
|
declare const StoredEditableSchema: v.UnionSchema<
|
|
1681
1683
|
[
|
|
1682
1684
|
v.LiteralSchema<true, undefined>,
|
|
@@ -1946,18 +1948,23 @@ declare const StoredOpSchema: v.VariantSchema<
|
|
|
1946
1948
|
undefined
|
|
1947
1949
|
>;
|
|
1948
1950
|
|
|
1951
|
+
/**
|
|
1952
|
+
* Fan-out declared as an action's `spawn`, read back as `$subworkflows`.
|
|
1953
|
+
* `forEach` is GROQ producing one row per subworkflow (bound as `$row`); each
|
|
1954
|
+
* row needs an identity the engine can adopt on re-entry (`_key` ?? `_id` ??
|
|
1955
|
+
* GDR `id`, or the value itself for a scalar row) or the spawn fails.
|
|
1956
|
+
* `definition` resolves by stable `name`, ordered `version desc` unless
|
|
1957
|
+
* pinned. `with` seeds each child's initial fields; `context` delivers extra
|
|
1958
|
+
* parent-scope values into the child's `$context`. `onExit` governs only
|
|
1959
|
+
* still-live children when the cohort's scope stops applying: `'detach'`
|
|
1960
|
+
* (default) lets them run to completion, `'abort'` kills them recursively —
|
|
1961
|
+
* always an authored choice, never automatic. Whether the PARENT may move at
|
|
1962
|
+
* all is a separate gate over `$subworkflows`.
|
|
1963
|
+
*/
|
|
1949
1964
|
declare type Subworkflows = v.InferOutput<typeof SubworkflowsSchema>;
|
|
1950
1965
|
|
|
1951
1966
|
declare const SubworkflowsSchema: v.StrictObjectSchema<
|
|
1952
1967
|
{
|
|
1953
|
-
/**
|
|
1954
|
-
* GROQ producing one row per subworkflow; each row binds as `$row`. Every
|
|
1955
|
-
* row must carry an identity the engine can adopt against on re-entry:
|
|
1956
|
-
* `_key` ?? `_id` ?? GDR `id` for object rows (a GDR value — `{id, type}`
|
|
1957
|
-
* with a GDR-URI `id`, the rows a `doc.refs` field stores — keys on its
|
|
1958
|
-
* `id`; mint a `_key` in the projection for synthetic rows), the value
|
|
1959
|
-
* itself for scalar rows. A row without an identity fails the spawn.
|
|
1960
|
-
*/
|
|
1961
1968
|
readonly forEach: v.SchemaWithPipe<
|
|
1962
1969
|
readonly [
|
|
1963
1970
|
v.StringSchema<undefined>,
|
|
@@ -1991,7 +1998,6 @@ declare const SubworkflowsSchema: v.StrictObjectSchema<
|
|
|
1991
1998
|
},
|
|
1992
1999
|
undefined
|
|
1993
2000
|
>;
|
|
1994
|
-
/** Initial fields for each subworkflow — entry name → GROQ over `$row` + the parent scope. */
|
|
1995
2001
|
readonly with: v.OptionalSchema<
|
|
1996
2002
|
v.RecordSchema<
|
|
1997
2003
|
v.SchemaWithPipe<
|
|
@@ -2010,11 +2016,6 @@ declare const SubworkflowsSchema: v.StrictObjectSchema<
|
|
|
2010
2016
|
>,
|
|
2011
2017
|
undefined
|
|
2012
2018
|
>;
|
|
2013
|
-
/**
|
|
2014
|
-
* Extra values evaluated in the parent's rendered scope at spawn time and
|
|
2015
|
-
* delivered into each subworkflow's `$context` bag — the parent→child
|
|
2016
|
-
* handoff.
|
|
2017
|
-
*/
|
|
2018
2019
|
readonly context: v.OptionalSchema<
|
|
2019
2020
|
v.RecordSchema<
|
|
2020
2021
|
v.SchemaWithPipe<
|
|
@@ -2033,16 +2034,6 @@ declare const SubworkflowsSchema: v.StrictObjectSchema<
|
|
|
2033
2034
|
>,
|
|
2034
2035
|
undefined
|
|
2035
2036
|
>;
|
|
2036
|
-
/**
|
|
2037
|
-
* What happens to still-live children when their cohort's scope stops
|
|
2038
|
-
* applying — the spawning stage exits, or a re-fire's `forEach` no longer
|
|
2039
|
-
* discovers their row. `'detach'` (the default) lets them run to
|
|
2040
|
-
* completion outside the gate; `'abort'` kills them (recursively). The
|
|
2041
|
-
* engine never destroys in-flight work implicitly — `'abort'` is always
|
|
2042
|
-
* an authored choice. Note this governs only the CHILDREN's fate; whether
|
|
2043
|
-
* the parent may move at all is what gates (conditions over
|
|
2044
|
-
* `$subworkflows`) decide.
|
|
2045
|
-
*/
|
|
2046
2037
|
readonly onExit: v.OptionalSchema<
|
|
2047
2038
|
v.PicklistSchema<readonly ["detach", "abort"], string>,
|
|
2048
2039
|
undefined
|
|
@@ -2051,6 +2042,14 @@ declare const SubworkflowsSchema: v.StrictObjectSchema<
|
|
|
2051
2042
|
undefined
|
|
2052
2043
|
>;
|
|
2053
2044
|
|
|
2045
|
+
/**
|
|
2046
|
+
* The statuses an activity can be resolved INTO — what `status.set` accepts.
|
|
2047
|
+
* A health axis, not a decision axis: a routine decision (decline, send back,
|
|
2048
|
+
* hold) resolves `done` and routes via a field write; `failed` means the work
|
|
2049
|
+
* genuinely could not complete. Only `done`/`skipped` satisfy
|
|
2050
|
+
* `$allActivitiesDone` — a `failed` activity blocks it permanently, surfacing
|
|
2051
|
+
* via `$anyActivityFailed`.
|
|
2052
|
+
*/
|
|
2054
2053
|
declare const TERMINAL_ACTIVITY_STATUSES: readonly [
|
|
2055
2054
|
"done",
|
|
2056
2055
|
"skipped",
|
|
@@ -2060,19 +2059,22 @@ declare const TERMINAL_ACTIVITY_STATUSES: readonly [
|
|
|
2060
2059
|
declare type TerminalActivityStatus =
|
|
2061
2060
|
(typeof TERMINAL_ACTIVITY_STATUSES)[number];
|
|
2062
2061
|
|
|
2063
|
-
/**
|
|
2064
|
-
* `
|
|
2065
|
-
* { label, status, assignee?, dueDate? }`; a plain checklist is this used with
|
|
2066
|
-
* `{label, status}` only (open ↔ done). Never a stored kind.
|
|
2067
|
-
*
|
|
2068
|
-
* The `dueDate` column is a `date` NAMED `dueDate`, not the {@link
|
|
2069
|
-
* FieldValueMap.dueDate} kind — that kind reserves one deadline slot per level,
|
|
2070
|
-
* and a repeating row has nothing to reserve.
|
|
2071
|
-
*/
|
|
2062
|
+
/** Ad-hoc, status-tracked work items: sugar over `array of object {label, status, assignee?, dueDate?}`; a plain checklist is that with `{label, status}` alone.
|
|
2063
|
+
* Its `dueDate` is a `date` column named `dueDate`, not the elevated `dueDate` kind, which reserves one deadline slot per level. Never a stored kind. */
|
|
2072
2064
|
declare type TodoListField = FieldBase<AuthoringEditable, GroupMembership> & {
|
|
2073
2065
|
type: "todoList";
|
|
2074
2066
|
};
|
|
2075
2067
|
|
|
2068
|
+
/**
|
|
2069
|
+
* A pure edge — `{name, when, to}` plus presentation, no ops or effects
|
|
2070
|
+
* (structure never does; only actions do). Every transition is evaluated on
|
|
2071
|
+
* every commit and cascade; the first truthy `when` in declaration order
|
|
2072
|
+
* fires. No action coupling: a routing difference is written into fields by
|
|
2073
|
+
* an action and read by the trigger — arrival work is a `when: 'true'`
|
|
2074
|
+
* action in the destination stage, and exit work is an action in the source
|
|
2075
|
+
* stage whose `when` repeats this transition's condition (the hop rule
|
|
2076
|
+
* guarantees it commits before the move).
|
|
2077
|
+
*/
|
|
2076
2078
|
declare type Transition = TransitionFields & {
|
|
2077
2079
|
when: string;
|
|
2078
2080
|
};
|
|
@@ -2112,6 +2114,16 @@ declare type ValueExprInternal =
|
|
|
2112
2114
|
|
|
2113
2115
|
declare const WORKFLOW_LIFECYCLES: readonly ["standalone", "child"];
|
|
2114
2116
|
|
|
2117
|
+
/**
|
|
2118
|
+
* `deployments` names must be unique (the selector deployment-targeted
|
|
2119
|
+
* commands resolve by), and each `(workflowResource, tag)` pair must be
|
|
2120
|
+
* unique — that pair is the storage partition, so two deployments sharing
|
|
2121
|
+
* both would fight over definition versions. `telemetry`, when set, replaces
|
|
2122
|
+
* the CLI's built-in Sanity-intake shell entirely: every event flows to this
|
|
2123
|
+
* logger unconditionally (CI and `DO_NOT_TRACK` included), and consent,
|
|
2124
|
+
* environment suppression, and transport become this implementation's
|
|
2125
|
+
* business.
|
|
2126
|
+
*/
|
|
2115
2127
|
declare type WorkflowConfig = v.InferOutput<typeof WorkflowConfigSchema>;
|
|
2116
2128
|
|
|
2117
2129
|
/**
|
|
@@ -2735,14 +2747,6 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
|
|
|
2735
2747
|
>,
|
|
2736
2748
|
]
|
|
2737
2749
|
>;
|
|
2738
|
-
/**
|
|
2739
|
-
* Custom telemetry destination for the CLI. When set, the CLI's built-in
|
|
2740
|
-
* Sanity-intake shell is not constructed and none of its policy applies:
|
|
2741
|
-
* every event — the command trace and the engine vocabulary — flows to
|
|
2742
|
-
* this logger unconditionally (CI and `DO_NOT_TRACK` environments
|
|
2743
|
-
* included). Consent, environment suppression, transport, and destination
|
|
2744
|
-
* are wholly this implementation's business.
|
|
2745
|
-
*/
|
|
2746
2750
|
readonly telemetry: v.OptionalSchema<
|
|
2747
2751
|
v.CustomSchema<
|
|
2748
2752
|
WorkflowTelemetryLogger,
|
|
@@ -2754,6 +2758,21 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
|
|
|
2754
2758
|
undefined
|
|
2755
2759
|
>;
|
|
2756
2760
|
|
|
2761
|
+
/**
|
|
2762
|
+
* `name` is a lake-id-segment (`^[a-z0-9][a-z0-9-]*$`) that interpolates into
|
|
2763
|
+
* every deployed document id (`<tag>.<name>.v<version>`) — stable identity
|
|
2764
|
+
* that instances pin to and subworkflows resolve by. `lifecycle: 'child'`
|
|
2765
|
+
* marks a spawn-only definition, instantiated by a parent via an action's
|
|
2766
|
+
* `spawn`, never started cold from a picker (omitted ⇒ `'standalone'`,
|
|
2767
|
+
* startable); advisory only — consumers filter start pickers on it (see
|
|
2768
|
+
* {@link isStartableDefinition}), the engine does not itself refuse a
|
|
2769
|
+
* `startInstance` on a `'child'` definition. `start` is meaningless
|
|
2770
|
+
* (deploy-rejected) on a spawn-only definition; omitted, it means
|
|
2771
|
+
* interactive semantics with no predicates. `predicates` are nullary named
|
|
2772
|
+
* conditions — each `name: groq` entry is pre-evaluated and bound as the
|
|
2773
|
+
* boolean `$name` var; redefining a built-in var is a deploy error, never a
|
|
2774
|
+
* silent shadow.
|
|
2775
|
+
*/
|
|
2757
2776
|
declare type WorkflowDefinition = v.InferOutput<
|
|
2758
2777
|
typeof WorkflowDefinitionSchema
|
|
2759
2778
|
>;
|
|
@@ -2763,47 +2782,41 @@ declare type WorkflowDefinition = v.InferOutput<
|
|
|
2763
2782
|
* every reference scope resolved. Cross-field invariants (unique names,
|
|
2764
2783
|
* transition targets, effect-name uniqueness, predicate shadowing) are
|
|
2765
2784
|
* checked by `checkWorkflowInvariants` after desugar — see `defineWorkflow`.
|
|
2785
|
+
* Carries NO `version`: a definition's version and content fingerprint are
|
|
2786
|
+
* stamped onto the deployed document at deploy time, derived from the
|
|
2787
|
+
* content itself, so redeploying identical content is a no-op and any
|
|
2788
|
+
* change mints the next version.
|
|
2766
2789
|
*
|
|
2767
|
-
*
|
|
2768
|
-
*
|
|
2769
|
-
*
|
|
2770
|
-
*
|
|
2771
|
-
* source of identity: redeploying identical content is a no-op, any change
|
|
2772
|
-
* mints the next version.
|
|
2790
|
+
* Exported (module-level, not package API) for the model-surface gate's
|
|
2791
|
+
* coverage test and for `parseStoredDefinition` — the boundary parse for a
|
|
2792
|
+
* definition that did not come out of `defineWorkflow` in-process; trusted
|
|
2793
|
+
* in-process desugar output is never re-parsed.
|
|
2773
2794
|
*/
|
|
2774
2795
|
declare const WorkflowDefinitionSchema: v.GenericSchema<
|
|
2775
2796
|
WorkflowFields<FieldEntry, Stage, StartBlock>
|
|
2776
2797
|
>;
|
|
2777
2798
|
|
|
2778
2799
|
/** One deployment as loaded from a config: the floor is optional/unverified so
|
|
2779
|
-
*
|
|
2780
|
-
*
|
|
2781
|
-
*
|
|
2800
|
+
* commands that do not submit definitions can hold a missing acknowledgement.
|
|
2801
|
+
* Definition-submission paths compare it with their selected definitions; authors write
|
|
2802
|
+
* {@link WorkflowDeploymentInput}. */
|
|
2782
2803
|
declare type WorkflowDeployment = WorkflowConfig["deployments"][number];
|
|
2783
2804
|
|
|
2784
2805
|
/**
|
|
2785
|
-
* What an author writes for one deployment: the
|
|
2786
|
-
*
|
|
2787
|
-
*
|
|
2788
|
-
*
|
|
2789
|
-
* deployment still run; deployment-scoped paths assert the selected
|
|
2790
|
-
* deployment (instance-id commands do not).
|
|
2806
|
+
* What an author writes for one deployment: the highest reader model verified
|
|
2807
|
+
* across runtimes sharing its workflow resource. Runtime validation compares
|
|
2808
|
+
* it with the submitted definitions, so a dependency upgrade alone does not
|
|
2809
|
+
* require changing the literal.
|
|
2791
2810
|
*/
|
|
2792
2811
|
declare type WorkflowDeploymentInput = Omit<
|
|
2793
2812
|
WorkflowDeployment,
|
|
2794
2813
|
"expectedMinReaderModel"
|
|
2795
2814
|
> & {
|
|
2796
|
-
expectedMinReaderModel:
|
|
2815
|
+
expectedMinReaderModel: number;
|
|
2797
2816
|
};
|
|
2798
2817
|
|
|
2799
2818
|
/** Type-mirror of {@link workflowFields}, parameterised over field/stage/start. */
|
|
2800
2819
|
declare type WorkflowFields<TField, TStage, TStart> = {
|
|
2801
|
-
/**
|
|
2802
|
-
* Lake-id-segment grammar (`^[a-z0-9][a-z0-9-]*$`, deploy-enforced): the
|
|
2803
|
-
* name interpolates into every deployed document id
|
|
2804
|
-
* (`<tag>.<name>.v<version>`). Stable identity — instances pin to it,
|
|
2805
|
-
* subworkflows resolve by it.
|
|
2806
|
-
*/
|
|
2807
2820
|
name: string;
|
|
2808
2821
|
semantics?: Semantic[] | undefined;
|
|
2809
2822
|
title: string;
|