@sanity/workflow-engine 0.29.0 → 0.31.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/CHANGELOG.md +61 -0
- package/DATAMODEL.md +67 -22
- package/dist/_chunks-cjs/invariants.cjs +286 -87
- package/dist/_chunks-es/invariants.js +281 -88
- package/dist/define.d.cts +289 -276
- package/dist/define.d.ts +289 -276
- package/dist/index.cjs +1297 -914
- package/dist/index.d.cts +917 -1056
- package/dist/index.d.ts +917 -1056
- package/dist/index.js +1116 -749
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -144,6 +144,9 @@ function resolveFieldSite(site, stage) {
|
|
|
144
144
|
...site.entry.validation !== void 0 ? {
|
|
145
145
|
validation: site.entry.validation
|
|
146
146
|
} : {},
|
|
147
|
+
...site.entry.roles !== void 0 ? {
|
|
148
|
+
roles: site.entry.roles
|
|
149
|
+
} : {},
|
|
147
150
|
ref: {
|
|
148
151
|
scope: site.scope,
|
|
149
152
|
field: site.entry.name
|
|
@@ -280,58 +283,58 @@ function resolveTelemetry(telemetry) {
|
|
|
280
283
|
}
|
|
281
284
|
|
|
282
285
|
const HIGH_FREQUENCY_SAMPLE_MS = 6e4, WorkflowDefinitionDeployed = defineWorkflowEvent({
|
|
283
|
-
name: "
|
|
286
|
+
name: "Workflows Definition Deployed",
|
|
284
287
|
version: 1,
|
|
285
288
|
description: "A definition went through a deploy — status distinguishes a newly minted version from an unchanged redeploy"
|
|
286
289
|
}), WorkflowInstanceStarted = defineWorkflowEvent({
|
|
287
|
-
name: "
|
|
290
|
+
name: "Workflows Instance Started",
|
|
288
291
|
version: 1,
|
|
289
292
|
description: "A workflow instance was started from a deployed definition"
|
|
290
293
|
}), WorkflowStageTransitioned = defineWorkflowEvent({
|
|
291
|
-
name: "
|
|
294
|
+
name: "Workflows Stage Transitioned",
|
|
292
295
|
version: 1,
|
|
293
296
|
description: "A committed stage move — one event per hop, cascades included, whichever verb drove it. Unsampled: funnel and dwell reads need complete counts, and volume is bounded by actual movement"
|
|
294
297
|
}), WorkflowActionFired = defineWorkflowEvent({
|
|
295
|
-
name: "
|
|
298
|
+
name: "Workflows Action Fired",
|
|
296
299
|
version: 1,
|
|
297
300
|
description: "An action was fired against an activity"
|
|
298
301
|
}), WorkflowFieldEdited = defineWorkflowEvent({
|
|
299
|
-
name: "
|
|
302
|
+
name: "Workflows Field Edited",
|
|
300
303
|
version: 1,
|
|
301
304
|
description: "A declared-editable field was edited through the generic edit seam",
|
|
302
305
|
maxSampleRate: HIGH_FREQUENCY_SAMPLE_MS
|
|
303
306
|
}), WorkflowInstanceTicked = defineWorkflowEvent({
|
|
304
|
-
name: "
|
|
307
|
+
name: "Workflows Instance Ticked",
|
|
305
308
|
version: 1,
|
|
306
309
|
description: "An instance was re-evaluated for auto-transitions and due waits",
|
|
307
310
|
maxSampleRate: HIGH_FREQUENCY_SAMPLE_MS
|
|
308
311
|
}), WorkflowEffectsDrained = defineWorkflowEvent({
|
|
309
|
-
name: "
|
|
312
|
+
name: "Workflows Effects Drained",
|
|
310
313
|
version: 1,
|
|
311
314
|
description: "A drain pass ran — drainedCount/drainedEffects report the successful dispatches. Unsampled when non-empty (outcome counts must be complete; volume is bounded by real effect work); empty polls are machine-cadence noise, throttled engine-side to at most one per minute"
|
|
312
315
|
}), WorkflowEffectStateReported = defineWorkflowEvent({
|
|
313
|
-
name: "
|
|
316
|
+
name: "Workflows Effect State Reported",
|
|
314
317
|
version: 1,
|
|
315
318
|
description: "A running effect handler committed mid-dispatch field state through commitEffectOps. Sampled (high-frequency by design — a dispatch may report many times): an adoption and usage signal, not an exact per-run report count",
|
|
316
319
|
maxSampleRate: HIGH_FREQUENCY_SAMPLE_MS
|
|
317
320
|
}), WorkflowEffectCompleted = defineWorkflowEvent({
|
|
318
|
-
name: "
|
|
321
|
+
name: "Workflows Effect Completed",
|
|
319
322
|
version: 1,
|
|
320
|
-
description: "An effect outcome was recorded — reported directly through completeEffect, or cancelled by the abort verb (external runtimes; engine-drained effects surface via
|
|
323
|
+
description: "An effect outcome was recorded — reported directly through completeEffect, or cancelled by the abort verb (external runtimes; engine-drained effects surface via Workflows Effects Drained instead — each outcome counts once)"
|
|
321
324
|
}), WorkflowInstanceAborted = defineWorkflowEvent({
|
|
322
|
-
name: "
|
|
325
|
+
name: "Workflows Instance Aborted",
|
|
323
326
|
version: 1,
|
|
324
327
|
description: "The abort admin override was invoked (changed: false = instance already terminal)"
|
|
325
328
|
}), WorkflowStageSet = defineWorkflowEvent({
|
|
326
|
-
name: "
|
|
329
|
+
name: "Workflows Stage Set",
|
|
327
330
|
version: 1,
|
|
328
331
|
description: "The set-stage admin override was invoked (changed: false = already at the target stage)"
|
|
329
332
|
}), WorkflowActivityReset = defineWorkflowEvent({
|
|
330
|
-
name: "
|
|
333
|
+
name: "Workflows Activity Reset",
|
|
331
334
|
version: 1,
|
|
332
335
|
description: "The reset-activity admin override was invoked (changed: false = already at the target status, or the instance was terminal)"
|
|
333
336
|
}), WorkflowDefinitionDeleted = defineWorkflowEvent({
|
|
334
|
-
name: "
|
|
337
|
+
name: "Workflows Definition Deleted",
|
|
335
338
|
version: 1,
|
|
336
339
|
description: "A deployed definition (or one version of it) was removed via the admin verb"
|
|
337
340
|
});
|
|
@@ -449,438 +452,131 @@ function fieldEditedData(args) {
|
|
|
449
452
|
};
|
|
450
453
|
}
|
|
451
454
|
|
|
452
|
-
|
|
455
|
+
function effectSites(def) {
|
|
456
|
+
const sites = [];
|
|
457
|
+
for (const stage of def.stages ?? []) for (const activity of stage.activities ?? []) for (const action of activity.actions ?? []) for (const effect of action.effects ?? []) sites.push({
|
|
458
|
+
effect: effect,
|
|
459
|
+
location: `stage[${stage.name}].activity[${activity.name}].action[${action.name}].effects`
|
|
460
|
+
});
|
|
461
|
+
return sites;
|
|
462
|
+
}
|
|
453
463
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
expectedMinReaderModel;
|
|
457
|
-
engineMinReaderModel=DATA_MODEL_MIN_READER;
|
|
458
|
-
engineModelVersion=DATA_MODEL_VERSION;
|
|
459
|
-
documentationUrl=READER_MODEL_ROLLOUT_URL;
|
|
460
|
-
constructor(expectedMinReaderModel, context = "Deployment") {
|
|
461
|
-
const expected = expectedMinReaderModel === void 0 ? "missing" : String(expectedMinReaderModel);
|
|
462
|
-
super("reader-model-acknowledgement", `${context} expected reader floor ${expected}; the installed engine requires acknowledgement ${DATA_MODEL_MIN_READER}.\nDo not change the acknowledgement yet: accepting ${DATA_MODEL_MIN_READER} authorizes this engine to write documents that older readers will refuse.\nUpgrade every Studio, CLI, MCP server, Function, and other runtime that reads engine-owned documents; verify that rollout in every environment sharing the workflow resource; then change the literal in deployment configuration and deploy the writer.\nRollout guide: ${READER_MODEL_ROLLOUT_URL}`),
|
|
463
|
-
this.name = "ReaderModelAcknowledgementError", this.expectedMinReaderModel = expectedMinReaderModel;
|
|
464
|
-
}
|
|
464
|
+
function findEffect(def, name) {
|
|
465
|
+
return effectSites(def).find(site => site.effect.name === name)?.effect;
|
|
465
466
|
}
|
|
466
467
|
|
|
467
|
-
function
|
|
468
|
-
|
|
468
|
+
function rolesGateOf(atom) {
|
|
469
|
+
const node = groqConditionDescribe.atomNode(atom);
|
|
470
|
+
if (atom.negated || node.type !== "OpCall" || node.op !== ">" || node.right.type !== "Value" || node.right.value !== 0) return;
|
|
471
|
+
const count = node.left;
|
|
472
|
+
if (!(count.type !== "FuncCall" || count.name !== "count" || count.args.length !== 1)) return rolesFilterList(count.args[0]);
|
|
469
473
|
}
|
|
470
474
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
}
|
|
480
|
-
id: "subject-field-kind",
|
|
481
|
-
introducedInModel: 2,
|
|
482
|
-
minReaderModel: 0,
|
|
483
|
-
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
484
|
-
compatibility: "additive",
|
|
485
|
-
applicability: "detectable",
|
|
486
|
-
summary: "A workflow-level subject field identifies the document a workflow is about."
|
|
487
|
-
}), Object.freeze({
|
|
488
|
-
id: "typed-scalar-choice-lists",
|
|
489
|
-
introducedInModel: 2,
|
|
490
|
-
minReaderModel: 2,
|
|
491
|
-
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
492
|
-
compatibility: "reader-floor",
|
|
493
|
-
applicability: "detectable",
|
|
494
|
-
summary: "Scalar fields may constrain writes to a persisted typed choice list."
|
|
495
|
-
}), Object.freeze({
|
|
496
|
-
id: "action-semantics",
|
|
497
|
-
introducedInModel: 2,
|
|
498
|
-
minReaderModel: 0,
|
|
499
|
-
documentTypes: Object.freeze([ "definition" ]),
|
|
500
|
-
compatibility: "additive",
|
|
501
|
-
applicability: "detectable",
|
|
502
|
-
summary: "Ordinary actions may carry advisory workflow semantics."
|
|
503
|
-
}), Object.freeze({
|
|
504
|
-
id: "inclusive-scalar-bounds",
|
|
505
|
-
introducedInModel: 2,
|
|
506
|
-
minReaderModel: 2,
|
|
507
|
-
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
508
|
-
compatibility: "reader-floor",
|
|
509
|
-
applicability: "detectable",
|
|
510
|
-
summary: "String, text, and number values may carry persisted inclusive bounds."
|
|
511
|
-
}), Object.freeze({
|
|
512
|
-
id: "progress-field-kind",
|
|
513
|
-
introducedInModel: 3,
|
|
514
|
-
minReaderModel: 0,
|
|
515
|
-
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
516
|
-
compatibility: "additive",
|
|
517
|
-
applicability: "detectable",
|
|
518
|
-
summary: "A progress field kind carries application-defined 0–100 completion."
|
|
519
|
-
}), Object.freeze({
|
|
520
|
-
id: "effect-claim-tokens",
|
|
521
|
-
introducedInModel: 3,
|
|
522
|
-
minReaderModel: 0,
|
|
523
|
-
documentTypes: Object.freeze([ "instance" ]),
|
|
524
|
-
compatibility: "additive",
|
|
525
|
-
applicability: "detectable",
|
|
526
|
-
summary: "Pending-effect claims carry an exact-claim token gating mid-dispatch state reports."
|
|
527
|
-
}), Object.freeze({
|
|
528
|
-
id: "classified-principal-ids",
|
|
529
|
-
introducedInModel: 4,
|
|
530
|
-
minReaderModel: 4,
|
|
531
|
-
documentTypes: Object.freeze([ "instance" ]),
|
|
532
|
-
compatibility: "reader-floor",
|
|
533
|
-
applicability: "unconditional",
|
|
534
|
-
summary: "Principal ids are namespace-classified: actor and assignee writes carry the account-global user id only, and readers resolve legacy project-scoped ids through the prefix classifier at the instance read funnel."
|
|
535
|
-
}), Object.freeze({
|
|
536
|
-
id: "readiness-requirements",
|
|
537
|
-
introducedInModel: 4,
|
|
538
|
-
minReaderModel: 4,
|
|
539
|
-
documentTypes: Object.freeze([ "definition" ]),
|
|
540
|
-
compatibility: "reader-floor",
|
|
541
|
-
applicability: "detectable",
|
|
542
|
-
summary: "Start and activity readiness use named polymorphic requirement arrays."
|
|
543
|
-
}), Object.freeze({
|
|
544
|
-
id: "due-date-field-kinds",
|
|
545
|
-
introducedInModel: 5,
|
|
546
|
-
minReaderModel: 0,
|
|
547
|
-
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
548
|
-
compatibility: "additive",
|
|
549
|
-
applicability: "detectable",
|
|
550
|
-
summary: "Due-date field kinds (dueDate, dueDatetime) mark a level deadline, elevated aliases of date/datetime carrying the same stored value."
|
|
551
|
-
}), Object.freeze({
|
|
552
|
-
id: "node-semantics",
|
|
553
|
-
introducedInModel: 6,
|
|
554
|
-
minReaderModel: 0,
|
|
555
|
-
documentTypes: Object.freeze([ "definition" ]),
|
|
556
|
-
compatibility: "additive",
|
|
557
|
-
applicability: "detectable",
|
|
558
|
-
summary: "Workflow, stage, activity, and action nodes may carry signal or custom advisory semantics."
|
|
559
|
-
}), Object.freeze({
|
|
560
|
-
id: "field-patch-ops",
|
|
561
|
-
introducedInModel: 6,
|
|
562
|
-
minReaderModel: 0,
|
|
563
|
-
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
564
|
-
compatibility: "additive",
|
|
565
|
-
applicability: "detectable",
|
|
566
|
-
summary: "Field ops may increment, decrement, or initialize a missing field value."
|
|
567
|
-
}), Object.freeze({
|
|
568
|
-
id: "attributes-condition-var",
|
|
569
|
-
introducedInModel: 7,
|
|
570
|
-
minReaderModel: 0,
|
|
571
|
-
documentTypes: Object.freeze([ "definition" ]),
|
|
572
|
-
compatibility: "additive",
|
|
573
|
-
applicability: "unconditional",
|
|
574
|
-
summary: "Caller-bound $attributes condition variable binds the acting token's org-level User Attributes (advisory; absent when unavailable)."
|
|
575
|
-
}) ]);
|
|
475
|
+
function rolesFilterList(node) {
|
|
476
|
+
if (node.type !== "Filter") return;
|
|
477
|
+
const base = node.base;
|
|
478
|
+
if (!(base.type === "AccessAttribute" && base.name === "roles" && base.base?.type === "Parameter" && base.base.name === "actor")) return;
|
|
479
|
+
const expr = node.expr;
|
|
480
|
+
if (expr.type !== "OpCall" || expr.op !== "in" || expr.left.type !== "This" || expr.right.type !== "Array") return;
|
|
481
|
+
const roles = expr.right.elements.flatMap(element => !element.isSplat && element.value.type === "Value" && typeof element.value.value == "string" ? [ element.value.value ] : []);
|
|
482
|
+
if (roles.length === expr.right.elements.length) return roles;
|
|
483
|
+
}
|
|
576
484
|
|
|
577
|
-
function
|
|
578
|
-
return
|
|
485
|
+
function deriveWorkflowAutonomy(definition, options = {}) {
|
|
486
|
+
return workflowAutonomy({
|
|
487
|
+
definition: definition,
|
|
488
|
+
children: options.children ?? /* @__PURE__ */ new Map,
|
|
489
|
+
lineage: /* @__PURE__ */ new Set
|
|
490
|
+
});
|
|
579
491
|
}
|
|
580
492
|
|
|
581
|
-
function
|
|
582
|
-
const
|
|
583
|
-
|
|
493
|
+
function stageAutonomyOf(autonomy, stageName) {
|
|
494
|
+
const stage = autonomy.stages.find(candidate => candidate.stage === stageName);
|
|
495
|
+
if (stage === void 0) throw new Error(`Autonomy rollup is missing stage "${stageName}"`);
|
|
496
|
+
return stage;
|
|
584
497
|
}
|
|
585
498
|
|
|
586
|
-
function
|
|
587
|
-
|
|
499
|
+
function activityAutonomyOf(stageAutonomy2, activityName) {
|
|
500
|
+
const answer = stageAutonomy2.activities[activityName];
|
|
501
|
+
if (answer === void 0) throw new Error(`Autonomy rollup is missing activity "${activityName}" in stage "${stageAutonomy2.stage}"`);
|
|
502
|
+
return answer;
|
|
588
503
|
}
|
|
589
504
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
505
|
+
const AUTONOMOUS = {
|
|
506
|
+
completesWithoutCaller: "yes",
|
|
507
|
+
waitsOn: []
|
|
508
|
+
}, UNDECIDABLE = {
|
|
509
|
+
completesWithoutCaller: "conditional",
|
|
510
|
+
waitsOn: []
|
|
511
|
+
}, CALLER = {
|
|
512
|
+
completesWithoutCaller: "no",
|
|
513
|
+
waitsOn: []
|
|
514
|
+
}, VERDICT_RANK = {
|
|
515
|
+
yes: 0,
|
|
516
|
+
conditional: 1,
|
|
517
|
+
no: 2
|
|
518
|
+
};
|
|
519
|
+
|
|
520
|
+
function allOf(deps) {
|
|
521
|
+
return {
|
|
522
|
+
completesWithoutCaller: deps.map(dep => dep.completesWithoutCaller).reduce((worst, verdict) => VERDICT_RANK[verdict] > VERDICT_RANK[worst] ? verdict : worst, "yes"),
|
|
523
|
+
waitsOn: mergeWaits(deps)
|
|
524
|
+
};
|
|
595
525
|
}
|
|
596
526
|
|
|
597
|
-
function
|
|
598
|
-
const
|
|
599
|
-
if (
|
|
600
|
-
const snapshot = parsedDefinitionSnapshot(root), roots = snapshot === void 0 ? [ root ] : [ root, snapshot ], {stages: stages, activities: activities, actions: actions} = definitionDescendants(roots);
|
|
527
|
+
function anyOf(deps) {
|
|
528
|
+
const [first, ...rest] = deps;
|
|
529
|
+
if (first === void 0) throw new Error("anyOf needs at least one route — callers guard empties");
|
|
601
530
|
return {
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
activities: activities,
|
|
605
|
-
actions: actions
|
|
531
|
+
completesWithoutCaller: rest.every(dep => dep.completesWithoutCaller === first.completesWithoutCaller) ? first.completesWithoutCaller : "conditional",
|
|
532
|
+
waitsOn: mergeWaits(deps)
|
|
606
533
|
};
|
|
607
534
|
}
|
|
608
535
|
|
|
609
|
-
function
|
|
610
|
-
|
|
611
|
-
if (tree === void 0) return [];
|
|
612
|
-
const {roots: roots, stages: stages, activities: activities, actions: actions} = tree, effects = actions.flatMap(action => recordsAt(action, "effects"));
|
|
613
|
-
return nestedFieldEntries([ ...roots.flatMap(candidate => recordsAt(candidate, "fields")), ...stages.flatMap(stage => recordsAt(stage, "fields")), ...activities.flatMap(activity => recordsAt(activity, "fields")), ...actions.flatMap(action => recordsAt(action, "params")), ...effects.flatMap(effect => recordsAt(effect, "outputs")) ]);
|
|
536
|
+
function mergeWaits(deps) {
|
|
537
|
+
return groqConditionDescribe.dedupeBy(deps.flatMap(dep => dep.waitsOn), wait => JSON.stringify(wait));
|
|
614
538
|
}
|
|
615
539
|
|
|
616
|
-
function
|
|
617
|
-
const
|
|
540
|
+
function analysisCtx(args) {
|
|
541
|
+
const memo = /* @__PURE__ */ new Map, visiting = /* @__PURE__ */ new Set;
|
|
618
542
|
return {
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
543
|
+
...args,
|
|
544
|
+
memoized: (key, compute) => {
|
|
545
|
+
const hit = memo.get(key);
|
|
546
|
+
if (hit !== void 0) return hit;
|
|
547
|
+
if (visiting.has(key)) return UNDECIDABLE;
|
|
548
|
+
visiting.add(key);
|
|
549
|
+
try {
|
|
550
|
+
const answer = compute();
|
|
551
|
+
return memo.set(key, answer), answer;
|
|
552
|
+
} finally {
|
|
553
|
+
visiting.delete(key);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
622
556
|
};
|
|
623
557
|
}
|
|
624
558
|
|
|
625
|
-
function
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
559
|
+
function workflowAutonomy(args) {
|
|
560
|
+
const ctx = analysisCtx({
|
|
561
|
+
definition: args.definition,
|
|
562
|
+
children: args.children,
|
|
563
|
+
lineage: /* @__PURE__ */ new Set([ ...args.lineage, args.definition.name ])
|
|
564
|
+
}), stages = ctx.definition.stages.map(stage => stageAutonomy(stage, ctx));
|
|
565
|
+
return {
|
|
566
|
+
...allOf(stages),
|
|
567
|
+
stages: stages
|
|
568
|
+
};
|
|
634
569
|
}
|
|
635
570
|
|
|
636
|
-
function
|
|
637
|
-
const
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
return definitionNodes(document)?.actions.some(hasSemantics) ?? !1;
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
function hasNodeSemantics(document) {
|
|
649
|
-
const nodes = definitionNodes(document);
|
|
650
|
-
return nodes === void 0 ? !1 : [ nodes.root, ...nodes.stages, ...nodes.activities ].some(hasSemantics) ? !0 : nodes.actions.some(action => hasSemantics(action) && action.semantics.some(isNodeSemanticValue));
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
function isNodeSemanticValue(semantic) {
|
|
654
|
-
return typeof semantic == "string" && (semantic.startsWith("signal.") || semantic.startsWith("custom."));
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
function hasSemantics(node) {
|
|
658
|
-
return Array.isArray(node.semantics);
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
function hasPersistedOpType(document, types) {
|
|
662
|
-
const tree = persistedDefinitionTree(document);
|
|
663
|
-
return tree === void 0 ? !1 : tree.actions.flatMap(action => recordsAt(action, "ops")).some(op => typeof op.type == "string" && types.includes(op.type)) ? !0 : tree.roots.some(root => recordsAt(root, "history").some(entry => entry._type === "opApplied" && typeof entry.opType == "string" && types.includes(entry.opType)));
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
function hasScalarValidation(document) {
|
|
667
|
-
return persistedFieldEntries(document).some(entry => {
|
|
668
|
-
const validation = recordOf(entry.validation);
|
|
669
|
-
return typeof validation?.min == "number" || typeof validation?.max == "number";
|
|
670
|
-
});
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
function hasClaimTokens(document) {
|
|
674
|
-
const root = recordOf(document);
|
|
675
|
-
return root === void 0 ? !1 : recordsAt(root, "pendingEffects").some(entry => {
|
|
676
|
-
const claim = recordOf(entry.claim);
|
|
677
|
-
return claim !== void 0 && typeof claim.claimToken == "string";
|
|
678
|
-
});
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
function hasReadinessRequirements(document) {
|
|
682
|
-
const root = recordOf(document);
|
|
683
|
-
return root === void 0 ? !1 : Array.isArray(recordOf(root.start)?.requirements) ? !0 : recordsAt(root, "stages").some(stage => recordsAt(stage, "activities").some(activity => Array.isArray(activity.requirements)));
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
const featureDetectors = {
|
|
687
|
-
"governed-model-stamps": () => !0,
|
|
688
|
-
"subject-field-kind": document => hasFieldKind(document, "subject"),
|
|
689
|
-
"typed-scalar-choice-lists": hasChoiceList,
|
|
690
|
-
"action-semantics": hasActionSemantics,
|
|
691
|
-
"inclusive-scalar-bounds": hasScalarValidation,
|
|
692
|
-
"progress-field-kind": document => hasFieldKind(document, "progress"),
|
|
693
|
-
"effect-claim-tokens": hasClaimTokens,
|
|
694
|
-
"classified-principal-ids": () => !0,
|
|
695
|
-
"readiness-requirements": hasReadinessRequirements,
|
|
696
|
-
"due-date-field-kinds": document => hasFieldKind(document, "dueDate") || hasFieldKind(document, "dueDatetime"),
|
|
697
|
-
"node-semantics": hasNodeSemantics,
|
|
698
|
-
"field-patch-ops": document => hasPersistedOpType(document, [ "field.inc", "field.dec", "field.setIfMissing" ]),
|
|
699
|
-
"attributes-condition-var": () => !0
|
|
700
|
-
};
|
|
701
|
-
|
|
702
|
-
function requiredModelFeatures(documentType, document) {
|
|
703
|
-
return DATA_MODEL_CHANGES.filter(change => change.documentTypes.some(candidate => candidate === documentType) && featureDetectors[change.id](document));
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
function requiredReaderModel(documentType, document) {
|
|
707
|
-
return Math.max(0, ...requiredModelFeatures(documentType, document).map(change => change.minReaderModel));
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
function modelStampFor(args) {
|
|
711
|
-
return {
|
|
712
|
-
modelVersion: DATA_MODEL_VERSION,
|
|
713
|
-
minReaderModel: Math.max(DATA_MODEL_MIN_READER, args.storedMinReaderModel ?? 0, requiredReaderModel(args.documentType, args.document))
|
|
714
|
-
};
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
function fieldTreeShape(value) {
|
|
718
|
-
if (Array.isArray(value)) return value.map(fieldTreeShape);
|
|
719
|
-
if (value === null) return "null";
|
|
720
|
-
if (typeof value == "object") {
|
|
721
|
-
const record = value;
|
|
722
|
-
return Object.fromEntries(Object.keys(record).toSorted().map(key => [ key, fieldTreeShape(record[key]) ]));
|
|
723
|
-
}
|
|
724
|
-
return typeof value;
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
function modelVersionOf(doc) {
|
|
728
|
-
const stamp = doc.modelVersion;
|
|
729
|
-
return typeof stamp == "number" ? stamp : 0;
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
function minReaderModelOf(doc) {
|
|
733
|
-
const floor = doc.minReaderModel;
|
|
734
|
-
return typeof floor == "number" ? floor : modelVersionOf(doc);
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
class ModelVersionAheadError extends invariants.WorkflowError {
|
|
738
|
-
documentId;
|
|
739
|
-
documentModelVersion;
|
|
740
|
-
requiredReaderModel;
|
|
741
|
-
engineModelVersion;
|
|
742
|
-
constructor(args) {
|
|
743
|
-
super("model-version-ahead", `Document "${args.documentId}" was written by engine data model ${args.documentModelVersion} and requires a reader at model ${args.requiredReaderModel} or newer; this engine reads up to model ${DATA_MODEL_VERSION}. Upgrade @sanity/workflow-engine to a version that understands it.`),
|
|
744
|
-
this.name = "ModelVersionAheadError", this.documentId = args.documentId, this.documentModelVersion = args.documentModelVersion,
|
|
745
|
-
this.requiredReaderModel = args.requiredReaderModel, this.engineModelVersion = DATA_MODEL_VERSION;
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
function assertReadableModel(doc) {
|
|
750
|
-
const documentReaderModel = minReaderModelOf(doc);
|
|
751
|
-
if (documentReaderModel > DATA_MODEL_VERSION) throw new ModelVersionAheadError({
|
|
752
|
-
documentId: doc._id,
|
|
753
|
-
documentModelVersion: modelVersionOf(doc),
|
|
754
|
-
requiredReaderModel: documentReaderModel
|
|
755
|
-
});
|
|
756
|
-
return doc;
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
function effectSites(def) {
|
|
760
|
-
const sites = [];
|
|
761
|
-
for (const stage of def.stages ?? []) for (const activity of stage.activities ?? []) for (const action of activity.actions ?? []) for (const effect of action.effects ?? []) sites.push({
|
|
762
|
-
effect: effect,
|
|
763
|
-
location: `stage[${stage.name}].activity[${activity.name}].action[${action.name}].effects`
|
|
764
|
-
});
|
|
765
|
-
return sites;
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
function findEffect(def, name) {
|
|
769
|
-
return effectSites(def).find(site => site.effect.name === name)?.effect;
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
function rolesGateOf(atom) {
|
|
773
|
-
const node = groqConditionDescribe.atomNode(atom);
|
|
774
|
-
if (atom.negated || node.type !== "OpCall" || node.op !== ">" || node.right.type !== "Value" || node.right.value !== 0) return;
|
|
775
|
-
const count = node.left;
|
|
776
|
-
if (!(count.type !== "FuncCall" || count.name !== "count" || count.args.length !== 1)) return rolesFilterList(count.args[0]);
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
function rolesFilterList(node) {
|
|
780
|
-
if (node.type !== "Filter") return;
|
|
781
|
-
const base = node.base;
|
|
782
|
-
if (!(base.type === "AccessAttribute" && base.name === "roles" && base.base?.type === "Parameter" && base.base.name === "actor")) return;
|
|
783
|
-
const expr = node.expr;
|
|
784
|
-
if (expr.type !== "OpCall" || expr.op !== "in" || expr.left.type !== "This" || expr.right.type !== "Array") return;
|
|
785
|
-
const roles = expr.right.elements.flatMap(element => !element.isSplat && element.value.type === "Value" && typeof element.value.value == "string" ? [ element.value.value ] : []);
|
|
786
|
-
if (roles.length === expr.right.elements.length) return roles;
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
function deriveWorkflowAutonomy(definition, options = {}) {
|
|
790
|
-
return workflowAutonomy({
|
|
791
|
-
definition: definition,
|
|
792
|
-
children: options.children ?? /* @__PURE__ */ new Map,
|
|
793
|
-
lineage: /* @__PURE__ */ new Set
|
|
794
|
-
});
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
function stageAutonomyOf(autonomy, stageName) {
|
|
798
|
-
const stage = autonomy.stages.find(candidate => candidate.stage === stageName);
|
|
799
|
-
if (stage === void 0) throw new Error(`Autonomy rollup is missing stage "${stageName}"`);
|
|
800
|
-
return stage;
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
function activityAutonomyOf(stageAutonomy2, activityName) {
|
|
804
|
-
const answer = stageAutonomy2.activities[activityName];
|
|
805
|
-
if (answer === void 0) throw new Error(`Autonomy rollup is missing activity "${activityName}" in stage "${stageAutonomy2.stage}"`);
|
|
806
|
-
return answer;
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
const AUTONOMOUS = {
|
|
810
|
-
completesWithoutCaller: "yes",
|
|
811
|
-
waitsOn: []
|
|
812
|
-
}, UNDECIDABLE = {
|
|
813
|
-
completesWithoutCaller: "conditional",
|
|
814
|
-
waitsOn: []
|
|
815
|
-
}, CALLER = {
|
|
816
|
-
completesWithoutCaller: "no",
|
|
817
|
-
waitsOn: []
|
|
818
|
-
}, VERDICT_RANK = {
|
|
819
|
-
yes: 0,
|
|
820
|
-
conditional: 1,
|
|
821
|
-
no: 2
|
|
822
|
-
};
|
|
823
|
-
|
|
824
|
-
function allOf(deps) {
|
|
825
|
-
return {
|
|
826
|
-
completesWithoutCaller: deps.map(dep => dep.completesWithoutCaller).reduce((worst, verdict) => VERDICT_RANK[verdict] > VERDICT_RANK[worst] ? verdict : worst, "yes"),
|
|
827
|
-
waitsOn: mergeWaits(deps)
|
|
828
|
-
};
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
function anyOf(deps) {
|
|
832
|
-
const [first, ...rest] = deps;
|
|
833
|
-
if (first === void 0) throw new Error("anyOf needs at least one route — callers guard empties");
|
|
834
|
-
return {
|
|
835
|
-
completesWithoutCaller: rest.every(dep => dep.completesWithoutCaller === first.completesWithoutCaller) ? first.completesWithoutCaller : "conditional",
|
|
836
|
-
waitsOn: mergeWaits(deps)
|
|
837
|
-
};
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
function mergeWaits(deps) {
|
|
841
|
-
return groqConditionDescribe.dedupeBy(deps.flatMap(dep => dep.waitsOn), wait => JSON.stringify(wait));
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
function analysisCtx(args) {
|
|
845
|
-
const memo = /* @__PURE__ */ new Map, visiting = /* @__PURE__ */ new Set;
|
|
846
|
-
return {
|
|
847
|
-
...args,
|
|
848
|
-
memoized: (key, compute) => {
|
|
849
|
-
const hit = memo.get(key);
|
|
850
|
-
if (hit !== void 0) return hit;
|
|
851
|
-
if (visiting.has(key)) return UNDECIDABLE;
|
|
852
|
-
visiting.add(key);
|
|
853
|
-
try {
|
|
854
|
-
const answer = compute();
|
|
855
|
-
return memo.set(key, answer), answer;
|
|
856
|
-
} finally {
|
|
857
|
-
visiting.delete(key);
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
};
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
function workflowAutonomy(args) {
|
|
864
|
-
const ctx = analysisCtx({
|
|
865
|
-
definition: args.definition,
|
|
866
|
-
children: args.children,
|
|
867
|
-
lineage: /* @__PURE__ */ new Set([ ...args.lineage, args.definition.name ])
|
|
868
|
-
}), stages = ctx.definition.stages.map(stage => stageAutonomy(stage, ctx));
|
|
869
|
-
return {
|
|
870
|
-
...allOf(stages),
|
|
871
|
-
stages: stages
|
|
872
|
-
};
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
function stageAutonomy(stage, ctx) {
|
|
876
|
-
const activities = Object.fromEntries((stage.activities ?? []).map(activity => [ activity.name, activityCompletion({
|
|
877
|
-
stage: stage,
|
|
878
|
-
activity: activity
|
|
879
|
-
}, ctx) ]));
|
|
880
|
-
return {
|
|
881
|
-
...stageProgress(stage, ctx),
|
|
882
|
-
stage: stage.name,
|
|
883
|
-
activities: activities
|
|
571
|
+
function stageAutonomy(stage, ctx) {
|
|
572
|
+
const activities = Object.fromEntries((stage.activities ?? []).map(activity => [ activity.name, activityCompletion({
|
|
573
|
+
stage: stage,
|
|
574
|
+
activity: activity
|
|
575
|
+
}, ctx) ]));
|
|
576
|
+
return {
|
|
577
|
+
...stageProgress(stage, ctx),
|
|
578
|
+
stage: stage.name,
|
|
579
|
+
activities: activities
|
|
884
580
|
};
|
|
885
581
|
}
|
|
886
582
|
|
|
@@ -2171,10 +1867,6 @@ function derefBase(ref, snapshot) {
|
|
|
2171
1867
|
};
|
|
2172
1868
|
}
|
|
2173
1869
|
|
|
2174
|
-
function isRecord(value) {
|
|
2175
|
-
return typeof value == "object" && value !== null && !Array.isArray(value);
|
|
2176
|
-
}
|
|
2177
|
-
|
|
2178
1870
|
function buildParams(args) {
|
|
2179
1871
|
const {instance: instance, now: now, snapshot: snapshot, extra: extra} = args, currentActivities2 = findOpenStageEntry(instance)?.activities ?? [];
|
|
2180
1872
|
return {
|
|
@@ -2711,38 +2403,7 @@ function isFieldOp(summary) {
|
|
|
2711
2403
|
|
|
2712
2404
|
function validateActionParams({action: action, activityName: activityName, callerParams: callerParams}) {
|
|
2713
2405
|
const declared = action.params ?? [], params = callerParams ?? {}, issues = [];
|
|
2714
|
-
for (const decl of declared)
|
|
2715
|
-
const value = params[decl.name], present = decl.name in params && value !== void 0 && value !== null;
|
|
2716
|
-
if (decl.required === !0 && !present) {
|
|
2717
|
-
issues.push({
|
|
2718
|
-
param: decl.name,
|
|
2719
|
-
reason: "required but missing"
|
|
2720
|
-
});
|
|
2721
|
-
continue;
|
|
2722
|
-
}
|
|
2723
|
-
if (!present) continue;
|
|
2724
|
-
if (!checkParamType(value, decl)) {
|
|
2725
|
-
issues.push({
|
|
2726
|
-
param: decl.name,
|
|
2727
|
-
reason: `expected type=${decl.type}, got ${typeof value}`
|
|
2728
|
-
});
|
|
2729
|
-
continue;
|
|
2730
|
-
}
|
|
2731
|
-
const choiceIssues = invariants.choiceValueIssues(decl.options, value);
|
|
2732
|
-
choiceIssues !== void 0 && issues.push({
|
|
2733
|
-
param: decl.name,
|
|
2734
|
-
reason: choiceIssues.join("; ")
|
|
2735
|
-
});
|
|
2736
|
-
const validationIssues = invariants.scalarValidationIssues({
|
|
2737
|
-
entryType: decl.type,
|
|
2738
|
-
validation: decl.validation,
|
|
2739
|
-
value: value
|
|
2740
|
-
});
|
|
2741
|
-
validationIssues !== void 0 && issues.push({
|
|
2742
|
-
param: decl.name,
|
|
2743
|
-
reason: validationIssues.join("; ")
|
|
2744
|
-
});
|
|
2745
|
-
}
|
|
2406
|
+
for (const decl of declared) issues.push(...declaredParamIssues(decl, params));
|
|
2746
2407
|
if (issues.length > 0) throw new ActionParamsInvalidError({
|
|
2747
2408
|
action: action.name,
|
|
2748
2409
|
activity: activityName,
|
|
@@ -2751,8 +2412,32 @@ function validateActionParams({action: action, activityName: activityName, calle
|
|
|
2751
2412
|
return params;
|
|
2752
2413
|
}
|
|
2753
2414
|
|
|
2754
|
-
function
|
|
2755
|
-
|
|
2415
|
+
function declaredParamIssues(decl, params) {
|
|
2416
|
+
const value = params[decl.name];
|
|
2417
|
+
if (!(decl.name in params && value !== void 0 && value !== null)) return decl.required === !0 ? [ {
|
|
2418
|
+
param: decl.name,
|
|
2419
|
+
reason: "required but missing"
|
|
2420
|
+
} ] : [];
|
|
2421
|
+
if (!checkParamType(value, decl)) return [ {
|
|
2422
|
+
param: decl.name,
|
|
2423
|
+
reason: `expected type=${decl.type}, got ${typeof value}`
|
|
2424
|
+
} ];
|
|
2425
|
+
const choiceIssues = invariants.choiceValueIssues(decl.options, value), validationIssues = invariants.scalarValidationIssues({
|
|
2426
|
+
entryType: decl.type,
|
|
2427
|
+
validation: decl.validation,
|
|
2428
|
+
value: value
|
|
2429
|
+
});
|
|
2430
|
+
return [ ...choiceIssues === void 0 ? [] : [ {
|
|
2431
|
+
param: decl.name,
|
|
2432
|
+
reason: choiceIssues.join("; ")
|
|
2433
|
+
} ], ...validationIssues === void 0 ? [] : [ {
|
|
2434
|
+
param: decl.name,
|
|
2435
|
+
reason: validationIssues.join("; ")
|
|
2436
|
+
} ] ];
|
|
2437
|
+
}
|
|
2438
|
+
|
|
2439
|
+
function hasStringField(value, field) {
|
|
2440
|
+
return typeof value == "object" && value !== null && field in value && typeof value[field] == "string";
|
|
2756
2441
|
}
|
|
2757
2442
|
|
|
2758
2443
|
function checkParamType(value, decl) {
|
|
@@ -2802,7 +2487,9 @@ async function runOps(args) {
|
|
|
2802
2487
|
now: now,
|
|
2803
2488
|
snapshot: snapshot,
|
|
2804
2489
|
refSurface: refSurface,
|
|
2805
|
-
opsFromDefinition: opsFromDefinition
|
|
2490
|
+
opsFromDefinition: opsFromDefinition,
|
|
2491
|
+
memberRoles: args.memberRoles,
|
|
2492
|
+
roleAliases: args.roleAliases
|
|
2806
2493
|
});
|
|
2807
2494
|
summaries.push(summary), shouldRecordOpApplied(summary) && mutation.history.push(opAppliedEntry({
|
|
2808
2495
|
origin: origin,
|
|
@@ -2923,7 +2610,12 @@ function applyFieldSet(op, ctx) {
|
|
|
2923
2610
|
entryType: entry._type,
|
|
2924
2611
|
entryName: entry.name,
|
|
2925
2612
|
value: value,
|
|
2926
|
-
...entryShape(entry)
|
|
2613
|
+
...entryShape(entry),
|
|
2614
|
+
memberRoles: ctx.memberRoles,
|
|
2615
|
+
roleAliases: ctx.roleAliases,
|
|
2616
|
+
...entry._type === "assignees" || entry._type === "object" || entry._type === "array" ? {
|
|
2617
|
+
previousValue: entry.value
|
|
2618
|
+
} : {}
|
|
2927
2619
|
});
|
|
2928
2620
|
return assertRuntimeRefsWithinSurface({
|
|
2929
2621
|
entryType: entry._type,
|
|
@@ -3020,7 +2712,17 @@ function entryShape(entry) {
|
|
|
3020
2712
|
of: entry.of
|
|
3021
2713
|
} : invariants.isSingleDocRefEntry(entry) || entry._type === "doc.refs" ? entry.types !== void 0 ? {
|
|
3022
2714
|
types: entry.types
|
|
3023
|
-
} : {} :
|
|
2715
|
+
} : {} : invariants.isAssignmentFieldEntry(entry) ? assignmentEntryShape(entry) : scalarEntryShape(entry);
|
|
2716
|
+
}
|
|
2717
|
+
|
|
2718
|
+
function assignmentEntryShape(entry) {
|
|
2719
|
+
return entry.roles !== void 0 ? {
|
|
2720
|
+
roles: entry.roles
|
|
2721
|
+
} : {};
|
|
2722
|
+
}
|
|
2723
|
+
|
|
2724
|
+
function scalarEntryShape(entry) {
|
|
2725
|
+
return {
|
|
3024
2726
|
...entry.options !== void 0 ? {
|
|
3025
2727
|
options: entry.options
|
|
3026
2728
|
} : {},
|
|
@@ -3069,7 +2771,10 @@ function applyFieldAppend(op, ctx) {
|
|
|
3069
2771
|
entryName: entry.name,
|
|
3070
2772
|
item: item,
|
|
3071
2773
|
types: entry._type === "doc.refs" ? entry.types : void 0,
|
|
3072
|
-
of: entry._type === "array" ? entry.of : void 0
|
|
2774
|
+
of: entry._type === "array" ? entry.of : void 0,
|
|
2775
|
+
roles: entry._type === "assignees" ? entry.roles : void 0,
|
|
2776
|
+
memberRoles: ctx.memberRoles,
|
|
2777
|
+
roleAliases: ctx.roleAliases
|
|
3073
2778
|
});
|
|
3074
2779
|
assertRuntimeRefsWithinSurface({
|
|
3075
2780
|
entryType: entry._type === "doc.refs" ? "doc.ref" : "object",
|
|
@@ -3090,7 +2795,7 @@ function applyFieldAppend(op, ctx) {
|
|
|
3090
2795
|
}
|
|
3091
2796
|
|
|
3092
2797
|
function withRowKey(item) {
|
|
3093
|
-
return isRecord(item) && !("_key" in item) ? {
|
|
2798
|
+
return invariants.isRecord(item) && !("_key" in item) ? {
|
|
3094
2799
|
_key: randomKey(),
|
|
3095
2800
|
...item
|
|
3096
2801
|
} : item;
|
|
@@ -3117,6 +2822,13 @@ async function applyFieldUpdateWhere(op, ctx) {
|
|
|
3117
2822
|
merge: mergeRecord,
|
|
3118
2823
|
entry: entry,
|
|
3119
2824
|
op: op
|
|
2825
|
+
}), invariants.validateFieldValue({
|
|
2826
|
+
entryType: "array",
|
|
2827
|
+
entryName: entry.name,
|
|
2828
|
+
value: [ mergeRecord ],
|
|
2829
|
+
of: entry.of,
|
|
2830
|
+
memberRoles: ctx.memberRoles,
|
|
2831
|
+
roleAliases: ctx.roleAliases
|
|
3120
2832
|
});
|
|
3121
2833
|
const matches = await rowMatches({
|
|
3122
2834
|
where: op.where,
|
|
@@ -3233,18 +2945,6 @@ function subSlot(target, field) {
|
|
|
3233
2945
|
function resolveOpValue(args) {
|
|
3234
2946
|
const {src: src, ctx: ctx, target: target} = args;
|
|
3235
2947
|
switch (src.type) {
|
|
3236
|
-
case "literal":
|
|
3237
|
-
case "param":
|
|
3238
|
-
case "actor":
|
|
3239
|
-
case "now":
|
|
3240
|
-
return resolveStaticValueExpr(src, ctx);
|
|
3241
|
-
|
|
3242
|
-
case "self":
|
|
3243
|
-
return ctx.self;
|
|
3244
|
-
|
|
3245
|
-
case "stage":
|
|
3246
|
-
return ctx.stage;
|
|
3247
|
-
|
|
3248
2948
|
case "fieldRead":
|
|
3249
2949
|
{
|
|
3250
2950
|
const entry = readEntryFromMutation(ctx, src);
|
|
@@ -3274,6 +2974,25 @@ function resolveOpValue(args) {
|
|
|
3274
2974
|
}
|
|
3275
2975
|
return out;
|
|
3276
2976
|
}
|
|
2977
|
+
|
|
2978
|
+
default:
|
|
2979
|
+
return resolveAtomicOpValue(src, ctx);
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2982
|
+
|
|
2983
|
+
function resolveAtomicOpValue(src, ctx) {
|
|
2984
|
+
switch (src.type) {
|
|
2985
|
+
case "literal":
|
|
2986
|
+
case "param":
|
|
2987
|
+
case "actor":
|
|
2988
|
+
case "now":
|
|
2989
|
+
return resolveStaticValueExpr(src, ctx);
|
|
2990
|
+
|
|
2991
|
+
case "self":
|
|
2992
|
+
return ctx.self;
|
|
2993
|
+
|
|
2994
|
+
case "stage":
|
|
2995
|
+
return ctx.stage;
|
|
3277
2996
|
}
|
|
3278
2997
|
}
|
|
3279
2998
|
|
|
@@ -3724,88 +3443,429 @@ async function assertInstanceWriteAllowed(args) {
|
|
|
3724
3443
|
});
|
|
3725
3444
|
}
|
|
3726
3445
|
|
|
3727
|
-
|
|
3728
|
-
const {instance: instance, definition: definition, snapshot: snapshot, now: now} = source, base = buildParams({
|
|
3729
|
-
instance: instance,
|
|
3730
|
-
now: now,
|
|
3731
|
-
snapshot: snapshot
|
|
3732
|
-
}), fields = {
|
|
3733
|
-
...base.fields,
|
|
3734
|
-
...scopedFieldOverlay({
|
|
3735
|
-
instance: instance,
|
|
3736
|
-
snapshot: snapshot,
|
|
3737
|
-
activityName: opts?.activityName
|
|
3738
|
-
})
|
|
3739
|
-
}, params = {
|
|
3740
|
-
...base,
|
|
3741
|
-
fields: fields,
|
|
3742
|
-
actor: opts?.actor,
|
|
3743
|
-
assigned: opts?.activityName !== void 0 ? assignedFor({
|
|
3744
|
-
instance: instance,
|
|
3745
|
-
activityName: opts.activityName,
|
|
3746
|
-
actor: opts?.actor,
|
|
3747
|
-
roleAliases: definition.roleAliases
|
|
3748
|
-
}) : !1,
|
|
3749
|
-
...opts?.vars
|
|
3750
|
-
};
|
|
3751
|
-
return {
|
|
3752
|
-
...await invariants.evaluatePredicates({
|
|
3753
|
-
predicates: definition.predicates,
|
|
3754
|
-
snapshot: snapshot,
|
|
3755
|
-
params: params
|
|
3756
|
-
}),
|
|
3757
|
-
...params
|
|
3758
|
-
};
|
|
3759
|
-
}
|
|
3446
|
+
const DATA_MODEL_VERSION = 8, DATA_MODEL_MIN_READER = 4, DATA_MODEL_MAX_READER = 8, READER_MODEL_ROLLOUT_URL = "https://www.sanity.io/docs/workflows/prerelease";
|
|
3760
3447
|
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3448
|
+
class ReaderModelAcknowledgementError extends invariants.WorkflowError {
|
|
3449
|
+
code="WORKFLOW_READER_MODEL_ACKNOWLEDGEMENT_MISMATCH";
|
|
3450
|
+
expectedMinReaderModel;
|
|
3451
|
+
requiredMinReaderModel;
|
|
3452
|
+
engineMinReaderModel=DATA_MODEL_MIN_READER;
|
|
3453
|
+
engineMaxReaderModel=DATA_MODEL_MAX_READER;
|
|
3454
|
+
engineModelVersion=DATA_MODEL_VERSION;
|
|
3455
|
+
documentationUrl=READER_MODEL_ROLLOUT_URL;
|
|
3456
|
+
constructor(expectedMinReaderModel, options = {}) {
|
|
3457
|
+
const {context: context = "Deployment", requiredMinReaderModel: requiredMinReaderModel = DATA_MODEL_MIN_READER} = options, expected = expectedMinReaderModel === void 0 ? "missing" : String(expectedMinReaderModel);
|
|
3458
|
+
super("reader-model-acknowledgement", `${context} acknowledges reader model ${expected}; the submitted definitions require at least ${requiredMinReaderModel}, and this writer supports acknowledgements through ${DATA_MODEL_MAX_READER}.\nUse a reviewed numeric literal in that range. Before raising it, ensure every runtime sharing the workflow resource can read the required model.\nRollout guide: ${READER_MODEL_ROLLOUT_URL}`),
|
|
3459
|
+
this.name = "ReaderModelAcknowledgementError", this.expectedMinReaderModel = expectedMinReaderModel,
|
|
3460
|
+
this.requiredMinReaderModel = requiredMinReaderModel;
|
|
3461
|
+
}
|
|
3764
3462
|
}
|
|
3765
3463
|
|
|
3766
|
-
function
|
|
3767
|
-
|
|
3464
|
+
function assertReaderModelAcknowledgement(expectedMinReaderModel, options) {
|
|
3465
|
+
const {context: context, requiredMinReaderModel: requiredMinReaderModel} = options;
|
|
3466
|
+
if (typeof expectedMinReaderModel != "number" || !Number.isFinite(expectedMinReaderModel) || !Number.isInteger(expectedMinReaderModel) || expectedMinReaderModel < 0 || expectedMinReaderModel < requiredMinReaderModel || expectedMinReaderModel > DATA_MODEL_MAX_READER) throw new ReaderModelAcknowledgementError(expectedMinReaderModel, {
|
|
3467
|
+
requiredMinReaderModel: requiredMinReaderModel,
|
|
3468
|
+
...context !== void 0 ? {
|
|
3469
|
+
context: context
|
|
3470
|
+
} : {}
|
|
3471
|
+
});
|
|
3768
3472
|
}
|
|
3769
3473
|
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3474
|
+
const DATA_MODEL_CHANGES = Object.freeze([ Object.freeze({
|
|
3475
|
+
id: "governed-model-stamps",
|
|
3476
|
+
introducedInModel: 1,
|
|
3477
|
+
minReaderModel: 0,
|
|
3478
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
3479
|
+
compatibility: "additive",
|
|
3480
|
+
applicability: "unconditional",
|
|
3481
|
+
summary: "Definition and instance documents carry model provenance and reader-floor stamps."
|
|
3482
|
+
}), Object.freeze({
|
|
3483
|
+
id: "subject-field-kind",
|
|
3484
|
+
introducedInModel: 2,
|
|
3485
|
+
minReaderModel: 0,
|
|
3486
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
3487
|
+
compatibility: "additive",
|
|
3488
|
+
applicability: "detectable",
|
|
3489
|
+
summary: "A workflow-level subject field identifies the document a workflow is about."
|
|
3490
|
+
}), Object.freeze({
|
|
3491
|
+
id: "typed-scalar-choice-lists",
|
|
3492
|
+
introducedInModel: 2,
|
|
3493
|
+
minReaderModel: 2,
|
|
3494
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
3495
|
+
compatibility: "reader-floor",
|
|
3496
|
+
applicability: "detectable",
|
|
3497
|
+
summary: "Scalar fields may constrain writes to a persisted typed choice list."
|
|
3498
|
+
}), Object.freeze({
|
|
3499
|
+
id: "action-semantics",
|
|
3500
|
+
introducedInModel: 2,
|
|
3501
|
+
minReaderModel: 0,
|
|
3502
|
+
documentTypes: Object.freeze([ "definition" ]),
|
|
3503
|
+
compatibility: "additive",
|
|
3504
|
+
applicability: "detectable",
|
|
3505
|
+
summary: "Ordinary actions may carry advisory workflow semantics."
|
|
3506
|
+
}), Object.freeze({
|
|
3507
|
+
id: "inclusive-scalar-bounds",
|
|
3508
|
+
introducedInModel: 2,
|
|
3509
|
+
minReaderModel: 2,
|
|
3510
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
3511
|
+
compatibility: "reader-floor",
|
|
3512
|
+
applicability: "detectable",
|
|
3513
|
+
summary: "String, text, and number values may carry persisted inclusive bounds."
|
|
3514
|
+
}), Object.freeze({
|
|
3515
|
+
id: "progress-field-kind",
|
|
3516
|
+
introducedInModel: 3,
|
|
3517
|
+
minReaderModel: 0,
|
|
3518
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
3519
|
+
compatibility: "additive",
|
|
3520
|
+
applicability: "detectable",
|
|
3521
|
+
summary: "A progress field kind carries application-defined 0–100 completion."
|
|
3522
|
+
}), Object.freeze({
|
|
3523
|
+
id: "effect-claim-tokens",
|
|
3524
|
+
introducedInModel: 3,
|
|
3525
|
+
minReaderModel: 0,
|
|
3526
|
+
documentTypes: Object.freeze([ "instance" ]),
|
|
3527
|
+
compatibility: "additive",
|
|
3528
|
+
applicability: "detectable",
|
|
3529
|
+
summary: "Pending-effect claims carry an exact-claim token gating mid-dispatch state reports."
|
|
3530
|
+
}), Object.freeze({
|
|
3531
|
+
id: "classified-principal-ids",
|
|
3532
|
+
introducedInModel: 4,
|
|
3533
|
+
minReaderModel: 4,
|
|
3534
|
+
documentTypes: Object.freeze([ "instance" ]),
|
|
3535
|
+
compatibility: "reader-floor",
|
|
3536
|
+
applicability: "unconditional",
|
|
3537
|
+
summary: "Principal ids are namespace-classified: actor and assignee writes carry the account-global user id only, and readers resolve legacy project-scoped ids through the prefix classifier at the instance read funnel."
|
|
3538
|
+
}), Object.freeze({
|
|
3539
|
+
id: "readiness-requirements",
|
|
3540
|
+
introducedInModel: 4,
|
|
3541
|
+
minReaderModel: 4,
|
|
3542
|
+
documentTypes: Object.freeze([ "definition" ]),
|
|
3543
|
+
compatibility: "reader-floor",
|
|
3544
|
+
applicability: "detectable",
|
|
3545
|
+
summary: "Start and activity readiness use named polymorphic requirement arrays."
|
|
3546
|
+
}), Object.freeze({
|
|
3547
|
+
id: "due-date-field-kinds",
|
|
3548
|
+
introducedInModel: 5,
|
|
3549
|
+
minReaderModel: 0,
|
|
3550
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
3551
|
+
compatibility: "additive",
|
|
3552
|
+
applicability: "detectable",
|
|
3553
|
+
summary: "Due-date field kinds (dueDate, dueDatetime) mark a level deadline, elevated aliases of date/datetime carrying the same stored value."
|
|
3554
|
+
}), Object.freeze({
|
|
3555
|
+
id: "node-semantics",
|
|
3556
|
+
introducedInModel: 6,
|
|
3557
|
+
minReaderModel: 0,
|
|
3558
|
+
documentTypes: Object.freeze([ "definition" ]),
|
|
3559
|
+
compatibility: "additive",
|
|
3560
|
+
applicability: "detectable",
|
|
3561
|
+
summary: "Workflow, stage, activity, and action nodes may carry signal or custom advisory semantics."
|
|
3562
|
+
}), Object.freeze({
|
|
3563
|
+
id: "field-patch-ops",
|
|
3564
|
+
introducedInModel: 6,
|
|
3565
|
+
minReaderModel: 0,
|
|
3566
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
3567
|
+
compatibility: "additive",
|
|
3568
|
+
applicability: "detectable",
|
|
3569
|
+
summary: "Field ops may increment, decrement, or initialize a missing field value."
|
|
3570
|
+
}), Object.freeze({
|
|
3571
|
+
id: "attributes-condition-var",
|
|
3572
|
+
introducedInModel: 7,
|
|
3573
|
+
minReaderModel: 0,
|
|
3574
|
+
documentTypes: Object.freeze([ "definition" ]),
|
|
3575
|
+
compatibility: "additive",
|
|
3576
|
+
applicability: "unconditional",
|
|
3577
|
+
summary: "Caller-bound $attributes condition variable binds the acting token's org-level User Attributes (advisory; absent when unavailable)."
|
|
3578
|
+
}), Object.freeze({
|
|
3579
|
+
id: "role-constrained-assignment-fields",
|
|
3580
|
+
introducedInModel: 8,
|
|
3581
|
+
minReaderModel: 8,
|
|
3582
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
3583
|
+
compatibility: "reader-floor",
|
|
3584
|
+
applicability: "detectable",
|
|
3585
|
+
summary: "Assignee fields may restrict newly assigned users and collective roles by role."
|
|
3586
|
+
}) ]);
|
|
3774
3587
|
|
|
3775
|
-
function
|
|
3776
|
-
return
|
|
3588
|
+
function recordOf(value) {
|
|
3589
|
+
return value !== null && typeof value == "object" && !Array.isArray(value) ? value : void 0;
|
|
3777
3590
|
}
|
|
3778
3591
|
|
|
3779
|
-
function
|
|
3780
|
-
|
|
3592
|
+
function recordsAt(record, key) {
|
|
3593
|
+
const value = record[key];
|
|
3594
|
+
return Array.isArray(value) ? value.map(recordOf).filter(item => item !== void 0) : [];
|
|
3781
3595
|
}
|
|
3782
3596
|
|
|
3783
|
-
function
|
|
3784
|
-
|
|
3785
|
-
for (const row of rows) {
|
|
3786
|
-
const held = byName.get(row.name);
|
|
3787
|
-
(held === void 0 || row.version > held.version) && byName.set(row.name, row);
|
|
3788
|
-
}
|
|
3789
|
-
return [ ...byName.values() ];
|
|
3597
|
+
function nestedFieldEntries(entries) {
|
|
3598
|
+
return entries.flatMap(entry => [ entry, ...nestedFieldEntries(recordsAt(entry, "fields")), ...nestedFieldEntries(recordsAt(entry, "of")) ]);
|
|
3790
3599
|
}
|
|
3791
3600
|
|
|
3792
|
-
function
|
|
3793
|
-
|
|
3601
|
+
function parsedDefinitionSnapshot(root) {
|
|
3602
|
+
if (typeof root.definitionSnapshot == "string") return recordOf(parseDefinitionSnapshotValue({
|
|
3603
|
+
_id: typeof root._id == "string" ? root._id : "<unknown instance>",
|
|
3604
|
+
definitionSnapshot: root.definitionSnapshot
|
|
3605
|
+
}));
|
|
3794
3606
|
}
|
|
3795
3607
|
|
|
3796
|
-
function
|
|
3797
|
-
|
|
3608
|
+
function persistedDefinitionTree(document) {
|
|
3609
|
+
const root = recordOf(document);
|
|
3610
|
+
if (root === void 0) return;
|
|
3611
|
+
const snapshot = parsedDefinitionSnapshot(root), roots = snapshot === void 0 ? [ root ] : [ root, snapshot ], {stages: stages, activities: activities, actions: actions} = definitionDescendants(roots);
|
|
3612
|
+
return {
|
|
3613
|
+
roots: roots,
|
|
3614
|
+
stages: stages,
|
|
3615
|
+
activities: activities,
|
|
3616
|
+
actions: actions
|
|
3617
|
+
};
|
|
3798
3618
|
}
|
|
3799
3619
|
|
|
3800
|
-
function
|
|
3801
|
-
const
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3620
|
+
function persistedFieldEntries(document) {
|
|
3621
|
+
const tree = persistedDefinitionTree(document);
|
|
3622
|
+
if (tree === void 0) return [];
|
|
3623
|
+
const {roots: roots, stages: stages, activities: activities, actions: actions} = tree, effects = actions.flatMap(action => recordsAt(action, "effects"));
|
|
3624
|
+
return nestedFieldEntries([ ...roots.flatMap(candidate => recordsAt(candidate, "fields")), ...stages.flatMap(stage => recordsAt(stage, "fields")), ...activities.flatMap(activity => recordsAt(activity, "fields")), ...actions.flatMap(action => recordsAt(action, "params")), ...effects.flatMap(effect => recordsAt(effect, "outputs")) ]);
|
|
3805
3625
|
}
|
|
3806
3626
|
|
|
3807
|
-
function
|
|
3808
|
-
|
|
3627
|
+
function definitionDescendants(roots) {
|
|
3628
|
+
const stages = roots.flatMap(root => recordsAt(root, "stages")), activities = stages.flatMap(stage => recordsAt(stage, "activities")), actions = activities.flatMap(activity => recordsAt(activity, "actions"));
|
|
3629
|
+
return {
|
|
3630
|
+
stages: stages,
|
|
3631
|
+
activities: activities,
|
|
3632
|
+
actions: actions
|
|
3633
|
+
};
|
|
3634
|
+
}
|
|
3635
|
+
|
|
3636
|
+
function hasChoiceList(document) {
|
|
3637
|
+
return persistedFieldEntries(document).some(entry => {
|
|
3638
|
+
const options = recordOf(entry.options);
|
|
3639
|
+
return options !== void 0 && Array.isArray(options.list);
|
|
3640
|
+
});
|
|
3641
|
+
}
|
|
3642
|
+
|
|
3643
|
+
function entryHasKind(entry, kind) {
|
|
3644
|
+
return entryKindMatches(entry, candidate => candidate === kind);
|
|
3645
|
+
}
|
|
3646
|
+
|
|
3647
|
+
function entryKindMatches(entry, accepts) {
|
|
3648
|
+
return [ entry.type, entry._type ].some(kind => typeof kind == "string" && accepts(kind));
|
|
3649
|
+
}
|
|
3650
|
+
|
|
3651
|
+
function hasFieldKind(document, kind) {
|
|
3652
|
+
return persistedFieldEntries(document).some(entry => entryHasKind(entry, kind));
|
|
3653
|
+
}
|
|
3654
|
+
|
|
3655
|
+
function definitionNodes(document) {
|
|
3656
|
+
const root = recordOf(document);
|
|
3657
|
+
if (root !== void 0) return {
|
|
3658
|
+
root: root,
|
|
3659
|
+
...definitionDescendants([ root ])
|
|
3660
|
+
};
|
|
3661
|
+
}
|
|
3662
|
+
|
|
3663
|
+
function hasActionSemantics(document) {
|
|
3664
|
+
return definitionNodes(document)?.actions.some(hasSemantics) ?? !1;
|
|
3665
|
+
}
|
|
3666
|
+
|
|
3667
|
+
function hasNodeSemantics(document) {
|
|
3668
|
+
const nodes = definitionNodes(document);
|
|
3669
|
+
return nodes === void 0 ? !1 : [ nodes.root, ...nodes.stages, ...nodes.activities ].some(hasSemantics) ? !0 : nodes.actions.some(action => hasSemantics(action) && action.semantics.some(isNodeSemanticValue));
|
|
3670
|
+
}
|
|
3671
|
+
|
|
3672
|
+
function isNodeSemanticValue(semantic) {
|
|
3673
|
+
return typeof semantic == "string" && (semantic.startsWith("signal.") || semantic.startsWith("custom."));
|
|
3674
|
+
}
|
|
3675
|
+
|
|
3676
|
+
function hasSemantics(node) {
|
|
3677
|
+
return Array.isArray(node.semantics);
|
|
3678
|
+
}
|
|
3679
|
+
|
|
3680
|
+
function hasPersistedOpType(document, types) {
|
|
3681
|
+
const tree = persistedDefinitionTree(document);
|
|
3682
|
+
return tree === void 0 ? !1 : tree.actions.flatMap(action => recordsAt(action, "ops")).some(op => typeof op.type == "string" && types.includes(op.type)) ? !0 : tree.roots.some(root => recordsAt(root, "history").some(entry => entry._type === "opApplied" && typeof entry.opType == "string" && types.includes(entry.opType)));
|
|
3683
|
+
}
|
|
3684
|
+
|
|
3685
|
+
function hasScalarValidation(document) {
|
|
3686
|
+
return persistedFieldEntries(document).some(entry => {
|
|
3687
|
+
const validation = recordOf(entry.validation);
|
|
3688
|
+
return typeof validation?.min == "number" || typeof validation?.max == "number";
|
|
3689
|
+
});
|
|
3690
|
+
}
|
|
3691
|
+
|
|
3692
|
+
function hasClaimTokens(document) {
|
|
3693
|
+
const root = recordOf(document);
|
|
3694
|
+
return root === void 0 ? !1 : recordsAt(root, "pendingEffects").some(entry => {
|
|
3695
|
+
const claim = recordOf(entry.claim);
|
|
3696
|
+
return claim !== void 0 && typeof claim.claimToken == "string";
|
|
3697
|
+
});
|
|
3698
|
+
}
|
|
3699
|
+
|
|
3700
|
+
function hasReadinessRequirements(document) {
|
|
3701
|
+
const root = recordOf(document);
|
|
3702
|
+
return root === void 0 ? !1 : Array.isArray(recordOf(root.start)?.requirements) ? !0 : recordsAt(root, "stages").some(stage => recordsAt(stage, "activities").some(activity => Array.isArray(activity.requirements)));
|
|
3703
|
+
}
|
|
3704
|
+
|
|
3705
|
+
function hasRoleConstrainedAssignments(document) {
|
|
3706
|
+
return persistedFieldEntries(document).some(entry => entryKindMatches(entry, invariants.assignmentKindAcceptsRoles) && Array.isArray(entry.roles) && entry.roles.length > 0);
|
|
3707
|
+
}
|
|
3708
|
+
|
|
3709
|
+
const featureDetectors = {
|
|
3710
|
+
"governed-model-stamps": () => !0,
|
|
3711
|
+
"subject-field-kind": document => hasFieldKind(document, "subject"),
|
|
3712
|
+
"typed-scalar-choice-lists": hasChoiceList,
|
|
3713
|
+
"action-semantics": hasActionSemantics,
|
|
3714
|
+
"inclusive-scalar-bounds": hasScalarValidation,
|
|
3715
|
+
"progress-field-kind": document => hasFieldKind(document, "progress"),
|
|
3716
|
+
"effect-claim-tokens": hasClaimTokens,
|
|
3717
|
+
"classified-principal-ids": () => !0,
|
|
3718
|
+
"readiness-requirements": hasReadinessRequirements,
|
|
3719
|
+
"due-date-field-kinds": document => hasFieldKind(document, "dueDate") || hasFieldKind(document, "dueDatetime"),
|
|
3720
|
+
"role-constrained-assignment-fields": hasRoleConstrainedAssignments,
|
|
3721
|
+
"node-semantics": hasNodeSemantics,
|
|
3722
|
+
"field-patch-ops": document => hasPersistedOpType(document, [ "field.inc", "field.dec", "field.setIfMissing" ]),
|
|
3723
|
+
"attributes-condition-var": () => !0
|
|
3724
|
+
};
|
|
3725
|
+
|
|
3726
|
+
function requiredModelFeatures(documentType, document) {
|
|
3727
|
+
return DATA_MODEL_CHANGES.filter(change => change.documentTypes.some(candidate => candidate === documentType) && featureDetectors[change.id](document));
|
|
3728
|
+
}
|
|
3729
|
+
|
|
3730
|
+
function requiredReaderModel(documentType, document) {
|
|
3731
|
+
return Math.max(0, ...requiredModelFeatures(documentType, document).map(change => change.minReaderModel));
|
|
3732
|
+
}
|
|
3733
|
+
|
|
3734
|
+
function requiredDefinitionReaderModel(definitions) {
|
|
3735
|
+
return Math.max(DATA_MODEL_MIN_READER, ...definitions.map(definition => requiredReaderModel("definition", definition)));
|
|
3736
|
+
}
|
|
3737
|
+
|
|
3738
|
+
function modelStampFor(args) {
|
|
3739
|
+
return {
|
|
3740
|
+
modelVersion: DATA_MODEL_VERSION,
|
|
3741
|
+
minReaderModel: Math.max(DATA_MODEL_MIN_READER, args.storedMinReaderModel ?? 0, requiredReaderModel(args.documentType, args.document))
|
|
3742
|
+
};
|
|
3743
|
+
}
|
|
3744
|
+
|
|
3745
|
+
function fieldTreeShape(value) {
|
|
3746
|
+
if (Array.isArray(value)) return value.map(fieldTreeShape);
|
|
3747
|
+
if (value === null) return "null";
|
|
3748
|
+
if (typeof value == "object") {
|
|
3749
|
+
const record = value;
|
|
3750
|
+
return Object.fromEntries(Object.keys(record).toSorted().map(key => [ key, fieldTreeShape(record[key]) ]));
|
|
3751
|
+
}
|
|
3752
|
+
return typeof value;
|
|
3753
|
+
}
|
|
3754
|
+
|
|
3755
|
+
function modelVersionOf(doc) {
|
|
3756
|
+
const stamp = doc.modelVersion;
|
|
3757
|
+
return typeof stamp == "number" ? stamp : 0;
|
|
3758
|
+
}
|
|
3759
|
+
|
|
3760
|
+
function minReaderModelOf(doc) {
|
|
3761
|
+
const floor = doc.minReaderModel;
|
|
3762
|
+
return typeof floor == "number" ? floor : modelVersionOf(doc);
|
|
3763
|
+
}
|
|
3764
|
+
|
|
3765
|
+
class ModelVersionAheadError extends invariants.WorkflowError {
|
|
3766
|
+
documentId;
|
|
3767
|
+
documentModelVersion;
|
|
3768
|
+
requiredReaderModel;
|
|
3769
|
+
engineModelVersion;
|
|
3770
|
+
constructor(args) {
|
|
3771
|
+
super("model-version-ahead", `Document "${args.documentId}" was written by engine data model ${args.documentModelVersion} and requires a reader at model ${args.requiredReaderModel} or newer; this engine reads up to model ${DATA_MODEL_VERSION}. Upgrade @sanity/workflow-engine to a version that understands it.`),
|
|
3772
|
+
this.name = "ModelVersionAheadError", this.documentId = args.documentId, this.documentModelVersion = args.documentModelVersion,
|
|
3773
|
+
this.requiredReaderModel = args.requiredReaderModel, this.engineModelVersion = DATA_MODEL_VERSION;
|
|
3774
|
+
}
|
|
3775
|
+
}
|
|
3776
|
+
|
|
3777
|
+
function assertReadableModel(doc) {
|
|
3778
|
+
const documentReaderModel = minReaderModelOf(doc);
|
|
3779
|
+
if (documentReaderModel > DATA_MODEL_VERSION) throw new ModelVersionAheadError({
|
|
3780
|
+
documentId: doc._id,
|
|
3781
|
+
documentModelVersion: modelVersionOf(doc),
|
|
3782
|
+
requiredReaderModel: documentReaderModel
|
|
3783
|
+
});
|
|
3784
|
+
return doc;
|
|
3785
|
+
}
|
|
3786
|
+
|
|
3787
|
+
async function renderConditionScope(source, opts) {
|
|
3788
|
+
const {instance: instance, definition: definition, snapshot: snapshot, now: now} = source, base = buildParams({
|
|
3789
|
+
instance: instance,
|
|
3790
|
+
now: now,
|
|
3791
|
+
snapshot: snapshot
|
|
3792
|
+
}), fields = {
|
|
3793
|
+
...base.fields,
|
|
3794
|
+
...scopedFieldOverlay({
|
|
3795
|
+
instance: instance,
|
|
3796
|
+
snapshot: snapshot,
|
|
3797
|
+
activityName: opts?.activityName
|
|
3798
|
+
})
|
|
3799
|
+
}, params = {
|
|
3800
|
+
...base,
|
|
3801
|
+
fields: fields,
|
|
3802
|
+
actor: opts?.actor,
|
|
3803
|
+
assigned: opts?.activityName !== void 0 ? assignedFor({
|
|
3804
|
+
instance: instance,
|
|
3805
|
+
activityName: opts.activityName,
|
|
3806
|
+
actor: opts?.actor,
|
|
3807
|
+
roleAliases: definition.roleAliases
|
|
3808
|
+
}) : !1,
|
|
3809
|
+
...opts?.vars
|
|
3810
|
+
};
|
|
3811
|
+
return {
|
|
3812
|
+
...await invariants.evaluatePredicates({
|
|
3813
|
+
predicates: definition.predicates,
|
|
3814
|
+
snapshot: snapshot,
|
|
3815
|
+
params: params
|
|
3816
|
+
}),
|
|
3817
|
+
...params
|
|
3818
|
+
};
|
|
3819
|
+
}
|
|
3820
|
+
|
|
3821
|
+
function definitionLookupGroq(explicit) {
|
|
3822
|
+
const scoped = `_type == "${invariants.WORKFLOW_DEFINITION_TYPE}" && name == $definition && ${invariants.tagScopeFilter()}`;
|
|
3823
|
+
return explicit ? `*[${scoped} && version == $version][0]` : `*[${scoped}] | order(version desc)[0]`;
|
|
3824
|
+
}
|
|
3825
|
+
|
|
3826
|
+
function definitionsListGroq(versionOrder) {
|
|
3827
|
+
return `*[_type == "${invariants.WORKFLOW_DEFINITION_TYPE}" && ${invariants.tagScopeFilter()}] | order(name asc, version ${versionOrder})`;
|
|
3828
|
+
}
|
|
3829
|
+
|
|
3830
|
+
function latestDefinitionsGroq() {
|
|
3831
|
+
const scoped = `_type == "${invariants.WORKFLOW_DEFINITION_TYPE}" && ${invariants.tagScopeFilter()}`;
|
|
3832
|
+
return `*[${scoped} && version == math::max(*[${scoped} && name == ^.name].version)] | order(name asc)`;
|
|
3833
|
+
}
|
|
3834
|
+
|
|
3835
|
+
function deployedTagsGroq() {
|
|
3836
|
+
return `array::unique(*[_type == "${invariants.WORKFLOW_DEFINITION_TYPE}"].tag) | order(@ asc)`;
|
|
3837
|
+
}
|
|
3838
|
+
|
|
3839
|
+
function definitionTagsGroq() {
|
|
3840
|
+
return `array::unique(*[_type == "${invariants.WORKFLOW_DEFINITION_TYPE}" && name == $definition].tag) | order(@ asc)`;
|
|
3841
|
+
}
|
|
3842
|
+
|
|
3843
|
+
function latestDeployedDefinitions(rows) {
|
|
3844
|
+
const byName = /* @__PURE__ */ new Map;
|
|
3845
|
+
for (const row of rows) {
|
|
3846
|
+
const held = byName.get(row.name);
|
|
3847
|
+
(held === void 0 || row.version > held.version) && byName.set(row.name, row);
|
|
3848
|
+
}
|
|
3849
|
+
return [ ...byName.values() ];
|
|
3850
|
+
}
|
|
3851
|
+
|
|
3852
|
+
function findStageNode(args) {
|
|
3853
|
+
return args.definition?.stages.find(entry => entry.name === args.stageName);
|
|
3854
|
+
}
|
|
3855
|
+
|
|
3856
|
+
function findActivityNode(args) {
|
|
3857
|
+
return findStageNode(args)?.activities?.find(entry => entry.name === args.activityName);
|
|
3858
|
+
}
|
|
3859
|
+
|
|
3860
|
+
function liveChildrenField(instance) {
|
|
3861
|
+
const live = liveSubworkflows(instance).length;
|
|
3862
|
+
return live > 0 ? {
|
|
3863
|
+
liveChildren: live
|
|
3864
|
+
} : {};
|
|
3865
|
+
}
|
|
3866
|
+
|
|
3867
|
+
function abortReason(instance) {
|
|
3868
|
+
return instance.history.find(h => h._type === "aborted")?.reason;
|
|
3809
3869
|
}
|
|
3810
3870
|
|
|
3811
3871
|
function diagnoseInputFromEvaluation(evaluation) {
|
|
@@ -3933,60 +3993,260 @@ function diagnoseInstance(input) {
|
|
|
3933
3993
|
};
|
|
3934
3994
|
}
|
|
3935
3995
|
|
|
3936
|
-
const RUNNABLE_VERBS = /* @__PURE__ */ new Set([ "set-stage", "abort", "drain-effects", "reset-activity" ]);
|
|
3937
|
-
|
|
3938
|
-
function remediationsForCause(cause) {
|
|
3939
|
-
switch (cause.kind) {
|
|
3940
|
-
case "failed-effect":
|
|
3941
|
-
return [ {
|
|
3942
|
-
verb: "retry-effect",
|
|
3943
|
-
rationale: "Re-run the failed effect once the upstream system is healthy."
|
|
3944
|
-
}, {
|
|
3945
|
-
verb: "abort",
|
|
3946
|
-
rationale: "Abort the instance if it can no longer recover."
|
|
3947
|
-
} ];
|
|
3948
|
-
|
|
3949
|
-
case "hung-effect":
|
|
3950
|
-
return [ {
|
|
3951
|
-
verb: "drain-effects",
|
|
3952
|
-
rationale: "Re-run the effect drainer — the runtime that registered the effect handlers — to re-pick the claimed effect."
|
|
3953
|
-
}, {
|
|
3954
|
-
verb: "abort",
|
|
3955
|
-
rationale: "Abort the instance if the effect never drains."
|
|
3956
|
-
} ];
|
|
3957
|
-
|
|
3958
|
-
case "failed-activity":
|
|
3959
|
-
return [ {
|
|
3960
|
-
verb: "reset-activity",
|
|
3961
|
-
rationale: "Reset or skip the failed activity."
|
|
3962
|
-
}, {
|
|
3963
|
-
verb: "set-stage",
|
|
3964
|
-
rationale: "Move the instance past the failed activity to the intended next stage."
|
|
3965
|
-
} ];
|
|
3966
|
-
|
|
3967
|
-
case "no-transition-fires":
|
|
3968
|
-
return [ {
|
|
3969
|
-
verb: "set-stage",
|
|
3970
|
-
rationale: "Move the instance to the intended next stage to force it forward."
|
|
3971
|
-
} ];
|
|
3972
|
-
|
|
3973
|
-
case "transition-unevaluable":
|
|
3974
|
-
return [];
|
|
3975
|
-
}
|
|
3996
|
+
const RUNNABLE_VERBS = /* @__PURE__ */ new Set([ "set-stage", "abort", "drain-effects", "reset-activity" ]);
|
|
3997
|
+
|
|
3998
|
+
function remediationsForCause(cause) {
|
|
3999
|
+
switch (cause.kind) {
|
|
4000
|
+
case "failed-effect":
|
|
4001
|
+
return [ {
|
|
4002
|
+
verb: "retry-effect",
|
|
4003
|
+
rationale: "Re-run the failed effect once the upstream system is healthy."
|
|
4004
|
+
}, {
|
|
4005
|
+
verb: "abort",
|
|
4006
|
+
rationale: "Abort the instance if it can no longer recover."
|
|
4007
|
+
} ];
|
|
4008
|
+
|
|
4009
|
+
case "hung-effect":
|
|
4010
|
+
return [ {
|
|
4011
|
+
verb: "drain-effects",
|
|
4012
|
+
rationale: "Re-run the effect drainer — the runtime that registered the effect handlers — to re-pick the claimed effect."
|
|
4013
|
+
}, {
|
|
4014
|
+
verb: "abort",
|
|
4015
|
+
rationale: "Abort the instance if the effect never drains."
|
|
4016
|
+
} ];
|
|
4017
|
+
|
|
4018
|
+
case "failed-activity":
|
|
4019
|
+
return [ {
|
|
4020
|
+
verb: "reset-activity",
|
|
4021
|
+
rationale: "Reset or skip the failed activity."
|
|
4022
|
+
}, {
|
|
4023
|
+
verb: "set-stage",
|
|
4024
|
+
rationale: "Move the instance past the failed activity to the intended next stage."
|
|
4025
|
+
} ];
|
|
4026
|
+
|
|
4027
|
+
case "no-transition-fires":
|
|
4028
|
+
return [ {
|
|
4029
|
+
verb: "set-stage",
|
|
4030
|
+
rationale: "Move the instance to the intended next stage to force it forward."
|
|
4031
|
+
} ];
|
|
4032
|
+
|
|
4033
|
+
case "transition-unevaluable":
|
|
4034
|
+
return [];
|
|
4035
|
+
}
|
|
4036
|
+
}
|
|
4037
|
+
|
|
4038
|
+
function remediationsFor(diagnosis) {
|
|
4039
|
+
return diagnosis.state !== "stuck" ? [] : remediationsForCause(diagnosis.cause).map(seed => ({
|
|
4040
|
+
...seed,
|
|
4041
|
+
available: RUNNABLE_VERBS.has(seed.verb)
|
|
4042
|
+
}));
|
|
4043
|
+
}
|
|
4044
|
+
|
|
4045
|
+
function isClaimExpired(claim, now) {
|
|
4046
|
+
return claim.leaseExpiresAt === void 0 || hasPassed(claim.leaseExpiresAt, now);
|
|
4047
|
+
}
|
|
4048
|
+
|
|
4049
|
+
const EFFECT_RUN_STATUSES = [ "done", "failed", "cancelled" ];
|
|
4050
|
+
|
|
4051
|
+
function userLoginProvider(user) {
|
|
4052
|
+
return user?.provider ?? user?.loginProvider;
|
|
4053
|
+
}
|
|
4054
|
+
|
|
4055
|
+
function optionalString(value) {
|
|
4056
|
+
return value === void 0 || typeof value == "string";
|
|
4057
|
+
}
|
|
4058
|
+
|
|
4059
|
+
function isClientProjectUser(value) {
|
|
4060
|
+
return invariants.isRecord(value) && typeof value.id == "string" && optionalString(value.sanityUserId) && optionalString(value.displayName) && optionalString(value.email) && (value.imageUrl === null || optionalString(value.imageUrl)) && optionalString(value.provider) && optionalString(value.loginProvider);
|
|
4061
|
+
}
|
|
4062
|
+
|
|
4063
|
+
function objectProperty(value, property) {
|
|
4064
|
+
if (!invariants.isRecord(value)) return;
|
|
4065
|
+
const propertyValue = value[property];
|
|
4066
|
+
return typeof propertyValue == "object" && propertyValue !== null ? propertyValue : void 0;
|
|
4067
|
+
}
|
|
4068
|
+
|
|
4069
|
+
function stringProperty(value, property) {
|
|
4070
|
+
const propertyValue = Reflect.get(value, property);
|
|
4071
|
+
return typeof propertyValue == "string" ? propertyValue : void 0;
|
|
4072
|
+
}
|
|
4073
|
+
|
|
4074
|
+
function apiErrorType(error) {
|
|
4075
|
+
const response = objectProperty(error, "response"), body = objectProperty(response, "body");
|
|
4076
|
+
if (!body) return;
|
|
4077
|
+
const nestedError = objectProperty(body, "error");
|
|
4078
|
+
return (nestedError ? stringProperty(nestedError, "type") : void 0) ?? stringProperty(body, "type");
|
|
4079
|
+
}
|
|
4080
|
+
|
|
4081
|
+
function isProjectUserNotFoundError(error) {
|
|
4082
|
+
return apiErrorType(error) === "projectUserNotFoundError";
|
|
4083
|
+
}
|
|
4084
|
+
|
|
4085
|
+
const memberJoinCache = /* @__PURE__ */ new WeakMap;
|
|
4086
|
+
|
|
4087
|
+
function joinCacheFor(client) {
|
|
4088
|
+
let cache = memberJoinCache.get(client);
|
|
4089
|
+
return cache === void 0 && (cache = /* @__PURE__ */ new Map, memberJoinCache.set(client, cache)),
|
|
4090
|
+
cache;
|
|
4091
|
+
}
|
|
4092
|
+
|
|
4093
|
+
function isClientProjectMember(value) {
|
|
4094
|
+
return invariants.isRecord(value) && typeof value.id == "string";
|
|
4095
|
+
}
|
|
4096
|
+
|
|
4097
|
+
async function requestProjectMembers(request, projectId) {
|
|
4098
|
+
const project = await request({
|
|
4099
|
+
uri: `/projects/${encodeURIComponent(projectId)}`
|
|
4100
|
+
}), members = invariants.isRecord(project) ? project.members : void 0;
|
|
4101
|
+
if (!Array.isArray(members) || !members.every(isClientProjectMember)) throw new Error(`Project member directory response is invalid for project "${projectId}"`);
|
|
4102
|
+
return members;
|
|
4103
|
+
}
|
|
4104
|
+
|
|
4105
|
+
async function requestProjectUsers(args) {
|
|
4106
|
+
const {request: request, projectId: projectId, memberIds: memberIds} = args, response = await request({
|
|
4107
|
+
uri: `/projects/${encodeURIComponent(projectId)}/users/${memberIds.map(encodeURIComponent).join(",")}`
|
|
4108
|
+
}), rows = Array.isArray(response) ? response : [ response ];
|
|
4109
|
+
if (!rows.every(isClientProjectUser)) throw new Error(`Project user directory response is invalid for project "${projectId}"`);
|
|
4110
|
+
const requested = new Set(memberIds);
|
|
4111
|
+
return rows.filter(row => requested.has(row.id));
|
|
4112
|
+
}
|
|
4113
|
+
|
|
4114
|
+
async function requestProjectMemberDirectory(args) {
|
|
4115
|
+
const {request: request, projectId: projectId} = args, members = await requestProjectMembers(request, projectId), memberIds = members.map(member => member.id).filter(id => invariants.classifyPrincipalId(id).namespace === "project");
|
|
4116
|
+
if (memberIds.length === 0) return {
|
|
4117
|
+
members: members,
|
|
4118
|
+
globalUsers: []
|
|
4119
|
+
};
|
|
4120
|
+
const users = await requestProjectUsers({
|
|
4121
|
+
request: request,
|
|
4122
|
+
projectId: projectId,
|
|
4123
|
+
memberIds: memberIds
|
|
4124
|
+
});
|
|
4125
|
+
return {
|
|
4126
|
+
members: members,
|
|
4127
|
+
globalUsers: users.flatMap(user => {
|
|
4128
|
+
const globalId = invariants.directoryBridgeId(user.sanityUserId);
|
|
4129
|
+
return globalId === void 0 ? [] : [ {
|
|
4130
|
+
memberId: user.id,
|
|
4131
|
+
globalId: globalId,
|
|
4132
|
+
user: user
|
|
4133
|
+
} ];
|
|
4134
|
+
})
|
|
4135
|
+
};
|
|
4136
|
+
}
|
|
4137
|
+
|
|
4138
|
+
async function resolveGlobalProjectUser(args) {
|
|
4139
|
+
const {client: client, request: request, projectId: projectId, id: id} = args, cache = joinCacheFor(client), key = `${projectId}:${id}`, hit = cache.get(key);
|
|
4140
|
+
if (hit !== void 0) return hit === null ? {
|
|
4141
|
+
status: "missing"
|
|
4142
|
+
} : {
|
|
4143
|
+
status: "resolved",
|
|
4144
|
+
user: hit
|
|
4145
|
+
};
|
|
4146
|
+
try {
|
|
4147
|
+
await ingestMemberJoin({
|
|
4148
|
+
request: request,
|
|
4149
|
+
projectId: projectId,
|
|
4150
|
+
cache: cache
|
|
4151
|
+
});
|
|
4152
|
+
const found = cache.get(key);
|
|
4153
|
+
return found != null ? {
|
|
4154
|
+
status: "resolved",
|
|
4155
|
+
user: found
|
|
4156
|
+
} : (cache.set(key, null), {
|
|
4157
|
+
status: "missing"
|
|
4158
|
+
});
|
|
4159
|
+
} catch (cause) {
|
|
4160
|
+
return {
|
|
4161
|
+
status: "inaccessible",
|
|
4162
|
+
cause: cause
|
|
4163
|
+
};
|
|
4164
|
+
}
|
|
4165
|
+
}
|
|
4166
|
+
|
|
4167
|
+
async function ingestMemberJoin(args) {
|
|
4168
|
+
const {request: request, projectId: projectId, cache: cache} = args, snapshot = await requestProjectMemberDirectory({
|
|
4169
|
+
request: request,
|
|
4170
|
+
projectId: projectId
|
|
4171
|
+
});
|
|
4172
|
+
for (const {globalId: globalId, user: user} of snapshot.globalUsers) cache.set(`${projectId}:${globalId}`, user);
|
|
4173
|
+
}
|
|
4174
|
+
|
|
4175
|
+
function clientProjectUserDirectory(client, projectId) {
|
|
4176
|
+
return {
|
|
4177
|
+
findById: async id => {
|
|
4178
|
+
if (!client.request) return {
|
|
4179
|
+
status: "inaccessible",
|
|
4180
|
+
cause: new Error("Project-user resolution requires WorkflowClient.request")
|
|
4181
|
+
};
|
|
4182
|
+
if (invariants.classifyPrincipalId(id).namespace === "global") return resolveGlobalProjectUser({
|
|
4183
|
+
client: client,
|
|
4184
|
+
request: client.request,
|
|
4185
|
+
projectId: projectId,
|
|
4186
|
+
id: id
|
|
4187
|
+
});
|
|
4188
|
+
try {
|
|
4189
|
+
const response = await client.request({
|
|
4190
|
+
uri: `/projects/${encodeURIComponent(projectId)}/users/${encodeURIComponent(id)}`
|
|
4191
|
+
}), candidate = Array.isArray(response) ? response[0] : response;
|
|
4192
|
+
return candidate == null ? {
|
|
4193
|
+
status: "missing"
|
|
4194
|
+
} : isClientProjectUser(candidate) ? candidate.id !== id ? {
|
|
4195
|
+
status: "inaccessible",
|
|
4196
|
+
cause: new Error(`Project-user response answered id "${candidate.id}", not the requested "${id}"`)
|
|
4197
|
+
} : {
|
|
4198
|
+
status: "resolved",
|
|
4199
|
+
user: candidate
|
|
4200
|
+
} : {
|
|
4201
|
+
status: "inaccessible",
|
|
4202
|
+
cause: new Error("Project-user response had an invalid shape")
|
|
4203
|
+
};
|
|
4204
|
+
} catch (cause) {
|
|
4205
|
+
return isProjectUserNotFoundError(cause) ? {
|
|
4206
|
+
status: "missing"
|
|
4207
|
+
} : {
|
|
4208
|
+
status: "inaccessible",
|
|
4209
|
+
cause: cause
|
|
4210
|
+
};
|
|
4211
|
+
}
|
|
4212
|
+
}
|
|
4213
|
+
};
|
|
4214
|
+
}
|
|
4215
|
+
|
|
4216
|
+
function resolveClientActor(client, args) {
|
|
4217
|
+
return resolveActor(clientProjectUserDirectory(client, args.projectId), args.actor);
|
|
3976
4218
|
}
|
|
3977
4219
|
|
|
3978
|
-
function
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
}
|
|
4220
|
+
async function resolveActor(directory, actor) {
|
|
4221
|
+
if (actor.kind !== "person") return {
|
|
4222
|
+
status: "not-person",
|
|
4223
|
+
actor: actor
|
|
4224
|
+
};
|
|
4225
|
+
const personActor = {
|
|
4226
|
+
...actor,
|
|
4227
|
+
kind: "person"
|
|
4228
|
+
}, lookup = await directory.findById(personActor.id);
|
|
4229
|
+
return lookup.status === "resolved" ? {
|
|
4230
|
+
status: "resolved",
|
|
4231
|
+
actor: personActor,
|
|
4232
|
+
user: lookup.user
|
|
4233
|
+
} : lookup.status === "inaccessible" ? {
|
|
4234
|
+
status: "inaccessible",
|
|
4235
|
+
actor: personActor,
|
|
4236
|
+
...lookup.cause === void 0 ? {} : {
|
|
4237
|
+
cause: lookup.cause
|
|
4238
|
+
}
|
|
4239
|
+
} : {
|
|
4240
|
+
status: "missing",
|
|
4241
|
+
actor: personActor
|
|
4242
|
+
};
|
|
3983
4243
|
}
|
|
3984
4244
|
|
|
3985
|
-
function
|
|
3986
|
-
|
|
4245
|
+
function assertRoleConstrainedAssignmentResource(args) {
|
|
4246
|
+
if (hasRoleConstrainedAssignments(args.definition) && args.workflowResource.type !== "dataset") throw new Error(`${args.context}: definition "${args.definition.name}" uses role-constrained assignment fields, which require a dataset workflow resource; received resource type "${args.workflowResource.type}"`);
|
|
3987
4247
|
}
|
|
3988
4248
|
|
|
3989
|
-
const
|
|
4249
|
+
const EXECUTION_KINDS = {
|
|
3990
4250
|
interactive: "interactive",
|
|
3991
4251
|
server: "server",
|
|
3992
4252
|
cli: "cli",
|
|
@@ -4409,6 +4669,9 @@ function buildResolvedEntry({entry: entry, value: value, _key: _key, now: now})
|
|
|
4409
4669
|
...entry.validation !== void 0 ? {
|
|
4410
4670
|
validation: entry.validation
|
|
4411
4671
|
} : {},
|
|
4672
|
+
...entry.roles !== void 0 ? {
|
|
4673
|
+
roles: entry.roles
|
|
4674
|
+
} : {},
|
|
4412
4675
|
value: value,
|
|
4413
4676
|
...entry.initialValue?.type === "query" ? {
|
|
4414
4677
|
resolvedAt: now
|
|
@@ -4440,7 +4703,10 @@ async function resolveOneEntry({entry: entry, initialFields: initialFields, ctx:
|
|
|
4440
4703
|
fields: entry.fields,
|
|
4441
4704
|
of: entry.of,
|
|
4442
4705
|
options: entry.options,
|
|
4443
|
-
validation: entry.validation
|
|
4706
|
+
validation: entry.validation,
|
|
4707
|
+
roles: entry.roles,
|
|
4708
|
+
memberRoles: ctx.memberRoles,
|
|
4709
|
+
roleAliases: ctx.roleAliases
|
|
4444
4710
|
});
|
|
4445
4711
|
return "issues" in check ? (ctx.recordDiscard?.({
|
|
4446
4712
|
field: entry.name,
|
|
@@ -4465,7 +4731,10 @@ async function resolveOneEntry({entry: entry, initialFields: initialFields, ctx:
|
|
|
4465
4731
|
fields: entry.fields,
|
|
4466
4732
|
of: entry.of,
|
|
4467
4733
|
options: entry.options,
|
|
4468
|
-
validation: entry.validation
|
|
4734
|
+
validation: entry.validation,
|
|
4735
|
+
roles: entry.roles,
|
|
4736
|
+
memberRoles: ctx.memberRoles,
|
|
4737
|
+
roleAliases: ctx.roleAliases
|
|
4469
4738
|
});
|
|
4470
4739
|
return entry.initialValue?.type === "input" && ctx.inputProvenance !== "definition" && assertRefsWithinSurface({
|
|
4471
4740
|
entryType: entry.type,
|
|
@@ -4559,7 +4828,7 @@ function coerceToGdr(raw, workflowResource) {
|
|
|
4559
4828
|
} : null;
|
|
4560
4829
|
}
|
|
4561
4830
|
|
|
4562
|
-
const NonEmpty = invariants.NonEmptyString, UnknownRecord = v__namespace.record(v__namespace.string(), v__namespace.unknown()), PersistedChoiceOptionsSchema = v__namespace.looseObject({
|
|
4831
|
+
const NonEmpty = invariants.NonEmptyString, PersistedAssignmentRolesSchema = v__namespace.pipe(v__namespace.array(invariants.NonEmptyString), v__namespace.minLength(1, "assignment roles must not be empty")), UnknownRecord = v__namespace.record(v__namespace.string(), v__namespace.unknown()), PersistedChoiceOptionsSchema = v__namespace.looseObject({
|
|
4563
4832
|
list: v__namespace.array(v__namespace.looseObject({
|
|
4564
4833
|
title: v__namespace.string(),
|
|
4565
4834
|
value: v__namespace.union([ v__namespace.string(), v__namespace.number() ])
|
|
@@ -4574,6 +4843,7 @@ const NonEmpty = invariants.NonEmptyString, UnknownRecord = v__namespace.record(
|
|
|
4574
4843
|
description: v__namespace.optional(v__namespace.string()),
|
|
4575
4844
|
options: v__namespace.optional(PersistedChoiceOptionsSchema),
|
|
4576
4845
|
validation: v__namespace.optional(PersistedScalarValidationSchema),
|
|
4846
|
+
roles: v__namespace.optional(PersistedAssignmentRolesSchema),
|
|
4577
4847
|
fields: v__namespace.optional(v__namespace.array(PersistedFieldShapeSchema)),
|
|
4578
4848
|
of: v__namespace.optional(v__namespace.array(PersistedFieldShapeSchema))
|
|
4579
4849
|
}))), ExecutionContextSchema = invariants.tolerantObject()({
|
|
@@ -4619,7 +4889,13 @@ const OptionalRefTypes = v__namespace.exactOptional(v__namespace.array(v__namesp
|
|
|
4619
4889
|
})), v__namespace.looseObject(invariants.tolerantEntries()({
|
|
4620
4890
|
...fieldArm("subject", invariants.fieldValueSchemas.subject),
|
|
4621
4891
|
types: OptionalRefTypes
|
|
4622
|
-
})), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("release.ref", invariants.fieldValueSchemas["release.ref"]))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("string", invariants.fieldValueSchemas.string))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("text", invariants.fieldValueSchemas.text))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("number", invariants.fieldValueSchemas.number))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("progress", invariants.fieldValueSchemas.progress))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("boolean", invariants.fieldValueSchemas.boolean))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("date", invariants.fieldValueSchemas.date))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("dueDate", invariants.fieldValueSchemas.dueDate))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("datetime", invariants.fieldValueSchemas.datetime))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("dueDatetime", invariants.fieldValueSchemas.dueDatetime))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("url", invariants.fieldValueSchemas.url))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("actor", invariants.fieldValueSchemas.actor))), v__namespace.looseObject(invariants.tolerantEntries()(
|
|
4892
|
+
})), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("release.ref", invariants.fieldValueSchemas["release.ref"]))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("string", invariants.fieldValueSchemas.string))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("text", invariants.fieldValueSchemas.text))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("number", invariants.fieldValueSchemas.number))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("progress", invariants.fieldValueSchemas.progress))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("boolean", invariants.fieldValueSchemas.boolean))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("date", invariants.fieldValueSchemas.date))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("dueDate", invariants.fieldValueSchemas.dueDate))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("datetime", invariants.fieldValueSchemas.datetime))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("dueDatetime", invariants.fieldValueSchemas.dueDatetime))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("url", invariants.fieldValueSchemas.url))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("actor", invariants.fieldValueSchemas.actor))), v__namespace.looseObject(invariants.tolerantEntries()({
|
|
4893
|
+
...fieldArm("assignee", invariants.fieldValueSchemas.assignee),
|
|
4894
|
+
roles: v__namespace.exactOptional(PersistedAssignmentRolesSchema)
|
|
4895
|
+
})), v__namespace.looseObject(invariants.tolerantEntries()({
|
|
4896
|
+
...fieldArm("assignees", invariants.fieldValueSchemas.assignees),
|
|
4897
|
+
roles: v__namespace.exactOptional(PersistedAssignmentRolesSchema)
|
|
4898
|
+
})), v__namespace.looseObject(invariants.tolerantEntries()({
|
|
4623
4899
|
...fieldArm("object", v__namespace.union([ v__namespace.null(), UnknownRecord ])),
|
|
4624
4900
|
fields: v__namespace.array(PersistedFieldShapeSchema)
|
|
4625
4901
|
})), v__namespace.looseObject(invariants.tolerantEntries()({
|
|
@@ -4870,6 +5146,37 @@ function parseInstanceDocument(doc) {
|
|
|
4870
5146
|
});
|
|
4871
5147
|
}
|
|
4872
5148
|
|
|
5149
|
+
const WorkflowInstancePreviewEffectSchema = invariants.tolerantObject()({
|
|
5150
|
+
name: NonEmpty,
|
|
5151
|
+
title: v__namespace.exactOptional(v__namespace.string())
|
|
5152
|
+
}), WorkflowInstancePreviewSchema = v__namespace.looseObject(invariants.tolerantEntries()({
|
|
5153
|
+
_id: NonEmpty,
|
|
5154
|
+
_type: v__namespace.literal(WORKFLOW_INSTANCE_TYPE),
|
|
5155
|
+
modelVersion: v__namespace.exactOptional(v__namespace.number()),
|
|
5156
|
+
minReaderModel: v__namespace.exactOptional(v__namespace.number()),
|
|
5157
|
+
workflowResource: WorkflowResourceSchema,
|
|
5158
|
+
definition: NonEmpty,
|
|
5159
|
+
pinnedVersion: v__namespace.number(),
|
|
5160
|
+
fields: v__namespace.array(ResolvedFieldEntrySchema),
|
|
5161
|
+
ancestors: v__namespace.array(invariants.GdrShape),
|
|
5162
|
+
perspective: v__namespace.exactOptional(WorkflowPerspectiveSchema),
|
|
5163
|
+
currentStage: NonEmpty,
|
|
5164
|
+
stages: v__namespace.array(StageEntrySchema),
|
|
5165
|
+
claimedEffects: v__namespace.array(WorkflowInstancePreviewEffectSchema),
|
|
5166
|
+
failedEffects: v__namespace.array(WorkflowInstancePreviewEffectSchema),
|
|
5167
|
+
startedAt: invariants.IsoTimestamp,
|
|
5168
|
+
completedAt: v__namespace.exactOptional(invariants.IsoTimestamp),
|
|
5169
|
+
abortedAt: v__namespace.exactOptional(invariants.IsoTimestamp)
|
|
5170
|
+
}));
|
|
5171
|
+
|
|
5172
|
+
function parseInstancePreviewDocument(doc) {
|
|
5173
|
+
return invariants.parsePersistedDoc({
|
|
5174
|
+
schema: WorkflowInstancePreviewSchema,
|
|
5175
|
+
doc: doc,
|
|
5176
|
+
docType: WORKFLOW_INSTANCE_TYPE
|
|
5177
|
+
});
|
|
5178
|
+
}
|
|
5179
|
+
|
|
4873
5180
|
const SYNC_COMMIT = {
|
|
4874
5181
|
visibility: "sync"
|
|
4875
5182
|
}, ENGINE_API_VERSION = "2026-04-29", REQUEST_TAG = {
|
|
@@ -5317,6 +5624,40 @@ function readInstanceDoc(doc) {
|
|
|
5317
5624
|
return parseInstanceDocument(assertReadableModel(doc));
|
|
5318
5625
|
}
|
|
5319
5626
|
|
|
5627
|
+
function readInstancePreviewDoc(doc) {
|
|
5628
|
+
return hasDocumentId(doc) ? parseInstancePreviewDocument(withoutProjectedNulls(assertReadableModel(doc))) : parseInstancePreviewDocument(doc);
|
|
5629
|
+
}
|
|
5630
|
+
|
|
5631
|
+
function hasDocumentId(doc) {
|
|
5632
|
+
return typeof doc == "object" && doc !== null && typeof doc._id == "string";
|
|
5633
|
+
}
|
|
5634
|
+
|
|
5635
|
+
function withoutProjectedNulls(doc) {
|
|
5636
|
+
const row = withoutNullMembers(doc);
|
|
5637
|
+
if (typeof row != "object" || row === null) return row;
|
|
5638
|
+
const out = {
|
|
5639
|
+
...row
|
|
5640
|
+
};
|
|
5641
|
+
return Array.isArray(out.stages) && (out.stages = out.stages.map(withoutStageEntryNulls)),
|
|
5642
|
+
Array.isArray(out.claimedEffects) && (out.claimedEffects = out.claimedEffects.map(withoutNullMembers)),
|
|
5643
|
+
Array.isArray(out.failedEffects) && (out.failedEffects = out.failedEffects.map(withoutNullMembers)),
|
|
5644
|
+
out;
|
|
5645
|
+
}
|
|
5646
|
+
|
|
5647
|
+
function withoutStageEntryNulls(entry) {
|
|
5648
|
+
const stage = withoutNullMembers(entry);
|
|
5649
|
+
if (typeof stage != "object" || stage === null) return stage;
|
|
5650
|
+
const out = {
|
|
5651
|
+
...stage
|
|
5652
|
+
};
|
|
5653
|
+
return Array.isArray(out.activities) && (out.activities = out.activities.map(withoutNullMembers)),
|
|
5654
|
+
out;
|
|
5655
|
+
}
|
|
5656
|
+
|
|
5657
|
+
function withoutNullMembers(value) {
|
|
5658
|
+
return value === null || typeof value != "object" || Array.isArray(value) ? value : Object.fromEntries(Object.entries(value).filter(([, member]) => member !== null));
|
|
5659
|
+
}
|
|
5660
|
+
|
|
5320
5661
|
async function reload({client: client, instanceId: instanceId, tag: tag}) {
|
|
5321
5662
|
const doc = await getInstanceDocument(client, instanceId);
|
|
5322
5663
|
if (!doc) throw new invariants.InstanceNotFoundError({
|
|
@@ -5563,7 +5904,8 @@ function loadCallContext({client: client, instanceId: instanceId, options: optio
|
|
|
5563
5904
|
} : {},
|
|
5564
5905
|
...options.telemetry ? {
|
|
5565
5906
|
telemetry: options.telemetry
|
|
5566
|
-
} : {}
|
|
5907
|
+
} : {},
|
|
5908
|
+
memberRolesLoader: options.memberRolesLoader
|
|
5567
5909
|
}
|
|
5568
5910
|
});
|
|
5569
5911
|
}
|
|
@@ -5608,6 +5950,7 @@ async function loadContext({client: client, instanceId: instanceId, options: opt
|
|
|
5608
5950
|
...options.telemetry !== void 0 ? {
|
|
5609
5951
|
telemetry: options.telemetry
|
|
5610
5952
|
} : {},
|
|
5953
|
+
memberRolesLoader: options.memberRolesLoader,
|
|
5611
5954
|
...options.overlay !== void 0 ? {
|
|
5612
5955
|
overlay: options.overlay
|
|
5613
5956
|
} : {},
|
|
@@ -5643,7 +5986,10 @@ async function ctxEvaluateCondition({ctx: ctx, condition: condition, opts: opts}
|
|
|
5643
5986
|
}
|
|
5644
5987
|
|
|
5645
5988
|
async function buildEngineContext(args) {
|
|
5646
|
-
const {client: client, clientForGdr: clientForGdr, refSurface: refSurface, instance: instance, definition: definition} = args, clock = args.clock ?? wallClock
|
|
5989
|
+
const {client: client, clientForGdr: clientForGdr, refSurface: refSurface, instance: instance, definition: definition} = args, clock = args.clock ?? wallClock, memberRolesLoader = args.memberRolesLoader, memberRoles = await memberRolesLoader({
|
|
5990
|
+
workflowResource: instance.workflowResource,
|
|
5991
|
+
definition: definition
|
|
5992
|
+
});
|
|
5647
5993
|
return {
|
|
5648
5994
|
client: client,
|
|
5649
5995
|
clientForGdr: clientForGdr,
|
|
@@ -5660,6 +6006,10 @@ async function buildEngineContext(args) {
|
|
|
5660
6006
|
} : {},
|
|
5661
6007
|
instance: instance,
|
|
5662
6008
|
definition: definition,
|
|
6009
|
+
memberRolesLoader: memberRolesLoader,
|
|
6010
|
+
...memberRoles !== void 0 ? {
|
|
6011
|
+
memberRoles: memberRoles
|
|
6012
|
+
} : {},
|
|
5663
6013
|
snapshot: await hydrateSnapshot({
|
|
5664
6014
|
client: client,
|
|
5665
6015
|
clientForGdr: clientForGdr,
|
|
@@ -5671,6 +6021,62 @@ async function buildEngineContext(args) {
|
|
|
5671
6021
|
};
|
|
5672
6022
|
}
|
|
5673
6023
|
|
|
6024
|
+
function createAssignmentMemberRolesLoader(client) {
|
|
6025
|
+
const byProjectId = /* @__PURE__ */ new Map;
|
|
6026
|
+
return async ({workflowResource: workflowResource, definition: definition}) => {
|
|
6027
|
+
if (!hasRoleConstrainedAssignments(definition)) return;
|
|
6028
|
+
assertRoleConstrainedAssignmentResource({
|
|
6029
|
+
context: "workflow",
|
|
6030
|
+
definition: definition,
|
|
6031
|
+
workflowResource: workflowResource
|
|
6032
|
+
});
|
|
6033
|
+
const projectId = invariants.datasetResourceParts(workflowResource.id).projectId;
|
|
6034
|
+
let pending = byProjectId.get(projectId);
|
|
6035
|
+
return pending === void 0 && (pending = client.request === void 0 ? Promise.reject(new Error(`Definition "${definition.name}" has role-constrained assignments, which require project-directory access for project "${projectId}"; the client cannot issue requests`)) : loadProjectMemberRoles({
|
|
6036
|
+
request: client.request,
|
|
6037
|
+
projectId: projectId
|
|
6038
|
+
}), byProjectId.set(projectId, pending)), pending;
|
|
6039
|
+
};
|
|
6040
|
+
}
|
|
6041
|
+
|
|
6042
|
+
async function loadProjectMemberRoles(args) {
|
|
6043
|
+
const {request: request, projectId: projectId} = args, snapshot = await requestProjectMemberDirectory({
|
|
6044
|
+
request: request,
|
|
6045
|
+
projectId: projectId
|
|
6046
|
+
}), rolesByProjectId = projectMemberRoles({
|
|
6047
|
+
members: snapshot.members,
|
|
6048
|
+
projectId: projectId
|
|
6049
|
+
});
|
|
6050
|
+
return globalizeMemberRoles({
|
|
6051
|
+
snapshot: snapshot,
|
|
6052
|
+
rolesByProjectId: rolesByProjectId
|
|
6053
|
+
});
|
|
6054
|
+
}
|
|
6055
|
+
|
|
6056
|
+
function globalizeMemberRoles(args) {
|
|
6057
|
+
const {snapshot: snapshot, rolesByProjectId: rolesByProjectId} = args, humanIds = [ ...rolesByProjectId.keys() ].filter(id => invariants.classifyPrincipalId(id).namespace === "project");
|
|
6058
|
+
for (const {globalId: globalId, memberId: memberId} of snapshot.globalUsers) {
|
|
6059
|
+
const roles = rolesByProjectId.get(memberId);
|
|
6060
|
+
roles !== void 0 && rolesByProjectId.set(globalId, roles);
|
|
6061
|
+
}
|
|
6062
|
+
for (const id of humanIds) rolesByProjectId.delete(id);
|
|
6063
|
+
return Object.fromEntries(rolesByProjectId);
|
|
6064
|
+
}
|
|
6065
|
+
|
|
6066
|
+
function projectMemberRoles(args) {
|
|
6067
|
+
const result = /* @__PURE__ */ new Map;
|
|
6068
|
+
for (const member of args.members) {
|
|
6069
|
+
const {id: id, roles: roles} = member;
|
|
6070
|
+
if (!Array.isArray(roles) || !roles.every(isProjectMemberRole)) throw new Error(`Project member role directory response is invalid for project "${args.projectId}" and member "${id}"`);
|
|
6071
|
+
result.set(id, roles.map(role => role.name));
|
|
6072
|
+
}
|
|
6073
|
+
return result;
|
|
6074
|
+
}
|
|
6075
|
+
|
|
6076
|
+
function isProjectMemberRole(role) {
|
|
6077
|
+
return invariants.isRecord(role) && typeof role.name == "string";
|
|
6078
|
+
}
|
|
6079
|
+
|
|
5674
6080
|
function findStage(definition, stageName) {
|
|
5675
6081
|
const stage = definition.stages.find(s => s.name === stageName);
|
|
5676
6082
|
if (stage === void 0) throw new Error(`Stage "${stageName}" not found in definition ${definition.name}`);
|
|
@@ -5690,6 +6096,8 @@ async function resolveStageFieldEntries(args) {
|
|
|
5690
6096
|
tag: instance.tag,
|
|
5691
6097
|
stageName: stage.name,
|
|
5692
6098
|
workflowResource: instance.workflowResource,
|
|
6099
|
+
memberRoles: args.memberRoles,
|
|
6100
|
+
roleAliases: args.roleAliases,
|
|
5693
6101
|
workflowFields: instance.fields ?? [],
|
|
5694
6102
|
...instance.perspective !== void 0 ? {
|
|
5695
6103
|
perspective: instance.perspective
|
|
@@ -5716,6 +6124,8 @@ async function resolveActivityFieldEntries(args) {
|
|
|
5716
6124
|
stageName: stage.name,
|
|
5717
6125
|
workflowResource: instance.workflowResource,
|
|
5718
6126
|
activityName: activity.name,
|
|
6127
|
+
memberRoles: args.memberRoles,
|
|
6128
|
+
roleAliases: args.roleAliases,
|
|
5719
6129
|
workflowFields: instance.fields ?? [],
|
|
5720
6130
|
...instance.perspective !== void 0 ? {
|
|
5721
6131
|
perspective: instance.perspective
|
|
@@ -5799,237 +6209,76 @@ function resolveGuardRead(args) {
|
|
|
5799
6209
|
return entry === void 0 ? void 0 : deref ? resolveFieldRead({
|
|
5800
6210
|
kind: entry._type,
|
|
5801
6211
|
value: entry.value,
|
|
5802
|
-
path: fieldRead[2],
|
|
5803
|
-
snapshot: ctx.snapshot
|
|
5804
|
-
}) : fieldRead[2] !== void 0 ? getPath(entry.value, fieldRead[2]) : entry.value;
|
|
5805
|
-
}
|
|
5806
|
-
const effectsRead = invariants.EFFECTS_READ.exec(expr);
|
|
5807
|
-
if (effectsRead !== null) {
|
|
5808
|
-
const outputs = effectOutputsMap(ctx.instance)[effectsRead[1]];
|
|
5809
|
-
return effectsRead[2] !== void 0 ? getPath(outputs, effectsRead[2]) : outputs;
|
|
5810
|
-
}
|
|
5811
|
-
throw new Error(`Guard read "${expr}" is not a supported deploy-time value — use "$self", "$now", "$fields.<name>[.path]", or "$effects['<name>'][.path]" (guards store resolved values; the lake cannot see $fields or $effects)`);
|
|
5812
|
-
}
|
|
5813
|
-
|
|
5814
|
-
function resolveIdRefTarget(expr, ctx) {
|
|
5815
|
-
const value = resolveGuardRead({
|
|
5816
|
-
expr: expr,
|
|
5817
|
-
ctx: ctx,
|
|
5818
|
-
deref: !1
|
|
5819
|
-
});
|
|
5820
|
-
if (typeof value == "string" && invariants.isGdrUri(value)) return {
|
|
5821
|
-
parsed: invariants.parseGdr(value)
|
|
5822
|
-
};
|
|
5823
|
-
if (value && typeof value == "object") {
|
|
5824
|
-
const v2 = value;
|
|
5825
|
-
if (typeof v2.id == "string" && invariants.isGdrUri(v2.id)) return typeof v2.type == "string" ? {
|
|
5826
|
-
parsed: invariants.parseGdr(v2.id),
|
|
5827
|
-
type: v2.type
|
|
5828
|
-
} : {
|
|
5829
|
-
parsed: invariants.parseGdr(v2.id)
|
|
5830
|
-
};
|
|
5831
|
-
}
|
|
5832
|
-
return null;
|
|
5833
|
-
}
|
|
5834
|
-
|
|
5835
|
-
function resolveIdRefTargets(idRefs, ctx) {
|
|
5836
|
-
const targets = [];
|
|
5837
|
-
for (const expr of idRefs ?? []) {
|
|
5838
|
-
const target = resolveIdRefTarget(expr, ctx);
|
|
5839
|
-
if (target === null) return null;
|
|
5840
|
-
targets.push(target);
|
|
5841
|
-
}
|
|
5842
|
-
return targets.length === 0 ? null : targets;
|
|
5843
|
-
}
|
|
5844
|
-
|
|
5845
|
-
function assertSingleResource(targets) {
|
|
5846
|
-
const resource = invariants.resourceFromParsed(targets[0].parsed);
|
|
5847
|
-
for (const g of targets) {
|
|
5848
|
-
const r = invariants.resourceFromParsed(g.parsed);
|
|
5849
|
-
if (r.type !== resource.type || r.id !== resource.id) throw new Error(`Guard targets span multiple resources (${resource.type}:${resource.id} vs ${r.type}:${r.id}); a guard is single-resource.`);
|
|
5850
|
-
}
|
|
5851
|
-
return resource;
|
|
5852
|
-
}
|
|
5853
|
-
|
|
5854
|
-
function bareIdRefs(targets) {
|
|
5855
|
-
return targets.flatMap(g => [ g.parsed.documentId, `drafts.${g.parsed.documentId}` ]);
|
|
5856
|
-
}
|
|
5857
|
-
|
|
5858
|
-
function resolveMatchTypes(targets, authorTypes) {
|
|
5859
|
-
if (authorTypes !== void 0) return authorTypes;
|
|
5860
|
-
const inferred = [ ...new Set(targets.map(g => g.type).filter(t => !!t)) ];
|
|
5861
|
-
return inferred.length > 0 ? inferred : void 0;
|
|
5862
|
-
}
|
|
5863
|
-
|
|
5864
|
-
function resolveMetadata(metadata, ctx) {
|
|
5865
|
-
const out = {};
|
|
5866
|
-
for (const [k, expr] of Object.entries(metadata ?? {})) out[k] = resolveGuardRead({
|
|
5867
|
-
expr: expr,
|
|
5868
|
-
ctx: ctx,
|
|
5869
|
-
deref: !0
|
|
5870
|
-
});
|
|
5871
|
-
return out;
|
|
5872
|
-
}
|
|
5873
|
-
|
|
5874
|
-
function userLoginProvider(user) {
|
|
5875
|
-
return user?.provider ?? user?.loginProvider;
|
|
5876
|
-
}
|
|
5877
|
-
|
|
5878
|
-
function optionalString(value) {
|
|
5879
|
-
return value === void 0 || typeof value == "string";
|
|
5880
|
-
}
|
|
5881
|
-
|
|
5882
|
-
function isClientProjectUser(value) {
|
|
5883
|
-
return isRecord(value) && typeof value.id == "string" && optionalString(value.sanityUserId) && optionalString(value.displayName) && optionalString(value.email) && (value.imageUrl === null || optionalString(value.imageUrl)) && optionalString(value.provider) && optionalString(value.loginProvider);
|
|
5884
|
-
}
|
|
5885
|
-
|
|
5886
|
-
function objectProperty(value, property) {
|
|
5887
|
-
if (!isRecord(value)) return;
|
|
5888
|
-
const propertyValue = value[property];
|
|
5889
|
-
return typeof propertyValue == "object" && propertyValue !== null ? propertyValue : void 0;
|
|
5890
|
-
}
|
|
5891
|
-
|
|
5892
|
-
function stringProperty(value, property) {
|
|
5893
|
-
const propertyValue = Reflect.get(value, property);
|
|
5894
|
-
return typeof propertyValue == "string" ? propertyValue : void 0;
|
|
5895
|
-
}
|
|
5896
|
-
|
|
5897
|
-
function apiErrorType(error) {
|
|
5898
|
-
const response = objectProperty(error, "response"), body = objectProperty(response, "body");
|
|
5899
|
-
if (!body) return;
|
|
5900
|
-
const nestedError = objectProperty(body, "error");
|
|
5901
|
-
return (nestedError ? stringProperty(nestedError, "type") : void 0) ?? stringProperty(body, "type");
|
|
5902
|
-
}
|
|
5903
|
-
|
|
5904
|
-
function isProjectUserNotFoundError(error) {
|
|
5905
|
-
return apiErrorType(error) === "projectUserNotFoundError";
|
|
5906
|
-
}
|
|
5907
|
-
|
|
5908
|
-
const memberJoinCache = /* @__PURE__ */ new WeakMap;
|
|
5909
|
-
|
|
5910
|
-
function joinCacheFor(client) {
|
|
5911
|
-
let cache = memberJoinCache.get(client);
|
|
5912
|
-
return cache === void 0 && (cache = /* @__PURE__ */ new Map, memberJoinCache.set(client, cache)),
|
|
5913
|
-
cache;
|
|
5914
|
-
}
|
|
5915
|
-
|
|
5916
|
-
async function projectMemberIds(request, projectId) {
|
|
5917
|
-
const project = await request({
|
|
5918
|
-
uri: `/projects/${encodeURIComponent(projectId)}`
|
|
5919
|
-
}), members = isRecord(project) ? project.members : void 0;
|
|
5920
|
-
return Array.isArray(members) ? members.map(member => isRecord(member) ? member.id : void 0).filter(id => typeof id == "string") : [];
|
|
6212
|
+
path: fieldRead[2],
|
|
6213
|
+
snapshot: ctx.snapshot
|
|
6214
|
+
}) : fieldRead[2] !== void 0 ? getPath(entry.value, fieldRead[2]) : entry.value;
|
|
6215
|
+
}
|
|
6216
|
+
const effectsRead = invariants.EFFECTS_READ.exec(expr);
|
|
6217
|
+
if (effectsRead !== null) {
|
|
6218
|
+
const outputs = effectOutputsMap(ctx.instance)[effectsRead[1]];
|
|
6219
|
+
return effectsRead[2] !== void 0 ? getPath(outputs, effectsRead[2]) : outputs;
|
|
6220
|
+
}
|
|
6221
|
+
throw new Error(`Guard read "${expr}" is not a supported deploy-time value — use "$self", "$now", "$fields.<name>[.path]", or "$effects['<name>'][.path]" (guards store resolved values; the lake cannot see $fields or $effects)`);
|
|
5921
6222
|
}
|
|
5922
6223
|
|
|
5923
|
-
|
|
5924
|
-
const
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
6224
|
+
function resolveIdRefTarget(expr, ctx) {
|
|
6225
|
+
const value = resolveGuardRead({
|
|
6226
|
+
expr: expr,
|
|
6227
|
+
ctx: ctx,
|
|
6228
|
+
deref: !1
|
|
6229
|
+
});
|
|
6230
|
+
if (typeof value == "string" && invariants.isGdrUri(value)) return {
|
|
6231
|
+
parsed: invariants.parseGdr(value)
|
|
5930
6232
|
};
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
}
|
|
5937
|
-
|
|
5938
|
-
return found != null ? {
|
|
5939
|
-
status: "resolved",
|
|
5940
|
-
user: found
|
|
5941
|
-
} : (cache.set(key, null), {
|
|
5942
|
-
status: "missing"
|
|
5943
|
-
});
|
|
5944
|
-
} catch (cause) {
|
|
5945
|
-
return {
|
|
5946
|
-
status: "inaccessible",
|
|
5947
|
-
cause: cause
|
|
6233
|
+
if (value && typeof value == "object") {
|
|
6234
|
+
const v2 = value;
|
|
6235
|
+
if (typeof v2.id == "string" && invariants.isGdrUri(v2.id)) return typeof v2.type == "string" ? {
|
|
6236
|
+
parsed: invariants.parseGdr(v2.id),
|
|
6237
|
+
type: v2.type
|
|
6238
|
+
} : {
|
|
6239
|
+
parsed: invariants.parseGdr(v2.id)
|
|
5948
6240
|
};
|
|
5949
6241
|
}
|
|
6242
|
+
return null;
|
|
5950
6243
|
}
|
|
5951
6244
|
|
|
5952
|
-
|
|
5953
|
-
const
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
for (const row of Array.isArray(response) ? response : [ response ]) {
|
|
5959
|
-
if (!isClientProjectUser(row) || !requested.has(row.id)) continue;
|
|
5960
|
-
const globalId = invariants.directoryBridgeId(row.sanityUserId);
|
|
5961
|
-
globalId !== void 0 && cache.set(`${projectId}:${globalId}`, row);
|
|
6245
|
+
function resolveIdRefTargets(idRefs, ctx) {
|
|
6246
|
+
const targets = [];
|
|
6247
|
+
for (const expr of idRefs ?? []) {
|
|
6248
|
+
const target = resolveIdRefTarget(expr, ctx);
|
|
6249
|
+
if (target === null) return null;
|
|
6250
|
+
targets.push(target);
|
|
5962
6251
|
}
|
|
6252
|
+
return targets.length === 0 ? null : targets;
|
|
5963
6253
|
}
|
|
5964
6254
|
|
|
5965
|
-
function
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
if (invariants.classifyPrincipalId(id).namespace === "global") return resolveGlobalProjectUser({
|
|
5973
|
-
client: client,
|
|
5974
|
-
request: client.request,
|
|
5975
|
-
projectId: projectId,
|
|
5976
|
-
id: id
|
|
5977
|
-
});
|
|
5978
|
-
try {
|
|
5979
|
-
const response = await client.request({
|
|
5980
|
-
uri: `/projects/${encodeURIComponent(projectId)}/users/${encodeURIComponent(id)}`
|
|
5981
|
-
}), candidate = Array.isArray(response) ? response[0] : response;
|
|
5982
|
-
return candidate == null ? {
|
|
5983
|
-
status: "missing"
|
|
5984
|
-
} : isClientProjectUser(candidate) ? candidate.id !== id ? {
|
|
5985
|
-
status: "inaccessible",
|
|
5986
|
-
cause: new Error(`Project-user response answered id "${candidate.id}", not the requested "${id}"`)
|
|
5987
|
-
} : {
|
|
5988
|
-
status: "resolved",
|
|
5989
|
-
user: candidate
|
|
5990
|
-
} : {
|
|
5991
|
-
status: "inaccessible",
|
|
5992
|
-
cause: new Error("Project-user response had an invalid shape")
|
|
5993
|
-
};
|
|
5994
|
-
} catch (cause) {
|
|
5995
|
-
return isProjectUserNotFoundError(cause) ? {
|
|
5996
|
-
status: "missing"
|
|
5997
|
-
} : {
|
|
5998
|
-
status: "inaccessible",
|
|
5999
|
-
cause: cause
|
|
6000
|
-
};
|
|
6001
|
-
}
|
|
6002
|
-
}
|
|
6003
|
-
};
|
|
6255
|
+
function assertSingleResource(targets) {
|
|
6256
|
+
const resource = invariants.resourceFromParsed(targets[0].parsed);
|
|
6257
|
+
for (const g of targets) {
|
|
6258
|
+
const r = invariants.resourceFromParsed(g.parsed);
|
|
6259
|
+
if (r.type !== resource.type || r.id !== resource.id) throw new Error(`Guard targets span multiple resources (${resource.type}:${resource.id} vs ${r.type}:${r.id}); a guard is single-resource.`);
|
|
6260
|
+
}
|
|
6261
|
+
return resource;
|
|
6004
6262
|
}
|
|
6005
6263
|
|
|
6006
|
-
function
|
|
6007
|
-
return
|
|
6264
|
+
function bareIdRefs(targets) {
|
|
6265
|
+
return targets.flatMap(g => [ g.parsed.documentId, `drafts.${g.parsed.documentId}` ]);
|
|
6008
6266
|
}
|
|
6009
6267
|
|
|
6010
|
-
|
|
6011
|
-
if (
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
|
|
6016
|
-
|
|
6017
|
-
|
|
6018
|
-
|
|
6019
|
-
|
|
6020
|
-
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
status: "inaccessible",
|
|
6025
|
-
actor: personActor,
|
|
6026
|
-
...lookup.cause === void 0 ? {} : {
|
|
6027
|
-
cause: lookup.cause
|
|
6028
|
-
}
|
|
6029
|
-
} : {
|
|
6030
|
-
status: "missing",
|
|
6031
|
-
actor: personActor
|
|
6032
|
-
};
|
|
6268
|
+
function resolveMatchTypes(targets, authorTypes) {
|
|
6269
|
+
if (authorTypes !== void 0) return authorTypes;
|
|
6270
|
+
const inferred = [ ...new Set(targets.map(g => g.type).filter(t => !!t)) ];
|
|
6271
|
+
return inferred.length > 0 ? inferred : void 0;
|
|
6272
|
+
}
|
|
6273
|
+
|
|
6274
|
+
function resolveMetadata(metadata, ctx) {
|
|
6275
|
+
const out = {};
|
|
6276
|
+
for (const [k, expr] of Object.entries(metadata ?? {})) out[k] = resolveGuardRead({
|
|
6277
|
+
expr: expr,
|
|
6278
|
+
ctx: ctx,
|
|
6279
|
+
deref: !0
|
|
6280
|
+
});
|
|
6281
|
+
return out;
|
|
6033
6282
|
}
|
|
6034
6283
|
|
|
6035
6284
|
const IDENTITY_KINDS = /* @__PURE__ */ new Set([ "actor", "assignee", "assignees" ]);
|
|
@@ -6677,6 +6926,8 @@ async function buildActivityEntry({ctx: ctx, stage: stage, activity: activity, r
|
|
|
6677
6926
|
activity: activity,
|
|
6678
6927
|
now: ctx.now,
|
|
6679
6928
|
refSurface: ctx.refSurface,
|
|
6929
|
+
memberRoles: ctx.memberRoles,
|
|
6930
|
+
roleAliases: ctx.definition.roleAliases,
|
|
6680
6931
|
...recordDiscard !== void 0 ? {
|
|
6681
6932
|
recordDiscard: recordDiscard
|
|
6682
6933
|
} : {}
|
|
@@ -6879,7 +7130,8 @@ async function spawnRow({ctx: ctx, mutation: mutation, activity: activity, actio
|
|
|
6879
7130
|
context: context,
|
|
6880
7131
|
actor: actor,
|
|
6881
7132
|
now: now,
|
|
6882
|
-
refSurface: ctx.refSurface
|
|
7133
|
+
refSurface: ctx.refSurface,
|
|
7134
|
+
memberRolesLoader: ctx.memberRolesLoader
|
|
6883
7135
|
});
|
|
6884
7136
|
mutation.pendingCreates.push({
|
|
6885
7137
|
body: body,
|
|
@@ -7102,13 +7354,16 @@ async function resolveDefinitionRef({client: client, ref: ref, tag: tag}) {
|
|
|
7102
7354
|
}
|
|
7103
7355
|
|
|
7104
7356
|
async function prepareChildInstance(args) {
|
|
7105
|
-
const {client: client, parent: parent, definition: definition, initialFields: initialFields, context: context, actor: actor, now: now, refSurface: refSurface} = args, childTag = parent.tag, workflowResource = parent.workflowResource, childDocId = instanceDocId(childTag), childRef = {
|
|
7357
|
+
const {client: client, parent: parent, definition: definition, initialFields: initialFields, context: context, actor: actor, now: now, refSurface: refSurface, memberRolesLoader: memberRolesLoader} = args, childTag = parent.tag, workflowResource = parent.workflowResource, childDocId = instanceDocId(childTag), childRef = {
|
|
7106
7358
|
id: invariants.gdrFromResource(workflowResource, childDocId),
|
|
7107
7359
|
type: WORKFLOW_INSTANCE_TYPE
|
|
7108
7360
|
}, ancestors = [ ...parent.ancestors, {
|
|
7109
7361
|
id: invariants.selfGdr(parent),
|
|
7110
7362
|
type: WORKFLOW_INSTANCE_TYPE
|
|
7111
|
-
} ], inheritedPerspective = parent.perspective, fieldDiscards = [],
|
|
7363
|
+
} ], inheritedPerspective = parent.perspective, fieldDiscards = [], memberRoles = await memberRolesLoader({
|
|
7364
|
+
workflowResource: workflowResource,
|
|
7365
|
+
definition: definition
|
|
7366
|
+
}), childFields = await resolveDeclaredFields({
|
|
7112
7367
|
entryDefs: definition.fields,
|
|
7113
7368
|
initialFields: initialFields,
|
|
7114
7369
|
ctx: {
|
|
@@ -7119,6 +7374,8 @@ async function prepareChildInstance(args) {
|
|
|
7119
7374
|
workflowResource: workflowResource,
|
|
7120
7375
|
definitionName: definition.name,
|
|
7121
7376
|
refSurface: refSurface,
|
|
7377
|
+
memberRoles: memberRoles,
|
|
7378
|
+
roleAliases: definition.roleAliases,
|
|
7122
7379
|
inputProvenance: "definition",
|
|
7123
7380
|
...inheritedPerspective !== void 0 ? {
|
|
7124
7381
|
perspective: inheritedPerspective
|
|
@@ -7189,6 +7446,8 @@ async function enterStage({ctx: ctx, mutation: mutation, nextStage: nextStage, a
|
|
|
7189
7446
|
stage: nextStage,
|
|
7190
7447
|
now: at,
|
|
7191
7448
|
refSurface: ctx.refSurface,
|
|
7449
|
+
memberRoles: ctx.memberRoles,
|
|
7450
|
+
roleAliases: ctx.definition.roleAliases,
|
|
7192
7451
|
recordDiscard: recordFieldDiscards({
|
|
7193
7452
|
target: mutation.history,
|
|
7194
7453
|
scope: "stage",
|
|
@@ -7415,11 +7674,11 @@ async function advisoryCan({instance: instance, identity: identity, grants: gran
|
|
|
7415
7674
|
const DANGEROUS_ATTRIBUTE_KEYS = /* @__PURE__ */ new Set([ "__proto__", "constructor", "prototype" ]);
|
|
7416
7675
|
|
|
7417
7676
|
function attributeEntry(row) {
|
|
7418
|
-
if (!(!isRecord(row) || typeof row.key != "string" || row.key.length === 0) && !DANGEROUS_ATTRIBUTE_KEYS.has(row.key) && !(!("activeValue" in row) || row.activeValue === void 0)) return [ row.key, row.activeValue ];
|
|
7677
|
+
if (!(!invariants.isRecord(row) || typeof row.key != "string" || row.key.length === 0) && !DANGEROUS_ATTRIBUTE_KEYS.has(row.key) && !(!("activeValue" in row) || row.activeValue === void 0)) return [ row.key, row.activeValue ];
|
|
7419
7678
|
}
|
|
7420
7679
|
|
|
7421
7680
|
function normalizeUserAttributes(response) {
|
|
7422
|
-
if (!isRecord(response)) return;
|
|
7681
|
+
if (!invariants.isRecord(response)) return;
|
|
7423
7682
|
const rows = response.attributes;
|
|
7424
7683
|
if (!Array.isArray(rows)) return;
|
|
7425
7684
|
const out = {};
|
|
@@ -7743,7 +8002,7 @@ async function resolveOrganizationId(args) {
|
|
|
7743
8002
|
uri: `/projects/${encodeURIComponent(projectId)}`,
|
|
7744
8003
|
tag: REQUEST_TAG.accessResolveOrg
|
|
7745
8004
|
});
|
|
7746
|
-
if (!isRecord(project)) return;
|
|
8005
|
+
if (!invariants.isRecord(project)) return;
|
|
7747
8006
|
const orgId = project.organizationId;
|
|
7748
8007
|
return typeof orgId == "string" && orgId.length > 0 ? orgId : void 0;
|
|
7749
8008
|
} catch (err) {
|
|
@@ -7760,7 +8019,7 @@ async function resolveOrganizationId(args) {
|
|
|
7760
8019
|
const ATTRIBUTES_FETCH_LIMIT = 100, EXPECTED_ATTRIBUTES_ABSENCE = /* @__PURE__ */ new Set([ 401, 402, 403, 404 ]);
|
|
7761
8020
|
|
|
7762
8021
|
function httpStatusOf(err) {
|
|
7763
|
-
if (!isRecord(err)) return;
|
|
8022
|
+
if (!invariants.isRecord(err)) return;
|
|
7764
8023
|
const status = err.statusCode;
|
|
7765
8024
|
return typeof status == "number" ? status : void 0;
|
|
7766
8025
|
}
|
|
@@ -7775,7 +8034,7 @@ async function fetchAttributesCached(args) {
|
|
|
7775
8034
|
const response = await sibling.request({
|
|
7776
8035
|
uri: `/organizations/${encodeURIComponent(orgId)}/users/me/attributes?limit=${ATTRIBUTES_FETCH_LIMIT}`,
|
|
7777
8036
|
tag: REQUEST_TAG.accessAttributes
|
|
7778
|
-
}), envelope = isRecord(response) ? response : void 0;
|
|
8037
|
+
}), envelope = invariants.isRecord(response) ? response : void 0;
|
|
7779
8038
|
if (envelope?.hasMore === !0) {
|
|
7780
8039
|
const page = Array.isArray(envelope.attributes) ? envelope.attributes : [];
|
|
7781
8040
|
console.warn(`workflow: org attributes for organization "${orgId}" report hasMore=true (bound ${page.length} of the requested limit ${ATTRIBUTES_FETCH_LIMIT}); advisory $attributes may be incomplete — the engine fetches no further pages. Conditions that read missing keys fail closed.`);
|
|
@@ -8026,7 +8285,9 @@ async function applyActionFire({ctx: ctx, mutation: mutation, activity: activity
|
|
|
8026
8285
|
self: invariants.selfGdr(ctx.instance),
|
|
8027
8286
|
now: ctx.now,
|
|
8028
8287
|
snapshot: ctx.snapshot,
|
|
8029
|
-
refSurface: ctx.refSurface
|
|
8288
|
+
refSurface: ctx.refSurface,
|
|
8289
|
+
memberRoles: ctx.memberRoles,
|
|
8290
|
+
roleAliases: ctx.definition.roleAliases
|
|
8030
8291
|
});
|
|
8031
8292
|
if (await queueEffects({
|
|
8032
8293
|
ctx: ctx,
|
|
@@ -8209,6 +8470,8 @@ async function primeInitialStage(args) {
|
|
|
8209
8470
|
stage: stage,
|
|
8210
8471
|
now: now,
|
|
8211
8472
|
refSurface: refSurface,
|
|
8473
|
+
memberRoles: ctx.memberRoles,
|
|
8474
|
+
roleAliases: ctx.definition.roleAliases,
|
|
8212
8475
|
recordDiscard: recordFieldDiscards({
|
|
8213
8476
|
target: discards,
|
|
8214
8477
|
scope: "stage",
|
|
@@ -8268,7 +8531,7 @@ async function primeInitialStage(args) {
|
|
|
8268
8531
|
|
|
8269
8532
|
const CASCADE_LIMIT = 100;
|
|
8270
8533
|
|
|
8271
|
-
async function runCascadeHop({client: client, instanceId: instanceId, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, executionContext: executionContext, telemetry: telemetry, overlay: overlay, settlingCohorts: settlingCohorts, instance: instance}) {
|
|
8534
|
+
async function runCascadeHop({client: client, instanceId: instanceId, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock, executionContext: executionContext, telemetry: telemetry, overlay: overlay, settlingCohorts: settlingCohorts, instance: instance}) {
|
|
8272
8535
|
const contextOptions = {
|
|
8273
8536
|
clientForGdr: clientForGdr,
|
|
8274
8537
|
refSurface: refSurface,
|
|
@@ -8289,7 +8552,8 @@ async function runCascadeHop({client: client, instanceId: instanceId, actor: act
|
|
|
8289
8552
|
} : {},
|
|
8290
8553
|
...settlingCohorts ? {
|
|
8291
8554
|
settlingCohorts: settlingCohorts
|
|
8292
|
-
} : {}
|
|
8555
|
+
} : {},
|
|
8556
|
+
memberRolesLoader: memberRolesLoader
|
|
8293
8557
|
}, ctx = instance === void 0 ? await loadContext({
|
|
8294
8558
|
client: client,
|
|
8295
8559
|
instanceId: instanceId,
|
|
@@ -8328,7 +8592,7 @@ async function runCascadeHop({client: client, instanceId: instanceId, actor: act
|
|
|
8328
8592
|
});
|
|
8329
8593
|
}
|
|
8330
8594
|
|
|
8331
|
-
async function cascadeAutoTransitions({client: client, instanceId: instanceId, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, executionContext: executionContext, telemetry: telemetry, overlay: overlay, settlingCohorts: settlingCohorts}) {
|
|
8595
|
+
async function cascadeAutoTransitions({client: client, instanceId: instanceId, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock, executionContext: executionContext, telemetry: telemetry, overlay: overlay, settlingCohorts: settlingCohorts}) {
|
|
8332
8596
|
let count = 0;
|
|
8333
8597
|
for (;;) {
|
|
8334
8598
|
const drained = await drainCondemnedChildren({
|
|
@@ -8337,6 +8601,7 @@ async function cascadeAutoTransitions({client: client, instanceId: instanceId, a
|
|
|
8337
8601
|
actor: actor,
|
|
8338
8602
|
clientForGdr: clientForGdr,
|
|
8339
8603
|
refSurface: refSurface,
|
|
8604
|
+
memberRolesLoader: memberRolesLoader,
|
|
8340
8605
|
clock: clock,
|
|
8341
8606
|
executionContext: executionContext,
|
|
8342
8607
|
telemetry: telemetry
|
|
@@ -8347,6 +8612,7 @@ async function cascadeAutoTransitions({client: client, instanceId: instanceId, a
|
|
|
8347
8612
|
actor: actor,
|
|
8348
8613
|
clientForGdr: clientForGdr,
|
|
8349
8614
|
refSurface: refSurface,
|
|
8615
|
+
memberRolesLoader: memberRolesLoader,
|
|
8350
8616
|
clock: clock,
|
|
8351
8617
|
executionContext: executionContext,
|
|
8352
8618
|
telemetry: telemetry,
|
|
@@ -8363,7 +8629,7 @@ async function cascadeAutoTransitions({client: client, instanceId: instanceId, a
|
|
|
8363
8629
|
}
|
|
8364
8630
|
}
|
|
8365
8631
|
|
|
8366
|
-
async function drainCondemnedChildren({client: client, instanceId: instanceId, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, executionContext: executionContext, telemetry: telemetry, draining: draining = /* @__PURE__ */ new Set, instance: preloadedInstance}) {
|
|
8632
|
+
async function drainCondemnedChildren({client: client, instanceId: instanceId, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock, executionContext: executionContext, telemetry: telemetry, draining: draining = /* @__PURE__ */ new Set, instance: preloadedInstance}) {
|
|
8367
8633
|
if (draining.has(instanceId)) return {
|
|
8368
8634
|
instance: preloadedInstance,
|
|
8369
8635
|
drained: !1
|
|
@@ -8386,6 +8652,7 @@ async function drainCondemnedChildren({client: client, instanceId: instanceId, a
|
|
|
8386
8652
|
actor: actor,
|
|
8387
8653
|
clientForGdr: clientForGdr,
|
|
8388
8654
|
refSurface: refSurface,
|
|
8655
|
+
memberRolesLoader: memberRolesLoader,
|
|
8389
8656
|
clock: clock,
|
|
8390
8657
|
executionContext: executionContext,
|
|
8391
8658
|
telemetry: telemetry,
|
|
@@ -8403,7 +8670,7 @@ async function drainCondemnedChildren({client: client, instanceId: instanceId, a
|
|
|
8403
8670
|
};
|
|
8404
8671
|
}
|
|
8405
8672
|
|
|
8406
|
-
async function settleCondemnedRow({client: client, ownerId: ownerId, row: row, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, executionContext: executionContext, telemetry: telemetry, draining: draining}) {
|
|
8673
|
+
async function settleCondemnedRow({client: client, ownerId: ownerId, row: row, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock, executionContext: executionContext, telemetry: telemetry, draining: draining}) {
|
|
8407
8674
|
const childId = invariants.toBareId(row.ref.id);
|
|
8408
8675
|
try {
|
|
8409
8676
|
const result = await abortInstance({
|
|
@@ -8416,6 +8683,7 @@ async function settleCondemnedRow({client: client, ownerId: ownerId, row: row, a
|
|
|
8416
8683
|
} : {},
|
|
8417
8684
|
clientForGdr: clientForGdr,
|
|
8418
8685
|
refSurface: refSurface,
|
|
8686
|
+
memberRolesLoader: memberRolesLoader,
|
|
8419
8687
|
...clock ? {
|
|
8420
8688
|
clock: clock
|
|
8421
8689
|
} : {},
|
|
@@ -8433,6 +8701,7 @@ async function settleCondemnedRow({client: client, ownerId: ownerId, row: row, a
|
|
|
8433
8701
|
actor: actor,
|
|
8434
8702
|
clientForGdr: clientForGdr,
|
|
8435
8703
|
refSurface: refSurface,
|
|
8704
|
+
memberRolesLoader: memberRolesLoader,
|
|
8436
8705
|
clock: clock,
|
|
8437
8706
|
executionContext: executionContext,
|
|
8438
8707
|
telemetry: telemetry,
|
|
@@ -8583,7 +8852,8 @@ async function buildCascadeStepContext(args, instance) {
|
|
|
8583
8852
|
} : {},
|
|
8584
8853
|
...args.settlingCohorts ? {
|
|
8585
8854
|
settlingCohorts: args.settlingCohorts
|
|
8586
|
-
} : {}
|
|
8855
|
+
} : {},
|
|
8856
|
+
memberRolesLoader: args.memberRolesLoader
|
|
8587
8857
|
});
|
|
8588
8858
|
}
|
|
8589
8859
|
|
|
@@ -8811,6 +9081,7 @@ function spawnStepArgs(ctx, args) {
|
|
|
8811
9081
|
actor: args.actor,
|
|
8812
9082
|
clientForGdr: ctx.clientForGdr,
|
|
8813
9083
|
refSurface: ctx.refSurface,
|
|
9084
|
+
memberRolesLoader: ctx.memberRolesLoader,
|
|
8814
9085
|
clock: ctx.clock,
|
|
8815
9086
|
executionContext: ctx.executionContext,
|
|
8816
9087
|
telemetry: ctx.telemetry,
|
|
@@ -8952,7 +9223,11 @@ function validateEffectOutputs(args) {
|
|
|
8952
9223
|
issues.push(`"${key}" is not a declared output`);
|
|
8953
9224
|
continue;
|
|
8954
9225
|
}
|
|
8955
|
-
const check = effectOutputCheck(
|
|
9226
|
+
const check = effectOutputCheck({
|
|
9227
|
+
shape: shape,
|
|
9228
|
+
value: value,
|
|
9229
|
+
eligibility: args
|
|
9230
|
+
});
|
|
8956
9231
|
"issues" in check ? issues.push(...check.issues.map(i => `"${key}": ${i}`)) : normalized[key] = check.output;
|
|
8957
9232
|
}
|
|
8958
9233
|
if (issues.length > 0) throw new EffectOutputsInvalidError({
|
|
@@ -8962,7 +9237,8 @@ function validateEffectOutputs(args) {
|
|
|
8962
9237
|
return normalized;
|
|
8963
9238
|
}
|
|
8964
9239
|
|
|
8965
|
-
function effectOutputCheck(
|
|
9240
|
+
function effectOutputCheck(args) {
|
|
9241
|
+
const {shape: shape, value: value, eligibility: eligibility} = args;
|
|
8966
9242
|
return invariants.parseFieldValue({
|
|
8967
9243
|
entryType: shape.type,
|
|
8968
9244
|
value: value,
|
|
@@ -8977,7 +9253,12 @@ function effectOutputCheck(shape, value) {
|
|
|
8977
9253
|
} : {},
|
|
8978
9254
|
...shape.validation !== void 0 ? {
|
|
8979
9255
|
validation: shape.validation
|
|
8980
|
-
} : {}
|
|
9256
|
+
} : {},
|
|
9257
|
+
...shape.roles !== void 0 ? {
|
|
9258
|
+
roles: shape.roles
|
|
9259
|
+
} : {},
|
|
9260
|
+
memberRoles: eligibility.memberRoles,
|
|
9261
|
+
roleAliases: eligibility.roleAliases
|
|
8981
9262
|
});
|
|
8982
9263
|
}
|
|
8983
9264
|
|
|
@@ -9000,7 +9281,7 @@ function requirePendingEffect(instance, effectKey) {
|
|
|
9000
9281
|
});
|
|
9001
9282
|
}
|
|
9002
9283
|
|
|
9003
|
-
function validateCompletionInput({pending: pending, definition: definition, status: status, ops: ops, outputs: outputs}) {
|
|
9284
|
+
function validateCompletionInput({pending: pending, definition: definition, status: status, ops: ops, outputs: outputs, memberRoles: memberRoles, roleAliases: roleAliases}) {
|
|
9004
9285
|
if (status === "failed" && ops !== void 0 && ops.length > 0) throw new EffectOpsInvalidError({
|
|
9005
9286
|
effect: pending.name,
|
|
9006
9287
|
issues: [ "ops cannot accompany a failed completion — field.set the outcome on a done completion instead" ]
|
|
@@ -9012,7 +9293,9 @@ function validateCompletionInput({pending: pending, definition: definition, stat
|
|
|
9012
9293
|
const normalizedOutputs = outputs !== void 0 ? validateEffectOutputs({
|
|
9013
9294
|
outputs: outputs,
|
|
9014
9295
|
declared: findEffect(definition, pending.name)?.outputs ?? [],
|
|
9015
|
-
effectName: pending.name
|
|
9296
|
+
effectName: pending.name,
|
|
9297
|
+
memberRoles: memberRoles,
|
|
9298
|
+
roleAliases: roleAliases
|
|
9016
9299
|
}) : void 0;
|
|
9017
9300
|
return {
|
|
9018
9301
|
ops: ops !== void 0 ? validateEffectOps(ops, pending.name) : [],
|
|
@@ -9031,7 +9314,9 @@ async function commitCompleteEffect({ctx: ctx, effectKey: effectKey, status: sta
|
|
|
9031
9314
|
definition: ctx.definition,
|
|
9032
9315
|
status: status,
|
|
9033
9316
|
ops: ops,
|
|
9034
|
-
outputs: outputs
|
|
9317
|
+
outputs: outputs,
|
|
9318
|
+
memberRoles: ctx.memberRoles,
|
|
9319
|
+
roleAliases: ctx.definition.roleAliases
|
|
9035
9320
|
}), mutation = startMutation(ctx.instance);
|
|
9036
9321
|
recordProcessedRequest({
|
|
9037
9322
|
mutation: mutation,
|
|
@@ -9062,7 +9347,9 @@ async function commitCompleteEffect({ctx: ctx, effectKey: effectKey, status: sta
|
|
|
9062
9347
|
self: invariants.selfGdr(ctx.instance),
|
|
9063
9348
|
now: ranAt,
|
|
9064
9349
|
snapshot: ctx.snapshot,
|
|
9065
|
-
refSurface: ctx.refSurface
|
|
9350
|
+
refSurface: ctx.refSurface,
|
|
9351
|
+
memberRoles: ctx.memberRoles,
|
|
9352
|
+
roleAliases: ctx.definition.roleAliases
|
|
9066
9353
|
}), needsGuardRefresh = wroteEffectOutputs || ranOps.some(isFieldOp);
|
|
9067
9354
|
return await persistThenMaybeRefresh({
|
|
9068
9355
|
ctx: ctx,
|
|
@@ -9231,7 +9518,9 @@ async function commitReport({ctx: ctx, effectKey: effectKey, claimToken: claimTo
|
|
|
9231
9518
|
self: invariants.selfGdr(ctx.instance),
|
|
9232
9519
|
now: ctx.now,
|
|
9233
9520
|
snapshot: ctx.snapshot,
|
|
9234
|
-
refSurface: ctx.refSurface
|
|
9521
|
+
refSurface: ctx.refSurface,
|
|
9522
|
+
memberRoles: ctx.memberRoles,
|
|
9523
|
+
roleAliases: ctx.definition.roleAliases
|
|
9235
9524
|
}), await persistThenMaybeRefresh({
|
|
9236
9525
|
ctx: ctx,
|
|
9237
9526
|
mutation: mutation,
|
|
@@ -9726,6 +10015,12 @@ async function evaluateEditableFields(args) {
|
|
|
9726
10015
|
...site.validation !== void 0 ? {
|
|
9727
10016
|
validation: site.validation
|
|
9728
10017
|
} : {},
|
|
10018
|
+
...site.roles !== void 0 ? {
|
|
10019
|
+
roles: site.roles,
|
|
10020
|
+
...definition.roleAliases !== void 0 ? {
|
|
10021
|
+
roleAliases: definition.roleAliases
|
|
10022
|
+
} : {}
|
|
10023
|
+
} : {},
|
|
9729
10024
|
value: value,
|
|
9730
10025
|
editable: reason === void 0,
|
|
9731
10026
|
...reason !== void 0 ? {
|
|
@@ -10076,23 +10371,63 @@ function idsArm(filter, params) {
|
|
|
10076
10371
|
}
|
|
10077
10372
|
}
|
|
10078
10373
|
|
|
10079
|
-
function
|
|
10080
|
-
const
|
|
10081
|
-
if (
|
|
10082
|
-
|
|
10083
|
-
|
|
10084
|
-
|
|
10374
|
+
function beforeArm(filter, params) {
|
|
10375
|
+
const before = filter.before;
|
|
10376
|
+
if (before !== void 0) {
|
|
10377
|
+
if (filter.limit === void 0) throw new invariants.ContractViolationError("instancesQuery: `before` requires `limit` — a cursor pages the newest-first sliced read");
|
|
10378
|
+
if (before.id === "" || before.startedAt === "") throw new invariants.ContractViolationError(`instancesQuery: \`before\` needs a non-empty id and startedAt; got ${JSON.stringify(before)}`);
|
|
10379
|
+
return params.beforeStartedAt = before.startedAt, params.beforeId = before.id, "(startedAt < $beforeStartedAt || (startedAt == $beforeStartedAt && _id > $beforeId))";
|
|
10380
|
+
}
|
|
10381
|
+
}
|
|
10382
|
+
|
|
10383
|
+
function compiledConditions(filter, params) {
|
|
10384
|
+
if (filter.limit !== void 0 && (!Number.isInteger(filter.limit) || filter.limit <= 0)) throw new invariants.ContractViolationError(`instancesQuery: limit must be a positive integer; got ${JSON.stringify(filter.limit)}`);
|
|
10385
|
+
const conditions = [ `_type == "${WORKFLOW_INSTANCE_TYPE}"`, invariants.tagScopeFilter() ];
|
|
10085
10386
|
filter.includeCompleted !== !0 && conditions.push(inFlightFilter()), filter.definition !== void 0 && (conditions.push("definition == $definition"),
|
|
10086
10387
|
params.definition = filter.definition), filter.stage !== void 0 && (conditions.push("currentStage == $stage"),
|
|
10087
10388
|
params.stage = filter.stage);
|
|
10389
|
+
const cursor = beforeArm(filter, params);
|
|
10390
|
+
cursor !== void 0 && conditions.push(cursor);
|
|
10088
10391
|
const arms = [ documentArm(filter, params), idsArm(filter, params) ].filter(arm => arm !== void 0);
|
|
10089
|
-
arms.length > 0 && conditions.push(`(${arms.join(" || ")})`);
|
|
10090
|
-
|
|
10091
|
-
|
|
10092
|
-
|
|
10392
|
+
return arms.length > 0 && conditions.push(`(${arms.join(" || ")})`), conditions;
|
|
10393
|
+
}
|
|
10394
|
+
|
|
10395
|
+
function orderedSlice(filter) {
|
|
10396
|
+
return filter.limit !== void 0 ? ` | order(startedAt desc, _id asc) [0...${filter.limit}]` : " | order(startedAt asc, _id asc)";
|
|
10397
|
+
}
|
|
10398
|
+
|
|
10399
|
+
function instancesQuery(args) {
|
|
10400
|
+
const {tag: tag, filter: filter = {}} = args;
|
|
10401
|
+
invariants.validateTag(tag);
|
|
10402
|
+
const params = {
|
|
10403
|
+
tag: tag
|
|
10404
|
+
};
|
|
10405
|
+
return {
|
|
10406
|
+
query: `*[${compiledConditions(filter, params).join(" && ")}]${orderedSlice(filter)}`,
|
|
10093
10407
|
params: params
|
|
10094
|
-
}
|
|
10095
|
-
|
|
10408
|
+
};
|
|
10409
|
+
}
|
|
10410
|
+
|
|
10411
|
+
function instanceChangesQuery(args) {
|
|
10412
|
+
return invariants.validateTag(args.tag), {
|
|
10413
|
+
query: `*[_type == "${WORKFLOW_INSTANCE_TYPE}" && ${invariants.tagScopeFilter()}]`,
|
|
10414
|
+
params: {
|
|
10415
|
+
tag: args.tag
|
|
10416
|
+
}
|
|
10417
|
+
};
|
|
10418
|
+
}
|
|
10419
|
+
|
|
10420
|
+
const PREVIEW_FIELD_TYPES = [ "actor", "assignee", "assignees", "date", "datetime", "doc.ref", "doc.refs", "dueDate", "dueDatetime", "release.ref", "subject" ], PREVIEW_PROJECTION = `{\n _id, _type, modelVersion, minReaderModel, workflowResource, definition, pinnedVersion,\n currentStage, startedAt, completedAt, abortedAt, perspective, ancestors,\n "fields": fields[_type in $previewFieldTypes],\n "stages": stages[!defined(exitedAt) && name == ^.currentStage]{\n _key, name, enteredAt,\n "fields": fields[_type in $previewFieldTypes],\n "activities": activities[]{\n _key, name, status, completedBy,\n "fields": fields[_type in $previewFieldTypes]\n }\n },\n "claimedEffects": pendingEffects[defined(claim)]{name, title},\n "failedEffects": effectHistory[status == "failed"]{name, title}\n}`.replaceAll(/\s+/g, " ").trim();
|
|
10421
|
+
|
|
10422
|
+
function instancePreviewsQuery(args) {
|
|
10423
|
+
const {tag: tag, filter: filter = {}} = args;
|
|
10424
|
+
invariants.validateTag(tag);
|
|
10425
|
+
const params = {
|
|
10426
|
+
tag: tag,
|
|
10427
|
+
previewFieldTypes: PREVIEW_FIELD_TYPES
|
|
10428
|
+
};
|
|
10429
|
+
return {
|
|
10430
|
+
query: `*[${compiledConditions(filter, params).join(" && ")}]${orderedSlice(filter)} ${PREVIEW_PROJECTION}`,
|
|
10096
10431
|
params: params
|
|
10097
10432
|
};
|
|
10098
10433
|
}
|
|
@@ -10277,6 +10612,11 @@ function hashDefinitionContent(def) {
|
|
|
10277
10612
|
}
|
|
10278
10613
|
|
|
10279
10614
|
function planDefinitionDeploy({def: def, latest: latest, target: target}) {
|
|
10615
|
+
assertRoleConstrainedAssignmentResource({
|
|
10616
|
+
context: "workflow.deployDefinitions",
|
|
10617
|
+
definition: def,
|
|
10618
|
+
workflowResource: target.workflowResource
|
|
10619
|
+
});
|
|
10280
10620
|
const expanded = expandResourceAliases(def, target.resourceAliases), contentHash = hashDefinitionContent(expanded), unchanged = latest !== void 0 && latest.contentHash === contentHash, version = unchanged ? latest.version : (latest?.version ?? 0) + 1, docId = invariants.definitionDocId({
|
|
10281
10621
|
tag: target.tag,
|
|
10282
10622
|
definition: expanded.name,
|
|
@@ -10469,7 +10809,9 @@ async function commitEdit({ctx: ctx, target: target, mode: mode, value: value, r
|
|
|
10469
10809
|
self: invariants.selfGdr(ctx.instance),
|
|
10470
10810
|
now: ctx.now,
|
|
10471
10811
|
snapshot: ctx.snapshot,
|
|
10472
|
-
refSurface: ctx.refSurface
|
|
10812
|
+
refSurface: ctx.refSurface,
|
|
10813
|
+
memberRoles: ctx.memberRoles,
|
|
10814
|
+
roleAliases: ctx.definition.roleAliases
|
|
10473
10815
|
});
|
|
10474
10816
|
return await persistThenMaybeRefresh({
|
|
10475
10817
|
ctx: ctx,
|
|
@@ -10568,6 +10910,7 @@ async function resolveOperationContext(args) {
|
|
|
10568
10910
|
return {
|
|
10569
10911
|
access: access,
|
|
10570
10912
|
actor: access.actor,
|
|
10913
|
+
memberRolesLoader: createAssignmentMemberRolesLoader(args.client),
|
|
10571
10914
|
clientForGdr: buildClientForGdr({
|
|
10572
10915
|
client: args.client,
|
|
10573
10916
|
workflowResource: args.workflowResource,
|
|
@@ -10600,6 +10943,7 @@ async function runCommitVerb(params) {
|
|
|
10600
10943
|
actor: context.actor,
|
|
10601
10944
|
clientForGdr: context.clientForGdr,
|
|
10602
10945
|
refSurface: context.refSurface,
|
|
10946
|
+
memberRolesLoader: context.memberRolesLoader,
|
|
10603
10947
|
clock: clock,
|
|
10604
10948
|
executionContext: args.executionContext,
|
|
10605
10949
|
telemetry: args.telemetry,
|
|
@@ -10624,7 +10968,7 @@ function requestRecordFor(args) {
|
|
|
10624
10968
|
}
|
|
10625
10969
|
|
|
10626
10970
|
async function runDeduped(args) {
|
|
10627
|
-
const {client: client, tag: tag, instanceId: instanceId, record: record, before: before, now: now, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, run: run} = args, {clock: clock, executionContext: executionContext, telemetry: telemetry} = args, replay = async () => {
|
|
10971
|
+
const {client: client, tag: tag, instanceId: instanceId, record: record, before: before, now: now, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, run: run} = args, {clock: clock, executionContext: executionContext, telemetry: telemetry} = args, replay = async () => {
|
|
10628
10972
|
const pre = await reload({
|
|
10629
10973
|
client: client,
|
|
10630
10974
|
instanceId: instanceId,
|
|
@@ -10636,6 +10980,7 @@ async function runDeduped(args) {
|
|
|
10636
10980
|
actor: actor,
|
|
10637
10981
|
clientForGdr: clientForGdr,
|
|
10638
10982
|
refSurface: refSurface,
|
|
10983
|
+
memberRolesLoader: memberRolesLoader,
|
|
10639
10984
|
clock: clock,
|
|
10640
10985
|
executionContext: executionContext,
|
|
10641
10986
|
telemetry: telemetry
|
|
@@ -10659,13 +11004,14 @@ async function runDeduped(args) {
|
|
|
10659
11004
|
}
|
|
10660
11005
|
}
|
|
10661
11006
|
|
|
10662
|
-
async function cascade({client: client, instanceId: instanceId, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, executionContext: executionContext, telemetry: telemetry, overlay: overlay}) {
|
|
11007
|
+
async function cascade({client: client, instanceId: instanceId, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock, executionContext: executionContext, telemetry: telemetry, overlay: overlay}) {
|
|
10663
11008
|
const count = await cascadeAutoTransitions({
|
|
10664
11009
|
client: client,
|
|
10665
11010
|
instanceId: instanceId,
|
|
10666
11011
|
actor: actor,
|
|
10667
11012
|
clientForGdr: clientForGdr,
|
|
10668
11013
|
refSurface: refSurface,
|
|
11014
|
+
memberRolesLoader: memberRolesLoader,
|
|
10669
11015
|
...clock !== void 0 ? {
|
|
10670
11016
|
clock: clock
|
|
10671
11017
|
} : {},
|
|
@@ -10685,6 +11031,7 @@ async function cascade({client: client, instanceId: instanceId, actor: actor, cl
|
|
|
10685
11031
|
actor: actor,
|
|
10686
11032
|
clientForGdr: clientForGdr,
|
|
10687
11033
|
refSurface: refSurface,
|
|
11034
|
+
memberRolesLoader: memberRolesLoader,
|
|
10688
11035
|
...clock !== void 0 ? {
|
|
10689
11036
|
clock: clock
|
|
10690
11037
|
} : {},
|
|
@@ -10698,7 +11045,7 @@ async function cascade({client: client, instanceId: instanceId, actor: actor, cl
|
|
|
10698
11045
|
}
|
|
10699
11046
|
|
|
10700
11047
|
async function cascadeAndReload(args) {
|
|
10701
|
-
const {client: client, tag: tag, instanceId: instanceId, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock} = args;
|
|
11048
|
+
const {client: client, tag: tag, instanceId: instanceId, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock} = args;
|
|
10702
11049
|
return {
|
|
10703
11050
|
cascaded: await cascade({
|
|
10704
11051
|
client: client,
|
|
@@ -10706,6 +11053,7 @@ async function cascadeAndReload(args) {
|
|
|
10706
11053
|
actor: actor,
|
|
10707
11054
|
clientForGdr: clientForGdr,
|
|
10708
11055
|
refSurface: refSurface,
|
|
11056
|
+
memberRolesLoader: memberRolesLoader,
|
|
10709
11057
|
clock: clock,
|
|
10710
11058
|
...args.executionContext !== void 0 ? {
|
|
10711
11059
|
executionContext: args.executionContext
|
|
@@ -10729,6 +11077,7 @@ async function settleStart(args) {
|
|
|
10729
11077
|
actor: args.actor,
|
|
10730
11078
|
clientForGdr: args.clientForGdr,
|
|
10731
11079
|
refSurface: args.refSurface,
|
|
11080
|
+
memberRolesLoader: args.memberRolesLoader,
|
|
10732
11081
|
clock: args.clock,
|
|
10733
11082
|
...args.executionContext !== void 0 ? {
|
|
10734
11083
|
executionContext: args.executionContext
|
|
@@ -10771,31 +11120,20 @@ function resumeMismatch(args) {
|
|
|
10771
11120
|
}
|
|
10772
11121
|
|
|
10773
11122
|
async function resumeStart(args) {
|
|
10774
|
-
const {existing: existing} = args, mismatch = resumeMismatch({
|
|
11123
|
+
const {existing: existing, definition: definition, version: version, initialFieldCount: initialFieldCount, ...settlementArgs} = args, mismatch = resumeMismatch({
|
|
10775
11124
|
existing: existing,
|
|
10776
|
-
definition:
|
|
10777
|
-
version:
|
|
11125
|
+
definition: definition,
|
|
11126
|
+
version: version
|
|
10778
11127
|
});
|
|
10779
11128
|
if (mismatch !== void 0) throw new invariants.ContractViolationError(`startInstance: instanceId "${existing._id}" already exists and ${mismatch}. A supplied instanceId is start's idempotency key — reuse one only to retry the same start.`);
|
|
10780
11129
|
if (existing.stages.length === 0 && terminalState(existing) !== "in-flight") throw new invariants.ContractViolationError(`startInstance: instanceId "${existing._id}" belongs to a start that was discarded (aborted before it finished starting) — mint a new id to start again.`);
|
|
10781
11130
|
const completesStart = isUnprimed(existing), emitStarted = () => resolveTelemetry(args.telemetry).log(WorkflowInstanceStarted, instanceStartedDataFor({
|
|
10782
11131
|
instance: existing,
|
|
10783
|
-
initialFieldCount:
|
|
11132
|
+
initialFieldCount: initialFieldCount,
|
|
10784
11133
|
viaSpawn: !1
|
|
10785
11134
|
})), cascaded = await settleStart({
|
|
10786
|
-
|
|
10787
|
-
tag: args.tag,
|
|
11135
|
+
...settlementArgs,
|
|
10788
11136
|
instanceId: existing._id,
|
|
10789
|
-
actor: args.actor,
|
|
10790
|
-
clientForGdr: args.clientForGdr,
|
|
10791
|
-
refSurface: args.refSurface,
|
|
10792
|
-
clock: args.clock,
|
|
10793
|
-
...args.executionContext !== void 0 ? {
|
|
10794
|
-
executionContext: args.executionContext
|
|
10795
|
-
} : {},
|
|
10796
|
-
...args.telemetry !== void 0 ? {
|
|
10797
|
-
telemetry: args.telemetry
|
|
10798
|
-
} : {},
|
|
10799
11137
|
...completesStart ? {
|
|
10800
11138
|
emitStarted: emitStarted
|
|
10801
11139
|
} : {}
|
|
@@ -10811,7 +11149,7 @@ async function resumeStart(args) {
|
|
|
10811
11149
|
};
|
|
10812
11150
|
}
|
|
10813
11151
|
|
|
10814
|
-
function engineOptionsForActor({actor: actor, clock: clock, clientForGdr: clientForGdr, refSurface: refSurface, executionContext: executionContext, telemetry: telemetry}) {
|
|
11152
|
+
function engineOptionsForActor({actor: actor, clock: clock, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, executionContext: executionContext, telemetry: telemetry}) {
|
|
10815
11153
|
return {
|
|
10816
11154
|
...actor !== void 0 ? {
|
|
10817
11155
|
actor: actor
|
|
@@ -10819,6 +11157,7 @@ function engineOptionsForActor({actor: actor, clock: clock, clientForGdr: client
|
|
|
10819
11157
|
clock: clock,
|
|
10820
11158
|
clientForGdr: clientForGdr,
|
|
10821
11159
|
refSurface: refSurface,
|
|
11160
|
+
memberRolesLoader: memberRolesLoader,
|
|
10822
11161
|
...executionContext !== void 0 ? {
|
|
10823
11162
|
executionContext: executionContext
|
|
10824
11163
|
} : {},
|
|
@@ -10829,7 +11168,7 @@ function engineOptionsForActor({actor: actor, clock: clock, clientForGdr: client
|
|
|
10829
11168
|
}
|
|
10830
11169
|
|
|
10831
11170
|
async function abortAndPropagate(args) {
|
|
10832
|
-
const {client: client, instanceId: instanceId, reason: reason, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, executionContext: executionContext, telemetry: telemetry, requestRecord: requestRecord} = args, result = await abortInstance({
|
|
11171
|
+
const {client: client, instanceId: instanceId, reason: reason, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock, executionContext: executionContext, telemetry: telemetry, requestRecord: requestRecord} = args, result = await abortInstance({
|
|
10833
11172
|
client: client,
|
|
10834
11173
|
instanceId: instanceId,
|
|
10835
11174
|
...reason !== void 0 ? {
|
|
@@ -10843,6 +11182,7 @@ async function abortAndPropagate(args) {
|
|
|
10843
11182
|
clock: clock,
|
|
10844
11183
|
clientForGdr: clientForGdr,
|
|
10845
11184
|
refSurface: refSurface,
|
|
11185
|
+
memberRolesLoader: memberRolesLoader,
|
|
10846
11186
|
executionContext: executionContext,
|
|
10847
11187
|
telemetry: telemetry
|
|
10848
11188
|
})
|
|
@@ -10852,6 +11192,7 @@ async function abortAndPropagate(args) {
|
|
|
10852
11192
|
actor: actor,
|
|
10853
11193
|
clientForGdr: clientForGdr,
|
|
10854
11194
|
refSurface: refSurface,
|
|
11195
|
+
memberRolesLoader: memberRolesLoader,
|
|
10855
11196
|
clock: clock,
|
|
10856
11197
|
...executionContext !== void 0 ? {
|
|
10857
11198
|
executionContext: executionContext
|
|
@@ -10869,6 +11210,7 @@ async function abortAndPropagate(args) {
|
|
|
10869
11210
|
actor: actor,
|
|
10870
11211
|
clientForGdr: clientForGdr,
|
|
10871
11212
|
refSurface: refSurface,
|
|
11213
|
+
memberRolesLoader: memberRolesLoader,
|
|
10872
11214
|
clock: clock,
|
|
10873
11215
|
...executionContext !== void 0 ? {
|
|
10874
11216
|
executionContext: executionContext
|
|
@@ -10910,6 +11252,7 @@ async function dispatchGatedWrite(args) {
|
|
|
10910
11252
|
actor: args.actor,
|
|
10911
11253
|
clientForGdr: args.clientForGdr,
|
|
10912
11254
|
refSurface: args.refSurface,
|
|
11255
|
+
memberRolesLoader: args.memberRolesLoader,
|
|
10913
11256
|
clock: args.clock,
|
|
10914
11257
|
executionContext: args.executionContext,
|
|
10915
11258
|
telemetry: args.telemetry
|
|
@@ -10985,6 +11328,7 @@ function buildEngineCallOptions(args) {
|
|
|
10985
11328
|
actor: args.actor,
|
|
10986
11329
|
clientForGdr: args.clientForGdr,
|
|
10987
11330
|
refSurface: args.refSurface,
|
|
11331
|
+
memberRolesLoader: args.memberRolesLoader,
|
|
10988
11332
|
...args.localPrincipalId !== void 0 ? {
|
|
10989
11333
|
localPrincipalId: args.localPrincipalId
|
|
10990
11334
|
} : {},
|
|
@@ -11024,7 +11368,7 @@ async function applyAction(args) {
|
|
|
11024
11368
|
}
|
|
11025
11369
|
|
|
11026
11370
|
async function deleteDefinition(args) {
|
|
11027
|
-
const {client: client, tag: tag, definition: definition, version: version, cascade: cascade2, reason: reason, executionContext: executionContext, telemetry: telemetry} = args, {actor: actor, clientForGdr: clientForGdr, refSurface: refSurface} = await resolveOperationContext(args), clock = args.clock ?? wallClock, versions = await loadDefinitionVersionsOrThrow({
|
|
11371
|
+
const {client: client, tag: tag, definition: definition, version: version, cascade: cascade2, reason: reason, executionContext: executionContext, telemetry: telemetry} = args, {actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader} = await resolveOperationContext(args), clock = args.clock ?? wallClock, versions = await loadDefinitionVersionsOrThrow({
|
|
11028
11372
|
client: client,
|
|
11029
11373
|
definition: definition,
|
|
11030
11374
|
tag: tag
|
|
@@ -11063,6 +11407,7 @@ async function deleteDefinition(args) {
|
|
|
11063
11407
|
actor: actor,
|
|
11064
11408
|
clientForGdr: clientForGdr,
|
|
11065
11409
|
refSurface: refSurface,
|
|
11410
|
+
memberRolesLoader: memberRolesLoader,
|
|
11066
11411
|
clock: clock,
|
|
11067
11412
|
executionContext: executionContext,
|
|
11068
11413
|
telemetry: telemetry
|
|
@@ -11121,6 +11466,7 @@ async function abortInstances(args) {
|
|
|
11121
11466
|
actor: actor,
|
|
11122
11467
|
clientForGdr: clientForGdr,
|
|
11123
11468
|
refSurface: args.refSurface,
|
|
11469
|
+
memberRolesLoader: args.memberRolesLoader,
|
|
11124
11470
|
clock: clock,
|
|
11125
11471
|
...executionContext !== void 0 ? {
|
|
11126
11472
|
executionContext: executionContext
|
|
@@ -11153,11 +11499,12 @@ async function fetchStartSlice(args) {
|
|
|
11153
11499
|
|
|
11154
11500
|
const workflow = {
|
|
11155
11501
|
deployDefinitions: async rawArgs => {
|
|
11156
|
-
|
|
11157
|
-
const args = taggedScope(rawArgs, REQUEST_TAG.deploy), {client: client, tag: tag, resourceAliases: resourceAliases} = args;
|
|
11502
|
+
const args = taggedScope(rawArgs, REQUEST_TAG.deploy), {client: client, tag: tag, workflowResource: workflowResource, resourceAliases: resourceAliases} = args;
|
|
11158
11503
|
invariants.validateTag(tag);
|
|
11159
11504
|
const definitions = args.definitions.map(def => parseDefinitionInput(def, "workflow.deployDefinitions"));
|
|
11160
|
-
definitions.forEach(validateDefinition)
|
|
11505
|
+
definitions.forEach(validateDefinition), assertReaderModelAcknowledgement(args.expectedMinReaderModel, {
|
|
11506
|
+
requiredMinReaderModel: requiredDefinitionReaderModel(definitions)
|
|
11507
|
+
});
|
|
11161
11508
|
const ordered = await sortByDependencies({
|
|
11162
11509
|
client: client,
|
|
11163
11510
|
definitions: definitions,
|
|
@@ -11176,6 +11523,7 @@ const workflow = {
|
|
|
11176
11523
|
latest: latest,
|
|
11177
11524
|
target: {
|
|
11178
11525
|
tag: tag,
|
|
11526
|
+
workflowResource: workflowResource,
|
|
11179
11527
|
...resourceAliases !== void 0 ? {
|
|
11180
11528
|
resourceAliases: resourceAliases
|
|
11181
11529
|
} : {}
|
|
@@ -11226,7 +11574,7 @@ const workflow = {
|
|
|
11226
11574
|
}), result;
|
|
11227
11575
|
},
|
|
11228
11576
|
startInstance: async rawArgs => {
|
|
11229
|
-
const args = taggedScope(rawArgs, REQUEST_TAG.start), {client: client, tag: tag, definition: definitionName, version: version, initialFields: initialFields, instanceId: instanceId, executionContext: executionContext} = args, operationContext = await resolveOperationContext(args), {actor: actor, clientForGdr: clientForGdr, refSurface: refSurface} = operationContext, clock = args.clock ?? wallClock, seedFields = initialFields ?? [], existing = instanceId !== void 0 ? await getInstanceDocument(client, instanceId) : void 0;
|
|
11577
|
+
const args = taggedScope(rawArgs, REQUEST_TAG.start), {client: client, tag: tag, definition: definitionName, version: version, initialFields: initialFields, instanceId: instanceId, executionContext: executionContext} = args, operationContext = await resolveOperationContext(args), {actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader} = operationContext, clock = args.clock ?? wallClock, seedFields = initialFields ?? [], existing = instanceId !== void 0 ? await getInstanceDocument(client, instanceId) : void 0;
|
|
11230
11578
|
return existing !== void 0 && existing.tag === tag ? resumeStart({
|
|
11231
11579
|
client: client,
|
|
11232
11580
|
tag: tag,
|
|
@@ -11237,6 +11585,7 @@ const workflow = {
|
|
|
11237
11585
|
actor: actor,
|
|
11238
11586
|
clientForGdr: clientForGdr,
|
|
11239
11587
|
refSurface: refSurface,
|
|
11588
|
+
memberRolesLoader: memberRolesLoader,
|
|
11240
11589
|
clock: clock,
|
|
11241
11590
|
...executionContext !== void 0 ? {
|
|
11242
11591
|
executionContext: executionContext
|
|
@@ -11256,7 +11605,7 @@ const workflow = {
|
|
|
11256
11605
|
return runCommitVerb({
|
|
11257
11606
|
args: args,
|
|
11258
11607
|
op: "fireAction",
|
|
11259
|
-
run: async ({access: access, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, record: record, before: before}) => {
|
|
11608
|
+
run: async ({access: access, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock, record: record, before: before}) => {
|
|
11260
11609
|
if (findCurrentActivityEntry(before, activity) === void 0 && idempotent === !0) return {
|
|
11261
11610
|
instance: before,
|
|
11262
11611
|
cascaded: 0,
|
|
@@ -11270,6 +11619,7 @@ const workflow = {
|
|
|
11270
11619
|
actor: actor,
|
|
11271
11620
|
clientForGdr: clientForGdr,
|
|
11272
11621
|
refSurface: refSurface,
|
|
11622
|
+
memberRolesLoader: memberRolesLoader,
|
|
11273
11623
|
clock: clock,
|
|
11274
11624
|
before: before,
|
|
11275
11625
|
...grantsFromPath !== void 0 ? {
|
|
@@ -11303,6 +11653,7 @@ const workflow = {
|
|
|
11303
11653
|
clock: clock,
|
|
11304
11654
|
clientForGdr: clientForGdr,
|
|
11305
11655
|
refSurface: refSurface,
|
|
11656
|
+
memberRolesLoader: memberRolesLoader,
|
|
11306
11657
|
...executionContext !== void 0 ? {
|
|
11307
11658
|
executionContext: executionContext
|
|
11308
11659
|
} : {},
|
|
@@ -11331,7 +11682,7 @@ const workflow = {
|
|
|
11331
11682
|
return runCommitVerb({
|
|
11332
11683
|
args: args,
|
|
11333
11684
|
op: "editField",
|
|
11334
|
-
run: async ({access: access, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, record: record, before: before}) => {
|
|
11685
|
+
run: async ({access: access, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock, record: record, before: before}) => {
|
|
11335
11686
|
const result = await dispatchGatedWrite({
|
|
11336
11687
|
client: client,
|
|
11337
11688
|
tag: tag,
|
|
@@ -11340,6 +11691,7 @@ const workflow = {
|
|
|
11340
11691
|
actor: actor,
|
|
11341
11692
|
clientForGdr: clientForGdr,
|
|
11342
11693
|
refSurface: refSurface,
|
|
11694
|
+
memberRolesLoader: memberRolesLoader,
|
|
11343
11695
|
clock: clock,
|
|
11344
11696
|
before: before,
|
|
11345
11697
|
...grantsFromPath !== void 0 ? {
|
|
@@ -11374,6 +11726,7 @@ const workflow = {
|
|
|
11374
11726
|
clock: clock,
|
|
11375
11727
|
clientForGdr: clientForGdr,
|
|
11376
11728
|
refSurface: refSurface,
|
|
11729
|
+
memberRolesLoader: memberRolesLoader,
|
|
11377
11730
|
...executionContext !== void 0 ? {
|
|
11378
11731
|
executionContext: executionContext
|
|
11379
11732
|
} : {},
|
|
@@ -11394,7 +11747,7 @@ const workflow = {
|
|
|
11394
11747
|
});
|
|
11395
11748
|
},
|
|
11396
11749
|
completeEffect: async rawArgs => {
|
|
11397
|
-
const args = taggedScope(rawArgs, REQUEST_TAG.completeEffect), {client: client, tag: tag, instanceId: instanceId, effectKey: effectKey, status: status, outputs: outputs, ops: ops, detail: detail, error: error, durationMs: durationMs, executionContext: executionContext} = args,
|
|
11750
|
+
const args = taggedScope(rawArgs, REQUEST_TAG.completeEffect), {client: client, tag: tag, instanceId: instanceId, effectKey: effectKey, status: status, outputs: outputs, ops: ops, detail: detail, error: error, durationMs: durationMs, executionContext: executionContext} = args, operationContext = await resolveOperationContext(args), clock = args.clock ?? wallClock, record = requestRecordFor({
|
|
11398
11751
|
idempotencyKey: args.idempotencyKey,
|
|
11399
11752
|
op: "completeEffect",
|
|
11400
11753
|
idempotencyTtlMs: args.idempotencyTtlMs
|
|
@@ -11405,9 +11758,7 @@ const workflow = {
|
|
|
11405
11758
|
instanceId: instanceId,
|
|
11406
11759
|
record: record,
|
|
11407
11760
|
now: clock(),
|
|
11408
|
-
|
|
11409
|
-
clientForGdr: clientForGdr,
|
|
11410
|
-
refSurface: refSurface,
|
|
11761
|
+
...operationContext,
|
|
11411
11762
|
clock: clock,
|
|
11412
11763
|
executionContext: executionContext,
|
|
11413
11764
|
telemetry: args.telemetry,
|
|
@@ -11436,10 +11787,8 @@ const workflow = {
|
|
|
11436
11787
|
requestRecord: record
|
|
11437
11788
|
} : {},
|
|
11438
11789
|
options: engineOptionsForActor({
|
|
11439
|
-
|
|
11790
|
+
...operationContext,
|
|
11440
11791
|
clock: clock,
|
|
11441
|
-
clientForGdr: clientForGdr,
|
|
11442
|
-
refSurface: refSurface,
|
|
11443
11792
|
executionContext: executionContext,
|
|
11444
11793
|
telemetry: args.telemetry
|
|
11445
11794
|
})
|
|
@@ -11447,9 +11796,7 @@ const workflow = {
|
|
|
11447
11796
|
client: client,
|
|
11448
11797
|
tag: tag,
|
|
11449
11798
|
instanceId: instanceId,
|
|
11450
|
-
|
|
11451
|
-
clientForGdr: clientForGdr,
|
|
11452
|
-
refSurface: refSurface,
|
|
11799
|
+
...operationContext,
|
|
11453
11800
|
clock: clock,
|
|
11454
11801
|
executionContext: executionContext,
|
|
11455
11802
|
telemetry: args.telemetry
|
|
@@ -11470,7 +11817,7 @@ const workflow = {
|
|
|
11470
11817
|
});
|
|
11471
11818
|
},
|
|
11472
11819
|
commitEffectOps: async rawArgs => {
|
|
11473
|
-
const args = taggedScope(rawArgs, REQUEST_TAG.commitEffectOps), {client: client, tag: tag, instanceId: instanceId, effectKey: effectKey, claimToken: claimToken, ops: ops, executionContext: executionContext} = args,
|
|
11820
|
+
const args = taggedScope(rawArgs, REQUEST_TAG.commitEffectOps), {client: client, tag: tag, instanceId: instanceId, effectKey: effectKey, claimToken: claimToken, ops: ops, executionContext: executionContext} = args, operationContext = await resolveOperationContext(args), clock = args.clock ?? wallClock, record = requestRecordFor({
|
|
11474
11821
|
idempotencyKey: args.idempotencyKey,
|
|
11475
11822
|
op: "commitEffectOps",
|
|
11476
11823
|
idempotencyTtlMs: args.idempotencyTtlMs
|
|
@@ -11482,9 +11829,7 @@ const workflow = {
|
|
|
11482
11829
|
instanceId: instanceId,
|
|
11483
11830
|
record: record,
|
|
11484
11831
|
now: clock(),
|
|
11485
|
-
|
|
11486
|
-
clientForGdr: clientForGdr,
|
|
11487
|
-
refSurface: refSurface,
|
|
11832
|
+
...operationContext,
|
|
11488
11833
|
clock: clock,
|
|
11489
11834
|
executionContext: executionContext,
|
|
11490
11835
|
telemetry: args.telemetry,
|
|
@@ -11498,10 +11843,8 @@ const workflow = {
|
|
|
11498
11843
|
requestRecord: record,
|
|
11499
11844
|
leaseMs: args.leaseMs ?? DEFAULT_EFFECT_LEASE_MS,
|
|
11500
11845
|
options: engineOptionsForActor({
|
|
11501
|
-
|
|
11846
|
+
...operationContext,
|
|
11502
11847
|
clock: clock,
|
|
11503
|
-
clientForGdr: clientForGdr,
|
|
11504
|
-
refSurface: refSurface,
|
|
11505
11848
|
executionContext: executionContext,
|
|
11506
11849
|
telemetry: args.telemetry
|
|
11507
11850
|
})
|
|
@@ -11509,9 +11852,7 @@ const workflow = {
|
|
|
11509
11852
|
client: client,
|
|
11510
11853
|
tag: tag,
|
|
11511
11854
|
instanceId: instanceId,
|
|
11512
|
-
|
|
11513
|
-
clientForGdr: clientForGdr,
|
|
11514
|
-
refSurface: refSurface,
|
|
11855
|
+
...operationContext,
|
|
11515
11856
|
clock: clock,
|
|
11516
11857
|
executionContext: executionContext,
|
|
11517
11858
|
telemetry: args.telemetry
|
|
@@ -11530,7 +11871,7 @@ const workflow = {
|
|
|
11530
11871
|
});
|
|
11531
11872
|
},
|
|
11532
11873
|
tick: async rawArgs => {
|
|
11533
|
-
const args = taggedScope(rawArgs, REQUEST_TAG.tick), {client: client, tag: tag, instanceId: instanceId, executionContext: executionContext} = args,
|
|
11874
|
+
const args = taggedScope(rawArgs, REQUEST_TAG.tick), {client: client, tag: tag, instanceId: instanceId, executionContext: executionContext} = args, operationContext = await resolveOperationContext(args), {access: access} = operationContext, clock = args.clock ?? wallClock, current = await reload({
|
|
11534
11875
|
client: client,
|
|
11535
11876
|
instanceId: instanceId,
|
|
11536
11877
|
tag: tag
|
|
@@ -11544,9 +11885,7 @@ const workflow = {
|
|
|
11544
11885
|
client: client,
|
|
11545
11886
|
tag: tag,
|
|
11546
11887
|
instanceId: instanceId,
|
|
11547
|
-
|
|
11548
|
-
clientForGdr: clientForGdr,
|
|
11549
|
-
refSurface: refSurface,
|
|
11888
|
+
...operationContext,
|
|
11550
11889
|
clock: clock,
|
|
11551
11890
|
executionContext: executionContext,
|
|
11552
11891
|
telemetry: args.telemetry
|
|
@@ -11566,7 +11905,7 @@ const workflow = {
|
|
|
11566
11905
|
return runCommitVerb({
|
|
11567
11906
|
args: args,
|
|
11568
11907
|
op: "setStage",
|
|
11569
|
-
run: async ({actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, record: record, before: before}) => {
|
|
11908
|
+
run: async ({actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock, record: record, before: before}) => {
|
|
11570
11909
|
const result = await setStage({
|
|
11571
11910
|
client: client,
|
|
11572
11911
|
instanceId: instanceId,
|
|
@@ -11582,6 +11921,7 @@ const workflow = {
|
|
|
11582
11921
|
clock: clock,
|
|
11583
11922
|
clientForGdr: clientForGdr,
|
|
11584
11923
|
refSurface: refSurface,
|
|
11924
|
+
memberRolesLoader: memberRolesLoader,
|
|
11585
11925
|
executionContext: executionContext,
|
|
11586
11926
|
telemetry: args.telemetry
|
|
11587
11927
|
})
|
|
@@ -11591,6 +11931,7 @@ const workflow = {
|
|
|
11591
11931
|
actor: actor,
|
|
11592
11932
|
clientForGdr: clientForGdr,
|
|
11593
11933
|
refSurface: refSurface,
|
|
11934
|
+
memberRolesLoader: memberRolesLoader,
|
|
11594
11935
|
clock: clock,
|
|
11595
11936
|
...executionContext !== void 0 ? {
|
|
11596
11937
|
executionContext: executionContext
|
|
@@ -11620,7 +11961,7 @@ const workflow = {
|
|
|
11620
11961
|
return runCommitVerb({
|
|
11621
11962
|
args: args,
|
|
11622
11963
|
op: "abortInstance",
|
|
11623
|
-
run: async ({actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, record: record, before: before}) => {
|
|
11964
|
+
run: async ({actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock, record: record, before: before}) => {
|
|
11624
11965
|
const changed = await abortAndPropagate({
|
|
11625
11966
|
client: client,
|
|
11626
11967
|
instanceId: instanceId,
|
|
@@ -11628,6 +11969,7 @@ const workflow = {
|
|
|
11628
11969
|
actor: actor,
|
|
11629
11970
|
clientForGdr: clientForGdr,
|
|
11630
11971
|
refSurface: refSurface,
|
|
11972
|
+
memberRolesLoader: memberRolesLoader,
|
|
11631
11973
|
clock: clock,
|
|
11632
11974
|
...executionContext !== void 0 ? {
|
|
11633
11975
|
executionContext: executionContext
|
|
@@ -11661,7 +12003,7 @@ const workflow = {
|
|
|
11661
12003
|
return runCommitVerb({
|
|
11662
12004
|
args: args,
|
|
11663
12005
|
op: "resetActivity",
|
|
11664
|
-
run: async ({actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, record: record, before: before}) => {
|
|
12006
|
+
run: async ({actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock, record: record, before: before}) => {
|
|
11665
12007
|
const result = await resetActivity({
|
|
11666
12008
|
client: client,
|
|
11667
12009
|
instanceId: instanceId,
|
|
@@ -11675,6 +12017,7 @@ const workflow = {
|
|
|
11675
12017
|
clock: clock,
|
|
11676
12018
|
clientForGdr: clientForGdr,
|
|
11677
12019
|
refSurface: refSurface,
|
|
12020
|
+
memberRolesLoader: memberRolesLoader,
|
|
11678
12021
|
executionContext: executionContext,
|
|
11679
12022
|
telemetry: args.telemetry
|
|
11680
12023
|
})
|
|
@@ -11684,6 +12027,7 @@ const workflow = {
|
|
|
11684
12027
|
actor: actor,
|
|
11685
12028
|
clientForGdr: clientForGdr,
|
|
11686
12029
|
refSurface: refSurface,
|
|
12030
|
+
memberRolesLoader: memberRolesLoader,
|
|
11687
12031
|
clock: clock,
|
|
11688
12032
|
...executionContext !== void 0 ? {
|
|
11689
12033
|
executionContext: executionContext
|
|
@@ -11989,7 +12333,7 @@ async function startRequirementVerdict(args) {
|
|
|
11989
12333
|
}
|
|
11990
12334
|
|
|
11991
12335
|
async function startFreshInstance(args) {
|
|
11992
|
-
const {args: startArgs, operationContext: operationContext, clock: clock, seedFields: seedFields} = args, {client: client, tag: tag, workflowResource: workflowResource, definition: definitionName, version: version, ancestors: ancestors, context: context, instanceId: instanceId, perspective: perspective, executionContext: executionContext} = startArgs, {actor: actor, clientForGdr: clientForGdr, refSurface: refSurface} = operationContext, definition = await loadDefinition({
|
|
12336
|
+
const {args: startArgs, operationContext: operationContext, clock: clock, seedFields: seedFields} = args, {client: client, tag: tag, workflowResource: workflowResource, definition: definitionName, version: version, ancestors: ancestors, context: context, instanceId: instanceId, perspective: perspective, executionContext: executionContext} = startArgs, {actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader} = operationContext, definition = await loadDefinition({
|
|
11993
12337
|
client: client,
|
|
11994
12338
|
definition: definitionName,
|
|
11995
12339
|
version: version,
|
|
@@ -12013,6 +12357,7 @@ async function startFreshInstance(args) {
|
|
|
12013
12357
|
id: id,
|
|
12014
12358
|
now: now,
|
|
12015
12359
|
refSurface: refSurface,
|
|
12360
|
+
memberRolesLoader: memberRolesLoader,
|
|
12016
12361
|
...perspective !== void 0 ? {
|
|
12017
12362
|
perspective: perspective
|
|
12018
12363
|
} : {}
|
|
@@ -12044,6 +12389,7 @@ async function startFreshInstance(args) {
|
|
|
12044
12389
|
actor: actor,
|
|
12045
12390
|
clientForGdr: clientForGdr,
|
|
12046
12391
|
refSurface: refSurface,
|
|
12392
|
+
memberRolesLoader: memberRolesLoader,
|
|
12047
12393
|
clock: clock,
|
|
12048
12394
|
...executionContext !== void 0 ? {
|
|
12049
12395
|
executionContext: executionContext
|
|
@@ -12099,7 +12445,10 @@ async function assertStartInputs(args) {
|
|
|
12099
12445
|
}
|
|
12100
12446
|
|
|
12101
12447
|
async function resolveStartFields(args) {
|
|
12102
|
-
const {client: client, tag: tag, workflowResource: workflowResource, definition: definition, initialFields: initialFields, id: id, now: now, refSurface: refSurface, perspective: perspective} = args, fieldDiscards = []
|
|
12448
|
+
const {client: client, tag: tag, workflowResource: workflowResource, definition: definition, initialFields: initialFields, id: id, now: now, refSurface: refSurface, memberRolesLoader: memberRolesLoader, perspective: perspective} = args, fieldDiscards = [], memberRoles = await memberRolesLoader({
|
|
12449
|
+
workflowResource: workflowResource,
|
|
12450
|
+
definition: definition
|
|
12451
|
+
});
|
|
12103
12452
|
return {
|
|
12104
12453
|
resolvedFields: await resolveDeclaredFields({
|
|
12105
12454
|
entryDefs: definition.fields ?? [],
|
|
@@ -12112,6 +12461,8 @@ async function resolveStartFields(args) {
|
|
|
12112
12461
|
workflowResource: workflowResource,
|
|
12113
12462
|
definitionName: definition.name,
|
|
12114
12463
|
refSurface: refSurface,
|
|
12464
|
+
memberRoles: memberRoles,
|
|
12465
|
+
roleAliases: definition.roleAliases,
|
|
12115
12466
|
...perspective !== void 0 ? {
|
|
12116
12467
|
perspective: perspective
|
|
12117
12468
|
} : {},
|
|
@@ -12779,11 +13130,12 @@ function createInstanceSession(args) {
|
|
|
12779
13130
|
attributes: attributes
|
|
12780
13131
|
} : {}
|
|
12781
13132
|
});
|
|
12782
|
-
}, settleAfterApply = async ({actor: actor, held: held, ranOps: ranOps, scope: scope}) => {
|
|
13133
|
+
}, settleAfterApply = async ({actor: actor, held: held, ranOps: ranOps, scope: scope, memberRolesLoader: memberRolesLoader}) => {
|
|
12783
13134
|
const cascaded = await cascadeHeld({
|
|
12784
13135
|
scope: scope,
|
|
12785
13136
|
actor: actor,
|
|
12786
|
-
held: held
|
|
13137
|
+
held: held,
|
|
13138
|
+
memberRolesLoader: memberRolesLoader
|
|
12787
13139
|
});
|
|
12788
13140
|
return instance = await reload({
|
|
12789
13141
|
client: scope.client,
|
|
@@ -12797,12 +13149,13 @@ function createInstanceSession(args) {
|
|
|
12797
13149
|
ranOps: ranOps
|
|
12798
13150
|
} : {}
|
|
12799
13151
|
};
|
|
12800
|
-
}, cascadeHeld = ({scope: scope, actor: actor, held: held}) => cascade({
|
|
13152
|
+
}, cascadeHeld = ({scope: scope, actor: actor, held: held, memberRolesLoader: memberRolesLoader}) => cascade({
|
|
12801
13153
|
client: scope.client,
|
|
12802
13154
|
instanceId: instance._id,
|
|
12803
13155
|
actor: actor,
|
|
12804
13156
|
clientForGdr: scope.clientForGdr,
|
|
12805
13157
|
refSurface: scope.refSurface,
|
|
13158
|
+
memberRolesLoader: memberRolesLoader,
|
|
12806
13159
|
...clock !== void 0 ? {
|
|
12807
13160
|
clock: clock
|
|
12808
13161
|
} : {},
|
|
@@ -12899,6 +13252,7 @@ function createInstanceSession(args) {
|
|
|
12899
13252
|
},
|
|
12900
13253
|
tick() {
|
|
12901
13254
|
return commit(async ({actor: actor, localPrincipalId: localPrincipalId}, held) => {
|
|
13255
|
+
const memberRolesLoader = createAssignmentMemberRolesLoader(tickScope.client);
|
|
12902
13256
|
await assertInstanceWriteAllowed({
|
|
12903
13257
|
instance: instance,
|
|
12904
13258
|
guards: heldGuards,
|
|
@@ -12914,7 +13268,8 @@ function createInstanceSession(args) {
|
|
|
12914
13268
|
}), cascaded = await cascadeHeld({
|
|
12915
13269
|
scope: tickScope,
|
|
12916
13270
|
actor: actor,
|
|
12917
|
-
held: held
|
|
13271
|
+
held: held,
|
|
13272
|
+
memberRolesLoader: memberRolesLoader
|
|
12918
13273
|
});
|
|
12919
13274
|
return instance = await reload({
|
|
12920
13275
|
client: tickScope.client,
|
|
@@ -12933,6 +13288,7 @@ function createInstanceSession(args) {
|
|
|
12933
13288
|
},
|
|
12934
13289
|
fireAction({activity: activity, action: action, params: params}) {
|
|
12935
13290
|
return commit(async ({actor: actor, localPrincipalId: localPrincipalId}, held) => {
|
|
13291
|
+
const memberRolesLoader = createAssignmentMemberRolesLoader(fireScope.client);
|
|
12936
13292
|
assertActionAllowed({
|
|
12937
13293
|
evaluation: await evaluateWith({
|
|
12938
13294
|
held: held,
|
|
@@ -12953,6 +13309,7 @@ function createInstanceSession(args) {
|
|
|
12953
13309
|
} : {},
|
|
12954
13310
|
clientForGdr: fireScope.clientForGdr,
|
|
12955
13311
|
refSurface: fireScope.refSurface,
|
|
13312
|
+
memberRolesLoader: memberRolesLoader,
|
|
12956
13313
|
...grants !== void 0 ? {
|
|
12957
13314
|
grants: grants
|
|
12958
13315
|
} : {},
|
|
@@ -12972,7 +13329,8 @@ function createInstanceSession(args) {
|
|
|
12972
13329
|
actor: actor,
|
|
12973
13330
|
held: held,
|
|
12974
13331
|
ranOps: ranOps,
|
|
12975
|
-
scope: fireScope
|
|
13332
|
+
scope: fireScope,
|
|
13333
|
+
memberRolesLoader: memberRolesLoader
|
|
12976
13334
|
});
|
|
12977
13335
|
return telemetry.log(WorkflowActionFired, actionFiredData({
|
|
12978
13336
|
instance: preOp,
|
|
@@ -12994,6 +13352,7 @@ function createInstanceSession(args) {
|
|
|
12994
13352
|
return Promise.reject(err);
|
|
12995
13353
|
}
|
|
12996
13354
|
return commit(async ({actor: actor, localPrincipalId: localPrincipalId}, held) => {
|
|
13355
|
+
const memberRolesLoader = createAssignmentMemberRolesLoader(editScope.client);
|
|
12997
13356
|
assertEditAllowed(await evaluateWith({
|
|
12998
13357
|
held: held,
|
|
12999
13358
|
guards: heldGuards,
|
|
@@ -13015,6 +13374,7 @@ function createInstanceSession(args) {
|
|
|
13015
13374
|
} : {},
|
|
13016
13375
|
clientForGdr: editScope.clientForGdr,
|
|
13017
13376
|
refSurface: editScope.refSurface,
|
|
13377
|
+
memberRolesLoader: memberRolesLoader,
|
|
13018
13378
|
...grants !== void 0 ? {
|
|
13019
13379
|
grants: grants
|
|
13020
13380
|
} : {},
|
|
@@ -13031,7 +13391,8 @@ function createInstanceSession(args) {
|
|
|
13031
13391
|
actor: actor,
|
|
13032
13392
|
held: held,
|
|
13033
13393
|
ranOps: ranOps,
|
|
13034
|
-
scope: editScope
|
|
13394
|
+
scope: editScope,
|
|
13395
|
+
memberRolesLoader: memberRolesLoader
|
|
13035
13396
|
});
|
|
13036
13397
|
return telemetry.log(WorkflowFieldEdited, fieldEditedData({
|
|
13037
13398
|
instance: preOp,
|
|
@@ -13350,8 +13711,11 @@ function attributeMember({member: member, group: group, chain: chain}) {
|
|
|
13350
13711
|
}
|
|
13351
13712
|
|
|
13352
13713
|
function diffEntry({def: rawDef, latestRaw: latestRaw, target: target}) {
|
|
13353
|
-
|
|
13354
|
-
|
|
13714
|
+
const def = parseDefinitionInput(rawDef, "diffEntry");
|
|
13715
|
+
assertReaderModelAcknowledgement(target.expectedMinReaderModel, {
|
|
13716
|
+
requiredMinReaderModel: requiredDefinitionReaderModel([ def ])
|
|
13717
|
+
});
|
|
13718
|
+
const plan = planDefinitionDeploy({
|
|
13355
13719
|
def: def,
|
|
13356
13720
|
latest: asLatest(latestRaw),
|
|
13357
13721
|
target: target
|
|
@@ -13382,10 +13746,13 @@ function asLatest(raw) {
|
|
|
13382
13746
|
}
|
|
13383
13747
|
|
|
13384
13748
|
async function computeDiffEntries({client: client, defs: defs, target: target}) {
|
|
13385
|
-
|
|
13749
|
+
const definitions = defs.map(def => parseDefinitionInput(def, "computeDiffEntries"));
|
|
13750
|
+
assertReaderModelAcknowledgement(target.expectedMinReaderModel, {
|
|
13751
|
+
requiredMinReaderModel: requiredDefinitionReaderModel(definitions)
|
|
13752
|
+
});
|
|
13386
13753
|
const entries = [];
|
|
13387
|
-
for (const
|
|
13388
|
-
const
|
|
13754
|
+
for (const def of definitions) {
|
|
13755
|
+
const latest = await loadLatestDeployed({
|
|
13389
13756
|
client: client,
|
|
13390
13757
|
definition: def.name,
|
|
13391
13758
|
tag: target.tag
|
|
@@ -13764,6 +14131,8 @@ exports.WORKFLOW_DEFINITION_TYPE = invariants.WORKFLOW_DEFINITION_TYPE;
|
|
|
13764
14131
|
|
|
13765
14132
|
exports.WorkflowError = invariants.WorkflowError;
|
|
13766
14133
|
|
|
14134
|
+
exports.actorFulfillsRole = invariants.actorFulfillsRole;
|
|
14135
|
+
|
|
13767
14136
|
exports.classifyPrincipalId = invariants.classifyPrincipalId;
|
|
13768
14137
|
|
|
13769
14138
|
exports.clientConfigFromResource = invariants.clientConfigFromResource;
|
|
@@ -13978,6 +14347,8 @@ exports.ConcurrentFireActionError = ConcurrentFireActionError;
|
|
|
13978
14347
|
|
|
13979
14348
|
exports.DATA_MODEL_CHANGES = DATA_MODEL_CHANGES;
|
|
13980
14349
|
|
|
14350
|
+
exports.DATA_MODEL_MAX_READER = DATA_MODEL_MAX_READER;
|
|
14351
|
+
|
|
13981
14352
|
exports.DATA_MODEL_MIN_READER = DATA_MODEL_MIN_READER;
|
|
13982
14353
|
|
|
13983
14354
|
exports.DATA_MODEL_VERSION = DATA_MODEL_VERSION;
|
|
@@ -14070,6 +14441,8 @@ exports.WorkflowFieldEdited = WorkflowFieldEdited;
|
|
|
14070
14441
|
|
|
14071
14442
|
exports.WorkflowInstanceAborted = WorkflowInstanceAborted;
|
|
14072
14443
|
|
|
14444
|
+
exports.WorkflowInstancePreviewSchema = WorkflowInstancePreviewSchema;
|
|
14445
|
+
|
|
14073
14446
|
exports.WorkflowInstanceSchema = WorkflowInstanceSchema;
|
|
14074
14447
|
|
|
14075
14448
|
exports.WorkflowInstanceStarted = WorkflowInstanceStarted;
|
|
@@ -14228,10 +14601,14 @@ exports.inFlightFilter = inFlightFilter;
|
|
|
14228
14601
|
|
|
14229
14602
|
exports.initialFieldIssues = initialFieldIssues;
|
|
14230
14603
|
|
|
14604
|
+
exports.instanceChangesQuery = instanceChangesQuery;
|
|
14605
|
+
|
|
14231
14606
|
exports.instanceDocId = instanceDocId;
|
|
14232
14607
|
|
|
14233
14608
|
exports.instanceGuardQuery = instanceGuardQuery;
|
|
14234
14609
|
|
|
14610
|
+
exports.instancePreviewsQuery = instancePreviewsQuery;
|
|
14611
|
+
|
|
14235
14612
|
exports.instanceWatchesDocument = instanceWatchesDocument;
|
|
14236
14613
|
|
|
14237
14614
|
exports.instancesGuardQuery = instancesGuardQuery;
|
|
@@ -14286,6 +14663,8 @@ exports.parseGuardDocument = parseGuardDocument;
|
|
|
14286
14663
|
|
|
14287
14664
|
exports.parseInstanceDocument = parseInstanceDocument;
|
|
14288
14665
|
|
|
14666
|
+
exports.parseInstancePreviewDocument = parseInstancePreviewDocument;
|
|
14667
|
+
|
|
14289
14668
|
exports.processShellUserProperties = processShellUserProperties;
|
|
14290
14669
|
|
|
14291
14670
|
exports.projectStartSliceRow = projectStartSliceRow;
|
|
@@ -14294,12 +14673,16 @@ exports.projectToWatchRef = projectToWatchRef;
|
|
|
14294
14673
|
|
|
14295
14674
|
exports.readInstanceDoc = readInstanceDoc;
|
|
14296
14675
|
|
|
14676
|
+
exports.readInstancePreviewDoc = readInstancePreviewDoc;
|
|
14677
|
+
|
|
14297
14678
|
exports.readsRaw = readsRaw;
|
|
14298
14679
|
|
|
14299
14680
|
exports.refsOf = refsOf;
|
|
14300
14681
|
|
|
14301
14682
|
exports.remediationsFor = remediationsFor;
|
|
14302
14683
|
|
|
14684
|
+
exports.requiredDefinitionReaderModel = requiredDefinitionReaderModel;
|
|
14685
|
+
|
|
14303
14686
|
exports.requiredModelFeatures = requiredModelFeatures;
|
|
14304
14687
|
|
|
14305
14688
|
exports.requiredReaderModel = requiredReaderModel;
|