@sanity/workflow-engine 0.10.0 → 0.12.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,7 +17,7 @@ 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
23
  function actorFulfillsRole(actorRoles, required, aliases) {
@@ -19,17 +25,17 @@ function actorFulfillsRole(actorRoles, required, aliases) {
19
25
  const accepted = new Set(expandRequiredRoles([required], aliases));
20
26
  return actorRoles.some((role) => accepted.has(role));
21
27
  }
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);
28
+ const ACTIVITY_STATUSES = ["pending", "active", "done", "skipped", "failed"], TERMINAL_ACTIVITY_STATUSES = ["done", "skipped", "failed"];
29
+ function isTerminalActivityStatus(status) {
30
+ return TERMINAL_ACTIVITY_STATUSES.includes(status);
25
31
  }
26
- const FIELD_SCOPES = ["workflow", "stage", "task"], DOCUMENT_VALUE_PERMISSIONS = ["create", "read", "update"], MUTATION_GUARD_ACTIONS = [
32
+ const FIELD_SCOPES = ["workflow", "stage", "activity"], DOCUMENT_VALUE_PERMISSIONS = ["create", "read", "update"], MUTATION_GUARD_ACTIONS = [
27
33
  "create",
28
34
  "update",
29
35
  "delete",
30
36
  "publish",
31
37
  "unpublish"
32
- ], 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_]*$/;
38
+ ], 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
39
  function groqIdentifier(referencedAs) {
34
40
  return v.pipe(
35
41
  v.string(),
@@ -45,32 +51,28 @@ function picklist(options) {
45
51
  `Invalid option: expected one of ${options.map((o) => `"${o}"`).join("|")}`
46
52
  );
47
53
  }
48
- const SourceSchema = v.lazy(
54
+ const LiteralSchema = v.strictObject({ type: v.literal("literal"), value: v.unknown() }), FieldReadSchema = v.strictObject({
55
+ type: v.literal("fieldRead"),
56
+ scope: v.optional(v.union([v.literal("workflow"), v.literal("stage")])),
57
+ field: NonEmpty,
58
+ path: v.optional(v.string())
59
+ }), FieldSourceSchema = v.union([
60
+ // The caller supplies it at start/spawn (`initialFields` / `subworkflows.with`).
61
+ v.strictObject({ type: v.literal("input") }),
62
+ // Computed once by running GROQ against the lake at materialisation.
63
+ v.strictObject({ type: v.literal("query"), query: NonEmpty }),
64
+ LiteralSchema,
65
+ FieldReadSchema
66
+ ]), ValueExprSchema = v.lazy(
49
67
  () => 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() }),
68
+ LiteralSchema,
69
+ FieldReadSchema,
59
70
  v.strictObject({ type: v.literal("param"), param: NonEmpty }),
60
71
  v.strictObject({ type: v.literal("actor") }),
61
72
  v.strictObject({ type: v.literal("now") }),
62
73
  v.strictObject({ type: v.literal("self") }),
63
74
  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
- })
75
+ v.strictObject({ type: v.literal("object"), fields: v.record(NonEmpty, ValueExprSchema) })
74
76
  ])
