@sanity/workflow-engine 0.11.0 → 0.13.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.
@@ -4,6 +4,12 @@ function andConditions(parts) {
4
4
  if (present.length !== 0)
5
5
  return present.length === 1 ? present[0] : present.map((p) => `(${p})`).join(" && ");
6
6
  }
7
+ const UNIVERSAL_ROLE_ALIAS_KEY = "$all";
8
+ function normalizeRoleAliases(aliases) {
9
+ if (aliases === void 0 || !("*" in aliases)) return aliases;
10
+ const { ["*"]: universal, ...perRole } = aliases;
11
+ return { ...perRole, [UNIVERSAL_ROLE_ALIAS_KEY]: universal };
12
+ }
7
13
  function expandRequiredRoles(required, aliases) {
8
14
  if (aliases === void 0) return [...required];
9
15
  const out = /* @__PURE__ */ new Set();
@@ -11,25 +17,29 @@ function expandRequiredRoles(required, aliases) {
11
17
  out.add(role);
12
18
  for (const fulfiller of aliases[role] ?? []) out.add(fulfiller);
13
19
  }
14
- for (const fulfiller of aliases["*"] ?? []) out.add(fulfiller);
20
+ for (const fulfiller of aliases[UNIVERSAL_ROLE_ALIAS_KEY] ?? []) out.add(fulfiller);
15
21
  return [...out];
16
22
  }
