@sanity/workflow-engine 0.28.0 → 0.30.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 +201 -0
- package/DATAMODEL.md +171 -19
- package/dist/_chunks-cjs/invariants.cjs +465 -175
- package/dist/_chunks-es/invariants.js +454 -176
- package/dist/define.d.cts +472 -281
- package/dist/define.d.ts +472 -281
- package/dist/index.cjs +1823 -1025
- package/dist/index.d.cts +1316 -1059
- package/dist/index.d.ts +1316 -1059
- package/dist/index.js +1817 -1048
- 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,240 +452,6 @@ function fieldEditedData(args) {
|
|
|
449
452
|
};
|
|
450
453
|
}
|
|
451
454
|
|
|
452
|
-
const DATA_MODEL_VERSION = 5, DATA_MODEL_MIN_READER = 4, READER_MODEL_ROLLOUT_URL = "https://www.sanity.io/docs/editorial-workflows/prerelease";
|
|
453
|
-
|
|
454
|
-
class ReaderModelAcknowledgementError extends invariants.WorkflowError {
|
|
455
|
-
code="WORKFLOW_READER_MODEL_ACKNOWLEDGEMENT_MISMATCH";
|
|
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
|
-
}
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
function assertReaderModelAcknowledgement(expectedMinReaderModel, context) {
|
|
468
|
-
if (typeof expectedMinReaderModel != "number" || !Number.isFinite(expectedMinReaderModel) || !Number.isInteger(expectedMinReaderModel) || expectedMinReaderModel < 0 || expectedMinReaderModel !== DATA_MODEL_MIN_READER) throw new ReaderModelAcknowledgementError(expectedMinReaderModel, context);
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
const DATA_MODEL_CHANGES = Object.freeze([ Object.freeze({
|
|
472
|
-
id: "governed-model-stamps",
|
|
473
|
-
introducedInModel: 1,
|
|
474
|
-
minReaderModel: 0,
|
|
475
|
-
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
476
|
-
compatibility: "additive",
|
|
477
|
-
applicability: "unconditional",
|
|
478
|
-
summary: "Definition and instance documents carry model provenance and reader-floor stamps."
|
|
479
|
-
}), Object.freeze({
|
|
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 a closed bag of 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
|
-
}) ]);
|
|
552
|
-
|
|
553
|
-
function recordOf(value) {
|
|
554
|
-
return value !== null && typeof value == "object" && !Array.isArray(value) ? value : void 0;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
function recordsAt(record, key) {
|
|
558
|
-
const value = record[key];
|
|
559
|
-
return Array.isArray(value) ? value.map(recordOf).filter(item => item !== void 0) : [];
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
function nestedFieldEntries(entries) {
|
|
563
|
-
return entries.flatMap(entry => [ entry, ...nestedFieldEntries(recordsAt(entry, "fields")), ...nestedFieldEntries(recordsAt(entry, "of")) ]);
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
function parsedDefinitionSnapshot(root) {
|
|
567
|
-
if (typeof root.definitionSnapshot == "string") return recordOf(parseDefinitionSnapshotValue({
|
|
568
|
-
_id: typeof root._id == "string" ? root._id : "<unknown instance>",
|
|
569
|
-
definitionSnapshot: root.definitionSnapshot
|
|
570
|
-
}));
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
function persistedFieldEntries(document) {
|
|
574
|
-
const root = recordOf(document);
|
|
575
|
-
if (root === void 0) return [];
|
|
576
|
-
const snapshot = parsedDefinitionSnapshot(root), roots = snapshot === void 0 ? [ root ] : [ root, snapshot ], stages = roots.flatMap(candidate => recordsAt(candidate, "stages")), activities = stages.flatMap(stage => recordsAt(stage, "activities")), actions = activities.flatMap(activity => recordsAt(activity, "actions")), effects = actions.flatMap(action => recordsAt(action, "effects"));
|
|
577
|
-
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")) ]);
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
function hasChoiceList(document) {
|
|
581
|
-
return persistedFieldEntries(document).some(entry => {
|
|
582
|
-
const options = recordOf(entry.options);
|
|
583
|
-
return options !== void 0 && Array.isArray(options.list);
|
|
584
|
-
});
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
function hasFieldKind(document, kind) {
|
|
588
|
-
return persistedFieldEntries(document).some(entry => entry.type === kind || entry._type === kind);
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
function hasActionSemantics(document) {
|
|
592
|
-
const root = recordOf(document);
|
|
593
|
-
return root === void 0 ? !1 : recordsAt(root, "stages").flatMap(stage => recordsAt(stage, "activities")).flatMap(activity => recordsAt(activity, "actions")).some(action => Array.isArray(action.semantics));
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
function hasScalarValidation(document) {
|
|
597
|
-
return persistedFieldEntries(document).some(entry => {
|
|
598
|
-
const validation = recordOf(entry.validation);
|
|
599
|
-
return typeof validation?.min == "number" || typeof validation?.max == "number";
|
|
600
|
-
});
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
function hasClaimTokens(document) {
|
|
604
|
-
const root = recordOf(document);
|
|
605
|
-
return root === void 0 ? !1 : recordsAt(root, "pendingEffects").some(entry => {
|
|
606
|
-
const claim = recordOf(entry.claim);
|
|
607
|
-
return claim !== void 0 && typeof claim.claimToken == "string";
|
|
608
|
-
});
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
function hasReadinessRequirements(document) {
|
|
612
|
-
const root = recordOf(document);
|
|
613
|
-
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)));
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
const featureDetectors = {
|
|
617
|
-
"governed-model-stamps": () => !0,
|
|
618
|
-
"subject-field-kind": document => hasFieldKind(document, "subject"),
|
|
619
|
-
"typed-scalar-choice-lists": hasChoiceList,
|
|
620
|
-
"action-semantics": hasActionSemantics,
|
|
621
|
-
"inclusive-scalar-bounds": hasScalarValidation,
|
|
622
|
-
"progress-field-kind": document => hasFieldKind(document, "progress"),
|
|
623
|
-
"effect-claim-tokens": hasClaimTokens,
|
|
624
|
-
"classified-principal-ids": () => !0,
|
|
625
|
-
"readiness-requirements": hasReadinessRequirements,
|
|
626
|
-
"due-date-field-kinds": document => hasFieldKind(document, "dueDate") || hasFieldKind(document, "dueDatetime")
|
|
627
|
-
};
|
|
628
|
-
|
|
629
|
-
function requiredModelFeatures(documentType, document) {
|
|
630
|
-
return DATA_MODEL_CHANGES.filter(change => change.documentTypes.some(candidate => candidate === documentType) && featureDetectors[change.id](document));
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
function requiredReaderModel(documentType, document) {
|
|
634
|
-
return Math.max(0, ...requiredModelFeatures(documentType, document).map(change => change.minReaderModel));
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
function modelStampFor(args) {
|
|
638
|
-
return {
|
|
639
|
-
modelVersion: DATA_MODEL_VERSION,
|
|
640
|
-
minReaderModel: Math.max(DATA_MODEL_MIN_READER, args.storedMinReaderModel ?? 0, requiredReaderModel(args.documentType, args.document))
|
|
641
|
-
};
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
function fieldTreeShape(value) {
|
|
645
|
-
if (Array.isArray(value)) return value.map(fieldTreeShape);
|
|
646
|
-
if (value === null) return "null";
|
|
647
|
-
if (typeof value == "object") {
|
|
648
|
-
const record = value;
|
|
649
|
-
return Object.fromEntries(Object.keys(record).toSorted().map(key => [ key, fieldTreeShape(record[key]) ]));
|
|
650
|
-
}
|
|
651
|
-
return typeof value;
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
function modelVersionOf(doc) {
|
|
655
|
-
const stamp = doc.modelVersion;
|
|
656
|
-
return typeof stamp == "number" ? stamp : 0;
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
function minReaderModelOf(doc) {
|
|
660
|
-
const floor = doc.minReaderModel;
|
|
661
|
-
return typeof floor == "number" ? floor : modelVersionOf(doc);
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
class ModelVersionAheadError extends invariants.WorkflowError {
|
|
665
|
-
documentId;
|
|
666
|
-
documentModelVersion;
|
|
667
|
-
requiredReaderModel;
|
|
668
|
-
engineModelVersion;
|
|
669
|
-
constructor(args) {
|
|
670
|
-
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.`),
|
|
671
|
-
this.name = "ModelVersionAheadError", this.documentId = args.documentId, this.documentModelVersion = args.documentModelVersion,
|
|
672
|
-
this.requiredReaderModel = args.requiredReaderModel, this.engineModelVersion = DATA_MODEL_VERSION;
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
function assertReadableModel(doc) {
|
|
677
|
-
const documentReaderModel = minReaderModelOf(doc);
|
|
678
|
-
if (documentReaderModel > DATA_MODEL_VERSION) throw new ModelVersionAheadError({
|
|
679
|
-
documentId: doc._id,
|
|
680
|
-
documentModelVersion: modelVersionOf(doc),
|
|
681
|
-
requiredReaderModel: documentReaderModel
|
|
682
|
-
});
|
|
683
|
-
return doc;
|
|
684
|
-
}
|
|
685
|
-
|
|
686
455
|
function effectSites(def) {
|
|
687
456
|
const sites = [];
|
|
688
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({
|
|
@@ -1157,12 +926,8 @@ function renderWorkflowRead(read, ctx) {
|
|
|
1157
926
|
text: groqConditionDescribe.guillemets(title)
|
|
1158
927
|
});
|
|
1159
928
|
}
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
permission: read.path[0]
|
|
1163
|
-
},
|
|
1164
|
-
text: `your ${read.path[0]} permission`
|
|
1165
|
-
});
|
|
929
|
+
const keyed = keyedCallerRead(read);
|
|
930
|
+
if (keyed !== void 0) return keyed;
|
|
1166
931
|
if (read.variable === "actor" && read.path.length === 1 && read.path[0] === "id") return groqConditionDescribe.phrase("read.actor-id", {
|
|
1167
932
|
params: {},
|
|
1168
933
|
text: "your id"
|
|
@@ -1184,6 +949,24 @@ function renderWorkflowRead(read, ctx) {
|
|
|
1184
949
|
});
|
|
1185
950
|
}
|
|
1186
951
|
|
|
952
|
+
function keyedCallerRead(read) {
|
|
953
|
+
const key = read.path[0];
|
|
954
|
+
if (typeof key == "string") {
|
|
955
|
+
if (read.variable === "can") return groqConditionDescribe.phrase("read.permission", {
|
|
956
|
+
params: {
|
|
957
|
+
permission: key
|
|
958
|
+
},
|
|
959
|
+
text: `your ${key} permission`
|
|
960
|
+
});
|
|
961
|
+
if (read.variable === "attributes") return groqConditionDescribe.phrase("read.attribute", {
|
|
962
|
+
params: {
|
|
963
|
+
attribute: key
|
|
964
|
+
},
|
|
965
|
+
text: `your ${groqConditionDescribe.guillemets(key)} attribute`
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
|
|
1187
970
|
function workflowRequirement(requirement, ctx) {
|
|
1188
971
|
const {target: target} = requirement, clause = clauseVarRequirement(requirement);
|
|
1189
972
|
if (clause !== void 0) return clause;
|
|
@@ -2612,7 +2395,7 @@ class CascadeLimitError extends invariants.WorkflowError {
|
|
|
2612
2395
|
}
|
|
2613
2396
|
}
|
|
2614
2397
|
|
|
2615
|
-
const FIELD_OP_TYPES = [ "field.set", "field.unset", "field.append", "field.updateWhere", "field.removeWhere" ];
|
|
2398
|
+
const FIELD_OP_TYPES = [ "field.set", "field.setIfMissing", "field.unset", "field.append", "field.inc", "field.dec", "field.updateWhere", "field.removeWhere" ];
|
|
2616
2399
|
|
|
2617
2400
|
function isFieldOp(summary) {
|
|
2618
2401
|
return FIELD_OP_TYPES.includes(summary.opType);
|
|
@@ -2620,38 +2403,7 @@ function isFieldOp(summary) {
|
|
|
2620
2403
|
|
|
2621
2404
|
function validateActionParams({action: action, activityName: activityName, callerParams: callerParams}) {
|
|
2622
2405
|
const declared = action.params ?? [], params = callerParams ?? {}, issues = [];
|
|
2623
|
-
for (const decl of declared)
|
|
2624
|
-
const value = params[decl.name], present = decl.name in params && value !== void 0 && value !== null;
|
|
2625
|
-
if (decl.required === !0 && !present) {
|
|
2626
|
-
issues.push({
|
|
2627
|
-
param: decl.name,
|
|
2628
|
-
reason: "required but missing"
|
|
2629
|
-
});
|
|
2630
|
-
continue;
|
|
2631
|
-
}
|
|
2632
|
-
if (!present) continue;
|
|
2633
|
-
if (!checkParamType(value, decl)) {
|
|
2634
|
-
issues.push({
|
|
2635
|
-
param: decl.name,
|
|
2636
|
-
reason: `expected type=${decl.type}, got ${typeof value}`
|
|
2637
|
-
});
|
|
2638
|
-
continue;
|
|
2639
|
-
}
|
|
2640
|
-
const choiceIssues = invariants.choiceValueIssues(decl.options, value);
|
|
2641
|
-
choiceIssues !== void 0 && issues.push({
|
|
2642
|
-
param: decl.name,
|
|
2643
|
-
reason: choiceIssues.join("; ")
|
|
2644
|
-
});
|
|
2645
|
-
const validationIssues = invariants.scalarValidationIssues({
|
|
2646
|
-
entryType: decl.type,
|
|
2647
|
-
validation: decl.validation,
|
|
2648
|
-
value: value
|
|
2649
|
-
});
|
|
2650
|
-
validationIssues !== void 0 && issues.push({
|
|
2651
|
-
param: decl.name,
|
|
2652
|
-
reason: validationIssues.join("; ")
|
|
2653
|
-
});
|
|
2654
|
-
}
|
|
2406
|
+
for (const decl of declared) issues.push(...declaredParamIssues(decl, params));
|
|
2655
2407
|
if (issues.length > 0) throw new ActionParamsInvalidError({
|
|
2656
2408
|
action: action.name,
|
|
2657
2409
|
activity: activityName,
|
|
@@ -2660,6 +2412,30 @@ function validateActionParams({action: action, activityName: activityName, calle
|
|
|
2660
2412
|
return params;
|
|
2661
2413
|
}
|
|
2662
2414
|
|
|
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
|
+
|
|
2663
2439
|
function hasStringField(value, field) {
|
|
2664
2440
|
return typeof value == "object" && value !== null && field in value && typeof value[field] == "string";
|
|
2665
2441
|
}
|
|
@@ -2711,9 +2487,11 @@ async function runOps(args) {
|
|
|
2711
2487
|
now: now,
|
|
2712
2488
|
snapshot: snapshot,
|
|
2713
2489
|
refSurface: refSurface,
|
|
2714
|
-
opsFromDefinition: opsFromDefinition
|
|
2490
|
+
opsFromDefinition: opsFromDefinition,
|
|
2491
|
+
memberRoles: args.memberRoles,
|
|
2492
|
+
roleAliases: args.roleAliases
|
|
2715
2493
|
});
|
|
2716
|
-
summaries.push(summary), mutation.history.push(opAppliedEntry({
|
|
2494
|
+
summaries.push(summary), shouldRecordOpApplied(summary) && mutation.history.push(opAppliedEntry({
|
|
2717
2495
|
origin: origin,
|
|
2718
2496
|
summary: summary,
|
|
2719
2497
|
stage: stage,
|
|
@@ -2724,6 +2502,10 @@ async function runOps(args) {
|
|
|
2724
2502
|
return summaries;
|
|
2725
2503
|
}
|
|
2726
2504
|
|
|
2505
|
+
function shouldRecordOpApplied(summary) {
|
|
2506
|
+
return summary.opType !== "field.setIfMissing" || summary.resolved !== void 0;
|
|
2507
|
+
}
|
|
2508
|
+
|
|
2727
2509
|
function opAppliedEntry(args) {
|
|
2728
2510
|
const {origin: origin, summary: summary, stage: stage, actor: actor, now: now} = args;
|
|
2729
2511
|
return {
|
|
@@ -2795,12 +2577,19 @@ async function applyOp(op, ctx) {
|
|
|
2795
2577
|
case "field.set":
|
|
2796
2578
|
return applyFieldSet(op, ctx);
|
|
2797
2579
|
|
|
2580
|
+
case "field.setIfMissing":
|
|
2581
|
+
return applyFieldSetIfMissing(op, ctx);
|
|
2582
|
+
|
|
2798
2583
|
case "field.unset":
|
|
2799
2584
|
return applyFieldUnset(op, ctx);
|
|
2800
2585
|
|
|
2801
2586
|
case "field.append":
|
|
2802
2587
|
return applyFieldAppend(op, ctx);
|
|
2803
2588
|
|
|
2589
|
+
case "field.inc":
|
|
2590
|
+
case "field.dec":
|
|
2591
|
+
return applyFieldArithmetic(op, ctx);
|
|
2592
|
+
|
|
2804
2593
|
case "field.updateWhere":
|
|
2805
2594
|
return applyFieldUpdateWhere(op, ctx);
|
|
2806
2595
|
|
|
@@ -2821,7 +2610,12 @@ function applyFieldSet(op, ctx) {
|
|
|
2821
2610
|
entryType: entry._type,
|
|
2822
2611
|
entryName: entry.name,
|
|
2823
2612
|
value: value,
|
|
2824
|
-
...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
|
+
} : {}
|
|
2825
2619
|
});
|
|
2826
2620
|
return assertRuntimeRefsWithinSurface({
|
|
2827
2621
|
entryType: entry._type,
|
|
@@ -2839,6 +2633,78 @@ function applyFieldSet(op, ctx) {
|
|
|
2839
2633
|
};
|
|
2840
2634
|
}
|
|
2841
2635
|
|
|
2636
|
+
function applyFieldSetIfMissing(op, ctx) {
|
|
2637
|
+
const entry = locateEntry(ctx, op.target);
|
|
2638
|
+
return invariants.isAlwaysArrayFieldKind(entry._type) && rejectFieldOpTarget({
|
|
2639
|
+
entry: entry,
|
|
2640
|
+
op: op,
|
|
2641
|
+
issue: "is always array-valued — setIfMissing applies to nullable entries only; an empty array entry already holds []"
|
|
2642
|
+
}), entry.value !== null && entry.value !== void 0 ? {
|
|
2643
|
+
opType: op.type,
|
|
2644
|
+
target: op.target
|
|
2645
|
+
} : {
|
|
2646
|
+
...applyFieldSet({
|
|
2647
|
+
...op,
|
|
2648
|
+
type: "field.set"
|
|
2649
|
+
}, ctx),
|
|
2650
|
+
opType: op.type
|
|
2651
|
+
};
|
|
2652
|
+
}
|
|
2653
|
+
|
|
2654
|
+
function applyFieldArithmetic(op, ctx) {
|
|
2655
|
+
const entry = locateEntry(ctx, op.target);
|
|
2656
|
+
entry._type !== "number" && rejectFieldOpTarget({
|
|
2657
|
+
entry: entry,
|
|
2658
|
+
op: op,
|
|
2659
|
+
issue: `is a ${entry._type} entry — arithmetic ops target \`number\` entries only`
|
|
2660
|
+
}), typeof entry.value != "number" && rejectFieldOpTarget({
|
|
2661
|
+
entry: entry,
|
|
2662
|
+
op: op,
|
|
2663
|
+
issue: "has no numeric value — initialize it before applying arithmetic"
|
|
2664
|
+
});
|
|
2665
|
+
const resolvedDelta = op.value === void 0 ? 1 : resolveOpValue({
|
|
2666
|
+
src: op.value,
|
|
2667
|
+
ctx: ctx,
|
|
2668
|
+
target: {
|
|
2669
|
+
kind: "number"
|
|
2670
|
+
}
|
|
2671
|
+
});
|
|
2672
|
+
(typeof resolvedDelta != "number" || !Number.isFinite(resolvedDelta)) && rejectFieldOpTarget({
|
|
2673
|
+
entry: entry,
|
|
2674
|
+
op: op,
|
|
2675
|
+
issue: "value must resolve to a finite number"
|
|
2676
|
+
});
|
|
2677
|
+
const nextValue = entry.value + (op.type === "field.inc" ? resolvedDelta : -resolvedDelta);
|
|
2678
|
+
Number.isFinite(nextValue) || rejectFieldOpTarget({
|
|
2679
|
+
entry: entry,
|
|
2680
|
+
op: op,
|
|
2681
|
+
issue: "result must be a finite number"
|
|
2682
|
+
});
|
|
2683
|
+
const value = invariants.validateFieldValue({
|
|
2684
|
+
entryType: entry._type,
|
|
2685
|
+
entryName: entry.name,
|
|
2686
|
+
value: nextValue,
|
|
2687
|
+
...entryShape(entry)
|
|
2688
|
+
});
|
|
2689
|
+
return setEntryValue(entry, value), {
|
|
2690
|
+
opType: op.type,
|
|
2691
|
+
target: op.target,
|
|
2692
|
+
resolved: {
|
|
2693
|
+
value: value
|
|
2694
|
+
}
|
|
2695
|
+
};
|
|
2696
|
+
}
|
|
2697
|
+
|
|
2698
|
+
function rejectFieldOpTarget(args) {
|
|
2699
|
+
const {entry: entry, op: op, issue: issue} = args;
|
|
2700
|
+
throw new invariants.FieldValueShapeError({
|
|
2701
|
+
entryType: entry._type,
|
|
2702
|
+
entryName: entry.name,
|
|
2703
|
+
mode: "value",
|
|
2704
|
+
issues: [ `${op.type} target ${op.target.scope}:"${op.target.field}" ${issue}` ]
|
|
2705
|
+
});
|
|
2706
|
+
}
|
|
2707
|
+
|
|
2842
2708
|
function entryShape(entry) {
|
|
2843
2709
|
return entry._type === "object" ? {
|
|
2844
2710
|
fields: entry.fields
|
|
@@ -2846,7 +2712,17 @@ function entryShape(entry) {
|
|
|
2846
2712
|
of: entry.of
|
|
2847
2713
|
} : invariants.isSingleDocRefEntry(entry) || entry._type === "doc.refs" ? entry.types !== void 0 ? {
|
|
2848
2714
|
types: entry.types
|
|
2849
|
-
} : {} :
|
|
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 {
|
|
2850
2726
|
...entry.options !== void 0 ? {
|
|
2851
2727
|
options: entry.options
|
|
2852
2728
|
} : {},
|
|
@@ -2874,15 +2750,10 @@ function appendItemSlot(entry) {
|
|
|
2874
2750
|
};
|
|
2875
2751
|
}
|
|
2876
2752
|
|
|
2877
|
-
const EMPTY_BY_KIND = {
|
|
2878
|
-
"doc.refs": [],
|
|
2879
|
-
array: [],
|
|
2880
|
-
assignees: []
|
|
2881
|
-
};
|
|
2882
|
-
|
|
2883
2753
|
function applyFieldUnset(op, ctx) {
|
|
2884
2754
|
const entry = locateEntry(ctx, op.target);
|
|
2885
|
-
return setEntryValue(entry,
|
|
2755
|
+
return setEntryValue(entry, invariants.isAlwaysArrayFieldKind(entry._type) ? [] : null),
|
|
2756
|
+
{
|
|
2886
2757
|
opType: op.type,
|
|
2887
2758
|
target: op.target
|
|
2888
2759
|
};
|
|
@@ -2900,7 +2771,10 @@ function applyFieldAppend(op, ctx) {
|
|
|
2900
2771
|
entryName: entry.name,
|
|
2901
2772
|
item: item,
|
|
2902
2773
|
types: entry._type === "doc.refs" ? entry.types : void 0,
|
|
2903
|
-
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
|
|
2904
2778
|
});
|
|
2905
2779
|
assertRuntimeRefsWithinSurface({
|
|
2906
2780
|
entryType: entry._type === "doc.refs" ? "doc.ref" : "object",
|
|
@@ -2921,7 +2795,7 @@ function applyFieldAppend(op, ctx) {
|
|
|
2921
2795
|
}
|
|
2922
2796
|
|
|
2923
2797
|
function withRowKey(item) {
|
|
2924
|
-
return
|
|
2798
|
+
return invariants.isRecord(item) && !("_key" in item) ? {
|
|
2925
2799
|
_key: randomKey(),
|
|
2926
2800
|
...item
|
|
2927
2801
|
} : item;
|
|
@@ -2948,6 +2822,13 @@ async function applyFieldUpdateWhere(op, ctx) {
|
|
|
2948
2822
|
merge: mergeRecord,
|
|
2949
2823
|
entry: entry,
|
|
2950
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
|
|
2951
2832
|
});
|
|
2952
2833
|
const matches = await rowMatches({
|
|
2953
2834
|
where: op.where,
|
|
@@ -3064,18 +2945,6 @@ function subSlot(target, field) {
|
|
|
3064
2945
|
function resolveOpValue(args) {
|
|
3065
2946
|
const {src: src, ctx: ctx, target: target} = args;
|
|
3066
2947
|
switch (src.type) {
|
|
3067
|
-
case "literal":
|
|
3068
|
-
case "param":
|
|
3069
|
-
case "actor":
|
|
3070
|
-
case "now":
|
|
3071
|
-
return resolveStaticValueExpr(src, ctx);
|
|
3072
|
-
|
|
3073
|
-
case "self":
|
|
3074
|
-
return ctx.self;
|
|
3075
|
-
|
|
3076
|
-
case "stage":
|
|
3077
|
-
return ctx.stage;
|
|
3078
|
-
|
|
3079
2948
|
case "fieldRead":
|
|
3080
2949
|
{
|
|
3081
2950
|
const entry = readEntryFromMutation(ctx, src);
|
|
@@ -3105,6 +2974,25 @@ function resolveOpValue(args) {
|
|
|
3105
2974
|
}
|
|
3106
2975
|
return out;
|
|
3107
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;
|
|
3108
2996
|
}
|
|
3109
2997
|
}
|
|
3110
2998
|
|
|
@@ -3555,75 +3443,424 @@ async function assertInstanceWriteAllowed(args) {
|
|
|
3555
3443
|
});
|
|
3556
3444
|
}
|
|
3557
3445
|
|
|
3558
|
-
|
|
3559
|
-
const {instance: instance, definition: definition, snapshot: snapshot, now: now} = source, base = buildParams({
|
|
3560
|
-
instance: instance,
|
|
3561
|
-
now: now,
|
|
3562
|
-
snapshot: snapshot
|
|
3563
|
-
}), fields = {
|
|
3564
|
-
...base.fields,
|
|
3565
|
-
...scopedFieldOverlay({
|
|
3566
|
-
instance: instance,
|
|
3567
|
-
snapshot: snapshot,
|
|
3568
|
-
activityName: opts?.activityName
|
|
3569
|
-
})
|
|
3570
|
-
}, params = {
|
|
3571
|
-
...base,
|
|
3572
|
-
fields: fields,
|
|
3573
|
-
actor: opts?.actor,
|
|
3574
|
-
assigned: opts?.activityName !== void 0 ? assignedFor({
|
|
3575
|
-
instance: instance,
|
|
3576
|
-
activityName: opts.activityName,
|
|
3577
|
-
actor: opts?.actor,
|
|
3578
|
-
roleAliases: definition.roleAliases
|
|
3579
|
-
}) : !1,
|
|
3580
|
-
...opts?.vars
|
|
3581
|
-
};
|
|
3582
|
-
return {
|
|
3583
|
-
...await invariants.evaluatePredicates({
|
|
3584
|
-
predicates: definition.predicates,
|
|
3585
|
-
snapshot: snapshot,
|
|
3586
|
-
params: params
|
|
3587
|
-
}),
|
|
3588
|
-
...params
|
|
3589
|
-
};
|
|
3590
|
-
}
|
|
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/editorial-workflows/prerelease";
|
|
3591
3447
|
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
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
|
+
}
|
|
3595
3462
|
}
|
|
3596
3463
|
|
|
3597
|
-
function
|
|
3598
|
-
|
|
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
|
+
});
|
|
3599
3472
|
}
|
|
3600
3473
|
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
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
|
+
}) ]);
|
|
3605
3587
|
|
|
3606
|
-
function
|
|
3607
|
-
return
|
|
3588
|
+
function recordOf(value) {
|
|
3589
|
+
return value !== null && typeof value == "object" && !Array.isArray(value) ? value : void 0;
|
|
3608
3590
|
}
|
|
3609
3591
|
|
|
3610
|
-
function
|
|
3611
|
-
|
|
3592
|
+
function recordsAt(record, key) {
|
|
3593
|
+
const value = record[key];
|
|
3594
|
+
return Array.isArray(value) ? value.map(recordOf).filter(item => item !== void 0) : [];
|
|
3612
3595
|
}
|
|
3613
3596
|
|
|
3614
|
-
function
|
|
3615
|
-
|
|
3616
|
-
for (const row of rows) {
|
|
3617
|
-
const held = byName.get(row.name);
|
|
3618
|
-
(held === void 0 || row.version > held.version) && byName.set(row.name, row);
|
|
3619
|
-
}
|
|
3620
|
-
return [ ...byName.values() ];
|
|
3597
|
+
function nestedFieldEntries(entries) {
|
|
3598
|
+
return entries.flatMap(entry => [ entry, ...nestedFieldEntries(recordsAt(entry, "fields")), ...nestedFieldEntries(recordsAt(entry, "of")) ]);
|
|
3621
3599
|
}
|
|
3622
3600
|
|
|
3623
|
-
function
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
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
|
+
}));
|
|
3606
|
+
}
|
|
3607
|
+
|
|
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
|
+
};
|
|
3618
|
+
}
|
|
3619
|
+
|
|
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")) ]);
|
|
3625
|
+
}
|
|
3626
|
+
|
|
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
|
|
3627
3864
|
} : {};
|
|
3628
3865
|
}
|
|
3629
3866
|
|
|
@@ -3708,6 +3945,27 @@ function noTransitionFiresCause(input) {
|
|
|
3708
3945
|
};
|
|
3709
3946
|
}
|
|
3710
3947
|
|
|
3948
|
+
function stuckFromDocumentState(input) {
|
|
3949
|
+
return failedEffectCause(input) ?? failedActivityCause(input) ?? hungEffectCause(input);
|
|
3950
|
+
}
|
|
3951
|
+
|
|
3952
|
+
function documentStuckCause(args) {
|
|
3953
|
+
const stage = findOpenStageEntry(args.instance);
|
|
3954
|
+
if (stage !== void 0) return stuckFromDocumentState({
|
|
3955
|
+
instance: args.instance,
|
|
3956
|
+
activities: stage.activities.map(entry => ({
|
|
3957
|
+
status: entry.status,
|
|
3958
|
+
activity: findActivityNode({
|
|
3959
|
+
activityName: entry.name,
|
|
3960
|
+
definition: args.definition,
|
|
3961
|
+
stageName: stage.name
|
|
3962
|
+
}) ?? {
|
|
3963
|
+
name: entry.name
|
|
3964
|
+
}
|
|
3965
|
+
}))
|
|
3966
|
+
});
|
|
3967
|
+
}
|
|
3968
|
+
|
|
3711
3969
|
function diagnoseInstance(input) {
|
|
3712
3970
|
const {instance: instance} = input, terminal = terminalState(instance);
|
|
3713
3971
|
if (terminal === "aborted" && instance.abortedAt !== void 0) {
|
|
@@ -3726,7 +3984,7 @@ function diagnoseInstance(input) {
|
|
|
3726
3984
|
at: instance.completedAt,
|
|
3727
3985
|
...liveChildrenField(instance)
|
|
3728
3986
|
};
|
|
3729
|
-
const cause =
|
|
3987
|
+
const cause = stuckFromDocumentState(input) ?? noTransitionFiresCause(input);
|
|
3730
3988
|
return cause !== void 0 ? {
|
|
3731
3989
|
state: "stuck",
|
|
3732
3990
|
cause: cause
|
|
@@ -3788,35 +4046,235 @@ function isClaimExpired(claim, now) {
|
|
|
3788
4046
|
return claim.leaseExpiresAt === void 0 || hasPassed(claim.leaseExpiresAt, now);
|
|
3789
4047
|
}
|
|
3790
4048
|
|
|
3791
|
-
const EFFECT_RUN_STATUSES = [ "done", "failed", "cancelled" ]
|
|
3792
|
-
interactive: "interactive",
|
|
3793
|
-
server: "server",
|
|
3794
|
-
cli: "cli",
|
|
3795
|
-
mcp: "mcp",
|
|
3796
|
-
drainer: "drainer",
|
|
3797
|
-
script: "script",
|
|
3798
|
-
test: "test",
|
|
3799
|
-
studio: "studio",
|
|
3800
|
-
sdkApp: "sdk-app"
|
|
3801
|
-
};
|
|
4049
|
+
const EFFECT_RUN_STATUSES = [ "done", "failed", "cancelled" ];
|
|
3802
4050
|
|
|
3803
|
-
function
|
|
3804
|
-
|
|
3805
|
-
if (g.Deno !== void 0) return "deno";
|
|
3806
|
-
if (g.Bun !== void 0) return "bun";
|
|
3807
|
-
if (g.EdgeRuntime !== void 0) return "edge";
|
|
3808
|
-
if (g.window !== void 0 && g.document !== void 0) return "browser";
|
|
3809
|
-
if (g.WorkerGlobalScope !== void 0 && g.self !== void 0) return "worker";
|
|
3810
|
-
const proc = g.process;
|
|
3811
|
-
return typeof proc == "object" && proc !== null && typeof proc.versions?.node == "string" ? "node" : "unknown";
|
|
4051
|
+
function userLoginProvider(user) {
|
|
4052
|
+
return user?.provider ?? user?.loginProvider;
|
|
3812
4053
|
}
|
|
3813
4054
|
|
|
3814
|
-
|
|
4055
|
+
function optionalString(value) {
|
|
4056
|
+
return value === void 0 || typeof value == "string";
|
|
4057
|
+
}
|
|
3815
4058
|
|
|
3816
|
-
function
|
|
3817
|
-
return
|
|
3818
|
-
|
|
3819
|
-
|
|
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);
|
|
4218
|
+
}
|
|
4219
|
+
|
|
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
|
+
};
|
|
4243
|
+
}
|
|
4244
|
+
|
|
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}"`);
|
|
4247
|
+
}
|
|
4248
|
+
|
|
4249
|
+
const EXECUTION_KINDS = {
|
|
4250
|
+
interactive: "interactive",
|
|
4251
|
+
server: "server",
|
|
4252
|
+
cli: "cli",
|
|
4253
|
+
mcp: "mcp",
|
|
4254
|
+
drainer: "drainer",
|
|
4255
|
+
script: "script",
|
|
4256
|
+
test: "test",
|
|
4257
|
+
studio: "studio",
|
|
4258
|
+
sdkApp: "sdk-app"
|
|
4259
|
+
};
|
|
4260
|
+
|
|
4261
|
+
function detectRuntime() {
|
|
4262
|
+
const g = globalThis;
|
|
4263
|
+
if (g.Deno !== void 0) return "deno";
|
|
4264
|
+
if (g.Bun !== void 0) return "bun";
|
|
4265
|
+
if (g.EdgeRuntime !== void 0) return "edge";
|
|
4266
|
+
if (g.window !== void 0 && g.document !== void 0) return "browser";
|
|
4267
|
+
if (g.WorkerGlobalScope !== void 0 && g.self !== void 0) return "worker";
|
|
4268
|
+
const proc = g.process;
|
|
4269
|
+
return typeof proc == "object" && proc !== null && typeof proc.versions?.node == "string" ? "node" : "unknown";
|
|
4270
|
+
}
|
|
4271
|
+
|
|
4272
|
+
let inferredRuntime;
|
|
4273
|
+
|
|
4274
|
+
function resolveExecutionContext(declared) {
|
|
4275
|
+
return inferredRuntime ??= detectRuntime(), {
|
|
4276
|
+
runtime: inferredRuntime,
|
|
4277
|
+
...declared?.kind !== void 0 ? {
|
|
3820
4278
|
kind: declared.kind
|
|
3821
4279
|
} : {},
|
|
3822
4280
|
...declared?.id !== void 0 ? {
|
|
@@ -4105,10 +4563,8 @@ function assertRequiredInputProvided({entryDefs: entryDefs, initialFields: initi
|
|
|
4105
4563
|
});
|
|
4106
4564
|
}
|
|
4107
4565
|
|
|
4108
|
-
const ARRAY_FIELD_TYPES = /* @__PURE__ */ new Set([ "doc.refs", "array", "assignees" ]);
|
|
4109
|
-
|
|
4110
4566
|
function defaultEntryValue(entryType) {
|
|
4111
|
-
return
|
|
4567
|
+
return invariants.isAlwaysArrayFieldKind(entryType) ? [] : null;
|
|
4112
4568
|
}
|
|
4113
4569
|
|
|
4114
4570
|
function resolveInputValue({entry: entry, initialFields: initialFields, defaultValue: defaultValue}) {
|
|
@@ -4213,6 +4669,9 @@ function buildResolvedEntry({entry: entry, value: value, _key: _key, now: now})
|
|
|
4213
4669
|
...entry.validation !== void 0 ? {
|
|
4214
4670
|
validation: entry.validation
|
|
4215
4671
|
} : {},
|
|
4672
|
+
...entry.roles !== void 0 ? {
|
|
4673
|
+
roles: entry.roles
|
|
4674
|
+
} : {},
|
|
4216
4675
|
value: value,
|
|
4217
4676
|
...entry.initialValue?.type === "query" ? {
|
|
4218
4677
|
resolvedAt: now
|
|
@@ -4244,7 +4703,10 @@ async function resolveOneEntry({entry: entry, initialFields: initialFields, ctx:
|
|
|
4244
4703
|
fields: entry.fields,
|
|
4245
4704
|
of: entry.of,
|
|
4246
4705
|
options: entry.options,
|
|
4247
|
-
validation: entry.validation
|
|
4706
|
+
validation: entry.validation,
|
|
4707
|
+
roles: entry.roles,
|
|
4708
|
+
memberRoles: ctx.memberRoles,
|
|
4709
|
+
roleAliases: ctx.roleAliases
|
|
4248
4710
|
});
|
|
4249
4711
|
return "issues" in check ? (ctx.recordDiscard?.({
|
|
4250
4712
|
field: entry.name,
|
|
@@ -4269,7 +4731,10 @@ async function resolveOneEntry({entry: entry, initialFields: initialFields, ctx:
|
|
|
4269
4731
|
fields: entry.fields,
|
|
4270
4732
|
of: entry.of,
|
|
4271
4733
|
options: entry.options,
|
|
4272
|
-
validation: entry.validation
|
|
4734
|
+
validation: entry.validation,
|
|
4735
|
+
roles: entry.roles,
|
|
4736
|
+
memberRoles: ctx.memberRoles,
|
|
4737
|
+
roleAliases: ctx.roleAliases
|
|
4273
4738
|
});
|
|
4274
4739
|
return entry.initialValue?.type === "input" && ctx.inputProvenance !== "definition" && assertRefsWithinSurface({
|
|
4275
4740
|
entryType: entry.type,
|
|
@@ -4363,7 +4828,7 @@ function coerceToGdr(raw, workflowResource) {
|
|
|
4363
4828
|
} : null;
|
|
4364
4829
|
}
|
|
4365
4830
|
|
|
4366
|
-
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({
|
|
4367
4832
|
list: v__namespace.array(v__namespace.looseObject({
|
|
4368
4833
|
title: v__namespace.string(),
|
|
4369
4834
|
value: v__namespace.union([ v__namespace.string(), v__namespace.number() ])
|
|
@@ -4378,6 +4843,7 @@ const NonEmpty = invariants.NonEmptyString, UnknownRecord = v__namespace.record(
|
|
|
4378
4843
|
description: v__namespace.optional(v__namespace.string()),
|
|
4379
4844
|
options: v__namespace.optional(PersistedChoiceOptionsSchema),
|
|
4380
4845
|
validation: v__namespace.optional(PersistedScalarValidationSchema),
|
|
4846
|
+
roles: v__namespace.optional(PersistedAssignmentRolesSchema),
|
|
4381
4847
|
fields: v__namespace.optional(v__namespace.array(PersistedFieldShapeSchema)),
|
|
4382
4848
|
of: v__namespace.optional(v__namespace.array(PersistedFieldShapeSchema))
|
|
4383
4849
|
}))), ExecutionContextSchema = invariants.tolerantObject()({
|
|
@@ -4423,7 +4889,13 @@ const OptionalRefTypes = v__namespace.exactOptional(v__namespace.array(v__namesp
|
|
|
4423
4889
|
})), v__namespace.looseObject(invariants.tolerantEntries()({
|
|
4424
4890
|
...fieldArm("subject", invariants.fieldValueSchemas.subject),
|
|
4425
4891
|
types: OptionalRefTypes
|
|
4426
|
-
})), 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()({
|
|
4427
4899
|
...fieldArm("object", v__namespace.union([ v__namespace.null(), UnknownRecord ])),
|
|
4428
4900
|
fields: v__namespace.array(PersistedFieldShapeSchema)
|
|
4429
4901
|
})), v__namespace.looseObject(invariants.tolerantEntries()({
|
|
@@ -4674,6 +5146,37 @@ function parseInstanceDocument(doc) {
|
|
|
4674
5146
|
});
|
|
4675
5147
|
}
|
|
4676
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
|
+
|
|
4677
5180
|
const SYNC_COMMIT = {
|
|
4678
5181
|
visibility: "sync"
|
|
4679
5182
|
}, ENGINE_API_VERSION = "2026-04-29", REQUEST_TAG = {
|
|
@@ -4709,7 +5212,9 @@ const SYNC_COMMIT = {
|
|
|
4709
5212
|
effect: "workflow.effect",
|
|
4710
5213
|
verifyDefinitions: "workflow.verify-definitions",
|
|
4711
5214
|
accessResolveActor: "workflow.access.resolve-actor",
|
|
4712
|
-
accessGrants: "workflow.access.grants"
|
|
5215
|
+
accessGrants: "workflow.access.grants",
|
|
5216
|
+
accessResolveOrg: "workflow.access.resolve-org",
|
|
5217
|
+
accessAttributes: "workflow.access.attributes"
|
|
4713
5218
|
}, RAW_PATCH = /* @__PURE__ */ Symbol("workflow-engine.raw-patch");
|
|
4714
5219
|
|
|
4715
5220
|
function unwrapPatch(patch) {
|
|
@@ -5119,6 +5624,40 @@ function readInstanceDoc(doc) {
|
|
|
5119
5624
|
return parseInstanceDocument(assertReadableModel(doc));
|
|
5120
5625
|
}
|
|
5121
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
|
+
|
|
5122
5661
|
async function reload({client: client, instanceId: instanceId, tag: tag}) {
|
|
5123
5662
|
const doc = await getInstanceDocument(client, instanceId);
|
|
5124
5663
|
if (!doc) throw new invariants.InstanceNotFoundError({
|
|
@@ -5365,7 +5904,8 @@ function loadCallContext({client: client, instanceId: instanceId, options: optio
|
|
|
5365
5904
|
} : {},
|
|
5366
5905
|
...options.telemetry ? {
|
|
5367
5906
|
telemetry: options.telemetry
|
|
5368
|
-
} : {}
|
|
5907
|
+
} : {},
|
|
5908
|
+
memberRolesLoader: options.memberRolesLoader
|
|
5369
5909
|
}
|
|
5370
5910
|
});
|
|
5371
5911
|
}
|
|
@@ -5410,6 +5950,7 @@ async function loadContext({client: client, instanceId: instanceId, options: opt
|
|
|
5410
5950
|
...options.telemetry !== void 0 ? {
|
|
5411
5951
|
telemetry: options.telemetry
|
|
5412
5952
|
} : {},
|
|
5953
|
+
memberRolesLoader: options.memberRolesLoader,
|
|
5413
5954
|
...options.overlay !== void 0 ? {
|
|
5414
5955
|
overlay: options.overlay
|
|
5415
5956
|
} : {},
|
|
@@ -5445,7 +5986,10 @@ async function ctxEvaluateCondition({ctx: ctx, condition: condition, opts: opts}
|
|
|
5445
5986
|
}
|
|
5446
5987
|
|
|
5447
5988
|
async function buildEngineContext(args) {
|
|
5448
|
-
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
|
+
});
|
|
5449
5993
|
return {
|
|
5450
5994
|
client: client,
|
|
5451
5995
|
clientForGdr: clientForGdr,
|
|
@@ -5462,6 +6006,10 @@ async function buildEngineContext(args) {
|
|
|
5462
6006
|
} : {},
|
|
5463
6007
|
instance: instance,
|
|
5464
6008
|
definition: definition,
|
|
6009
|
+
memberRolesLoader: memberRolesLoader,
|
|
6010
|
+
...memberRoles !== void 0 ? {
|
|
6011
|
+
memberRoles: memberRoles
|
|
6012
|
+
} : {},
|
|
5465
6013
|
snapshot: await hydrateSnapshot({
|
|
5466
6014
|
client: client,
|
|
5467
6015
|
clientForGdr: clientForGdr,
|
|
@@ -5473,6 +6021,62 @@ async function buildEngineContext(args) {
|
|
|
5473
6021
|
};
|
|
5474
6022
|
}
|
|
5475
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
|
+
|
|
5476
6080
|
function findStage(definition, stageName) {
|
|
5477
6081
|
const stage = definition.stages.find(s => s.name === stageName);
|
|
5478
6082
|
if (stage === void 0) throw new Error(`Stage "${stageName}" not found in definition ${definition.name}`);
|
|
@@ -5492,6 +6096,8 @@ async function resolveStageFieldEntries(args) {
|
|
|
5492
6096
|
tag: instance.tag,
|
|
5493
6097
|
stageName: stage.name,
|
|
5494
6098
|
workflowResource: instance.workflowResource,
|
|
6099
|
+
memberRoles: args.memberRoles,
|
|
6100
|
+
roleAliases: args.roleAliases,
|
|
5495
6101
|
workflowFields: instance.fields ?? [],
|
|
5496
6102
|
...instance.perspective !== void 0 ? {
|
|
5497
6103
|
perspective: instance.perspective
|
|
@@ -5518,6 +6124,8 @@ async function resolveActivityFieldEntries(args) {
|
|
|
5518
6124
|
stageName: stage.name,
|
|
5519
6125
|
workflowResource: instance.workflowResource,
|
|
5520
6126
|
activityName: activity.name,
|
|
6127
|
+
memberRoles: args.memberRoles,
|
|
6128
|
+
roleAliases: args.roleAliases,
|
|
5521
6129
|
workflowFields: instance.fields ?? [],
|
|
5522
6130
|
...instance.perspective !== void 0 ? {
|
|
5523
6131
|
perspective: instance.perspective
|
|
@@ -5673,172 +6281,7 @@ function resolveMetadata(metadata, ctx) {
|
|
|
5673
6281
|
return out;
|
|
5674
6282
|
}
|
|
5675
6283
|
|
|
5676
|
-
|
|
5677
|
-
return user?.provider ?? user?.loginProvider;
|
|
5678
|
-
}
|
|
5679
|
-
|
|
5680
|
-
function isRecord(value) {
|
|
5681
|
-
return typeof value == "object" && value !== null && !Array.isArray(value);
|
|
5682
|
-
}
|
|
5683
|
-
|
|
5684
|
-
function optionalString(value) {
|
|
5685
|
-
return value === void 0 || typeof value == "string";
|
|
5686
|
-
}
|
|
5687
|
-
|
|
5688
|
-
function isClientProjectUser(value) {
|
|
5689
|
-
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);
|
|
5690
|
-
}
|
|
5691
|
-
|
|
5692
|
-
function objectProperty(value, property) {
|
|
5693
|
-
if (!isRecord(value)) return;
|
|
5694
|
-
const propertyValue = value[property];
|
|
5695
|
-
return typeof propertyValue == "object" && propertyValue !== null ? propertyValue : void 0;
|
|
5696
|
-
}
|
|
5697
|
-
|
|
5698
|
-
function stringProperty(value, property) {
|
|
5699
|
-
const propertyValue = Reflect.get(value, property);
|
|
5700
|
-
return typeof propertyValue == "string" ? propertyValue : void 0;
|
|
5701
|
-
}
|
|
5702
|
-
|
|
5703
|
-
function apiErrorType(error) {
|
|
5704
|
-
const response = objectProperty(error, "response"), body = objectProperty(response, "body");
|
|
5705
|
-
if (!body) return;
|
|
5706
|
-
const nestedError = objectProperty(body, "error");
|
|
5707
|
-
return (nestedError ? stringProperty(nestedError, "type") : void 0) ?? stringProperty(body, "type");
|
|
5708
|
-
}
|
|
5709
|
-
|
|
5710
|
-
function isProjectUserNotFoundError(error) {
|
|
5711
|
-
return apiErrorType(error) === "projectUserNotFoundError";
|
|
5712
|
-
}
|
|
5713
|
-
|
|
5714
|
-
const memberJoinCache = /* @__PURE__ */ new WeakMap;
|
|
5715
|
-
|
|
5716
|
-
function joinCacheFor(client) {
|
|
5717
|
-
let cache = memberJoinCache.get(client);
|
|
5718
|
-
return cache === void 0 && (cache = /* @__PURE__ */ new Map, memberJoinCache.set(client, cache)),
|
|
5719
|
-
cache;
|
|
5720
|
-
}
|
|
5721
|
-
|
|
5722
|
-
async function projectMemberIds(request, projectId) {
|
|
5723
|
-
const project = await request({
|
|
5724
|
-
uri: `/projects/${encodeURIComponent(projectId)}`
|
|
5725
|
-
}), members = isRecord(project) ? project.members : void 0;
|
|
5726
|
-
return Array.isArray(members) ? members.map(member => isRecord(member) ? member.id : void 0).filter(id => typeof id == "string") : [];
|
|
5727
|
-
}
|
|
5728
|
-
|
|
5729
|
-
async function resolveGlobalProjectUser(args) {
|
|
5730
|
-
const {client: client, request: request, projectId: projectId, id: id} = args, cache = joinCacheFor(client), key = `${projectId}:${id}`, hit = cache.get(key);
|
|
5731
|
-
if (hit !== void 0) return hit === null ? {
|
|
5732
|
-
status: "missing"
|
|
5733
|
-
} : {
|
|
5734
|
-
status: "resolved",
|
|
5735
|
-
user: hit
|
|
5736
|
-
};
|
|
5737
|
-
try {
|
|
5738
|
-
await ingestMemberJoin({
|
|
5739
|
-
request: request,
|
|
5740
|
-
projectId: projectId,
|
|
5741
|
-
cache: cache
|
|
5742
|
-
});
|
|
5743
|
-
const found = cache.get(key);
|
|
5744
|
-
return found != null ? {
|
|
5745
|
-
status: "resolved",
|
|
5746
|
-
user: found
|
|
5747
|
-
} : (cache.set(key, null), {
|
|
5748
|
-
status: "missing"
|
|
5749
|
-
});
|
|
5750
|
-
} catch (cause) {
|
|
5751
|
-
return {
|
|
5752
|
-
status: "inaccessible",
|
|
5753
|
-
cause: cause
|
|
5754
|
-
};
|
|
5755
|
-
}
|
|
5756
|
-
}
|
|
5757
|
-
|
|
5758
|
-
async function ingestMemberJoin(args) {
|
|
5759
|
-
const {request: request, projectId: projectId, cache: cache} = args, memberIds = await projectMemberIds(request, projectId);
|
|
5760
|
-
if (memberIds.length === 0) return;
|
|
5761
|
-
const requested = new Set(memberIds), response = await request({
|
|
5762
|
-
uri: `/projects/${encodeURIComponent(projectId)}/users/${memberIds.map(encodeURIComponent).join(",")}`
|
|
5763
|
-
});
|
|
5764
|
-
for (const row of Array.isArray(response) ? response : [ response ]) {
|
|
5765
|
-
if (!isClientProjectUser(row) || !requested.has(row.id)) continue;
|
|
5766
|
-
const globalId = invariants.directoryBridgeId(row.sanityUserId);
|
|
5767
|
-
globalId !== void 0 && cache.set(`${projectId}:${globalId}`, row);
|
|
5768
|
-
}
|
|
5769
|
-
}
|
|
5770
|
-
|
|
5771
|
-
function clientProjectUserDirectory(client, projectId) {
|
|
5772
|
-
return {
|
|
5773
|
-
findById: async id => {
|
|
5774
|
-
if (!client.request) return {
|
|
5775
|
-
status: "inaccessible",
|
|
5776
|
-
cause: new Error("Project-user resolution requires WorkflowClient.request")
|
|
5777
|
-
};
|
|
5778
|
-
if (invariants.classifyPrincipalId(id).namespace === "global") return resolveGlobalProjectUser({
|
|
5779
|
-
client: client,
|
|
5780
|
-
request: client.request,
|
|
5781
|
-
projectId: projectId,
|
|
5782
|
-
id: id
|
|
5783
|
-
});
|
|
5784
|
-
try {
|
|
5785
|
-
const response = await client.request({
|
|
5786
|
-
uri: `/projects/${encodeURIComponent(projectId)}/users/${encodeURIComponent(id)}`
|
|
5787
|
-
}), candidate = Array.isArray(response) ? response[0] : response;
|
|
5788
|
-
return candidate == null ? {
|
|
5789
|
-
status: "missing"
|
|
5790
|
-
} : isClientProjectUser(candidate) ? candidate.id !== id ? {
|
|
5791
|
-
status: "inaccessible",
|
|
5792
|
-
cause: new Error(`Project-user response answered id "${candidate.id}", not the requested "${id}"`)
|
|
5793
|
-
} : {
|
|
5794
|
-
status: "resolved",
|
|
5795
|
-
user: candidate
|
|
5796
|
-
} : {
|
|
5797
|
-
status: "inaccessible",
|
|
5798
|
-
cause: new Error("Project-user response had an invalid shape")
|
|
5799
|
-
};
|
|
5800
|
-
} catch (cause) {
|
|
5801
|
-
return isProjectUserNotFoundError(cause) ? {
|
|
5802
|
-
status: "missing"
|
|
5803
|
-
} : {
|
|
5804
|
-
status: "inaccessible",
|
|
5805
|
-
cause: cause
|
|
5806
|
-
};
|
|
5807
|
-
}
|
|
5808
|
-
}
|
|
5809
|
-
};
|
|
5810
|
-
}
|
|
5811
|
-
|
|
5812
|
-
function resolveClientActor(client, args) {
|
|
5813
|
-
return resolveActor(clientProjectUserDirectory(client, args.projectId), args.actor);
|
|
5814
|
-
}
|
|
5815
|
-
|
|
5816
|
-
async function resolveActor(directory, actor) {
|
|
5817
|
-
if (actor.kind !== "person") return {
|
|
5818
|
-
status: "not-person",
|
|
5819
|
-
actor: actor
|
|
5820
|
-
};
|
|
5821
|
-
const personActor = {
|
|
5822
|
-
...actor,
|
|
5823
|
-
kind: "person"
|
|
5824
|
-
}, lookup = await directory.findById(personActor.id);
|
|
5825
|
-
return lookup.status === "resolved" ? {
|
|
5826
|
-
status: "resolved",
|
|
5827
|
-
actor: personActor,
|
|
5828
|
-
user: lookup.user
|
|
5829
|
-
} : lookup.status === "inaccessible" ? {
|
|
5830
|
-
status: "inaccessible",
|
|
5831
|
-
actor: personActor,
|
|
5832
|
-
...lookup.cause === void 0 ? {} : {
|
|
5833
|
-
cause: lookup.cause
|
|
5834
|
-
}
|
|
5835
|
-
} : {
|
|
5836
|
-
status: "missing",
|
|
5837
|
-
actor: personActor
|
|
5838
|
-
};
|
|
5839
|
-
}
|
|
5840
|
-
|
|
5841
|
-
const IDENTITY_KINDS = /* @__PURE__ */ new Set([ "actor", "assignee", "assignees" ]);
|
|
6284
|
+
const IDENTITY_KINDS = /* @__PURE__ */ new Set([ "actor", "assignee", "assignees" ]);
|
|
5842
6285
|
|
|
5843
6286
|
async function localizeGuardMetadata(args) {
|
|
5844
6287
|
const {doc: doc, guard: guard, client: client, instance: instance, definition: definition} = args;
|
|
@@ -6483,6 +6926,8 @@ async function buildActivityEntry({ctx: ctx, stage: stage, activity: activity, r
|
|
|
6483
6926
|
activity: activity,
|
|
6484
6927
|
now: ctx.now,
|
|
6485
6928
|
refSurface: ctx.refSurface,
|
|
6929
|
+
memberRoles: ctx.memberRoles,
|
|
6930
|
+
roleAliases: ctx.definition.roleAliases,
|
|
6486
6931
|
...recordDiscard !== void 0 ? {
|
|
6487
6932
|
recordDiscard: recordDiscard
|
|
6488
6933
|
} : {}
|
|
@@ -6685,7 +7130,8 @@ async function spawnRow({ctx: ctx, mutation: mutation, activity: activity, actio
|
|
|
6685
7130
|
context: context,
|
|
6686
7131
|
actor: actor,
|
|
6687
7132
|
now: now,
|
|
6688
|
-
refSurface: ctx.refSurface
|
|
7133
|
+
refSurface: ctx.refSurface,
|
|
7134
|
+
memberRolesLoader: ctx.memberRolesLoader
|
|
6689
7135
|
});
|
|
6690
7136
|
mutation.pendingCreates.push({
|
|
6691
7137
|
body: body,
|
|
@@ -6908,13 +7354,16 @@ async function resolveDefinitionRef({client: client, ref: ref, tag: tag}) {
|
|
|
6908
7354
|
}
|
|
6909
7355
|
|
|
6910
7356
|
async function prepareChildInstance(args) {
|
|
6911
|
-
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 = {
|
|
6912
7358
|
id: invariants.gdrFromResource(workflowResource, childDocId),
|
|
6913
7359
|
type: WORKFLOW_INSTANCE_TYPE
|
|
6914
7360
|
}, ancestors = [ ...parent.ancestors, {
|
|
6915
7361
|
id: invariants.selfGdr(parent),
|
|
6916
7362
|
type: WORKFLOW_INSTANCE_TYPE
|
|
6917
|
-
} ], inheritedPerspective = parent.perspective, fieldDiscards = [],
|
|
7363
|
+
} ], inheritedPerspective = parent.perspective, fieldDiscards = [], memberRoles = await memberRolesLoader({
|
|
7364
|
+
workflowResource: workflowResource,
|
|
7365
|
+
definition: definition
|
|
7366
|
+
}), childFields = await resolveDeclaredFields({
|
|
6918
7367
|
entryDefs: definition.fields,
|
|
6919
7368
|
initialFields: initialFields,
|
|
6920
7369
|
ctx: {
|
|
@@ -6925,6 +7374,8 @@ async function prepareChildInstance(args) {
|
|
|
6925
7374
|
workflowResource: workflowResource,
|
|
6926
7375
|
definitionName: definition.name,
|
|
6927
7376
|
refSurface: refSurface,
|
|
7377
|
+
memberRoles: memberRoles,
|
|
7378
|
+
roleAliases: definition.roleAliases,
|
|
6928
7379
|
inputProvenance: "definition",
|
|
6929
7380
|
...inheritedPerspective !== void 0 ? {
|
|
6930
7381
|
perspective: inheritedPerspective
|
|
@@ -6995,6 +7446,8 @@ async function enterStage({ctx: ctx, mutation: mutation, nextStage: nextStage, a
|
|
|
6995
7446
|
stage: nextStage,
|
|
6996
7447
|
now: at,
|
|
6997
7448
|
refSurface: ctx.refSurface,
|
|
7449
|
+
memberRoles: ctx.memberRoles,
|
|
7450
|
+
roleAliases: ctx.definition.roleAliases,
|
|
6998
7451
|
recordDiscard: recordFieldDiscards({
|
|
6999
7452
|
target: mutation.history,
|
|
7000
7453
|
scope: "stage",
|
|
@@ -7180,42 +7633,449 @@ function aclPathForResource(res) {
|
|
|
7180
7633
|
const {projectId: projectId, dataset: dataset} = invariants.datasetResourceParts(res.id);
|
|
7181
7634
|
return `/projects/${projectId}/datasets/${dataset}/acl`;
|
|
7182
7635
|
}
|
|
7183
|
-
if (res.type === "canvas") return `/canvases/${res.id}/acl`;
|
|
7636
|
+
if (res.type === "canvas") return `/canvases/${res.id}/acl`;
|
|
7637
|
+
}
|
|
7638
|
+
|
|
7639
|
+
async function fetchGrants(args) {
|
|
7640
|
+
const {client: client, resourcePath: resourcePath, signal: signal} = args;
|
|
7641
|
+
return client.request({
|
|
7642
|
+
url: resourcePath,
|
|
7643
|
+
tag: REQUEST_TAG.accessGrants,
|
|
7644
|
+
...signal ? {
|
|
7645
|
+
signal: signal
|
|
7646
|
+
} : {}
|
|
7647
|
+
});
|
|
7648
|
+
}
|
|
7649
|
+
|
|
7650
|
+
async function advisoryCanForCall(args) {
|
|
7651
|
+
const actor = args.options?.actor;
|
|
7652
|
+
if (!(args.options?.grants === void 0 || actor === void 0)) return advisoryCan({
|
|
7653
|
+
instance: args.instance,
|
|
7654
|
+
identity: invariants.lakePrincipalId({
|
|
7655
|
+
actor: actor,
|
|
7656
|
+
localPrincipalId: args.options.localPrincipalId
|
|
7657
|
+
}),
|
|
7658
|
+
grants: args.options.grants
|
|
7659
|
+
});
|
|
7660
|
+
}
|
|
7661
|
+
|
|
7662
|
+
async function advisoryCan({instance: instance, identity: identity, grants: grants}) {
|
|
7663
|
+
if (grants === void 0) return;
|
|
7664
|
+
const can = {};
|
|
7665
|
+
for (const permission of invariants.DOCUMENT_VALUE_PERMISSIONS) can[permission] = await grantsPermissionOn({
|
|
7666
|
+
document: instance,
|
|
7667
|
+
grants: grants,
|
|
7668
|
+
permission: permission,
|
|
7669
|
+
userId: identity
|
|
7670
|
+
});
|
|
7671
|
+
return can;
|
|
7672
|
+
}
|
|
7673
|
+
|
|
7674
|
+
const DANGEROUS_ATTRIBUTE_KEYS = /* @__PURE__ */ new Set([ "__proto__", "constructor", "prototype" ]);
|
|
7675
|
+
|
|
7676
|
+
function attributeEntry(row) {
|
|
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 ];
|
|
7678
|
+
}
|
|
7679
|
+
|
|
7680
|
+
function normalizeUserAttributes(response) {
|
|
7681
|
+
if (!invariants.isRecord(response)) return;
|
|
7682
|
+
const rows = response.attributes;
|
|
7683
|
+
if (!Array.isArray(rows)) return;
|
|
7684
|
+
const out = {};
|
|
7685
|
+
for (const row of rows) {
|
|
7686
|
+
const entry = attributeEntry(row);
|
|
7687
|
+
entry !== void 0 && (out[entry[0]] = entry[1]);
|
|
7688
|
+
}
|
|
7689
|
+
return out;
|
|
7690
|
+
}
|
|
7691
|
+
|
|
7692
|
+
const actorCache = /* @__PURE__ */ new WeakMap, grantsCache = /* @__PURE__ */ new WeakMap, orgIdCache = /* @__PURE__ */ new WeakMap, attributesCache = /* @__PURE__ */ new WeakMap;
|
|
7693
|
+
|
|
7694
|
+
async function resolveAccess(taggedClient, args = {}) {
|
|
7695
|
+
const client = unwrapRequestTag(taggedClient), requestFn = lazyRequest(client);
|
|
7696
|
+
if (requestFn === void 0) throw new invariants.ContractViolationError("workflow: no actor available. The engine resolves the actor from the client's token via `client.request({ uri: '/users/me' })`. Supply a real `@sanity/client` configured with a token (the test bench serves these endpoints per registered token).");
|
|
7697
|
+
const grantsPromise = args.grantsFromPath !== void 0 ? cachedGrants({
|
|
7698
|
+
client: client,
|
|
7699
|
+
requestFn: requestFn,
|
|
7700
|
+
resourcePath: args.grantsFromPath
|
|
7701
|
+
}) : Promise.resolve(void 0), [identity, grants] = await Promise.all([ cachedActor(client, requestFn), grantsPromise ]);
|
|
7702
|
+
if (identity === void 0) throw new invariants.ContractViolationError("workflow: failed to resolve actor from `/users/me`. The client is configured but the endpoint returned no usable identity — check the token.");
|
|
7703
|
+
return {
|
|
7704
|
+
actor: identity.actor,
|
|
7705
|
+
...identity.localPrincipalId !== void 0 ? {
|
|
7706
|
+
localPrincipalId: identity.localPrincipalId
|
|
7707
|
+
} : {},
|
|
7708
|
+
...grants !== void 0 ? {
|
|
7709
|
+
grants: grants
|
|
7710
|
+
} : {}
|
|
7711
|
+
};
|
|
7712
|
+
}
|
|
7713
|
+
|
|
7714
|
+
async function resolveUserAttributes(taggedClient) {
|
|
7715
|
+
const client = unwrapRequestTag(taggedClient), requestFn = lazyRequest(client);
|
|
7716
|
+
if (requestFn !== void 0) return cachedAttributes({
|
|
7717
|
+
client: client,
|
|
7718
|
+
requestFn: requestFn
|
|
7719
|
+
});
|
|
7720
|
+
}
|
|
7721
|
+
|
|
7722
|
+
function cachedActor(client, requestFn) {
|
|
7723
|
+
const cached = actorCache.get(client);
|
|
7724
|
+
if (cached !== void 0) return cached;
|
|
7725
|
+
const pending = fetchActor(client, requestFn).catch(err => {
|
|
7726
|
+
throw actorCache.get(client) === pending && actorCache.delete(client), err;
|
|
7727
|
+
});
|
|
7728
|
+
return actorCache.set(client, pending), pending;
|
|
7729
|
+
}
|
|
7730
|
+
|
|
7731
|
+
function grantsForClientPath(taggedClient, resourcePath) {
|
|
7732
|
+
const client = unwrapRequestTag(taggedClient), requestFn = lazyRequest(client);
|
|
7733
|
+
return requestFn === void 0 ? Promise.resolve(void 0) : cachedGrants({
|
|
7734
|
+
client: client,
|
|
7735
|
+
requestFn: requestFn,
|
|
7736
|
+
resourcePath: resourcePath
|
|
7737
|
+
});
|
|
7738
|
+
}
|
|
7739
|
+
|
|
7740
|
+
function lazyRequest(client) {
|
|
7741
|
+
return client.request === void 0 ? void 0 : opts => client.request(opts);
|
|
7742
|
+
}
|
|
7743
|
+
|
|
7744
|
+
function cachedGrants({client: client, requestFn: requestFn, resourcePath: resourcePath}) {
|
|
7745
|
+
return cachedByKey({
|
|
7746
|
+
store: grantsCache,
|
|
7747
|
+
client: client,
|
|
7748
|
+
key: resourcePath,
|
|
7749
|
+
load: () => fetchGrantsCached(requestFn, resourcePath)
|
|
7750
|
+
});
|
|
7751
|
+
}
|
|
7752
|
+
|
|
7753
|
+
function cachedByKey(args) {
|
|
7754
|
+
let byKey = args.store.get(args.client);
|
|
7755
|
+
byKey === void 0 && (byKey = /* @__PURE__ */ new Map, args.store.set(args.client, byKey));
|
|
7756
|
+
const cached = byKey.get(args.key);
|
|
7757
|
+
if (cached !== void 0) return cached;
|
|
7758
|
+
const pending = args.evictOnRejection ? args.load().catch(err => {
|
|
7759
|
+
throw byKey.get(args.key) === pending && byKey.delete(args.key), err;
|
|
7760
|
+
}) : args.load();
|
|
7761
|
+
return byKey.set(args.key, pending), pending;
|
|
7762
|
+
}
|
|
7763
|
+
|
|
7764
|
+
async function fetchActor(client, requestFn) {
|
|
7765
|
+
const [resourceUser, globalUser] = await Promise.all([ fetchCurrentUser(requestFn, "the workflow resource host"), fetchGlobalUser(client) ]), resourceId = usableId(resourceUser), globalHostId = usableId(globalUser.user), carriedId = invariants.firstCarriedGlobalId([ globalHostId, resourceId ]), sessionId = carriedId ?? globalHostId ?? resourceId;
|
|
7766
|
+
if (sessionId === void 0) return;
|
|
7767
|
+
const bridge = carriedId === void 0 ? await bridgeProjectPrincipal({
|
|
7768
|
+
client: client,
|
|
7769
|
+
sessionId: sessionId,
|
|
7770
|
+
resourceId: resourceId
|
|
7771
|
+
}) : NO_BRIDGE, id = bridge.status === "resolved" ? bridge.globalId : sessionId;
|
|
7772
|
+
refuseProjectScopedActor({
|
|
7773
|
+
id: id,
|
|
7774
|
+
globalUser: globalUser,
|
|
7775
|
+
globalHostId: globalHostId,
|
|
7776
|
+
bridgeFailure: bridge.status === "unavailable" ? bridge : void 0
|
|
7777
|
+
});
|
|
7778
|
+
const roleNames = roleNamesFor(resourceUser, globalUser);
|
|
7779
|
+
return {
|
|
7780
|
+
actor: {
|
|
7781
|
+
kind: "person",
|
|
7782
|
+
id: id,
|
|
7783
|
+
...roleNames.length > 0 ? {
|
|
7784
|
+
roles: roleNames
|
|
7785
|
+
} : {}
|
|
7786
|
+
},
|
|
7787
|
+
...resourceId !== void 0 && resourceId !== id ? {
|
|
7788
|
+
localPrincipalId: resourceId
|
|
7789
|
+
} : {}
|
|
7790
|
+
};
|
|
7791
|
+
}
|
|
7792
|
+
|
|
7793
|
+
function roleNamesFor(resourceUser, globalUser) {
|
|
7794
|
+
return (resourceUser?.roles?.length ? resourceUser : globalUser.user)?.roles?.map(r => r.name).filter(n => !!n) ?? [];
|
|
7795
|
+
}
|
|
7796
|
+
|
|
7797
|
+
const NO_BRIDGE = {
|
|
7798
|
+
status: "not-applicable"
|
|
7799
|
+
};
|
|
7800
|
+
|
|
7801
|
+
function globalRouteReason(globalUser, globalHostId) {
|
|
7802
|
+
return "reason" in globalUser ? globalUser.reason : globalHostId === void 0 ? "no record" : `the global host answered with project-scoped principal "${globalHostId}"`;
|
|
7803
|
+
}
|
|
7804
|
+
|
|
7805
|
+
async function bridgeProjectPrincipal(args) {
|
|
7806
|
+
const {client: client, sessionId: sessionId, resourceId: resourceId} = args;
|
|
7807
|
+
return invariants.classifyPrincipalId(sessionId).namespace !== "project" ? NO_BRIDGE : resourceId === void 0 || invariants.classifyPrincipalId(resourceId).namespace !== "project" ? {
|
|
7808
|
+
status: "unavailable",
|
|
7809
|
+
reason: "no project-scoped principal from the resource host to address the directory with"
|
|
7810
|
+
} : directoryGlobalId({
|
|
7811
|
+
client: client,
|
|
7812
|
+
principalId: resourceId
|
|
7813
|
+
});
|
|
7814
|
+
}
|
|
7815
|
+
|
|
7816
|
+
async function directoryGlobalId(args) {
|
|
7817
|
+
const {client: client, principalId: principalId} = args, projectId = projectIdOf(client);
|
|
7818
|
+
if (projectId === void 0) return {
|
|
7819
|
+
status: "unavailable",
|
|
7820
|
+
reason: "the client reports no projectId, so its user directory has no address"
|
|
7821
|
+
};
|
|
7822
|
+
const lookup = await clientProjectUserDirectory(withRequestTag(client, REQUEST_TAG.accessResolveActor), projectId).findById(principalId);
|
|
7823
|
+
if (lookup.status !== "resolved") return {
|
|
7824
|
+
status: "unavailable",
|
|
7825
|
+
reason: `project "${projectId}"'s user directory reported the principal ${lookup.status}`,
|
|
7826
|
+
...lookup.status === "inaccessible" && lookup.cause !== void 0 ? {
|
|
7827
|
+
cause: lookup.cause
|
|
7828
|
+
} : {}
|
|
7829
|
+
};
|
|
7830
|
+
const globalId = invariants.directoryBridgeId(lookup.user.sanityUserId);
|
|
7831
|
+
return globalId === void 0 ? {
|
|
7832
|
+
status: "unavailable",
|
|
7833
|
+
reason: `project "${projectId}"'s user directory row for the principal carries no account-global sanityUserId`
|
|
7834
|
+
} : {
|
|
7835
|
+
status: "resolved",
|
|
7836
|
+
globalId: globalId
|
|
7837
|
+
};
|
|
7838
|
+
}
|
|
7839
|
+
|
|
7840
|
+
function refuseProjectScopedActor(args) {
|
|
7841
|
+
const {id: id, globalUser: globalUser, globalHostId: globalHostId, bridgeFailure: bridgeFailure} = args;
|
|
7842
|
+
if (invariants.classifyPrincipalId(id).namespace !== "project") return;
|
|
7843
|
+
const routes = [ `The account-global record: ${globalRouteReason(globalUser, globalHostId)}.` ];
|
|
7844
|
+
bridgeFailure !== void 0 && routes.push(`The project user directory: ${bridgeFailure.reason}.`);
|
|
7845
|
+
const cause = bridgeFailure?.cause ?? ("cause" in globalUser ? globalUser.cause : void 0);
|
|
7846
|
+
throw new Error(`workflow: the caller's identity resolves to the project-scoped principal "${id}" and its account-global id could not be resolved. ${routes.join(" ")} The engine speaks account-global user ids only and never acts as a project-scoped principal.`, cause === void 0 ? void 0 : {
|
|
7847
|
+
cause: cause
|
|
7848
|
+
});
|
|
7849
|
+
}
|
|
7850
|
+
|
|
7851
|
+
function usableId(user) {
|
|
7852
|
+
if (!(!user || typeof user.id != "string" || user.id.length === 0)) return user.id;
|
|
7853
|
+
}
|
|
7854
|
+
|
|
7855
|
+
async function fetchCurrentUser(requestFn, hostDescription) {
|
|
7856
|
+
try {
|
|
7857
|
+
return await requestFn({
|
|
7858
|
+
uri: "/users/me",
|
|
7859
|
+
tag: REQUEST_TAG.accessResolveActor
|
|
7860
|
+
});
|
|
7861
|
+
} catch (err) {
|
|
7862
|
+
throw new Error(`workflow: /users/me request against ${hostDescription} failed. The engine resolves the actor from the client's token via \`client.request({ uri: '/users/me' })\`. Check the token/connectivity.`, {
|
|
7863
|
+
cause: err
|
|
7864
|
+
});
|
|
7865
|
+
}
|
|
7866
|
+
}
|
|
7867
|
+
|
|
7868
|
+
async function fetchGlobalUser(client) {
|
|
7869
|
+
const sibling = globalHostRequestOf(client);
|
|
7870
|
+
if ("reason" in sibling) return {
|
|
7871
|
+
user: void 0,
|
|
7872
|
+
reason: sibling.reason,
|
|
7873
|
+
...sibling.cause !== void 0 ? {
|
|
7874
|
+
cause: sibling.cause
|
|
7875
|
+
} : {}
|
|
7876
|
+
};
|
|
7877
|
+
try {
|
|
7878
|
+
const user = await sibling.request({
|
|
7879
|
+
uri: "/users/me",
|
|
7880
|
+
tag: REQUEST_TAG.accessResolveActor
|
|
7881
|
+
}), id = usableId(user);
|
|
7882
|
+
return sibling.requireGlobalPrincipal && id !== void 0 && invariants.classifyPrincipalId(id).namespace === "project" ? {
|
|
7883
|
+
user: void 0,
|
|
7884
|
+
reason: `global-host /users/me returned project-scoped principal "${id}"; the sibling client is still bound to a project API host`
|
|
7885
|
+
} : {
|
|
7886
|
+
user: user
|
|
7887
|
+
};
|
|
7888
|
+
} catch (err) {
|
|
7889
|
+
return {
|
|
7890
|
+
user: void 0,
|
|
7891
|
+
reason: `global-host /users/me failed: ${invariants.errorMessage(err)}`,
|
|
7892
|
+
cause: err
|
|
7893
|
+
};
|
|
7894
|
+
}
|
|
7895
|
+
}
|
|
7896
|
+
|
|
7897
|
+
function globalHostRequestOf(client) {
|
|
7898
|
+
if (typeof client.withConfig != "function") return {
|
|
7899
|
+
reason: "the client cannot reach the global API host (no withConfig)"
|
|
7900
|
+
};
|
|
7901
|
+
const hostResolution = resolveGlobalApiHost(client);
|
|
7902
|
+
try {
|
|
7903
|
+
const globalClient = client.withConfig({
|
|
7904
|
+
useProjectHostname: !1,
|
|
7905
|
+
apiVersion: ENGINE_API_VERSION,
|
|
7906
|
+
...hostResolution.apiHost === void 0 ? {} : {
|
|
7907
|
+
apiHost: hostResolution.apiHost
|
|
7908
|
+
}
|
|
7909
|
+
}), request = lazyRequest(globalClient);
|
|
7910
|
+
return request === void 0 ? {
|
|
7911
|
+
reason: "the global-host sibling client cannot issue requests"
|
|
7912
|
+
} : {
|
|
7913
|
+
request: request,
|
|
7914
|
+
requireGlobalPrincipal: hostResolution.requireGlobalPrincipal
|
|
7915
|
+
};
|
|
7916
|
+
} catch (err) {
|
|
7917
|
+
return {
|
|
7918
|
+
reason: `building the global-host sibling client failed: ${invariants.errorMessage(err)}`,
|
|
7919
|
+
cause: err
|
|
7920
|
+
};
|
|
7921
|
+
}
|
|
7922
|
+
}
|
|
7923
|
+
|
|
7924
|
+
function resolveGlobalApiHost(client) {
|
|
7925
|
+
if (typeof client.config != "function") return {
|
|
7926
|
+
requireGlobalPrincipal: !1
|
|
7927
|
+
};
|
|
7928
|
+
const apiHost = client.config().apiHost;
|
|
7929
|
+
if (apiHost === void 0) return {
|
|
7930
|
+
requireGlobalPrincipal: !1
|
|
7931
|
+
};
|
|
7932
|
+
let parsed;
|
|
7933
|
+
try {
|
|
7934
|
+
parsed = new URL(apiHost);
|
|
7935
|
+
} catch {
|
|
7936
|
+
return {
|
|
7937
|
+
requireGlobalPrincipal: !0
|
|
7938
|
+
};
|
|
7939
|
+
}
|
|
7940
|
+
if (/^api\.sanity\.(io|work)$/.test(parsed.hostname)) return {
|
|
7941
|
+
requireGlobalPrincipal: !1
|
|
7942
|
+
};
|
|
7943
|
+
const match = /^[^.]+\.api\.sanity\.(io|work)$/.exec(parsed.hostname);
|
|
7944
|
+
return match === null ? {
|
|
7945
|
+
requireGlobalPrincipal: !0
|
|
7946
|
+
} : (parsed.hostname = `api.sanity.${match[1]}`, {
|
|
7947
|
+
apiHost: parsed.origin,
|
|
7948
|
+
requireGlobalPrincipal: !0
|
|
7949
|
+
});
|
|
7950
|
+
}
|
|
7951
|
+
|
|
7952
|
+
async function fetchGrantsCached(requestFn, resourcePath) {
|
|
7953
|
+
try {
|
|
7954
|
+
return await fetchGrants({
|
|
7955
|
+
client: {
|
|
7956
|
+
request: requestFn
|
|
7957
|
+
},
|
|
7958
|
+
resourcePath: resourcePath
|
|
7959
|
+
});
|
|
7960
|
+
} catch (err) {
|
|
7961
|
+
console.warn(`workflow: failed to fetch grants from "${resourcePath}"; advisory permission reads that depend on them are skipped — a rendered $can stays undefined (conditions referencing it fail closed) and the subject-write forecast omits this resource. The lake still enforces writes. Original error: ${invariants.errorMessage(err)}`);
|
|
7962
|
+
return;
|
|
7963
|
+
}
|
|
7964
|
+
}
|
|
7965
|
+
|
|
7966
|
+
function projectIdOf(client) {
|
|
7967
|
+
if (typeof client.config != "function") return;
|
|
7968
|
+
const projectId = client.config().projectId;
|
|
7969
|
+
return typeof projectId == "string" && projectId.length > 0 ? projectId : void 0;
|
|
7970
|
+
}
|
|
7971
|
+
|
|
7972
|
+
function cachedAttributes(args) {
|
|
7973
|
+
const projectId = projectIdOf(args.client);
|
|
7974
|
+
return projectId === void 0 ? Promise.resolve(void 0) : resolveOrganizationId({
|
|
7975
|
+
client: args.client,
|
|
7976
|
+
requestFn: args.requestFn,
|
|
7977
|
+
projectId: projectId
|
|
7978
|
+
}).then(orgId => {
|
|
7979
|
+
if (orgId !== void 0) return cachedByKey({
|
|
7980
|
+
store: attributesCache,
|
|
7981
|
+
client: args.client,
|
|
7982
|
+
key: orgId,
|
|
7983
|
+
evictOnRejection: !0,
|
|
7984
|
+
load: () => fetchAttributesCached({
|
|
7985
|
+
client: args.client,
|
|
7986
|
+
orgId: orgId
|
|
7987
|
+
})
|
|
7988
|
+
});
|
|
7989
|
+
});
|
|
7990
|
+
}
|
|
7991
|
+
|
|
7992
|
+
async function resolveOrganizationId(args) {
|
|
7993
|
+
const {client: client, requestFn: requestFn, projectId: projectId} = args;
|
|
7994
|
+
return cachedByKey({
|
|
7995
|
+
store: orgIdCache,
|
|
7996
|
+
client: client,
|
|
7997
|
+
key: projectId,
|
|
7998
|
+
evictOnRejection: !0,
|
|
7999
|
+
load: async () => {
|
|
8000
|
+
try {
|
|
8001
|
+
const project = await requestFn({
|
|
8002
|
+
uri: `/projects/${encodeURIComponent(projectId)}`,
|
|
8003
|
+
tag: REQUEST_TAG.accessResolveOrg
|
|
8004
|
+
});
|
|
8005
|
+
if (!invariants.isRecord(project)) return;
|
|
8006
|
+
const orgId = project.organizationId;
|
|
8007
|
+
return typeof orgId == "string" && orgId.length > 0 ? orgId : void 0;
|
|
8008
|
+
} catch (err) {
|
|
8009
|
+
const status = httpStatusOf(err);
|
|
8010
|
+
if (status !== void 0 && EXPECTED_ATTRIBUTES_ABSENCE.has(status)) return;
|
|
8011
|
+
throw new Error(`workflow: failed to resolve organizationId for project "${projectId}"; advisory $attributes cannot be bound. Original error: ${invariants.errorMessage(err)}`, {
|
|
8012
|
+
cause: err
|
|
8013
|
+
});
|
|
8014
|
+
}
|
|
8015
|
+
}
|
|
8016
|
+
});
|
|
8017
|
+
}
|
|
8018
|
+
|
|
8019
|
+
const ATTRIBUTES_FETCH_LIMIT = 100, EXPECTED_ATTRIBUTES_ABSENCE = /* @__PURE__ */ new Set([ 401, 402, 403, 404 ]);
|
|
8020
|
+
|
|
8021
|
+
function httpStatusOf(err) {
|
|
8022
|
+
if (!invariants.isRecord(err)) return;
|
|
8023
|
+
const status = err.statusCode;
|
|
8024
|
+
return typeof status == "number" ? status : void 0;
|
|
8025
|
+
}
|
|
8026
|
+
|
|
8027
|
+
async function fetchAttributesCached(args) {
|
|
8028
|
+
const {client: client, orgId: orgId} = args, sibling = globalHostRequestOf(client);
|
|
8029
|
+
if ("reason" in sibling) {
|
|
8030
|
+
console.warn(`workflow: skipped org attributes fetch (${sibling.reason}); advisory $attributes stays undefined (conditions referencing it fail closed).`);
|
|
8031
|
+
return;
|
|
8032
|
+
}
|
|
8033
|
+
try {
|
|
8034
|
+
const response = await sibling.request({
|
|
8035
|
+
uri: `/organizations/${encodeURIComponent(orgId)}/users/me/attributes?limit=${ATTRIBUTES_FETCH_LIMIT}`,
|
|
8036
|
+
tag: REQUEST_TAG.accessAttributes
|
|
8037
|
+
}), envelope = invariants.isRecord(response) ? response : void 0;
|
|
8038
|
+
if (envelope?.hasMore === !0) {
|
|
8039
|
+
const page = Array.isArray(envelope.attributes) ? envelope.attributes : [];
|
|
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.`);
|
|
8041
|
+
}
|
|
8042
|
+
const normalized = normalizeUserAttributes(response);
|
|
8043
|
+
return normalized === void 0 && console.warn(`workflow: org attributes response for organization "${orgId}" was unusable; advisory $attributes stays undefined (conditions referencing it fail closed).`),
|
|
8044
|
+
normalized;
|
|
8045
|
+
} catch (err) {
|
|
8046
|
+
const status = httpStatusOf(err);
|
|
8047
|
+
if (status !== void 0 && EXPECTED_ATTRIBUTES_ABSENCE.has(status)) return;
|
|
8048
|
+
throw new Error(`workflow: failed to fetch org attributes for organization "${orgId}". Original error: ${invariants.errorMessage(err)}`, {
|
|
8049
|
+
cause: err
|
|
8050
|
+
});
|
|
8051
|
+
}
|
|
7184
8052
|
}
|
|
7185
8053
|
|
|
7186
|
-
|
|
7187
|
-
const
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
|
|
7191
|
-
...
|
|
7192
|
-
|
|
8054
|
+
function callerBoundVars(args) {
|
|
8055
|
+
const vars = {
|
|
8056
|
+
...args.can !== void 0 ? {
|
|
8057
|
+
can: args.can
|
|
8058
|
+
} : {},
|
|
8059
|
+
...args.attributes !== void 0 ? {
|
|
8060
|
+
attributes: args.attributes
|
|
7193
8061
|
} : {}
|
|
7194
|
-
}
|
|
8062
|
+
};
|
|
8063
|
+
return Object.keys(vars).length > 0 ? vars : void 0;
|
|
7195
8064
|
}
|
|
7196
8065
|
|
|
7197
|
-
async function
|
|
7198
|
-
const
|
|
7199
|
-
if (!(args.options?.grants === void 0 || actor === void 0)) return advisoryCan({
|
|
8066
|
+
async function callerBoundVarsForCall(args) {
|
|
8067
|
+
const can = await advisoryCanForCall({
|
|
7200
8068
|
instance: args.instance,
|
|
7201
|
-
|
|
7202
|
-
|
|
7203
|
-
|
|
7204
|
-
|
|
7205
|
-
|
|
7206
|
-
|
|
7207
|
-
|
|
7208
|
-
|
|
7209
|
-
|
|
7210
|
-
if (grants === void 0) return;
|
|
7211
|
-
const can = {};
|
|
7212
|
-
for (const permission of invariants.DOCUMENT_VALUE_PERMISSIONS) can[permission] = await grantsPermissionOn({
|
|
7213
|
-
document: instance,
|
|
7214
|
-
grants: grants,
|
|
7215
|
-
permission: permission,
|
|
7216
|
-
userId: identity
|
|
8069
|
+
options: args.options
|
|
8070
|
+
}), attributes = args.options?.attributes !== void 0 ? args.options.attributes : await resolveUserAttributes(args.client);
|
|
8071
|
+
return callerBoundVars({
|
|
8072
|
+
...can !== void 0 ? {
|
|
8073
|
+
can: can
|
|
8074
|
+
} : {},
|
|
8075
|
+
...attributes !== void 0 ? {
|
|
8076
|
+
attributes: attributes
|
|
8077
|
+
} : {}
|
|
7217
8078
|
});
|
|
7218
|
-
return can;
|
|
7219
8079
|
}
|
|
7220
8080
|
|
|
7221
8081
|
function requirementDescriptor(requirement) {
|
|
@@ -7338,7 +8198,8 @@ async function resolveActionCommit({ctx: ctx, activityName: activityName, action
|
|
|
7338
8198
|
}
|
|
7339
8199
|
});
|
|
7340
8200
|
if (action.filter !== void 0) {
|
|
7341
|
-
const
|
|
8201
|
+
const vars = await callerBoundVarsForCall({
|
|
8202
|
+
client: ctx.client,
|
|
7342
8203
|
instance: ctx.instance,
|
|
7343
8204
|
options: options
|
|
7344
8205
|
});
|
|
@@ -7350,10 +8211,8 @@ async function resolveActionCommit({ctx: ctx, activityName: activityName, action
|
|
|
7350
8211
|
...actor !== void 0 ? {
|
|
7351
8212
|
actor: actor
|
|
7352
8213
|
} : {},
|
|
7353
|
-
...
|
|
7354
|
-
vars:
|
|
7355
|
-
can: can
|
|
7356
|
-
}
|
|
8214
|
+
...vars !== void 0 ? {
|
|
8215
|
+
vars: vars
|
|
7357
8216
|
} : {}
|
|
7358
8217
|
}
|
|
7359
8218
|
})) throw new ActionDisabledError({
|
|
@@ -7426,7 +8285,9 @@ async function applyActionFire({ctx: ctx, mutation: mutation, activity: activity
|
|
|
7426
8285
|
self: invariants.selfGdr(ctx.instance),
|
|
7427
8286
|
now: ctx.now,
|
|
7428
8287
|
snapshot: ctx.snapshot,
|
|
7429
|
-
refSurface: ctx.refSurface
|
|
8288
|
+
refSurface: ctx.refSurface,
|
|
8289
|
+
memberRoles: ctx.memberRoles,
|
|
8290
|
+
roleAliases: ctx.definition.roleAliases
|
|
7430
8291
|
});
|
|
7431
8292
|
if (await queueEffects({
|
|
7432
8293
|
ctx: ctx,
|
|
@@ -7609,6 +8470,8 @@ async function primeInitialStage(args) {
|
|
|
7609
8470
|
stage: stage,
|
|
7610
8471
|
now: now,
|
|
7611
8472
|
refSurface: refSurface,
|
|
8473
|
+
memberRoles: ctx.memberRoles,
|
|
8474
|
+
roleAliases: ctx.definition.roleAliases,
|
|
7612
8475
|
recordDiscard: recordFieldDiscards({
|
|
7613
8476
|
target: discards,
|
|
7614
8477
|
scope: "stage",
|
|
@@ -7668,7 +8531,7 @@ async function primeInitialStage(args) {
|
|
|
7668
8531
|
|
|
7669
8532
|
const CASCADE_LIMIT = 100;
|
|
7670
8533
|
|
|
7671
|
-
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}) {
|
|
7672
8535
|
const contextOptions = {
|
|
7673
8536
|
clientForGdr: clientForGdr,
|
|
7674
8537
|
refSurface: refSurface,
|
|
@@ -7689,7 +8552,8 @@ async function runCascadeHop({client: client, instanceId: instanceId, actor: act
|
|
|
7689
8552
|
} : {},
|
|
7690
8553
|
...settlingCohorts ? {
|
|
7691
8554
|
settlingCohorts: settlingCohorts
|
|
7692
|
-
} : {}
|
|
8555
|
+
} : {},
|
|
8556
|
+
memberRolesLoader: memberRolesLoader
|
|
7693
8557
|
}, ctx = instance === void 0 ? await loadContext({
|
|
7694
8558
|
client: client,
|
|
7695
8559
|
instanceId: instanceId,
|
|
@@ -7728,7 +8592,7 @@ async function runCascadeHop({client: client, instanceId: instanceId, actor: act
|
|
|
7728
8592
|
});
|
|
7729
8593
|
}
|
|
7730
8594
|
|
|
7731
|
-
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}) {
|
|
7732
8596
|
let count = 0;
|
|
7733
8597
|
for (;;) {
|
|
7734
8598
|
const drained = await drainCondemnedChildren({
|
|
@@ -7737,6 +8601,7 @@ async function cascadeAutoTransitions({client: client, instanceId: instanceId, a
|
|
|
7737
8601
|
actor: actor,
|
|
7738
8602
|
clientForGdr: clientForGdr,
|
|
7739
8603
|
refSurface: refSurface,
|
|
8604
|
+
memberRolesLoader: memberRolesLoader,
|
|
7740
8605
|
clock: clock,
|
|
7741
8606
|
executionContext: executionContext,
|
|
7742
8607
|
telemetry: telemetry
|
|
@@ -7747,6 +8612,7 @@ async function cascadeAutoTransitions({client: client, instanceId: instanceId, a
|
|
|
7747
8612
|
actor: actor,
|
|
7748
8613
|
clientForGdr: clientForGdr,
|
|
7749
8614
|
refSurface: refSurface,
|
|
8615
|
+
memberRolesLoader: memberRolesLoader,
|
|
7750
8616
|
clock: clock,
|
|
7751
8617
|
executionContext: executionContext,
|
|
7752
8618
|
telemetry: telemetry,
|
|
@@ -7763,7 +8629,7 @@ async function cascadeAutoTransitions({client: client, instanceId: instanceId, a
|
|
|
7763
8629
|
}
|
|
7764
8630
|
}
|
|
7765
8631
|
|
|
7766
|
-
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}) {
|
|
7767
8633
|
if (draining.has(instanceId)) return {
|
|
7768
8634
|
instance: preloadedInstance,
|
|
7769
8635
|
drained: !1
|
|
@@ -7786,6 +8652,7 @@ async function drainCondemnedChildren({client: client, instanceId: instanceId, a
|
|
|
7786
8652
|
actor: actor,
|
|
7787
8653
|
clientForGdr: clientForGdr,
|
|
7788
8654
|
refSurface: refSurface,
|
|
8655
|
+
memberRolesLoader: memberRolesLoader,
|
|
7789
8656
|
clock: clock,
|
|
7790
8657
|
executionContext: executionContext,
|
|
7791
8658
|
telemetry: telemetry,
|
|
@@ -7803,7 +8670,7 @@ async function drainCondemnedChildren({client: client, instanceId: instanceId, a
|
|
|
7803
8670
|
};
|
|
7804
8671
|
}
|
|
7805
8672
|
|
|
7806
|
-
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}) {
|
|
7807
8674
|
const childId = invariants.toBareId(row.ref.id);
|
|
7808
8675
|
try {
|
|
7809
8676
|
const result = await abortInstance({
|
|
@@ -7816,6 +8683,7 @@ async function settleCondemnedRow({client: client, ownerId: ownerId, row: row, a
|
|
|
7816
8683
|
} : {},
|
|
7817
8684
|
clientForGdr: clientForGdr,
|
|
7818
8685
|
refSurface: refSurface,
|
|
8686
|
+
memberRolesLoader: memberRolesLoader,
|
|
7819
8687
|
...clock ? {
|
|
7820
8688
|
clock: clock
|
|
7821
8689
|
} : {},
|
|
@@ -7833,6 +8701,7 @@ async function settleCondemnedRow({client: client, ownerId: ownerId, row: row, a
|
|
|
7833
8701
|
actor: actor,
|
|
7834
8702
|
clientForGdr: clientForGdr,
|
|
7835
8703
|
refSurface: refSurface,
|
|
8704
|
+
memberRolesLoader: memberRolesLoader,
|
|
7836
8705
|
clock: clock,
|
|
7837
8706
|
executionContext: executionContext,
|
|
7838
8707
|
telemetry: telemetry,
|
|
@@ -7983,7 +8852,8 @@ async function buildCascadeStepContext(args, instance) {
|
|
|
7983
8852
|
} : {},
|
|
7984
8853
|
...args.settlingCohorts ? {
|
|
7985
8854
|
settlingCohorts: args.settlingCohorts
|
|
7986
|
-
} : {}
|
|
8855
|
+
} : {},
|
|
8856
|
+
memberRolesLoader: args.memberRolesLoader
|
|
7987
8857
|
});
|
|
7988
8858
|
}
|
|
7989
8859
|
|
|
@@ -8211,6 +9081,7 @@ function spawnStepArgs(ctx, args) {
|
|
|
8211
9081
|
actor: args.actor,
|
|
8212
9082
|
clientForGdr: ctx.clientForGdr,
|
|
8213
9083
|
refSurface: ctx.refSurface,
|
|
9084
|
+
memberRolesLoader: ctx.memberRolesLoader,
|
|
8214
9085
|
clock: ctx.clock,
|
|
8215
9086
|
executionContext: ctx.executionContext,
|
|
8216
9087
|
telemetry: ctx.telemetry,
|
|
@@ -8352,7 +9223,11 @@ function validateEffectOutputs(args) {
|
|
|
8352
9223
|
issues.push(`"${key}" is not a declared output`);
|
|
8353
9224
|
continue;
|
|
8354
9225
|
}
|
|
8355
|
-
const check = effectOutputCheck(
|
|
9226
|
+
const check = effectOutputCheck({
|
|
9227
|
+
shape: shape,
|
|
9228
|
+
value: value,
|
|
9229
|
+
eligibility: args
|
|
9230
|
+
});
|
|
8356
9231
|
"issues" in check ? issues.push(...check.issues.map(i => `"${key}": ${i}`)) : normalized[key] = check.output;
|
|
8357
9232
|
}
|
|
8358
9233
|
if (issues.length > 0) throw new EffectOutputsInvalidError({
|
|
@@ -8362,7 +9237,8 @@ function validateEffectOutputs(args) {
|
|
|
8362
9237
|
return normalized;
|
|
8363
9238
|
}
|
|
8364
9239
|
|
|
8365
|
-
function effectOutputCheck(
|
|
9240
|
+
function effectOutputCheck(args) {
|
|
9241
|
+
const {shape: shape, value: value, eligibility: eligibility} = args;
|
|
8366
9242
|
return invariants.parseFieldValue({
|
|
8367
9243
|
entryType: shape.type,
|
|
8368
9244
|
value: value,
|
|
@@ -8377,7 +9253,12 @@ function effectOutputCheck(shape, value) {
|
|
|
8377
9253
|
} : {},
|
|
8378
9254
|
...shape.validation !== void 0 ? {
|
|
8379
9255
|
validation: shape.validation
|
|
8380
|
-
} : {}
|
|
9256
|
+
} : {},
|
|
9257
|
+
...shape.roles !== void 0 ? {
|
|
9258
|
+
roles: shape.roles
|
|
9259
|
+
} : {},
|
|
9260
|
+
memberRoles: eligibility.memberRoles,
|
|
9261
|
+
roleAliases: eligibility.roleAliases
|
|
8381
9262
|
});
|
|
8382
9263
|
}
|
|
8383
9264
|
|
|
@@ -8400,7 +9281,7 @@ function requirePendingEffect(instance, effectKey) {
|
|
|
8400
9281
|
});
|
|
8401
9282
|
}
|
|
8402
9283
|
|
|
8403
|
-
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}) {
|
|
8404
9285
|
if (status === "failed" && ops !== void 0 && ops.length > 0) throw new EffectOpsInvalidError({
|
|
8405
9286
|
effect: pending.name,
|
|
8406
9287
|
issues: [ "ops cannot accompany a failed completion — field.set the outcome on a done completion instead" ]
|
|
@@ -8412,7 +9293,9 @@ function validateCompletionInput({pending: pending, definition: definition, stat
|
|
|
8412
9293
|
const normalizedOutputs = outputs !== void 0 ? validateEffectOutputs({
|
|
8413
9294
|
outputs: outputs,
|
|
8414
9295
|
declared: findEffect(definition, pending.name)?.outputs ?? [],
|
|
8415
|
-
effectName: pending.name
|
|
9296
|
+
effectName: pending.name,
|
|
9297
|
+
memberRoles: memberRoles,
|
|
9298
|
+
roleAliases: roleAliases
|
|
8416
9299
|
}) : void 0;
|
|
8417
9300
|
return {
|
|
8418
9301
|
ops: ops !== void 0 ? validateEffectOps(ops, pending.name) : [],
|
|
@@ -8431,7 +9314,9 @@ async function commitCompleteEffect({ctx: ctx, effectKey: effectKey, status: sta
|
|
|
8431
9314
|
definition: ctx.definition,
|
|
8432
9315
|
status: status,
|
|
8433
9316
|
ops: ops,
|
|
8434
|
-
outputs: outputs
|
|
9317
|
+
outputs: outputs,
|
|
9318
|
+
memberRoles: ctx.memberRoles,
|
|
9319
|
+
roleAliases: ctx.definition.roleAliases
|
|
8435
9320
|
}), mutation = startMutation(ctx.instance);
|
|
8436
9321
|
recordProcessedRequest({
|
|
8437
9322
|
mutation: mutation,
|
|
@@ -8462,7 +9347,9 @@ async function commitCompleteEffect({ctx: ctx, effectKey: effectKey, status: sta
|
|
|
8462
9347
|
self: invariants.selfGdr(ctx.instance),
|
|
8463
9348
|
now: ranAt,
|
|
8464
9349
|
snapshot: ctx.snapshot,
|
|
8465
|
-
refSurface: ctx.refSurface
|
|
9350
|
+
refSurface: ctx.refSurface,
|
|
9351
|
+
memberRoles: ctx.memberRoles,
|
|
9352
|
+
roleAliases: ctx.definition.roleAliases
|
|
8466
9353
|
}), needsGuardRefresh = wroteEffectOutputs || ranOps.some(isFieldOp);
|
|
8467
9354
|
return await persistThenMaybeRefresh({
|
|
8468
9355
|
ctx: ctx,
|
|
@@ -8631,7 +9518,9 @@ async function commitReport({ctx: ctx, effectKey: effectKey, claimToken: claimTo
|
|
|
8631
9518
|
self: invariants.selfGdr(ctx.instance),
|
|
8632
9519
|
now: ctx.now,
|
|
8633
9520
|
snapshot: ctx.snapshot,
|
|
8634
|
-
refSurface: ctx.refSurface
|
|
9521
|
+
refSurface: ctx.refSurface,
|
|
9522
|
+
memberRoles: ctx.memberRoles,
|
|
9523
|
+
roleAliases: ctx.definition.roleAliases
|
|
8635
9524
|
}), await persistThenMaybeRefresh({
|
|
8636
9525
|
ctx: ctx,
|
|
8637
9526
|
mutation: mutation,
|
|
@@ -8642,306 +9531,63 @@ async function commitReport({ctx: ctx, effectKey: effectKey, claimToken: claimTo
|
|
|
8642
9531
|
effect: pending.name
|
|
8643
9532
|
};
|
|
8644
9533
|
}
|
|
8645
|
-
|
|
8646
|
-
const RESET_ACTIVITY_TARGETS = [ "active", "skipped" ];
|
|
8647
|
-
|
|
8648
|
-
function isResetActivityTarget(value) {
|
|
8649
|
-
return RESET_ACTIVITY_TARGETS.includes(value);
|
|
8650
|
-
}
|
|
8651
|
-
|
|
8652
|
-
async function resetActivity(args) {
|
|
8653
|
-
const {client: client, instanceId: instanceId, activity: activity, to: to, requestRecord: requestRecord, options: options} = args, ctx = await loadCallContext({
|
|
8654
|
-
client: client,
|
|
8655
|
-
instanceId: instanceId,
|
|
8656
|
-
options: options
|
|
8657
|
-
});
|
|
8658
|
-
return commitResetActivity({
|
|
8659
|
-
ctx: ctx,
|
|
8660
|
-
activity: activity,
|
|
8661
|
-
to: to,
|
|
8662
|
-
requestRecord: requestRecord,
|
|
8663
|
-
actor: options?.actor
|
|
8664
|
-
});
|
|
8665
|
-
}
|
|
8666
|
-
|
|
8667
|
-
async function commitResetActivity({ctx: ctx, activity: activity, to: to, requestRecord: requestRecord, actor: actor}) {
|
|
8668
|
-
if (assertRequestUnprocessed({
|
|
8669
|
-
instance: ctx.instance,
|
|
8670
|
-
record: requestRecord,
|
|
8671
|
-
now: ctx.now
|
|
8672
|
-
}), isTerminal(ctx)) return {
|
|
8673
|
-
fired: !1
|
|
8674
|
-
};
|
|
8675
|
-
const mutation = startMutation(ctx.instance), openStage2 = findOpenStageEntry(mutation), entry = findCurrentActivityEntry(mutation, activity);
|
|
8676
|
-
if (openStage2 === void 0 || entry === void 0) throw new invariants.ContractViolationError(`resetActivity: activity "${activity}" is not in the current stage of instance "${ctx.instance._id}"`);
|
|
8677
|
-
const from = entry.status;
|
|
8678
|
-
if (from === to) return {
|
|
8679
|
-
fired: !1
|
|
8680
|
-
};
|
|
8681
|
-
if (!invariants.isTerminalActivityStatus(from)) throw new invariants.ContractViolationError(`resetActivity: activity "${activity}" is "${from}", not a terminal status — a reset only recovers a resolved (typically failed) activity. Use setStage to force past a live stage.`);
|
|
8682
|
-
return recordProcessedRequest({
|
|
8683
|
-
mutation: mutation,
|
|
8684
|
-
record: requestRecord,
|
|
8685
|
-
now: ctx.now
|
|
8686
|
-
}), applyActivityStatusChange({
|
|
8687
|
-
entry: entry,
|
|
8688
|
-
history: mutation.history,
|
|
8689
|
-
stage: openStage2.name,
|
|
8690
|
-
to: to,
|
|
8691
|
-
at: ctx.now,
|
|
8692
|
-
...actor !== void 0 ? {
|
|
8693
|
-
actor: actor
|
|
8694
|
-
} : {}
|
|
8695
|
-
}), await persist(ctx, mutation), {
|
|
8696
|
-
fired: !0,
|
|
8697
|
-
stage: openStage2.name,
|
|
8698
|
-
activity: activity,
|
|
8699
|
-
from: from,
|
|
8700
|
-
to: to
|
|
8701
|
-
};
|
|
8702
|
-
}
|
|
8703
|
-
|
|
8704
|
-
const actorCache = /* @__PURE__ */ new WeakMap, grantsCache = /* @__PURE__ */ new WeakMap;
|
|
8705
|
-
|
|
8706
|
-
async function resolveAccess(taggedClient, args = {}) {
|
|
8707
|
-
const client = unwrapRequestTag(taggedClient), requestFn = lazyRequest(client);
|
|
8708
|
-
if (requestFn === void 0) throw new invariants.ContractViolationError("workflow: no actor available. The engine resolves the actor from the client's token via `client.request({ uri: '/users/me' })`. Supply a real `@sanity/client` configured with a token (the test bench serves these endpoints per registered token).");
|
|
8709
|
-
const grantsPromise = args.grantsFromPath !== void 0 ? cachedGrants({
|
|
8710
|
-
client: client,
|
|
8711
|
-
requestFn: requestFn,
|
|
8712
|
-
resourcePath: args.grantsFromPath
|
|
8713
|
-
}) : Promise.resolve(void 0), [identity, grants] = await Promise.all([ cachedActor(client, requestFn), grantsPromise ]);
|
|
8714
|
-
if (identity === void 0) throw new invariants.ContractViolationError("workflow: failed to resolve actor from `/users/me`. The client is configured but the endpoint returned no usable identity — check the token.");
|
|
8715
|
-
return {
|
|
8716
|
-
actor: identity.actor,
|
|
8717
|
-
...identity.localPrincipalId !== void 0 ? {
|
|
8718
|
-
localPrincipalId: identity.localPrincipalId
|
|
8719
|
-
} : {},
|
|
8720
|
-
...grants !== void 0 ? {
|
|
8721
|
-
grants: grants
|
|
8722
|
-
} : {}
|
|
8723
|
-
};
|
|
8724
|
-
}
|
|
8725
|
-
|
|
8726
|
-
function cachedActor(client, requestFn) {
|
|
8727
|
-
const cached = actorCache.get(client);
|
|
8728
|
-
if (cached !== void 0) return cached;
|
|
8729
|
-
const pending = fetchActor(client, requestFn).catch(err => {
|
|
8730
|
-
throw actorCache.get(client) === pending && actorCache.delete(client), err;
|
|
8731
|
-
});
|
|
8732
|
-
return actorCache.set(client, pending), pending;
|
|
8733
|
-
}
|
|
8734
|
-
|
|
8735
|
-
function grantsForClientPath(taggedClient, resourcePath) {
|
|
8736
|
-
const client = unwrapRequestTag(taggedClient), requestFn = lazyRequest(client);
|
|
8737
|
-
return requestFn === void 0 ? Promise.resolve(void 0) : cachedGrants({
|
|
8738
|
-
client: client,
|
|
8739
|
-
requestFn: requestFn,
|
|
8740
|
-
resourcePath: resourcePath
|
|
8741
|
-
});
|
|
8742
|
-
}
|
|
8743
|
-
|
|
8744
|
-
function lazyRequest(client) {
|
|
8745
|
-
return client.request === void 0 ? void 0 : opts => client.request(opts);
|
|
8746
|
-
}
|
|
8747
|
-
|
|
8748
|
-
function cachedGrants({client: client, requestFn: requestFn, resourcePath: resourcePath}) {
|
|
8749
|
-
let byPath = grantsCache.get(client);
|
|
8750
|
-
byPath === void 0 && (byPath = /* @__PURE__ */ new Map, grantsCache.set(client, byPath));
|
|
8751
|
-
let cached = byPath.get(resourcePath);
|
|
8752
|
-
return cached === void 0 && (cached = fetchGrantsCached(requestFn, resourcePath),
|
|
8753
|
-
byPath.set(resourcePath, cached)), cached;
|
|
8754
|
-
}
|
|
8755
|
-
|
|
8756
|
-
async function fetchActor(client, requestFn) {
|
|
8757
|
-
const [resourceUser, globalUser] = await Promise.all([ fetchCurrentUser(requestFn, "the workflow resource host"), fetchGlobalUser(client) ]), resourceId = usableId(resourceUser), globalHostId = usableId(globalUser.user), carriedId = invariants.firstCarriedGlobalId([ globalHostId, resourceId ]), sessionId = carriedId ?? globalHostId ?? resourceId;
|
|
8758
|
-
if (sessionId === void 0) return;
|
|
8759
|
-
const bridge = carriedId === void 0 ? await bridgeProjectPrincipal({
|
|
8760
|
-
client: client,
|
|
8761
|
-
sessionId: sessionId,
|
|
8762
|
-
resourceId: resourceId
|
|
8763
|
-
}) : NO_BRIDGE, id = bridge.status === "resolved" ? bridge.globalId : sessionId;
|
|
8764
|
-
refuseProjectScopedActor({
|
|
8765
|
-
id: id,
|
|
8766
|
-
globalUser: globalUser,
|
|
8767
|
-
globalHostId: globalHostId,
|
|
8768
|
-
bridgeFailure: bridge.status === "unavailable" ? bridge : void 0
|
|
8769
|
-
});
|
|
8770
|
-
const roleNames = roleNamesFor(resourceUser, globalUser);
|
|
8771
|
-
return {
|
|
8772
|
-
actor: {
|
|
8773
|
-
kind: "person",
|
|
8774
|
-
id: id,
|
|
8775
|
-
...roleNames.length > 0 ? {
|
|
8776
|
-
roles: roleNames
|
|
8777
|
-
} : {}
|
|
8778
|
-
},
|
|
8779
|
-
...resourceId !== void 0 && resourceId !== id ? {
|
|
8780
|
-
localPrincipalId: resourceId
|
|
8781
|
-
} : {}
|
|
8782
|
-
};
|
|
8783
|
-
}
|
|
8784
|
-
|
|
8785
|
-
function roleNamesFor(resourceUser, globalUser) {
|
|
8786
|
-
return (resourceUser?.roles?.length ? resourceUser : globalUser.user)?.roles?.map(r => r.name).filter(n => !!n) ?? [];
|
|
8787
|
-
}
|
|
8788
|
-
|
|
8789
|
-
const NO_BRIDGE = {
|
|
8790
|
-
status: "not-applicable"
|
|
8791
|
-
};
|
|
8792
|
-
|
|
8793
|
-
function globalRouteReason(globalUser, globalHostId) {
|
|
8794
|
-
return "reason" in globalUser ? globalUser.reason : globalHostId === void 0 ? "no record" : `the global host answered with project-scoped principal "${globalHostId}"`;
|
|
8795
|
-
}
|
|
8796
|
-
|
|
8797
|
-
async function bridgeProjectPrincipal(args) {
|
|
8798
|
-
const {client: client, sessionId: sessionId, resourceId: resourceId} = args;
|
|
8799
|
-
return invariants.classifyPrincipalId(sessionId).namespace !== "project" ? NO_BRIDGE : resourceId === void 0 || invariants.classifyPrincipalId(resourceId).namespace !== "project" ? {
|
|
8800
|
-
status: "unavailable",
|
|
8801
|
-
reason: "no project-scoped principal from the resource host to address the directory with"
|
|
8802
|
-
} : directoryGlobalId({
|
|
8803
|
-
client: client,
|
|
8804
|
-
principalId: resourceId
|
|
8805
|
-
});
|
|
8806
|
-
}
|
|
8807
|
-
|
|
8808
|
-
async function directoryGlobalId(args) {
|
|
8809
|
-
const {client: client, principalId: principalId} = args, projectId = typeof client.config == "function" ? client.config().projectId : void 0;
|
|
8810
|
-
if (projectId === void 0) return {
|
|
8811
|
-
status: "unavailable",
|
|
8812
|
-
reason: "the client reports no projectId, so its user directory has no address"
|
|
8813
|
-
};
|
|
8814
|
-
const lookup = await clientProjectUserDirectory(withRequestTag(client, REQUEST_TAG.accessResolveActor), projectId).findById(principalId);
|
|
8815
|
-
if (lookup.status !== "resolved") return {
|
|
8816
|
-
status: "unavailable",
|
|
8817
|
-
reason: `project "${projectId}"'s user directory reported the principal ${lookup.status}`,
|
|
8818
|
-
...lookup.status === "inaccessible" && lookup.cause !== void 0 ? {
|
|
8819
|
-
cause: lookup.cause
|
|
8820
|
-
} : {}
|
|
8821
|
-
};
|
|
8822
|
-
const globalId = invariants.directoryBridgeId(lookup.user.sanityUserId);
|
|
8823
|
-
return globalId === void 0 ? {
|
|
8824
|
-
status: "unavailable",
|
|
8825
|
-
reason: `project "${projectId}"'s user directory row for the principal carries no account-global sanityUserId`
|
|
8826
|
-
} : {
|
|
8827
|
-
status: "resolved",
|
|
8828
|
-
globalId: globalId
|
|
8829
|
-
};
|
|
8830
|
-
}
|
|
8831
|
-
|
|
8832
|
-
function refuseProjectScopedActor(args) {
|
|
8833
|
-
const {id: id, globalUser: globalUser, globalHostId: globalHostId, bridgeFailure: bridgeFailure} = args;
|
|
8834
|
-
if (invariants.classifyPrincipalId(id).namespace !== "project") return;
|
|
8835
|
-
const routes = [ `The account-global record: ${globalRouteReason(globalUser, globalHostId)}.` ];
|
|
8836
|
-
bridgeFailure !== void 0 && routes.push(`The project user directory: ${bridgeFailure.reason}.`);
|
|
8837
|
-
const cause = bridgeFailure?.cause ?? ("cause" in globalUser ? globalUser.cause : void 0);
|
|
8838
|
-
throw new Error(`workflow: the caller's identity resolves to the project-scoped principal "${id}" and its account-global id could not be resolved. ${routes.join(" ")} The engine speaks account-global user ids only and never acts as a project-scoped principal.`, cause === void 0 ? void 0 : {
|
|
8839
|
-
cause: cause
|
|
8840
|
-
});
|
|
8841
|
-
}
|
|
8842
|
-
|
|
8843
|
-
function usableId(user) {
|
|
8844
|
-
if (!(!user || typeof user.id != "string" || user.id.length === 0)) return user.id;
|
|
8845
|
-
}
|
|
8846
|
-
|
|
8847
|
-
async function fetchCurrentUser(requestFn, hostDescription) {
|
|
8848
|
-
try {
|
|
8849
|
-
return await requestFn({
|
|
8850
|
-
uri: "/users/me",
|
|
8851
|
-
tag: REQUEST_TAG.accessResolveActor
|
|
8852
|
-
});
|
|
8853
|
-
} catch (err) {
|
|
8854
|
-
throw new Error(`workflow: /users/me request against ${hostDescription} failed. The engine resolves the actor from the client's token via \`client.request({ uri: '/users/me' })\`. Check the token/connectivity.`, {
|
|
8855
|
-
cause: err
|
|
8856
|
-
});
|
|
8857
|
-
}
|
|
9534
|
+
|
|
9535
|
+
const RESET_ACTIVITY_TARGETS = [ "active", "skipped" ];
|
|
9536
|
+
|
|
9537
|
+
function isResetActivityTarget(value) {
|
|
9538
|
+
return RESET_ACTIVITY_TARGETS.includes(value);
|
|
8858
9539
|
}
|
|
8859
9540
|
|
|
8860
|
-
async function
|
|
8861
|
-
|
|
8862
|
-
|
|
8863
|
-
|
|
8864
|
-
|
|
8865
|
-
|
|
8866
|
-
|
|
8867
|
-
|
|
8868
|
-
|
|
8869
|
-
|
|
8870
|
-
|
|
8871
|
-
|
|
8872
|
-
|
|
8873
|
-
}), globalRequest = lazyRequest(globalClient);
|
|
8874
|
-
} catch (err) {
|
|
8875
|
-
return {
|
|
8876
|
-
user: void 0,
|
|
8877
|
-
reason: `building the global-host sibling client failed: ${invariants.errorMessage(err)}`,
|
|
8878
|
-
cause: err
|
|
8879
|
-
};
|
|
8880
|
-
}
|
|
8881
|
-
if (globalRequest === void 0) return {
|
|
8882
|
-
user: void 0,
|
|
8883
|
-
reason: "the global-host sibling client cannot issue requests"
|
|
8884
|
-
};
|
|
8885
|
-
try {
|
|
8886
|
-
const user = await globalRequest({
|
|
8887
|
-
uri: "/users/me",
|
|
8888
|
-
tag: REQUEST_TAG.accessResolveActor
|
|
8889
|
-
}), id = usableId(user);
|
|
8890
|
-
return hostResolution.requireGlobalPrincipal && id !== void 0 && invariants.classifyPrincipalId(id).namespace === "project" ? {
|
|
8891
|
-
user: void 0,
|
|
8892
|
-
reason: `global-host /users/me returned project-scoped principal "${id}"; the sibling client is still bound to a project API host`
|
|
8893
|
-
} : {
|
|
8894
|
-
user: user
|
|
8895
|
-
};
|
|
8896
|
-
} catch (err) {
|
|
8897
|
-
return {
|
|
8898
|
-
user: void 0,
|
|
8899
|
-
reason: `global-host /users/me failed: ${invariants.errorMessage(err)}`,
|
|
8900
|
-
cause: err
|
|
8901
|
-
};
|
|
8902
|
-
}
|
|
9541
|
+
async function resetActivity(args) {
|
|
9542
|
+
const {client: client, instanceId: instanceId, activity: activity, to: to, requestRecord: requestRecord, options: options} = args, ctx = await loadCallContext({
|
|
9543
|
+
client: client,
|
|
9544
|
+
instanceId: instanceId,
|
|
9545
|
+
options: options
|
|
9546
|
+
});
|
|
9547
|
+
return commitResetActivity({
|
|
9548
|
+
ctx: ctx,
|
|
9549
|
+
activity: activity,
|
|
9550
|
+
to: to,
|
|
9551
|
+
requestRecord: requestRecord,
|
|
9552
|
+
actor: options?.actor
|
|
9553
|
+
});
|
|
8903
9554
|
}
|
|
8904
9555
|
|
|
8905
|
-
function
|
|
8906
|
-
if (
|
|
8907
|
-
|
|
9556
|
+
async function commitResetActivity({ctx: ctx, activity: activity, to: to, requestRecord: requestRecord, actor: actor}) {
|
|
9557
|
+
if (assertRequestUnprocessed({
|
|
9558
|
+
instance: ctx.instance,
|
|
9559
|
+
record: requestRecord,
|
|
9560
|
+
now: ctx.now
|
|
9561
|
+
}), isTerminal(ctx)) return {
|
|
9562
|
+
fired: !1
|
|
8908
9563
|
};
|
|
8909
|
-
const
|
|
8910
|
-
if (
|
|
8911
|
-
|
|
9564
|
+
const mutation = startMutation(ctx.instance), openStage2 = findOpenStageEntry(mutation), entry = findCurrentActivityEntry(mutation, activity);
|
|
9565
|
+
if (openStage2 === void 0 || entry === void 0) throw new invariants.ContractViolationError(`resetActivity: activity "${activity}" is not in the current stage of instance "${ctx.instance._id}"`);
|
|
9566
|
+
const from = entry.status;
|
|
9567
|
+
if (from === to) return {
|
|
9568
|
+
fired: !1
|
|
8912
9569
|
};
|
|
8913
|
-
|
|
8914
|
-
|
|
8915
|
-
|
|
8916
|
-
|
|
8917
|
-
|
|
8918
|
-
|
|
8919
|
-
|
|
8920
|
-
|
|
8921
|
-
|
|
8922
|
-
|
|
9570
|
+
if (!invariants.isTerminalActivityStatus(from)) throw new invariants.ContractViolationError(`resetActivity: activity "${activity}" is "${from}", not a terminal status — a reset only recovers a resolved (typically failed) activity. Use setStage to force past a live stage.`);
|
|
9571
|
+
return recordProcessedRequest({
|
|
9572
|
+
mutation: mutation,
|
|
9573
|
+
record: requestRecord,
|
|
9574
|
+
now: ctx.now
|
|
9575
|
+
}), applyActivityStatusChange({
|
|
9576
|
+
entry: entry,
|
|
9577
|
+
history: mutation.history,
|
|
9578
|
+
stage: openStage2.name,
|
|
9579
|
+
to: to,
|
|
9580
|
+
at: ctx.now,
|
|
9581
|
+
...actor !== void 0 ? {
|
|
9582
|
+
actor: actor
|
|
9583
|
+
} : {}
|
|
9584
|
+
}), await persist(ctx, mutation), {
|
|
9585
|
+
fired: !0,
|
|
9586
|
+
stage: openStage2.name,
|
|
9587
|
+
activity: activity,
|
|
9588
|
+
from: from,
|
|
9589
|
+
to: to
|
|
8923
9590
|
};
|
|
8924
|
-
const match = /^[^.]+\.api\.sanity\.(io|work)$/.exec(parsed.hostname);
|
|
8925
|
-
return match === null ? {
|
|
8926
|
-
requireGlobalPrincipal: !0
|
|
8927
|
-
} : (parsed.hostname = `api.sanity.${match[1]}`, {
|
|
8928
|
-
apiHost: parsed.origin,
|
|
8929
|
-
requireGlobalPrincipal: !0
|
|
8930
|
-
});
|
|
8931
|
-
}
|
|
8932
|
-
|
|
8933
|
-
async function fetchGrantsCached(requestFn, resourcePath) {
|
|
8934
|
-
try {
|
|
8935
|
-
return await fetchGrants({
|
|
8936
|
-
client: {
|
|
8937
|
-
request: requestFn
|
|
8938
|
-
},
|
|
8939
|
-
resourcePath: resourcePath
|
|
8940
|
-
});
|
|
8941
|
-
} catch (err) {
|
|
8942
|
-
console.warn(`workflow: failed to fetch grants from "${resourcePath}"; advisory permission reads that depend on them are skipped — a rendered $can stays undefined (conditions referencing it fail closed) and the subject-write forecast omits this resource. The lake still enforces writes. Original error: ${invariants.errorMessage(err)}`);
|
|
8943
|
-
return;
|
|
8944
|
-
}
|
|
8945
9591
|
}
|
|
8946
9592
|
|
|
8947
9593
|
const REPLAY_SURFACE = {
|
|
@@ -9125,7 +9771,7 @@ async function resourceActorId(client) {
|
|
|
9125
9771
|
async function evaluateInstance(args) {
|
|
9126
9772
|
const {client: client, tag: tag, workflowResource: workflowResource, instanceId: instanceId, resourceClients: resourceClients} = args, now = (args.clock ?? wallClock)();
|
|
9127
9773
|
invariants.validateTag(tag);
|
|
9128
|
-
const [access, instance] = await Promise.all([ resolveAccess(client, {
|
|
9774
|
+
const [access, instance, attributes] = await Promise.all([ resolveAccess(client, {
|
|
9129
9775
|
...args.grantsFromPath !== void 0 ? {
|
|
9130
9776
|
grantsFromPath: args.grantsFromPath
|
|
9131
9777
|
} : {}
|
|
@@ -9133,7 +9779,7 @@ async function evaluateInstance(args) {
|
|
|
9133
9779
|
client: client,
|
|
9134
9780
|
instanceId: instanceId,
|
|
9135
9781
|
tag: tag
|
|
9136
|
-
}) ]), {actor: actor, grants: grants, localPrincipalId: localPrincipalId} = access, definition = parseDefinitionSnapshot(instance), clientForGdr = buildClientForGdr({
|
|
9782
|
+
}), resolveUserAttributes(client) ]), {actor: actor, grants: grants, localPrincipalId: localPrincipalId} = access, definition = parseDefinitionSnapshot(instance), clientForGdr = buildClientForGdr({
|
|
9137
9783
|
client: client,
|
|
9138
9784
|
workflowResource: workflowResource,
|
|
9139
9785
|
resourceClients: resourceClients
|
|
@@ -9158,6 +9804,9 @@ async function evaluateInstance(args) {
|
|
|
9158
9804
|
} : {},
|
|
9159
9805
|
...grants !== void 0 ? {
|
|
9160
9806
|
grants: grants
|
|
9807
|
+
} : {},
|
|
9808
|
+
...attributes !== void 0 ? {
|
|
9809
|
+
attributes: attributes
|
|
9161
9810
|
} : {}
|
|
9162
9811
|
});
|
|
9163
9812
|
}
|
|
@@ -9172,6 +9821,33 @@ function memoizedByName(render) {
|
|
|
9172
9821
|
};
|
|
9173
9822
|
}
|
|
9174
9823
|
|
|
9824
|
+
async function callerBoundProjectionScopes(args) {
|
|
9825
|
+
const can = await advisoryCan({
|
|
9826
|
+
instance: args.instance,
|
|
9827
|
+
identity: args.identity,
|
|
9828
|
+
grants: args.grants
|
|
9829
|
+
}), vars = callerBoundVars({
|
|
9830
|
+
...can !== void 0 ? {
|
|
9831
|
+
can: can
|
|
9832
|
+
} : {},
|
|
9833
|
+
...args.attributes !== void 0 ? {
|
|
9834
|
+
attributes: args.attributes
|
|
9835
|
+
} : {}
|
|
9836
|
+
}), opts = {
|
|
9837
|
+
actor: args.actor,
|
|
9838
|
+
...vars !== void 0 ? {
|
|
9839
|
+
vars: vars
|
|
9840
|
+
} : {}
|
|
9841
|
+
};
|
|
9842
|
+
return {
|
|
9843
|
+
scope: await renderConditionScope(args.scopeSource, opts),
|
|
9844
|
+
scopeForActivity: memoizedByName(activityName => renderConditionScope(args.scopeSource, {
|
|
9845
|
+
activityName: activityName,
|
|
9846
|
+
...opts
|
|
9847
|
+
}))
|
|
9848
|
+
};
|
|
9849
|
+
}
|
|
9850
|
+
|
|
9175
9851
|
function currentStageOf(instance, definition) {
|
|
9176
9852
|
try {
|
|
9177
9853
|
return findStage(definition, instance.currentStage);
|
|
@@ -9197,7 +9873,7 @@ async function explainSite(args) {
|
|
|
9197
9873
|
}
|
|
9198
9874
|
|
|
9199
9875
|
async function evaluateFromSnapshot(args) {
|
|
9200
|
-
const {instance: instance, definition: definition, actor: actor, grants: grants, snapshot: snapshot} = args, now = args.now ?? wallClock(), stage = currentStageOf(instance, definition), autonomy = autonomyOf(definition), stageAutonomy2 = stageAutonomyOf(autonomy, stage.name), fireConsequence = (activity, action) => whatIfFireAction({
|
|
9876
|
+
const {instance: instance, definition: definition, actor: actor, grants: grants, attributes: attributes, snapshot: snapshot} = args, now = args.now ?? wallClock(), stage = currentStageOf(instance, definition), autonomy = autonomyOf(definition), stageAutonomy2 = stageAutonomyOf(autonomy, stage.name), fireConsequence = (activity, action) => whatIfFireAction({
|
|
9201
9877
|
instance: instance,
|
|
9202
9878
|
definition: definition,
|
|
9203
9879
|
snapshot: snapshot,
|
|
@@ -9214,22 +9890,14 @@ async function evaluateFromSnapshot(args) {
|
|
|
9214
9890
|
}, anchorIdentity = invariants.lakePrincipalId({
|
|
9215
9891
|
actor: actor,
|
|
9216
9892
|
localPrincipalId: args.localPrincipalId
|
|
9217
|
-
}),
|
|
9218
|
-
|
|
9219
|
-
identity: anchorIdentity,
|
|
9220
|
-
grants: grants
|
|
9221
|
-
}), scope = await renderConditionScope(scopeSource, {
|
|
9222
|
-
actor: actor,
|
|
9223
|
-
vars: {
|
|
9224
|
-
can: can
|
|
9225
|
-
}
|
|
9226
|
-
}), scopeForActivity = memoizedByName(activityName => renderConditionScope(scopeSource, {
|
|
9227
|
-
activityName: activityName,
|
|
9893
|
+
}), {scope: scope, scopeForActivity: scopeForActivity} = await callerBoundProjectionScopes({
|
|
9894
|
+
scopeSource: scopeSource,
|
|
9228
9895
|
actor: actor,
|
|
9229
|
-
|
|
9230
|
-
|
|
9231
|
-
|
|
9232
|
-
|
|
9896
|
+
instance: instance,
|
|
9897
|
+
grants: grants,
|
|
9898
|
+
attributes: attributes,
|
|
9899
|
+
identity: anchorIdentity
|
|
9900
|
+
}), cascadeScopeForActivity = memoizedByName(activityName => renderConditionScope(scopeSource, {
|
|
9233
9901
|
activityName: activityName
|
|
9234
9902
|
})), currentActivityEntries = findOpenStageEntry(instance)?.activities ?? [], guardDenial = await instanceGuardReason({
|
|
9235
9903
|
instance: instance,
|
|
@@ -9278,6 +9946,7 @@ async function evaluateFromSnapshot(args) {
|
|
|
9278
9946
|
}
|
|
9279
9947
|
const currentStage = {
|
|
9280
9948
|
stage: stage,
|
|
9949
|
+
...semanticsOf(stage),
|
|
9281
9950
|
activities: activityEvaluations,
|
|
9282
9951
|
transitions: transitionEvaluations,
|
|
9283
9952
|
autonomy: stageAutonomy2
|
|
@@ -9294,6 +9963,7 @@ async function evaluateFromSnapshot(args) {
|
|
|
9294
9963
|
return {
|
|
9295
9964
|
instance: instance,
|
|
9296
9965
|
definition: definition,
|
|
9966
|
+
...semanticsOf(definition),
|
|
9297
9967
|
actor: actor,
|
|
9298
9968
|
currentStage: currentStage,
|
|
9299
9969
|
pendingOnYou: pendingOnYou,
|
|
@@ -9345,6 +10015,12 @@ async function evaluateEditableFields(args) {
|
|
|
9345
10015
|
...site.validation !== void 0 ? {
|
|
9346
10016
|
validation: site.validation
|
|
9347
10017
|
} : {},
|
|
10018
|
+
...site.roles !== void 0 ? {
|
|
10019
|
+
roles: site.roles,
|
|
10020
|
+
...definition.roleAliases !== void 0 ? {
|
|
10021
|
+
roleAliases: definition.roleAliases
|
|
10022
|
+
} : {}
|
|
10023
|
+
} : {},
|
|
9348
10024
|
value: value,
|
|
9349
10025
|
editable: reason === void 0,
|
|
9350
10026
|
...reason !== void 0 ? {
|
|
@@ -9449,6 +10125,7 @@ async function evaluateActivity(args) {
|
|
|
9449
10125
|
}));
|
|
9450
10126
|
return {
|
|
9451
10127
|
activity: activity,
|
|
10128
|
+
...semanticsOf(activity),
|
|
9452
10129
|
status: status,
|
|
9453
10130
|
kind: invariants.deriveActivityKind(activity),
|
|
9454
10131
|
classification: invariants.deriveExecutorClassification(activity),
|
|
@@ -9619,9 +10296,13 @@ function fireableActionVerdict({args: args, insights: insights}) {
|
|
|
9619
10296
|
function actionEvaluationIdentity(action) {
|
|
9620
10297
|
return {
|
|
9621
10298
|
action: action,
|
|
9622
|
-
...action
|
|
9623
|
-
|
|
9624
|
-
|
|
10299
|
+
...semanticsOf(action)
|
|
10300
|
+
};
|
|
10301
|
+
}
|
|
10302
|
+
|
|
10303
|
+
function semanticsOf(node) {
|
|
10304
|
+
return node.semantics === void 0 ? {} : {
|
|
10305
|
+
semantics: node.semantics
|
|
9625
10306
|
};
|
|
9626
10307
|
}
|
|
9627
10308
|
|
|
@@ -9690,23 +10371,63 @@ function idsArm(filter, params) {
|
|
|
9690
10371
|
}
|
|
9691
10372
|
}
|
|
9692
10373
|
|
|
9693
|
-
function
|
|
9694
|
-
const
|
|
9695
|
-
if (
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
|
|
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() ];
|
|
9699
10386
|
filter.includeCompleted !== !0 && conditions.push(inFlightFilter()), filter.definition !== void 0 && (conditions.push("definition == $definition"),
|
|
9700
10387
|
params.definition = filter.definition), filter.stage !== void 0 && (conditions.push("currentStage == $stage"),
|
|
9701
10388
|
params.stage = filter.stage);
|
|
10389
|
+
const cursor = beforeArm(filter, params);
|
|
10390
|
+
cursor !== void 0 && conditions.push(cursor);
|
|
9702
10391
|
const arms = [ documentArm(filter, params), idsArm(filter, params) ].filter(arm => arm !== void 0);
|
|
9703
|
-
arms.length > 0 && conditions.push(`(${arms.join(" || ")})`);
|
|
9704
|
-
|
|
9705
|
-
|
|
9706
|
-
|
|
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)}`,
|
|
9707
10407
|
params: params
|
|
9708
|
-
}
|
|
9709
|
-
|
|
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}`,
|
|
9710
10431
|
params: params
|
|
9711
10432
|
};
|
|
9712
10433
|
}
|
|
@@ -9891,6 +10612,11 @@ function hashDefinitionContent(def) {
|
|
|
9891
10612
|
}
|
|
9892
10613
|
|
|
9893
10614
|
function planDefinitionDeploy({def: def, latest: latest, target: target}) {
|
|
10615
|
+
assertRoleConstrainedAssignmentResource({
|
|
10616
|
+
context: "workflow.deployDefinitions",
|
|
10617
|
+
definition: def,
|
|
10618
|
+
workflowResource: target.workflowResource
|
|
10619
|
+
});
|
|
9894
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({
|
|
9895
10621
|
tag: target.tag,
|
|
9896
10622
|
definition: expanded.name,
|
|
@@ -10083,7 +10809,9 @@ async function commitEdit({ctx: ctx, target: target, mode: mode, value: value, r
|
|
|
10083
10809
|
self: invariants.selfGdr(ctx.instance),
|
|
10084
10810
|
now: ctx.now,
|
|
10085
10811
|
snapshot: ctx.snapshot,
|
|
10086
|
-
refSurface: ctx.refSurface
|
|
10812
|
+
refSurface: ctx.refSurface,
|
|
10813
|
+
memberRoles: ctx.memberRoles,
|
|
10814
|
+
roleAliases: ctx.definition.roleAliases
|
|
10087
10815
|
});
|
|
10088
10816
|
return await persistThenMaybeRefresh({
|
|
10089
10817
|
ctx: ctx,
|
|
@@ -10100,7 +10828,8 @@ async function commitEdit({ctx: ctx, target: target, mode: mode, value: value, r
|
|
|
10100
10828
|
}
|
|
10101
10829
|
|
|
10102
10830
|
async function assertFieldEditable({ctx: ctx, site: site, options: options}) {
|
|
10103
|
-
const actor = options?.actor, window = fieldWindowOpen(ctx.instance, site),
|
|
10831
|
+
const actor = options?.actor, window = fieldWindowOpen(ctx.instance, site), vars = await callerBoundVarsForCall({
|
|
10832
|
+
client: ctx.client,
|
|
10104
10833
|
instance: ctx.instance,
|
|
10105
10834
|
options: options
|
|
10106
10835
|
}), predicateSatisfied = window.open && site.effective !== !0 && site.effective !== void 0 ? await ctxEvaluateCondition({
|
|
@@ -10113,10 +10842,8 @@ async function assertFieldEditable({ctx: ctx, site: site, options: options}) {
|
|
|
10113
10842
|
...actor !== void 0 ? {
|
|
10114
10843
|
actor: actor
|
|
10115
10844
|
} : {},
|
|
10116
|
-
...
|
|
10117
|
-
vars:
|
|
10118
|
-
can: can
|
|
10119
|
-
}
|
|
10845
|
+
...vars !== void 0 ? {
|
|
10846
|
+
vars: vars
|
|
10120
10847
|
} : {}
|
|
10121
10848
|
}
|
|
10122
10849
|
}) : site.effective === !0, reason = editDisabledReason({
|
|
@@ -10183,6 +10910,7 @@ async function resolveOperationContext(args) {
|
|
|
10183
10910
|
return {
|
|
10184
10911
|
access: access,
|
|
10185
10912
|
actor: access.actor,
|
|
10913
|
+
memberRolesLoader: createAssignmentMemberRolesLoader(args.client),
|
|
10186
10914
|
clientForGdr: buildClientForGdr({
|
|
10187
10915
|
client: args.client,
|
|
10188
10916
|
workflowResource: args.workflowResource,
|
|
@@ -10215,6 +10943,7 @@ async function runCommitVerb(params) {
|
|
|
10215
10943
|
actor: context.actor,
|
|
10216
10944
|
clientForGdr: context.clientForGdr,
|
|
10217
10945
|
refSurface: context.refSurface,
|
|
10946
|
+
memberRolesLoader: context.memberRolesLoader,
|
|
10218
10947
|
clock: clock,
|
|
10219
10948
|
executionContext: args.executionContext,
|
|
10220
10949
|
telemetry: args.telemetry,
|
|
@@ -10239,7 +10968,7 @@ function requestRecordFor(args) {
|
|
|
10239
10968
|
}
|
|
10240
10969
|
|
|
10241
10970
|
async function runDeduped(args) {
|
|
10242
|
-
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 () => {
|
|
10243
10972
|
const pre = await reload({
|
|
10244
10973
|
client: client,
|
|
10245
10974
|
instanceId: instanceId,
|
|
@@ -10251,6 +10980,7 @@ async function runDeduped(args) {
|
|
|
10251
10980
|
actor: actor,
|
|
10252
10981
|
clientForGdr: clientForGdr,
|
|
10253
10982
|
refSurface: refSurface,
|
|
10983
|
+
memberRolesLoader: memberRolesLoader,
|
|
10254
10984
|
clock: clock,
|
|
10255
10985
|
executionContext: executionContext,
|
|
10256
10986
|
telemetry: telemetry
|
|
@@ -10274,13 +11004,14 @@ async function runDeduped(args) {
|
|
|
10274
11004
|
}
|
|
10275
11005
|
}
|
|
10276
11006
|
|
|
10277
|
-
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}) {
|
|
10278
11008
|
const count = await cascadeAutoTransitions({
|
|
10279
11009
|
client: client,
|
|
10280
11010
|
instanceId: instanceId,
|
|
10281
11011
|
actor: actor,
|
|
10282
11012
|
clientForGdr: clientForGdr,
|
|
10283
11013
|
refSurface: refSurface,
|
|
11014
|
+
memberRolesLoader: memberRolesLoader,
|
|
10284
11015
|
...clock !== void 0 ? {
|
|
10285
11016
|
clock: clock
|
|
10286
11017
|
} : {},
|
|
@@ -10300,6 +11031,7 @@ async function cascade({client: client, instanceId: instanceId, actor: actor, cl
|
|
|
10300
11031
|
actor: actor,
|
|
10301
11032
|
clientForGdr: clientForGdr,
|
|
10302
11033
|
refSurface: refSurface,
|
|
11034
|
+
memberRolesLoader: memberRolesLoader,
|
|
10303
11035
|
...clock !== void 0 ? {
|
|
10304
11036
|
clock: clock
|
|
10305
11037
|
} : {},
|
|
@@ -10313,7 +11045,7 @@ async function cascade({client: client, instanceId: instanceId, actor: actor, cl
|
|
|
10313
11045
|
}
|
|
10314
11046
|
|
|
10315
11047
|
async function cascadeAndReload(args) {
|
|
10316
|
-
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;
|
|
10317
11049
|
return {
|
|
10318
11050
|
cascaded: await cascade({
|
|
10319
11051
|
client: client,
|
|
@@ -10321,6 +11053,7 @@ async function cascadeAndReload(args) {
|
|
|
10321
11053
|
actor: actor,
|
|
10322
11054
|
clientForGdr: clientForGdr,
|
|
10323
11055
|
refSurface: refSurface,
|
|
11056
|
+
memberRolesLoader: memberRolesLoader,
|
|
10324
11057
|
clock: clock,
|
|
10325
11058
|
...args.executionContext !== void 0 ? {
|
|
10326
11059
|
executionContext: args.executionContext
|
|
@@ -10344,6 +11077,7 @@ async function settleStart(args) {
|
|
|
10344
11077
|
actor: args.actor,
|
|
10345
11078
|
clientForGdr: args.clientForGdr,
|
|
10346
11079
|
refSurface: args.refSurface,
|
|
11080
|
+
memberRolesLoader: args.memberRolesLoader,
|
|
10347
11081
|
clock: args.clock,
|
|
10348
11082
|
...args.executionContext !== void 0 ? {
|
|
10349
11083
|
executionContext: args.executionContext
|
|
@@ -10386,31 +11120,20 @@ function resumeMismatch(args) {
|
|
|
10386
11120
|
}
|
|
10387
11121
|
|
|
10388
11122
|
async function resumeStart(args) {
|
|
10389
|
-
const {existing: existing} = args, mismatch = resumeMismatch({
|
|
11123
|
+
const {existing: existing, definition: definition, version: version, initialFieldCount: initialFieldCount, ...settlementArgs} = args, mismatch = resumeMismatch({
|
|
10390
11124
|
existing: existing,
|
|
10391
|
-
definition:
|
|
10392
|
-
version:
|
|
11125
|
+
definition: definition,
|
|
11126
|
+
version: version
|
|
10393
11127
|
});
|
|
10394
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.`);
|
|
10395
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.`);
|
|
10396
11130
|
const completesStart = isUnprimed(existing), emitStarted = () => resolveTelemetry(args.telemetry).log(WorkflowInstanceStarted, instanceStartedDataFor({
|
|
10397
11131
|
instance: existing,
|
|
10398
|
-
initialFieldCount:
|
|
11132
|
+
initialFieldCount: initialFieldCount,
|
|
10399
11133
|
viaSpawn: !1
|
|
10400
11134
|
})), cascaded = await settleStart({
|
|
10401
|
-
|
|
10402
|
-
tag: args.tag,
|
|
11135
|
+
...settlementArgs,
|
|
10403
11136
|
instanceId: existing._id,
|
|
10404
|
-
actor: args.actor,
|
|
10405
|
-
clientForGdr: args.clientForGdr,
|
|
10406
|
-
refSurface: args.refSurface,
|
|
10407
|
-
clock: args.clock,
|
|
10408
|
-
...args.executionContext !== void 0 ? {
|
|
10409
|
-
executionContext: args.executionContext
|
|
10410
|
-
} : {},
|
|
10411
|
-
...args.telemetry !== void 0 ? {
|
|
10412
|
-
telemetry: args.telemetry
|
|
10413
|
-
} : {},
|
|
10414
11137
|
...completesStart ? {
|
|
10415
11138
|
emitStarted: emitStarted
|
|
10416
11139
|
} : {}
|
|
@@ -10426,7 +11149,7 @@ async function resumeStart(args) {
|
|
|
10426
11149
|
};
|
|
10427
11150
|
}
|
|
10428
11151
|
|
|
10429
|
-
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}) {
|
|
10430
11153
|
return {
|
|
10431
11154
|
...actor !== void 0 ? {
|
|
10432
11155
|
actor: actor
|
|
@@ -10434,6 +11157,7 @@ function engineOptionsForActor({actor: actor, clock: clock, clientForGdr: client
|
|
|
10434
11157
|
clock: clock,
|
|
10435
11158
|
clientForGdr: clientForGdr,
|
|
10436
11159
|
refSurface: refSurface,
|
|
11160
|
+
memberRolesLoader: memberRolesLoader,
|
|
10437
11161
|
...executionContext !== void 0 ? {
|
|
10438
11162
|
executionContext: executionContext
|
|
10439
11163
|
} : {},
|
|
@@ -10444,7 +11168,7 @@ function engineOptionsForActor({actor: actor, clock: clock, clientForGdr: client
|
|
|
10444
11168
|
}
|
|
10445
11169
|
|
|
10446
11170
|
async function abortAndPropagate(args) {
|
|
10447
|
-
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({
|
|
10448
11172
|
client: client,
|
|
10449
11173
|
instanceId: instanceId,
|
|
10450
11174
|
...reason !== void 0 ? {
|
|
@@ -10458,6 +11182,7 @@ async function abortAndPropagate(args) {
|
|
|
10458
11182
|
clock: clock,
|
|
10459
11183
|
clientForGdr: clientForGdr,
|
|
10460
11184
|
refSurface: refSurface,
|
|
11185
|
+
memberRolesLoader: memberRolesLoader,
|
|
10461
11186
|
executionContext: executionContext,
|
|
10462
11187
|
telemetry: telemetry
|
|
10463
11188
|
})
|
|
@@ -10467,6 +11192,7 @@ async function abortAndPropagate(args) {
|
|
|
10467
11192
|
actor: actor,
|
|
10468
11193
|
clientForGdr: clientForGdr,
|
|
10469
11194
|
refSurface: refSurface,
|
|
11195
|
+
memberRolesLoader: memberRolesLoader,
|
|
10470
11196
|
clock: clock,
|
|
10471
11197
|
...executionContext !== void 0 ? {
|
|
10472
11198
|
executionContext: executionContext
|
|
@@ -10484,6 +11210,7 @@ async function abortAndPropagate(args) {
|
|
|
10484
11210
|
actor: actor,
|
|
10485
11211
|
clientForGdr: clientForGdr,
|
|
10486
11212
|
refSurface: refSurface,
|
|
11213
|
+
memberRolesLoader: memberRolesLoader,
|
|
10487
11214
|
clock: clock,
|
|
10488
11215
|
...executionContext !== void 0 ? {
|
|
10489
11216
|
executionContext: executionContext
|
|
@@ -10525,6 +11252,7 @@ async function dispatchGatedWrite(args) {
|
|
|
10525
11252
|
actor: args.actor,
|
|
10526
11253
|
clientForGdr: args.clientForGdr,
|
|
10527
11254
|
refSurface: args.refSurface,
|
|
11255
|
+
memberRolesLoader: args.memberRolesLoader,
|
|
10528
11256
|
clock: args.clock,
|
|
10529
11257
|
executionContext: args.executionContext,
|
|
10530
11258
|
telemetry: args.telemetry
|
|
@@ -10600,12 +11328,16 @@ function buildEngineCallOptions(args) {
|
|
|
10600
11328
|
actor: args.actor,
|
|
10601
11329
|
clientForGdr: args.clientForGdr,
|
|
10602
11330
|
refSurface: args.refSurface,
|
|
11331
|
+
memberRolesLoader: args.memberRolesLoader,
|
|
10603
11332
|
...args.localPrincipalId !== void 0 ? {
|
|
10604
11333
|
localPrincipalId: args.localPrincipalId
|
|
10605
11334
|
} : {},
|
|
10606
11335
|
...args.grants !== void 0 ? {
|
|
10607
11336
|
grants: args.grants
|
|
10608
11337
|
} : {},
|
|
11338
|
+
...args.attributes !== void 0 ? {
|
|
11339
|
+
attributes: args.attributes
|
|
11340
|
+
} : {},
|
|
10609
11341
|
...args.clock !== void 0 ? {
|
|
10610
11342
|
clock: args.clock
|
|
10611
11343
|
} : {},
|
|
@@ -10636,7 +11368,7 @@ async function applyAction(args) {
|
|
|
10636
11368
|
}
|
|
10637
11369
|
|
|
10638
11370
|
async function deleteDefinition(args) {
|
|
10639
|
-
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({
|
|
10640
11372
|
client: client,
|
|
10641
11373
|
definition: definition,
|
|
10642
11374
|
tag: tag
|
|
@@ -10675,6 +11407,7 @@ async function deleteDefinition(args) {
|
|
|
10675
11407
|
actor: actor,
|
|
10676
11408
|
clientForGdr: clientForGdr,
|
|
10677
11409
|
refSurface: refSurface,
|
|
11410
|
+
memberRolesLoader: memberRolesLoader,
|
|
10678
11411
|
clock: clock,
|
|
10679
11412
|
executionContext: executionContext,
|
|
10680
11413
|
telemetry: telemetry
|
|
@@ -10733,6 +11466,7 @@ async function abortInstances(args) {
|
|
|
10733
11466
|
actor: actor,
|
|
10734
11467
|
clientForGdr: clientForGdr,
|
|
10735
11468
|
refSurface: args.refSurface,
|
|
11469
|
+
memberRolesLoader: args.memberRolesLoader,
|
|
10736
11470
|
clock: clock,
|
|
10737
11471
|
...executionContext !== void 0 ? {
|
|
10738
11472
|
executionContext: executionContext
|
|
@@ -10765,11 +11499,12 @@ async function fetchStartSlice(args) {
|
|
|
10765
11499
|
|
|
10766
11500
|
const workflow = {
|
|
10767
11501
|
deployDefinitions: async rawArgs => {
|
|
10768
|
-
|
|
10769
|
-
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;
|
|
10770
11503
|
invariants.validateTag(tag);
|
|
10771
11504
|
const definitions = args.definitions.map(def => parseDefinitionInput(def, "workflow.deployDefinitions"));
|
|
10772
|
-
definitions.forEach(validateDefinition)
|
|
11505
|
+
definitions.forEach(validateDefinition), assertReaderModelAcknowledgement(args.expectedMinReaderModel, {
|
|
11506
|
+
requiredMinReaderModel: requiredDefinitionReaderModel(definitions)
|
|
11507
|
+
});
|
|
10773
11508
|
const ordered = await sortByDependencies({
|
|
10774
11509
|
client: client,
|
|
10775
11510
|
definitions: definitions,
|
|
@@ -10788,6 +11523,7 @@ const workflow = {
|
|
|
10788
11523
|
latest: latest,
|
|
10789
11524
|
target: {
|
|
10790
11525
|
tag: tag,
|
|
11526
|
+
workflowResource: workflowResource,
|
|
10791
11527
|
...resourceAliases !== void 0 ? {
|
|
10792
11528
|
resourceAliases: resourceAliases
|
|
10793
11529
|
} : {}
|
|
@@ -10838,7 +11574,7 @@ const workflow = {
|
|
|
10838
11574
|
}), result;
|
|
10839
11575
|
},
|
|
10840
11576
|
startInstance: async rawArgs => {
|
|
10841
|
-
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;
|
|
10842
11578
|
return existing !== void 0 && existing.tag === tag ? resumeStart({
|
|
10843
11579
|
client: client,
|
|
10844
11580
|
tag: tag,
|
|
@@ -10849,6 +11585,7 @@ const workflow = {
|
|
|
10849
11585
|
actor: actor,
|
|
10850
11586
|
clientForGdr: clientForGdr,
|
|
10851
11587
|
refSurface: refSurface,
|
|
11588
|
+
memberRolesLoader: memberRolesLoader,
|
|
10852
11589
|
clock: clock,
|
|
10853
11590
|
...executionContext !== void 0 ? {
|
|
10854
11591
|
executionContext: executionContext
|
|
@@ -10868,7 +11605,7 @@ const workflow = {
|
|
|
10868
11605
|
return runCommitVerb({
|
|
10869
11606
|
args: args,
|
|
10870
11607
|
op: "fireAction",
|
|
10871
|
-
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}) => {
|
|
10872
11609
|
if (findCurrentActivityEntry(before, activity) === void 0 && idempotent === !0) return {
|
|
10873
11610
|
instance: before,
|
|
10874
11611
|
cascaded: 0,
|
|
@@ -10882,6 +11619,7 @@ const workflow = {
|
|
|
10882
11619
|
actor: actor,
|
|
10883
11620
|
clientForGdr: clientForGdr,
|
|
10884
11621
|
refSurface: refSurface,
|
|
11622
|
+
memberRolesLoader: memberRolesLoader,
|
|
10885
11623
|
clock: clock,
|
|
10886
11624
|
before: before,
|
|
10887
11625
|
...grantsFromPath !== void 0 ? {
|
|
@@ -10915,6 +11653,7 @@ const workflow = {
|
|
|
10915
11653
|
clock: clock,
|
|
10916
11654
|
clientForGdr: clientForGdr,
|
|
10917
11655
|
refSurface: refSurface,
|
|
11656
|
+
memberRolesLoader: memberRolesLoader,
|
|
10918
11657
|
...executionContext !== void 0 ? {
|
|
10919
11658
|
executionContext: executionContext
|
|
10920
11659
|
} : {},
|
|
@@ -10943,7 +11682,7 @@ const workflow = {
|
|
|
10943
11682
|
return runCommitVerb({
|
|
10944
11683
|
args: args,
|
|
10945
11684
|
op: "editField",
|
|
10946
|
-
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}) => {
|
|
10947
11686
|
const result = await dispatchGatedWrite({
|
|
10948
11687
|
client: client,
|
|
10949
11688
|
tag: tag,
|
|
@@ -10952,6 +11691,7 @@ const workflow = {
|
|
|
10952
11691
|
actor: actor,
|
|
10953
11692
|
clientForGdr: clientForGdr,
|
|
10954
11693
|
refSurface: refSurface,
|
|
11694
|
+
memberRolesLoader: memberRolesLoader,
|
|
10955
11695
|
clock: clock,
|
|
10956
11696
|
before: before,
|
|
10957
11697
|
...grantsFromPath !== void 0 ? {
|
|
@@ -10986,6 +11726,7 @@ const workflow = {
|
|
|
10986
11726
|
clock: clock,
|
|
10987
11727
|
clientForGdr: clientForGdr,
|
|
10988
11728
|
refSurface: refSurface,
|
|
11729
|
+
memberRolesLoader: memberRolesLoader,
|
|
10989
11730
|
...executionContext !== void 0 ? {
|
|
10990
11731
|
executionContext: executionContext
|
|
10991
11732
|
} : {},
|
|
@@ -11006,7 +11747,7 @@ const workflow = {
|
|
|
11006
11747
|
});
|
|
11007
11748
|
},
|
|
11008
11749
|
completeEffect: async rawArgs => {
|
|
11009
|
-
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({
|
|
11010
11751
|
idempotencyKey: args.idempotencyKey,
|
|
11011
11752
|
op: "completeEffect",
|
|
11012
11753
|
idempotencyTtlMs: args.idempotencyTtlMs
|
|
@@ -11017,9 +11758,7 @@ const workflow = {
|
|
|
11017
11758
|
instanceId: instanceId,
|
|
11018
11759
|
record: record,
|
|
11019
11760
|
now: clock(),
|
|
11020
|
-
|
|
11021
|
-
clientForGdr: clientForGdr,
|
|
11022
|
-
refSurface: refSurface,
|
|
11761
|
+
...operationContext,
|
|
11023
11762
|
clock: clock,
|
|
11024
11763
|
executionContext: executionContext,
|
|
11025
11764
|
telemetry: args.telemetry,
|
|
@@ -11048,10 +11787,8 @@ const workflow = {
|
|
|
11048
11787
|
requestRecord: record
|
|
11049
11788
|
} : {},
|
|
11050
11789
|
options: engineOptionsForActor({
|
|
11051
|
-
|
|
11790
|
+
...operationContext,
|
|
11052
11791
|
clock: clock,
|
|
11053
|
-
clientForGdr: clientForGdr,
|
|
11054
|
-
refSurface: refSurface,
|
|
11055
11792
|
executionContext: executionContext,
|
|
11056
11793
|
telemetry: args.telemetry
|
|
11057
11794
|
})
|
|
@@ -11059,9 +11796,7 @@ const workflow = {
|
|
|
11059
11796
|
client: client,
|
|
11060
11797
|
tag: tag,
|
|
11061
11798
|
instanceId: instanceId,
|
|
11062
|
-
|
|
11063
|
-
clientForGdr: clientForGdr,
|
|
11064
|
-
refSurface: refSurface,
|
|
11799
|
+
...operationContext,
|
|
11065
11800
|
clock: clock,
|
|
11066
11801
|
executionContext: executionContext,
|
|
11067
11802
|
telemetry: args.telemetry
|
|
@@ -11082,7 +11817,7 @@ const workflow = {
|
|
|
11082
11817
|
});
|
|
11083
11818
|
},
|
|
11084
11819
|
commitEffectOps: async rawArgs => {
|
|
11085
|
-
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({
|
|
11086
11821
|
idempotencyKey: args.idempotencyKey,
|
|
11087
11822
|
op: "commitEffectOps",
|
|
11088
11823
|
idempotencyTtlMs: args.idempotencyTtlMs
|
|
@@ -11094,9 +11829,7 @@ const workflow = {
|
|
|
11094
11829
|
instanceId: instanceId,
|
|
11095
11830
|
record: record,
|
|
11096
11831
|
now: clock(),
|
|
11097
|
-
|
|
11098
|
-
clientForGdr: clientForGdr,
|
|
11099
|
-
refSurface: refSurface,
|
|
11832
|
+
...operationContext,
|
|
11100
11833
|
clock: clock,
|
|
11101
11834
|
executionContext: executionContext,
|
|
11102
11835
|
telemetry: args.telemetry,
|
|
@@ -11110,10 +11843,8 @@ const workflow = {
|
|
|
11110
11843
|
requestRecord: record,
|
|
11111
11844
|
leaseMs: args.leaseMs ?? DEFAULT_EFFECT_LEASE_MS,
|
|
11112
11845
|
options: engineOptionsForActor({
|
|
11113
|
-
|
|
11846
|
+
...operationContext,
|
|
11114
11847
|
clock: clock,
|
|
11115
|
-
clientForGdr: clientForGdr,
|
|
11116
|
-
refSurface: refSurface,
|
|
11117
11848
|
executionContext: executionContext,
|
|
11118
11849
|
telemetry: args.telemetry
|
|
11119
11850
|
})
|
|
@@ -11121,9 +11852,7 @@ const workflow = {
|
|
|
11121
11852
|
client: client,
|
|
11122
11853
|
tag: tag,
|
|
11123
11854
|
instanceId: instanceId,
|
|
11124
|
-
|
|
11125
|
-
clientForGdr: clientForGdr,
|
|
11126
|
-
refSurface: refSurface,
|
|
11855
|
+
...operationContext,
|
|
11127
11856
|
clock: clock,
|
|
11128
11857
|
executionContext: executionContext,
|
|
11129
11858
|
telemetry: args.telemetry
|
|
@@ -11142,7 +11871,7 @@ const workflow = {
|
|
|
11142
11871
|
});
|
|
11143
11872
|
},
|
|
11144
11873
|
tick: async rawArgs => {
|
|
11145
|
-
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({
|
|
11146
11875
|
client: client,
|
|
11147
11876
|
instanceId: instanceId,
|
|
11148
11877
|
tag: tag
|
|
@@ -11156,9 +11885,7 @@ const workflow = {
|
|
|
11156
11885
|
client: client,
|
|
11157
11886
|
tag: tag,
|
|
11158
11887
|
instanceId: instanceId,
|
|
11159
|
-
|
|
11160
|
-
clientForGdr: clientForGdr,
|
|
11161
|
-
refSurface: refSurface,
|
|
11888
|
+
...operationContext,
|
|
11162
11889
|
clock: clock,
|
|
11163
11890
|
executionContext: executionContext,
|
|
11164
11891
|
telemetry: args.telemetry
|
|
@@ -11178,7 +11905,7 @@ const workflow = {
|
|
|
11178
11905
|
return runCommitVerb({
|
|
11179
11906
|
args: args,
|
|
11180
11907
|
op: "setStage",
|
|
11181
|
-
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}) => {
|
|
11182
11909
|
const result = await setStage({
|
|
11183
11910
|
client: client,
|
|
11184
11911
|
instanceId: instanceId,
|
|
@@ -11194,6 +11921,7 @@ const workflow = {
|
|
|
11194
11921
|
clock: clock,
|
|
11195
11922
|
clientForGdr: clientForGdr,
|
|
11196
11923
|
refSurface: refSurface,
|
|
11924
|
+
memberRolesLoader: memberRolesLoader,
|
|
11197
11925
|
executionContext: executionContext,
|
|
11198
11926
|
telemetry: args.telemetry
|
|
11199
11927
|
})
|
|
@@ -11203,6 +11931,7 @@ const workflow = {
|
|
|
11203
11931
|
actor: actor,
|
|
11204
11932
|
clientForGdr: clientForGdr,
|
|
11205
11933
|
refSurface: refSurface,
|
|
11934
|
+
memberRolesLoader: memberRolesLoader,
|
|
11206
11935
|
clock: clock,
|
|
11207
11936
|
...executionContext !== void 0 ? {
|
|
11208
11937
|
executionContext: executionContext
|
|
@@ -11232,7 +11961,7 @@ const workflow = {
|
|
|
11232
11961
|
return runCommitVerb({
|
|
11233
11962
|
args: args,
|
|
11234
11963
|
op: "abortInstance",
|
|
11235
|
-
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}) => {
|
|
11236
11965
|
const changed = await abortAndPropagate({
|
|
11237
11966
|
client: client,
|
|
11238
11967
|
instanceId: instanceId,
|
|
@@ -11240,6 +11969,7 @@ const workflow = {
|
|
|
11240
11969
|
actor: actor,
|
|
11241
11970
|
clientForGdr: clientForGdr,
|
|
11242
11971
|
refSurface: refSurface,
|
|
11972
|
+
memberRolesLoader: memberRolesLoader,
|
|
11243
11973
|
clock: clock,
|
|
11244
11974
|
...executionContext !== void 0 ? {
|
|
11245
11975
|
executionContext: executionContext
|
|
@@ -11273,7 +12003,7 @@ const workflow = {
|
|
|
11273
12003
|
return runCommitVerb({
|
|
11274
12004
|
args: args,
|
|
11275
12005
|
op: "resetActivity",
|
|
11276
|
-
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}) => {
|
|
11277
12007
|
const result = await resetActivity({
|
|
11278
12008
|
client: client,
|
|
11279
12009
|
instanceId: instanceId,
|
|
@@ -11287,6 +12017,7 @@ const workflow = {
|
|
|
11287
12017
|
clock: clock,
|
|
11288
12018
|
clientForGdr: clientForGdr,
|
|
11289
12019
|
refSurface: refSurface,
|
|
12020
|
+
memberRolesLoader: memberRolesLoader,
|
|
11290
12021
|
executionContext: executionContext,
|
|
11291
12022
|
telemetry: args.telemetry
|
|
11292
12023
|
})
|
|
@@ -11296,6 +12027,7 @@ const workflow = {
|
|
|
11296
12027
|
actor: actor,
|
|
11297
12028
|
clientForGdr: clientForGdr,
|
|
11298
12029
|
refSurface: refSurface,
|
|
12030
|
+
memberRolesLoader: memberRolesLoader,
|
|
11299
12031
|
clock: clock,
|
|
11300
12032
|
...executionContext !== void 0 ? {
|
|
11301
12033
|
executionContext: executionContext
|
|
@@ -11601,7 +12333,7 @@ async function startRequirementVerdict(args) {
|
|
|
11601
12333
|
}
|
|
11602
12334
|
|
|
11603
12335
|
async function startFreshInstance(args) {
|
|
11604
|
-
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({
|
|
11605
12337
|
client: client,
|
|
11606
12338
|
definition: definitionName,
|
|
11607
12339
|
version: version,
|
|
@@ -11625,6 +12357,7 @@ async function startFreshInstance(args) {
|
|
|
11625
12357
|
id: id,
|
|
11626
12358
|
now: now,
|
|
11627
12359
|
refSurface: refSurface,
|
|
12360
|
+
memberRolesLoader: memberRolesLoader,
|
|
11628
12361
|
...perspective !== void 0 ? {
|
|
11629
12362
|
perspective: perspective
|
|
11630
12363
|
} : {}
|
|
@@ -11656,6 +12389,7 @@ async function startFreshInstance(args) {
|
|
|
11656
12389
|
actor: actor,
|
|
11657
12390
|
clientForGdr: clientForGdr,
|
|
11658
12391
|
refSurface: refSurface,
|
|
12392
|
+
memberRolesLoader: memberRolesLoader,
|
|
11659
12393
|
clock: clock,
|
|
11660
12394
|
...executionContext !== void 0 ? {
|
|
11661
12395
|
executionContext: executionContext
|
|
@@ -11711,7 +12445,10 @@ async function assertStartInputs(args) {
|
|
|
11711
12445
|
}
|
|
11712
12446
|
|
|
11713
12447
|
async function resolveStartFields(args) {
|
|
11714
|
-
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
|
+
});
|
|
11715
12452
|
return {
|
|
11716
12453
|
resolvedFields: await resolveDeclaredFields({
|
|
11717
12454
|
entryDefs: definition.fields ?? [],
|
|
@@ -11724,6 +12461,8 @@ async function resolveStartFields(args) {
|
|
|
11724
12461
|
workflowResource: workflowResource,
|
|
11725
12462
|
definitionName: definition.name,
|
|
11726
12463
|
refSurface: refSurface,
|
|
12464
|
+
memberRoles: memberRoles,
|
|
12465
|
+
roleAliases: definition.roleAliases,
|
|
11727
12466
|
...perspective !== void 0 ? {
|
|
11728
12467
|
perspective: perspective
|
|
11729
12468
|
} : {},
|
|
@@ -12364,7 +13103,7 @@ function createInstanceSession(args) {
|
|
|
12364
13103
|
refSurface: evalScope.refSurface
|
|
12365
13104
|
});
|
|
12366
13105
|
}, evaluateWith = async ({held: held, guards: guards, self: self}) => {
|
|
12367
|
-
const {actor: actor, localPrincipalId: localPrincipalId, grants: grants} = await access(), resourceGrants = await subjectResourceGrants({
|
|
13106
|
+
const [{actor: actor, localPrincipalId: localPrincipalId, grants: grants}, attributes] = await Promise.all([ access(), resolveUserAttributes(client) ]), resourceGrants = await subjectResourceGrants({
|
|
12368
13107
|
clientForGdr: evalScope.clientForGdr,
|
|
12369
13108
|
instance: instance
|
|
12370
13109
|
}), normalizedSelf = await normalizeInstanceIdentities({
|
|
@@ -12386,13 +13125,17 @@ function createInstanceSession(args) {
|
|
|
12386
13125
|
} : {},
|
|
12387
13126
|
...grants !== void 0 ? {
|
|
12388
13127
|
grants: grants
|
|
13128
|
+
} : {},
|
|
13129
|
+
...attributes !== void 0 ? {
|
|
13130
|
+
attributes: attributes
|
|
12389
13131
|
} : {}
|
|
12390
13132
|
});
|
|
12391
|
-
}, settleAfterApply = async ({actor: actor, held: held, ranOps: ranOps, scope: scope}) => {
|
|
13133
|
+
}, settleAfterApply = async ({actor: actor, held: held, ranOps: ranOps, scope: scope, memberRolesLoader: memberRolesLoader}) => {
|
|
12392
13134
|
const cascaded = await cascadeHeld({
|
|
12393
13135
|
scope: scope,
|
|
12394
13136
|
actor: actor,
|
|
12395
|
-
held: held
|
|
13137
|
+
held: held,
|
|
13138
|
+
memberRolesLoader: memberRolesLoader
|
|
12396
13139
|
});
|
|
12397
13140
|
return instance = await reload({
|
|
12398
13141
|
client: scope.client,
|
|
@@ -12406,12 +13149,13 @@ function createInstanceSession(args) {
|
|
|
12406
13149
|
ranOps: ranOps
|
|
12407
13150
|
} : {}
|
|
12408
13151
|
};
|
|
12409
|
-
}, cascadeHeld = ({scope: scope, actor: actor, held: held}) => cascade({
|
|
13152
|
+
}, cascadeHeld = ({scope: scope, actor: actor, held: held, memberRolesLoader: memberRolesLoader}) => cascade({
|
|
12410
13153
|
client: scope.client,
|
|
12411
13154
|
instanceId: instance._id,
|
|
12412
13155
|
actor: actor,
|
|
12413
13156
|
clientForGdr: scope.clientForGdr,
|
|
12414
13157
|
refSurface: scope.refSurface,
|
|
13158
|
+
memberRolesLoader: memberRolesLoader,
|
|
12415
13159
|
...clock !== void 0 ? {
|
|
12416
13160
|
clock: clock
|
|
12417
13161
|
} : {},
|
|
@@ -12508,6 +13252,7 @@ function createInstanceSession(args) {
|
|
|
12508
13252
|
},
|
|
12509
13253
|
tick() {
|
|
12510
13254
|
return commit(async ({actor: actor, localPrincipalId: localPrincipalId}, held) => {
|
|
13255
|
+
const memberRolesLoader = createAssignmentMemberRolesLoader(tickScope.client);
|
|
12511
13256
|
await assertInstanceWriteAllowed({
|
|
12512
13257
|
instance: instance,
|
|
12513
13258
|
guards: heldGuards,
|
|
@@ -12523,7 +13268,8 @@ function createInstanceSession(args) {
|
|
|
12523
13268
|
}), cascaded = await cascadeHeld({
|
|
12524
13269
|
scope: tickScope,
|
|
12525
13270
|
actor: actor,
|
|
12526
|
-
held: held
|
|
13271
|
+
held: held,
|
|
13272
|
+
memberRolesLoader: memberRolesLoader
|
|
12527
13273
|
});
|
|
12528
13274
|
return instance = await reload({
|
|
12529
13275
|
client: tickScope.client,
|
|
@@ -12542,6 +13288,7 @@ function createInstanceSession(args) {
|
|
|
12542
13288
|
},
|
|
12543
13289
|
fireAction({activity: activity, action: action, params: params}) {
|
|
12544
13290
|
return commit(async ({actor: actor, localPrincipalId: localPrincipalId}, held) => {
|
|
13291
|
+
const memberRolesLoader = createAssignmentMemberRolesLoader(fireScope.client);
|
|
12545
13292
|
assertActionAllowed({
|
|
12546
13293
|
evaluation: await evaluateWith({
|
|
12547
13294
|
held: held,
|
|
@@ -12562,6 +13309,7 @@ function createInstanceSession(args) {
|
|
|
12562
13309
|
} : {},
|
|
12563
13310
|
clientForGdr: fireScope.clientForGdr,
|
|
12564
13311
|
refSurface: fireScope.refSurface,
|
|
13312
|
+
memberRolesLoader: memberRolesLoader,
|
|
12565
13313
|
...grants !== void 0 ? {
|
|
12566
13314
|
grants: grants
|
|
12567
13315
|
} : {},
|
|
@@ -12581,7 +13329,8 @@ function createInstanceSession(args) {
|
|
|
12581
13329
|
actor: actor,
|
|
12582
13330
|
held: held,
|
|
12583
13331
|
ranOps: ranOps,
|
|
12584
|
-
scope: fireScope
|
|
13332
|
+
scope: fireScope,
|
|
13333
|
+
memberRolesLoader: memberRolesLoader
|
|
12585
13334
|
});
|
|
12586
13335
|
return telemetry.log(WorkflowActionFired, actionFiredData({
|
|
12587
13336
|
instance: preOp,
|
|
@@ -12603,6 +13352,7 @@ function createInstanceSession(args) {
|
|
|
12603
13352
|
return Promise.reject(err);
|
|
12604
13353
|
}
|
|
12605
13354
|
return commit(async ({actor: actor, localPrincipalId: localPrincipalId}, held) => {
|
|
13355
|
+
const memberRolesLoader = createAssignmentMemberRolesLoader(editScope.client);
|
|
12606
13356
|
assertEditAllowed(await evaluateWith({
|
|
12607
13357
|
held: held,
|
|
12608
13358
|
guards: heldGuards,
|
|
@@ -12624,6 +13374,7 @@ function createInstanceSession(args) {
|
|
|
12624
13374
|
} : {},
|
|
12625
13375
|
clientForGdr: editScope.clientForGdr,
|
|
12626
13376
|
refSurface: editScope.refSurface,
|
|
13377
|
+
memberRolesLoader: memberRolesLoader,
|
|
12627
13378
|
...grants !== void 0 ? {
|
|
12628
13379
|
grants: grants
|
|
12629
13380
|
} : {},
|
|
@@ -12640,7 +13391,8 @@ function createInstanceSession(args) {
|
|
|
12640
13391
|
actor: actor,
|
|
12641
13392
|
held: held,
|
|
12642
13393
|
ranOps: ranOps,
|
|
12643
|
-
scope: editScope
|
|
13394
|
+
scope: editScope,
|
|
13395
|
+
memberRolesLoader: memberRolesLoader
|
|
12644
13396
|
});
|
|
12645
13397
|
return telemetry.log(WorkflowFieldEdited, fieldEditedData({
|
|
12646
13398
|
instance: preOp,
|
|
@@ -12959,8 +13711,11 @@ function attributeMember({member: member, group: group, chain: chain}) {
|
|
|
12959
13711
|
}
|
|
12960
13712
|
|
|
12961
13713
|
function diffEntry({def: rawDef, latestRaw: latestRaw, target: target}) {
|
|
12962
|
-
|
|
12963
|
-
|
|
13714
|
+
const def = parseDefinitionInput(rawDef, "diffEntry");
|
|
13715
|
+
assertReaderModelAcknowledgement(target.expectedMinReaderModel, {
|
|
13716
|
+
requiredMinReaderModel: requiredDefinitionReaderModel([ def ])
|
|
13717
|
+
});
|
|
13718
|
+
const plan = planDefinitionDeploy({
|
|
12964
13719
|
def: def,
|
|
12965
13720
|
latest: asLatest(latestRaw),
|
|
12966
13721
|
target: target
|
|
@@ -12991,10 +13746,13 @@ function asLatest(raw) {
|
|
|
12991
13746
|
}
|
|
12992
13747
|
|
|
12993
13748
|
async function computeDiffEntries({client: client, defs: defs, target: target}) {
|
|
12994
|
-
|
|
13749
|
+
const definitions = defs.map(def => parseDefinitionInput(def, "computeDiffEntries"));
|
|
13750
|
+
assertReaderModelAcknowledgement(target.expectedMinReaderModel, {
|
|
13751
|
+
requiredMinReaderModel: requiredDefinitionReaderModel(definitions)
|
|
13752
|
+
});
|
|
12995
13753
|
const entries = [];
|
|
12996
|
-
for (const
|
|
12997
|
-
const
|
|
13754
|
+
for (const def of definitions) {
|
|
13755
|
+
const latest = await loadLatestDeployed({
|
|
12998
13756
|
client: client,
|
|
12999
13757
|
definition: def.name,
|
|
13000
13758
|
tag: target.tag
|
|
@@ -13081,7 +13839,7 @@ const HISTORY_DISPLAY = {
|
|
|
13081
13839
|
},
|
|
13082
13840
|
opApplied: {
|
|
13083
13841
|
title: "Op applied",
|
|
13084
|
-
description: "An
|
|
13842
|
+
description: "An action, direct edit, or effect completion executed an operation and recorded its audit payload."
|
|
13085
13843
|
},
|
|
13086
13844
|
fieldQueryDiscarded: {
|
|
13087
13845
|
title: "Query result discarded",
|
|
@@ -13186,6 +13944,10 @@ const HISTORY_DISPLAY = {
|
|
|
13186
13944
|
title: "Set field entry",
|
|
13187
13945
|
description: "Overwrite a field entry's value with a resolved value expression."
|
|
13188
13946
|
},
|
|
13947
|
+
"field.setIfMissing": {
|
|
13948
|
+
title: "Set field entry if missing",
|
|
13949
|
+
description: "Set a nullable field entry's value only when it is currently null or undefined; array, assignees, and doc.refs entries are always arrays and are not supported."
|
|
13950
|
+
},
|
|
13189
13951
|
"field.unset": {
|
|
13190
13952
|
title: "Unset field entry",
|
|
13191
13953
|
description: "Reset a field entry to its default (null for scalars, [] for array kinds)."
|
|
@@ -13194,6 +13956,14 @@ const HISTORY_DISPLAY = {
|
|
|
13194
13956
|
title: "Append to field entry",
|
|
13195
13957
|
description: "Push a resolved item onto an array-kind entry (array, assignees, doc.refs)."
|
|
13196
13958
|
},
|
|
13959
|
+
"field.inc": {
|
|
13960
|
+
title: "Increment field entry",
|
|
13961
|
+
description: "Add a resolved numeric delta, defaulting to 1, to a number entry that already holds a finite number."
|
|
13962
|
+
},
|
|
13963
|
+
"field.dec": {
|
|
13964
|
+
title: "Decrement field entry",
|
|
13965
|
+
description: "Subtract a resolved numeric delta, defaulting to 1, from a number entry that already holds a finite number."
|
|
13966
|
+
},
|
|
13197
13967
|
"field.updateWhere": {
|
|
13198
13968
|
title: "Update matching rows",
|
|
13199
13969
|
description: "Merge declared sub-fields into rows of an `array` entry that match the `where` condition (`array` only — `doc.refs`/`assignees` rows are engine-shaped)."
|
|
@@ -13319,6 +14089,8 @@ exports.CONDITION_VARS = invariants.CONDITION_VARS;
|
|
|
13319
14089
|
|
|
13320
14090
|
exports.ContractViolationError = invariants.ContractViolationError;
|
|
13321
14091
|
|
|
14092
|
+
exports.DECISION_SEMANTICS = invariants.DECISION_SEMANTICS;
|
|
14093
|
+
|
|
13322
14094
|
exports.DEFAULT_TRANSITION_WHEN = invariants.DEFAULT_TRANSITION_WHEN;
|
|
13323
14095
|
|
|
13324
14096
|
exports.DRIVER_KINDS = invariants.DRIVER_KINDS;
|
|
@@ -13345,6 +14117,8 @@ exports.PersistedDocShapeError = invariants.PersistedDocShapeError;
|
|
|
13345
14117
|
|
|
13346
14118
|
exports.RESERVED_CONDITION_VARS = invariants.RESERVED_CONDITION_VARS;
|
|
13347
14119
|
|
|
14120
|
+
exports.SIGNAL_SEMANTICS = invariants.SIGNAL_SEMANTICS;
|
|
14121
|
+
|
|
13348
14122
|
exports.START_FILTER_VARS = invariants.START_FILTER_VARS;
|
|
13349
14123
|
|
|
13350
14124
|
exports.START_REQUIREMENT_VARS = invariants.START_REQUIREMENT_VARS;
|
|
@@ -13357,6 +14131,8 @@ exports.WORKFLOW_DEFINITION_TYPE = invariants.WORKFLOW_DEFINITION_TYPE;
|
|
|
13357
14131
|
|
|
13358
14132
|
exports.WorkflowError = invariants.WorkflowError;
|
|
13359
14133
|
|
|
14134
|
+
exports.actorFulfillsRole = invariants.actorFulfillsRole;
|
|
14135
|
+
|
|
13360
14136
|
exports.classifyPrincipalId = invariants.classifyPrincipalId;
|
|
13361
14137
|
|
|
13362
14138
|
exports.clientConfigFromResource = invariants.clientConfigFromResource;
|
|
@@ -13571,6 +14347,8 @@ exports.ConcurrentFireActionError = ConcurrentFireActionError;
|
|
|
13571
14347
|
|
|
13572
14348
|
exports.DATA_MODEL_CHANGES = DATA_MODEL_CHANGES;
|
|
13573
14349
|
|
|
14350
|
+
exports.DATA_MODEL_MAX_READER = DATA_MODEL_MAX_READER;
|
|
14351
|
+
|
|
13574
14352
|
exports.DATA_MODEL_MIN_READER = DATA_MODEL_MIN_READER;
|
|
13575
14353
|
|
|
13576
14354
|
exports.DATA_MODEL_VERSION = DATA_MODEL_VERSION;
|
|
@@ -13663,6 +14441,8 @@ exports.WorkflowFieldEdited = WorkflowFieldEdited;
|
|
|
13663
14441
|
|
|
13664
14442
|
exports.WorkflowInstanceAborted = WorkflowInstanceAborted;
|
|
13665
14443
|
|
|
14444
|
+
exports.WorkflowInstancePreviewSchema = WorkflowInstancePreviewSchema;
|
|
14445
|
+
|
|
13666
14446
|
exports.WorkflowInstanceSchema = WorkflowInstanceSchema;
|
|
13667
14447
|
|
|
13668
14448
|
exports.WorkflowInstanceStarted = WorkflowInstanceStarted;
|
|
@@ -13777,6 +14557,8 @@ exports.documentActionDenials = documentActionDenials;
|
|
|
13777
14557
|
|
|
13778
14558
|
exports.documentPrefilter = documentPrefilter;
|
|
13779
14559
|
|
|
14560
|
+
exports.documentStuckCause = documentStuckCause;
|
|
14561
|
+
|
|
13780
14562
|
exports.effectOutputsMap = effectOutputsMap;
|
|
13781
14563
|
|
|
13782
14564
|
exports.entryDocRefs = entryDocRefs;
|
|
@@ -13793,10 +14575,14 @@ exports.explainStartRequirement = explainStartRequirement;
|
|
|
13793
14575
|
|
|
13794
14576
|
exports.fieldTreeShape = fieldTreeShape;
|
|
13795
14577
|
|
|
14578
|
+
exports.findActivityNode = findActivityNode;
|
|
14579
|
+
|
|
13796
14580
|
exports.findCurrentActivityEntry = findCurrentActivityEntry;
|
|
13797
14581
|
|
|
13798
14582
|
exports.findOpenStageEntry = findOpenStageEntry;
|
|
13799
14583
|
|
|
14584
|
+
exports.findStageNode = findStageNode;
|
|
14585
|
+
|
|
13800
14586
|
exports.groupSitesOf = groupSitesOf;
|
|
13801
14587
|
|
|
13802
14588
|
exports.guardMatches = guardMatches;
|
|
@@ -13815,10 +14601,14 @@ exports.inFlightFilter = inFlightFilter;
|
|
|
13815
14601
|
|
|
13816
14602
|
exports.initialFieldIssues = initialFieldIssues;
|
|
13817
14603
|
|
|
14604
|
+
exports.instanceChangesQuery = instanceChangesQuery;
|
|
14605
|
+
|
|
13818
14606
|
exports.instanceDocId = instanceDocId;
|
|
13819
14607
|
|
|
13820
14608
|
exports.instanceGuardQuery = instanceGuardQuery;
|
|
13821
14609
|
|
|
14610
|
+
exports.instancePreviewsQuery = instancePreviewsQuery;
|
|
14611
|
+
|
|
13822
14612
|
exports.instanceWatchesDocument = instanceWatchesDocument;
|
|
13823
14613
|
|
|
13824
14614
|
exports.instancesGuardQuery = instancesGuardQuery;
|
|
@@ -13873,6 +14663,8 @@ exports.parseGuardDocument = parseGuardDocument;
|
|
|
13873
14663
|
|
|
13874
14664
|
exports.parseInstanceDocument = parseInstanceDocument;
|
|
13875
14665
|
|
|
14666
|
+
exports.parseInstancePreviewDocument = parseInstancePreviewDocument;
|
|
14667
|
+
|
|
13876
14668
|
exports.processShellUserProperties = processShellUserProperties;
|
|
13877
14669
|
|
|
13878
14670
|
exports.projectStartSliceRow = projectStartSliceRow;
|
|
@@ -13881,12 +14673,16 @@ exports.projectToWatchRef = projectToWatchRef;
|
|
|
13881
14673
|
|
|
13882
14674
|
exports.readInstanceDoc = readInstanceDoc;
|
|
13883
14675
|
|
|
14676
|
+
exports.readInstancePreviewDoc = readInstancePreviewDoc;
|
|
14677
|
+
|
|
13884
14678
|
exports.readsRaw = readsRaw;
|
|
13885
14679
|
|
|
13886
14680
|
exports.refsOf = refsOf;
|
|
13887
14681
|
|
|
13888
14682
|
exports.remediationsFor = remediationsFor;
|
|
13889
14683
|
|
|
14684
|
+
exports.requiredDefinitionReaderModel = requiredDefinitionReaderModel;
|
|
14685
|
+
|
|
13890
14686
|
exports.requiredModelFeatures = requiredModelFeatures;
|
|
13891
14687
|
|
|
13892
14688
|
exports.requiredReaderModel = requiredReaderModel;
|
|
@@ -13899,6 +14695,8 @@ exports.resolveClientActor = resolveClientActor;
|
|
|
13899
14695
|
|
|
13900
14696
|
exports.resolveFieldEntry = resolveFieldEntry$1;
|
|
13901
14697
|
|
|
14698
|
+
exports.resolveUserAttributes = resolveUserAttributes;
|
|
14699
|
+
|
|
13902
14700
|
exports.retractStageGuards = retractStageGuards;
|
|
13903
14701
|
|
|
13904
14702
|
exports.silentLogger = silentLogger;
|