75
77
  ), StoredFieldRefSchema = v.strictObject({
76
78
  scope: picklist(FIELD_SCOPES),
@@ -78,12 +80,31 @@ const SourceSchema = v.lazy(
78
80
  }), AuthoringFieldRefSchema = v.strictObject({
79
81
  scope: v.optional(picklist(FIELD_SCOPES)),
80
82
  field: NonEmpty
81
- }), OpPredicateSchema = v.lazy(
83
+ }), HREF_SCHEMES = ["http:", "https:"];
84
+ function isHttpUrl(value) {
85
+ try {
86
+ return HREF_SCHEMES.includes(new URL(value).protocol);
87
+ } catch {
88
+ return !1;
89
+ }
90
+ }
91
+ const UrlString = v.pipe(
92
+ v.string(),
93
+ v.url("must be a valid URL"),
94
+ v.check(isHttpUrl, "must be an http(s) URL")
95
+ );
96
+ function manualTargetSchema(ref) {
97
+ return v.variant("type", [
98
+ v.strictObject({ type: v.literal("url"), url: UrlString }),
99
+ v.strictObject({ type: v.literal("field"), field: ref })
100
+ ]);
101
+ }
102
+ const StoredManualTargetSchema = manualTargetSchema(StoredFieldRefSchema), AuthoringManualTargetSchema = manualTargetSchema(v.union([NonEmpty, AuthoringFieldRefSchema])), OpPredicateSchema = v.lazy(
82
103
  () => v.union([
83
104
  v.strictObject({
84
105
  type: v.literal("field"),
85
106
  field: NonEmpty,
86
- equals: SourceSchema
107
+ equals: ValueExprSchema
87
108
  }),
88
109
  v.strictObject({ type: v.literal("all"), of: v.array(OpPredicateSchema) }),
89
110
  v.strictObject({ type: v.literal("any"), of: v.array(OpPredicateSchema) })
@@ -94,7 +115,7 @@ function opSchemas(targetSchema) {
94
115
  v.strictObject({
95
116
  type: v.literal("field.set"),
96
117
  target: targetSchema,
97
- value: SourceSchema
118
+ value: ValueExprSchema
98
119
  }),
99
120
  v.strictObject({
100
121
  type: v.literal("field.unset"),
@@ -103,13 +124,13 @@ function opSchemas(targetSchema) {
103
124
  v.strictObject({
104
125
  type: v.literal("field.append"),
105
126
  target: targetSchema,
106
- value: SourceSchema
127
+ value: ValueExprSchema
107
128
  }),
108
129
  v.strictObject({
109
130
  type: v.literal("field.updateWhere"),
110
131
  target: targetSchema,
111
132
  where: OpPredicateSchema,
112
- value: SourceSchema
133
+ value: ValueExprSchema
113
134
  }),
114
135
  v.strictObject({
115
136
  type: v.literal("field.removeWhere"),
@@ -122,13 +143,13 @@ const StoredOpSchema = v.variant("type", [
122
143
  ...opSchemas(StoredFieldRefSchema),
123
144
  v.strictObject({
124
145
  type: v.literal("status.set"),
125
- task: NonEmpty,
126
- status: picklist(TASK_STATUSES)
146
+ activity: NonEmpty,
147
+ status: picklist(ACTIVITY_STATUSES)
127
148
  })
128
149
  ]), StoredTransitionOpSchema = v.variant("type", [...opSchemas(StoredFieldRefSchema)]), AuditOpSchema = v.strictObject({
129
150
  type: v.literal("audit"),
130
151
  target: AuthoringFieldRefSchema,
131
- value: SourceSchema,
152
+ value: ValueExprSchema,
132
153
  stampFields: v.optional(
133
154
  v.strictObject({
134
155
  actor: v.optional(NonEmpty),
@@ -139,33 +160,83 @@ const StoredOpSchema = v.variant("type", [
139
160
  ...opSchemas(AuthoringFieldRefSchema),
140
161
  v.strictObject({
141
162
  type: v.literal("status.set"),
142
- task: v.optional(NonEmpty),
143
- status: picklist(TASK_STATUSES)
163
+ activity: v.optional(NonEmpty),
164
+ status: picklist(ACTIVITY_STATUSES)
144
165
  }),
145
166
  AuditOpSchema
146
- ]), FieldKindSchema = picklist([
167
+ ]), FIELD_VALUE_KINDS = [
147
168
  "doc.ref",
148
169
  "doc.refs",
149
170
  // Release reference. A workflow declares this entry to say "I target a
150
171
  // Content Release"; the runtime fills it at start time and auto-derives
151
172
  // the instance's read perspective from it.
152
173
  "release.ref",
153
- "query",
154
- "value.string",
155
- "value.url",
156
- "value.number",
157
- "value.boolean",
158
- "value.dateTime",
159
- "value.actor",
160
- "checklist",
161
- "notes",
174
+ "string",
175
+ "text",
176
+ "number",
177
+ "boolean",
178
+ "date",
179
+ "datetime",
180
+ "url",
181
+ "actor",
182
+ // A single {@link Assignee} — the singular of `assignees`.
183
+ "assignee",
162
184
  // The WHO-FOR entry: the inbox reverse-query reads it by kind, and the
163
185
  // rendered `$assigned` gate matches the caller against it.
164
- "assignees"
165
- ]), FieldEntryName = groqIdentifier("`$fields.<name>`"), StoredEditableSchema = v.union([v.literal(!0), NonEmpty]), AuthoringEditableSchema = v.union([v.literal(!0), v.array(NonEmpty), NonEmpty]);
166
- function fieldEntryFields(editable) {
186
+ "assignees",
187
+ // Compositional kinds mirror Sanity's `object.fields` / `array.of`.
188
+ "object",
189
+ "array"
190
+ ], FieldValueKindSchema = picklist(FIELD_VALUE_KINDS), FieldKindSchema = picklist(FIELD_VALUE_KINDS), FieldEntryName = groqIdentifier("`$fields.<name>`");
191
+ function asShape(input) {
192
+ return typeof input == "object" && input !== null ? input : {};
193
+ }
194
+ function compositeShapeOk(input) {
195
+ const shape = asShape(input);
196
+ 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;
197
+ }
198
+ function compositeShapeMessage(input) {
199
+ const shape = asShape(input);
200
+ 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)}"`;
201
+ }
202
+ function duplicateSubfieldName(input) {
203
+ const shape = asShape(input);
204
+ let list = [];
205
+ Array.isArray(shape.fields) ? list = shape.fields : Array.isArray(shape.of) && (list = shape.of);
206
+ const seen = /* @__PURE__ */ new Set();
207
+ for (const item of list) {
208
+ const name = asShape(item).name;
209
+ if (typeof name == "string") {
210
+ if (seen.has(name)) return name;
211
+ seen.add(name);
212
+ }
213
+ }
214
+ }
215
+ function compositeChecked(entries) {
216
+ return v.pipe(
217
+ v.strictObject(entries),
218
+ v.check(
219
+ (input) => compositeShapeOk(input),
220
+ (issue) => compositeShapeMessage(issue.input)
221
+ ),
222
+ v.check(
223
+ (input) => duplicateSubfieldName(input) === void 0,
224
+ (issue) => `duplicate sub-field name "${duplicateSubfieldName(issue.input)}" \u2014 sub-field names must be unique within \`fields\` / \`of\``
225
+ )
226
+ );
227
+ }
228
+ const FieldShapeSchema = v.lazy(
229
+ () => compositeChecked({
230
+ type: FieldValueKindSchema,
231
+ name: FieldEntryName,
232
+ title: v.optional(v.string()),
233
+ description: v.optional(v.string()),
234
+ fields: v.optional(v.array(FieldShapeSchema)),
235
+ of: v.optional(v.array(FieldShapeSchema))
236
+ })
237
+ ), StoredEditableSchema = v.union([v.literal(!0), NonEmpty]), AuthoringEditableSchema = v.union([v.literal(!0), v.array(NonEmpty), NonEmpty]);
238
+ function slotFields(editable) {
167
239
  return {
168
- type: FieldKindSchema,
169
240
  name: FieldEntryName,
170
241
  title: v.optional(v.string()),
171
242
  description: v.optional(v.string()),
@@ -174,20 +245,47 @@ function fieldEntryFields(editable) {
174
245
  * `initialFields`) or spawn (via the parent's `subworkflows.with`). A
175
246
  * missing required entry throws rather than silently defaulting to
176
247
  * `null`/`[]` — the same fail-fast an action's `required` param gets.
177
- * Valid only on a workflow-scope `init`-sourced entry (deploy invariant).
248
+ * Valid only on a workflow-scope `input`-sourced entry (deploy invariant).
178
249
  */
179
250
  required: v.optional(v.boolean()),
180
- source: SourceSchema,
251
+ /**
252
+ * How this field SEEDS its value at materialisation — see
253
+ * {@link FieldSourceSchema}. Optional: an absent `initialValue` is working
254
+ * memory (the slot starts empty and an op fills it later), the common case.
255
+ */
256
+ initialValue: v.optional(FieldSourceSchema),
181
257
  /** Who-may-edit this slot via the edit seam — see {@link StoredEditableSchema}. */
182
258
  editable: v.optional(editable)
183
259
  };
184
260
  }
185
- const FieldEntrySchema = v.strictObject(fieldEntryFields(StoredEditableSchema)), RawAuthoringFieldEntrySchema = v.strictObject(fieldEntryFields(AuthoringEditableSchema)), ClaimFieldSchema = v.strictObject({
261
+ function fieldEntryFields(editable) {
262
+ return {
263
+ type: FieldKindSchema,
264
+ ...slotFields(editable),
265
+ /** Sub-field shapes for an `object` kind (see {@link compositeShapeOk}). */
266
+ fields: v.optional(v.array(FieldShapeSchema)),
267
+ /** Item sub-field shapes for an `array` kind (see {@link compositeShapeOk}). */
268
+ of: v.optional(v.array(FieldShapeSchema))
269
+ };
270
+ }
271
+ const FieldEntrySchema = compositeChecked(fieldEntryFields(StoredEditableSchema)), RawAuthoringFieldEntrySchema = compositeChecked(fieldEntryFields(AuthoringEditableSchema)), ClaimFieldSchema = v.strictObject({
186
272
  type: v.literal("claim"),
187
273
  name: FieldEntryName,
188
274
  title: v.optional(v.string()),
189
275
  description: v.optional(v.string())
190
- }), AuthoringFieldEntrySchema = v.union([RawAuthoringFieldEntrySchema, ClaimFieldSchema]), ConditionSchema = NonEmpty, EffectSchema = v.strictObject({
276
+ });
277
+ function listSugarFields(type) {
278
+ return {
279
+ type: v.literal(type),
280
+ ...slotFields(AuthoringEditableSchema)
281
+ };
282
+ }
283
+ const TodoListFieldSchema = v.strictObject(listSugarFields("todoList")), NotesFieldSchema = v.strictObject(listSugarFields("notes")), AuthoringFieldEntrySchema = v.union([
284
+ RawAuthoringFieldEntrySchema,
285
+ ClaimFieldSchema,
286
+ TodoListFieldSchema,
287
+ NotesFieldSchema
288
+ ]), ConditionSchema = NonEmpty, EffectSchema = v.strictObject({
191
289
  name: NonEmpty,
192
290
  title: v.optional(v.string()),
193
291
  description: v.optional(v.string()),
@@ -228,10 +326,10 @@ function actionFields(op) {
228
326
  effects: v.optional(v.array(EffectSchema))
229
327
  };
230
328
  }
231
- const StoredActionSchema = v.strictObject(actionFields(StoredOpSchema)), TerminalTaskStatus = picklist(TERMINAL_TASK_STATUSES), RawAuthoringActionSchema = v.strictObject({
329
+ const StoredActionSchema = v.strictObject(actionFields(StoredOpSchema)), TerminalActivityStatus = picklist(TERMINAL_ACTIVITY_STATUSES), RawAuthoringActionSchema = v.strictObject({
232
330
  ...actionFields(AuthoringOpSchema),
233
331
  roles: v.optional(v.array(NonEmpty)),
234
- status: v.optional(TerminalTaskStatus)
332
+ status: v.optional(TerminalActivityStatus)
235
333
  }), ClaimActionSchema = v.strictObject({
236
334
  type: v.literal("claim"),
237
335
  name: NonEmpty,
@@ -258,17 +356,27 @@ const StoredActionSchema = v.strictObject(actionFields(StoredOpSchema)), Termina
258
356
  */
259
357
  context: v.optional(v.record(NonEmpty, ConditionSchema))
260
358
  });
261
- function taskFields(field, action, op) {
359
+ function activityFields(field, action, op, target) {
262
360
  return {
263
361
  name: NonEmpty,
264
362
  title: v.optional(v.string()),
265
363
  description: v.optional(v.string()),
364
+ /**
365
+ * Advisory BPMN-aligned classification of this activity by its executor (see
366
+ * {@link ACTIVITY_KINDS}). Optional and derived from the activity's shape when
367
+ * omitted; declaring it lets deploy check the shape matches the lane.
368
+ * Changes no gating or resolution — a label for tooling, like `assignees`.
369
+ */
370
+ kind: v.optional(picklist(ACTIVITY_KINDS)),
371
+ /** Deep-link target for a `kind: "manual"` activity (off-system work). Render-only
372
+ * metadata; only valid on a manual activity (deploy-checked). */
373
+ target: v.optional(target),
266
374
  activation: v.optional(picklist(["auto", "manual"])),
267
375
  filter: v.optional(ConditionSchema),
268
376
  /**
269
377
  * Readiness gates, by name — conditions over the rendered scope that must
270
- * hold for the task to be *executable*, orthogonal to `filter`
271
- * (visibility). An unmet requirement keeps the task visible but disables
378
+ * hold for the activity to be *executable*, orthogonal to `filter`
379
+ * (visibility). An unmet requirement keeps the activity visible but disables
272
380
  * its actions with a `requirements-unmet` verdict naming the unmet keys;
273
381
  * all must hold (any-of lives inside one condition). Advisory like every
274
382
  * engine gate — the lake still enforces. Distinct from ACL (authorization)
@@ -277,8 +385,8 @@ function taskFields(field, action, op) {
277
385
  requirements: v.optional(v.record(NonEmpty, ConditionSchema)),
278
386
  /**
279
387
  * Auto-completion condition — evaluated at activation and on every
280
- * cascade; truthy flips the task to `done` with a system actor. On a
281
- * spawning task it typically reads `$subworkflows`.
388
+ * cascade; truthy flips the activity to `done` with a system actor. On a
389
+ * spawning activity it typically reads `$subworkflows`.
282
390
  */
283
391
  completeWhen: v.optional(ConditionSchema),
284
392
  /**
@@ -291,14 +399,19 @@ function taskFields(field, action, op) {
291
399
  effects: v.optional(v.array(EffectSchema)),
292
400
  actions: v.optional(v.array(action)),
293
401
  subworkflows: v.optional(SubworkflowsSchema),
294
- /** Task-scoped field entries. Resolved at task activation time. */
402
+ /** Activity-scoped field entries. Resolved at activity activation time. */
295
403
  fields: v.optional(v.array(field))
296
404
  };
297
405
  }
298
- const StoredTaskSchema = v.strictObject(
299
- taskFields(FieldEntrySchema, StoredActionSchema, StoredOpSchema)
300
- ), AuthoringTaskSchema = v.strictObject(
301
- taskFields(AuthoringFieldEntrySchema, AuthoringActionSchema, AuthoringOpSchema)
406
+ const StoredActivitySchema = v.strictObject(
407
+ activityFields(FieldEntrySchema, StoredActionSchema, StoredOpSchema, StoredManualTargetSchema)
408
+ ), AuthoringActivitySchema = v.strictObject(
409
+ activityFields(
410
+ AuthoringFieldEntrySchema,
411
+ AuthoringActionSchema,
412
+ AuthoringOpSchema,
413
+ AuthoringManualTargetSchema
414
+ )
302
415
  );
303
416
  function transitionFields(op, filter) {
304
417
  return {
@@ -352,12 +465,12 @@ const StoredTransitionSchema = v.strictObject(
352
465
  */
353
466
  metadata: v.optional(v.record(NonEmpty, NonEmpty))
354
467
  });
355
- function stageFields(field, task, transition, editable) {
468
+ function stageFields(field, activity, transition, editable) {
356
469
  return {
357
470
  name: NonEmpty,
358
471
  title: v.optional(v.string()),
359
472
  description: v.optional(v.string()),
360
- tasks: v.optional(v.array(task)),
473
+ activities: v.optional(v.array(activity)),
361
474
  transitions: v.optional(v.array(transition)),
362
475
  /**
363
476
  * Lake mutation guards active while this stage holds. Each compiles to a
@@ -377,11 +490,11 @@ function stageFields(field, task, transition, editable) {
377
490
  };
378
491
  }
379
492
  const StoredStageSchema = v.strictObject(
380
- stageFields(FieldEntrySchema, StoredTaskSchema, StoredTransitionSchema, StoredEditableSchema)
493
+ stageFields(FieldEntrySchema, StoredActivitySchema, StoredTransitionSchema, StoredEditableSchema)
381
494
  ), AuthoringStageSchema = v.strictObject(
382
495
  stageFields(
383
496
  AuthoringFieldEntrySchema,
384
- AuthoringTaskSchema,
497
+ AuthoringActivitySchema,
385
498
  AuthoringTransitionSchema,
386
499
  AuthoringEditableSchema
387
500
  )
@@ -392,12 +505,11 @@ const StoredStageSchema = v.strictObject(
392
505
  function workflowFields(field, stage) {
393
506
  return {
394
507
  name: NonEmpty,
395
- version: PositiveInt,
396
508
  title: NonEmpty,
397
509
  description: v.optional(v.string()),
398
510
  /**
399
511
  * Whether a human may start this workflow standalone. `'child'` marks a
400
- * spawn-only definition — instantiated by a parent via `task.subworkflows`,
512
+ * spawn-only definition — instantiated by a parent via `activity.subworkflows`,
401
513
  * never started cold from a picker. Omitted ⇒ `'workflow'` (startable).
402
514
  * Advisory: consumers filter their start pickers on it (see
403
515
  * {@link isStartableDefinition}); the engine does NOT refuse a
@@ -446,14 +558,16 @@ function formatPath(path) {
446
558
  return out;
447
559
  }
448
560
  export {
561
+ ACTIVITY_KINDS,
449
562
  AuthoringActionSchema,
563
+ AuthoringActivitySchema,
450
564
  AuthoringFieldEntrySchema,
451
565
  AuthoringOpSchema,
452
566
  AuthoringStageSchema,
453
- AuthoringTaskSchema,
454
567
  AuthoringTransitionSchema,
455
568
  AuthoringWorkflowSchema,
456
569
  DOCUMENT_VALUE_PERMISSIONS,
570
+ DRIVER_KINDS,
457
571
  EffectSchema,
458
572
  GROQ_IDENTIFIER,
459
573
  GuardSchema,
@@ -463,7 +577,8 @@ export {
463
577
  expandRequiredRoles,
464
578
  formatValidationError,
465
579
  isStartableDefinition,
466
- isTerminalTaskStatus,
467
- issuesFromValibot
580
+ isTerminalActivityStatus,
581
+ issuesFromValibot,
582
+ normalizeRoleAliases
468
583
  };
469
584
  //# sourceMappingURL=schema.js.map