17
- function actorFulfillsRole(actorRoles, required, aliases) {
23
+ function actorFulfillsRole({
24
+ actorRoles,
25
+ required,
26
+ aliases
27
+ }) {
18
28
  if (actorRoles === void 0 || actorRoles.length === 0) return !1;
19
29
  const accepted = new Set(expandRequiredRoles([required], aliases));
20
30
  return actorRoles.some((role) => accepted.has(role));
21
31
  }
22
- const TASK_STATUSES = ["pending", "active", "done", "skipped", "failed"], TERMINAL_TASK_STATUSES = ["done", "skipped", "failed"];
23
- function isTerminalTaskStatus(status) {
24
- return TERMINAL_TASK_STATUSES.includes(status);
32
+ const ACTIVITY_STATUSES = ["pending", "active", "done", "skipped", "failed"], TERMINAL_ACTIVITY_STATUSES = ["done", "skipped", "failed"];
33
+ function isTerminalActivityStatus(status) {
34
+ return TERMINAL_ACTIVITY_STATUSES.includes(status);
25
35
  }
26
- const FIELD_SCOPES = ["workflow", "stage", "task"], DOCUMENT_VALUE_PERMISSIONS = ["create", "read", "update"], MUTATION_GUARD_ACTIONS = [
36
+ const FIELD_SCOPES = ["workflow", "stage", "activity"], DOCUMENT_VALUE_PERMISSIONS = ["create", "read", "update"], MUTATION_GUARD_ACTIONS = [
27
37
  "create",
28
38
  "update",
29
39
  "delete",
30
40
  "publish",
31
41
  "unpublish"
32
- ], TASK_KINDS = ["user", "service", "script", "manual", "receive"], DRIVER_KINDS = ["person", "agent", "service", "engine"], NonEmpty = v.pipe(v.string(), v.minLength(1, "must be a non-empty string")), PositiveInt = v.pipe(v.number(), v.integer(), v.minValue(1)), GROQ_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
42
+ ], ACTIVITY_KINDS = ["user", "service", "script", "manual", "receive"], DRIVER_KINDS = ["person", "agent", "service", "engine"], NonEmpty = v.pipe(v.string(), v.minLength(1, "must be a non-empty string")), PositiveInt = v.pipe(v.number(), v.integer(), v.minValue(1)), GROQ_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
33
43
  function groqIdentifier(referencedAs) {
34
44
  return v.pipe(
35
45
  v.string(),
@@ -45,32 +55,31 @@ function picklist(options) {
45
55
  `Invalid option: expected one of ${options.map((o) => `"${o}"`).join("|")}`
46
56
  );
47
57
  }
48
- const SourceSchema = v.lazy(
58
+ function pinned() {
59
+ return (schema, ..._exact) => schema;
60
+ }
61
+ const LiteralSchema = v.strictObject({ type: v.literal("literal"), value: v.unknown() }), FieldReadSchema = v.strictObject({
62
+ type: v.literal("fieldRead"),
63
+ scope: v.optional(v.union([v.literal("workflow"), v.literal("stage")])),
64
+ field: NonEmpty,
65
+ path: v.optional(v.string())
66
+ }), FieldSourceSchema = v.union([
67
+ // The caller supplies it at start/spawn (`initialFields` / `subworkflows.with`).
68
+ v.strictObject({ type: v.literal("input") }),
69
+ // Computed once by running GROQ against the lake at materialisation.
70
+ v.strictObject({ type: v.literal("query"), query: NonEmpty }),
71
+ LiteralSchema,
72
+ FieldReadSchema
73
+ ]), ValueExprSchema = v.lazy(
49
74
  () => v.union([
50
- // Field-entry origins: who fills the entry, and when.
51
- v.strictObject({ type: v.literal("init") }),
52
- v.strictObject({ type: v.literal("write") }),
53
- v.strictObject({
54
- type: v.literal("query"),
55
- query: NonEmpty
56
- }),
57
- // Value sources: resolved to concrete JSON when an op or seed applies.
58
- v.strictObject({ type: v.literal("literal"), value: v.unknown() }),
75
+ LiteralSchema,
76
+ FieldReadSchema,
59
77
  v.strictObject({ type: v.literal("param"), param: NonEmpty }),
60
78
  v.strictObject({ type: v.literal("actor") }),
61
79
  v.strictObject({ type: v.literal("now") }),
62
80
  v.strictObject({ type: v.literal("self") }),
63
81
  v.strictObject({ type: v.literal("stage") }),
64
- v.strictObject({
65
- type: v.literal("fieldRead"),
66
- scope: v.optional(v.union([v.literal("workflow"), v.literal("stage")])),
67
- field: NonEmpty,
68
- path: v.optional(v.string())
69
- }),
70
- v.strictObject({
71
- type: v.literal("object"),
72
- fields: v.record(NonEmpty, SourceSchema)
73
- })
82
+ v.strictObject({ type: v.literal("object"), fields: v.record(NonEmpty, ValueExprSchema) })
74
83
  ])
75
84
  ), StoredFieldRefSchema = v.strictObject({
76
85
  scope: picklist(FIELD_SCOPES),
@@ -102,7 +111,7 @@ const StoredManualTargetSchema = manualTargetSchema(StoredFieldRefSchema), Autho
102
111
  v.strictObject({
103
112
  type: v.literal("field"),
104
113
  field: NonEmpty,
105
- equals: SourceSchema
114
+ equals: ValueExprSchema
106
115
  }),
107
116
  v.strictObject({ type: v.literal("all"), of: v.array(OpPredicateSchema) }),
108
117
  v.strictObject({ type: v.literal("any"), of: v.array(OpPredicateSchema) })
@@ -113,7 +122,7 @@ function opSchemas(targetSchema) {
113
122
  v.strictObject({
114
123
  type: v.literal("field.set"),
115
124
  target: targetSchema,
116
- value: SourceSchema
125
+ value: ValueExprSchema
117
126
  }),
118
127
  v.strictObject({
119
128
  type: v.literal("field.unset"),
@@ -122,13 +131,13 @@ function opSchemas(targetSchema) {
122
131
  v.strictObject({
123
132
  type: v.literal("field.append"),
124
133
  target: targetSchema,
125
- value: SourceSchema
134
+ value: ValueExprSchema
126
135
  }),
127
136
  v.strictObject({
128
137
  type: v.literal("field.updateWhere"),
129
138
  target: targetSchema,
130
139
  where: OpPredicateSchema,
131
- value: SourceSchema
140
+ value: ValueExprSchema
132
141
  }),
133
142
  v.strictObject({
134
143
  type: v.literal("field.removeWhere"),
@@ -137,17 +146,17 @@ function opSchemas(targetSchema) {
137
146
  })
138
147
  ];
139
148
  }
140
- const StoredOpSchema = v.variant("type", [
149
+ const StoredFieldOpSchema = v.variant("type", [...opSchemas(StoredFieldRefSchema)]), StoredOpSchema = v.variant("type", [
141
150
  ...opSchemas(StoredFieldRefSchema),
142
151
  v.strictObject({
143
152
  type: v.literal("status.set"),
144
- task: NonEmpty,
145
- status: picklist(TASK_STATUSES)
153
+ activity: NonEmpty,
154
+ status: picklist(ACTIVITY_STATUSES)
146
155
  })
147
- ]), StoredTransitionOpSchema = v.variant("type", [...opSchemas(StoredFieldRefSchema)]), AuditOpSchema = v.strictObject({
156
+ ]), StoredTransitionOpSchema = StoredFieldOpSchema, AuditOpSchema = v.strictObject({
148
157
  type: v.literal("audit"),
149
158
  target: AuthoringFieldRefSchema,
150
- value: SourceSchema,
159
+ value: ValueExprSchema,
151
160
  stampFields: v.optional(
152
161
  v.strictObject({
153
162
  actor: v.optional(NonEmpty),
@@ -158,33 +167,83 @@ const StoredOpSchema = v.variant("type", [
158
167
  ...opSchemas(AuthoringFieldRefSchema),
159
168
  v.strictObject({
160
169
  type: v.literal("status.set"),
161
- task: v.optional(NonEmpty),
162
- status: picklist(TASK_STATUSES)
170
+ activity: v.optional(NonEmpty),
171
+ status: picklist(ACTIVITY_STATUSES)
163
172
  }),
164
173
  AuditOpSchema
165
- ]), FieldKindSchema = picklist([
174
+ ]), FIELD_VALUE_KINDS = [
166
175
  "doc.ref",
167
176
  "doc.refs",
168
177
  // Release reference. A workflow declares this entry to say "I target a
169
178
  // Content Release"; the runtime fills it at start time and auto-derives
170
179
  // the instance's read perspective from it.
171
180
  "release.ref",
172
- "query",
173
- "value.string",
174
- "value.url",
175
- "value.number",
176
- "value.boolean",
177
- "value.dateTime",
178
- "value.actor",
179
- "checklist",
180
- "notes",
181
+ "string",
182
+ "text",
183
+ "number",
184
+ "boolean",
185
+ "date",
186
+ "datetime",
187
+ "url",
188
+ "actor",
189
+ // A single {@link Assignee} — the singular of `assignees`.
190
+ "assignee",
181
191
  // The WHO-FOR entry: the inbox reverse-query reads it by kind, and the
182
192
  // rendered `$assigned` gate matches the caller against it.
183
- "assignees"
184
- ]), FieldEntryName = groqIdentifier("`$fields.<name>`"), StoredEditableSchema = v.union([v.literal(!0), NonEmpty]), AuthoringEditableSchema = v.union([v.literal(!0), v.array(NonEmpty), NonEmpty]);
185
- function fieldEntryFields(editable) {
193
+ "assignees",
194
+ // Compositional kinds mirror Sanity's `object.fields` / `array.of`.
195
+ "object",
196
+ "array"
197
+ ], FieldValueKindSchema = picklist(FIELD_VALUE_KINDS), FieldKindSchema = picklist(FIELD_VALUE_KINDS), FieldEntryName = groqIdentifier("`$fields.<name>`");
198
+ function asShape(input) {
199
+ return typeof input == "object" && input !== null ? input : {};
200
+ }
201
+ function compositeShapeOk(input) {
202
+ const shape = asShape(input);
203
+ return shape.type === "object" ? Array.isArray(shape.fields) && shape.fields.length > 0 && shape.of === void 0 : shape.type === "array" ? Array.isArray(shape.of) && shape.of.length > 0 && shape.fields === void 0 : shape.fields === void 0 && shape.of === void 0;
204
+ }
205
+ function compositeShapeMessage(input) {
206
+ const shape = asShape(input);
207
+ return shape.type === "object" ? shape.of !== void 0 ? "an `object` kind declares its sub-fields with `fields`, not `of`" : "an `object` kind needs a non-empty `fields` list of sub-field shapes" : shape.type === "array" ? shape.fields !== void 0 ? "an `array` kind declares its item shape with `of`, not `fields`" : "an `array` kind needs a non-empty `of` list of sub-field shapes" : `\`fields\` / \`of\` are only valid on the \`object\` / \`array\` kinds, not "${String(shape.type)}"`;
208
+ }
209
+ function duplicateSubfieldName(input) {
210
+ const shape = asShape(input);
211
+ let list = [];
212
+ Array.isArray(shape.fields) ? list = shape.fields : Array.isArray(shape.of) && (list = shape.of);
213
+ const seen = /* @__PURE__ */ new Set();
214
+ for (const item of list) {
215
+ const name = asShape(item).name;
216
+ if (typeof name == "string") {
217
+ if (seen.has(name)) return name;
218
+ seen.add(name);
219
+ }
220
+ }
221
+ }
222
+ function compositeChecked(entries) {
223
+ return v.pipe(
224
+ v.strictObject(entries),
225
+ v.check(
226
+ (input) => compositeShapeOk(input),
227
+ (issue) => compositeShapeMessage(issue.input)
228
+ ),
229
+ v.check(
230
+ (input) => duplicateSubfieldName(input) === void 0,
231
+ (issue) => `duplicate sub-field name "${duplicateSubfieldName(issue.input)}" \u2014 sub-field names must be unique within \`fields\` / \`of\``
232
+ )
233
+ );
234
+ }
235
+ const FieldShapeSchema = v.lazy(
236
+ () => compositeChecked({
237
+ type: FieldValueKindSchema,
238
+ name: FieldEntryName,
239
+ title: v.optional(v.string()),
240
+ description: v.optional(v.string()),
241
+ fields: v.optional(v.array(FieldShapeSchema)),
242
+ of: v.optional(v.array(FieldShapeSchema))
243
+ })
244
+ ), StoredEditableSchema = v.union([v.literal(!0), NonEmpty]), AuthoringEditableSchema = v.union([v.literal(!0), v.array(NonEmpty), NonEmpty]);
245
+ function slotFields(editable) {
186
246
  return {
187
- type: FieldKindSchema,
188
247
  name: FieldEntryName,
189
248
  title: v.optional(v.string()),
190
249
  description: v.optional(v.string()),
@@ -193,20 +252,50 @@ function fieldEntryFields(editable) {
193
252
  * `initialFields`) or spawn (via the parent's `subworkflows.with`). A
194
253
  * missing required entry throws rather than silently defaulting to
195
254
  * `null`/`[]` — the same fail-fast an action's `required` param gets.
196
- * Valid only on a workflow-scope `init`-sourced entry (deploy invariant).
255
+ * Valid only on a workflow-scope `input`-sourced entry (deploy invariant).
197
256
  */
198
257
  required: v.optional(v.boolean()),
199
- source: SourceSchema,
258
+ /**
259
+ * How this field SEEDS its value at materialisation — see
260
+ * {@link FieldSourceSchema}. Optional: an absent `initialValue` is working
261
+ * memory (the slot starts empty and an op fills it later), the common case.
262
+ */
263
+ initialValue: v.optional(FieldSourceSchema),
200
264
  /** Who-may-edit this slot via the edit seam — see {@link StoredEditableSchema}. */
201
265
  editable: v.optional(editable)
202
266
  };
203
267
  }
204
- const FieldEntrySchema = v.strictObject(fieldEntryFields(StoredEditableSchema)), RawAuthoringFieldEntrySchema = v.strictObject(fieldEntryFields(AuthoringEditableSchema)), ClaimFieldSchema = v.strictObject({
205
- type: v.literal("claim"),
206
- name: FieldEntryName,
207
- title: v.optional(v.string()),
208
- description: v.optional(v.string())
209
- }), AuthoringFieldEntrySchema = v.union([RawAuthoringFieldEntrySchema, ClaimFieldSchema]), ConditionSchema = NonEmpty, EffectSchema = v.strictObject({
268
+ function fieldEntryFields(editable) {
269
+ return {
270
+ type: FieldKindSchema,
271
+ ...slotFields(editable),
272
+ /** Sub-field shapes for an `object` kind (see {@link compositeShapeOk}). */
273
+ fields: v.optional(v.array(FieldShapeSchema)),
274
+ /** Item sub-field shapes for an `array` kind (see {@link compositeShapeOk}). */
275
+ of: v.optional(v.array(FieldShapeSchema))
276
+ };
277
+ }
278
+ const FieldEntrySchema = pinned()(
279
+ compositeChecked(fieldEntryFields(StoredEditableSchema))
280
+ ), RawAuthoringFieldEntrySchema = pinned()(
281
+ compositeChecked(fieldEntryFields(AuthoringEditableSchema))
282
+ ), ClaimFieldSchema = pinned()(
283
+ v.strictObject({
284
+ type: v.literal("claim"),
285
+ name: FieldEntryName,
286
+ title: v.optional(v.string()),
287
+ description: v.optional(v.string())
288
+ })
289
+ );
290
+ function listSugarFields(type) {
291
+ return {
292
+ type: v.literal(type),
293
+ ...slotFields(AuthoringEditableSchema)
294
+ };
295
+ }
296
+ const TodoListFieldSchema = pinned()(v.strictObject(listSugarFields("todoList"))), NotesFieldSchema = pinned()(v.strictObject(listSugarFields("notes"))), AuthoringFieldEntrySchema = pinned()(
297
+ v.union([RawAuthoringFieldEntrySchema, ClaimFieldSchema, TodoListFieldSchema, NotesFieldSchema])
298
+ ), ConditionSchema = NonEmpty, EffectSchema = v.strictObject({
210
299
  name: NonEmpty,
211
300
  title: v.optional(v.string()),
212
301
  description: v.optional(v.string()),
@@ -247,21 +336,27 @@ function actionFields(op) {
247
336
  effects: v.optional(v.array(EffectSchema))
248
337
  };
249
338
  }
250
- const StoredActionSchema = v.strictObject(actionFields(StoredOpSchema)), TerminalTaskStatus = picklist(TERMINAL_TASK_STATUSES), RawAuthoringActionSchema = v.strictObject({
251
- ...actionFields(AuthoringOpSchema),
252
- roles: v.optional(v.array(NonEmpty)),
253
- status: v.optional(TerminalTaskStatus)
254
- }), ClaimActionSchema = v.strictObject({
255
- type: v.literal("claim"),
256
- name: NonEmpty,
257
- title: v.optional(v.string()),
258
- description: v.optional(v.string()),
259
- field: v.union([NonEmpty, AuthoringFieldRefSchema]),
260
- roles: v.optional(v.array(NonEmpty)),
261
- filter: v.optional(ConditionSchema),
262
- params: v.optional(v.array(ActionParamSchema)),
263
- effects: v.optional(v.array(EffectSchema))
264
- }), AuthoringActionSchema = v.union([RawAuthoringActionSchema, ClaimActionSchema]), DefinitionRefSchema = v.strictObject({
339
+ const StoredActionSchema = pinned()(v.strictObject(actionFields(StoredOpSchema))), TerminalActivityStatus = picklist(TERMINAL_ACTIVITY_STATUSES), RawAuthoringActionSchema = pinned()(
340
+ v.strictObject({
341
+ ...actionFields(AuthoringOpSchema),
342
+ roles: v.optional(v.array(NonEmpty)),
343
+ status: v.optional(TerminalActivityStatus)
344
+ })
345
+ ), ClaimActionSchema = pinned()(
346
+ v.strictObject({
347
+ type: v.literal("claim"),
348
+ name: NonEmpty,
349
+ title: v.optional(v.string()),
350
+ description: v.optional(v.string()),
351
+ field: v.union([NonEmpty, AuthoringFieldRefSchema]),
352
+ roles: v.optional(v.array(NonEmpty)),
353
+ filter: v.optional(ConditionSchema),
354
+ params: v.optional(v.array(ActionParamSchema)),
355
+ effects: v.optional(v.array(EffectSchema))
356
+ })
357
+ ), AuthoringActionSchema = pinned()(
358
+ v.union([RawAuthoringActionSchema, ClaimActionSchema])
359
+ ), DefinitionRefSchema = v.strictObject({
265
360
  name: NonEmpty,
266
361
  version: v.optional(v.union([PositiveInt, v.literal("latest")]))
267
362
  }), SubworkflowsSchema = v.strictObject({
@@ -277,27 +372,27 @@ const StoredActionSchema = v.strictObject(actionFields(StoredOpSchema)), Termina
277
372
  */
278
373
  context: v.optional(v.record(NonEmpty, ConditionSchema))
279
374
  });
280
- function taskFields(field, action, op, target) {
375
+ function activityFields({ field, action, op, target }) {
281
376
  return {
282
377
  name: NonEmpty,
283
378
  title: v.optional(v.string()),
284
379
  description: v.optional(v.string()),
285
380
  /**
286
- * Advisory BPMN-aligned classification of this task by its executor (see
287
- * {@link TASK_KINDS}). Optional and derived from the task's shape when
381
+ * Advisory BPMN-aligned classification of this activity by its executor (see
382
+ * {@link ACTIVITY_KINDS}). Optional and derived from the activity's shape when
288
383
  * omitted; declaring it lets deploy check the shape matches the lane.
289
384
  * Changes no gating or resolution — a label for tooling, like `assignees`.
290
385
  */
291
- kind: v.optional(picklist(TASK_KINDS)),
292
- /** Deep-link target for a `kind: "manual"` task (off-system work). Render-only
293
- * metadata; only valid on a manual task (deploy-checked). */
386
+ kind: v.optional(picklist(ACTIVITY_KINDS)),
387
+ /** Deep-link target for a `kind: "manual"` activity (off-system work). Render-only
388
+ * metadata; only valid on a manual activity (deploy-checked). */
294
389
  target: v.optional(target),
295
390
  activation: v.optional(picklist(["auto", "manual"])),
296
391
  filter: v.optional(ConditionSchema),
297
392
  /**
298
393
  * Readiness gates, by name — conditions over the rendered scope that must
299
- * hold for the task to be *executable*, orthogonal to `filter`
300
- * (visibility). An unmet requirement keeps the task visible but disables
394
+ * hold for the activity to be *executable*, orthogonal to `filter`
395
+ * (visibility). An unmet requirement keeps the activity visible but disables
301
396
  * its actions with a `requirements-unmet` verdict naming the unmet keys;
302
397
  * all must hold (any-of lives inside one condition). Advisory like every
303
398
  * engine gate — the lake still enforces. Distinct from ACL (authorization)
@@ -306,8 +401,8 @@ function taskFields(field, action, op, target) {
306
401
  requirements: v.optional(v.record(NonEmpty, ConditionSchema)),
307
402
  /**
308
403
  * Auto-completion condition — evaluated at activation and on every
309
- * cascade; truthy flips the task to `done` with a system actor. On a
310
- * spawning task it typically reads `$subworkflows`.
404
+ * cascade; truthy flips the activity to `done` with a system actor. On a
405
+ * spawning activity it typically reads `$subworkflows`.
311
406
  */
312
407
  completeWhen: v.optional(ConditionSchema),
313
408
  /**
@@ -320,18 +415,27 @@ function taskFields(field, action, op, target) {
320
415
  effects: v.optional(v.array(EffectSchema)),
321
416
  actions: v.optional(v.array(action)),
322
417
  subworkflows: v.optional(SubworkflowsSchema),
323
- /** Task-scoped field entries. Resolved at task activation time. */
418
+ /** Activity-scoped field entries. Resolved at activity activation time. */
324
419
  fields: v.optional(v.array(field))
325
420
  };
326
421
  }
327
- const StoredTaskSchema = v.strictObject(
328
- taskFields(FieldEntrySchema, StoredActionSchema, StoredOpSchema, StoredManualTargetSchema)
329
- ), AuthoringTaskSchema = v.strictObject(
330
- taskFields(
331
- AuthoringFieldEntrySchema,
332
- AuthoringActionSchema,
333
- AuthoringOpSchema,
334
- AuthoringManualTargetSchema
422
+ const StoredActivitySchema = pinned()(
423
+ v.strictObject(
424
+ activityFields({
425
+ field: FieldEntrySchema,
426
+ action: StoredActionSchema,
427
+ op: StoredOpSchema,
428
+ target: StoredManualTargetSchema
429
+ })
430
+ )
431
+ ), AuthoringActivitySchema = pinned()(
432
+ v.strictObject(
433
+ activityFields({
434
+ field: AuthoringFieldEntrySchema,
435
+ action: AuthoringActionSchema,
436
+ op: AuthoringOpSchema,
437
+ target: AuthoringManualTargetSchema
438
+ })
335
439
  )
336
440
  );
337
441
  function transitionFields(op, filter) {
@@ -346,13 +450,13 @@ function transitionFields(op, filter) {
346
450
  effects: v.optional(v.array(EffectSchema))
347
451
  };
348
452
  }
349
- const StoredTransitionSchema = v.strictObject(
350
- transitionFields(StoredTransitionOpSchema, ConditionSchema)
453
+ const StoredTransitionSchema = pinned()(
454
+ v.strictObject(transitionFields(StoredTransitionOpSchema, ConditionSchema))
351
455
  ), AuthoringTransitionOpSchema = v.variant("type", [
352
456
  ...opSchemas(AuthoringFieldRefSchema),
353
457
  AuditOpSchema
354
- ]), AuthoringTransitionSchema = v.strictObject(
355
- transitionFields(AuthoringTransitionOpSchema, v.optional(ConditionSchema))
458
+ ]), AuthoringTransitionSchema = pinned()(
459
+ v.strictObject(transitionFields(AuthoringTransitionOpSchema, v.optional(ConditionSchema)))
356
460
  ), GuardActionSchema = picklist(MUTATION_GUARD_ACTIONS), GuardMatchSchema = v.strictObject({
357
461
  /** Subject `_type`(s); empty matches any type. */
358
462
  types: v.optional(v.array(NonEmpty)),
@@ -386,12 +490,17 @@ const StoredTransitionSchema = v.strictObject(
386
490
  */
387
491
  metadata: v.optional(v.record(NonEmpty, NonEmpty))
388
492
  });
389
- function stageFields(field, task, transition, editable) {
493
+ function stageFields({
494
+ field,
495
+ activity,
496
+ transition,
497
+ editable
498
+ }) {
390
499
  return {
391
500
  name: NonEmpty,
392
501
  title: v.optional(v.string()),
393
502
  description: v.optional(v.string()),
394
- tasks: v.optional(v.array(task)),
503
+ activities: v.optional(v.array(activity)),
395
504
  transitions: v.optional(v.array(transition)),
396
505
  /**
397
506
  * Lake mutation guards active while this stage holds. Each compiles to a
@@ -410,14 +519,23 @@ function stageFields(field, task, transition, editable) {
410
519
  editable: v.optional(v.record(FieldEntryName, editable))
411
520
  };
412
521
  }
413
- const StoredStageSchema = v.strictObject(
414
- stageFields(FieldEntrySchema, StoredTaskSchema, StoredTransitionSchema, StoredEditableSchema)
415
- ), AuthoringStageSchema = v.strictObject(
416
- stageFields(
417
- AuthoringFieldEntrySchema,
418
- AuthoringTaskSchema,
419
- AuthoringTransitionSchema,
420
- AuthoringEditableSchema
522
+ const StoredStageSchema = pinned()(
523
+ v.strictObject(
524
+ stageFields({
525
+ field: FieldEntrySchema,
526
+ activity: StoredActivitySchema,
527
+ transition: StoredTransitionSchema,
528
+ editable: StoredEditableSchema
529
+ })
530
+ )
531
+ ), AuthoringStageSchema = pinned()(
532
+ v.strictObject(
533
+ stageFields({
534
+ field: AuthoringFieldEntrySchema,
535
+ activity: AuthoringActivitySchema,
536
+ transition: AuthoringTransitionSchema,
537
+ editable: AuthoringEditableSchema
538
+ })
421
539
  )
422
540
  ), RoleAliasesSchema = v.record(
423
541
  NonEmpty,
@@ -426,12 +544,11 @@ const StoredStageSchema = v.strictObject(
426
544
  function workflowFields(field, stage) {
427
545
  return {
428
546
  name: NonEmpty,
429
- version: PositiveInt,
430
547
  title: NonEmpty,
431
548
  description: v.optional(v.string()),
432
549
  /**
433
550
  * Whether a human may start this workflow standalone. `'child'` marks a
434
- * spawn-only definition — instantiated by a parent via `task.subworkflows`,
551
+ * spawn-only definition — instantiated by a parent via `activity.subworkflows`,
435
552
  * never started cold from a picker. Omitted ⇒ `'workflow'` (startable).
436
553
  * Advisory: consumers filter their start pickers on it (see
437
554
  * {@link isStartableDefinition}); the engine does NOT refuse a
@@ -454,9 +571,11 @@ function workflowFields(field, stage) {
454
571
  roleAliases: v.optional(RoleAliasesSchema)
455
572
  };
456
573
  }
457
- v.strictObject(workflowFields(FieldEntrySchema, StoredStageSchema));
458
- const AuthoringWorkflowSchema = v.strictObject(
459
- workflowFields(AuthoringFieldEntrySchema, AuthoringStageSchema)
574
+ pinned()(
575
+ v.strictObject(workflowFields(FieldEntrySchema, StoredStageSchema))
576
+ );
577
+ const AuthoringWorkflowSchema = pinned()(
578
+ v.strictObject(workflowFields(AuthoringFieldEntrySchema, AuthoringStageSchema))
460
579
  ), WORKFLOW_DEFINITION_TYPE = "sanity.workflow.definition";
461
580
  function isStartableDefinition(definition) {
462
581
  return definition.role !== "child";
@@ -480,11 +599,12 @@ function formatPath(path) {
480
599
  return out;
481
600
  }
482
601
  export {
602
+ ACTIVITY_KINDS,
483
603
  AuthoringActionSchema,
604
+ AuthoringActivitySchema,
484
605
  AuthoringFieldEntrySchema,
485
606
  AuthoringOpSchema,
486
607
  AuthoringStageSchema,
487
- AuthoringTaskSchema,
488
608
  AuthoringTransitionSchema,
489
609
  AuthoringWorkflowSchema,
490
610
  DOCUMENT_VALUE_PERMISSIONS,
@@ -492,14 +612,15 @@ export {
492
612
  EffectSchema,
493
613
  GROQ_IDENTIFIER,
494
614
  GuardSchema,
495
- TASK_KINDS,
615
+ StoredFieldOpSchema,
496
616
  WORKFLOW_DEFINITION_TYPE,
497
617
  actorFulfillsRole,
498
618
  andConditions,
499
619
  expandRequiredRoles,
500
620
  formatValidationError,
501
621
  isStartableDefinition,
502
- isTerminalTaskStatus,
503
- issuesFromValibot
622
+ isTerminalActivityStatus,
623
+ issuesFromValibot,
624
+ normalizeRoleAliases
504
625
  };
505
626
  //# sourceMappingURL=schema.js.map