@sanity/workflow-engine 0.12.0 → 0.14.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,28 +36,28 @@ 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: editableFieldNames({ workflowFields, stageFields, activities }),
52
+ path: [...path, "editable"],
53
53
  ctx
54
- );
54
+ });
55
55
  return {
56
56
  ...stripUndefined({
57
57
  name: stage.name,
58
58
  title: stage.title,
59
59
  description: stage.description,
60
- guards: stage.guards
60
+ guards: stage.guards?.map(desugarGuard)
61
61
  }),
62
62
  ...stageFields ? { fields: stageFields } : {},
63
63
  ...activities.length > 0 ? { activities } : {},
@@ -70,7 +70,7 @@ function desugarWorkflow(authoring) {
70
70
  name: authoring.name,
71
71
  title: authoring.title,
72
72
  description: authoring.description,
73
- role: authoring.role,
73
+ lifecycle: authoring.lifecycle,
74
74
  initialStage: authoring.initialStage,
75
75
  predicates: authoring.predicates,
76
76
  roleAliases
@@ -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,14 +156,18 @@ 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);
146
167
  if (condition === void 0) {
147
168
  ctx.issues.push({
148
169
  path,
149
- message: "editable: [] names no roles \u2014 use `true` to open the slot to anyone in its scope, or list at least one role"
170
+ message: "editable: [] names no roles \u2014 use `true` to open the field to anyone in its scope, or list at least one role"
150
171
  });
151
172
  return;
152
173
  }
@@ -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 editableFieldNames({
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,18 +187,23 @@ 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)) {
169
199
  if (!inScope.has(name)) {
170
200
  ctx.issues.push({
171
201
  path: [...path, name],
172
- message: `stage editable override "${name}" does not narrow an editable slot in scope \u2014 name a workflow/stage/activity slot of this stage that declares \`editable\``
202
+ message: `stage editable override "${name}" does not narrow an editable field in scope \u2014 name a workflow/stage/activity field of this stage that declares \`editable\``
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,38 @@ function desugarTransition(transition, path, stageEnv, ctx) {
286
372
  ...ops ? { ops } : {}
287
373
  };
288
374
  }
289
- function desugarOps(ops, path, env, firingActivity, ctx) {
290
- if (ops)
291
- return ops.map((op, i) => desugarOp(op, [...path, i], env, firingActivity, ctx));
375
+ function desugarGuard(guard) {
376
+ const { match, metadata, ...rest } = guard, { idRefs, ...matchRest } = match;
377
+ return {
378
+ ...rest,
379
+ match: {
380
+ ...matchRest,
381
+ ...idRefs !== void 0 ? { idRefs: idRefs.map(schema.printGuardRead) } : {}
382
+ },
383
+ ...metadata !== void 0 ? {
384
+ metadata: Object.fromEntries(
385
+ Object.entries(metadata).map(([key, read]) => [key, schema.printGuardRead(read)])
386
+ )
387
+ } : {}
388
+ };
292
389
  }
293
- function desugarOp(op, path, env, firingActivity, ctx) {
390
+ function desugarOps({
391
+ ops,
392
+ path,
393
+ env,
394
+ firingActivity,
395
+ ctx
396
+ }) {
397
+ if (ops)
398
+ return ops.map((op, i) => desugarOp({ op, path: [...path, i], env, firingActivity, ctx }));
399
+ }
400
+ function desugarOp({
401
+ op,
402
+ path,
403
+ env,
404
+ firingActivity,
405
+ ctx
406
+ }) {
294
407
  if (op.type === "status.set") {
295
408
  const activity = op.activity ?? firingActivity;
296
409
  return activity === void 0 && ctx.issues.push({
@@ -298,13 +411,18 @@ function desugarOp(op, path, env, firingActivity, ctx) {
298
411
  message: "status.set outside an action must name its target activity"
299
412
  }), { type: "status.set", activity: activity ?? "", status: op.status };
300
413
  }
301
- if (op.type === "audit") return desugarAuditOp(op, path, env, ctx);
302
- const target = resolveRef(op.target, env, [...path, "target"], ctx) ?? fallbackRef(op.target);
414
+ if (op.type === "audit") return desugarAuditOp({ op, path, env, ctx });
415
+ const target = resolveRef({ ref: op.target, env, path: [...path, "target"], ctx }) ?? fallbackRef(op.target);
303
416
  return { ...op, target };
304
417
  }
305
418
  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);
419
+ function desugarAuditOp({
420
+ op,
421
+ path,
422
+ env,
423
+ ctx
424
+ }) {
425
+ const target = resolveRef({ ref: op.target, env, path: [...path, "target"], ctx }) ?? fallbackRef(op.target);
308
426
  if (op.value.type !== "object")
309
427
  return ctx.issues.push({
310
428
  path: [...path, "value"],
@@ -326,7 +444,12 @@ function desugarAuditOp(op, path, env, ctx) {
326
444
  }
327
445
  return { type: "field.append", target, value: { type: "object", fields } };
328
446
  }
329
- function resolveRef(ref, env, path, ctx) {
447
+ function resolveRef({
448
+ ref,
449
+ env,
450
+ path,
451
+ ctx
452
+ }) {
330
453
  const layers = ref.scope === void 0 ? env.layers : env.layers.filter((l) => l.scope === ref.scope);
331
454
  for (const layer of layers)
332
455
  if (layer.entries.has(ref.field)) return { scope: layer.scope, field: ref.field };
@@ -352,91 +475,109 @@ function stripUndefined(obj) {
352
475
  value !== void 0 && (out[k] = value);
353
476
  return out;
354
477
  }
355
- const RESERVED_CONDITION_VARS = [
356
- "fields",
357
- "actor",
358
- "assigned",
359
- "can",
360
- "row",
361
- "now",
362
- "effects",
363
- "activities",
364
- "subworkflows",
365
- "self",
366
- "stage",
367
- "parent",
368
- "ancestors",
369
- "allActivitiesDone",
370
- "anyActivityFailed"
371
- ], PREDICATE_CALLER_VARS = ["actor", "assigned", "can"];
478
+ const PREDICATE_CALLER_VARS = schema.CONDITION_VARS.filter((v2) => v2.binding === "caller").map(
479
+ (v2) => v2.name
480
+ );
372
481
  function knownList(ids) {
373
482
  return [...ids].map((s) => `"${s}"`).join(", ");
374
483
  }
375
- function checkDuplicates(names, what, issues) {
484
+ function checkDuplicates({
485
+ names,
486
+ what,
487
+ issues
488
+ }) {
376
489
  const seen = /* @__PURE__ */ new Set();
377
490
  for (const { name, path } of names)
378
491
  seen.has(name) && issues.push({ path, message: `duplicate ${what} "${name}" (already declared earlier)` }), seen.add(name);
379
492
  return seen;
380
493
  }
381
494
  function checkStages(def, issues) {
382
- const stageNames = checkDuplicates(
383
- def.stages.map((stage, i) => ({ name: stage.name, path: ["stages", i, "name"] })),
384
- "stage name",
495
+ const stageNames = checkDuplicates({
496
+ names: def.stages.map((stage, i) => ({ name: stage.name, path: ["stages", i, "name"] })),
497
+ what: "stage name",
385
498
  issues
386
- );
499
+ });
387
500
  for (const [i, stage] of def.stages.entries()) {
388
- const activityNames = checkDuplicates(
389
- (stage.activities ?? []).map((activity, j) => ({
501
+ const activityNames = checkDuplicates({
502
+ names: (stage.activities ?? []).map((activity, j) => ({
390
503
  name: activity.name,
391
504
  path: ["stages", i, "activities", j, "name"]
392
505
  })),
393
- `activity name in stage "${stage.name}"`,
506
+ what: `activity name in stage "${stage.name}"`,
394
507
  issues
395
- );
396
- checkDuplicates(
397
- (stage.transitions ?? []).map((t, k) => ({
508
+ });
509
+ checkDuplicates({
510
+ names: (stage.transitions ?? []).map((t, k) => ({
398
511
  name: t.name,
399
512
  path: ["stages", i, "transitions", k, "name"]
400
513
  })),
401
- `transition name in stage "${stage.name}"`,
514
+ what: `transition name in stage "${stage.name}"`,
402
515
  issues
403
- ), checkActivities(def, i, activityNames, issues);
516
+ }), checkActivities({ def, i, activityNames, issues });
404
517
  }
405
518
  return stageNames;
406
519
  }
407
- function checkActivities(def, i, activityNames, issues) {
520
+ function checkActivities({
521
+ def,
522
+ i,
523
+ activityNames,
524
+ issues
525
+ }) {
408
526
  const stage = def.stages[i];
409
527
  for (const [j, activity] of (stage.activities ?? []).entries()) {
410
528
  const path = ["stages", i, "activities", j];
411
- checkDuplicates(
412
- (activity.actions ?? []).map((action, a) => ({
529
+ checkDuplicates({
530
+ names: (activity.actions ?? []).map((action, a) => ({
413
531
  name: action.name,
414
532
  path: [...path, "actions", a, "name"]
415
533
  })),
416
- `action name in activity "${activity.name}"`,
534
+ what: `action name in activity "${activity.name}"`,
417
535
  issues
418
- ), checkStatusSetTargets(activity, activityNames, path, issues);
536
+ }), checkStatusSetTargets({ activity, activityNames, path, issues });
419
537
  }
420
538
  }
421
- function checkStatusSetTargets(activity, activityNames, path, issues) {
422
- checkStatusSetOps(activity.ops, activityNames, [...path, "ops"], issues);
539
+ function checkStatusSetTargets({
540
+ activity,
541
+ activityNames,
542
+ path,
543
+ issues
544
+ }) {
545
+ checkStatusSetOps({ ops: activity.ops, activityNames, path: [...path, "ops"], issues });
423
546
  for (const [a, action] of (activity.actions ?? []).entries())
424
- checkStatusSetOps(action.ops, activityNames, [...path, "actions", a, "ops"], issues);
547
+ checkStatusSetOps({
548
+ ops: action.ops,
549
+ activityNames,
550
+ path: [...path, "actions", a, "ops"],
551
+ issues
552
+ });
425
553
  }
426
- function checkStatusSetOps(ops, activityNames, path, issues) {
554
+ function checkStatusSetOps({
555
+ ops,
556
+ activityNames,
557
+ path,
558
+ issues
559
+ }) {
427
560
  for (const [o, op] of (ops ?? []).entries())
428
561
  op.type !== "status.set" || activityNames.has(op.activity) || issues.push({
429
562
  path: [...path, o, "activity"],
430
563
  message: `status.set targets activity "${op.activity}" which is not declared in this stage. Known activities: ${knownList(activityNames)}`
431
564
  });
432
565
  }
433
- function checkInitialStage(def, stageNames, issues) {
566
+ function checkInitialStage({
567
+ def,
568
+ stageNames,
569
+ issues
570
+ }) {
434
571
  stageNames.has(def.initialStage) || issues.push({
435
572
  path: ["initialStage"],
436
573
  message: `initialStage "${def.initialStage}" is not a declared stage. Known stages: ${knownList(stageNames)}`
437
574
  });
438
575
  }
439
- function checkTransitionTargets(def, stageNames, issues) {
576
+ function checkTransitionTargets({
577
+ def,
578
+ stageNames,
579
+ issues
580
+ }) {
440
581
  for (const [i, stage] of def.stages.entries())
441
582
  for (const [k, t] of (stage.transitions ?? []).entries())
442
583
  stageNames.has(t.to) || issues.push({
@@ -448,20 +589,32 @@ function checkEffectNames(def, issues) {
448
589
  const sites = [];
449
590
  for (const [i, stage] of def.stages.entries()) {
450
591
  for (const [j, activity] of (stage.activities ?? []).entries()) {
451
- collectEffects(activity.effects, ["stages", i, "activities", j, "effects"], sites);
592
+ collectEffects({
593
+ effects: activity.effects,
594
+ path: ["stages", i, "activities", j, "effects"],
595
+ sites
596
+ });
452
597
  for (const [a, action] of (activity.actions ?? []).entries())
453
- collectEffects(
454
- action.effects,
455
- ["stages", i, "activities", j, "actions", a, "effects"],
598
+ collectEffects({
599
+ effects: action.effects,
600
+ path: ["stages", i, "activities", j, "actions", a, "effects"],
456
601
  sites
457
- );
602
+ });
458
603
  }
459
604
  for (const [k, t] of (stage.transitions ?? []).entries())
460
- collectEffects(t.effects, ["stages", i, "transitions", k, "effects"], sites);
605
+ collectEffects({ effects: t.effects, path: ["stages", i, "transitions", k, "effects"], sites });
461
606
  }
462
- checkDuplicates(sites, "effect name (registry key \u2014 unique per definition)", issues);
607
+ checkDuplicates({
608
+ names: sites,
609
+ what: "effect name (registry key \u2014 unique per definition)",
610
+ issues
611
+ });
463
612
  }
464
- function collectEffects(effects, path, sites) {
613
+ function collectEffects({
614
+ effects,
615
+ path,
616
+ sites
617
+ }) {
465
618
  for (const [e, effect] of (effects ?? []).entries())
466
619
  sites.push({ name: effect.name, path: [...path, e, "name"] });
467
620
  }
@@ -472,11 +625,11 @@ function checkGuardNames(def, issues) {
472
625
  path: ["stages", i, "guards", g, "name"]
473
626
  }))
474
627
  );
475
- checkDuplicates(
476
- sites,
477
- "guard name (the guard lake _id derives from it \u2014 unique per definition)",
628
+ checkDuplicates({
629
+ names: sites,
630
+ what: "guard name (the guard lake _id derives from it \u2014 unique per definition)",
478
631
  issues
479
- );
632
+ });
480
633
  }
481
634
  function fieldScopes(def) {
482
635
  const scopes = [
@@ -519,23 +672,28 @@ function checkRequiredField(def, issues) {
519
672
  }
520
673
  function checkFieldEntryNames(def, issues) {
521
674
  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}`,
675
+ checkDuplicates({
676
+ names: (entries ?? []).map((entry, n) => ({ name: entry.name, path: [...path, n, "name"] })),
677
+ what: `field entry name in ${label}`,
525
678
  issues
526
- );
679
+ });
527
680
  }
528
681
  function checkPredicates(def, issues) {
529
- const reserved = new Set(RESERVED_CONDITION_VARS), names = Object.keys(def.predicates ?? {});
682
+ const reserved = new Set(schema.RESERVED_CONDITION_VARS), names = Object.keys(def.predicates ?? {});
530
683
  for (const name of names)
531
684
  reserved.has(name) && issues.push({
532
685
  path: ["predicates", name],
533
686
  message: `predicate "${name}" shadows the built-in $${name} \u2014 pick another name`
534
687
  });
535
688
  for (const [name, groq2] of Object.entries(def.predicates ?? {}))
536
- checkPredicateBody(name, groq2, names, issues);
537
- }
538
- function checkPredicateBody(name, groq2, names, issues) {
689
+ checkPredicateBody({ name, groq: groq2, names, issues });
690
+ }
691
+ function checkPredicateBody({
692
+ name,
693
+ groq: groq2,
694
+ names,
695
+ issues
696
+ }) {
539
697
  for (const caller of PREDICATE_CALLER_VARS)
540
698
  referencesVar(groq2, caller) && issues.push({
541
699
  path: ["predicates", name],
@@ -565,33 +723,74 @@ function nonActionFilterConditionSites(def) {
565
723
  groq: t.filter,
566
724
  path: ["stages", i, "transitions", k, "filter"],
567
725
  label: `transition "${t.name}" filter`
568
- }), collectBindingSites(
569
- t.effects,
570
- ["stages", i, "transitions", k, "effects"],
571
- `transition "${t.name}"`,
726
+ }), collectBindingSites({
727
+ effects: t.effects,
728
+ path: ["stages", i, "transitions", k, "effects"],
729
+ label: `transition "${t.name}"`,
730
+ sites
731
+ }), collectOpWhereSites({
732
+ ops: t.ops,
733
+ path: ["stages", i, "transitions", k, "ops"],
734
+ label: `transition "${t.name}"`,
572
735
  sites
573
- );
736
+ });
574
737
  for (const [j, activity] of (stage.activities ?? []).entries())
575
- collectActivityConditionSites(activity, ["stages", i, "activities", j], sites);
738
+ collectActivityConditionSites({ activity, path: ["stages", i, "activities", j], sites });
576
739
  }
577
740
  return sites;
578
741
  }
579
- function collectActivityConditionSites(activity, path, sites) {
742
+ function collectOpWhereSites({
743
+ ops,
744
+ path,
745
+ label,
746
+ sites
747
+ }) {
748
+ for (const [o, op] of (ops ?? []).entries())
749
+ op.where !== void 0 && sites.push({
750
+ groq: op.where,
751
+ path: [...path, o, "where"],
752
+ label: `${label} ${op.type} where`
753
+ });
754
+ }
755
+ function collectActivityConditionSites({
756
+ activity,
757
+ path,
758
+ sites
759
+ }) {
580
760
  for (const field of ["filter", "completeWhen", "failWhen"]) {
581
761
  const groq2 = activity[field];
582
762
  groq2 !== void 0 && sites.push({ groq: groq2, path: [...path, field], label: `activity "${activity.name}".${field}` });
583
763
  }
584
- collectBindingSites(activity.effects, [...path, "effects"], `activity "${activity.name}"`, sites);
764
+ collectBindingSites({
765
+ effects: activity.effects,
766
+ path: [...path, "effects"],
767
+ label: `activity "${activity.name}"`,
768
+ sites
769
+ }), collectOpWhereSites({
770
+ ops: activity.ops,
771
+ path: [...path, "ops"],
772
+ label: `activity "${activity.name}"`,
773
+ sites
774
+ });
585
775
  for (const [a, action] of (activity.actions ?? []).entries())
586
- collectBindingSites(
587
- action.effects,
588
- [...path, "actions", a, "effects"],
589
- `action "${action.name}"`,
776
+ collectBindingSites({
777
+ effects: action.effects,
778
+ path: [...path, "actions", a, "effects"],
779
+ label: `action "${action.name}"`,
590
780
  sites
591
- );
592
- collectSubworkflowSites(activity, path, sites);
781
+ }), collectOpWhereSites({
782
+ ops: action.ops,
783
+ path: [...path, "actions", a, "ops"],
784
+ label: `action "${action.name}"`,
785
+ sites
786
+ });
787
+ collectSubworkflowSites({ activity, path, sites });
593
788
  }
594
- function collectSubworkflowSites(activity, path, sites) {
789
+ function collectSubworkflowSites({
790
+ activity,
791
+ path,
792
+ sites
793
+ }) {
595
794
  const sub = activity.subworkflows;
596
795
  if (sub === void 0) return;
597
796
  const subPath = [...path, "subworkflows"];
@@ -611,7 +810,12 @@ function collectSubworkflowSites(activity, path, sites) {
611
810
  label: `activity "${activity.name}".subworkflows.${group} "${key}"`
612
811
  });
613
812
  }
614
- function collectBindingSites(effects, path, label, sites) {
813
+ function collectBindingSites({
814
+ effects,
815
+ path,
816
+ label,
817
+ sites
818
+ }) {
615
819
  for (const [e, effect] of (effects ?? []).entries())
616
820
  for (const [key, groq2] of Object.entries(effect.bindings ?? {}))
617
821
  sites.push({
@@ -669,36 +873,67 @@ function checkActivityKinds(def, issues) {
669
873
  }
670
874
  function checkWorkflowInvariants(def) {
671
875
  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;
876
+ 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
877
  }
674
878
  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)];
879
+ const label = labelFor("defineWorkflow", definition), parsed = parseOrThrow({ schema: schema.AuthoringWorkflowSchema, input: definition, label }), { definition: stored, issues: desugarIssues } = desugarWorkflow(parsed), issues = [...desugarIssues, ...checkWorkflowInvariants(stored)];
676
880
  if (issues.length > 0) throw new Error(schema.formatValidationError(label, issues));
677
881
  return stored;
678
882
  }
883
+ function defineWorkflowConfig(config) {
884
+ return parseOrThrow({ schema: schema.WorkflowConfigSchema, input: config, label: "defineWorkflowConfig" });
885
+ }
679
886
  function defineStage(stage) {
680
- return parseOrThrow(schema.AuthoringStageSchema, stage, labelFor("defineStage", stage));
887
+ return parseOrThrow({
888
+ schema: schema.AuthoringStageSchema,
889
+ input: stage,
890
+ label: labelFor("defineStage", stage)
891
+ });
681
892
  }
682
893
  function defineActivity(activity) {
683
- return parseOrThrow(schema.AuthoringActivitySchema, activity, labelFor("defineActivity", activity));
894
+ return parseOrThrow({
895
+ schema: schema.AuthoringActivitySchema,
896
+ input: activity,
897
+ label: labelFor("defineActivity", activity)
898
+ });
684
899
  }
685
900
  function defineAction(action) {
686
- return parseOrThrow(schema.AuthoringActionSchema, action, labelFor("defineAction", action));
901
+ return parseOrThrow({
902
+ schema: schema.AuthoringActionSchema,
903
+ input: action,
904
+ label: labelFor("defineAction", action)
905
+ });
687
906
  }
688
907
  function defineTransition(transition) {
689
- return parseOrThrow(schema.AuthoringTransitionSchema, transition, transitionLabel(transition));
908
+ return parseOrThrow({
909
+ schema: schema.AuthoringTransitionSchema,
910
+ input: transition,
911
+ label: transitionLabel(transition)
912
+ });
690
913
  }
691
914
  function defineField(entry) {
692
- return parseOrThrow(schema.AuthoringFieldEntrySchema, entry, labelFor("defineField", entry));
915
+ return parseOrThrow({
916
+ schema: schema.AuthoringFieldEntrySchema,
917
+ input: entry,
918
+ label: labelFor("defineField", entry)
919
+ });
693
920
  }
694
921
  function defineOp(op) {
695
- return parseOrThrow(schema.AuthoringOpSchema, op, "defineOp");
922
+ return parseOrThrow({ schema: schema.AuthoringOpSchema, input: op, label: "defineOp" });
696
923
  }
697
924
  function defineGuard(guard) {
698
- return parseOrThrow(schema.GuardSchema, guard, labelFor("defineGuard", guard));
925
+ return parseOrThrow({
926
+ schema: schema.AuthoringGuardSchema,
927
+ input: guard,
928
+ label: labelFor("defineGuard", guard)
929
+ });
699
930
  }
700
931
  function defineEffect(effect) {
701
- return parseOrThrow(schema.EffectSchema, effect, labelFor("defineEffect", effect));
932
+ return parseOrThrow({
933
+ schema: schema.EffectSchema,
934
+ input: effect,
935
+ label: labelFor("defineEffect", effect)
936
+ });
702
937
  }
703
938
  function transitionLabel(transition) {
704
939
  const { name, to } = transition;
@@ -708,7 +943,11 @@ function defineEffectDescriptor(descriptor) {
708
943
  if (!descriptor.name) throw new Error("EffectDescriptor missing name");
709
944
  return descriptor;
710
945
  }
711
- function parseOrThrow(schema$1, input, label) {
946
+ function parseOrThrow({
947
+ schema: schema$1,
948
+ input,
949
+ label
950
+ }) {
712
951
  const result = v__namespace.safeParse(schema$1, input);
713
952
  if (!result.success)
714
953
  throw new Error(schema.formatValidationError(label, schema.issuesFromValibot(result.issues)));
@@ -721,6 +960,10 @@ function labelFor(fn, value) {
721
960
  }
722
961
  return fn;
723
962
  }
963
+ exports.CONDITION_VARS = schema.CONDITION_VARS;
964
+ exports.FILTER_SCOPE_VARS = schema.FILTER_SCOPE_VARS;
965
+ exports.GUARD_PREDICATE_VARS = schema.GUARD_PREDICATE_VARS;
966
+ exports.RESERVED_CONDITION_VARS = schema.RESERVED_CONDITION_VARS;
724
967
  exports.defineAction = defineAction;
725
968
  exports.defineActivity = defineActivity;
726
969
  exports.defineEffect = defineEffect;
@@ -731,5 +974,6 @@ exports.defineOp = defineOp;
731
974
  exports.defineStage = defineStage;
732
975
  exports.defineTransition = defineTransition;
733
976
  exports.defineWorkflow = defineWorkflow;
977
+ exports.defineWorkflowConfig = defineWorkflowConfig;
734
978
  exports.groq = groq;
735
979
  //# sourceMappingURL=define.cjs.map