@sanity/workflow-engine 0.16.0 → 0.18.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/dist/define.cjs CHANGED
@@ -17,11 +17,16 @@ function defineWorkflow(definition) {
17
17
  }
18
18
 
19
19
  function defineWorkflowConfig(config) {
20
- return invariants.parseOrThrow({
20
+ const parsed = invariants.parseOrThrow({
21
21
  schema: invariants.WorkflowConfigSchema,
22
22
  input: config,
23
23
  label: "defineWorkflowConfig"
24
24
  });
25
+ return assertDeploymentAcknowledgements(parsed), parsed;
26
+ }
27
+
28
+ function assertDeploymentAcknowledgements(config) {
29
+ for (const [index, deployment] of config.deployments.entries()) invariants.assertReaderModelAcknowledgement(deployment.expectedMinReaderModel, `Deployment ${deployment.name || `at deployments[${index}]`}`);
25
30
  }
26
31
 
27
32
  function defineStage(stage) {
package/dist/define.d.cts CHANGED
@@ -4,10 +4,16 @@ declare type Action = ActionFields<Op, string[]> & {
4
4
  roles?: string[] | undefined;
5
5
  };
6
6
 
7
+ declare const ACTION_SEMANTICS: readonly [
8
+ "decision.accept",
9
+ "decision.decline",
10
+ ];
11
+
7
12
  /** Type-mirror of {@link actionFields}, parameterised over the op and
8
13
  * group-membership grammars. */
9
14
  declare type ActionFields<TOp, TGroup> = {
10
15
  name: string;
16
+ semantics?: ActionSemantic[] | undefined;
11
17
  title?: string | undefined;
12
18
  description?: string | undefined;
13
19
  group?: TGroup | undefined;
@@ -27,38 +33,135 @@ declare type ActionParam = v.InferOutput<typeof ActionParamSchema>;
27
33
  * effects: missing required params → ActionParamsInvalidError, action
28
34
  * does not commit. Resolved values feed `ValueExpr.param` lookups.
29
35
  */
30
- declare const ActionParamSchema: v.StrictObjectSchema<
31
- {
32
- readonly type: v.PicklistSchema<
33
- readonly [
34
- "string",
35
- "number",
36
- "boolean",
37
- "url",
38
- "dateTime",
39
- "actor",
40
- "doc.ref",
41
- "doc.refs",
42
- "json",
43
- ],
44
- `Invalid option: expected one of ${string}`
45
- >;
46
- readonly name: v.SchemaWithPipe<
47
- readonly [
48
- v.StringSchema<undefined>,
49
- v.MinLengthAction<string, 1, "must be a non-empty string">,
50
- ]
51
- >;
52
- readonly title: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
53
- readonly description: v.OptionalSchema<
54
- v.StringSchema<undefined>,
36
+ declare const ActionParamSchema: v.SchemaWithPipe<
37
+ readonly [
38
+ v.StrictObjectSchema<
39
+ {
40
+ readonly type: v.PicklistSchema<
41
+ readonly [
42
+ "string",
43
+ "number",
44
+ "boolean",
45
+ "url",
46
+ "dateTime",
47
+ "actor",
48
+ "doc.ref",
49
+ "doc.refs",
50
+ "json",
51
+ ],
52
+ `Invalid option: expected one of ${string}`
53
+ >;
54
+ readonly name: v.SchemaWithPipe<
55
+ readonly [
56
+ v.StringSchema<undefined>,
57
+ v.MinLengthAction<string, 1, "must be a non-empty string">,
58
+ ]
59
+ >;
60
+ readonly title: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
61
+ readonly description: v.OptionalSchema<
62
+ v.StringSchema<undefined>,
63
+ undefined
64
+ >;
65
+ readonly required: v.OptionalSchema<
66
+ v.BooleanSchema<undefined>,
67
+ undefined
68
+ >;
69
+ readonly options: v.OptionalSchema<
70
+ v.GenericSchema<ChoiceOptions>,
71
+ undefined
72
+ >;
73
+ readonly validation: v.OptionalSchema<
74
+ v.GenericSchema<ScalarValidation>,
75
+ undefined
76
+ >;
77
+ },
55
78
  undefined
56
- >;
57
- readonly required: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
58
- },
59
- undefined
79
+ >,
80
+ v.CheckAction<
81
+ {
82
+ type:
83
+ | "string"
84
+ | "number"
85
+ | "boolean"
86
+ | "doc.ref"
87
+ | "doc.refs"
88
+ | "url"
89
+ | "actor"
90
+ | "dateTime"
91
+ | "json";
92
+ name: string;
93
+ title?: string | undefined;
94
+ description?: string | undefined;
95
+ required?: boolean | undefined;
96
+ options?: ChoiceOptions | undefined;
97
+ validation?: ScalarValidation | undefined;
98
+ },
99
+ (
100
+ issue: v.CheckIssue<{
101
+ type:
102
+ | "string"
103
+ | "number"
104
+ | "boolean"
105
+ | "doc.ref"
106
+ | "doc.refs"
107
+ | "url"
108
+ | "actor"
109
+ | "dateTime"
110
+ | "json";
111
+ name: string;
112
+ title?: string | undefined;
113
+ description?: string | undefined;
114
+ required?: boolean | undefined;
115
+ options?: ChoiceOptions | undefined;
116
+ validation?: ScalarValidation | undefined;
117
+ }>,
118
+ ) => string
119
+ >,
120
+ v.CheckAction<
121
+ {
122
+ type:
123
+ | "string"
124
+ | "number"
125
+ | "boolean"
126
+ | "doc.ref"
127
+ | "doc.refs"
128
+ | "url"
129
+ | "actor"
130
+ | "dateTime"
131
+ | "json";
132
+ name: string;
133
+ title?: string | undefined;
134
+ description?: string | undefined;
135
+ required?: boolean | undefined;
136
+ options?: ChoiceOptions | undefined;
137
+ validation?: ScalarValidation | undefined;
138
+ },
139
+ (
140
+ issue: v.CheckIssue<{
141
+ type:
142
+ | "string"
143
+ | "number"
144
+ | "boolean"
145
+ | "doc.ref"
146
+ | "doc.refs"
147
+ | "url"
148
+ | "actor"
149
+ | "dateTime"
150
+ | "json";
151
+ name: string;
152
+ title?: string | undefined;
153
+ description?: string | undefined;
154
+ required?: boolean | undefined;
155
+ options?: ChoiceOptions | undefined;
156
+ validation?: ScalarValidation | undefined;
157
+ }>,
158
+ ) => string
159
+ >,
160
+ ]
60
161
  >;
61
162
 
163
+ declare type ActionSemantic = (typeof ACTION_SEMANTICS)[number];
164
+
62
165
  declare type Activity = ActivityFields<
63
166
  FieldEntry,
64
167
  Action,
@@ -150,6 +253,11 @@ declare type AuthoringGuard = v.InferOutput<typeof AuthoringGuardSchema>;
150
253
 
151
254
  declare const AuthoringGuardSchema: v.StrictObjectSchema<
152
255
  {
256
+ /**
257
+ * Lake-id-segment grammar (`^[a-z0-9][a-z0-9-]*$`, deploy-enforced): the
258
+ * guard's lake `_id` derives from `(instanceId, name)` at stage entry.
259
+ * Unique per definition.
260
+ */
153
261
  name: v.SchemaWithPipe<
154
262
  readonly [
155
263
  v.StringSchema<undefined>,
@@ -311,8 +419,9 @@ declare const AuthoringGuardSchema: v.StrictObjectSchema<
311
419
  /**
312
420
  * Lake GROQ predicate — a distinct eval context: delta-mode GROQ
313
421
  * reading the `before()`/`after()` natives, `mutation`, `guard`, and
314
- * `identity()`. Bare ids/fields only. Omitted or empty means
315
- * UNCONDITIONAL DENY.
422
+ * `identity()`. Bare ids/fields only. Polarity: a result of strictly
423
+ * `true` ALLOWS the matched mutation; anything else (false, null, an
424
+ * evaluation error) DENIES. Omitted or empty means UNCONDITIONAL DENY.
316
425
  */
317
426
  predicate: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
318
427
  /**
@@ -764,6 +873,17 @@ declare type AuthoringWorkflow = WorkflowFields<
764
873
  AuthoringStartBlock
765
874
  >;
766
875
 
876
+ declare interface ChoiceOption {
877
+ title: string;
878
+ value: ChoiceValue;
879
+ }
880
+
881
+ declare interface ChoiceOptions {
882
+ list: ChoiceOption[];
883
+ }
884
+
885
+ declare type ChoiceValue = string | number;
886
+
767
887
  /**
768
888
  * The action half of the mirrored claim pair. `field` references an
769
889
  * author-declared actor-valued entry (the pair's other half), resolved
@@ -839,11 +959,14 @@ export declare interface ConditionVar {
839
959
  * the rest evaluate to `undefined` — and deploy rejects them at these
840
960
  * sites; a cascade-fired action's per-token gate is `roles`, never its
841
961
  * conditions.
842
- * 3. **The start-filter context** — a definition's `start.filter` evaluates
843
- * against a CANDIDATE (no instance exists yet): the candidate document is
844
- * the root, {@link START_FILTER_VARS} are the only bound vars, and
845
- * `*[...]` reads the WORKFLOW resource's dataset. None of the rendered
846
- * condition vars exist there.
962
+ * 3. **The start contexts** — a definition's `start.filter` and
963
+ * `start.allowed` evaluate against a CANDIDATE (no instance exists yet):
964
+ * `*[...]` reads the WORKFLOW resource's dataset and none of the rendered
965
+ * condition vars exist. The two split on what a surface can know:
966
+ * `filter` is browse-time-pure (candidate document as root,
967
+ * {@link START_FILTER_VARS} — no `$fields`, which cannot exist before
968
+ * inputs do), `allowed` is the start-time permission predicate
969
+ * ({@link START_ALLOWED_VARS} — `$fields` bound, never a root).
847
970
  * 4. **Guard predicates** — NOT conditions. A lake mutation guard's
848
971
  * `predicate` is groq-js **delta-mode** GROQ over a document mutation:
849
972
  * `before()`/`after()`/`identity()` are dialect natives, and the wire
@@ -857,11 +980,20 @@ export declare interface ConditionVar {
857
980
  * instance and its snapshot.
858
981
  * - `'caller'` — rides the acting caller; without one the var is `undefined`
859
982
  * (conditions referencing it fail closed). Author predicates may not read
860
- * these — they pre-evaluate once per instance, caller-free.
983
+ * these — they pre-evaluate caller-free, per evaluation context.
861
984
  * - `'spawn'` — bound only at spawn sites (the per-row `$row`).
862
985
  */
863
986
  export declare type ConditionVarBinding = "always" | "caller" | "spawn";
864
987
 
988
+ /**
989
+ * The maximum reader floor this writer can emit. Individual documents derive
990
+ * their `minReaderModel` from the compatibility-bearing features actually
991
+ * present; a document written at {@link DATA_MODEL_VERSION} may therefore
992
+ * carry a lower floor. Raising this maximum is a declared, DATAMODEL.md-logged
993
+ * decision that requires readers-first fleet sequencing.
994
+ */
995
+ declare const DATA_MODEL_MIN_READER = 2;
996
+
865
997
  export declare function defineAction(action: AuthoringAction): AuthoringAction;
866
998
 
867
999
  export declare function defineActivity(
@@ -919,8 +1051,9 @@ export declare function defineWorkflow(
919
1051
  /**
920
1052
  * Validate a deploy config — the binding of each definition's logical resource
921
1053
  * handles to physical resources, per environment (tag). Throws a formatted,
922
- * path-prefixed error if the shape is invalid. The CLI hands the selected
923
- * deployment's {@link resourceAliasesToMap} map to {@link deployDefinitions}.
1054
+ * path-prefixed error if the shape is invalid. The CLI collapses the selected
1055
+ * deployment's bindings via {@link resourceAliasesToMap} into the
1056
+ * `resourceAliases` map `deployDefinitions` expands against.
924
1057
  */
925
1058
  export declare function defineWorkflowConfig(
926
1059
  config: WorkflowConfig,
@@ -1018,6 +1151,7 @@ declare const EffectSchema: v.StrictObjectSchema<
1018
1151
  declare const FIELD_VALUE_KINDS: readonly [
1019
1152
  "doc.ref",
1020
1153
  "doc.refs",
1154
+ "subject",
1021
1155
  "release.ref",
1022
1156
  "string",
1023
1157
  "text",
@@ -1054,6 +1188,8 @@ declare type FieldEntryFields<TEditable, TGroup> = FieldBase<
1054
1188
  TGroup
1055
1189
  > & {
1056
1190
  type: FieldValueKind;
1191
+ options?: ChoiceOptions | undefined;
1192
+ validation?: ScalarValidation | undefined;
1057
1193
  types?: string[] | undefined;
1058
1194
  fields?: FieldShape[] | undefined;
1059
1195
  of?: FieldShape[] | undefined;
@@ -1071,6 +1207,8 @@ declare interface FieldShape {
1071
1207
  name: string;
1072
1208
  title?: string | undefined;
1073
1209
  description?: string | undefined;
1210
+ options?: ChoiceOptions | undefined;
1211
+ validation?: ScalarValidation | undefined;
1074
1212
  fields?: FieldShape[] | undefined;
1075
1213
  of?: FieldShape[] | undefined;
1076
1214
  }
@@ -1158,6 +1296,11 @@ export declare const GUARD_PREDICATE_VARS: readonly {
1158
1296
  /** Stored guards carry the printed string reads (the deploy resolver's input). */
1159
1297
  declare const GuardSchema: v.StrictObjectSchema<
1160
1298
  {
1299
+ /**
1300
+ * Lake-id-segment grammar (`^[a-z0-9][a-z0-9-]*$`, deploy-enforced): the
1301
+ * guard's lake `_id` derives from `(instanceId, name)` at stage entry.
1302
+ * Unique per definition.
1303
+ */
1161
1304
  name: v.SchemaWithPipe<
1162
1305
  readonly [
1163
1306
  v.StringSchema<undefined>,
@@ -1229,8 +1372,9 @@ declare const GuardSchema: v.StrictObjectSchema<
1229
1372
  /**
1230
1373
  * Lake GROQ predicate — a distinct eval context: delta-mode GROQ
1231
1374
  * reading the `before()`/`after()` natives, `mutation`, `guard`, and
1232
- * `identity()`. Bare ids/fields only. Omitted or empty means
1233
- * UNCONDITIONAL DENY.
1375
+ * `identity()`. Bare ids/fields only. Polarity: a result of strictly
1376
+ * `true` ALLOWS the matched mutation; anything else (false, null, an
1377
+ * evaluation error) DENIES. Omitted or empty means UNCONDITIONAL DENY.
1234
1378
  */
1235
1379
  predicate: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
1236
1380
  /**
@@ -1281,12 +1425,11 @@ declare type NotesField = FieldBase<AuthoringEditable, GroupMembership> & {
1281
1425
 
1282
1426
  declare type Op = v.InferOutput<typeof StoredOpSchema>;
1283
1427
 
1284
- /**
1285
- * Names an author's predicate may not use — engine-owned and author names
1286
- * share one namespace, so a predicate redefining a binding would silently
1287
- * shadow engine behaviour. Rejected at deploy; derived from
1288
- * {@link CONDITION_VARS}.
1289
- */
1428
+ declare type ParsedWorkflowConfig = v.InferOutput<typeof WorkflowConfigSchema>;
1429
+
1430
+ declare type ParsedWorkflowDeployment =
1431
+ ParsedWorkflowConfig["deployments"][number];
1432
+
1290
1433
  export declare const RESERVED_CONDITION_VARS: readonly string[];
1291
1434
 
1292
1435
  declare type RoleAliases = v.InferOutput<typeof RoleAliasesSchema>;
@@ -1346,6 +1489,13 @@ declare const RoleAliasesSchema: v.RecordSchema<
1346
1489
  undefined
1347
1490
  >;
1348
1491
 
1492
+ /** Inclusive scalar bounds. String/text bounds measure character length;
1493
+ * number bounds measure the numeric value. */
1494
+ declare interface ScalarValidation {
1495
+ min?: number | undefined;
1496
+ max?: number | undefined;
1497
+ }
1498
+
1349
1499
  declare type Stage = StageFields<
1350
1500
  FieldEntry,
1351
1501
  Activity,
@@ -1378,6 +1528,7 @@ declare type StartBlock = StartFields & {
1378
1528
  * authoring may omit it — so each variant declares it. */
1379
1529
  declare type StartFields = {
1380
1530
  filter?: string | undefined;
1531
+ allowed?: string | undefined;
1381
1532
  };
1382
1533
 
1383
1534
  /**
@@ -1762,7 +1913,9 @@ declare type ValueExprInternal =
1762
1913
 
1763
1914
  declare const WORKFLOW_LIFECYCLES: readonly ["standalone", "child"];
1764
1915
 
1765
- declare type WorkflowConfig = v.InferOutput<typeof WorkflowConfigSchema>;
1916
+ declare type WorkflowConfig = Omit<ParsedWorkflowConfig, "deployments"> & {
1917
+ deployments: WorkflowDeployment[];
1918
+ };
1766
1919
 
1767
1920
  declare const WorkflowConfigSchema: v.ObjectSchema<
1768
1921
  {
@@ -1777,6 +1930,10 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
1777
1930
  v.NonEmptyAction<string, "must not be empty">,
1778
1931
  ]
1779
1932
  >;
1933
+ readonly expectedMinReaderModel: v.OptionalSchema<
1934
+ v.CustomSchema<2, undefined>,
1935
+ undefined
1936
+ >;
1780
1937
  readonly tag: v.SchemaWithPipe<
1781
1938
  readonly [
1782
1939
  v.StringSchema<undefined>,
@@ -2038,6 +2195,7 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
2038
2195
  v.MinLengthAction<
2039
2196
  {
2040
2197
  name: string;
2198
+ expectedMinReaderModel?: 2 | undefined;
2041
2199
  tag: string;
2042
2200
  workflowResource:
2043
2201
  | {
@@ -2098,6 +2256,7 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
2098
2256
  v.CheckAction<
2099
2257
  {
2100
2258
  name: string;
2259
+ expectedMinReaderModel?: 2 | undefined;
2101
2260
  tag: string;
2102
2261
  workflowResource:
2103
2262
  | {
@@ -2196,8 +2355,21 @@ declare const WorkflowDefinitionSchema: v.GenericSchema<
2196
2355
  WorkflowFields<FieldEntry, Stage, StartBlock>
2197
2356
  >;
2198
2357
 
2358
+ declare type WorkflowDeployment = Omit<
2359
+ ParsedWorkflowDeployment,
2360
+ "expectedMinReaderModel"
2361
+ > & {
2362
+ expectedMinReaderModel: typeof DATA_MODEL_MIN_READER;
2363
+ };
2364
+
2199
2365
  /** Type-mirror of {@link workflowFields}, parameterised over field/stage/start. */
2200
2366
  declare type WorkflowFields<TField, TStage, TStart> = {
2367
+ /**
2368
+ * Lake-id-segment grammar (`^[a-z0-9][a-z0-9-]*$`, deploy-enforced): the
2369
+ * name interpolates into every deployed document id
2370
+ * (`<tag>.<name>.v<version>`). Stable identity — instances pin to it,
2371
+ * subworkflows resolve by it.
2372
+ */
2201
2373
  name: string;
2202
2374
  title: string;
2203
2375
  description?: string | undefined;