@sanity/workflow-engine 0.12.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.
package/dist/define.cjs CHANGED
@@ -36,22 +36,22 @@ function desugarWorkflow(authoring) {
36
36
  claimFields: /* @__PURE__ */ new Map(),
37
37
  claimedFields: /* @__PURE__ */ new Set(),
38
38
  roleAliases
39
- }, workflowFields = desugarFieldEntries(authoring.fields, ["fields"], ctx), workflowLayer = layerOf(workflowFields), stages = authoring.stages.map((stage, i) => {
40
- const path = ["stages", i], stageFields = desugarFieldEntries(stage.fields, [...path, "fields"], ctx), stageEnv = {
39
+ }, workflowFields = desugarFieldEntries({ entries: authoring.fields, path: ["fields"], ctx }), workflowLayer = layerOf(workflowFields), stages = authoring.stages.map((stage, i) => {
40
+ const path = ["stages", i], stageFields = desugarFieldEntries({ entries: stage.fields, path: [...path, "fields"], ctx }), stageEnv = {
41
41
  layers: [
42
42
  { scope: "stage", entries: layerOf(stageFields) },
43
43
  { scope: "workflow", entries: workflowLayer }
44
44
  ]
45
45
  }, activities = (stage.activities ?? []).map(
46
- (activity, j) => desugarActivity(activity, [...path, "activities", j], stageEnv, ctx)
46
+ (activity, j) => desugarActivity({ activity, path: [...path, "activities", j], stageEnv, ctx })
47
47
  ), transitions = (stage.transitions ?? []).map(
48
- (transition, k) => desugarTransition(transition, [...path, "transitions", k], stageEnv, ctx)
49
- ), editable = desugarStageEditable(
50
- stage.editable,
51
- editableSlotNames(workflowFields, stageFields, activities),
52
- [...path, "editable"],
48
+ (transition, k) => desugarTransition({ transition, path: [...path, "transitions", k], stageEnv, ctx })
49
+ ), editable = desugarStageEditable({
50
+ overrides: stage.editable,
51
+ inScope: editableSlotNames({ workflowFields, stageFields, activities }),
52
+ path: [...path, "editable"],
53
53
  ctx
54
- );
54
+ });
55
55
  return {
56
56
  ...stripUndefined({
57
57
  name: stage.name,
@@ -96,13 +96,22 @@ const TODOLIST_OF = [
96
96
  { type: "actor", name: "actor", title: "Actor" },
97
97
  { type: "datetime", name: "at", title: "At" }
98
98
  ];
99
- function desugarFieldEntries(entries, path, ctx) {
100
- return !entries || entries.length === 0 ? entries === void 0 ? void 0 : [] : entries.map((entry, i) => desugarFieldEntry(entry, [...path, i], ctx));
101
- }
102
- function desugarFieldEntry(entry, path, ctx) {
103
- if (entry.type === "claim") return desugarClaimField(entry, path, ctx);
104
- if (entry.type === "todoList" || entry.type === "notes") return desugarListField(entry, path, ctx);
105
- const editable = normalizeEditable(entry.editable, [...path, "editable"], ctx);
99
+ function desugarFieldEntries({
100
+ entries,
101
+ path,
102
+ ctx
103
+ }) {
104
+ return !entries || entries.length === 0 ? entries === void 0 ? void 0 : [] : entries.map((entry, i) => desugarFieldEntry({ entry, path: [...path, i], ctx }));
105
+ }
106
+ function desugarFieldEntry({
107
+ entry,
108
+ path,
109
+ ctx
110
+ }) {
111
+ if (entry.type === "claim") return desugarClaimField({ entry, path, ctx });
112
+ if (entry.type === "todoList" || entry.type === "notes")
113
+ return desugarListField({ entry, path, ctx });
114
+ const editable = normalizeEditable({ editable: entry.editable, path: [...path, "editable"], ctx });
106
115
  return {
107
116
  ...stripUndefined({
108
117
  type: entry.type,
@@ -117,15 +126,23 @@ function desugarFieldEntry(entry, path, ctx) {
117
126
  })
118
127
  };
119
128
  }
120
- function desugarClaimField(entry, path, ctx) {
129
+ function desugarClaimField({
130
+ entry,
131
+ path,
132
+ ctx
133
+ }) {
121
134
  const desugared = {
122
135
  ...stripUndefined({ name: entry.name, title: entry.title, description: entry.description }),
123
136
  type: "actor"
124
137
  };
125
138
  return ctx.claimFields.set(desugared, { name: entry.name, path }), desugared;
126
139
  }
127
- function desugarListField(entry, path, ctx) {
128
- const editable = normalizeEditable(entry.editable, [...path, "editable"], ctx);
140
+ function desugarListField({
141
+ entry,
142
+ path,
143
+ ctx
144
+ }) {
145
+ const editable = normalizeEditable({ editable: entry.editable, path: [...path, "editable"], ctx });
129
146
  return {
130
147
  ...stripUndefined({
131
148
  name: entry.name,
@@ -139,7 +156,11 @@ function desugarListField(entry, path, ctx) {
139
156
  of: entry.type === "todoList" ? TODOLIST_OF : NOTES_OF
140
157
  };
141
158
  }
142
- function normalizeEditable(editable, path, ctx) {
159
+ function normalizeEditable({
160
+ editable,
161
+ path,
162
+ ctx
163
+ }) {
143
164
  if (editable === void 0 || editable === !0) return editable;
144
165
  if (Array.isArray(editable)) {
145
166
  const condition = rolesCondition(editable, ctx.roleAliases);
@@ -154,7 +175,11 @@ function normalizeEditable(editable, path, ctx) {
154
175
  }
155
176
  return editable;
156
177
  }
157
- function editableSlotNames(workflowFields, stageFields, activities) {
178
+ function editableSlotNames({
179
+ workflowFields,
180
+ stageFields,
181
+ activities
182
+ }) {
158
183
  const names = /* @__PURE__ */ new Set(), collect = (entries) => {
159
184
  for (const entry of entries ?? []) entry.editable !== void 0 && names.add(entry.name);
160
185
  };
@@ -162,7 +187,12 @@ function editableSlotNames(workflowFields, stageFields, activities) {
162
187
  for (const activity of activities) collect(activity.fields);
163
188
  return names;
164
189
  }
165
- function desugarStageEditable(overrides, inScope, path, ctx) {
190
+ function desugarStageEditable({
191
+ overrides,
192
+ inScope,
193
+ path,
194
+ ctx
195
+ }) {
166
196
  if (overrides === void 0) return;
167
197
  const out = {};
168
198
  for (const [name, value] of Object.entries(overrides)) {
@@ -173,7 +203,7 @@ function desugarStageEditable(overrides, inScope, path, ctx) {
173
203
  });
174
204
  continue;
175
205
  }
176
- const normalized = normalizeEditable(value, [...path, name], ctx);
206
+ const normalized = normalizeEditable({ editable: value, path: [...path, name], ctx });
177
207
  normalized !== void 0 && (out[name] = normalized);
178
208
  }
179
209
  return Object.keys(out).length > 0 ? out : void 0;
@@ -181,12 +211,27 @@ function desugarStageEditable(overrides, inScope, path, ctx) {
181
211
  function layerOf(entries) {
182
212
  return new Map((entries ?? []).map((entry) => [entry.name, entry]));
183
213
  }
184
- function desugarActivity(activity, path, stageEnv, ctx) {
185
- const activityFields = desugarFieldEntries(activity.fields, [...path, "fields"], ctx), env = {
214
+ function desugarActivity({
215
+ activity,
216
+ path,
217
+ stageEnv,
218
+ ctx
219
+ }) {
220
+ const activityFields = desugarFieldEntries({
221
+ entries: activity.fields,
222
+ path: [...path, "fields"],
223
+ ctx
224
+ }), env = {
186
225
  layers: [{ scope: "activity", entries: layerOf(activityFields) }, ...stageEnv.layers]
187
- }, ops = desugarOps(activity.ops, [...path, "ops"], env, activity.name, ctx), actions = (activity.actions ?? []).map(
188
- (action, a) => desugarAction(action, [...path, "actions", a], env, activity.name, ctx)
189
- ), target = desugarTarget(activity.target, env, [...path, "target"], ctx);
226
+ }, ops = desugarOps({
227
+ ops: activity.ops,
228
+ path: [...path, "ops"],
229
+ env,
230
+ firingActivity: activity.name,
231
+ ctx
232
+ }), actions = (activity.actions ?? []).map(
233
+ (action, a) => desugarAction({ action, path: [...path, "actions", a], env, activityName: activity.name, ctx })
234
+ ), target = desugarTarget({ target: activity.target, env, path: [...path, "target"], ctx });
190
235
  return {
191
236
  ...stripUndefined({
192
237
  name: activity.name,
@@ -208,18 +253,29 @@ function desugarActivity(activity, path, stageEnv, ctx) {
208
253
  };
209
254
  }
210
255
  const TARGET_DOC_KINDS = ["doc.ref", "doc.refs", "release.ref"];
211
- function desugarTarget(target, env, path, ctx) {
256
+ function desugarTarget({
257
+ target,
258
+ env,
259
+ path,
260
+ ctx
261
+ }) {
212
262
  if (target === void 0 || target.type === "url") return target;
213
- const ref = typeof target.field == "string" ? { field: target.field } : target.field, field = resolveRef(ref, env, [...path, "field"], ctx) ?? fallbackRef(ref), entry = entryAt(env, field);
263
+ const ref = typeof target.field == "string" ? { field: target.field } : target.field, field = resolveRef({ ref, env, path: [...path, "field"], ctx }) ?? fallbackRef(ref), entry = entryAt(env, field);
214
264
  return entry && !TARGET_DOC_KINDS.includes(entry.type) && ctx.issues.push({
215
265
  path: [...path, "field"],
216
266
  message: `manual activity target references "${field.field}" of kind "${entry.type}" \u2014 a deep-link target needs a document-valued entry (${TARGET_DOC_KINDS.join(", ")})`
217
267
  }), { type: "field", field };
218
268
  }
219
- function desugarAction(action, path, env, activityName, ctx) {
269
+ function desugarAction({
270
+ action,
271
+ path,
272
+ env,
273
+ activityName,
274
+ ctx
275
+ }) {
220
276
  if ("type" in action)
221
- return desugarClaimAction(action, path, env, ctx);
222
- const filter = schema.andConditions([rolesCondition(action.roles, ctx.roleAliases), action.filter]), ops = desugarOps(action.ops, [...path, "ops"], env, activityName, ctx) ?? [];
277
+ return desugarClaimAction({ action, path, env, ctx });
278
+ const filter = schema.andConditions([rolesCondition(action.roles, ctx.roleAliases), action.filter]), ops = desugarOps({ ops: action.ops, path: [...path, "ops"], env, firingActivity: activityName, ctx }) ?? [];
223
279
  return action.status !== void 0 && ops.push({ type: "status.set", activity: activityName, status: action.status }), {
224
280
  ...stripUndefined({
225
281
  name: action.name,
@@ -232,14 +288,26 @@ function desugarAction(action, path, env, activityName, ctx) {
232
288
  ...ops.length > 0 ? { ops } : {}
233
289
  };
234
290
  }
235
- function desugarClaimAction(action, path, env, ctx) {
236
- const ref = typeof action.field == "string" ? { field: action.field } : action.field, resolved = resolveRef(ref, env, [...path, "field"], ctx);
291
+ function desugarClaimAction({
292
+ action,
293
+ path,
294
+ env,
295
+ ctx
296
+ }) {
297
+ const ref = typeof action.field == "string" ? { field: action.field } : action.field, resolved = resolveRef({ ref, env, path: [...path, "field"], ctx });
237
298
  if (resolved) {
238
299
  const entry = entryAt(env, resolved);
239
300
  entry && entry.type !== "actor" && ctx.issues.push({
240
301
  path: [...path, "field"],
241
302
  message: `claim action "${action.name}" references "${resolved.field}" of kind "${entry.type}" \u2014 a claim pair needs an actor-valued entry (a "claim" or "actor" field declaration)`
242
- }), checkShadowedClaimTarget(action.name, ref.field, resolved, env, [...path, "field"], ctx), entry && ctx.claimedFields.add(entry);
303
+ }), checkShadowedClaimTarget({
304
+ actionName: action.name,
305
+ field: ref.field,
306
+ resolved,
307
+ env,
308
+ path: [...path, "field"],
309
+ ctx
310
+ }), entry && ctx.claimedFields.add(entry);
243
311
  }
244
312
  const noSteal = `!defined($fields.${ref.field})`, filter = schema.andConditions([
245
313
  noSteal,
@@ -258,7 +326,14 @@ function desugarClaimAction(action, path, env, ctx) {
258
326
  ...ops.length > 0 ? { ops } : {}
259
327
  };
260
328
  }
261
- function checkShadowedClaimTarget(actionName, field, resolved, env, path, ctx) {
329
+ function checkShadowedClaimTarget({
330
+ actionName,
331
+ field,
332
+ resolved,
333
+ env,
334
+ path,
335
+ ctx
336
+ }) {
262
337
  const nearest = env.layers.find((l) => l.entries.has(field));
263
338
  nearest === void 0 || nearest.scope === resolved.scope || ctx.issues.push({
264
339
  path,
@@ -272,8 +347,19 @@ function checkUnclaimedClaimFields(ctx) {
272
347
  message: `claim field "${name}" is never referenced by a claim action \u2014 you announced the pattern and wrote half of it. Declare a defineAction({ type: "claim", field: "${name}" }) or use a raw actor entry`
273
348
  });
274
349
  }
275
- function desugarTransition(transition, path, stageEnv, ctx) {
276
- const ops = desugarOps(transition.ops, [...path, "ops"], stageEnv, void 0, ctx);
350
+ function desugarTransition({
351
+ transition,
352
+ path,
353
+ stageEnv,
354
+ ctx
355
+ }) {
356
+ const ops = desugarOps({
357
+ ops: transition.ops,
358
+ path: [...path, "ops"],
359
+ env: stageEnv,
360
+ firingActivity: void 0,
361
+ ctx
362
+ });
277
363
  return {
278
364
  ...stripUndefined({
279
365
  name: transition.name,
@@ -286,11 +372,23 @@ function desugarTransition(transition, path, stageEnv, ctx) {
286
372
  ...ops ? { ops } : {}
287
373
  };
288
374
  }
289
- function desugarOps(ops, path, env, firingActivity, ctx) {
375
+ function desugarOps({
376
+ ops,
377
+ path,
378
+ env,
379
+ firingActivity,
380
+ ctx
381
+ }) {
290
382
  if (ops)
291
- return ops.map((op, i) => desugarOp(op, [...path, i], env, firingActivity, ctx));
292
- }
293
- function desugarOp(op, path, env, firingActivity, ctx) {
383
+ return ops.map((op, i) => desugarOp({ op, path: [...path, i], env, firingActivity, ctx }));
384
+ }
385
+ function desugarOp({
386
+ op,
387
+ path,
388
+ env,
389
+ firingActivity,
390
+ ctx
391
+ }) {
294
392
  if (op.type === "status.set") {
295
393
  const activity = op.activity ?? firingActivity;
296
394
  return activity === void 0 && ctx.issues.push({
@@ -298,13 +396,18 @@ function desugarOp(op, path, env, firingActivity, ctx) {
298
396
  message: "status.set outside an action must name its target activity"
299
397
  }), { type: "status.set", activity: activity ?? "", status: op.status };
300
398
  }
301
- if (op.type === "audit") return desugarAuditOp(op, path, env, ctx);
302
- const target = resolveRef(op.target, env, [...path, "target"], ctx) ?? fallbackRef(op.target);
399
+ if (op.type === "audit") return desugarAuditOp({ op, path, env, ctx });
400
+ const target = resolveRef({ ref: op.target, env, path: [...path, "target"], ctx }) ?? fallbackRef(op.target);
303
401
  return { ...op, target };
304
402
  }
305
403
  const AUDIT_STAMPS = { actor: { type: "actor" }, at: { type: "now" } };
306
- function desugarAuditOp(op, path, env, ctx) {
307
- const target = resolveRef(op.target, env, [...path, "target"], ctx) ?? fallbackRef(op.target);
404
+ function desugarAuditOp({
405
+ op,
406
+ path,
407
+ env,
408
+ ctx
409
+ }) {
410
+ const target = resolveRef({ ref: op.target, env, path: [...path, "target"], ctx }) ?? fallbackRef(op.target);
308
411
  if (op.value.type !== "object")
309
412
  return ctx.issues.push({
310
413
  path: [...path, "value"],
@@ -326,7 +429,12 @@ function desugarAuditOp(op, path, env, ctx) {
326
429
  }
327
430
  return { type: "field.append", target, value: { type: "object", fields } };
328
431
  }
329
- function resolveRef(ref, env, path, ctx) {
432
+ function resolveRef({
433
+ ref,
434
+ env,
435
+ path,
436
+ ctx
437
+ }) {
330
438
  const layers = ref.scope === void 0 ? env.layers : env.layers.filter((l) => l.scope === ref.scope);
331
439
  for (const layer of layers)
332
440
  if (layer.entries.has(ref.field)) return { scope: layer.scope, field: ref.field };
@@ -372,71 +480,103 @@ const RESERVED_CONDITION_VARS = [
372
480
  function knownList(ids) {
373
481
  return [...ids].map((s) => `"${s}"`).join(", ");
374
482
  }
375
- function checkDuplicates(names, what, issues) {
483
+ function checkDuplicates({
484
+ names,
485
+ what,
486
+ issues
487
+ }) {
376
488
  const seen = /* @__PURE__ */ new Set();
377
489
  for (const { name, path } of names)
378
490
  seen.has(name) && issues.push({ path, message: `duplicate ${what} "${name}" (already declared earlier)` }), seen.add(name);
379
491
  return seen;
380
492
  }
381
493
  function checkStages(def, issues) {
382
- const stageNames = checkDuplicates(
383
- def.stages.map((stage, i) => ({ name: stage.name, path: ["stages", i, "name"] })),
384
- "stage name",
494
+ const stageNames = checkDuplicates({
495
+ names: def.stages.map((stage, i) => ({ name: stage.name, path: ["stages", i, "name"] })),
496
+ what: "stage name",
385
497
  issues
386
- );
498
+ });
387
499
  for (const [i, stage] of def.stages.entries()) {
388
- const activityNames = checkDuplicates(
389
- (stage.activities ?? []).map((activity, j) => ({
500
+ const activityNames = checkDuplicates({
501
+ names: (stage.activities ?? []).map((activity, j) => ({
390
502
  name: activity.name,
391
503
  path: ["stages", i, "activities", j, "name"]
392
504
  })),
393
- `activity name in stage "${stage.name}"`,
505
+ what: `activity name in stage "${stage.name}"`,
394
506
  issues
395
- );
396
- checkDuplicates(
397
- (stage.transitions ?? []).map((t, k) => ({
507
+ });
508
+ checkDuplicates({
509
+ names: (stage.transitions ?? []).map((t, k) => ({
398
510
  name: t.name,
399
511
  path: ["stages", i, "transitions", k, "name"]
400
512
  })),
401
- `transition name in stage "${stage.name}"`,
513
+ what: `transition name in stage "${stage.name}"`,
402
514
  issues
403
- ), checkActivities(def, i, activityNames, issues);
515
+ }), checkActivities({ def, i, activityNames, issues });
404
516
  }
405
517
  return stageNames;
406
518
  }
407
- function checkActivities(def, i, activityNames, issues) {
519
+ function checkActivities({
520
+ def,
521
+ i,
522
+ activityNames,
523
+ issues
524
+ }) {
408
525
  const stage = def.stages[i];
409
526
  for (const [j, activity] of (stage.activities ?? []).entries()) {
410
527
  const path = ["stages", i, "activities", j];
411
- checkDuplicates(
412
- (activity.actions ?? []).map((action, a) => ({
528
+ checkDuplicates({
529
+ names: (activity.actions ?? []).map((action, a) => ({
413
530
  name: action.name,
414
531
  path: [...path, "actions", a, "name"]
415
532
  })),
416
- `action name in activity "${activity.name}"`,
533
+ what: `action name in activity "${activity.name}"`,
417
534
  issues
418
- ), checkStatusSetTargets(activity, activityNames, path, issues);
535
+ }), checkStatusSetTargets({ activity, activityNames, path, issues });
419
536
  }
420
537
  }
421
- function checkStatusSetTargets(activity, activityNames, path, issues) {
422
- checkStatusSetOps(activity.ops, activityNames, [...path, "ops"], issues);
538
+ function checkStatusSetTargets({
539
+ activity,
540
+ activityNames,
541
+ path,
542
+ issues
543
+ }) {
544
+ checkStatusSetOps({ ops: activity.ops, activityNames, path: [...path, "ops"], issues });
423
545
  for (const [a, action] of (activity.actions ?? []).entries())
424
- checkStatusSetOps(action.ops, activityNames, [...path, "actions", a, "ops"], issues);
546
+ checkStatusSetOps({
547
+ ops: action.ops,
548
+ activityNames,
549
+ path: [...path, "actions", a, "ops"],
550
+ issues
551
+ });
425
552
  }
426
- function checkStatusSetOps(ops, activityNames, path, issues) {
553
+ function checkStatusSetOps({
554
+ ops,
555
+ activityNames,
556
+ path,
557
+ issues
558
+ }) {
427
559
  for (const [o, op] of (ops ?? []).entries())
428
560
  op.type !== "status.set" || activityNames.has(op.activity) || issues.push({
429
561
  path: [...path, o, "activity"],
430
562
  message: `status.set targets activity "${op.activity}" which is not declared in this stage. Known activities: ${knownList(activityNames)}`
431
563
  });
432
564
  }
433
- function checkInitialStage(def, stageNames, issues) {
565
+ function checkInitialStage({
566
+ def,
567
+ stageNames,
568
+ issues
569
+ }) {
434
570
  stageNames.has(def.initialStage) || issues.push({
435
571
  path: ["initialStage"],
436
572
  message: `initialStage "${def.initialStage}" is not a declared stage. Known stages: ${knownList(stageNames)}`
437
573
  });
438
574
  }
439
- function checkTransitionTargets(def, stageNames, issues) {
575
+ function checkTransitionTargets({
576
+ def,
577
+ stageNames,
578
+ issues
579
+ }) {
440
580
  for (const [i, stage] of def.stages.entries())
441
581
  for (const [k, t] of (stage.transitions ?? []).entries())
442
582
  stageNames.has(t.to) || issues.push({
@@ -448,20 +588,32 @@ function checkEffectNames(def, issues) {
448
588
  const sites = [];
449
589
  for (const [i, stage] of def.stages.entries()) {
450
590
  for (const [j, activity] of (stage.activities ?? []).entries()) {
451
- collectEffects(activity.effects, ["stages", i, "activities", j, "effects"], sites);
591
+ collectEffects({
592
+ effects: activity.effects,
593
+ path: ["stages", i, "activities", j, "effects"],
594
+ sites
595
+ });
452
596
  for (const [a, action] of (activity.actions ?? []).entries())
453
- collectEffects(
454
- action.effects,
455
- ["stages", i, "activities", j, "actions", a, "effects"],
597
+ collectEffects({
598
+ effects: action.effects,
599
+ path: ["stages", i, "activities", j, "actions", a, "effects"],
456
600
  sites
457
- );
601
+ });
458
602
  }
459
603
  for (const [k, t] of (stage.transitions ?? []).entries())
460
- collectEffects(t.effects, ["stages", i, "transitions", k, "effects"], sites);
604
+ collectEffects({ effects: t.effects, path: ["stages", i, "transitions", k, "effects"], sites });
461
605
  }
462
- checkDuplicates(sites, "effect name (registry key \u2014 unique per definition)", issues);
606
+ checkDuplicates({
607
+ names: sites,
608
+ what: "effect name (registry key \u2014 unique per definition)",
609
+ issues
610
+ });
463
611
  }
464
- function collectEffects(effects, path, sites) {
612
+ function collectEffects({
613
+ effects,
614
+ path,
615
+ sites
616
+ }) {
465
617
  for (const [e, effect] of (effects ?? []).entries())
466
618
  sites.push({ name: effect.name, path: [...path, e, "name"] });
467
619
  }
@@ -472,11 +624,11 @@ function checkGuardNames(def, issues) {
472
624
  path: ["stages", i, "guards", g, "name"]
473
625
  }))
474
626
  );
475
- checkDuplicates(
476
- sites,
477
- "guard name (the guard lake _id derives from it \u2014 unique per definition)",
627
+ checkDuplicates({
628
+ names: sites,
629
+ what: "guard name (the guard lake _id derives from it \u2014 unique per definition)",
478
630
  issues
479
- );
631
+ });
480
632
  }
481
633
  function fieldScopes(def) {
482
634
  const scopes = [
@@ -519,11 +671,11 @@ function checkRequiredField(def, issues) {
519
671
  }
520
672
  function checkFieldEntryNames(def, issues) {
521
673
  for (const { entries, path, label } of fieldScopes(def))
522
- checkDuplicates(
523
- (entries ?? []).map((entry, n) => ({ name: entry.name, path: [...path, n, "name"] })),
524
- `field entry name in ${label}`,
674
+ checkDuplicates({
675
+ names: (entries ?? []).map((entry, n) => ({ name: entry.name, path: [...path, n, "name"] })),
676
+ what: `field entry name in ${label}`,
525
677
  issues
526
- );
678
+ });
527
679
  }
528
680
  function checkPredicates(def, issues) {
529
681
  const reserved = new Set(RESERVED_CONDITION_VARS), names = Object.keys(def.predicates ?? {});
@@ -533,9 +685,14 @@ function checkPredicates(def, issues) {
533
685
  message: `predicate "${name}" shadows the built-in $${name} \u2014 pick another name`
534
686
  });
535
687
  for (const [name, groq2] of Object.entries(def.predicates ?? {}))
536
- checkPredicateBody(name, groq2, names, issues);
537
- }
538
- function checkPredicateBody(name, groq2, names, issues) {
688
+ checkPredicateBody({ name, groq: groq2, names, issues });
689
+ }
690
+ function checkPredicateBody({
691
+ name,
692
+ groq: groq2,
693
+ names,
694
+ issues
695
+ }) {
539
696
  for (const caller of PREDICATE_CALLER_VARS)
540
697
  referencesVar(groq2, caller) && issues.push({
541
698
  path: ["predicates", name],
@@ -565,33 +722,46 @@ function nonActionFilterConditionSites(def) {
565
722
  groq: t.filter,
566
723
  path: ["stages", i, "transitions", k, "filter"],
567
724
  label: `transition "${t.name}" filter`
568
- }), collectBindingSites(
569
- t.effects,
570
- ["stages", i, "transitions", k, "effects"],
571
- `transition "${t.name}"`,
725
+ }), collectBindingSites({
726
+ effects: t.effects,
727
+ path: ["stages", i, "transitions", k, "effects"],
728
+ label: `transition "${t.name}"`,
572
729
  sites
573
- );
730
+ });
574
731
  for (const [j, activity] of (stage.activities ?? []).entries())
575
- collectActivityConditionSites(activity, ["stages", i, "activities", j], sites);
732
+ collectActivityConditionSites({ activity, path: ["stages", i, "activities", j], sites });
576
733
  }
577
734
  return sites;
578
735
  }
579
- function collectActivityConditionSites(activity, path, sites) {
736
+ function collectActivityConditionSites({
737
+ activity,
738
+ path,
739
+ sites
740
+ }) {
580
741
  for (const field of ["filter", "completeWhen", "failWhen"]) {
581
742
  const groq2 = activity[field];
582
743
  groq2 !== void 0 && sites.push({ groq: groq2, path: [...path, field], label: `activity "${activity.name}".${field}` });
583
744
  }
584
- collectBindingSites(activity.effects, [...path, "effects"], `activity "${activity.name}"`, sites);
745
+ collectBindingSites({
746
+ effects: activity.effects,
747
+ path: [...path, "effects"],
748
+ label: `activity "${activity.name}"`,
749
+ sites
750
+ });
585
751
  for (const [a, action] of (activity.actions ?? []).entries())
586
- collectBindingSites(
587
- action.effects,
588
- [...path, "actions", a, "effects"],
589
- `action "${action.name}"`,
752
+ collectBindingSites({
753
+ effects: action.effects,
754
+ path: [...path, "actions", a, "effects"],
755
+ label: `action "${action.name}"`,
590
756
  sites
591
- );
592
- collectSubworkflowSites(activity, path, sites);
757
+ });
758
+ collectSubworkflowSites({ activity, path, sites });
593
759
  }
594
- function collectSubworkflowSites(activity, path, sites) {
760
+ function collectSubworkflowSites({
761
+ activity,
762
+ path,
763
+ sites
764
+ }) {
595
765
  const sub = activity.subworkflows;
596
766
  if (sub === void 0) return;
597
767
  const subPath = [...path, "subworkflows"];
@@ -611,7 +781,12 @@ function collectSubworkflowSites(activity, path, sites) {
611
781
  label: `activity "${activity.name}".subworkflows.${group} "${key}"`
612
782
  });
613
783
  }
614
- function collectBindingSites(effects, path, label, sites) {
784
+ function collectBindingSites({
785
+ effects,
786
+ path,
787
+ label,
788
+ sites
789
+ }) {
615
790
  for (const [e, effect] of (effects ?? []).entries())
616
791
  for (const [key, groq2] of Object.entries(effect.bindings ?? {}))
617
792
  sites.push({
@@ -669,36 +844,60 @@ function checkActivityKinds(def, issues) {
669
844
  }
670
845
  function checkWorkflowInvariants(def) {
671
846
  const issues = [], stageNames = checkStages(def, issues);
672
- return checkInitialStage(def, stageNames, issues), checkTransitionTargets(def, stageNames, issues), checkEffectNames(def, issues), checkGuardNames(def, issues), checkFieldEntryNames(def, issues), checkRequiredField(def, issues), checkPredicates(def, issues), checkCanOutsideActionFilters(def, issues), checkAssigneesEntries(def, issues), checkActivityKinds(def, issues), issues;
847
+ return checkInitialStage({ def, stageNames, issues }), checkTransitionTargets({ def, stageNames, issues }), checkEffectNames(def, issues), checkGuardNames(def, issues), checkFieldEntryNames(def, issues), checkRequiredField(def, issues), checkPredicates(def, issues), checkCanOutsideActionFilters(def, issues), checkAssigneesEntries(def, issues), checkActivityKinds(def, issues), issues;
673
848
  }
674
849
  function defineWorkflow(definition) {
675
- const label = labelFor("defineWorkflow", definition), parsed = parseOrThrow(schema.AuthoringWorkflowSchema, definition, label), { definition: stored, issues: desugarIssues } = desugarWorkflow(parsed), issues = [...desugarIssues, ...checkWorkflowInvariants(stored)];
850
+ const label = labelFor("defineWorkflow", definition), parsed = parseOrThrow({ schema: schema.AuthoringWorkflowSchema, input: definition, label }), { definition: stored, issues: desugarIssues } = desugarWorkflow(parsed), issues = [...desugarIssues, ...checkWorkflowInvariants(stored)];
676
851
  if (issues.length > 0) throw new Error(schema.formatValidationError(label, issues));
677
852
  return stored;
678
853
  }
679
854
  function defineStage(stage) {
680
- return parseOrThrow(schema.AuthoringStageSchema, stage, labelFor("defineStage", stage));
855
+ return parseOrThrow({
856
+ schema: schema.AuthoringStageSchema,
857
+ input: stage,
858
+ label: labelFor("defineStage", stage)
859
+ });
681
860
  }
682
861
  function defineActivity(activity) {
683
- return parseOrThrow(schema.AuthoringActivitySchema, activity, labelFor("defineActivity", activity));
862
+ return parseOrThrow({
863
+ schema: schema.AuthoringActivitySchema,
864
+ input: activity,
865
+ label: labelFor("defineActivity", activity)
866
+ });
684
867
  }
685
868
  function defineAction(action) {
686
- return parseOrThrow(schema.AuthoringActionSchema, action, labelFor("defineAction", action));
869
+ return parseOrThrow({
870
+ schema: schema.AuthoringActionSchema,
871
+ input: action,
872
+ label: labelFor("defineAction", action)
873
+ });
687
874
  }
688
875
  function defineTransition(transition) {
689
- return parseOrThrow(schema.AuthoringTransitionSchema, transition, transitionLabel(transition));
876
+ return parseOrThrow({
877
+ schema: schema.AuthoringTransitionSchema,
878
+ input: transition,
879
+ label: transitionLabel(transition)
880
+ });
690
881
  }
691
882
  function defineField(entry) {
692
- return parseOrThrow(schema.AuthoringFieldEntrySchema, entry, labelFor("defineField", entry));
883
+ return parseOrThrow({
884
+ schema: schema.AuthoringFieldEntrySchema,
885
+ input: entry,
886
+ label: labelFor("defineField", entry)
887
+ });
693
888
  }
694
889
  function defineOp(op) {
695
- return parseOrThrow(schema.AuthoringOpSchema, op, "defineOp");
890
+ return parseOrThrow({ schema: schema.AuthoringOpSchema, input: op, label: "defineOp" });
696
891
  }
697
892
  function defineGuard(guard) {
698
- return parseOrThrow(schema.GuardSchema, guard, labelFor("defineGuard", guard));
893
+ return parseOrThrow({ schema: schema.GuardSchema, input: guard, label: labelFor("defineGuard", guard) });
699
894
  }
700
895
  function defineEffect(effect) {
701
- return parseOrThrow(schema.EffectSchema, effect, labelFor("defineEffect", effect));
896
+ return parseOrThrow({
897
+ schema: schema.EffectSchema,
898
+ input: effect,
899
+ label: labelFor("defineEffect", effect)
900
+ });
702
901
  }
703
902
  function transitionLabel(transition) {
704
903
  const { name, to } = transition;
@@ -708,7 +907,11 @@ function defineEffectDescriptor(descriptor) {
708
907
  if (!descriptor.name) throw new Error("EffectDescriptor missing name");
709
908
  return descriptor;
710
909
  }
711
- function parseOrThrow(schema$1, input, label) {
910
+ function parseOrThrow({
911
+ schema: schema$1,
912
+ input,
913
+ label
914
+ }) {
712
915
  const result = v__namespace.safeParse(schema$1, input);
713
916
  if (!result.success)
714
917
  throw new Error(schema.formatValidationError(label, schema.issuesFromValibot(result.issues)));