@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.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { rethrowWithContext, andConditions, deriveActivityKind,
|
|
1
|
+
import { rethrowWithContext, andConditions, deriveActivityKind, CALLER_BOUND_VARS, START_REQUIREMENT_VARS, CONDITION_VARS, isSubjectEntry, isUnevaluable, ContractViolationError, isStartableDefinition, conditionFieldReadNames, isGdr, errorMessage, conditionParameterNames, START_FILTER_VARS, gdrFromResource, selfGdr, isSingleDocRefKind, actorFulfillsRole, toBareId, WorkflowError, sameResource, resourceFromParsed, tryParseGdr, isTerminalActivityStatus, FieldValueShapeError, validateFieldValue, validateFieldAppendItem, isAlwaysArrayFieldKind, evaluateCondition, isRecord, isSingleDocRefEntry, isAssignmentFieldEntry, choiceValueIssues, scalarValidationIssues, StoredFieldOpSchema, formatIssues, conditionSyntaxIssues, checkWorkflowInvariants, formatIssuePath, isGuardReadExpr, conditionEffectReads, EFFECTS_READ, datasetResourceParts, assignmentKindAcceptsRoles, evaluatePredicates, WORKFLOW_DEFINITION_TYPE, tagScopeFilter, isCascadeFired, classifyPrincipalId, directoryBridgeId, parseGdr, isGdrUri, gdrRef, isInputSourced, parseFieldValue, VersionSpecificDatasetGdrError, toPhysicalGdr, isBareSeedId, NonEmptyString, tolerantEntries, FIELD_VALUE_KINDS, tolerantObject, ActorShape, IsoTimestamp, ACTIVITY_STATUSES, GdrShape, DRIVER_KINDS, FIELD_SCOPES, fieldValueSchemas, parsePersistedDoc, ACTOR_KINDS, InstanceNotFoundError, evaluateConditionOutcome, runGroq, FIELD_READ, MUTATION_GUARD_ACTIONS, resourceGdr, resourceFromGdrUri, refTypeIssues, rejectedRefTypes, DOCUMENT_VALUE_PERMISSIONS, lakePrincipalId, firstCarriedGlobalId, driverKind, EffectNotFoundError, deriveExecutorClassification, validateTag, extractDocumentId, parseStoredDefinition, validateResourceAliasName, labelFor, DefinitionNotFoundError, definitionDocId, SpawnContractsInvalidError, gdrResourcePrefix, RESOURCE_ALIAS_NAME_SOURCE, DefinitionInUseError, isParseableInstant, groupMembershipNames } from "./_chunks-es/invariants.js";
|
|
2
2
|
|
|
3
|
-
import { ACTION_SEMANTICS, ACTIVITY_KINDS, ANONYMOUS_IDENTITY, DEFAULT_TRANSITION_WHEN, EXECUTOR_CLASSIFICATIONS, FILTER_SCOPE_VARS, GROUP_KINDS, GUARD_PREDICATE_VARS, PersistedDocShapeError, RESERVED_CONDITION_VARS, SYSTEM_IDENTITY, clientConfigFromResource, gdrUri, isNotesEntry, isTodoListEntry, isTodoListItem, parseResourceGdr, readsRootDocument, refCanvas, refDashboard, refDataset, refKindAcceptsTypes, refMediaLibrary, releaseDocId, releaseRef, resourceAliasesToMap, schemaTreeShape, startKindOf } from "./_chunks-es/invariants.js";
|
|
3
|
+
import { ACTION_SEMANTICS, ACTIVITY_KINDS, ANONYMOUS_IDENTITY, DECISION_SEMANTICS, DEFAULT_TRANSITION_WHEN, EXECUTOR_CLASSIFICATIONS, FILTER_SCOPE_VARS, GROUP_KINDS, GUARD_PREDICATE_VARS, PersistedDocShapeError, RESERVED_CONDITION_VARS, SIGNAL_SEMANTICS, SYSTEM_IDENTITY, clientConfigFromResource, gdrUri, isNotesEntry, isTodoListEntry, isTodoListItem, parseResourceGdr, readsRootDocument, refCanvas, refDashboard, refDataset, refKindAcceptsTypes, refMediaLibrary, releaseDocId, releaseRef, resourceAliasesToMap, schemaTreeShape, startKindOf } from "./_chunks-es/invariants.js";
|
|
4
4
|
|
|
5
5
|
import { atomNode, dedupeBy, analyzeCondition, atomReadsDataset, checklistLines as checklistLines$1, phrase, quoted, listAnd, describeAtom as describeAtom$1, describeCondition as describeCondition$1, guillemets, formatValue, humanize, listOr, scopeReadOf, describeRead, explainCondition, dedupeReads, whatIfCondition, MAX_COUNTERFACTUAL_INDEX } from "@sanity/groq-condition-describe";
|
|
6
6
|
|
|
@@ -130,6 +130,9 @@ function resolveFieldSite(site, stage) {
|
|
|
130
130
|
...site.entry.validation !== void 0 ? {
|
|
131
131
|
validation: site.entry.validation
|
|
132
132
|
} : {},
|
|
133
|
+
...site.entry.roles !== void 0 ? {
|
|
134
|
+
roles: site.entry.roles
|
|
135
|
+
} : {},
|
|
133
136
|
ref: {
|
|
134
137
|
scope: site.scope,
|
|
135
138
|
field: site.entry.name
|
|
@@ -266,58 +269,58 @@ function resolveTelemetry(telemetry) {
|
|
|
266
269
|
}
|
|
267
270
|
|
|
268
271
|
const HIGH_FREQUENCY_SAMPLE_MS = 6e4, WorkflowDefinitionDeployed = defineWorkflowEvent({
|
|
269
|
-
name: "
|
|
272
|
+
name: "Workflows Definition Deployed",
|
|
270
273
|
version: 1,
|
|
271
274
|
description: "A definition went through a deploy — status distinguishes a newly minted version from an unchanged redeploy"
|
|
272
275
|
}), WorkflowInstanceStarted = defineWorkflowEvent({
|
|
273
|
-
name: "
|
|
276
|
+
name: "Workflows Instance Started",
|
|
274
277
|
version: 1,
|
|
275
278
|
description: "A workflow instance was started from a deployed definition"
|
|
276
279
|
}), WorkflowStageTransitioned = defineWorkflowEvent({
|
|
277
|
-
name: "
|
|
280
|
+
name: "Workflows Stage Transitioned",
|
|
278
281
|
version: 1,
|
|
279
282
|
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"
|
|
280
283
|
}), WorkflowActionFired = defineWorkflowEvent({
|
|
281
|
-
name: "
|
|
284
|
+
name: "Workflows Action Fired",
|
|
282
285
|
version: 1,
|
|
283
286
|
description: "An action was fired against an activity"
|
|
284
287
|
}), WorkflowFieldEdited = defineWorkflowEvent({
|
|
285
|
-
name: "
|
|
288
|
+
name: "Workflows Field Edited",
|
|
286
289
|
version: 1,
|
|
287
290
|
description: "A declared-editable field was edited through the generic edit seam",
|
|
288
291
|
maxSampleRate: HIGH_FREQUENCY_SAMPLE_MS
|
|
289
292
|
}), WorkflowInstanceTicked = defineWorkflowEvent({
|
|
290
|
-
name: "
|
|
293
|
+
name: "Workflows Instance Ticked",
|
|
291
294
|
version: 1,
|
|
292
295
|
description: "An instance was re-evaluated for auto-transitions and due waits",
|
|
293
296
|
maxSampleRate: HIGH_FREQUENCY_SAMPLE_MS
|
|
294
297
|
}), WorkflowEffectsDrained = defineWorkflowEvent({
|
|
295
|
-
name: "
|
|
298
|
+
name: "Workflows Effects Drained",
|
|
296
299
|
version: 1,
|
|
297
300
|
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"
|
|
298
301
|
}), WorkflowEffectStateReported = defineWorkflowEvent({
|
|
299
|
-
name: "
|
|
302
|
+
name: "Workflows Effect State Reported",
|
|
300
303
|
version: 1,
|
|
301
304
|
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",
|
|
302
305
|
maxSampleRate: HIGH_FREQUENCY_SAMPLE_MS
|
|
303
306
|
}), WorkflowEffectCompleted = defineWorkflowEvent({
|
|
304
|
-
name: "
|
|
307
|
+
name: "Workflows Effect Completed",
|
|
305
308
|
version: 1,
|
|
306
|
-
description: "An effect outcome was recorded — reported directly through completeEffect, or cancelled by the abort verb (external runtimes; engine-drained effects surface via
|
|
309
|
+
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)"
|
|
307
310
|
}), WorkflowInstanceAborted = defineWorkflowEvent({
|
|
308
|
-
name: "
|
|
311
|
+
name: "Workflows Instance Aborted",
|
|
309
312
|
version: 1,
|
|
310
313
|
description: "The abort admin override was invoked (changed: false = instance already terminal)"
|
|
311
314
|
}), WorkflowStageSet = defineWorkflowEvent({
|
|
312
|
-
name: "
|
|
315
|
+
name: "Workflows Stage Set",
|
|
313
316
|
version: 1,
|
|
314
317
|
description: "The set-stage admin override was invoked (changed: false = already at the target stage)"
|
|
315
318
|
}), WorkflowActivityReset = defineWorkflowEvent({
|
|
316
|
-
name: "
|
|
319
|
+
name: "Workflows Activity Reset",
|
|
317
320
|
version: 1,
|
|
318
321
|
description: "The reset-activity admin override was invoked (changed: false = already at the target status, or the instance was terminal)"
|
|
319
322
|
}), WorkflowDefinitionDeleted = defineWorkflowEvent({
|
|
320
|
-
name: "
|
|
323
|
+
name: "Workflows Definition Deleted",
|
|
321
324
|
version: 1,
|
|
322
325
|
description: "A deployed definition (or one version of it) was removed via the admin verb"
|
|
323
326
|
});
|
|
@@ -435,240 +438,6 @@ function fieldEditedData(args) {
|
|
|
435
438
|
};
|
|
436
439
|
}
|
|
437
440
|
|
|
438
|
-
const DATA_MODEL_VERSION = 5, DATA_MODEL_MIN_READER = 4, READER_MODEL_ROLLOUT_URL = "https://www.sanity.io/docs/editorial-workflows/prerelease";
|
|
439
|
-
|
|
440
|
-
class ReaderModelAcknowledgementError extends WorkflowError {
|
|
441
|
-
code="WORKFLOW_READER_MODEL_ACKNOWLEDGEMENT_MISMATCH";
|
|
442
|
-
expectedMinReaderModel;
|
|
443
|
-
engineMinReaderModel=DATA_MODEL_MIN_READER;
|
|
444
|
-
engineModelVersion=DATA_MODEL_VERSION;
|
|
445
|
-
documentationUrl=READER_MODEL_ROLLOUT_URL;
|
|
446
|
-
constructor(expectedMinReaderModel, context = "Deployment") {
|
|
447
|
-
const expected = expectedMinReaderModel === void 0 ? "missing" : String(expectedMinReaderModel);
|
|
448
|
-
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}`),
|
|
449
|
-
this.name = "ReaderModelAcknowledgementError", this.expectedMinReaderModel = expectedMinReaderModel;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
function assertReaderModelAcknowledgement(expectedMinReaderModel, context) {
|
|
454
|
-
if (typeof expectedMinReaderModel != "number" || !Number.isFinite(expectedMinReaderModel) || !Number.isInteger(expectedMinReaderModel) || expectedMinReaderModel < 0 || expectedMinReaderModel !== DATA_MODEL_MIN_READER) throw new ReaderModelAcknowledgementError(expectedMinReaderModel, context);
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
const DATA_MODEL_CHANGES = Object.freeze([ Object.freeze({
|
|
458
|
-
id: "governed-model-stamps",
|
|
459
|
-
introducedInModel: 1,
|
|
460
|
-
minReaderModel: 0,
|
|
461
|
-
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
462
|
-
compatibility: "additive",
|
|
463
|
-
applicability: "unconditional",
|
|
464
|
-
summary: "Definition and instance documents carry model provenance and reader-floor stamps."
|
|
465
|
-
}), Object.freeze({
|
|
466
|
-
id: "subject-field-kind",
|
|
467
|
-
introducedInModel: 2,
|
|
468
|
-
minReaderModel: 0,
|
|
469
|
-
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
470
|
-
compatibility: "additive",
|
|
471
|
-
applicability: "detectable",
|
|
472
|
-
summary: "A workflow-level subject field identifies the document a workflow is about."
|
|
473
|
-
}), Object.freeze({
|
|
474
|
-
id: "typed-scalar-choice-lists",
|
|
475
|
-
introducedInModel: 2,
|
|
476
|
-
minReaderModel: 2,
|
|
477
|
-
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
478
|
-
compatibility: "reader-floor",
|
|
479
|
-
applicability: "detectable",
|
|
480
|
-
summary: "Scalar fields may constrain writes to a persisted typed choice list."
|
|
481
|
-
}), Object.freeze({
|
|
482
|
-
id: "action-semantics",
|
|
483
|
-
introducedInModel: 2,
|
|
484
|
-
minReaderModel: 0,
|
|
485
|
-
documentTypes: Object.freeze([ "definition" ]),
|
|
486
|
-
compatibility: "additive",
|
|
487
|
-
applicability: "detectable",
|
|
488
|
-
summary: "Ordinary actions may carry a closed bag of advisory workflow semantics."
|
|
489
|
-
}), Object.freeze({
|
|
490
|
-
id: "inclusive-scalar-bounds",
|
|
491
|
-
introducedInModel: 2,
|
|
492
|
-
minReaderModel: 2,
|
|
493
|
-
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
494
|
-
compatibility: "reader-floor",
|
|
495
|
-
applicability: "detectable",
|
|
496
|
-
summary: "String, text, and number values may carry persisted inclusive bounds."
|
|
497
|
-
}), Object.freeze({
|
|
498
|
-
id: "progress-field-kind",
|
|
499
|
-
introducedInModel: 3,
|
|
500
|
-
minReaderModel: 0,
|
|
501
|
-
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
502
|
-
compatibility: "additive",
|
|
503
|
-
applicability: "detectable",
|
|
504
|
-
summary: "A progress field kind carries application-defined 0–100 completion."
|
|
505
|
-
}), Object.freeze({
|
|
506
|
-
id: "effect-claim-tokens",
|
|
507
|
-
introducedInModel: 3,
|
|
508
|
-
minReaderModel: 0,
|
|
509
|
-
documentTypes: Object.freeze([ "instance" ]),
|
|
510
|
-
compatibility: "additive",
|
|
511
|
-
applicability: "detectable",
|
|
512
|
-
summary: "Pending-effect claims carry an exact-claim token gating mid-dispatch state reports."
|
|
513
|
-
}), Object.freeze({
|
|
514
|
-
id: "classified-principal-ids",
|
|
515
|
-
introducedInModel: 4,
|
|
516
|
-
minReaderModel: 4,
|
|
517
|
-
documentTypes: Object.freeze([ "instance" ]),
|
|
518
|
-
compatibility: "reader-floor",
|
|
519
|
-
applicability: "unconditional",
|
|
520
|
-
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."
|
|
521
|
-
}), Object.freeze({
|
|
522
|
-
id: "readiness-requirements",
|
|
523
|
-
introducedInModel: 4,
|
|
524
|
-
minReaderModel: 4,
|
|
525
|
-
documentTypes: Object.freeze([ "definition" ]),
|
|
526
|
-
compatibility: "reader-floor",
|
|
527
|
-
applicability: "detectable",
|
|
528
|
-
summary: "Start and activity readiness use named polymorphic requirement arrays."
|
|
529
|
-
}), Object.freeze({
|
|
530
|
-
id: "due-date-field-kinds",
|
|
531
|
-
introducedInModel: 5,
|
|
532
|
-
minReaderModel: 0,
|
|
533
|
-
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
534
|
-
compatibility: "additive",
|
|
535
|
-
applicability: "detectable",
|
|
536
|
-
summary: "Due-date field kinds (dueDate, dueDatetime) mark a level deadline, elevated aliases of date/datetime carrying the same stored value."
|
|
537
|
-
}) ]);
|
|
538
|
-
|
|
539
|
-
function recordOf(value) {
|
|
540
|
-
return value !== null && typeof value == "object" && !Array.isArray(value) ? value : void 0;
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
function recordsAt(record, key) {
|
|
544
|
-
const value = record[key];
|
|
545
|
-
return Array.isArray(value) ? value.map(recordOf).filter(item => item !== void 0) : [];
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
function nestedFieldEntries(entries) {
|
|
549
|
-
return entries.flatMap(entry => [ entry, ...nestedFieldEntries(recordsAt(entry, "fields")), ...nestedFieldEntries(recordsAt(entry, "of")) ]);
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
function parsedDefinitionSnapshot(root) {
|
|
553
|
-
if (typeof root.definitionSnapshot == "string") return recordOf(parseDefinitionSnapshotValue({
|
|
554
|
-
_id: typeof root._id == "string" ? root._id : "<unknown instance>",
|
|
555
|
-
definitionSnapshot: root.definitionSnapshot
|
|
556
|
-
}));
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
function persistedFieldEntries(document) {
|
|
560
|
-
const root = recordOf(document);
|
|
561
|
-
if (root === void 0) return [];
|
|
562
|
-
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"));
|
|
563
|
-
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")) ]);
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
function hasChoiceList(document) {
|
|
567
|
-
return persistedFieldEntries(document).some(entry => {
|
|
568
|
-
const options = recordOf(entry.options);
|
|
569
|
-
return options !== void 0 && Array.isArray(options.list);
|
|
570
|
-
});
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
function hasFieldKind(document, kind) {
|
|
574
|
-
return persistedFieldEntries(document).some(entry => entry.type === kind || entry._type === kind);
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
function hasActionSemantics(document) {
|
|
578
|
-
const root = recordOf(document);
|
|
579
|
-
return root === void 0 ? !1 : recordsAt(root, "stages").flatMap(stage => recordsAt(stage, "activities")).flatMap(activity => recordsAt(activity, "actions")).some(action => Array.isArray(action.semantics));
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
function hasScalarValidation(document) {
|
|
583
|
-
return persistedFieldEntries(document).some(entry => {
|
|
584
|
-
const validation = recordOf(entry.validation);
|
|
585
|
-
return typeof validation?.min == "number" || typeof validation?.max == "number";
|
|
586
|
-
});
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
function hasClaimTokens(document) {
|
|
590
|
-
const root = recordOf(document);
|
|
591
|
-
return root === void 0 ? !1 : recordsAt(root, "pendingEffects").some(entry => {
|
|
592
|
-
const claim = recordOf(entry.claim);
|
|
593
|
-
return claim !== void 0 && typeof claim.claimToken == "string";
|
|
594
|
-
});
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
function hasReadinessRequirements(document) {
|
|
598
|
-
const root = recordOf(document);
|
|
599
|
-
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)));
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
const featureDetectors = {
|
|
603
|
-
"governed-model-stamps": () => !0,
|
|
604
|
-
"subject-field-kind": document => hasFieldKind(document, "subject"),
|
|
605
|
-
"typed-scalar-choice-lists": hasChoiceList,
|
|
606
|
-
"action-semantics": hasActionSemantics,
|
|
607
|
-
"inclusive-scalar-bounds": hasScalarValidation,
|
|
608
|
-
"progress-field-kind": document => hasFieldKind(document, "progress"),
|
|
609
|
-
"effect-claim-tokens": hasClaimTokens,
|
|
610
|
-
"classified-principal-ids": () => !0,
|
|
611
|
-
"readiness-requirements": hasReadinessRequirements,
|
|
612
|
-
"due-date-field-kinds": document => hasFieldKind(document, "dueDate") || hasFieldKind(document, "dueDatetime")
|
|
613
|
-
};
|
|
614
|
-
|
|
615
|
-
function requiredModelFeatures(documentType, document) {
|
|
616
|
-
return DATA_MODEL_CHANGES.filter(change => change.documentTypes.some(candidate => candidate === documentType) && featureDetectors[change.id](document));
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
function requiredReaderModel(documentType, document) {
|
|
620
|
-
return Math.max(0, ...requiredModelFeatures(documentType, document).map(change => change.minReaderModel));
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
function modelStampFor(args) {
|
|
624
|
-
return {
|
|
625
|
-
modelVersion: DATA_MODEL_VERSION,
|
|
626
|
-
minReaderModel: Math.max(DATA_MODEL_MIN_READER, args.storedMinReaderModel ?? 0, requiredReaderModel(args.documentType, args.document))
|
|
627
|
-
};
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
function fieldTreeShape(value) {
|
|
631
|
-
if (Array.isArray(value)) return value.map(fieldTreeShape);
|
|
632
|
-
if (value === null) return "null";
|
|
633
|
-
if (typeof value == "object") {
|
|
634
|
-
const record = value;
|
|
635
|
-
return Object.fromEntries(Object.keys(record).toSorted().map(key => [ key, fieldTreeShape(record[key]) ]));
|
|
636
|
-
}
|
|
637
|
-
return typeof value;
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
function modelVersionOf(doc) {
|
|
641
|
-
const stamp = doc.modelVersion;
|
|
642
|
-
return typeof stamp == "number" ? stamp : 0;
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
function minReaderModelOf(doc) {
|
|
646
|
-
const floor = doc.minReaderModel;
|
|
647
|
-
return typeof floor == "number" ? floor : modelVersionOf(doc);
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
class ModelVersionAheadError extends WorkflowError {
|
|
651
|
-
documentId;
|
|
652
|
-
documentModelVersion;
|
|
653
|
-
requiredReaderModel;
|
|
654
|
-
engineModelVersion;
|
|
655
|
-
constructor(args) {
|
|
656
|
-
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.`),
|
|
657
|
-
this.name = "ModelVersionAheadError", this.documentId = args.documentId, this.documentModelVersion = args.documentModelVersion,
|
|
658
|
-
this.requiredReaderModel = args.requiredReaderModel, this.engineModelVersion = DATA_MODEL_VERSION;
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
function assertReadableModel(doc) {
|
|
663
|
-
const documentReaderModel = minReaderModelOf(doc);
|
|
664
|
-
if (documentReaderModel > DATA_MODEL_VERSION) throw new ModelVersionAheadError({
|
|
665
|
-
documentId: doc._id,
|
|
666
|
-
documentModelVersion: modelVersionOf(doc),
|
|
667
|
-
requiredReaderModel: documentReaderModel
|
|
668
|
-
});
|
|
669
|
-
return doc;
|
|
670
|
-
}
|
|
671
|
-
|
|
672
441
|
function effectSites(def) {
|
|
673
442
|
const sites = [];
|
|
674
443
|
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({
|
|
@@ -1143,12 +912,8 @@ function renderWorkflowRead(read, ctx) {
|
|
|
1143
912
|
text: guillemets(title)
|
|
1144
913
|
});
|
|
1145
914
|
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
permission: read.path[0]
|
|
1149
|
-
},
|
|
1150
|
-
text: `your ${read.path[0]} permission`
|
|
1151
|
-
});
|
|
915
|
+
const keyed = keyedCallerRead(read);
|
|
916
|
+
if (keyed !== void 0) return keyed;
|
|
1152
917
|
if (read.variable === "actor" && read.path.length === 1 && read.path[0] === "id") return phrase("read.actor-id", {
|
|
1153
918
|
params: {},
|
|
1154
919
|
text: "your id"
|
|
@@ -1170,6 +935,24 @@ function renderWorkflowRead(read, ctx) {
|
|
|
1170
935
|
});
|
|
1171
936
|
}
|
|
1172
937
|
|
|
938
|
+
function keyedCallerRead(read) {
|
|
939
|
+
const key = read.path[0];
|
|
940
|
+
if (typeof key == "string") {
|
|
941
|
+
if (read.variable === "can") return phrase("read.permission", {
|
|
942
|
+
params: {
|
|
943
|
+
permission: key
|
|
944
|
+
},
|
|
945
|
+
text: `your ${key} permission`
|
|
946
|
+
});
|
|
947
|
+
if (read.variable === "attributes") return phrase("read.attribute", {
|
|
948
|
+
params: {
|
|
949
|
+
attribute: key
|
|
950
|
+
},
|
|
951
|
+
text: `your ${guillemets(key)} attribute`
|
|
952
|
+
});
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
|
|
1173
956
|
function workflowRequirement(requirement, ctx) {
|
|
1174
957
|
const {target: target} = requirement, clause = clauseVarRequirement(requirement);
|
|
1175
958
|
if (clause !== void 0) return clause;
|
|
@@ -2597,7 +2380,7 @@ class CascadeLimitError extends WorkflowError {
|
|
|
2597
2380
|
}
|
|
2598
2381
|
}
|
|
2599
2382
|
|
|
2600
|
-
const FIELD_OP_TYPES = [ "field.set", "field.unset", "field.append", "field.updateWhere", "field.removeWhere" ];
|
|
2383
|
+
const FIELD_OP_TYPES = [ "field.set", "field.setIfMissing", "field.unset", "field.append", "field.inc", "field.dec", "field.updateWhere", "field.removeWhere" ];
|
|
2601
2384
|
|
|
2602
2385
|
function isFieldOp(summary) {
|
|
2603
2386
|
return FIELD_OP_TYPES.includes(summary.opType);
|
|
@@ -2605,38 +2388,7 @@ function isFieldOp(summary) {
|
|
|
2605
2388
|
|
|
2606
2389
|
function validateActionParams({action: action, activityName: activityName, callerParams: callerParams}) {
|
|
2607
2390
|
const declared = action.params ?? [], params = callerParams ?? {}, issues = [];
|
|
2608
|
-
for (const decl of declared)
|
|
2609
|
-
const value = params[decl.name], present = decl.name in params && value !== void 0 && value !== null;
|
|
2610
|
-
if (decl.required === !0 && !present) {
|
|
2611
|
-
issues.push({
|
|
2612
|
-
param: decl.name,
|
|
2613
|
-
reason: "required but missing"
|
|
2614
|
-
});
|
|
2615
|
-
continue;
|
|
2616
|
-
}
|
|
2617
|
-
if (!present) continue;
|
|
2618
|
-
if (!checkParamType(value, decl)) {
|
|
2619
|
-
issues.push({
|
|
2620
|
-
param: decl.name,
|
|
2621
|
-
reason: `expected type=${decl.type}, got ${typeof value}`
|
|
2622
|
-
});
|
|
2623
|
-
continue;
|
|
2624
|
-
}
|
|
2625
|
-
const choiceIssues = choiceValueIssues(decl.options, value);
|
|
2626
|
-
choiceIssues !== void 0 && issues.push({
|
|
2627
|
-
param: decl.name,
|
|
2628
|
-
reason: choiceIssues.join("; ")
|
|
2629
|
-
});
|
|
2630
|
-
const validationIssues = scalarValidationIssues({
|
|
2631
|
-
entryType: decl.type,
|
|
2632
|
-
validation: decl.validation,
|
|
2633
|
-
value: value
|
|
2634
|
-
});
|
|
2635
|
-
validationIssues !== void 0 && issues.push({
|
|
2636
|
-
param: decl.name,
|
|
2637
|
-
reason: validationIssues.join("; ")
|
|
2638
|
-
});
|
|
2639
|
-
}
|
|
2391
|
+
for (const decl of declared) issues.push(...declaredParamIssues(decl, params));
|
|
2640
2392
|
if (issues.length > 0) throw new ActionParamsInvalidError({
|
|
2641
2393
|
action: action.name,
|
|
2642
2394
|
activity: activityName,
|
|
@@ -2645,6 +2397,30 @@ function validateActionParams({action: action, activityName: activityName, calle
|
|
|
2645
2397
|
return params;
|
|
2646
2398
|
}
|
|
2647
2399
|
|
|
2400
|
+
function declaredParamIssues(decl, params) {
|
|
2401
|
+
const value = params[decl.name];
|
|
2402
|
+
if (!(decl.name in params && value !== void 0 && value !== null)) return decl.required === !0 ? [ {
|
|
2403
|
+
param: decl.name,
|
|
2404
|
+
reason: "required but missing"
|
|
2405
|
+
} ] : [];
|
|
2406
|
+
if (!checkParamType(value, decl)) return [ {
|
|
2407
|
+
param: decl.name,
|
|
2408
|
+
reason: `expected type=${decl.type}, got ${typeof value}`
|
|
2409
|
+
} ];
|
|
2410
|
+
const choiceIssues = choiceValueIssues(decl.options, value), validationIssues = scalarValidationIssues({
|
|
2411
|
+
entryType: decl.type,
|
|
2412
|
+
validation: decl.validation,
|
|
2413
|
+
value: value
|
|
2414
|
+
});
|
|
2415
|
+
return [ ...choiceIssues === void 0 ? [] : [ {
|
|
2416
|
+
param: decl.name,
|
|
2417
|
+
reason: choiceIssues.join("; ")
|
|
2418
|
+
} ], ...validationIssues === void 0 ? [] : [ {
|
|
2419
|
+
param: decl.name,
|
|
2420
|
+
reason: validationIssues.join("; ")
|
|
2421
|
+
} ] ];
|
|
2422
|
+
}
|
|
2423
|
+
|
|
2648
2424
|
function hasStringField(value, field) {
|
|
2649
2425
|
return typeof value == "object" && value !== null && field in value && typeof value[field] == "string";
|
|
2650
2426
|
}
|
|
@@ -2696,9 +2472,11 @@ async function runOps(args) {
|
|
|
2696
2472
|
now: now,
|
|
2697
2473
|
snapshot: snapshot,
|
|
2698
2474
|
refSurface: refSurface,
|
|
2699
|
-
opsFromDefinition: opsFromDefinition
|
|
2475
|
+
opsFromDefinition: opsFromDefinition,
|
|
2476
|
+
memberRoles: args.memberRoles,
|
|
2477
|
+
roleAliases: args.roleAliases
|
|
2700
2478
|
});
|
|
2701
|
-
summaries.push(summary), mutation.history.push(opAppliedEntry({
|
|
2479
|
+
summaries.push(summary), shouldRecordOpApplied(summary) && mutation.history.push(opAppliedEntry({
|
|
2702
2480
|
origin: origin,
|
|
2703
2481
|
summary: summary,
|
|
2704
2482
|
stage: stage,
|
|
@@ -2709,6 +2487,10 @@ async function runOps(args) {
|
|
|
2709
2487
|
return summaries;
|
|
2710
2488
|
}
|
|
2711
2489
|
|
|
2490
|
+
function shouldRecordOpApplied(summary) {
|
|
2491
|
+
return summary.opType !== "field.setIfMissing" || summary.resolved !== void 0;
|
|
2492
|
+
}
|
|
2493
|
+
|
|
2712
2494
|
function opAppliedEntry(args) {
|
|
2713
2495
|
const {origin: origin, summary: summary, stage: stage, actor: actor, now: now} = args;
|
|
2714
2496
|
return {
|
|
@@ -2780,12 +2562,19 @@ async function applyOp(op, ctx) {
|
|
|
2780
2562
|
case "field.set":
|
|
2781
2563
|
return applyFieldSet(op, ctx);
|
|
2782
2564
|
|
|
2565
|
+
case "field.setIfMissing":
|
|
2566
|
+
return applyFieldSetIfMissing(op, ctx);
|
|
2567
|
+
|
|
2783
2568
|
case "field.unset":
|
|
2784
2569
|
return applyFieldUnset(op, ctx);
|
|
2785
2570
|
|
|
2786
2571
|
case "field.append":
|
|
2787
2572
|
return applyFieldAppend(op, ctx);
|
|
2788
2573
|
|
|
2574
|
+
case "field.inc":
|
|
2575
|
+
case "field.dec":
|
|
2576
|
+
return applyFieldArithmetic(op, ctx);
|
|
2577
|
+
|
|
2789
2578
|
case "field.updateWhere":
|
|
2790
2579
|
return applyFieldUpdateWhere(op, ctx);
|
|
2791
2580
|
|
|
@@ -2806,7 +2595,12 @@ function applyFieldSet(op, ctx) {
|
|
|
2806
2595
|
entryType: entry._type,
|
|
2807
2596
|
entryName: entry.name,
|
|
2808
2597
|
value: value,
|
|
2809
|
-
...entryShape(entry)
|
|
2598
|
+
...entryShape(entry),
|
|
2599
|
+
memberRoles: ctx.memberRoles,
|
|
2600
|
+
roleAliases: ctx.roleAliases,
|
|
2601
|
+
...entry._type === "assignees" || entry._type === "object" || entry._type === "array" ? {
|
|
2602
|
+
previousValue: entry.value
|
|
2603
|
+
} : {}
|
|
2810
2604
|
});
|
|
2811
2605
|
return assertRuntimeRefsWithinSurface({
|
|
2812
2606
|
entryType: entry._type,
|
|
@@ -2824,6 +2618,78 @@ function applyFieldSet(op, ctx) {
|
|
|
2824
2618
|
};
|
|
2825
2619
|
}
|
|
2826
2620
|
|
|
2621
|
+
function applyFieldSetIfMissing(op, ctx) {
|
|
2622
|
+
const entry = locateEntry(ctx, op.target);
|
|
2623
|
+
return isAlwaysArrayFieldKind(entry._type) && rejectFieldOpTarget({
|
|
2624
|
+
entry: entry,
|
|
2625
|
+
op: op,
|
|
2626
|
+
issue: "is always array-valued — setIfMissing applies to nullable entries only; an empty array entry already holds []"
|
|
2627
|
+
}), entry.value !== null && entry.value !== void 0 ? {
|
|
2628
|
+
opType: op.type,
|
|
2629
|
+
target: op.target
|
|
2630
|
+
} : {
|
|
2631
|
+
...applyFieldSet({
|
|
2632
|
+
...op,
|
|
2633
|
+
type: "field.set"
|
|
2634
|
+
}, ctx),
|
|
2635
|
+
opType: op.type
|
|
2636
|
+
};
|
|
2637
|
+
}
|
|
2638
|
+
|
|
2639
|
+
function applyFieldArithmetic(op, ctx) {
|
|
2640
|
+
const entry = locateEntry(ctx, op.target);
|
|
2641
|
+
entry._type !== "number" && rejectFieldOpTarget({
|
|
2642
|
+
entry: entry,
|
|
2643
|
+
op: op,
|
|
2644
|
+
issue: `is a ${entry._type} entry — arithmetic ops target \`number\` entries only`
|
|
2645
|
+
}), typeof entry.value != "number" && rejectFieldOpTarget({
|
|
2646
|
+
entry: entry,
|
|
2647
|
+
op: op,
|
|
2648
|
+
issue: "has no numeric value — initialize it before applying arithmetic"
|
|
2649
|
+
});
|
|
2650
|
+
const resolvedDelta = op.value === void 0 ? 1 : resolveOpValue({
|
|
2651
|
+
src: op.value,
|
|
2652
|
+
ctx: ctx,
|
|
2653
|
+
target: {
|
|
2654
|
+
kind: "number"
|
|
2655
|
+
}
|
|
2656
|
+
});
|
|
2657
|
+
(typeof resolvedDelta != "number" || !Number.isFinite(resolvedDelta)) && rejectFieldOpTarget({
|
|
2658
|
+
entry: entry,
|
|
2659
|
+
op: op,
|
|
2660
|
+
issue: "value must resolve to a finite number"
|
|
2661
|
+
});
|
|
2662
|
+
const nextValue = entry.value + (op.type === "field.inc" ? resolvedDelta : -resolvedDelta);
|
|
2663
|
+
Number.isFinite(nextValue) || rejectFieldOpTarget({
|
|
2664
|
+
entry: entry,
|
|
2665
|
+
op: op,
|
|
2666
|
+
issue: "result must be a finite number"
|
|
2667
|
+
});
|
|
2668
|
+
const value = validateFieldValue({
|
|
2669
|
+
entryType: entry._type,
|
|
2670
|
+
entryName: entry.name,
|
|
2671
|
+
value: nextValue,
|
|
2672
|
+
...entryShape(entry)
|
|
2673
|
+
});
|
|
2674
|
+
return setEntryValue(entry, value), {
|
|
2675
|
+
opType: op.type,
|
|
2676
|
+
target: op.target,
|
|
2677
|
+
resolved: {
|
|
2678
|
+
value: value
|
|
2679
|
+
}
|
|
2680
|
+
};
|
|
2681
|
+
}
|
|
2682
|
+
|
|
2683
|
+
function rejectFieldOpTarget(args) {
|
|
2684
|
+
const {entry: entry, op: op, issue: issue} = args;
|
|
2685
|
+
throw new FieldValueShapeError({
|
|
2686
|
+
entryType: entry._type,
|
|
2687
|
+
entryName: entry.name,
|
|
2688
|
+
mode: "value",
|
|
2689
|
+
issues: [ `${op.type} target ${op.target.scope}:"${op.target.field}" ${issue}` ]
|
|
2690
|
+
});
|
|
2691
|
+
}
|
|
2692
|
+
|
|
2827
2693
|
function entryShape(entry) {
|
|
2828
2694
|
return entry._type === "object" ? {
|
|
2829
2695
|
fields: entry.fields
|
|
@@ -2831,7 +2697,17 @@ function entryShape(entry) {
|
|
|
2831
2697
|
of: entry.of
|
|
2832
2698
|
} : isSingleDocRefEntry(entry) || entry._type === "doc.refs" ? entry.types !== void 0 ? {
|
|
2833
2699
|
types: entry.types
|
|
2834
|
-
} : {} :
|
|
2700
|
+
} : {} : isAssignmentFieldEntry(entry) ? assignmentEntryShape(entry) : scalarEntryShape(entry);
|
|
2701
|
+
}
|
|
2702
|
+
|
|
2703
|
+
function assignmentEntryShape(entry) {
|
|
2704
|
+
return entry.roles !== void 0 ? {
|
|
2705
|
+
roles: entry.roles
|
|
2706
|
+
} : {};
|
|
2707
|
+
}
|
|
2708
|
+
|
|
2709
|
+
function scalarEntryShape(entry) {
|
|
2710
|
+
return {
|
|
2835
2711
|
...entry.options !== void 0 ? {
|
|
2836
2712
|
options: entry.options
|
|
2837
2713
|
} : {},
|
|
@@ -2859,15 +2735,9 @@ function appendItemSlot(entry) {
|
|
|
2859
2735
|
};
|
|
2860
2736
|
}
|
|
2861
2737
|
|
|
2862
|
-
const EMPTY_BY_KIND = {
|
|
2863
|
-
"doc.refs": [],
|
|
2864
|
-
array: [],
|
|
2865
|
-
assignees: []
|
|
2866
|
-
};
|
|
2867
|
-
|
|
2868
2738
|
function applyFieldUnset(op, ctx) {
|
|
2869
2739
|
const entry = locateEntry(ctx, op.target);
|
|
2870
|
-
return setEntryValue(entry,
|
|
2740
|
+
return setEntryValue(entry, isAlwaysArrayFieldKind(entry._type) ? [] : null), {
|
|
2871
2741
|
opType: op.type,
|
|
2872
2742
|
target: op.target
|
|
2873
2743
|
};
|
|
@@ -2885,7 +2755,10 @@ function applyFieldAppend(op, ctx) {
|
|
|
2885
2755
|
entryName: entry.name,
|
|
2886
2756
|
item: item,
|
|
2887
2757
|
types: entry._type === "doc.refs" ? entry.types : void 0,
|
|
2888
|
-
of: entry._type === "array" ? entry.of : void 0
|
|
2758
|
+
of: entry._type === "array" ? entry.of : void 0,
|
|
2759
|
+
roles: entry._type === "assignees" ? entry.roles : void 0,
|
|
2760
|
+
memberRoles: ctx.memberRoles,
|
|
2761
|
+
roleAliases: ctx.roleAliases
|
|
2889
2762
|
});
|
|
2890
2763
|
assertRuntimeRefsWithinSurface({
|
|
2891
2764
|
entryType: entry._type === "doc.refs" ? "doc.ref" : "object",
|
|
@@ -2906,7 +2779,7 @@ function applyFieldAppend(op, ctx) {
|
|
|
2906
2779
|
}
|
|
2907
2780
|
|
|
2908
2781
|
function withRowKey(item) {
|
|
2909
|
-
return
|
|
2782
|
+
return isRecord(item) && !("_key" in item) ? {
|
|
2910
2783
|
_key: randomKey(),
|
|
2911
2784
|
...item
|
|
2912
2785
|
} : item;
|
|
@@ -2933,6 +2806,13 @@ async function applyFieldUpdateWhere(op, ctx) {
|
|
|
2933
2806
|
merge: mergeRecord,
|
|
2934
2807
|
entry: entry,
|
|
2935
2808
|
op: op
|
|
2809
|
+
}), validateFieldValue({
|
|
2810
|
+
entryType: "array",
|
|
2811
|
+
entryName: entry.name,
|
|
2812
|
+
value: [ mergeRecord ],
|
|
2813
|
+
of: entry.of,
|
|
2814
|
+
memberRoles: ctx.memberRoles,
|
|
2815
|
+
roleAliases: ctx.roleAliases
|
|
2936
2816
|
});
|
|
2937
2817
|
const matches = await rowMatches({
|
|
2938
2818
|
where: op.where,
|
|
@@ -3049,18 +2929,6 @@ function subSlot(target, field) {
|
|
|
3049
2929
|
function resolveOpValue(args) {
|
|
3050
2930
|
const {src: src, ctx: ctx, target: target} = args;
|
|
3051
2931
|
switch (src.type) {
|
|
3052
|
-
case "literal":
|
|
3053
|
-
case "param":
|
|
3054
|
-
case "actor":
|
|
3055
|
-
case "now":
|
|
3056
|
-
return resolveStaticValueExpr(src, ctx);
|
|
3057
|
-
|
|
3058
|
-
case "self":
|
|
3059
|
-
return ctx.self;
|
|
3060
|
-
|
|
3061
|
-
case "stage":
|
|
3062
|
-
return ctx.stage;
|
|
3063
|
-
|
|
3064
2932
|
case "fieldRead":
|
|
3065
2933
|
{
|
|
3066
2934
|
const entry = readEntryFromMutation(ctx, src);
|
|
@@ -3090,6 +2958,25 @@ function resolveOpValue(args) {
|
|
|
3090
2958
|
}
|
|
3091
2959
|
return out;
|
|
3092
2960
|
}
|
|
2961
|
+
|
|
2962
|
+
default:
|
|
2963
|
+
return resolveAtomicOpValue(src, ctx);
|
|
2964
|
+
}
|
|
2965
|
+
}
|
|
2966
|
+
|
|
2967
|
+
function resolveAtomicOpValue(src, ctx) {
|
|
2968
|
+
switch (src.type) {
|
|
2969
|
+
case "literal":
|
|
2970
|
+
case "param":
|
|
2971
|
+
case "actor":
|
|
2972
|
+
case "now":
|
|
2973
|
+
return resolveStaticValueExpr(src, ctx);
|
|
2974
|
+
|
|
2975
|
+
case "self":
|
|
2976
|
+
return ctx.self;
|
|
2977
|
+
|
|
2978
|
+
case "stage":
|
|
2979
|
+
return ctx.stage;
|
|
3093
2980
|
}
|
|
3094
2981
|
}
|
|
3095
2982
|
|
|
@@ -3540,69 +3427,418 @@ async function assertInstanceWriteAllowed(args) {
|
|
|
3540
3427
|
});
|
|
3541
3428
|
}
|
|
3542
3429
|
|
|
3543
|
-
|
|
3544
|
-
const {instance: instance, definition: definition, snapshot: snapshot, now: now} = source, base = buildParams({
|
|
3545
|
-
instance: instance,
|
|
3546
|
-
now: now,
|
|
3547
|
-
snapshot: snapshot
|
|
3548
|
-
}), fields = {
|
|
3549
|
-
...base.fields,
|
|
3550
|
-
...scopedFieldOverlay({
|
|
3551
|
-
instance: instance,
|
|
3552
|
-
snapshot: snapshot,
|
|
3553
|
-
activityName: opts?.activityName
|
|
3554
|
-
})
|
|
3555
|
-
}, params = {
|
|
3556
|
-
...base,
|
|
3557
|
-
fields: fields,
|
|
3558
|
-
actor: opts?.actor,
|
|
3559
|
-
assigned: opts?.activityName !== void 0 ? assignedFor({
|
|
3560
|
-
instance: instance,
|
|
3561
|
-
activityName: opts.activityName,
|
|
3562
|
-
actor: opts?.actor,
|
|
3563
|
-
roleAliases: definition.roleAliases
|
|
3564
|
-
}) : !1,
|
|
3565
|
-
...opts?.vars
|
|
3566
|
-
};
|
|
3567
|
-
return {
|
|
3568
|
-
...await evaluatePredicates({
|
|
3569
|
-
predicates: definition.predicates,
|
|
3570
|
-
snapshot: snapshot,
|
|
3571
|
-
params: params
|
|
3572
|
-
}),
|
|
3573
|
-
...params
|
|
3574
|
-
};
|
|
3575
|
-
}
|
|
3430
|
+
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";
|
|
3576
3431
|
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3432
|
+
class ReaderModelAcknowledgementError extends WorkflowError {
|
|
3433
|
+
code="WORKFLOW_READER_MODEL_ACKNOWLEDGEMENT_MISMATCH";
|
|
3434
|
+
expectedMinReaderModel;
|
|
3435
|
+
requiredMinReaderModel;
|
|
3436
|
+
engineMinReaderModel=DATA_MODEL_MIN_READER;
|
|
3437
|
+
engineMaxReaderModel=DATA_MODEL_MAX_READER;
|
|
3438
|
+
engineModelVersion=DATA_MODEL_VERSION;
|
|
3439
|
+
documentationUrl=READER_MODEL_ROLLOUT_URL;
|
|
3440
|
+
constructor(expectedMinReaderModel, options = {}) {
|
|
3441
|
+
const {context: context = "Deployment", requiredMinReaderModel: requiredMinReaderModel = DATA_MODEL_MIN_READER} = options, expected = expectedMinReaderModel === void 0 ? "missing" : String(expectedMinReaderModel);
|
|
3442
|
+
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}`),
|
|
3443
|
+
this.name = "ReaderModelAcknowledgementError", this.expectedMinReaderModel = expectedMinReaderModel,
|
|
3444
|
+
this.requiredMinReaderModel = requiredMinReaderModel;
|
|
3445
|
+
}
|
|
3580
3446
|
}
|
|
3581
3447
|
|
|
3582
|
-
function
|
|
3583
|
-
|
|
3448
|
+
function assertReaderModelAcknowledgement(expectedMinReaderModel, options) {
|
|
3449
|
+
const {context: context, requiredMinReaderModel: requiredMinReaderModel} = options;
|
|
3450
|
+
if (typeof expectedMinReaderModel != "number" || !Number.isFinite(expectedMinReaderModel) || !Number.isInteger(expectedMinReaderModel) || expectedMinReaderModel < 0 || expectedMinReaderModel < requiredMinReaderModel || expectedMinReaderModel > DATA_MODEL_MAX_READER) throw new ReaderModelAcknowledgementError(expectedMinReaderModel, {
|
|
3451
|
+
requiredMinReaderModel: requiredMinReaderModel,
|
|
3452
|
+
...context !== void 0 ? {
|
|
3453
|
+
context: context
|
|
3454
|
+
} : {}
|
|
3455
|
+
});
|
|
3584
3456
|
}
|
|
3585
3457
|
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3458
|
+
const DATA_MODEL_CHANGES = Object.freeze([ Object.freeze({
|
|
3459
|
+
id: "governed-model-stamps",
|
|
3460
|
+
introducedInModel: 1,
|
|
3461
|
+
minReaderModel: 0,
|
|
3462
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
3463
|
+
compatibility: "additive",
|
|
3464
|
+
applicability: "unconditional",
|
|
3465
|
+
summary: "Definition and instance documents carry model provenance and reader-floor stamps."
|
|
3466
|
+
}), Object.freeze({
|
|
3467
|
+
id: "subject-field-kind",
|
|
3468
|
+
introducedInModel: 2,
|
|
3469
|
+
minReaderModel: 0,
|
|
3470
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
3471
|
+
compatibility: "additive",
|
|
3472
|
+
applicability: "detectable",
|
|
3473
|
+
summary: "A workflow-level subject field identifies the document a workflow is about."
|
|
3474
|
+
}), Object.freeze({
|
|
3475
|
+
id: "typed-scalar-choice-lists",
|
|
3476
|
+
introducedInModel: 2,
|
|
3477
|
+
minReaderModel: 2,
|
|
3478
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
3479
|
+
compatibility: "reader-floor",
|
|
3480
|
+
applicability: "detectable",
|
|
3481
|
+
summary: "Scalar fields may constrain writes to a persisted typed choice list."
|
|
3482
|
+
}), Object.freeze({
|
|
3483
|
+
id: "action-semantics",
|
|
3484
|
+
introducedInModel: 2,
|
|
3485
|
+
minReaderModel: 0,
|
|
3486
|
+
documentTypes: Object.freeze([ "definition" ]),
|
|
3487
|
+
compatibility: "additive",
|
|
3488
|
+
applicability: "detectable",
|
|
3489
|
+
summary: "Ordinary actions may carry advisory workflow semantics."
|
|
3490
|
+
}), Object.freeze({
|
|
3491
|
+
id: "inclusive-scalar-bounds",
|
|
3492
|
+
introducedInModel: 2,
|
|
3493
|
+
minReaderModel: 2,
|
|
3494
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
3495
|
+
compatibility: "reader-floor",
|
|
3496
|
+
applicability: "detectable",
|
|
3497
|
+
summary: "String, text, and number values may carry persisted inclusive bounds."
|
|
3498
|
+
}), Object.freeze({
|
|
3499
|
+
id: "progress-field-kind",
|
|
3500
|
+
introducedInModel: 3,
|
|
3501
|
+
minReaderModel: 0,
|
|
3502
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
3503
|
+
compatibility: "additive",
|
|
3504
|
+
applicability: "detectable",
|
|
3505
|
+
summary: "A progress field kind carries application-defined 0–100 completion."
|
|
3506
|
+
}), Object.freeze({
|
|
3507
|
+
id: "effect-claim-tokens",
|
|
3508
|
+
introducedInModel: 3,
|
|
3509
|
+
minReaderModel: 0,
|
|
3510
|
+
documentTypes: Object.freeze([ "instance" ]),
|
|
3511
|
+
compatibility: "additive",
|
|
3512
|
+
applicability: "detectable",
|
|
3513
|
+
summary: "Pending-effect claims carry an exact-claim token gating mid-dispatch state reports."
|
|
3514
|
+
}), Object.freeze({
|
|
3515
|
+
id: "classified-principal-ids",
|
|
3516
|
+
introducedInModel: 4,
|
|
3517
|
+
minReaderModel: 4,
|
|
3518
|
+
documentTypes: Object.freeze([ "instance" ]),
|
|
3519
|
+
compatibility: "reader-floor",
|
|
3520
|
+
applicability: "unconditional",
|
|
3521
|
+
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."
|
|
3522
|
+
}), Object.freeze({
|
|
3523
|
+
id: "readiness-requirements",
|
|
3524
|
+
introducedInModel: 4,
|
|
3525
|
+
minReaderModel: 4,
|
|
3526
|
+
documentTypes: Object.freeze([ "definition" ]),
|
|
3527
|
+
compatibility: "reader-floor",
|
|
3528
|
+
applicability: "detectable",
|
|
3529
|
+
summary: "Start and activity readiness use named polymorphic requirement arrays."
|
|
3530
|
+
}), Object.freeze({
|
|
3531
|
+
id: "due-date-field-kinds",
|
|
3532
|
+
introducedInModel: 5,
|
|
3533
|
+
minReaderModel: 0,
|
|
3534
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
3535
|
+
compatibility: "additive",
|
|
3536
|
+
applicability: "detectable",
|
|
3537
|
+
summary: "Due-date field kinds (dueDate, dueDatetime) mark a level deadline, elevated aliases of date/datetime carrying the same stored value."
|
|
3538
|
+
}), Object.freeze({
|
|
3539
|
+
id: "node-semantics",
|
|
3540
|
+
introducedInModel: 6,
|
|
3541
|
+
minReaderModel: 0,
|
|
3542
|
+
documentTypes: Object.freeze([ "definition" ]),
|
|
3543
|
+
compatibility: "additive",
|
|
3544
|
+
applicability: "detectable",
|
|
3545
|
+
summary: "Workflow, stage, activity, and action nodes may carry signal or custom advisory semantics."
|
|
3546
|
+
}), Object.freeze({
|
|
3547
|
+
id: "field-patch-ops",
|
|
3548
|
+
introducedInModel: 6,
|
|
3549
|
+
minReaderModel: 0,
|
|
3550
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
3551
|
+
compatibility: "additive",
|
|
3552
|
+
applicability: "detectable",
|
|
3553
|
+
summary: "Field ops may increment, decrement, or initialize a missing field value."
|
|
3554
|
+
}), Object.freeze({
|
|
3555
|
+
id: "attributes-condition-var",
|
|
3556
|
+
introducedInModel: 7,
|
|
3557
|
+
minReaderModel: 0,
|
|
3558
|
+
documentTypes: Object.freeze([ "definition" ]),
|
|
3559
|
+
compatibility: "additive",
|
|
3560
|
+
applicability: "unconditional",
|
|
3561
|
+
summary: "Caller-bound $attributes condition variable binds the acting token's org-level User Attributes (advisory; absent when unavailable)."
|
|
3562
|
+
}), Object.freeze({
|
|
3563
|
+
id: "role-constrained-assignment-fields",
|
|
3564
|
+
introducedInModel: 8,
|
|
3565
|
+
minReaderModel: 8,
|
|
3566
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
3567
|
+
compatibility: "reader-floor",
|
|
3568
|
+
applicability: "detectable",
|
|
3569
|
+
summary: "Assignee fields may restrict newly assigned users and collective roles by role."
|
|
3570
|
+
}) ]);
|
|
3571
|
+
|
|
3572
|
+
function recordOf(value) {
|
|
3573
|
+
return value !== null && typeof value == "object" && !Array.isArray(value) ? value : void 0;
|
|
3589
3574
|
}
|
|
3590
3575
|
|
|
3591
|
-
function
|
|
3592
|
-
|
|
3576
|
+
function recordsAt(record, key) {
|
|
3577
|
+
const value = record[key];
|
|
3578
|
+
return Array.isArray(value) ? value.map(recordOf).filter(item => item !== void 0) : [];
|
|
3593
3579
|
}
|
|
3594
3580
|
|
|
3595
|
-
function
|
|
3596
|
-
return
|
|
3581
|
+
function nestedFieldEntries(entries) {
|
|
3582
|
+
return entries.flatMap(entry => [ entry, ...nestedFieldEntries(recordsAt(entry, "fields")), ...nestedFieldEntries(recordsAt(entry, "of")) ]);
|
|
3597
3583
|
}
|
|
3598
3584
|
|
|
3599
|
-
function
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3585
|
+
function parsedDefinitionSnapshot(root) {
|
|
3586
|
+
if (typeof root.definitionSnapshot == "string") return recordOf(parseDefinitionSnapshotValue({
|
|
3587
|
+
_id: typeof root._id == "string" ? root._id : "<unknown instance>",
|
|
3588
|
+
definitionSnapshot: root.definitionSnapshot
|
|
3589
|
+
}));
|
|
3590
|
+
}
|
|
3591
|
+
|
|
3592
|
+
function persistedDefinitionTree(document) {
|
|
3593
|
+
const root = recordOf(document);
|
|
3594
|
+
if (root === void 0) return;
|
|
3595
|
+
const snapshot = parsedDefinitionSnapshot(root), roots = snapshot === void 0 ? [ root ] : [ root, snapshot ], {stages: stages, activities: activities, actions: actions} = definitionDescendants(roots);
|
|
3596
|
+
return {
|
|
3597
|
+
roots: roots,
|
|
3598
|
+
stages: stages,
|
|
3599
|
+
activities: activities,
|
|
3600
|
+
actions: actions
|
|
3601
|
+
};
|
|
3602
|
+
}
|
|
3603
|
+
|
|
3604
|
+
function persistedFieldEntries(document) {
|
|
3605
|
+
const tree = persistedDefinitionTree(document);
|
|
3606
|
+
if (tree === void 0) return [];
|
|
3607
|
+
const {roots: roots, stages: stages, activities: activities, actions: actions} = tree, effects = actions.flatMap(action => recordsAt(action, "effects"));
|
|
3608
|
+
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")) ]);
|
|
3609
|
+
}
|
|
3610
|
+
|
|
3611
|
+
function definitionDescendants(roots) {
|
|
3612
|
+
const stages = roots.flatMap(root => recordsAt(root, "stages")), activities = stages.flatMap(stage => recordsAt(stage, "activities")), actions = activities.flatMap(activity => recordsAt(activity, "actions"));
|
|
3613
|
+
return {
|
|
3614
|
+
stages: stages,
|
|
3615
|
+
activities: activities,
|
|
3616
|
+
actions: actions
|
|
3617
|
+
};
|
|
3618
|
+
}
|
|
3619
|
+
|
|
3620
|
+
function hasChoiceList(document) {
|
|
3621
|
+
return persistedFieldEntries(document).some(entry => {
|
|
3622
|
+
const options = recordOf(entry.options);
|
|
3623
|
+
return options !== void 0 && Array.isArray(options.list);
|
|
3624
|
+
});
|
|
3625
|
+
}
|
|
3626
|
+
|
|
3627
|
+
function entryHasKind(entry, kind) {
|
|
3628
|
+
return entryKindMatches(entry, candidate => candidate === kind);
|
|
3629
|
+
}
|
|
3630
|
+
|
|
3631
|
+
function entryKindMatches(entry, accepts) {
|
|
3632
|
+
return [ entry.type, entry._type ].some(kind => typeof kind == "string" && accepts(kind));
|
|
3633
|
+
}
|
|
3634
|
+
|
|
3635
|
+
function hasFieldKind(document, kind) {
|
|
3636
|
+
return persistedFieldEntries(document).some(entry => entryHasKind(entry, kind));
|
|
3637
|
+
}
|
|
3638
|
+
|
|
3639
|
+
function definitionNodes(document) {
|
|
3640
|
+
const root = recordOf(document);
|
|
3641
|
+
if (root !== void 0) return {
|
|
3642
|
+
root: root,
|
|
3643
|
+
...definitionDescendants([ root ])
|
|
3644
|
+
};
|
|
3645
|
+
}
|
|
3646
|
+
|
|
3647
|
+
function hasActionSemantics(document) {
|
|
3648
|
+
return definitionNodes(document)?.actions.some(hasSemantics) ?? !1;
|
|
3649
|
+
}
|
|
3650
|
+
|
|
3651
|
+
function hasNodeSemantics(document) {
|
|
3652
|
+
const nodes = definitionNodes(document);
|
|
3653
|
+
return nodes === void 0 ? !1 : [ nodes.root, ...nodes.stages, ...nodes.activities ].some(hasSemantics) ? !0 : nodes.actions.some(action => hasSemantics(action) && action.semantics.some(isNodeSemanticValue));
|
|
3654
|
+
}
|
|
3655
|
+
|
|
3656
|
+
function isNodeSemanticValue(semantic) {
|
|
3657
|
+
return typeof semantic == "string" && (semantic.startsWith("signal.") || semantic.startsWith("custom."));
|
|
3658
|
+
}
|
|
3659
|
+
|
|
3660
|
+
function hasSemantics(node) {
|
|
3661
|
+
return Array.isArray(node.semantics);
|
|
3662
|
+
}
|
|
3663
|
+
|
|
3664
|
+
function hasPersistedOpType(document, types) {
|
|
3665
|
+
const tree = persistedDefinitionTree(document);
|
|
3666
|
+
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)));
|
|
3667
|
+
}
|
|
3668
|
+
|
|
3669
|
+
function hasScalarValidation(document) {
|
|
3670
|
+
return persistedFieldEntries(document).some(entry => {
|
|
3671
|
+
const validation = recordOf(entry.validation);
|
|
3672
|
+
return typeof validation?.min == "number" || typeof validation?.max == "number";
|
|
3673
|
+
});
|
|
3674
|
+
}
|
|
3675
|
+
|
|
3676
|
+
function hasClaimTokens(document) {
|
|
3677
|
+
const root = recordOf(document);
|
|
3678
|
+
return root === void 0 ? !1 : recordsAt(root, "pendingEffects").some(entry => {
|
|
3679
|
+
const claim = recordOf(entry.claim);
|
|
3680
|
+
return claim !== void 0 && typeof claim.claimToken == "string";
|
|
3681
|
+
});
|
|
3682
|
+
}
|
|
3683
|
+
|
|
3684
|
+
function hasReadinessRequirements(document) {
|
|
3685
|
+
const root = recordOf(document);
|
|
3686
|
+
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)));
|
|
3687
|
+
}
|
|
3688
|
+
|
|
3689
|
+
function hasRoleConstrainedAssignments(document) {
|
|
3690
|
+
return persistedFieldEntries(document).some(entry => entryKindMatches(entry, assignmentKindAcceptsRoles) && Array.isArray(entry.roles) && entry.roles.length > 0);
|
|
3691
|
+
}
|
|
3692
|
+
|
|
3693
|
+
const featureDetectors = {
|
|
3694
|
+
"governed-model-stamps": () => !0,
|
|
3695
|
+
"subject-field-kind": document => hasFieldKind(document, "subject"),
|
|
3696
|
+
"typed-scalar-choice-lists": hasChoiceList,
|
|
3697
|
+
"action-semantics": hasActionSemantics,
|
|
3698
|
+
"inclusive-scalar-bounds": hasScalarValidation,
|
|
3699
|
+
"progress-field-kind": document => hasFieldKind(document, "progress"),
|
|
3700
|
+
"effect-claim-tokens": hasClaimTokens,
|
|
3701
|
+
"classified-principal-ids": () => !0,
|
|
3702
|
+
"readiness-requirements": hasReadinessRequirements,
|
|
3703
|
+
"due-date-field-kinds": document => hasFieldKind(document, "dueDate") || hasFieldKind(document, "dueDatetime"),
|
|
3704
|
+
"role-constrained-assignment-fields": hasRoleConstrainedAssignments,
|
|
3705
|
+
"node-semantics": hasNodeSemantics,
|
|
3706
|
+
"field-patch-ops": document => hasPersistedOpType(document, [ "field.inc", "field.dec", "field.setIfMissing" ]),
|
|
3707
|
+
"attributes-condition-var": () => !0
|
|
3708
|
+
};
|
|
3709
|
+
|
|
3710
|
+
function requiredModelFeatures(documentType, document) {
|
|
3711
|
+
return DATA_MODEL_CHANGES.filter(change => change.documentTypes.some(candidate => candidate === documentType) && featureDetectors[change.id](document));
|
|
3712
|
+
}
|
|
3713
|
+
|
|
3714
|
+
function requiredReaderModel(documentType, document) {
|
|
3715
|
+
return Math.max(0, ...requiredModelFeatures(documentType, document).map(change => change.minReaderModel));
|
|
3716
|
+
}
|
|
3717
|
+
|
|
3718
|
+
function requiredDefinitionReaderModel(definitions) {
|
|
3719
|
+
return Math.max(DATA_MODEL_MIN_READER, ...definitions.map(definition => requiredReaderModel("definition", definition)));
|
|
3720
|
+
}
|
|
3721
|
+
|
|
3722
|
+
function modelStampFor(args) {
|
|
3723
|
+
return {
|
|
3724
|
+
modelVersion: DATA_MODEL_VERSION,
|
|
3725
|
+
minReaderModel: Math.max(DATA_MODEL_MIN_READER, args.storedMinReaderModel ?? 0, requiredReaderModel(args.documentType, args.document))
|
|
3726
|
+
};
|
|
3727
|
+
}
|
|
3728
|
+
|
|
3729
|
+
function fieldTreeShape(value) {
|
|
3730
|
+
if (Array.isArray(value)) return value.map(fieldTreeShape);
|
|
3731
|
+
if (value === null) return "null";
|
|
3732
|
+
if (typeof value == "object") {
|
|
3733
|
+
const record = value;
|
|
3734
|
+
return Object.fromEntries(Object.keys(record).toSorted().map(key => [ key, fieldTreeShape(record[key]) ]));
|
|
3735
|
+
}
|
|
3736
|
+
return typeof value;
|
|
3737
|
+
}
|
|
3738
|
+
|
|
3739
|
+
function modelVersionOf(doc) {
|
|
3740
|
+
const stamp = doc.modelVersion;
|
|
3741
|
+
return typeof stamp == "number" ? stamp : 0;
|
|
3742
|
+
}
|
|
3743
|
+
|
|
3744
|
+
function minReaderModelOf(doc) {
|
|
3745
|
+
const floor = doc.minReaderModel;
|
|
3746
|
+
return typeof floor == "number" ? floor : modelVersionOf(doc);
|
|
3747
|
+
}
|
|
3748
|
+
|
|
3749
|
+
class ModelVersionAheadError extends WorkflowError {
|
|
3750
|
+
documentId;
|
|
3751
|
+
documentModelVersion;
|
|
3752
|
+
requiredReaderModel;
|
|
3753
|
+
engineModelVersion;
|
|
3754
|
+
constructor(args) {
|
|
3755
|
+
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.`),
|
|
3756
|
+
this.name = "ModelVersionAheadError", this.documentId = args.documentId, this.documentModelVersion = args.documentModelVersion,
|
|
3757
|
+
this.requiredReaderModel = args.requiredReaderModel, this.engineModelVersion = DATA_MODEL_VERSION;
|
|
3758
|
+
}
|
|
3759
|
+
}
|
|
3760
|
+
|
|
3761
|
+
function assertReadableModel(doc) {
|
|
3762
|
+
const documentReaderModel = minReaderModelOf(doc);
|
|
3763
|
+
if (documentReaderModel > DATA_MODEL_VERSION) throw new ModelVersionAheadError({
|
|
3764
|
+
documentId: doc._id,
|
|
3765
|
+
documentModelVersion: modelVersionOf(doc),
|
|
3766
|
+
requiredReaderModel: documentReaderModel
|
|
3767
|
+
});
|
|
3768
|
+
return doc;
|
|
3769
|
+
}
|
|
3770
|
+
|
|
3771
|
+
async function renderConditionScope(source, opts) {
|
|
3772
|
+
const {instance: instance, definition: definition, snapshot: snapshot, now: now} = source, base = buildParams({
|
|
3773
|
+
instance: instance,
|
|
3774
|
+
now: now,
|
|
3775
|
+
snapshot: snapshot
|
|
3776
|
+
}), fields = {
|
|
3777
|
+
...base.fields,
|
|
3778
|
+
...scopedFieldOverlay({
|
|
3779
|
+
instance: instance,
|
|
3780
|
+
snapshot: snapshot,
|
|
3781
|
+
activityName: opts?.activityName
|
|
3782
|
+
})
|
|
3783
|
+
}, params = {
|
|
3784
|
+
...base,
|
|
3785
|
+
fields: fields,
|
|
3786
|
+
actor: opts?.actor,
|
|
3787
|
+
assigned: opts?.activityName !== void 0 ? assignedFor({
|
|
3788
|
+
instance: instance,
|
|
3789
|
+
activityName: opts.activityName,
|
|
3790
|
+
actor: opts?.actor,
|
|
3791
|
+
roleAliases: definition.roleAliases
|
|
3792
|
+
}) : !1,
|
|
3793
|
+
...opts?.vars
|
|
3794
|
+
};
|
|
3795
|
+
return {
|
|
3796
|
+
...await evaluatePredicates({
|
|
3797
|
+
predicates: definition.predicates,
|
|
3798
|
+
snapshot: snapshot,
|
|
3799
|
+
params: params
|
|
3800
|
+
}),
|
|
3801
|
+
...params
|
|
3802
|
+
};
|
|
3803
|
+
}
|
|
3804
|
+
|
|
3805
|
+
function definitionLookupGroq(explicit) {
|
|
3806
|
+
const scoped = `_type == "${WORKFLOW_DEFINITION_TYPE}" && name == $definition && ${tagScopeFilter()}`;
|
|
3807
|
+
return explicit ? `*[${scoped} && version == $version][0]` : `*[${scoped}] | order(version desc)[0]`;
|
|
3808
|
+
}
|
|
3809
|
+
|
|
3810
|
+
function definitionsListGroq(versionOrder) {
|
|
3811
|
+
return `*[_type == "${WORKFLOW_DEFINITION_TYPE}" && ${tagScopeFilter()}] | order(name asc, version ${versionOrder})`;
|
|
3812
|
+
}
|
|
3813
|
+
|
|
3814
|
+
function latestDefinitionsGroq() {
|
|
3815
|
+
const scoped = `_type == "${WORKFLOW_DEFINITION_TYPE}" && ${tagScopeFilter()}`;
|
|
3816
|
+
return `*[${scoped} && version == math::max(*[${scoped} && name == ^.name].version)] | order(name asc)`;
|
|
3817
|
+
}
|
|
3818
|
+
|
|
3819
|
+
function deployedTagsGroq() {
|
|
3820
|
+
return `array::unique(*[_type == "${WORKFLOW_DEFINITION_TYPE}"].tag) | order(@ asc)`;
|
|
3821
|
+
}
|
|
3822
|
+
|
|
3823
|
+
function definitionTagsGroq() {
|
|
3824
|
+
return `array::unique(*[_type == "${WORKFLOW_DEFINITION_TYPE}" && name == $definition].tag) | order(@ asc)`;
|
|
3825
|
+
}
|
|
3826
|
+
|
|
3827
|
+
function latestDeployedDefinitions(rows) {
|
|
3828
|
+
const byName = /* @__PURE__ */ new Map;
|
|
3829
|
+
for (const row of rows) {
|
|
3830
|
+
const held = byName.get(row.name);
|
|
3831
|
+
(held === void 0 || row.version > held.version) && byName.set(row.name, row);
|
|
3832
|
+
}
|
|
3833
|
+
return [ ...byName.values() ];
|
|
3834
|
+
}
|
|
3835
|
+
|
|
3836
|
+
function findStageNode(args) {
|
|
3837
|
+
return args.definition?.stages.find(entry => entry.name === args.stageName);
|
|
3838
|
+
}
|
|
3839
|
+
|
|
3840
|
+
function findActivityNode(args) {
|
|
3841
|
+
return findStageNode(args)?.activities?.find(entry => entry.name === args.activityName);
|
|
3606
3842
|
}
|
|
3607
3843
|
|
|
3608
3844
|
function liveChildrenField(instance) {
|
|
@@ -3693,6 +3929,27 @@ function noTransitionFiresCause(input) {
|
|
|
3693
3929
|
};
|
|
3694
3930
|
}
|
|
3695
3931
|
|
|
3932
|
+
function stuckFromDocumentState(input) {
|
|
3933
|
+
return failedEffectCause(input) ?? failedActivityCause(input) ?? hungEffectCause(input);
|
|
3934
|
+
}
|
|
3935
|
+
|
|
3936
|
+
function documentStuckCause(args) {
|
|
3937
|
+
const stage = findOpenStageEntry(args.instance);
|
|
3938
|
+
if (stage !== void 0) return stuckFromDocumentState({
|
|
3939
|
+
instance: args.instance,
|
|
3940
|
+
activities: stage.activities.map(entry => ({
|
|
3941
|
+
status: entry.status,
|
|
3942
|
+
activity: findActivityNode({
|
|
3943
|
+
activityName: entry.name,
|
|
3944
|
+
definition: args.definition,
|
|
3945
|
+
stageName: stage.name
|
|
3946
|
+
}) ?? {
|
|
3947
|
+
name: entry.name
|
|
3948
|
+
}
|
|
3949
|
+
}))
|
|
3950
|
+
});
|
|
3951
|
+
}
|
|
3952
|
+
|
|
3696
3953
|
function diagnoseInstance(input) {
|
|
3697
3954
|
const {instance: instance} = input, terminal = terminalState(instance);
|
|
3698
3955
|
if (terminal === "aborted" && instance.abortedAt !== void 0) {
|
|
@@ -3711,7 +3968,7 @@ function diagnoseInstance(input) {
|
|
|
3711
3968
|
at: instance.completedAt,
|
|
3712
3969
|
...liveChildrenField(instance)
|
|
3713
3970
|
};
|
|
3714
|
-
const cause =
|
|
3971
|
+
const cause = stuckFromDocumentState(input) ?? noTransitionFiresCause(input);
|
|
3715
3972
|
return cause !== void 0 ? {
|
|
3716
3973
|
state: "stuck",
|
|
3717
3974
|
cause: cause
|
|
@@ -3773,46 +4030,246 @@ function isClaimExpired(claim, now) {
|
|
|
3773
4030
|
return claim.leaseExpiresAt === void 0 || hasPassed(claim.leaseExpiresAt, now);
|
|
3774
4031
|
}
|
|
3775
4032
|
|
|
3776
|
-
const EFFECT_RUN_STATUSES = [ "done", "failed", "cancelled" ]
|
|
3777
|
-
interactive: "interactive",
|
|
3778
|
-
server: "server",
|
|
3779
|
-
cli: "cli",
|
|
3780
|
-
mcp: "mcp",
|
|
3781
|
-
drainer: "drainer",
|
|
3782
|
-
script: "script",
|
|
3783
|
-
test: "test",
|
|
3784
|
-
studio: "studio",
|
|
3785
|
-
sdkApp: "sdk-app"
|
|
3786
|
-
};
|
|
4033
|
+
const EFFECT_RUN_STATUSES = [ "done", "failed", "cancelled" ];
|
|
3787
4034
|
|
|
3788
|
-
function
|
|
3789
|
-
|
|
3790
|
-
if (g.Deno !== void 0) return "deno";
|
|
3791
|
-
if (g.Bun !== void 0) return "bun";
|
|
3792
|
-
if (g.EdgeRuntime !== void 0) return "edge";
|
|
3793
|
-
if (g.window !== void 0 && g.document !== void 0) return "browser";
|
|
3794
|
-
if (g.WorkerGlobalScope !== void 0 && g.self !== void 0) return "worker";
|
|
3795
|
-
const proc = g.process;
|
|
3796
|
-
return typeof proc == "object" && proc !== null && typeof proc.versions?.node == "string" ? "node" : "unknown";
|
|
4035
|
+
function userLoginProvider(user) {
|
|
4036
|
+
return user?.provider ?? user?.loginProvider;
|
|
3797
4037
|
}
|
|
3798
4038
|
|
|
3799
|
-
|
|
4039
|
+
function optionalString(value) {
|
|
4040
|
+
return value === void 0 || typeof value == "string";
|
|
4041
|
+
}
|
|
3800
4042
|
|
|
3801
|
-
function
|
|
3802
|
-
return
|
|
3803
|
-
runtime: inferredRuntime,
|
|
3804
|
-
...declared?.kind !== void 0 ? {
|
|
3805
|
-
kind: declared.kind
|
|
3806
|
-
} : {},
|
|
3807
|
-
...declared?.id !== void 0 ? {
|
|
3808
|
-
id: declared.id
|
|
3809
|
-
} : {}
|
|
3810
|
-
};
|
|
4043
|
+
function isClientProjectUser(value) {
|
|
4044
|
+
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);
|
|
3811
4045
|
}
|
|
3812
4046
|
|
|
3813
|
-
function
|
|
3814
|
-
|
|
3815
|
-
|
|
4047
|
+
function objectProperty(value, property) {
|
|
4048
|
+
if (!isRecord(value)) return;
|
|
4049
|
+
const propertyValue = value[property];
|
|
4050
|
+
return typeof propertyValue == "object" && propertyValue !== null ? propertyValue : void 0;
|
|
4051
|
+
}
|
|
4052
|
+
|
|
4053
|
+
function stringProperty(value, property) {
|
|
4054
|
+
const propertyValue = Reflect.get(value, property);
|
|
4055
|
+
return typeof propertyValue == "string" ? propertyValue : void 0;
|
|
4056
|
+
}
|
|
4057
|
+
|
|
4058
|
+
function apiErrorType(error) {
|
|
4059
|
+
const response = objectProperty(error, "response"), body = objectProperty(response, "body");
|
|
4060
|
+
if (!body) return;
|
|
4061
|
+
const nestedError = objectProperty(body, "error");
|
|
4062
|
+
return (nestedError ? stringProperty(nestedError, "type") : void 0) ?? stringProperty(body, "type");
|
|
4063
|
+
}
|
|
4064
|
+
|
|
4065
|
+
function isProjectUserNotFoundError(error) {
|
|
4066
|
+
return apiErrorType(error) === "projectUserNotFoundError";
|
|
4067
|
+
}
|
|
4068
|
+
|
|
4069
|
+
const memberJoinCache = /* @__PURE__ */ new WeakMap;
|
|
4070
|
+
|
|
4071
|
+
function joinCacheFor(client) {
|
|
4072
|
+
let cache = memberJoinCache.get(client);
|
|
4073
|
+
return cache === void 0 && (cache = /* @__PURE__ */ new Map, memberJoinCache.set(client, cache)),
|
|
4074
|
+
cache;
|
|
4075
|
+
}
|
|
4076
|
+
|
|
4077
|
+
function isClientProjectMember(value) {
|
|
4078
|
+
return isRecord(value) && typeof value.id == "string";
|
|
4079
|
+
}
|
|
4080
|
+
|
|
4081
|
+
async function requestProjectMembers(request, projectId) {
|
|
4082
|
+
const project = await request({
|
|
4083
|
+
uri: `/projects/${encodeURIComponent(projectId)}`
|
|
4084
|
+
}), members = isRecord(project) ? project.members : void 0;
|
|
4085
|
+
if (!Array.isArray(members) || !members.every(isClientProjectMember)) throw new Error(`Project member directory response is invalid for project "${projectId}"`);
|
|
4086
|
+
return members;
|
|
4087
|
+
}
|
|
4088
|
+
|
|
4089
|
+
async function requestProjectUsers(args) {
|
|
4090
|
+
const {request: request, projectId: projectId, memberIds: memberIds} = args, response = await request({
|
|
4091
|
+
uri: `/projects/${encodeURIComponent(projectId)}/users/${memberIds.map(encodeURIComponent).join(",")}`
|
|
4092
|
+
}), rows = Array.isArray(response) ? response : [ response ];
|
|
4093
|
+
if (!rows.every(isClientProjectUser)) throw new Error(`Project user directory response is invalid for project "${projectId}"`);
|
|
4094
|
+
const requested = new Set(memberIds);
|
|
4095
|
+
return rows.filter(row => requested.has(row.id));
|
|
4096
|
+
}
|
|
4097
|
+
|
|
4098
|
+
async function requestProjectMemberDirectory(args) {
|
|
4099
|
+
const {request: request, projectId: projectId} = args, members = await requestProjectMembers(request, projectId), memberIds = members.map(member => member.id).filter(id => classifyPrincipalId(id).namespace === "project");
|
|
4100
|
+
if (memberIds.length === 0) return {
|
|
4101
|
+
members: members,
|
|
4102
|
+
globalUsers: []
|
|
4103
|
+
};
|
|
4104
|
+
const users = await requestProjectUsers({
|
|
4105
|
+
request: request,
|
|
4106
|
+
projectId: projectId,
|
|
4107
|
+
memberIds: memberIds
|
|
4108
|
+
});
|
|
4109
|
+
return {
|
|
4110
|
+
members: members,
|
|
4111
|
+
globalUsers: users.flatMap(user => {
|
|
4112
|
+
const globalId = directoryBridgeId(user.sanityUserId);
|
|
4113
|
+
return globalId === void 0 ? [] : [ {
|
|
4114
|
+
memberId: user.id,
|
|
4115
|
+
globalId: globalId,
|
|
4116
|
+
user: user
|
|
4117
|
+
} ];
|
|
4118
|
+
})
|
|
4119
|
+
};
|
|
4120
|
+
}
|
|
4121
|
+
|
|
4122
|
+
async function resolveGlobalProjectUser(args) {
|
|
4123
|
+
const {client: client, request: request, projectId: projectId, id: id} = args, cache = joinCacheFor(client), key = `${projectId}:${id}`, hit = cache.get(key);
|
|
4124
|
+
if (hit !== void 0) return hit === null ? {
|
|
4125
|
+
status: "missing"
|
|
4126
|
+
} : {
|
|
4127
|
+
status: "resolved",
|
|
4128
|
+
user: hit
|
|
4129
|
+
};
|
|
4130
|
+
try {
|
|
4131
|
+
await ingestMemberJoin({
|
|
4132
|
+
request: request,
|
|
4133
|
+
projectId: projectId,
|
|
4134
|
+
cache: cache
|
|
4135
|
+
});
|
|
4136
|
+
const found = cache.get(key);
|
|
4137
|
+
return found != null ? {
|
|
4138
|
+
status: "resolved",
|
|
4139
|
+
user: found
|
|
4140
|
+
} : (cache.set(key, null), {
|
|
4141
|
+
status: "missing"
|
|
4142
|
+
});
|
|
4143
|
+
} catch (cause) {
|
|
4144
|
+
return {
|
|
4145
|
+
status: "inaccessible",
|
|
4146
|
+
cause: cause
|
|
4147
|
+
};
|
|
4148
|
+
}
|
|
4149
|
+
}
|
|
4150
|
+
|
|
4151
|
+
async function ingestMemberJoin(args) {
|
|
4152
|
+
const {request: request, projectId: projectId, cache: cache} = args, snapshot = await requestProjectMemberDirectory({
|
|
4153
|
+
request: request,
|
|
4154
|
+
projectId: projectId
|
|
4155
|
+
});
|
|
4156
|
+
for (const {globalId: globalId, user: user} of snapshot.globalUsers) cache.set(`${projectId}:${globalId}`, user);
|
|
4157
|
+
}
|
|
4158
|
+
|
|
4159
|
+
function clientProjectUserDirectory(client, projectId) {
|
|
4160
|
+
return {
|
|
4161
|
+
findById: async id => {
|
|
4162
|
+
if (!client.request) return {
|
|
4163
|
+
status: "inaccessible",
|
|
4164
|
+
cause: new Error("Project-user resolution requires WorkflowClient.request")
|
|
4165
|
+
};
|
|
4166
|
+
if (classifyPrincipalId(id).namespace === "global") return resolveGlobalProjectUser({
|
|
4167
|
+
client: client,
|
|
4168
|
+
request: client.request,
|
|
4169
|
+
projectId: projectId,
|
|
4170
|
+
id: id
|
|
4171
|
+
});
|
|
4172
|
+
try {
|
|
4173
|
+
const response = await client.request({
|
|
4174
|
+
uri: `/projects/${encodeURIComponent(projectId)}/users/${encodeURIComponent(id)}`
|
|
4175
|
+
}), candidate = Array.isArray(response) ? response[0] : response;
|
|
4176
|
+
return candidate == null ? {
|
|
4177
|
+
status: "missing"
|
|
4178
|
+
} : isClientProjectUser(candidate) ? candidate.id !== id ? {
|
|
4179
|
+
status: "inaccessible",
|
|
4180
|
+
cause: new Error(`Project-user response answered id "${candidate.id}", not the requested "${id}"`)
|
|
4181
|
+
} : {
|
|
4182
|
+
status: "resolved",
|
|
4183
|
+
user: candidate
|
|
4184
|
+
} : {
|
|
4185
|
+
status: "inaccessible",
|
|
4186
|
+
cause: new Error("Project-user response had an invalid shape")
|
|
4187
|
+
};
|
|
4188
|
+
} catch (cause) {
|
|
4189
|
+
return isProjectUserNotFoundError(cause) ? {
|
|
4190
|
+
status: "missing"
|
|
4191
|
+
} : {
|
|
4192
|
+
status: "inaccessible",
|
|
4193
|
+
cause: cause
|
|
4194
|
+
};
|
|
4195
|
+
}
|
|
4196
|
+
}
|
|
4197
|
+
};
|
|
4198
|
+
}
|
|
4199
|
+
|
|
4200
|
+
function resolveClientActor(client, args) {
|
|
4201
|
+
return resolveActor(clientProjectUserDirectory(client, args.projectId), args.actor);
|
|
4202
|
+
}
|
|
4203
|
+
|
|
4204
|
+
async function resolveActor(directory, actor) {
|
|
4205
|
+
if (actor.kind !== "person") return {
|
|
4206
|
+
status: "not-person",
|
|
4207
|
+
actor: actor
|
|
4208
|
+
};
|
|
4209
|
+
const personActor = {
|
|
4210
|
+
...actor,
|
|
4211
|
+
kind: "person"
|
|
4212
|
+
}, lookup = await directory.findById(personActor.id);
|
|
4213
|
+
return lookup.status === "resolved" ? {
|
|
4214
|
+
status: "resolved",
|
|
4215
|
+
actor: personActor,
|
|
4216
|
+
user: lookup.user
|
|
4217
|
+
} : lookup.status === "inaccessible" ? {
|
|
4218
|
+
status: "inaccessible",
|
|
4219
|
+
actor: personActor,
|
|
4220
|
+
...lookup.cause === void 0 ? {} : {
|
|
4221
|
+
cause: lookup.cause
|
|
4222
|
+
}
|
|
4223
|
+
} : {
|
|
4224
|
+
status: "missing",
|
|
4225
|
+
actor: personActor
|
|
4226
|
+
};
|
|
4227
|
+
}
|
|
4228
|
+
|
|
4229
|
+
function assertRoleConstrainedAssignmentResource(args) {
|
|
4230
|
+
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}"`);
|
|
4231
|
+
}
|
|
4232
|
+
|
|
4233
|
+
const EXECUTION_KINDS = {
|
|
4234
|
+
interactive: "interactive",
|
|
4235
|
+
server: "server",
|
|
4236
|
+
cli: "cli",
|
|
4237
|
+
mcp: "mcp",
|
|
4238
|
+
drainer: "drainer",
|
|
4239
|
+
script: "script",
|
|
4240
|
+
test: "test",
|
|
4241
|
+
studio: "studio",
|
|
4242
|
+
sdkApp: "sdk-app"
|
|
4243
|
+
};
|
|
4244
|
+
|
|
4245
|
+
function detectRuntime() {
|
|
4246
|
+
const g = globalThis;
|
|
4247
|
+
if (g.Deno !== void 0) return "deno";
|
|
4248
|
+
if (g.Bun !== void 0) return "bun";
|
|
4249
|
+
if (g.EdgeRuntime !== void 0) return "edge";
|
|
4250
|
+
if (g.window !== void 0 && g.document !== void 0) return "browser";
|
|
4251
|
+
if (g.WorkerGlobalScope !== void 0 && g.self !== void 0) return "worker";
|
|
4252
|
+
const proc = g.process;
|
|
4253
|
+
return typeof proc == "object" && proc !== null && typeof proc.versions?.node == "string" ? "node" : "unknown";
|
|
4254
|
+
}
|
|
4255
|
+
|
|
4256
|
+
let inferredRuntime;
|
|
4257
|
+
|
|
4258
|
+
function resolveExecutionContext(declared) {
|
|
4259
|
+
return inferredRuntime ??= detectRuntime(), {
|
|
4260
|
+
runtime: inferredRuntime,
|
|
4261
|
+
...declared?.kind !== void 0 ? {
|
|
4262
|
+
kind: declared.kind
|
|
4263
|
+
} : {},
|
|
4264
|
+
...declared?.id !== void 0 ? {
|
|
4265
|
+
id: declared.id
|
|
4266
|
+
} : {}
|
|
4267
|
+
};
|
|
4268
|
+
}
|
|
4269
|
+
|
|
4270
|
+
function stampHistoryEntries(entries, stamp) {
|
|
4271
|
+
return entries.map(entry => ({
|
|
4272
|
+
...entry,
|
|
3816
4273
|
executionContext: stamp
|
|
3817
4274
|
}));
|
|
3818
4275
|
}
|
|
@@ -4090,10 +4547,8 @@ function assertRequiredInputProvided({entryDefs: entryDefs, initialFields: initi
|
|
|
4090
4547
|
});
|
|
4091
4548
|
}
|
|
4092
4549
|
|
|
4093
|
-
const ARRAY_FIELD_TYPES = /* @__PURE__ */ new Set([ "doc.refs", "array", "assignees" ]);
|
|
4094
|
-
|
|
4095
4550
|
function defaultEntryValue(entryType) {
|
|
4096
|
-
return
|
|
4551
|
+
return isAlwaysArrayFieldKind(entryType) ? [] : null;
|
|
4097
4552
|
}
|
|
4098
4553
|
|
|
4099
4554
|
function resolveInputValue({entry: entry, initialFields: initialFields, defaultValue: defaultValue}) {
|
|
@@ -4198,6 +4653,9 @@ function buildResolvedEntry({entry: entry, value: value, _key: _key, now: now})
|
|
|
4198
4653
|
...entry.validation !== void 0 ? {
|
|
4199
4654
|
validation: entry.validation
|
|
4200
4655
|
} : {},
|
|
4656
|
+
...entry.roles !== void 0 ? {
|
|
4657
|
+
roles: entry.roles
|
|
4658
|
+
} : {},
|
|
4201
4659
|
value: value,
|
|
4202
4660
|
...entry.initialValue?.type === "query" ? {
|
|
4203
4661
|
resolvedAt: now
|
|
@@ -4229,7 +4687,10 @@ async function resolveOneEntry({entry: entry, initialFields: initialFields, ctx:
|
|
|
4229
4687
|
fields: entry.fields,
|
|
4230
4688
|
of: entry.of,
|
|
4231
4689
|
options: entry.options,
|
|
4232
|
-
validation: entry.validation
|
|
4690
|
+
validation: entry.validation,
|
|
4691
|
+
roles: entry.roles,
|
|
4692
|
+
memberRoles: ctx.memberRoles,
|
|
4693
|
+
roleAliases: ctx.roleAliases
|
|
4233
4694
|
});
|
|
4234
4695
|
return "issues" in check ? (ctx.recordDiscard?.({
|
|
4235
4696
|
field: entry.name,
|
|
@@ -4254,7 +4715,10 @@ async function resolveOneEntry({entry: entry, initialFields: initialFields, ctx:
|
|
|
4254
4715
|
fields: entry.fields,
|
|
4255
4716
|
of: entry.of,
|
|
4256
4717
|
options: entry.options,
|
|
4257
|
-
validation: entry.validation
|
|
4718
|
+
validation: entry.validation,
|
|
4719
|
+
roles: entry.roles,
|
|
4720
|
+
memberRoles: ctx.memberRoles,
|
|
4721
|
+
roleAliases: ctx.roleAliases
|
|
4258
4722
|
});
|
|
4259
4723
|
return entry.initialValue?.type === "input" && ctx.inputProvenance !== "definition" && assertRefsWithinSurface({
|
|
4260
4724
|
entryType: entry.type,
|
|
@@ -4348,7 +4812,7 @@ function coerceToGdr(raw, workflowResource) {
|
|
|
4348
4812
|
} : null;
|
|
4349
4813
|
}
|
|
4350
4814
|
|
|
4351
|
-
const NonEmpty = NonEmptyString, UnknownRecord = v.record(v.string(), v.unknown()), PersistedChoiceOptionsSchema = v.looseObject({
|
|
4815
|
+
const NonEmpty = NonEmptyString, PersistedAssignmentRolesSchema = v.pipe(v.array(NonEmptyString), v.minLength(1, "assignment roles must not be empty")), UnknownRecord = v.record(v.string(), v.unknown()), PersistedChoiceOptionsSchema = v.looseObject({
|
|
4352
4816
|
list: v.array(v.looseObject({
|
|
4353
4817
|
title: v.string(),
|
|
4354
4818
|
value: v.union([ v.string(), v.number() ])
|
|
@@ -4363,6 +4827,7 @@ const NonEmpty = NonEmptyString, UnknownRecord = v.record(v.string(), v.unknown(
|
|
|
4363
4827
|
description: v.optional(v.string()),
|
|
4364
4828
|
options: v.optional(PersistedChoiceOptionsSchema),
|
|
4365
4829
|
validation: v.optional(PersistedScalarValidationSchema),
|
|
4830
|
+
roles: v.optional(PersistedAssignmentRolesSchema),
|
|
4366
4831
|
fields: v.optional(v.array(PersistedFieldShapeSchema)),
|
|
4367
4832
|
of: v.optional(v.array(PersistedFieldShapeSchema))
|
|
4368
4833
|
}))), ExecutionContextSchema = tolerantObject()({
|
|
@@ -4408,7 +4873,13 @@ const OptionalRefTypes = v.exactOptional(v.array(v.string())), ResolvedFieldEntr
|
|
|
4408
4873
|
})), v.looseObject(tolerantEntries()({
|
|
4409
4874
|
...fieldArm("subject", fieldValueSchemas.subject),
|
|
4410
4875
|
types: OptionalRefTypes
|
|
4411
|
-
})), v.looseObject(tolerantEntries()(fieldArm("release.ref", fieldValueSchemas["release.ref"]))), v.looseObject(tolerantEntries()(fieldArm("string", fieldValueSchemas.string))), v.looseObject(tolerantEntries()(fieldArm("text", fieldValueSchemas.text))), v.looseObject(tolerantEntries()(fieldArm("number", fieldValueSchemas.number))), v.looseObject(tolerantEntries()(fieldArm("progress", fieldValueSchemas.progress))), v.looseObject(tolerantEntries()(fieldArm("boolean", fieldValueSchemas.boolean))), v.looseObject(tolerantEntries()(fieldArm("date", fieldValueSchemas.date))), v.looseObject(tolerantEntries()(fieldArm("dueDate", fieldValueSchemas.dueDate))), v.looseObject(tolerantEntries()(fieldArm("datetime", fieldValueSchemas.datetime))), v.looseObject(tolerantEntries()(fieldArm("dueDatetime", fieldValueSchemas.dueDatetime))), v.looseObject(tolerantEntries()(fieldArm("url", fieldValueSchemas.url))), v.looseObject(tolerantEntries()(fieldArm("actor", fieldValueSchemas.actor))), v.looseObject(tolerantEntries()(
|
|
4876
|
+
})), v.looseObject(tolerantEntries()(fieldArm("release.ref", fieldValueSchemas["release.ref"]))), v.looseObject(tolerantEntries()(fieldArm("string", fieldValueSchemas.string))), v.looseObject(tolerantEntries()(fieldArm("text", fieldValueSchemas.text))), v.looseObject(tolerantEntries()(fieldArm("number", fieldValueSchemas.number))), v.looseObject(tolerantEntries()(fieldArm("progress", fieldValueSchemas.progress))), v.looseObject(tolerantEntries()(fieldArm("boolean", fieldValueSchemas.boolean))), v.looseObject(tolerantEntries()(fieldArm("date", fieldValueSchemas.date))), v.looseObject(tolerantEntries()(fieldArm("dueDate", fieldValueSchemas.dueDate))), v.looseObject(tolerantEntries()(fieldArm("datetime", fieldValueSchemas.datetime))), v.looseObject(tolerantEntries()(fieldArm("dueDatetime", fieldValueSchemas.dueDatetime))), v.looseObject(tolerantEntries()(fieldArm("url", fieldValueSchemas.url))), v.looseObject(tolerantEntries()(fieldArm("actor", fieldValueSchemas.actor))), v.looseObject(tolerantEntries()({
|
|
4877
|
+
...fieldArm("assignee", fieldValueSchemas.assignee),
|
|
4878
|
+
roles: v.exactOptional(PersistedAssignmentRolesSchema)
|
|
4879
|
+
})), v.looseObject(tolerantEntries()({
|
|
4880
|
+
...fieldArm("assignees", fieldValueSchemas.assignees),
|
|
4881
|
+
roles: v.exactOptional(PersistedAssignmentRolesSchema)
|
|
4882
|
+
})), v.looseObject(tolerantEntries()({
|
|
4412
4883
|
...fieldArm("object", v.union([ v.null(), UnknownRecord ])),
|
|
4413
4884
|
fields: v.array(PersistedFieldShapeSchema)
|
|
4414
4885
|
})), v.looseObject(tolerantEntries()({
|
|
@@ -4659,6 +5130,37 @@ function parseInstanceDocument(doc) {
|
|
|
4659
5130
|
});
|
|
4660
5131
|
}
|
|
4661
5132
|
|
|
5133
|
+
const WorkflowInstancePreviewEffectSchema = tolerantObject()({
|
|
5134
|
+
name: NonEmpty,
|
|
5135
|
+
title: v.exactOptional(v.string())
|
|
5136
|
+
}), WorkflowInstancePreviewSchema = v.looseObject(tolerantEntries()({
|
|
5137
|
+
_id: NonEmpty,
|
|
5138
|
+
_type: v.literal(WORKFLOW_INSTANCE_TYPE),
|
|
5139
|
+
modelVersion: v.exactOptional(v.number()),
|
|
5140
|
+
minReaderModel: v.exactOptional(v.number()),
|
|
5141
|
+
workflowResource: WorkflowResourceSchema,
|
|
5142
|
+
definition: NonEmpty,
|
|
5143
|
+
pinnedVersion: v.number(),
|
|
5144
|
+
fields: v.array(ResolvedFieldEntrySchema),
|
|
5145
|
+
ancestors: v.array(GdrShape),
|
|
5146
|
+
perspective: v.exactOptional(WorkflowPerspectiveSchema),
|
|
5147
|
+
currentStage: NonEmpty,
|
|
5148
|
+
stages: v.array(StageEntrySchema),
|
|
5149
|
+
claimedEffects: v.array(WorkflowInstancePreviewEffectSchema),
|
|
5150
|
+
failedEffects: v.array(WorkflowInstancePreviewEffectSchema),
|
|
5151
|
+
startedAt: IsoTimestamp,
|
|
5152
|
+
completedAt: v.exactOptional(IsoTimestamp),
|
|
5153
|
+
abortedAt: v.exactOptional(IsoTimestamp)
|
|
5154
|
+
}));
|
|
5155
|
+
|
|
5156
|
+
function parseInstancePreviewDocument(doc) {
|
|
5157
|
+
return parsePersistedDoc({
|
|
5158
|
+
schema: WorkflowInstancePreviewSchema,
|
|
5159
|
+
doc: doc,
|
|
5160
|
+
docType: WORKFLOW_INSTANCE_TYPE
|
|
5161
|
+
});
|
|
5162
|
+
}
|
|
5163
|
+
|
|
4662
5164
|
const SYNC_COMMIT = {
|
|
4663
5165
|
visibility: "sync"
|
|
4664
5166
|
}, ENGINE_API_VERSION = "2026-04-29", REQUEST_TAG = {
|
|
@@ -4694,7 +5196,9 @@ const SYNC_COMMIT = {
|
|
|
4694
5196
|
effect: "workflow.effect",
|
|
4695
5197
|
verifyDefinitions: "workflow.verify-definitions",
|
|
4696
5198
|
accessResolveActor: "workflow.access.resolve-actor",
|
|
4697
|
-
accessGrants: "workflow.access.grants"
|
|
5199
|
+
accessGrants: "workflow.access.grants",
|
|
5200
|
+
accessResolveOrg: "workflow.access.resolve-org",
|
|
5201
|
+
accessAttributes: "workflow.access.attributes"
|
|
4698
5202
|
}, RAW_PATCH = /* @__PURE__ */ Symbol("workflow-engine.raw-patch");
|
|
4699
5203
|
|
|
4700
5204
|
function unwrapPatch(patch) {
|
|
@@ -5104,6 +5608,40 @@ function readInstanceDoc(doc) {
|
|
|
5104
5608
|
return parseInstanceDocument(assertReadableModel(doc));
|
|
5105
5609
|
}
|
|
5106
5610
|
|
|
5611
|
+
function readInstancePreviewDoc(doc) {
|
|
5612
|
+
return hasDocumentId(doc) ? parseInstancePreviewDocument(withoutProjectedNulls(assertReadableModel(doc))) : parseInstancePreviewDocument(doc);
|
|
5613
|
+
}
|
|
5614
|
+
|
|
5615
|
+
function hasDocumentId(doc) {
|
|
5616
|
+
return typeof doc == "object" && doc !== null && typeof doc._id == "string";
|
|
5617
|
+
}
|
|
5618
|
+
|
|
5619
|
+
function withoutProjectedNulls(doc) {
|
|
5620
|
+
const row = withoutNullMembers(doc);
|
|
5621
|
+
if (typeof row != "object" || row === null) return row;
|
|
5622
|
+
const out = {
|
|
5623
|
+
...row
|
|
5624
|
+
};
|
|
5625
|
+
return Array.isArray(out.stages) && (out.stages = out.stages.map(withoutStageEntryNulls)),
|
|
5626
|
+
Array.isArray(out.claimedEffects) && (out.claimedEffects = out.claimedEffects.map(withoutNullMembers)),
|
|
5627
|
+
Array.isArray(out.failedEffects) && (out.failedEffects = out.failedEffects.map(withoutNullMembers)),
|
|
5628
|
+
out;
|
|
5629
|
+
}
|
|
5630
|
+
|
|
5631
|
+
function withoutStageEntryNulls(entry) {
|
|
5632
|
+
const stage = withoutNullMembers(entry);
|
|
5633
|
+
if (typeof stage != "object" || stage === null) return stage;
|
|
5634
|
+
const out = {
|
|
5635
|
+
...stage
|
|
5636
|
+
};
|
|
5637
|
+
return Array.isArray(out.activities) && (out.activities = out.activities.map(withoutNullMembers)),
|
|
5638
|
+
out;
|
|
5639
|
+
}
|
|
5640
|
+
|
|
5641
|
+
function withoutNullMembers(value) {
|
|
5642
|
+
return value === null || typeof value != "object" || Array.isArray(value) ? value : Object.fromEntries(Object.entries(value).filter(([, member]) => member !== null));
|
|
5643
|
+
}
|
|
5644
|
+
|
|
5107
5645
|
async function reload({client: client, instanceId: instanceId, tag: tag}) {
|
|
5108
5646
|
const doc = await getInstanceDocument(client, instanceId);
|
|
5109
5647
|
if (!doc) throw new InstanceNotFoundError({
|
|
@@ -5350,7 +5888,8 @@ function loadCallContext({client: client, instanceId: instanceId, options: optio
|
|
|
5350
5888
|
} : {},
|
|
5351
5889
|
...options.telemetry ? {
|
|
5352
5890
|
telemetry: options.telemetry
|
|
5353
|
-
} : {}
|
|
5891
|
+
} : {},
|
|
5892
|
+
memberRolesLoader: options.memberRolesLoader
|
|
5354
5893
|
}
|
|
5355
5894
|
});
|
|
5356
5895
|
}
|
|
@@ -5395,6 +5934,7 @@ async function loadContext({client: client, instanceId: instanceId, options: opt
|
|
|
5395
5934
|
...options.telemetry !== void 0 ? {
|
|
5396
5935
|
telemetry: options.telemetry
|
|
5397
5936
|
} : {},
|
|
5937
|
+
memberRolesLoader: options.memberRolesLoader,
|
|
5398
5938
|
...options.overlay !== void 0 ? {
|
|
5399
5939
|
overlay: options.overlay
|
|
5400
5940
|
} : {},
|
|
@@ -5430,7 +5970,10 @@ async function ctxEvaluateCondition({ctx: ctx, condition: condition, opts: opts}
|
|
|
5430
5970
|
}
|
|
5431
5971
|
|
|
5432
5972
|
async function buildEngineContext(args) {
|
|
5433
|
-
const {client: client, clientForGdr: clientForGdr, refSurface: refSurface, instance: instance, definition: definition} = args, clock = args.clock ?? wallClock
|
|
5973
|
+
const {client: client, clientForGdr: clientForGdr, refSurface: refSurface, instance: instance, definition: definition} = args, clock = args.clock ?? wallClock, memberRolesLoader = args.memberRolesLoader, memberRoles = await memberRolesLoader({
|
|
5974
|
+
workflowResource: instance.workflowResource,
|
|
5975
|
+
definition: definition
|
|
5976
|
+
});
|
|
5434
5977
|
return {
|
|
5435
5978
|
client: client,
|
|
5436
5979
|
clientForGdr: clientForGdr,
|
|
@@ -5447,6 +5990,10 @@ async function buildEngineContext(args) {
|
|
|
5447
5990
|
} : {},
|
|
5448
5991
|
instance: instance,
|
|
5449
5992
|
definition: definition,
|
|
5993
|
+
memberRolesLoader: memberRolesLoader,
|
|
5994
|
+
...memberRoles !== void 0 ? {
|
|
5995
|
+
memberRoles: memberRoles
|
|
5996
|
+
} : {},
|
|
5450
5997
|
snapshot: await hydrateSnapshot({
|
|
5451
5998
|
client: client,
|
|
5452
5999
|
clientForGdr: clientForGdr,
|
|
@@ -5458,25 +6005,83 @@ async function buildEngineContext(args) {
|
|
|
5458
6005
|
};
|
|
5459
6006
|
}
|
|
5460
6007
|
|
|
5461
|
-
function
|
|
5462
|
-
const
|
|
5463
|
-
|
|
5464
|
-
|
|
6008
|
+
function createAssignmentMemberRolesLoader(client) {
|
|
6009
|
+
const byProjectId = /* @__PURE__ */ new Map;
|
|
6010
|
+
return async ({workflowResource: workflowResource, definition: definition}) => {
|
|
6011
|
+
if (!hasRoleConstrainedAssignments(definition)) return;
|
|
6012
|
+
assertRoleConstrainedAssignmentResource({
|
|
6013
|
+
context: "workflow",
|
|
6014
|
+
definition: definition,
|
|
6015
|
+
workflowResource: workflowResource
|
|
6016
|
+
});
|
|
6017
|
+
const projectId = datasetResourceParts(workflowResource.id).projectId;
|
|
6018
|
+
let pending = byProjectId.get(projectId);
|
|
6019
|
+
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({
|
|
6020
|
+
request: client.request,
|
|
6021
|
+
projectId: projectId
|
|
6022
|
+
}), byProjectId.set(projectId, pending)), pending;
|
|
6023
|
+
};
|
|
5465
6024
|
}
|
|
5466
6025
|
|
|
5467
|
-
async function
|
|
5468
|
-
const {
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
6026
|
+
async function loadProjectMemberRoles(args) {
|
|
6027
|
+
const {request: request, projectId: projectId} = args, snapshot = await requestProjectMemberDirectory({
|
|
6028
|
+
request: request,
|
|
6029
|
+
projectId: projectId
|
|
6030
|
+
}), rolesByProjectId = projectMemberRoles({
|
|
6031
|
+
members: snapshot.members,
|
|
6032
|
+
projectId: projectId
|
|
6033
|
+
});
|
|
6034
|
+
return globalizeMemberRoles({
|
|
6035
|
+
snapshot: snapshot,
|
|
6036
|
+
rolesByProjectId: rolesByProjectId
|
|
6037
|
+
});
|
|
6038
|
+
}
|
|
6039
|
+
|
|
6040
|
+
function globalizeMemberRoles(args) {
|
|
6041
|
+
const {snapshot: snapshot, rolesByProjectId: rolesByProjectId} = args, humanIds = [ ...rolesByProjectId.keys() ].filter(id => classifyPrincipalId(id).namespace === "project");
|
|
6042
|
+
for (const {globalId: globalId, memberId: memberId} of snapshot.globalUsers) {
|
|
6043
|
+
const roles = rolesByProjectId.get(memberId);
|
|
6044
|
+
roles !== void 0 && rolesByProjectId.set(globalId, roles);
|
|
6045
|
+
}
|
|
6046
|
+
for (const id of humanIds) rolesByProjectId.delete(id);
|
|
6047
|
+
return Object.fromEntries(rolesByProjectId);
|
|
6048
|
+
}
|
|
6049
|
+
|
|
6050
|
+
function projectMemberRoles(args) {
|
|
6051
|
+
const result = /* @__PURE__ */ new Map;
|
|
6052
|
+
for (const member of args.members) {
|
|
6053
|
+
const {id: id, roles: roles} = member;
|
|
6054
|
+
if (!Array.isArray(roles) || !roles.every(isProjectMemberRole)) throw new Error(`Project member role directory response is invalid for project "${args.projectId}" and member "${id}"`);
|
|
6055
|
+
result.set(id, roles.map(role => role.name));
|
|
6056
|
+
}
|
|
6057
|
+
return result;
|
|
6058
|
+
}
|
|
6059
|
+
|
|
6060
|
+
function isProjectMemberRole(role) {
|
|
6061
|
+
return isRecord(role) && typeof role.name == "string";
|
|
6062
|
+
}
|
|
6063
|
+
|
|
6064
|
+
function findStage(definition, stageName) {
|
|
6065
|
+
const stage = definition.stages.find(s => s.name === stageName);
|
|
6066
|
+
if (stage === void 0) throw new Error(`Stage "${stageName}" not found in definition ${definition.name}`);
|
|
6067
|
+
return stage;
|
|
6068
|
+
}
|
|
6069
|
+
|
|
6070
|
+
async function resolveStageFieldEntries(args) {
|
|
6071
|
+
const {client: client, instance: instance, stage: stage, now: now, refSurface: refSurface, initialFields: initialFields, recordDiscard: recordDiscard} = args;
|
|
6072
|
+
return resolveDeclaredFields({
|
|
6073
|
+
entryDefs: stage.fields,
|
|
6074
|
+
initialFields: initialFields ?? [],
|
|
6075
|
+
ctx: {
|
|
6076
|
+
client: client,
|
|
6077
|
+
now: now,
|
|
6078
|
+
refSurface: refSurface,
|
|
5476
6079
|
selfId: instance._id,
|
|
5477
6080
|
tag: instance.tag,
|
|
5478
6081
|
stageName: stage.name,
|
|
5479
6082
|
workflowResource: instance.workflowResource,
|
|
6083
|
+
memberRoles: args.memberRoles,
|
|
6084
|
+
roleAliases: args.roleAliases,
|
|
5480
6085
|
workflowFields: instance.fields ?? [],
|
|
5481
6086
|
...instance.perspective !== void 0 ? {
|
|
5482
6087
|
perspective: instance.perspective
|
|
@@ -5503,6 +6108,8 @@ async function resolveActivityFieldEntries(args) {
|
|
|
5503
6108
|
stageName: stage.name,
|
|
5504
6109
|
workflowResource: instance.workflowResource,
|
|
5505
6110
|
activityName: activity.name,
|
|
6111
|
+
memberRoles: args.memberRoles,
|
|
6112
|
+
roleAliases: args.roleAliases,
|
|
5506
6113
|
workflowFields: instance.fields ?? [],
|
|
5507
6114
|
...instance.perspective !== void 0 ? {
|
|
5508
6115
|
perspective: instance.perspective
|
|
@@ -5658,171 +6265,6 @@ function resolveMetadata(metadata, ctx) {
|
|
|
5658
6265
|
return out;
|
|
5659
6266
|
}
|
|
5660
6267
|
|
|
5661
|
-
function userLoginProvider(user) {
|
|
5662
|
-
return user?.provider ?? user?.loginProvider;
|
|
5663
|
-
}
|
|
5664
|
-
|
|
5665
|
-
function isRecord(value) {
|
|
5666
|
-
return typeof value == "object" && value !== null && !Array.isArray(value);
|
|
5667
|
-
}
|
|
5668
|
-
|
|
5669
|
-
function optionalString(value) {
|
|
5670
|
-
return value === void 0 || typeof value == "string";
|
|
5671
|
-
}
|
|
5672
|
-
|
|
5673
|
-
function isClientProjectUser(value) {
|
|
5674
|
-
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);
|
|
5675
|
-
}
|
|
5676
|
-
|
|
5677
|
-
function objectProperty(value, property) {
|
|
5678
|
-
if (!isRecord(value)) return;
|
|
5679
|
-
const propertyValue = value[property];
|
|
5680
|
-
return typeof propertyValue == "object" && propertyValue !== null ? propertyValue : void 0;
|
|
5681
|
-
}
|
|
5682
|
-
|
|
5683
|
-
function stringProperty(value, property) {
|
|
5684
|
-
const propertyValue = Reflect.get(value, property);
|
|
5685
|
-
return typeof propertyValue == "string" ? propertyValue : void 0;
|
|
5686
|
-
}
|
|
5687
|
-
|
|
5688
|
-
function apiErrorType(error) {
|
|
5689
|
-
const response = objectProperty(error, "response"), body = objectProperty(response, "body");
|
|
5690
|
-
if (!body) return;
|
|
5691
|
-
const nestedError = objectProperty(body, "error");
|
|
5692
|
-
return (nestedError ? stringProperty(nestedError, "type") : void 0) ?? stringProperty(body, "type");
|
|
5693
|
-
}
|
|
5694
|
-
|
|
5695
|
-
function isProjectUserNotFoundError(error) {
|
|
5696
|
-
return apiErrorType(error) === "projectUserNotFoundError";
|
|
5697
|
-
}
|
|
5698
|
-
|
|
5699
|
-
const memberJoinCache = /* @__PURE__ */ new WeakMap;
|
|
5700
|
-
|
|
5701
|
-
function joinCacheFor(client) {
|
|
5702
|
-
let cache = memberJoinCache.get(client);
|
|
5703
|
-
return cache === void 0 && (cache = /* @__PURE__ */ new Map, memberJoinCache.set(client, cache)),
|
|
5704
|
-
cache;
|
|
5705
|
-
}
|
|
5706
|
-
|
|
5707
|
-
async function projectMemberIds(request, projectId) {
|
|
5708
|
-
const project = await request({
|
|
5709
|
-
uri: `/projects/${encodeURIComponent(projectId)}`
|
|
5710
|
-
}), members = isRecord(project) ? project.members : void 0;
|
|
5711
|
-
return Array.isArray(members) ? members.map(member => isRecord(member) ? member.id : void 0).filter(id => typeof id == "string") : [];
|
|
5712
|
-
}
|
|
5713
|
-
|
|
5714
|
-
async function resolveGlobalProjectUser(args) {
|
|
5715
|
-
const {client: client, request: request, projectId: projectId, id: id} = args, cache = joinCacheFor(client), key = `${projectId}:${id}`, hit = cache.get(key);
|
|
5716
|
-
if (hit !== void 0) return hit === null ? {
|
|
5717
|
-
status: "missing"
|
|
5718
|
-
} : {
|
|
5719
|
-
status: "resolved",
|
|
5720
|
-
user: hit
|
|
5721
|
-
};
|
|
5722
|
-
try {
|
|
5723
|
-
await ingestMemberJoin({
|
|
5724
|
-
request: request,
|
|
5725
|
-
projectId: projectId,
|
|
5726
|
-
cache: cache
|
|
5727
|
-
});
|
|
5728
|
-
const found = cache.get(key);
|
|
5729
|
-
return found != null ? {
|
|
5730
|
-
status: "resolved",
|
|
5731
|
-
user: found
|
|
5732
|
-
} : (cache.set(key, null), {
|
|
5733
|
-
status: "missing"
|
|
5734
|
-
});
|
|
5735
|
-
} catch (cause) {
|
|
5736
|
-
return {
|
|
5737
|
-
status: "inaccessible",
|
|
5738
|
-
cause: cause
|
|
5739
|
-
};
|
|
5740
|
-
}
|
|
5741
|
-
}
|
|
5742
|
-
|
|
5743
|
-
async function ingestMemberJoin(args) {
|
|
5744
|
-
const {request: request, projectId: projectId, cache: cache} = args, memberIds = await projectMemberIds(request, projectId);
|
|
5745
|
-
if (memberIds.length === 0) return;
|
|
5746
|
-
const requested = new Set(memberIds), response = await request({
|
|
5747
|
-
uri: `/projects/${encodeURIComponent(projectId)}/users/${memberIds.map(encodeURIComponent).join(",")}`
|
|
5748
|
-
});
|
|
5749
|
-
for (const row of Array.isArray(response) ? response : [ response ]) {
|
|
5750
|
-
if (!isClientProjectUser(row) || !requested.has(row.id)) continue;
|
|
5751
|
-
const globalId = directoryBridgeId(row.sanityUserId);
|
|
5752
|
-
globalId !== void 0 && cache.set(`${projectId}:${globalId}`, row);
|
|
5753
|
-
}
|
|
5754
|
-
}
|
|
5755
|
-
|
|
5756
|
-
function clientProjectUserDirectory(client, projectId) {
|
|
5757
|
-
return {
|
|
5758
|
-
findById: async id => {
|
|
5759
|
-
if (!client.request) return {
|
|
5760
|
-
status: "inaccessible",
|
|
5761
|
-
cause: new Error("Project-user resolution requires WorkflowClient.request")
|
|
5762
|
-
};
|
|
5763
|
-
if (classifyPrincipalId(id).namespace === "global") return resolveGlobalProjectUser({
|
|
5764
|
-
client: client,
|
|
5765
|
-
request: client.request,
|
|
5766
|
-
projectId: projectId,
|
|
5767
|
-
id: id
|
|
5768
|
-
});
|
|
5769
|
-
try {
|
|
5770
|
-
const response = await client.request({
|
|
5771
|
-
uri: `/projects/${encodeURIComponent(projectId)}/users/${encodeURIComponent(id)}`
|
|
5772
|
-
}), candidate = Array.isArray(response) ? response[0] : response;
|
|
5773
|
-
return candidate == null ? {
|
|
5774
|
-
status: "missing"
|
|
5775
|
-
} : isClientProjectUser(candidate) ? candidate.id !== id ? {
|
|
5776
|
-
status: "inaccessible",
|
|
5777
|
-
cause: new Error(`Project-user response answered id "${candidate.id}", not the requested "${id}"`)
|
|
5778
|
-
} : {
|
|
5779
|
-
status: "resolved",
|
|
5780
|
-
user: candidate
|
|
5781
|
-
} : {
|
|
5782
|
-
status: "inaccessible",
|
|
5783
|
-
cause: new Error("Project-user response had an invalid shape")
|
|
5784
|
-
};
|
|
5785
|
-
} catch (cause) {
|
|
5786
|
-
return isProjectUserNotFoundError(cause) ? {
|
|
5787
|
-
status: "missing"
|
|
5788
|
-
} : {
|
|
5789
|
-
status: "inaccessible",
|
|
5790
|
-
cause: cause
|
|
5791
|
-
};
|
|
5792
|
-
}
|
|
5793
|
-
}
|
|
5794
|
-
};
|
|
5795
|
-
}
|
|
5796
|
-
|
|
5797
|
-
function resolveClientActor(client, args) {
|
|
5798
|
-
return resolveActor(clientProjectUserDirectory(client, args.projectId), args.actor);
|
|
5799
|
-
}
|
|
5800
|
-
|
|
5801
|
-
async function resolveActor(directory, actor) {
|
|
5802
|
-
if (actor.kind !== "person") return {
|
|
5803
|
-
status: "not-person",
|
|
5804
|
-
actor: actor
|
|
5805
|
-
};
|
|
5806
|
-
const personActor = {
|
|
5807
|
-
...actor,
|
|
5808
|
-
kind: "person"
|
|
5809
|
-
}, lookup = await directory.findById(personActor.id);
|
|
5810
|
-
return lookup.status === "resolved" ? {
|
|
5811
|
-
status: "resolved",
|
|
5812
|
-
actor: personActor,
|
|
5813
|
-
user: lookup.user
|
|
5814
|
-
} : lookup.status === "inaccessible" ? {
|
|
5815
|
-
status: "inaccessible",
|
|
5816
|
-
actor: personActor,
|
|
5817
|
-
...lookup.cause === void 0 ? {} : {
|
|
5818
|
-
cause: lookup.cause
|
|
5819
|
-
}
|
|
5820
|
-
} : {
|
|
5821
|
-
status: "missing",
|
|
5822
|
-
actor: personActor
|
|
5823
|
-
};
|
|
5824
|
-
}
|
|
5825
|
-
|
|
5826
6268
|
const IDENTITY_KINDS = /* @__PURE__ */ new Set([ "actor", "assignee", "assignees" ]);
|
|
5827
6269
|
|
|
5828
6270
|
async function localizeGuardMetadata(args) {
|
|
@@ -6468,6 +6910,8 @@ async function buildActivityEntry({ctx: ctx, stage: stage, activity: activity, r
|
|
|
6468
6910
|
activity: activity,
|
|
6469
6911
|
now: ctx.now,
|
|
6470
6912
|
refSurface: ctx.refSurface,
|
|
6913
|
+
memberRoles: ctx.memberRoles,
|
|
6914
|
+
roleAliases: ctx.definition.roleAliases,
|
|
6471
6915
|
...recordDiscard !== void 0 ? {
|
|
6472
6916
|
recordDiscard: recordDiscard
|
|
6473
6917
|
} : {}
|
|
@@ -6670,7 +7114,8 @@ async function spawnRow({ctx: ctx, mutation: mutation, activity: activity, actio
|
|
|
6670
7114
|
context: context,
|
|
6671
7115
|
actor: actor,
|
|
6672
7116
|
now: now,
|
|
6673
|
-
refSurface: ctx.refSurface
|
|
7117
|
+
refSurface: ctx.refSurface,
|
|
7118
|
+
memberRolesLoader: ctx.memberRolesLoader
|
|
6674
7119
|
});
|
|
6675
7120
|
mutation.pendingCreates.push({
|
|
6676
7121
|
body: body,
|
|
@@ -6892,13 +7337,16 @@ async function resolveDefinitionRef({client: client, ref: ref, tag: tag}) {
|
|
|
6892
7337
|
}
|
|
6893
7338
|
|
|
6894
7339
|
async function prepareChildInstance(args) {
|
|
6895
|
-
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 = {
|
|
7340
|
+
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 = {
|
|
6896
7341
|
id: gdrFromResource(workflowResource, childDocId),
|
|
6897
7342
|
type: WORKFLOW_INSTANCE_TYPE
|
|
6898
7343
|
}, ancestors = [ ...parent.ancestors, {
|
|
6899
7344
|
id: selfGdr(parent),
|
|
6900
7345
|
type: WORKFLOW_INSTANCE_TYPE
|
|
6901
|
-
} ], inheritedPerspective = parent.perspective, fieldDiscards = [],
|
|
7346
|
+
} ], inheritedPerspective = parent.perspective, fieldDiscards = [], memberRoles = await memberRolesLoader({
|
|
7347
|
+
workflowResource: workflowResource,
|
|
7348
|
+
definition: definition
|
|
7349
|
+
}), childFields = await resolveDeclaredFields({
|
|
6902
7350
|
entryDefs: definition.fields,
|
|
6903
7351
|
initialFields: initialFields,
|
|
6904
7352
|
ctx: {
|
|
@@ -6909,6 +7357,8 @@ async function prepareChildInstance(args) {
|
|
|
6909
7357
|
workflowResource: workflowResource,
|
|
6910
7358
|
definitionName: definition.name,
|
|
6911
7359
|
refSurface: refSurface,
|
|
7360
|
+
memberRoles: memberRoles,
|
|
7361
|
+
roleAliases: definition.roleAliases,
|
|
6912
7362
|
inputProvenance: "definition",
|
|
6913
7363
|
...inheritedPerspective !== void 0 ? {
|
|
6914
7364
|
perspective: inheritedPerspective
|
|
@@ -6979,6 +7429,8 @@ async function enterStage({ctx: ctx, mutation: mutation, nextStage: nextStage, a
|
|
|
6979
7429
|
stage: nextStage,
|
|
6980
7430
|
now: at,
|
|
6981
7431
|
refSurface: ctx.refSurface,
|
|
7432
|
+
memberRoles: ctx.memberRoles,
|
|
7433
|
+
roleAliases: ctx.definition.roleAliases,
|
|
6982
7434
|
recordDiscard: recordFieldDiscards({
|
|
6983
7435
|
target: mutation.history,
|
|
6984
7436
|
scope: "stage",
|
|
@@ -7159,47 +7611,454 @@ async function grantsPermissionOn(args) {
|
|
|
7159
7611
|
return !1;
|
|
7160
7612
|
}
|
|
7161
7613
|
|
|
7162
|
-
function aclPathForResource(res) {
|
|
7163
|
-
if (res.type === "dataset") {
|
|
7164
|
-
const {projectId: projectId, dataset: dataset} = datasetResourceParts(res.id);
|
|
7165
|
-
return `/projects/${projectId}/datasets/${dataset}/acl`;
|
|
7614
|
+
function aclPathForResource(res) {
|
|
7615
|
+
if (res.type === "dataset") {
|
|
7616
|
+
const {projectId: projectId, dataset: dataset} = datasetResourceParts(res.id);
|
|
7617
|
+
return `/projects/${projectId}/datasets/${dataset}/acl`;
|
|
7618
|
+
}
|
|
7619
|
+
if (res.type === "canvas") return `/canvases/${res.id}/acl`;
|
|
7620
|
+
}
|
|
7621
|
+
|
|
7622
|
+
async function fetchGrants(args) {
|
|
7623
|
+
const {client: client, resourcePath: resourcePath, signal: signal} = args;
|
|
7624
|
+
return client.request({
|
|
7625
|
+
url: resourcePath,
|
|
7626
|
+
tag: REQUEST_TAG.accessGrants,
|
|
7627
|
+
...signal ? {
|
|
7628
|
+
signal: signal
|
|
7629
|
+
} : {}
|
|
7630
|
+
});
|
|
7631
|
+
}
|
|
7632
|
+
|
|
7633
|
+
async function advisoryCanForCall(args) {
|
|
7634
|
+
const actor = args.options?.actor;
|
|
7635
|
+
if (!(args.options?.grants === void 0 || actor === void 0)) return advisoryCan({
|
|
7636
|
+
instance: args.instance,
|
|
7637
|
+
identity: lakePrincipalId({
|
|
7638
|
+
actor: actor,
|
|
7639
|
+
localPrincipalId: args.options.localPrincipalId
|
|
7640
|
+
}),
|
|
7641
|
+
grants: args.options.grants
|
|
7642
|
+
});
|
|
7643
|
+
}
|
|
7644
|
+
|
|
7645
|
+
async function advisoryCan({instance: instance, identity: identity, grants: grants}) {
|
|
7646
|
+
if (grants === void 0) return;
|
|
7647
|
+
const can = {};
|
|
7648
|
+
for (const permission of DOCUMENT_VALUE_PERMISSIONS) can[permission] = await grantsPermissionOn({
|
|
7649
|
+
document: instance,
|
|
7650
|
+
grants: grants,
|
|
7651
|
+
permission: permission,
|
|
7652
|
+
userId: identity
|
|
7653
|
+
});
|
|
7654
|
+
return can;
|
|
7655
|
+
}
|
|
7656
|
+
|
|
7657
|
+
const DANGEROUS_ATTRIBUTE_KEYS = /* @__PURE__ */ new Set([ "__proto__", "constructor", "prototype" ]);
|
|
7658
|
+
|
|
7659
|
+
function attributeEntry(row) {
|
|
7660
|
+
if (!(!isRecord(row) || typeof row.key != "string" || row.key.length === 0) && !DANGEROUS_ATTRIBUTE_KEYS.has(row.key) && !(!("activeValue" in row) || row.activeValue === void 0)) return [ row.key, row.activeValue ];
|
|
7661
|
+
}
|
|
7662
|
+
|
|
7663
|
+
function normalizeUserAttributes(response) {
|
|
7664
|
+
if (!isRecord(response)) return;
|
|
7665
|
+
const rows = response.attributes;
|
|
7666
|
+
if (!Array.isArray(rows)) return;
|
|
7667
|
+
const out = {};
|
|
7668
|
+
for (const row of rows) {
|
|
7669
|
+
const entry = attributeEntry(row);
|
|
7670
|
+
entry !== void 0 && (out[entry[0]] = entry[1]);
|
|
7671
|
+
}
|
|
7672
|
+
return out;
|
|
7673
|
+
}
|
|
7674
|
+
|
|
7675
|
+
const actorCache = /* @__PURE__ */ new WeakMap, grantsCache = /* @__PURE__ */ new WeakMap, orgIdCache = /* @__PURE__ */ new WeakMap, attributesCache = /* @__PURE__ */ new WeakMap;
|
|
7676
|
+
|
|
7677
|
+
async function resolveAccess(taggedClient, args = {}) {
|
|
7678
|
+
const client = unwrapRequestTag(taggedClient), requestFn = lazyRequest(client);
|
|
7679
|
+
if (requestFn === void 0) throw new 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).");
|
|
7680
|
+
const grantsPromise = args.grantsFromPath !== void 0 ? cachedGrants({
|
|
7681
|
+
client: client,
|
|
7682
|
+
requestFn: requestFn,
|
|
7683
|
+
resourcePath: args.grantsFromPath
|
|
7684
|
+
}) : Promise.resolve(void 0), [identity, grants] = await Promise.all([ cachedActor(client, requestFn), grantsPromise ]);
|
|
7685
|
+
if (identity === void 0) throw new ContractViolationError("workflow: failed to resolve actor from `/users/me`. The client is configured but the endpoint returned no usable identity — check the token.");
|
|
7686
|
+
return {
|
|
7687
|
+
actor: identity.actor,
|
|
7688
|
+
...identity.localPrincipalId !== void 0 ? {
|
|
7689
|
+
localPrincipalId: identity.localPrincipalId
|
|
7690
|
+
} : {},
|
|
7691
|
+
...grants !== void 0 ? {
|
|
7692
|
+
grants: grants
|
|
7693
|
+
} : {}
|
|
7694
|
+
};
|
|
7695
|
+
}
|
|
7696
|
+
|
|
7697
|
+
async function resolveUserAttributes(taggedClient) {
|
|
7698
|
+
const client = unwrapRequestTag(taggedClient), requestFn = lazyRequest(client);
|
|
7699
|
+
if (requestFn !== void 0) return cachedAttributes({
|
|
7700
|
+
client: client,
|
|
7701
|
+
requestFn: requestFn
|
|
7702
|
+
});
|
|
7703
|
+
}
|
|
7704
|
+
|
|
7705
|
+
function cachedActor(client, requestFn) {
|
|
7706
|
+
const cached = actorCache.get(client);
|
|
7707
|
+
if (cached !== void 0) return cached;
|
|
7708
|
+
const pending = fetchActor(client, requestFn).catch(err => {
|
|
7709
|
+
throw actorCache.get(client) === pending && actorCache.delete(client), err;
|
|
7710
|
+
});
|
|
7711
|
+
return actorCache.set(client, pending), pending;
|
|
7712
|
+
}
|
|
7713
|
+
|
|
7714
|
+
function grantsForClientPath(taggedClient, resourcePath) {
|
|
7715
|
+
const client = unwrapRequestTag(taggedClient), requestFn = lazyRequest(client);
|
|
7716
|
+
return requestFn === void 0 ? Promise.resolve(void 0) : cachedGrants({
|
|
7717
|
+
client: client,
|
|
7718
|
+
requestFn: requestFn,
|
|
7719
|
+
resourcePath: resourcePath
|
|
7720
|
+
});
|
|
7721
|
+
}
|
|
7722
|
+
|
|
7723
|
+
function lazyRequest(client) {
|
|
7724
|
+
return client.request === void 0 ? void 0 : opts => client.request(opts);
|
|
7725
|
+
}
|
|
7726
|
+
|
|
7727
|
+
function cachedGrants({client: client, requestFn: requestFn, resourcePath: resourcePath}) {
|
|
7728
|
+
return cachedByKey({
|
|
7729
|
+
store: grantsCache,
|
|
7730
|
+
client: client,
|
|
7731
|
+
key: resourcePath,
|
|
7732
|
+
load: () => fetchGrantsCached(requestFn, resourcePath)
|
|
7733
|
+
});
|
|
7734
|
+
}
|
|
7735
|
+
|
|
7736
|
+
function cachedByKey(args) {
|
|
7737
|
+
let byKey = args.store.get(args.client);
|
|
7738
|
+
byKey === void 0 && (byKey = /* @__PURE__ */ new Map, args.store.set(args.client, byKey));
|
|
7739
|
+
const cached = byKey.get(args.key);
|
|
7740
|
+
if (cached !== void 0) return cached;
|
|
7741
|
+
const pending = args.evictOnRejection ? args.load().catch(err => {
|
|
7742
|
+
throw byKey.get(args.key) === pending && byKey.delete(args.key), err;
|
|
7743
|
+
}) : args.load();
|
|
7744
|
+
return byKey.set(args.key, pending), pending;
|
|
7745
|
+
}
|
|
7746
|
+
|
|
7747
|
+
async function fetchActor(client, requestFn) {
|
|
7748
|
+
const [resourceUser, globalUser] = await Promise.all([ fetchCurrentUser(requestFn, "the workflow resource host"), fetchGlobalUser(client) ]), resourceId = usableId(resourceUser), globalHostId = usableId(globalUser.user), carriedId = firstCarriedGlobalId([ globalHostId, resourceId ]), sessionId = carriedId ?? globalHostId ?? resourceId;
|
|
7749
|
+
if (sessionId === void 0) return;
|
|
7750
|
+
const bridge = carriedId === void 0 ? await bridgeProjectPrincipal({
|
|
7751
|
+
client: client,
|
|
7752
|
+
sessionId: sessionId,
|
|
7753
|
+
resourceId: resourceId
|
|
7754
|
+
}) : NO_BRIDGE, id = bridge.status === "resolved" ? bridge.globalId : sessionId;
|
|
7755
|
+
refuseProjectScopedActor({
|
|
7756
|
+
id: id,
|
|
7757
|
+
globalUser: globalUser,
|
|
7758
|
+
globalHostId: globalHostId,
|
|
7759
|
+
bridgeFailure: bridge.status === "unavailable" ? bridge : void 0
|
|
7760
|
+
});
|
|
7761
|
+
const roleNames = roleNamesFor(resourceUser, globalUser);
|
|
7762
|
+
return {
|
|
7763
|
+
actor: {
|
|
7764
|
+
kind: "person",
|
|
7765
|
+
id: id,
|
|
7766
|
+
...roleNames.length > 0 ? {
|
|
7767
|
+
roles: roleNames
|
|
7768
|
+
} : {}
|
|
7769
|
+
},
|
|
7770
|
+
...resourceId !== void 0 && resourceId !== id ? {
|
|
7771
|
+
localPrincipalId: resourceId
|
|
7772
|
+
} : {}
|
|
7773
|
+
};
|
|
7774
|
+
}
|
|
7775
|
+
|
|
7776
|
+
function roleNamesFor(resourceUser, globalUser) {
|
|
7777
|
+
return (resourceUser?.roles?.length ? resourceUser : globalUser.user)?.roles?.map(r => r.name).filter(n => !!n) ?? [];
|
|
7778
|
+
}
|
|
7779
|
+
|
|
7780
|
+
const NO_BRIDGE = {
|
|
7781
|
+
status: "not-applicable"
|
|
7782
|
+
};
|
|
7783
|
+
|
|
7784
|
+
function globalRouteReason(globalUser, globalHostId) {
|
|
7785
|
+
return "reason" in globalUser ? globalUser.reason : globalHostId === void 0 ? "no record" : `the global host answered with project-scoped principal "${globalHostId}"`;
|
|
7786
|
+
}
|
|
7787
|
+
|
|
7788
|
+
async function bridgeProjectPrincipal(args) {
|
|
7789
|
+
const {client: client, sessionId: sessionId, resourceId: resourceId} = args;
|
|
7790
|
+
return classifyPrincipalId(sessionId).namespace !== "project" ? NO_BRIDGE : resourceId === void 0 || classifyPrincipalId(resourceId).namespace !== "project" ? {
|
|
7791
|
+
status: "unavailable",
|
|
7792
|
+
reason: "no project-scoped principal from the resource host to address the directory with"
|
|
7793
|
+
} : directoryGlobalId({
|
|
7794
|
+
client: client,
|
|
7795
|
+
principalId: resourceId
|
|
7796
|
+
});
|
|
7797
|
+
}
|
|
7798
|
+
|
|
7799
|
+
async function directoryGlobalId(args) {
|
|
7800
|
+
const {client: client, principalId: principalId} = args, projectId = projectIdOf(client);
|
|
7801
|
+
if (projectId === void 0) return {
|
|
7802
|
+
status: "unavailable",
|
|
7803
|
+
reason: "the client reports no projectId, so its user directory has no address"
|
|
7804
|
+
};
|
|
7805
|
+
const lookup = await clientProjectUserDirectory(withRequestTag(client, REQUEST_TAG.accessResolveActor), projectId).findById(principalId);
|
|
7806
|
+
if (lookup.status !== "resolved") return {
|
|
7807
|
+
status: "unavailable",
|
|
7808
|
+
reason: `project "${projectId}"'s user directory reported the principal ${lookup.status}`,
|
|
7809
|
+
...lookup.status === "inaccessible" && lookup.cause !== void 0 ? {
|
|
7810
|
+
cause: lookup.cause
|
|
7811
|
+
} : {}
|
|
7812
|
+
};
|
|
7813
|
+
const globalId = directoryBridgeId(lookup.user.sanityUserId);
|
|
7814
|
+
return globalId === void 0 ? {
|
|
7815
|
+
status: "unavailable",
|
|
7816
|
+
reason: `project "${projectId}"'s user directory row for the principal carries no account-global sanityUserId`
|
|
7817
|
+
} : {
|
|
7818
|
+
status: "resolved",
|
|
7819
|
+
globalId: globalId
|
|
7820
|
+
};
|
|
7821
|
+
}
|
|
7822
|
+
|
|
7823
|
+
function refuseProjectScopedActor(args) {
|
|
7824
|
+
const {id: id, globalUser: globalUser, globalHostId: globalHostId, bridgeFailure: bridgeFailure} = args;
|
|
7825
|
+
if (classifyPrincipalId(id).namespace !== "project") return;
|
|
7826
|
+
const routes = [ `The account-global record: ${globalRouteReason(globalUser, globalHostId)}.` ];
|
|
7827
|
+
bridgeFailure !== void 0 && routes.push(`The project user directory: ${bridgeFailure.reason}.`);
|
|
7828
|
+
const cause = bridgeFailure?.cause ?? ("cause" in globalUser ? globalUser.cause : void 0);
|
|
7829
|
+
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 : {
|
|
7830
|
+
cause: cause
|
|
7831
|
+
});
|
|
7832
|
+
}
|
|
7833
|
+
|
|
7834
|
+
function usableId(user) {
|
|
7835
|
+
if (!(!user || typeof user.id != "string" || user.id.length === 0)) return user.id;
|
|
7836
|
+
}
|
|
7837
|
+
|
|
7838
|
+
async function fetchCurrentUser(requestFn, hostDescription) {
|
|
7839
|
+
try {
|
|
7840
|
+
return await requestFn({
|
|
7841
|
+
uri: "/users/me",
|
|
7842
|
+
tag: REQUEST_TAG.accessResolveActor
|
|
7843
|
+
});
|
|
7844
|
+
} catch (err) {
|
|
7845
|
+
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.`, {
|
|
7846
|
+
cause: err
|
|
7847
|
+
});
|
|
7848
|
+
}
|
|
7849
|
+
}
|
|
7850
|
+
|
|
7851
|
+
async function fetchGlobalUser(client) {
|
|
7852
|
+
const sibling = globalHostRequestOf(client);
|
|
7853
|
+
if ("reason" in sibling) return {
|
|
7854
|
+
user: void 0,
|
|
7855
|
+
reason: sibling.reason,
|
|
7856
|
+
...sibling.cause !== void 0 ? {
|
|
7857
|
+
cause: sibling.cause
|
|
7858
|
+
} : {}
|
|
7859
|
+
};
|
|
7860
|
+
try {
|
|
7861
|
+
const user = await sibling.request({
|
|
7862
|
+
uri: "/users/me",
|
|
7863
|
+
tag: REQUEST_TAG.accessResolveActor
|
|
7864
|
+
}), id = usableId(user);
|
|
7865
|
+
return sibling.requireGlobalPrincipal && id !== void 0 && classifyPrincipalId(id).namespace === "project" ? {
|
|
7866
|
+
user: void 0,
|
|
7867
|
+
reason: `global-host /users/me returned project-scoped principal "${id}"; the sibling client is still bound to a project API host`
|
|
7868
|
+
} : {
|
|
7869
|
+
user: user
|
|
7870
|
+
};
|
|
7871
|
+
} catch (err) {
|
|
7872
|
+
return {
|
|
7873
|
+
user: void 0,
|
|
7874
|
+
reason: `global-host /users/me failed: ${errorMessage(err)}`,
|
|
7875
|
+
cause: err
|
|
7876
|
+
};
|
|
7877
|
+
}
|
|
7878
|
+
}
|
|
7879
|
+
|
|
7880
|
+
function globalHostRequestOf(client) {
|
|
7881
|
+
if (typeof client.withConfig != "function") return {
|
|
7882
|
+
reason: "the client cannot reach the global API host (no withConfig)"
|
|
7883
|
+
};
|
|
7884
|
+
const hostResolution = resolveGlobalApiHost(client);
|
|
7885
|
+
try {
|
|
7886
|
+
const globalClient = client.withConfig({
|
|
7887
|
+
useProjectHostname: !1,
|
|
7888
|
+
apiVersion: ENGINE_API_VERSION,
|
|
7889
|
+
...hostResolution.apiHost === void 0 ? {} : {
|
|
7890
|
+
apiHost: hostResolution.apiHost
|
|
7891
|
+
}
|
|
7892
|
+
}), request = lazyRequest(globalClient);
|
|
7893
|
+
return request === void 0 ? {
|
|
7894
|
+
reason: "the global-host sibling client cannot issue requests"
|
|
7895
|
+
} : {
|
|
7896
|
+
request: request,
|
|
7897
|
+
requireGlobalPrincipal: hostResolution.requireGlobalPrincipal
|
|
7898
|
+
};
|
|
7899
|
+
} catch (err) {
|
|
7900
|
+
return {
|
|
7901
|
+
reason: `building the global-host sibling client failed: ${errorMessage(err)}`,
|
|
7902
|
+
cause: err
|
|
7903
|
+
};
|
|
7904
|
+
}
|
|
7905
|
+
}
|
|
7906
|
+
|
|
7907
|
+
function resolveGlobalApiHost(client) {
|
|
7908
|
+
if (typeof client.config != "function") return {
|
|
7909
|
+
requireGlobalPrincipal: !1
|
|
7910
|
+
};
|
|
7911
|
+
const apiHost = client.config().apiHost;
|
|
7912
|
+
if (apiHost === void 0) return {
|
|
7913
|
+
requireGlobalPrincipal: !1
|
|
7914
|
+
};
|
|
7915
|
+
let parsed;
|
|
7916
|
+
try {
|
|
7917
|
+
parsed = new URL(apiHost);
|
|
7918
|
+
} catch {
|
|
7919
|
+
return {
|
|
7920
|
+
requireGlobalPrincipal: !0
|
|
7921
|
+
};
|
|
7922
|
+
}
|
|
7923
|
+
if (/^api\.sanity\.(io|work)$/.test(parsed.hostname)) return {
|
|
7924
|
+
requireGlobalPrincipal: !1
|
|
7925
|
+
};
|
|
7926
|
+
const match = /^[^.]+\.api\.sanity\.(io|work)$/.exec(parsed.hostname);
|
|
7927
|
+
return match === null ? {
|
|
7928
|
+
requireGlobalPrincipal: !0
|
|
7929
|
+
} : (parsed.hostname = `api.sanity.${match[1]}`, {
|
|
7930
|
+
apiHost: parsed.origin,
|
|
7931
|
+
requireGlobalPrincipal: !0
|
|
7932
|
+
});
|
|
7933
|
+
}
|
|
7934
|
+
|
|
7935
|
+
async function fetchGrantsCached(requestFn, resourcePath) {
|
|
7936
|
+
try {
|
|
7937
|
+
return await fetchGrants({
|
|
7938
|
+
client: {
|
|
7939
|
+
request: requestFn
|
|
7940
|
+
},
|
|
7941
|
+
resourcePath: resourcePath
|
|
7942
|
+
});
|
|
7943
|
+
} catch (err) {
|
|
7944
|
+
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: ${errorMessage(err)}`);
|
|
7945
|
+
return;
|
|
7946
|
+
}
|
|
7947
|
+
}
|
|
7948
|
+
|
|
7949
|
+
function projectIdOf(client) {
|
|
7950
|
+
if (typeof client.config != "function") return;
|
|
7951
|
+
const projectId = client.config().projectId;
|
|
7952
|
+
return typeof projectId == "string" && projectId.length > 0 ? projectId : void 0;
|
|
7953
|
+
}
|
|
7954
|
+
|
|
7955
|
+
function cachedAttributes(args) {
|
|
7956
|
+
const projectId = projectIdOf(args.client);
|
|
7957
|
+
return projectId === void 0 ? Promise.resolve(void 0) : resolveOrganizationId({
|
|
7958
|
+
client: args.client,
|
|
7959
|
+
requestFn: args.requestFn,
|
|
7960
|
+
projectId: projectId
|
|
7961
|
+
}).then(orgId => {
|
|
7962
|
+
if (orgId !== void 0) return cachedByKey({
|
|
7963
|
+
store: attributesCache,
|
|
7964
|
+
client: args.client,
|
|
7965
|
+
key: orgId,
|
|
7966
|
+
evictOnRejection: !0,
|
|
7967
|
+
load: () => fetchAttributesCached({
|
|
7968
|
+
client: args.client,
|
|
7969
|
+
orgId: orgId
|
|
7970
|
+
})
|
|
7971
|
+
});
|
|
7972
|
+
});
|
|
7973
|
+
}
|
|
7974
|
+
|
|
7975
|
+
async function resolveOrganizationId(args) {
|
|
7976
|
+
const {client: client, requestFn: requestFn, projectId: projectId} = args;
|
|
7977
|
+
return cachedByKey({
|
|
7978
|
+
store: orgIdCache,
|
|
7979
|
+
client: client,
|
|
7980
|
+
key: projectId,
|
|
7981
|
+
evictOnRejection: !0,
|
|
7982
|
+
load: async () => {
|
|
7983
|
+
try {
|
|
7984
|
+
const project = await requestFn({
|
|
7985
|
+
uri: `/projects/${encodeURIComponent(projectId)}`,
|
|
7986
|
+
tag: REQUEST_TAG.accessResolveOrg
|
|
7987
|
+
});
|
|
7988
|
+
if (!isRecord(project)) return;
|
|
7989
|
+
const orgId = project.organizationId;
|
|
7990
|
+
return typeof orgId == "string" && orgId.length > 0 ? orgId : void 0;
|
|
7991
|
+
} catch (err) {
|
|
7992
|
+
const status = httpStatusOf(err);
|
|
7993
|
+
if (status !== void 0 && EXPECTED_ATTRIBUTES_ABSENCE.has(status)) return;
|
|
7994
|
+
throw new Error(`workflow: failed to resolve organizationId for project "${projectId}"; advisory $attributes cannot be bound. Original error: ${errorMessage(err)}`, {
|
|
7995
|
+
cause: err
|
|
7996
|
+
});
|
|
7997
|
+
}
|
|
7998
|
+
}
|
|
7999
|
+
});
|
|
8000
|
+
}
|
|
8001
|
+
|
|
8002
|
+
const ATTRIBUTES_FETCH_LIMIT = 100, EXPECTED_ATTRIBUTES_ABSENCE = /* @__PURE__ */ new Set([ 401, 402, 403, 404 ]);
|
|
8003
|
+
|
|
8004
|
+
function httpStatusOf(err) {
|
|
8005
|
+
if (!isRecord(err)) return;
|
|
8006
|
+
const status = err.statusCode;
|
|
8007
|
+
return typeof status == "number" ? status : void 0;
|
|
8008
|
+
}
|
|
8009
|
+
|
|
8010
|
+
async function fetchAttributesCached(args) {
|
|
8011
|
+
const {client: client, orgId: orgId} = args, sibling = globalHostRequestOf(client);
|
|
8012
|
+
if ("reason" in sibling) {
|
|
8013
|
+
console.warn(`workflow: skipped org attributes fetch (${sibling.reason}); advisory $attributes stays undefined (conditions referencing it fail closed).`);
|
|
8014
|
+
return;
|
|
8015
|
+
}
|
|
8016
|
+
try {
|
|
8017
|
+
const response = await sibling.request({
|
|
8018
|
+
uri: `/organizations/${encodeURIComponent(orgId)}/users/me/attributes?limit=${ATTRIBUTES_FETCH_LIMIT}`,
|
|
8019
|
+
tag: REQUEST_TAG.accessAttributes
|
|
8020
|
+
}), envelope = isRecord(response) ? response : void 0;
|
|
8021
|
+
if (envelope?.hasMore === !0) {
|
|
8022
|
+
const page = Array.isArray(envelope.attributes) ? envelope.attributes : [];
|
|
8023
|
+
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.`);
|
|
8024
|
+
}
|
|
8025
|
+
const normalized = normalizeUserAttributes(response);
|
|
8026
|
+
return normalized === void 0 && console.warn(`workflow: org attributes response for organization "${orgId}" was unusable; advisory $attributes stays undefined (conditions referencing it fail closed).`),
|
|
8027
|
+
normalized;
|
|
8028
|
+
} catch (err) {
|
|
8029
|
+
const status = httpStatusOf(err);
|
|
8030
|
+
if (status !== void 0 && EXPECTED_ATTRIBUTES_ABSENCE.has(status)) return;
|
|
8031
|
+
throw new Error(`workflow: failed to fetch org attributes for organization "${orgId}". Original error: ${errorMessage(err)}`, {
|
|
8032
|
+
cause: err
|
|
8033
|
+
});
|
|
7166
8034
|
}
|
|
7167
|
-
if (res.type === "canvas") return `/canvases/${res.id}/acl`;
|
|
7168
8035
|
}
|
|
7169
8036
|
|
|
7170
|
-
|
|
7171
|
-
const
|
|
7172
|
-
|
|
7173
|
-
|
|
7174
|
-
|
|
7175
|
-
...
|
|
7176
|
-
|
|
8037
|
+
function callerBoundVars(args) {
|
|
8038
|
+
const vars = {
|
|
8039
|
+
...args.can !== void 0 ? {
|
|
8040
|
+
can: args.can
|
|
8041
|
+
} : {},
|
|
8042
|
+
...args.attributes !== void 0 ? {
|
|
8043
|
+
attributes: args.attributes
|
|
7177
8044
|
} : {}
|
|
7178
|
-
}
|
|
8045
|
+
};
|
|
8046
|
+
return Object.keys(vars).length > 0 ? vars : void 0;
|
|
7179
8047
|
}
|
|
7180
8048
|
|
|
7181
|
-
async function
|
|
7182
|
-
const
|
|
7183
|
-
if (!(args.options?.grants === void 0 || actor === void 0)) return advisoryCan({
|
|
8049
|
+
async function callerBoundVarsForCall(args) {
|
|
8050
|
+
const can = await advisoryCanForCall({
|
|
7184
8051
|
instance: args.instance,
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
|
|
7191
|
-
|
|
7192
|
-
|
|
7193
|
-
|
|
7194
|
-
if (grants === void 0) return;
|
|
7195
|
-
const can = {};
|
|
7196
|
-
for (const permission of DOCUMENT_VALUE_PERMISSIONS) can[permission] = await grantsPermissionOn({
|
|
7197
|
-
document: instance,
|
|
7198
|
-
grants: grants,
|
|
7199
|
-
permission: permission,
|
|
7200
|
-
userId: identity
|
|
8052
|
+
options: args.options
|
|
8053
|
+
}), attributes = args.options?.attributes !== void 0 ? args.options.attributes : await resolveUserAttributes(args.client);
|
|
8054
|
+
return callerBoundVars({
|
|
8055
|
+
...can !== void 0 ? {
|
|
8056
|
+
can: can
|
|
8057
|
+
} : {},
|
|
8058
|
+
...attributes !== void 0 ? {
|
|
8059
|
+
attributes: attributes
|
|
8060
|
+
} : {}
|
|
7201
8061
|
});
|
|
7202
|
-
return can;
|
|
7203
8062
|
}
|
|
7204
8063
|
|
|
7205
8064
|
function requirementDescriptor(requirement) {
|
|
@@ -7322,7 +8181,8 @@ async function resolveActionCommit({ctx: ctx, activityName: activityName, action
|
|
|
7322
8181
|
}
|
|
7323
8182
|
});
|
|
7324
8183
|
if (action.filter !== void 0) {
|
|
7325
|
-
const
|
|
8184
|
+
const vars = await callerBoundVarsForCall({
|
|
8185
|
+
client: ctx.client,
|
|
7326
8186
|
instance: ctx.instance,
|
|
7327
8187
|
options: options
|
|
7328
8188
|
});
|
|
@@ -7334,10 +8194,8 @@ async function resolveActionCommit({ctx: ctx, activityName: activityName, action
|
|
|
7334
8194
|
...actor !== void 0 ? {
|
|
7335
8195
|
actor: actor
|
|
7336
8196
|
} : {},
|
|
7337
|
-
...
|
|
7338
|
-
vars:
|
|
7339
|
-
can: can
|
|
7340
|
-
}
|
|
8197
|
+
...vars !== void 0 ? {
|
|
8198
|
+
vars: vars
|
|
7341
8199
|
} : {}
|
|
7342
8200
|
}
|
|
7343
8201
|
})) throw new ActionDisabledError({
|
|
@@ -7410,7 +8268,9 @@ async function applyActionFire({ctx: ctx, mutation: mutation, activity: activity
|
|
|
7410
8268
|
self: selfGdr(ctx.instance),
|
|
7411
8269
|
now: ctx.now,
|
|
7412
8270
|
snapshot: ctx.snapshot,
|
|
7413
|
-
refSurface: ctx.refSurface
|
|
8271
|
+
refSurface: ctx.refSurface,
|
|
8272
|
+
memberRoles: ctx.memberRoles,
|
|
8273
|
+
roleAliases: ctx.definition.roleAliases
|
|
7414
8274
|
});
|
|
7415
8275
|
if (await queueEffects({
|
|
7416
8276
|
ctx: ctx,
|
|
@@ -7593,6 +8453,8 @@ async function primeInitialStage(args) {
|
|
|
7593
8453
|
stage: stage,
|
|
7594
8454
|
now: now,
|
|
7595
8455
|
refSurface: refSurface,
|
|
8456
|
+
memberRoles: ctx.memberRoles,
|
|
8457
|
+
roleAliases: ctx.definition.roleAliases,
|
|
7596
8458
|
recordDiscard: recordFieldDiscards({
|
|
7597
8459
|
target: discards,
|
|
7598
8460
|
scope: "stage",
|
|
@@ -7652,7 +8514,7 @@ async function primeInitialStage(args) {
|
|
|
7652
8514
|
|
|
7653
8515
|
const CASCADE_LIMIT = 100;
|
|
7654
8516
|
|
|
7655
|
-
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}) {
|
|
8517
|
+
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}) {
|
|
7656
8518
|
const contextOptions = {
|
|
7657
8519
|
clientForGdr: clientForGdr,
|
|
7658
8520
|
refSurface: refSurface,
|
|
@@ -7673,7 +8535,8 @@ async function runCascadeHop({client: client, instanceId: instanceId, actor: act
|
|
|
7673
8535
|
} : {},
|
|
7674
8536
|
...settlingCohorts ? {
|
|
7675
8537
|
settlingCohorts: settlingCohorts
|
|
7676
|
-
} : {}
|
|
8538
|
+
} : {},
|
|
8539
|
+
memberRolesLoader: memberRolesLoader
|
|
7677
8540
|
}, ctx = instance === void 0 ? await loadContext({
|
|
7678
8541
|
client: client,
|
|
7679
8542
|
instanceId: instanceId,
|
|
@@ -7712,7 +8575,7 @@ async function runCascadeHop({client: client, instanceId: instanceId, actor: act
|
|
|
7712
8575
|
});
|
|
7713
8576
|
}
|
|
7714
8577
|
|
|
7715
|
-
async function cascadeAutoTransitions({client: client, instanceId: instanceId, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, executionContext: executionContext, telemetry: telemetry, overlay: overlay, settlingCohorts: settlingCohorts}) {
|
|
8578
|
+
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}) {
|
|
7716
8579
|
let count = 0;
|
|
7717
8580
|
for (;;) {
|
|
7718
8581
|
const drained = await drainCondemnedChildren({
|
|
@@ -7721,6 +8584,7 @@ async function cascadeAutoTransitions({client: client, instanceId: instanceId, a
|
|
|
7721
8584
|
actor: actor,
|
|
7722
8585
|
clientForGdr: clientForGdr,
|
|
7723
8586
|
refSurface: refSurface,
|
|
8587
|
+
memberRolesLoader: memberRolesLoader,
|
|
7724
8588
|
clock: clock,
|
|
7725
8589
|
executionContext: executionContext,
|
|
7726
8590
|
telemetry: telemetry
|
|
@@ -7731,6 +8595,7 @@ async function cascadeAutoTransitions({client: client, instanceId: instanceId, a
|
|
|
7731
8595
|
actor: actor,
|
|
7732
8596
|
clientForGdr: clientForGdr,
|
|
7733
8597
|
refSurface: refSurface,
|
|
8598
|
+
memberRolesLoader: memberRolesLoader,
|
|
7734
8599
|
clock: clock,
|
|
7735
8600
|
executionContext: executionContext,
|
|
7736
8601
|
telemetry: telemetry,
|
|
@@ -7747,7 +8612,7 @@ async function cascadeAutoTransitions({client: client, instanceId: instanceId, a
|
|
|
7747
8612
|
}
|
|
7748
8613
|
}
|
|
7749
8614
|
|
|
7750
|
-
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}) {
|
|
8615
|
+
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}) {
|
|
7751
8616
|
if (draining.has(instanceId)) return {
|
|
7752
8617
|
instance: preloadedInstance,
|
|
7753
8618
|
drained: !1
|
|
@@ -7770,6 +8635,7 @@ async function drainCondemnedChildren({client: client, instanceId: instanceId, a
|
|
|
7770
8635
|
actor: actor,
|
|
7771
8636
|
clientForGdr: clientForGdr,
|
|
7772
8637
|
refSurface: refSurface,
|
|
8638
|
+
memberRolesLoader: memberRolesLoader,
|
|
7773
8639
|
clock: clock,
|
|
7774
8640
|
executionContext: executionContext,
|
|
7775
8641
|
telemetry: telemetry,
|
|
@@ -7787,7 +8653,7 @@ async function drainCondemnedChildren({client: client, instanceId: instanceId, a
|
|
|
7787
8653
|
};
|
|
7788
8654
|
}
|
|
7789
8655
|
|
|
7790
|
-
async function settleCondemnedRow({client: client, ownerId: ownerId, row: row, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, executionContext: executionContext, telemetry: telemetry, draining: draining}) {
|
|
8656
|
+
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}) {
|
|
7791
8657
|
const childId = toBareId(row.ref.id);
|
|
7792
8658
|
try {
|
|
7793
8659
|
const result = await abortInstance({
|
|
@@ -7800,6 +8666,7 @@ async function settleCondemnedRow({client: client, ownerId: ownerId, row: row, a
|
|
|
7800
8666
|
} : {},
|
|
7801
8667
|
clientForGdr: clientForGdr,
|
|
7802
8668
|
refSurface: refSurface,
|
|
8669
|
+
memberRolesLoader: memberRolesLoader,
|
|
7803
8670
|
...clock ? {
|
|
7804
8671
|
clock: clock
|
|
7805
8672
|
} : {},
|
|
@@ -7817,6 +8684,7 @@ async function settleCondemnedRow({client: client, ownerId: ownerId, row: row, a
|
|
|
7817
8684
|
actor: actor,
|
|
7818
8685
|
clientForGdr: clientForGdr,
|
|
7819
8686
|
refSurface: refSurface,
|
|
8687
|
+
memberRolesLoader: memberRolesLoader,
|
|
7820
8688
|
clock: clock,
|
|
7821
8689
|
executionContext: executionContext,
|
|
7822
8690
|
telemetry: telemetry,
|
|
@@ -7967,7 +8835,8 @@ async function buildCascadeStepContext(args, instance) {
|
|
|
7967
8835
|
} : {},
|
|
7968
8836
|
...args.settlingCohorts ? {
|
|
7969
8837
|
settlingCohorts: args.settlingCohorts
|
|
7970
|
-
} : {}
|
|
8838
|
+
} : {},
|
|
8839
|
+
memberRolesLoader: args.memberRolesLoader
|
|
7971
8840
|
});
|
|
7972
8841
|
}
|
|
7973
8842
|
|
|
@@ -8195,6 +9064,7 @@ function spawnStepArgs(ctx, args) {
|
|
|
8195
9064
|
actor: args.actor,
|
|
8196
9065
|
clientForGdr: ctx.clientForGdr,
|
|
8197
9066
|
refSurface: ctx.refSurface,
|
|
9067
|
+
memberRolesLoader: ctx.memberRolesLoader,
|
|
8198
9068
|
clock: ctx.clock,
|
|
8199
9069
|
executionContext: ctx.executionContext,
|
|
8200
9070
|
telemetry: ctx.telemetry,
|
|
@@ -8336,7 +9206,11 @@ function validateEffectOutputs(args) {
|
|
|
8336
9206
|
issues.push(`"${key}" is not a declared output`);
|
|
8337
9207
|
continue;
|
|
8338
9208
|
}
|
|
8339
|
-
const check = effectOutputCheck(
|
|
9209
|
+
const check = effectOutputCheck({
|
|
9210
|
+
shape: shape,
|
|
9211
|
+
value: value,
|
|
9212
|
+
eligibility: args
|
|
9213
|
+
});
|
|
8340
9214
|
"issues" in check ? issues.push(...check.issues.map(i => `"${key}": ${i}`)) : normalized[key] = check.output;
|
|
8341
9215
|
}
|
|
8342
9216
|
if (issues.length > 0) throw new EffectOutputsInvalidError({
|
|
@@ -8346,7 +9220,8 @@ function validateEffectOutputs(args) {
|
|
|
8346
9220
|
return normalized;
|
|
8347
9221
|
}
|
|
8348
9222
|
|
|
8349
|
-
function effectOutputCheck(
|
|
9223
|
+
function effectOutputCheck(args) {
|
|
9224
|
+
const {shape: shape, value: value, eligibility: eligibility} = args;
|
|
8350
9225
|
return parseFieldValue({
|
|
8351
9226
|
entryType: shape.type,
|
|
8352
9227
|
value: value,
|
|
@@ -8361,7 +9236,12 @@ function effectOutputCheck(shape, value) {
|
|
|
8361
9236
|
} : {},
|
|
8362
9237
|
...shape.validation !== void 0 ? {
|
|
8363
9238
|
validation: shape.validation
|
|
8364
|
-
} : {}
|
|
9239
|
+
} : {},
|
|
9240
|
+
...shape.roles !== void 0 ? {
|
|
9241
|
+
roles: shape.roles
|
|
9242
|
+
} : {},
|
|
9243
|
+
memberRoles: eligibility.memberRoles,
|
|
9244
|
+
roleAliases: eligibility.roleAliases
|
|
8365
9245
|
});
|
|
8366
9246
|
}
|
|
8367
9247
|
|
|
@@ -8384,7 +9264,7 @@ function requirePendingEffect(instance, effectKey) {
|
|
|
8384
9264
|
});
|
|
8385
9265
|
}
|
|
8386
9266
|
|
|
8387
|
-
function validateCompletionInput({pending: pending, definition: definition, status: status, ops: ops, outputs: outputs}) {
|
|
9267
|
+
function validateCompletionInput({pending: pending, definition: definition, status: status, ops: ops, outputs: outputs, memberRoles: memberRoles, roleAliases: roleAliases}) {
|
|
8388
9268
|
if (status === "failed" && ops !== void 0 && ops.length > 0) throw new EffectOpsInvalidError({
|
|
8389
9269
|
effect: pending.name,
|
|
8390
9270
|
issues: [ "ops cannot accompany a failed completion — field.set the outcome on a done completion instead" ]
|
|
@@ -8396,7 +9276,9 @@ function validateCompletionInput({pending: pending, definition: definition, stat
|
|
|
8396
9276
|
const normalizedOutputs = outputs !== void 0 ? validateEffectOutputs({
|
|
8397
9277
|
outputs: outputs,
|
|
8398
9278
|
declared: findEffect(definition, pending.name)?.outputs ?? [],
|
|
8399
|
-
effectName: pending.name
|
|
9279
|
+
effectName: pending.name,
|
|
9280
|
+
memberRoles: memberRoles,
|
|
9281
|
+
roleAliases: roleAliases
|
|
8400
9282
|
}) : void 0;
|
|
8401
9283
|
return {
|
|
8402
9284
|
ops: ops !== void 0 ? validateEffectOps(ops, pending.name) : [],
|
|
@@ -8415,7 +9297,9 @@ async function commitCompleteEffect({ctx: ctx, effectKey: effectKey, status: sta
|
|
|
8415
9297
|
definition: ctx.definition,
|
|
8416
9298
|
status: status,
|
|
8417
9299
|
ops: ops,
|
|
8418
|
-
outputs: outputs
|
|
9300
|
+
outputs: outputs,
|
|
9301
|
+
memberRoles: ctx.memberRoles,
|
|
9302
|
+
roleAliases: ctx.definition.roleAliases
|
|
8419
9303
|
}), mutation = startMutation(ctx.instance);
|
|
8420
9304
|
recordProcessedRequest({
|
|
8421
9305
|
mutation: mutation,
|
|
@@ -8446,7 +9330,9 @@ async function commitCompleteEffect({ctx: ctx, effectKey: effectKey, status: sta
|
|
|
8446
9330
|
self: selfGdr(ctx.instance),
|
|
8447
9331
|
now: ranAt,
|
|
8448
9332
|
snapshot: ctx.snapshot,
|
|
8449
|
-
refSurface: ctx.refSurface
|
|
9333
|
+
refSurface: ctx.refSurface,
|
|
9334
|
+
memberRoles: ctx.memberRoles,
|
|
9335
|
+
roleAliases: ctx.definition.roleAliases
|
|
8450
9336
|
}), needsGuardRefresh = wroteEffectOutputs || ranOps.some(isFieldOp);
|
|
8451
9337
|
return await persistThenMaybeRefresh({
|
|
8452
9338
|
ctx: ctx,
|
|
@@ -8615,7 +9501,9 @@ async function commitReport({ctx: ctx, effectKey: effectKey, claimToken: claimTo
|
|
|
8615
9501
|
self: selfGdr(ctx.instance),
|
|
8616
9502
|
now: ctx.now,
|
|
8617
9503
|
snapshot: ctx.snapshot,
|
|
8618
|
-
refSurface: ctx.refSurface
|
|
9504
|
+
refSurface: ctx.refSurface,
|
|
9505
|
+
memberRoles: ctx.memberRoles,
|
|
9506
|
+
roleAliases: ctx.definition.roleAliases
|
|
8619
9507
|
}), await persistThenMaybeRefresh({
|
|
8620
9508
|
ctx: ctx,
|
|
8621
9509
|
mutation: mutation,
|
|
@@ -8623,309 +9511,66 @@ async function commitReport({ctx: ctx, effectKey: effectKey, claimToken: claimTo
|
|
|
8623
9511
|
didChangeState: !0
|
|
8624
9512
|
}), {
|
|
8625
9513
|
effectKey: effectKey,
|
|
8626
|
-
effect: pending.name
|
|
8627
|
-
};
|
|
8628
|
-
}
|
|
8629
|
-
|
|
8630
|
-
const RESET_ACTIVITY_TARGETS = [ "active", "skipped" ];
|
|
8631
|
-
|
|
8632
|
-
function isResetActivityTarget(value) {
|
|
8633
|
-
return RESET_ACTIVITY_TARGETS.includes(value);
|
|
8634
|
-
}
|
|
8635
|
-
|
|
8636
|
-
async function resetActivity(args) {
|
|
8637
|
-
const {client: client, instanceId: instanceId, activity: activity, to: to, requestRecord: requestRecord, options: options} = args, ctx = await loadCallContext({
|
|
8638
|
-
client: client,
|
|
8639
|
-
instanceId: instanceId,
|
|
8640
|
-
options: options
|
|
8641
|
-
});
|
|
8642
|
-
return commitResetActivity({
|
|
8643
|
-
ctx: ctx,
|
|
8644
|
-
activity: activity,
|
|
8645
|
-
to: to,
|
|
8646
|
-
requestRecord: requestRecord,
|
|
8647
|
-
actor: options?.actor
|
|
8648
|
-
});
|
|
8649
|
-
}
|
|
8650
|
-
|
|
8651
|
-
async function commitResetActivity({ctx: ctx, activity: activity, to: to, requestRecord: requestRecord, actor: actor}) {
|
|
8652
|
-
if (assertRequestUnprocessed({
|
|
8653
|
-
instance: ctx.instance,
|
|
8654
|
-
record: requestRecord,
|
|
8655
|
-
now: ctx.now
|
|
8656
|
-
}), isTerminal(ctx)) return {
|
|
8657
|
-
fired: !1
|
|
8658
|
-
};
|
|
8659
|
-
const mutation = startMutation(ctx.instance), openStage2 = findOpenStageEntry(mutation), entry = findCurrentActivityEntry(mutation, activity);
|
|
8660
|
-
if (openStage2 === void 0 || entry === void 0) throw new ContractViolationError(`resetActivity: activity "${activity}" is not in the current stage of instance "${ctx.instance._id}"`);
|
|
8661
|
-
const from = entry.status;
|
|
8662
|
-
if (from === to) return {
|
|
8663
|
-
fired: !1
|
|
8664
|
-
};
|
|
8665
|
-
if (!isTerminalActivityStatus(from)) throw new 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.`);
|
|
8666
|
-
return recordProcessedRequest({
|
|
8667
|
-
mutation: mutation,
|
|
8668
|
-
record: requestRecord,
|
|
8669
|
-
now: ctx.now
|
|
8670
|
-
}), applyActivityStatusChange({
|
|
8671
|
-
entry: entry,
|
|
8672
|
-
history: mutation.history,
|
|
8673
|
-
stage: openStage2.name,
|
|
8674
|
-
to: to,
|
|
8675
|
-
at: ctx.now,
|
|
8676
|
-
...actor !== void 0 ? {
|
|
8677
|
-
actor: actor
|
|
8678
|
-
} : {}
|
|
8679
|
-
}), await persist(ctx, mutation), {
|
|
8680
|
-
fired: !0,
|
|
8681
|
-
stage: openStage2.name,
|
|
8682
|
-
activity: activity,
|
|
8683
|
-
from: from,
|
|
8684
|
-
to: to
|
|
8685
|
-
};
|
|
8686
|
-
}
|
|
8687
|
-
|
|
8688
|
-
const actorCache = /* @__PURE__ */ new WeakMap, grantsCache = /* @__PURE__ */ new WeakMap;
|
|
8689
|
-
|
|
8690
|
-
async function resolveAccess(taggedClient, args = {}) {
|
|
8691
|
-
const client = unwrapRequestTag(taggedClient), requestFn = lazyRequest(client);
|
|
8692
|
-
if (requestFn === void 0) throw new 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).");
|
|
8693
|
-
const grantsPromise = args.grantsFromPath !== void 0 ? cachedGrants({
|
|
8694
|
-
client: client,
|
|
8695
|
-
requestFn: requestFn,
|
|
8696
|
-
resourcePath: args.grantsFromPath
|
|
8697
|
-
}) : Promise.resolve(void 0), [identity, grants] = await Promise.all([ cachedActor(client, requestFn), grantsPromise ]);
|
|
8698
|
-
if (identity === void 0) throw new ContractViolationError("workflow: failed to resolve actor from `/users/me`. The client is configured but the endpoint returned no usable identity — check the token.");
|
|
8699
|
-
return {
|
|
8700
|
-
actor: identity.actor,
|
|
8701
|
-
...identity.localPrincipalId !== void 0 ? {
|
|
8702
|
-
localPrincipalId: identity.localPrincipalId
|
|
8703
|
-
} : {},
|
|
8704
|
-
...grants !== void 0 ? {
|
|
8705
|
-
grants: grants
|
|
8706
|
-
} : {}
|
|
8707
|
-
};
|
|
8708
|
-
}
|
|
8709
|
-
|
|
8710
|
-
function cachedActor(client, requestFn) {
|
|
8711
|
-
const cached = actorCache.get(client);
|
|
8712
|
-
if (cached !== void 0) return cached;
|
|
8713
|
-
const pending = fetchActor(client, requestFn).catch(err => {
|
|
8714
|
-
throw actorCache.get(client) === pending && actorCache.delete(client), err;
|
|
8715
|
-
});
|
|
8716
|
-
return actorCache.set(client, pending), pending;
|
|
8717
|
-
}
|
|
8718
|
-
|
|
8719
|
-
function grantsForClientPath(taggedClient, resourcePath) {
|
|
8720
|
-
const client = unwrapRequestTag(taggedClient), requestFn = lazyRequest(client);
|
|
8721
|
-
return requestFn === void 0 ? Promise.resolve(void 0) : cachedGrants({
|
|
8722
|
-
client: client,
|
|
8723
|
-
requestFn: requestFn,
|
|
8724
|
-
resourcePath: resourcePath
|
|
8725
|
-
});
|
|
8726
|
-
}
|
|
8727
|
-
|
|
8728
|
-
function lazyRequest(client) {
|
|
8729
|
-
return client.request === void 0 ? void 0 : opts => client.request(opts);
|
|
8730
|
-
}
|
|
8731
|
-
|
|
8732
|
-
function cachedGrants({client: client, requestFn: requestFn, resourcePath: resourcePath}) {
|
|
8733
|
-
let byPath = grantsCache.get(client);
|
|
8734
|
-
byPath === void 0 && (byPath = /* @__PURE__ */ new Map, grantsCache.set(client, byPath));
|
|
8735
|
-
let cached = byPath.get(resourcePath);
|
|
8736
|
-
return cached === void 0 && (cached = fetchGrantsCached(requestFn, resourcePath),
|
|
8737
|
-
byPath.set(resourcePath, cached)), cached;
|
|
8738
|
-
}
|
|
8739
|
-
|
|
8740
|
-
async function fetchActor(client, requestFn) {
|
|
8741
|
-
const [resourceUser, globalUser] = await Promise.all([ fetchCurrentUser(requestFn, "the workflow resource host"), fetchGlobalUser(client) ]), resourceId = usableId(resourceUser), globalHostId = usableId(globalUser.user), carriedId = firstCarriedGlobalId([ globalHostId, resourceId ]), sessionId = carriedId ?? globalHostId ?? resourceId;
|
|
8742
|
-
if (sessionId === void 0) return;
|
|
8743
|
-
const bridge = carriedId === void 0 ? await bridgeProjectPrincipal({
|
|
8744
|
-
client: client,
|
|
8745
|
-
sessionId: sessionId,
|
|
8746
|
-
resourceId: resourceId
|
|
8747
|
-
}) : NO_BRIDGE, id = bridge.status === "resolved" ? bridge.globalId : sessionId;
|
|
8748
|
-
refuseProjectScopedActor({
|
|
8749
|
-
id: id,
|
|
8750
|
-
globalUser: globalUser,
|
|
8751
|
-
globalHostId: globalHostId,
|
|
8752
|
-
bridgeFailure: bridge.status === "unavailable" ? bridge : void 0
|
|
8753
|
-
});
|
|
8754
|
-
const roleNames = roleNamesFor(resourceUser, globalUser);
|
|
8755
|
-
return {
|
|
8756
|
-
actor: {
|
|
8757
|
-
kind: "person",
|
|
8758
|
-
id: id,
|
|
8759
|
-
...roleNames.length > 0 ? {
|
|
8760
|
-
roles: roleNames
|
|
8761
|
-
} : {}
|
|
8762
|
-
},
|
|
8763
|
-
...resourceId !== void 0 && resourceId !== id ? {
|
|
8764
|
-
localPrincipalId: resourceId
|
|
8765
|
-
} : {}
|
|
8766
|
-
};
|
|
8767
|
-
}
|
|
8768
|
-
|
|
8769
|
-
function roleNamesFor(resourceUser, globalUser) {
|
|
8770
|
-
return (resourceUser?.roles?.length ? resourceUser : globalUser.user)?.roles?.map(r => r.name).filter(n => !!n) ?? [];
|
|
8771
|
-
}
|
|
8772
|
-
|
|
8773
|
-
const NO_BRIDGE = {
|
|
8774
|
-
status: "not-applicable"
|
|
8775
|
-
};
|
|
8776
|
-
|
|
8777
|
-
function globalRouteReason(globalUser, globalHostId) {
|
|
8778
|
-
return "reason" in globalUser ? globalUser.reason : globalHostId === void 0 ? "no record" : `the global host answered with project-scoped principal "${globalHostId}"`;
|
|
8779
|
-
}
|
|
8780
|
-
|
|
8781
|
-
async function bridgeProjectPrincipal(args) {
|
|
8782
|
-
const {client: client, sessionId: sessionId, resourceId: resourceId} = args;
|
|
8783
|
-
return classifyPrincipalId(sessionId).namespace !== "project" ? NO_BRIDGE : resourceId === void 0 || classifyPrincipalId(resourceId).namespace !== "project" ? {
|
|
8784
|
-
status: "unavailable",
|
|
8785
|
-
reason: "no project-scoped principal from the resource host to address the directory with"
|
|
8786
|
-
} : directoryGlobalId({
|
|
8787
|
-
client: client,
|
|
8788
|
-
principalId: resourceId
|
|
8789
|
-
});
|
|
8790
|
-
}
|
|
8791
|
-
|
|
8792
|
-
async function directoryGlobalId(args) {
|
|
8793
|
-
const {client: client, principalId: principalId} = args, projectId = typeof client.config == "function" ? client.config().projectId : void 0;
|
|
8794
|
-
if (projectId === void 0) return {
|
|
8795
|
-
status: "unavailable",
|
|
8796
|
-
reason: "the client reports no projectId, so its user directory has no address"
|
|
8797
|
-
};
|
|
8798
|
-
const lookup = await clientProjectUserDirectory(withRequestTag(client, REQUEST_TAG.accessResolveActor), projectId).findById(principalId);
|
|
8799
|
-
if (lookup.status !== "resolved") return {
|
|
8800
|
-
status: "unavailable",
|
|
8801
|
-
reason: `project "${projectId}"'s user directory reported the principal ${lookup.status}`,
|
|
8802
|
-
...lookup.status === "inaccessible" && lookup.cause !== void 0 ? {
|
|
8803
|
-
cause: lookup.cause
|
|
8804
|
-
} : {}
|
|
8805
|
-
};
|
|
8806
|
-
const globalId = directoryBridgeId(lookup.user.sanityUserId);
|
|
8807
|
-
return globalId === void 0 ? {
|
|
8808
|
-
status: "unavailable",
|
|
8809
|
-
reason: `project "${projectId}"'s user directory row for the principal carries no account-global sanityUserId`
|
|
8810
|
-
} : {
|
|
8811
|
-
status: "resolved",
|
|
8812
|
-
globalId: globalId
|
|
8813
|
-
};
|
|
8814
|
-
}
|
|
8815
|
-
|
|
8816
|
-
function refuseProjectScopedActor(args) {
|
|
8817
|
-
const {id: id, globalUser: globalUser, globalHostId: globalHostId, bridgeFailure: bridgeFailure} = args;
|
|
8818
|
-
if (classifyPrincipalId(id).namespace !== "project") return;
|
|
8819
|
-
const routes = [ `The account-global record: ${globalRouteReason(globalUser, globalHostId)}.` ];
|
|
8820
|
-
bridgeFailure !== void 0 && routes.push(`The project user directory: ${bridgeFailure.reason}.`);
|
|
8821
|
-
const cause = bridgeFailure?.cause ?? ("cause" in globalUser ? globalUser.cause : void 0);
|
|
8822
|
-
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 : {
|
|
8823
|
-
cause: cause
|
|
8824
|
-
});
|
|
9514
|
+
effect: pending.name
|
|
9515
|
+
};
|
|
8825
9516
|
}
|
|
8826
9517
|
|
|
8827
|
-
|
|
8828
|
-
if (!(!user || typeof user.id != "string" || user.id.length === 0)) return user.id;
|
|
8829
|
-
}
|
|
9518
|
+
const RESET_ACTIVITY_TARGETS = [ "active", "skipped" ];
|
|
8830
9519
|
|
|
8831
|
-
|
|
8832
|
-
|
|
8833
|
-
return await requestFn({
|
|
8834
|
-
uri: "/users/me",
|
|
8835
|
-
tag: REQUEST_TAG.accessResolveActor
|
|
8836
|
-
});
|
|
8837
|
-
} catch (err) {
|
|
8838
|
-
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.`, {
|
|
8839
|
-
cause: err
|
|
8840
|
-
});
|
|
8841
|
-
}
|
|
9520
|
+
function isResetActivityTarget(value) {
|
|
9521
|
+
return RESET_ACTIVITY_TARGETS.includes(value);
|
|
8842
9522
|
}
|
|
8843
9523
|
|
|
8844
|
-
async function
|
|
8845
|
-
|
|
8846
|
-
|
|
8847
|
-
|
|
8848
|
-
|
|
8849
|
-
|
|
8850
|
-
|
|
8851
|
-
|
|
8852
|
-
|
|
8853
|
-
|
|
8854
|
-
|
|
8855
|
-
|
|
8856
|
-
|
|
8857
|
-
}), globalRequest = lazyRequest(globalClient);
|
|
8858
|
-
} catch (err) {
|
|
8859
|
-
return {
|
|
8860
|
-
user: void 0,
|
|
8861
|
-
reason: `building the global-host sibling client failed: ${errorMessage(err)}`,
|
|
8862
|
-
cause: err
|
|
8863
|
-
};
|
|
8864
|
-
}
|
|
8865
|
-
if (globalRequest === void 0) return {
|
|
8866
|
-
user: void 0,
|
|
8867
|
-
reason: "the global-host sibling client cannot issue requests"
|
|
8868
|
-
};
|
|
8869
|
-
try {
|
|
8870
|
-
const user = await globalRequest({
|
|
8871
|
-
uri: "/users/me",
|
|
8872
|
-
tag: REQUEST_TAG.accessResolveActor
|
|
8873
|
-
}), id = usableId(user);
|
|
8874
|
-
return hostResolution.requireGlobalPrincipal && id !== void 0 && classifyPrincipalId(id).namespace === "project" ? {
|
|
8875
|
-
user: void 0,
|
|
8876
|
-
reason: `global-host /users/me returned project-scoped principal "${id}"; the sibling client is still bound to a project API host`
|
|
8877
|
-
} : {
|
|
8878
|
-
user: user
|
|
8879
|
-
};
|
|
8880
|
-
} catch (err) {
|
|
8881
|
-
return {
|
|
8882
|
-
user: void 0,
|
|
8883
|
-
reason: `global-host /users/me failed: ${errorMessage(err)}`,
|
|
8884
|
-
cause: err
|
|
8885
|
-
};
|
|
8886
|
-
}
|
|
9524
|
+
async function resetActivity(args) {
|
|
9525
|
+
const {client: client, instanceId: instanceId, activity: activity, to: to, requestRecord: requestRecord, options: options} = args, ctx = await loadCallContext({
|
|
9526
|
+
client: client,
|
|
9527
|
+
instanceId: instanceId,
|
|
9528
|
+
options: options
|
|
9529
|
+
});
|
|
9530
|
+
return commitResetActivity({
|
|
9531
|
+
ctx: ctx,
|
|
9532
|
+
activity: activity,
|
|
9533
|
+
to: to,
|
|
9534
|
+
requestRecord: requestRecord,
|
|
9535
|
+
actor: options?.actor
|
|
9536
|
+
});
|
|
8887
9537
|
}
|
|
8888
9538
|
|
|
8889
|
-
function
|
|
8890
|
-
if (
|
|
8891
|
-
|
|
9539
|
+
async function commitResetActivity({ctx: ctx, activity: activity, to: to, requestRecord: requestRecord, actor: actor}) {
|
|
9540
|
+
if (assertRequestUnprocessed({
|
|
9541
|
+
instance: ctx.instance,
|
|
9542
|
+
record: requestRecord,
|
|
9543
|
+
now: ctx.now
|
|
9544
|
+
}), isTerminal(ctx)) return {
|
|
9545
|
+
fired: !1
|
|
8892
9546
|
};
|
|
8893
|
-
const
|
|
8894
|
-
if (
|
|
8895
|
-
|
|
9547
|
+
const mutation = startMutation(ctx.instance), openStage2 = findOpenStageEntry(mutation), entry = findCurrentActivityEntry(mutation, activity);
|
|
9548
|
+
if (openStage2 === void 0 || entry === void 0) throw new ContractViolationError(`resetActivity: activity "${activity}" is not in the current stage of instance "${ctx.instance._id}"`);
|
|
9549
|
+
const from = entry.status;
|
|
9550
|
+
if (from === to) return {
|
|
9551
|
+
fired: !1
|
|
8896
9552
|
};
|
|
8897
|
-
|
|
8898
|
-
|
|
8899
|
-
|
|
8900
|
-
|
|
8901
|
-
|
|
8902
|
-
|
|
8903
|
-
|
|
8904
|
-
|
|
8905
|
-
|
|
8906
|
-
|
|
9553
|
+
if (!isTerminalActivityStatus(from)) throw new 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.`);
|
|
9554
|
+
return recordProcessedRequest({
|
|
9555
|
+
mutation: mutation,
|
|
9556
|
+
record: requestRecord,
|
|
9557
|
+
now: ctx.now
|
|
9558
|
+
}), applyActivityStatusChange({
|
|
9559
|
+
entry: entry,
|
|
9560
|
+
history: mutation.history,
|
|
9561
|
+
stage: openStage2.name,
|
|
9562
|
+
to: to,
|
|
9563
|
+
at: ctx.now,
|
|
9564
|
+
...actor !== void 0 ? {
|
|
9565
|
+
actor: actor
|
|
9566
|
+
} : {}
|
|
9567
|
+
}), await persist(ctx, mutation), {
|
|
9568
|
+
fired: !0,
|
|
9569
|
+
stage: openStage2.name,
|
|
9570
|
+
activity: activity,
|
|
9571
|
+
from: from,
|
|
9572
|
+
to: to
|
|
8907
9573
|
};
|
|
8908
|
-
const match = /^[^.]+\.api\.sanity\.(io|work)$/.exec(parsed.hostname);
|
|
8909
|
-
return match === null ? {
|
|
8910
|
-
requireGlobalPrincipal: !0
|
|
8911
|
-
} : (parsed.hostname = `api.sanity.${match[1]}`, {
|
|
8912
|
-
apiHost: parsed.origin,
|
|
8913
|
-
requireGlobalPrincipal: !0
|
|
8914
|
-
});
|
|
8915
|
-
}
|
|
8916
|
-
|
|
8917
|
-
async function fetchGrantsCached(requestFn, resourcePath) {
|
|
8918
|
-
try {
|
|
8919
|
-
return await fetchGrants({
|
|
8920
|
-
client: {
|
|
8921
|
-
request: requestFn
|
|
8922
|
-
},
|
|
8923
|
-
resourcePath: resourcePath
|
|
8924
|
-
});
|
|
8925
|
-
} catch (err) {
|
|
8926
|
-
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: ${errorMessage(err)}`);
|
|
8927
|
-
return;
|
|
8928
|
-
}
|
|
8929
9574
|
}
|
|
8930
9575
|
|
|
8931
9576
|
const REPLAY_SURFACE = {
|
|
@@ -9109,7 +9754,7 @@ async function resourceActorId(client) {
|
|
|
9109
9754
|
async function evaluateInstance(args) {
|
|
9110
9755
|
const {client: client, tag: tag, workflowResource: workflowResource, instanceId: instanceId, resourceClients: resourceClients} = args, now = (args.clock ?? wallClock)();
|
|
9111
9756
|
validateTag(tag);
|
|
9112
|
-
const [access, instance] = await Promise.all([ resolveAccess(client, {
|
|
9757
|
+
const [access, instance, attributes] = await Promise.all([ resolveAccess(client, {
|
|
9113
9758
|
...args.grantsFromPath !== void 0 ? {
|
|
9114
9759
|
grantsFromPath: args.grantsFromPath
|
|
9115
9760
|
} : {}
|
|
@@ -9117,7 +9762,7 @@ async function evaluateInstance(args) {
|
|
|
9117
9762
|
client: client,
|
|
9118
9763
|
instanceId: instanceId,
|
|
9119
9764
|
tag: tag
|
|
9120
|
-
}) ]), {actor: actor, grants: grants, localPrincipalId: localPrincipalId} = access, definition = parseDefinitionSnapshot(instance), clientForGdr = buildClientForGdr({
|
|
9765
|
+
}), resolveUserAttributes(client) ]), {actor: actor, grants: grants, localPrincipalId: localPrincipalId} = access, definition = parseDefinitionSnapshot(instance), clientForGdr = buildClientForGdr({
|
|
9121
9766
|
client: client,
|
|
9122
9767
|
workflowResource: workflowResource,
|
|
9123
9768
|
resourceClients: resourceClients
|
|
@@ -9142,6 +9787,9 @@ async function evaluateInstance(args) {
|
|
|
9142
9787
|
} : {},
|
|
9143
9788
|
...grants !== void 0 ? {
|
|
9144
9789
|
grants: grants
|
|
9790
|
+
} : {},
|
|
9791
|
+
...attributes !== void 0 ? {
|
|
9792
|
+
attributes: attributes
|
|
9145
9793
|
} : {}
|
|
9146
9794
|
});
|
|
9147
9795
|
}
|
|
@@ -9156,6 +9804,33 @@ function memoizedByName(render) {
|
|
|
9156
9804
|
};
|
|
9157
9805
|
}
|
|
9158
9806
|
|
|
9807
|
+
async function callerBoundProjectionScopes(args) {
|
|
9808
|
+
const can = await advisoryCan({
|
|
9809
|
+
instance: args.instance,
|
|
9810
|
+
identity: args.identity,
|
|
9811
|
+
grants: args.grants
|
|
9812
|
+
}), vars = callerBoundVars({
|
|
9813
|
+
...can !== void 0 ? {
|
|
9814
|
+
can: can
|
|
9815
|
+
} : {},
|
|
9816
|
+
...args.attributes !== void 0 ? {
|
|
9817
|
+
attributes: args.attributes
|
|
9818
|
+
} : {}
|
|
9819
|
+
}), opts = {
|
|
9820
|
+
actor: args.actor,
|
|
9821
|
+
...vars !== void 0 ? {
|
|
9822
|
+
vars: vars
|
|
9823
|
+
} : {}
|
|
9824
|
+
};
|
|
9825
|
+
return {
|
|
9826
|
+
scope: await renderConditionScope(args.scopeSource, opts),
|
|
9827
|
+
scopeForActivity: memoizedByName(activityName => renderConditionScope(args.scopeSource, {
|
|
9828
|
+
activityName: activityName,
|
|
9829
|
+
...opts
|
|
9830
|
+
}))
|
|
9831
|
+
};
|
|
9832
|
+
}
|
|
9833
|
+
|
|
9159
9834
|
function currentStageOf(instance, definition) {
|
|
9160
9835
|
try {
|
|
9161
9836
|
return findStage(definition, instance.currentStage);
|
|
@@ -9181,7 +9856,7 @@ async function explainSite(args) {
|
|
|
9181
9856
|
}
|
|
9182
9857
|
|
|
9183
9858
|
async function evaluateFromSnapshot(args) {
|
|
9184
|
-
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({
|
|
9859
|
+
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({
|
|
9185
9860
|
instance: instance,
|
|
9186
9861
|
definition: definition,
|
|
9187
9862
|
snapshot: snapshot,
|
|
@@ -9198,22 +9873,14 @@ async function evaluateFromSnapshot(args) {
|
|
|
9198
9873
|
}, anchorIdentity = lakePrincipalId({
|
|
9199
9874
|
actor: actor,
|
|
9200
9875
|
localPrincipalId: args.localPrincipalId
|
|
9201
|
-
}),
|
|
9202
|
-
|
|
9203
|
-
identity: anchorIdentity,
|
|
9204
|
-
grants: grants
|
|
9205
|
-
}), scope = await renderConditionScope(scopeSource, {
|
|
9876
|
+
}), {scope: scope, scopeForActivity: scopeForActivity} = await callerBoundProjectionScopes({
|
|
9877
|
+
scopeSource: scopeSource,
|
|
9206
9878
|
actor: actor,
|
|
9207
|
-
|
|
9208
|
-
|
|
9209
|
-
|
|
9210
|
-
|
|
9211
|
-
|
|
9212
|
-
actor: actor,
|
|
9213
|
-
vars: {
|
|
9214
|
-
can: can
|
|
9215
|
-
}
|
|
9216
|
-
})), cascadeScopeForActivity = memoizedByName(activityName => renderConditionScope(scopeSource, {
|
|
9879
|
+
instance: instance,
|
|
9880
|
+
grants: grants,
|
|
9881
|
+
attributes: attributes,
|
|
9882
|
+
identity: anchorIdentity
|
|
9883
|
+
}), cascadeScopeForActivity = memoizedByName(activityName => renderConditionScope(scopeSource, {
|
|
9217
9884
|
activityName: activityName
|
|
9218
9885
|
})), currentActivityEntries = findOpenStageEntry(instance)?.activities ?? [], guardDenial = await instanceGuardReason({
|
|
9219
9886
|
instance: instance,
|
|
@@ -9262,6 +9929,7 @@ async function evaluateFromSnapshot(args) {
|
|
|
9262
9929
|
}
|
|
9263
9930
|
const currentStage = {
|
|
9264
9931
|
stage: stage,
|
|
9932
|
+
...semanticsOf(stage),
|
|
9265
9933
|
activities: activityEvaluations,
|
|
9266
9934
|
transitions: transitionEvaluations,
|
|
9267
9935
|
autonomy: stageAutonomy2
|
|
@@ -9278,6 +9946,7 @@ async function evaluateFromSnapshot(args) {
|
|
|
9278
9946
|
return {
|
|
9279
9947
|
instance: instance,
|
|
9280
9948
|
definition: definition,
|
|
9949
|
+
...semanticsOf(definition),
|
|
9281
9950
|
actor: actor,
|
|
9282
9951
|
currentStage: currentStage,
|
|
9283
9952
|
pendingOnYou: pendingOnYou,
|
|
@@ -9329,6 +9998,12 @@ async function evaluateEditableFields(args) {
|
|
|
9329
9998
|
...site.validation !== void 0 ? {
|
|
9330
9999
|
validation: site.validation
|
|
9331
10000
|
} : {},
|
|
10001
|
+
...site.roles !== void 0 ? {
|
|
10002
|
+
roles: site.roles,
|
|
10003
|
+
...definition.roleAliases !== void 0 ? {
|
|
10004
|
+
roleAliases: definition.roleAliases
|
|
10005
|
+
} : {}
|
|
10006
|
+
} : {},
|
|
9332
10007
|
value: value,
|
|
9333
10008
|
editable: reason === void 0,
|
|
9334
10009
|
...reason !== void 0 ? {
|
|
@@ -9433,6 +10108,7 @@ async function evaluateActivity(args) {
|
|
|
9433
10108
|
}));
|
|
9434
10109
|
return {
|
|
9435
10110
|
activity: activity,
|
|
10111
|
+
...semanticsOf(activity),
|
|
9436
10112
|
status: status,
|
|
9437
10113
|
kind: deriveActivityKind(activity),
|
|
9438
10114
|
classification: deriveExecutorClassification(activity),
|
|
@@ -9603,9 +10279,13 @@ function fireableActionVerdict({args: args, insights: insights}) {
|
|
|
9603
10279
|
function actionEvaluationIdentity(action) {
|
|
9604
10280
|
return {
|
|
9605
10281
|
action: action,
|
|
9606
|
-
...action
|
|
9607
|
-
|
|
9608
|
-
|
|
10282
|
+
...semanticsOf(action)
|
|
10283
|
+
};
|
|
10284
|
+
}
|
|
10285
|
+
|
|
10286
|
+
function semanticsOf(node) {
|
|
10287
|
+
return node.semantics === void 0 ? {} : {
|
|
10288
|
+
semantics: node.semantics
|
|
9609
10289
|
};
|
|
9610
10290
|
}
|
|
9611
10291
|
|
|
@@ -9674,23 +10354,63 @@ function idsArm(filter, params) {
|
|
|
9674
10354
|
}
|
|
9675
10355
|
}
|
|
9676
10356
|
|
|
9677
|
-
function
|
|
9678
|
-
const
|
|
9679
|
-
if (
|
|
9680
|
-
|
|
9681
|
-
|
|
9682
|
-
|
|
10357
|
+
function beforeArm(filter, params) {
|
|
10358
|
+
const before = filter.before;
|
|
10359
|
+
if (before !== void 0) {
|
|
10360
|
+
if (filter.limit === void 0) throw new ContractViolationError("instancesQuery: `before` requires `limit` — a cursor pages the newest-first sliced read");
|
|
10361
|
+
if (before.id === "" || before.startedAt === "") throw new ContractViolationError(`instancesQuery: \`before\` needs a non-empty id and startedAt; got ${JSON.stringify(before)}`);
|
|
10362
|
+
return params.beforeStartedAt = before.startedAt, params.beforeId = before.id, "(startedAt < $beforeStartedAt || (startedAt == $beforeStartedAt && _id > $beforeId))";
|
|
10363
|
+
}
|
|
10364
|
+
}
|
|
10365
|
+
|
|
10366
|
+
function compiledConditions(filter, params) {
|
|
10367
|
+
if (filter.limit !== void 0 && (!Number.isInteger(filter.limit) || filter.limit <= 0)) throw new ContractViolationError(`instancesQuery: limit must be a positive integer; got ${JSON.stringify(filter.limit)}`);
|
|
10368
|
+
const conditions = [ `_type == "${WORKFLOW_INSTANCE_TYPE}"`, tagScopeFilter() ];
|
|
9683
10369
|
filter.includeCompleted !== !0 && conditions.push(inFlightFilter()), filter.definition !== void 0 && (conditions.push("definition == $definition"),
|
|
9684
10370
|
params.definition = filter.definition), filter.stage !== void 0 && (conditions.push("currentStage == $stage"),
|
|
9685
10371
|
params.stage = filter.stage);
|
|
10372
|
+
const cursor = beforeArm(filter, params);
|
|
10373
|
+
cursor !== void 0 && conditions.push(cursor);
|
|
9686
10374
|
const arms = [ documentArm(filter, params), idsArm(filter, params) ].filter(arm => arm !== void 0);
|
|
9687
|
-
arms.length > 0 && conditions.push(`(${arms.join(" || ")})`);
|
|
9688
|
-
|
|
9689
|
-
|
|
9690
|
-
|
|
10375
|
+
return arms.length > 0 && conditions.push(`(${arms.join(" || ")})`), conditions;
|
|
10376
|
+
}
|
|
10377
|
+
|
|
10378
|
+
function orderedSlice(filter) {
|
|
10379
|
+
return filter.limit !== void 0 ? ` | order(startedAt desc, _id asc) [0...${filter.limit}]` : " | order(startedAt asc, _id asc)";
|
|
10380
|
+
}
|
|
10381
|
+
|
|
10382
|
+
function instancesQuery(args) {
|
|
10383
|
+
const {tag: tag, filter: filter = {}} = args;
|
|
10384
|
+
validateTag(tag);
|
|
10385
|
+
const params = {
|
|
10386
|
+
tag: tag
|
|
10387
|
+
};
|
|
10388
|
+
return {
|
|
10389
|
+
query: `*[${compiledConditions(filter, params).join(" && ")}]${orderedSlice(filter)}`,
|
|
9691
10390
|
params: params
|
|
9692
|
-
}
|
|
9693
|
-
|
|
10391
|
+
};
|
|
10392
|
+
}
|
|
10393
|
+
|
|
10394
|
+
function instanceChangesQuery(args) {
|
|
10395
|
+
return validateTag(args.tag), {
|
|
10396
|
+
query: `*[_type == "${WORKFLOW_INSTANCE_TYPE}" && ${tagScopeFilter()}]`,
|
|
10397
|
+
params: {
|
|
10398
|
+
tag: args.tag
|
|
10399
|
+
}
|
|
10400
|
+
};
|
|
10401
|
+
}
|
|
10402
|
+
|
|
10403
|
+
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();
|
|
10404
|
+
|
|
10405
|
+
function instancePreviewsQuery(args) {
|
|
10406
|
+
const {tag: tag, filter: filter = {}} = args;
|
|
10407
|
+
validateTag(tag);
|
|
10408
|
+
const params = {
|
|
10409
|
+
tag: tag,
|
|
10410
|
+
previewFieldTypes: PREVIEW_FIELD_TYPES
|
|
10411
|
+
};
|
|
10412
|
+
return {
|
|
10413
|
+
query: `*[${compiledConditions(filter, params).join(" && ")}]${orderedSlice(filter)} ${PREVIEW_PROJECTION}`,
|
|
9694
10414
|
params: params
|
|
9695
10415
|
};
|
|
9696
10416
|
}
|
|
@@ -9875,6 +10595,11 @@ function hashDefinitionContent(def) {
|
|
|
9875
10595
|
}
|
|
9876
10596
|
|
|
9877
10597
|
function planDefinitionDeploy({def: def, latest: latest, target: target}) {
|
|
10598
|
+
assertRoleConstrainedAssignmentResource({
|
|
10599
|
+
context: "workflow.deployDefinitions",
|
|
10600
|
+
definition: def,
|
|
10601
|
+
workflowResource: target.workflowResource
|
|
10602
|
+
});
|
|
9878
10603
|
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 = definitionDocId({
|
|
9879
10604
|
tag: target.tag,
|
|
9880
10605
|
definition: expanded.name,
|
|
@@ -10067,7 +10792,9 @@ async function commitEdit({ctx: ctx, target: target, mode: mode, value: value, r
|
|
|
10067
10792
|
self: selfGdr(ctx.instance),
|
|
10068
10793
|
now: ctx.now,
|
|
10069
10794
|
snapshot: ctx.snapshot,
|
|
10070
|
-
refSurface: ctx.refSurface
|
|
10795
|
+
refSurface: ctx.refSurface,
|
|
10796
|
+
memberRoles: ctx.memberRoles,
|
|
10797
|
+
roleAliases: ctx.definition.roleAliases
|
|
10071
10798
|
});
|
|
10072
10799
|
return await persistThenMaybeRefresh({
|
|
10073
10800
|
ctx: ctx,
|
|
@@ -10084,7 +10811,8 @@ async function commitEdit({ctx: ctx, target: target, mode: mode, value: value, r
|
|
|
10084
10811
|
}
|
|
10085
10812
|
|
|
10086
10813
|
async function assertFieldEditable({ctx: ctx, site: site, options: options}) {
|
|
10087
|
-
const actor = options?.actor, window = fieldWindowOpen(ctx.instance, site),
|
|
10814
|
+
const actor = options?.actor, window = fieldWindowOpen(ctx.instance, site), vars = await callerBoundVarsForCall({
|
|
10815
|
+
client: ctx.client,
|
|
10088
10816
|
instance: ctx.instance,
|
|
10089
10817
|
options: options
|
|
10090
10818
|
}), predicateSatisfied = window.open && site.effective !== !0 && site.effective !== void 0 ? await ctxEvaluateCondition({
|
|
@@ -10097,10 +10825,8 @@ async function assertFieldEditable({ctx: ctx, site: site, options: options}) {
|
|
|
10097
10825
|
...actor !== void 0 ? {
|
|
10098
10826
|
actor: actor
|
|
10099
10827
|
} : {},
|
|
10100
|
-
...
|
|
10101
|
-
vars:
|
|
10102
|
-
can: can
|
|
10103
|
-
}
|
|
10828
|
+
...vars !== void 0 ? {
|
|
10829
|
+
vars: vars
|
|
10104
10830
|
} : {}
|
|
10105
10831
|
}
|
|
10106
10832
|
}) : site.effective === !0, reason = editDisabledReason({
|
|
@@ -10167,6 +10893,7 @@ async function resolveOperationContext(args) {
|
|
|
10167
10893
|
return {
|
|
10168
10894
|
access: access,
|
|
10169
10895
|
actor: access.actor,
|
|
10896
|
+
memberRolesLoader: createAssignmentMemberRolesLoader(args.client),
|
|
10170
10897
|
clientForGdr: buildClientForGdr({
|
|
10171
10898
|
client: args.client,
|
|
10172
10899
|
workflowResource: args.workflowResource,
|
|
@@ -10199,6 +10926,7 @@ async function runCommitVerb(params) {
|
|
|
10199
10926
|
actor: context.actor,
|
|
10200
10927
|
clientForGdr: context.clientForGdr,
|
|
10201
10928
|
refSurface: context.refSurface,
|
|
10929
|
+
memberRolesLoader: context.memberRolesLoader,
|
|
10202
10930
|
clock: clock,
|
|
10203
10931
|
executionContext: args.executionContext,
|
|
10204
10932
|
telemetry: args.telemetry,
|
|
@@ -10223,7 +10951,7 @@ function requestRecordFor(args) {
|
|
|
10223
10951
|
}
|
|
10224
10952
|
|
|
10225
10953
|
async function runDeduped(args) {
|
|
10226
|
-
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 () => {
|
|
10954
|
+
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 () => {
|
|
10227
10955
|
const pre = await reload({
|
|
10228
10956
|
client: client,
|
|
10229
10957
|
instanceId: instanceId,
|
|
@@ -10235,6 +10963,7 @@ async function runDeduped(args) {
|
|
|
10235
10963
|
actor: actor,
|
|
10236
10964
|
clientForGdr: clientForGdr,
|
|
10237
10965
|
refSurface: refSurface,
|
|
10966
|
+
memberRolesLoader: memberRolesLoader,
|
|
10238
10967
|
clock: clock,
|
|
10239
10968
|
executionContext: executionContext,
|
|
10240
10969
|
telemetry: telemetry
|
|
@@ -10258,13 +10987,14 @@ async function runDeduped(args) {
|
|
|
10258
10987
|
}
|
|
10259
10988
|
}
|
|
10260
10989
|
|
|
10261
|
-
async function cascade({client: client, instanceId: instanceId, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, executionContext: executionContext, telemetry: telemetry, overlay: overlay}) {
|
|
10990
|
+
async function cascade({client: client, instanceId: instanceId, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock, executionContext: executionContext, telemetry: telemetry, overlay: overlay}) {
|
|
10262
10991
|
const count = await cascadeAutoTransitions({
|
|
10263
10992
|
client: client,
|
|
10264
10993
|
instanceId: instanceId,
|
|
10265
10994
|
actor: actor,
|
|
10266
10995
|
clientForGdr: clientForGdr,
|
|
10267
10996
|
refSurface: refSurface,
|
|
10997
|
+
memberRolesLoader: memberRolesLoader,
|
|
10268
10998
|
...clock !== void 0 ? {
|
|
10269
10999
|
clock: clock
|
|
10270
11000
|
} : {},
|
|
@@ -10284,6 +11014,7 @@ async function cascade({client: client, instanceId: instanceId, actor: actor, cl
|
|
|
10284
11014
|
actor: actor,
|
|
10285
11015
|
clientForGdr: clientForGdr,
|
|
10286
11016
|
refSurface: refSurface,
|
|
11017
|
+
memberRolesLoader: memberRolesLoader,
|
|
10287
11018
|
...clock !== void 0 ? {
|
|
10288
11019
|
clock: clock
|
|
10289
11020
|
} : {},
|
|
@@ -10297,7 +11028,7 @@ async function cascade({client: client, instanceId: instanceId, actor: actor, cl
|
|
|
10297
11028
|
}
|
|
10298
11029
|
|
|
10299
11030
|
async function cascadeAndReload(args) {
|
|
10300
|
-
const {client: client, tag: tag, instanceId: instanceId, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock} = args;
|
|
11031
|
+
const {client: client, tag: tag, instanceId: instanceId, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock} = args;
|
|
10301
11032
|
return {
|
|
10302
11033
|
cascaded: await cascade({
|
|
10303
11034
|
client: client,
|
|
@@ -10305,6 +11036,7 @@ async function cascadeAndReload(args) {
|
|
|
10305
11036
|
actor: actor,
|
|
10306
11037
|
clientForGdr: clientForGdr,
|
|
10307
11038
|
refSurface: refSurface,
|
|
11039
|
+
memberRolesLoader: memberRolesLoader,
|
|
10308
11040
|
clock: clock,
|
|
10309
11041
|
...args.executionContext !== void 0 ? {
|
|
10310
11042
|
executionContext: args.executionContext
|
|
@@ -10328,6 +11060,7 @@ async function settleStart(args) {
|
|
|
10328
11060
|
actor: args.actor,
|
|
10329
11061
|
clientForGdr: args.clientForGdr,
|
|
10330
11062
|
refSurface: args.refSurface,
|
|
11063
|
+
memberRolesLoader: args.memberRolesLoader,
|
|
10331
11064
|
clock: args.clock,
|
|
10332
11065
|
...args.executionContext !== void 0 ? {
|
|
10333
11066
|
executionContext: args.executionContext
|
|
@@ -10370,31 +11103,20 @@ function resumeMismatch(args) {
|
|
|
10370
11103
|
}
|
|
10371
11104
|
|
|
10372
11105
|
async function resumeStart(args) {
|
|
10373
|
-
const {existing: existing} = args, mismatch = resumeMismatch({
|
|
11106
|
+
const {existing: existing, definition: definition, version: version, initialFieldCount: initialFieldCount, ...settlementArgs} = args, mismatch = resumeMismatch({
|
|
10374
11107
|
existing: existing,
|
|
10375
|
-
definition:
|
|
10376
|
-
version:
|
|
11108
|
+
definition: definition,
|
|
11109
|
+
version: version
|
|
10377
11110
|
});
|
|
10378
11111
|
if (mismatch !== void 0) throw new 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.`);
|
|
10379
11112
|
if (existing.stages.length === 0 && terminalState(existing) !== "in-flight") throw new ContractViolationError(`startInstance: instanceId "${existing._id}" belongs to a start that was discarded (aborted before it finished starting) — mint a new id to start again.`);
|
|
10380
11113
|
const completesStart = isUnprimed(existing), emitStarted = () => resolveTelemetry(args.telemetry).log(WorkflowInstanceStarted, instanceStartedDataFor({
|
|
10381
11114
|
instance: existing,
|
|
10382
|
-
initialFieldCount:
|
|
11115
|
+
initialFieldCount: initialFieldCount,
|
|
10383
11116
|
viaSpawn: !1
|
|
10384
11117
|
})), cascaded = await settleStart({
|
|
10385
|
-
|
|
10386
|
-
tag: args.tag,
|
|
11118
|
+
...settlementArgs,
|
|
10387
11119
|
instanceId: existing._id,
|
|
10388
|
-
actor: args.actor,
|
|
10389
|
-
clientForGdr: args.clientForGdr,
|
|
10390
|
-
refSurface: args.refSurface,
|
|
10391
|
-
clock: args.clock,
|
|
10392
|
-
...args.executionContext !== void 0 ? {
|
|
10393
|
-
executionContext: args.executionContext
|
|
10394
|
-
} : {},
|
|
10395
|
-
...args.telemetry !== void 0 ? {
|
|
10396
|
-
telemetry: args.telemetry
|
|
10397
|
-
} : {},
|
|
10398
11120
|
...completesStart ? {
|
|
10399
11121
|
emitStarted: emitStarted
|
|
10400
11122
|
} : {}
|
|
@@ -10410,7 +11132,7 @@ async function resumeStart(args) {
|
|
|
10410
11132
|
};
|
|
10411
11133
|
}
|
|
10412
11134
|
|
|
10413
|
-
function engineOptionsForActor({actor: actor, clock: clock, clientForGdr: clientForGdr, refSurface: refSurface, executionContext: executionContext, telemetry: telemetry}) {
|
|
11135
|
+
function engineOptionsForActor({actor: actor, clock: clock, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, executionContext: executionContext, telemetry: telemetry}) {
|
|
10414
11136
|
return {
|
|
10415
11137
|
...actor !== void 0 ? {
|
|
10416
11138
|
actor: actor
|
|
@@ -10418,6 +11140,7 @@ function engineOptionsForActor({actor: actor, clock: clock, clientForGdr: client
|
|
|
10418
11140
|
clock: clock,
|
|
10419
11141
|
clientForGdr: clientForGdr,
|
|
10420
11142
|
refSurface: refSurface,
|
|
11143
|
+
memberRolesLoader: memberRolesLoader,
|
|
10421
11144
|
...executionContext !== void 0 ? {
|
|
10422
11145
|
executionContext: executionContext
|
|
10423
11146
|
} : {},
|
|
@@ -10428,7 +11151,7 @@ function engineOptionsForActor({actor: actor, clock: clock, clientForGdr: client
|
|
|
10428
11151
|
}
|
|
10429
11152
|
|
|
10430
11153
|
async function abortAndPropagate(args) {
|
|
10431
|
-
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({
|
|
11154
|
+
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({
|
|
10432
11155
|
client: client,
|
|
10433
11156
|
instanceId: instanceId,
|
|
10434
11157
|
...reason !== void 0 ? {
|
|
@@ -10442,6 +11165,7 @@ async function abortAndPropagate(args) {
|
|
|
10442
11165
|
clock: clock,
|
|
10443
11166
|
clientForGdr: clientForGdr,
|
|
10444
11167
|
refSurface: refSurface,
|
|
11168
|
+
memberRolesLoader: memberRolesLoader,
|
|
10445
11169
|
executionContext: executionContext,
|
|
10446
11170
|
telemetry: telemetry
|
|
10447
11171
|
})
|
|
@@ -10451,6 +11175,7 @@ async function abortAndPropagate(args) {
|
|
|
10451
11175
|
actor: actor,
|
|
10452
11176
|
clientForGdr: clientForGdr,
|
|
10453
11177
|
refSurface: refSurface,
|
|
11178
|
+
memberRolesLoader: memberRolesLoader,
|
|
10454
11179
|
clock: clock,
|
|
10455
11180
|
...executionContext !== void 0 ? {
|
|
10456
11181
|
executionContext: executionContext
|
|
@@ -10468,6 +11193,7 @@ async function abortAndPropagate(args) {
|
|
|
10468
11193
|
actor: actor,
|
|
10469
11194
|
clientForGdr: clientForGdr,
|
|
10470
11195
|
refSurface: refSurface,
|
|
11196
|
+
memberRolesLoader: memberRolesLoader,
|
|
10471
11197
|
clock: clock,
|
|
10472
11198
|
...executionContext !== void 0 ? {
|
|
10473
11199
|
executionContext: executionContext
|
|
@@ -10509,6 +11235,7 @@ async function dispatchGatedWrite(args) {
|
|
|
10509
11235
|
actor: args.actor,
|
|
10510
11236
|
clientForGdr: args.clientForGdr,
|
|
10511
11237
|
refSurface: args.refSurface,
|
|
11238
|
+
memberRolesLoader: args.memberRolesLoader,
|
|
10512
11239
|
clock: args.clock,
|
|
10513
11240
|
executionContext: args.executionContext,
|
|
10514
11241
|
telemetry: args.telemetry
|
|
@@ -10584,12 +11311,16 @@ function buildEngineCallOptions(args) {
|
|
|
10584
11311
|
actor: args.actor,
|
|
10585
11312
|
clientForGdr: args.clientForGdr,
|
|
10586
11313
|
refSurface: args.refSurface,
|
|
11314
|
+
memberRolesLoader: args.memberRolesLoader,
|
|
10587
11315
|
...args.localPrincipalId !== void 0 ? {
|
|
10588
11316
|
localPrincipalId: args.localPrincipalId
|
|
10589
11317
|
} : {},
|
|
10590
11318
|
...args.grants !== void 0 ? {
|
|
10591
11319
|
grants: args.grants
|
|
10592
11320
|
} : {},
|
|
11321
|
+
...args.attributes !== void 0 ? {
|
|
11322
|
+
attributes: args.attributes
|
|
11323
|
+
} : {},
|
|
10593
11324
|
...args.clock !== void 0 ? {
|
|
10594
11325
|
clock: args.clock
|
|
10595
11326
|
} : {},
|
|
@@ -10620,7 +11351,7 @@ async function applyAction(args) {
|
|
|
10620
11351
|
}
|
|
10621
11352
|
|
|
10622
11353
|
async function deleteDefinition(args) {
|
|
10623
|
-
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({
|
|
11354
|
+
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({
|
|
10624
11355
|
client: client,
|
|
10625
11356
|
definition: definition,
|
|
10626
11357
|
tag: tag
|
|
@@ -10659,6 +11390,7 @@ async function deleteDefinition(args) {
|
|
|
10659
11390
|
actor: actor,
|
|
10660
11391
|
clientForGdr: clientForGdr,
|
|
10661
11392
|
refSurface: refSurface,
|
|
11393
|
+
memberRolesLoader: memberRolesLoader,
|
|
10662
11394
|
clock: clock,
|
|
10663
11395
|
executionContext: executionContext,
|
|
10664
11396
|
telemetry: telemetry
|
|
@@ -10717,6 +11449,7 @@ async function abortInstances(args) {
|
|
|
10717
11449
|
actor: actor,
|
|
10718
11450
|
clientForGdr: clientForGdr,
|
|
10719
11451
|
refSurface: args.refSurface,
|
|
11452
|
+
memberRolesLoader: args.memberRolesLoader,
|
|
10720
11453
|
clock: clock,
|
|
10721
11454
|
...executionContext !== void 0 ? {
|
|
10722
11455
|
executionContext: executionContext
|
|
@@ -10749,11 +11482,12 @@ async function fetchStartSlice(args) {
|
|
|
10749
11482
|
|
|
10750
11483
|
const workflow = {
|
|
10751
11484
|
deployDefinitions: async rawArgs => {
|
|
10752
|
-
|
|
10753
|
-
const args = taggedScope(rawArgs, REQUEST_TAG.deploy), {client: client, tag: tag, resourceAliases: resourceAliases} = args;
|
|
11485
|
+
const args = taggedScope(rawArgs, REQUEST_TAG.deploy), {client: client, tag: tag, workflowResource: workflowResource, resourceAliases: resourceAliases} = args;
|
|
10754
11486
|
validateTag(tag);
|
|
10755
11487
|
const definitions = args.definitions.map(def => parseDefinitionInput(def, "workflow.deployDefinitions"));
|
|
10756
|
-
definitions.forEach(validateDefinition)
|
|
11488
|
+
definitions.forEach(validateDefinition), assertReaderModelAcknowledgement(args.expectedMinReaderModel, {
|
|
11489
|
+
requiredMinReaderModel: requiredDefinitionReaderModel(definitions)
|
|
11490
|
+
});
|
|
10757
11491
|
const ordered = await sortByDependencies({
|
|
10758
11492
|
client: client,
|
|
10759
11493
|
definitions: definitions,
|
|
@@ -10772,6 +11506,7 @@ const workflow = {
|
|
|
10772
11506
|
latest: latest,
|
|
10773
11507
|
target: {
|
|
10774
11508
|
tag: tag,
|
|
11509
|
+
workflowResource: workflowResource,
|
|
10775
11510
|
...resourceAliases !== void 0 ? {
|
|
10776
11511
|
resourceAliases: resourceAliases
|
|
10777
11512
|
} : {}
|
|
@@ -10822,7 +11557,7 @@ const workflow = {
|
|
|
10822
11557
|
}), result;
|
|
10823
11558
|
},
|
|
10824
11559
|
startInstance: async rawArgs => {
|
|
10825
|
-
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;
|
|
11560
|
+
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;
|
|
10826
11561
|
return existing !== void 0 && existing.tag === tag ? resumeStart({
|
|
10827
11562
|
client: client,
|
|
10828
11563
|
tag: tag,
|
|
@@ -10833,6 +11568,7 @@ const workflow = {
|
|
|
10833
11568
|
actor: actor,
|
|
10834
11569
|
clientForGdr: clientForGdr,
|
|
10835
11570
|
refSurface: refSurface,
|
|
11571
|
+
memberRolesLoader: memberRolesLoader,
|
|
10836
11572
|
clock: clock,
|
|
10837
11573
|
...executionContext !== void 0 ? {
|
|
10838
11574
|
executionContext: executionContext
|
|
@@ -10852,7 +11588,7 @@ const workflow = {
|
|
|
10852
11588
|
return runCommitVerb({
|
|
10853
11589
|
args: args,
|
|
10854
11590
|
op: "fireAction",
|
|
10855
|
-
run: async ({access: access, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, record: record, before: before}) => {
|
|
11591
|
+
run: async ({access: access, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock, record: record, before: before}) => {
|
|
10856
11592
|
if (findCurrentActivityEntry(before, activity) === void 0 && idempotent === !0) return {
|
|
10857
11593
|
instance: before,
|
|
10858
11594
|
cascaded: 0,
|
|
@@ -10866,6 +11602,7 @@ const workflow = {
|
|
|
10866
11602
|
actor: actor,
|
|
10867
11603
|
clientForGdr: clientForGdr,
|
|
10868
11604
|
refSurface: refSurface,
|
|
11605
|
+
memberRolesLoader: memberRolesLoader,
|
|
10869
11606
|
clock: clock,
|
|
10870
11607
|
before: before,
|
|
10871
11608
|
...grantsFromPath !== void 0 ? {
|
|
@@ -10899,6 +11636,7 @@ const workflow = {
|
|
|
10899
11636
|
clock: clock,
|
|
10900
11637
|
clientForGdr: clientForGdr,
|
|
10901
11638
|
refSurface: refSurface,
|
|
11639
|
+
memberRolesLoader: memberRolesLoader,
|
|
10902
11640
|
...executionContext !== void 0 ? {
|
|
10903
11641
|
executionContext: executionContext
|
|
10904
11642
|
} : {},
|
|
@@ -10927,7 +11665,7 @@ const workflow = {
|
|
|
10927
11665
|
return runCommitVerb({
|
|
10928
11666
|
args: args,
|
|
10929
11667
|
op: "editField",
|
|
10930
|
-
run: async ({access: access, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, record: record, before: before}) => {
|
|
11668
|
+
run: async ({access: access, actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock, record: record, before: before}) => {
|
|
10931
11669
|
const result = await dispatchGatedWrite({
|
|
10932
11670
|
client: client,
|
|
10933
11671
|
tag: tag,
|
|
@@ -10936,6 +11674,7 @@ const workflow = {
|
|
|
10936
11674
|
actor: actor,
|
|
10937
11675
|
clientForGdr: clientForGdr,
|
|
10938
11676
|
refSurface: refSurface,
|
|
11677
|
+
memberRolesLoader: memberRolesLoader,
|
|
10939
11678
|
clock: clock,
|
|
10940
11679
|
before: before,
|
|
10941
11680
|
...grantsFromPath !== void 0 ? {
|
|
@@ -10970,6 +11709,7 @@ const workflow = {
|
|
|
10970
11709
|
clock: clock,
|
|
10971
11710
|
clientForGdr: clientForGdr,
|
|
10972
11711
|
refSurface: refSurface,
|
|
11712
|
+
memberRolesLoader: memberRolesLoader,
|
|
10973
11713
|
...executionContext !== void 0 ? {
|
|
10974
11714
|
executionContext: executionContext
|
|
10975
11715
|
} : {},
|
|
@@ -10990,7 +11730,7 @@ const workflow = {
|
|
|
10990
11730
|
});
|
|
10991
11731
|
},
|
|
10992
11732
|
completeEffect: async rawArgs => {
|
|
10993
|
-
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,
|
|
11733
|
+
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({
|
|
10994
11734
|
idempotencyKey: args.idempotencyKey,
|
|
10995
11735
|
op: "completeEffect",
|
|
10996
11736
|
idempotencyTtlMs: args.idempotencyTtlMs
|
|
@@ -11001,9 +11741,7 @@ const workflow = {
|
|
|
11001
11741
|
instanceId: instanceId,
|
|
11002
11742
|
record: record,
|
|
11003
11743
|
now: clock(),
|
|
11004
|
-
|
|
11005
|
-
clientForGdr: clientForGdr,
|
|
11006
|
-
refSurface: refSurface,
|
|
11744
|
+
...operationContext,
|
|
11007
11745
|
clock: clock,
|
|
11008
11746
|
executionContext: executionContext,
|
|
11009
11747
|
telemetry: args.telemetry,
|
|
@@ -11032,10 +11770,8 @@ const workflow = {
|
|
|
11032
11770
|
requestRecord: record
|
|
11033
11771
|
} : {},
|
|
11034
11772
|
options: engineOptionsForActor({
|
|
11035
|
-
|
|
11773
|
+
...operationContext,
|
|
11036
11774
|
clock: clock,
|
|
11037
|
-
clientForGdr: clientForGdr,
|
|
11038
|
-
refSurface: refSurface,
|
|
11039
11775
|
executionContext: executionContext,
|
|
11040
11776
|
telemetry: args.telemetry
|
|
11041
11777
|
})
|
|
@@ -11043,9 +11779,7 @@ const workflow = {
|
|
|
11043
11779
|
client: client,
|
|
11044
11780
|
tag: tag,
|
|
11045
11781
|
instanceId: instanceId,
|
|
11046
|
-
|
|
11047
|
-
clientForGdr: clientForGdr,
|
|
11048
|
-
refSurface: refSurface,
|
|
11782
|
+
...operationContext,
|
|
11049
11783
|
clock: clock,
|
|
11050
11784
|
executionContext: executionContext,
|
|
11051
11785
|
telemetry: args.telemetry
|
|
@@ -11066,7 +11800,7 @@ const workflow = {
|
|
|
11066
11800
|
});
|
|
11067
11801
|
},
|
|
11068
11802
|
commitEffectOps: async rawArgs => {
|
|
11069
|
-
const args = taggedScope(rawArgs, REQUEST_TAG.commitEffectOps), {client: client, tag: tag, instanceId: instanceId, effectKey: effectKey, claimToken: claimToken, ops: ops, executionContext: executionContext} = args,
|
|
11803
|
+
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({
|
|
11070
11804
|
idempotencyKey: args.idempotencyKey,
|
|
11071
11805
|
op: "commitEffectOps",
|
|
11072
11806
|
idempotencyTtlMs: args.idempotencyTtlMs
|
|
@@ -11078,9 +11812,7 @@ const workflow = {
|
|
|
11078
11812
|
instanceId: instanceId,
|
|
11079
11813
|
record: record,
|
|
11080
11814
|
now: clock(),
|
|
11081
|
-
|
|
11082
|
-
clientForGdr: clientForGdr,
|
|
11083
|
-
refSurface: refSurface,
|
|
11815
|
+
...operationContext,
|
|
11084
11816
|
clock: clock,
|
|
11085
11817
|
executionContext: executionContext,
|
|
11086
11818
|
telemetry: args.telemetry,
|
|
@@ -11094,10 +11826,8 @@ const workflow = {
|
|
|
11094
11826
|
requestRecord: record,
|
|
11095
11827
|
leaseMs: args.leaseMs ?? DEFAULT_EFFECT_LEASE_MS,
|
|
11096
11828
|
options: engineOptionsForActor({
|
|
11097
|
-
|
|
11829
|
+
...operationContext,
|
|
11098
11830
|
clock: clock,
|
|
11099
|
-
clientForGdr: clientForGdr,
|
|
11100
|
-
refSurface: refSurface,
|
|
11101
11831
|
executionContext: executionContext,
|
|
11102
11832
|
telemetry: args.telemetry
|
|
11103
11833
|
})
|
|
@@ -11105,9 +11835,7 @@ const workflow = {
|
|
|
11105
11835
|
client: client,
|
|
11106
11836
|
tag: tag,
|
|
11107
11837
|
instanceId: instanceId,
|
|
11108
|
-
|
|
11109
|
-
clientForGdr: clientForGdr,
|
|
11110
|
-
refSurface: refSurface,
|
|
11838
|
+
...operationContext,
|
|
11111
11839
|
clock: clock,
|
|
11112
11840
|
executionContext: executionContext,
|
|
11113
11841
|
telemetry: args.telemetry
|
|
@@ -11126,7 +11854,7 @@ const workflow = {
|
|
|
11126
11854
|
});
|
|
11127
11855
|
},
|
|
11128
11856
|
tick: async rawArgs => {
|
|
11129
|
-
const args = taggedScope(rawArgs, REQUEST_TAG.tick), {client: client, tag: tag, instanceId: instanceId, executionContext: executionContext} = args,
|
|
11857
|
+
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({
|
|
11130
11858
|
client: client,
|
|
11131
11859
|
instanceId: instanceId,
|
|
11132
11860
|
tag: tag
|
|
@@ -11140,9 +11868,7 @@ const workflow = {
|
|
|
11140
11868
|
client: client,
|
|
11141
11869
|
tag: tag,
|
|
11142
11870
|
instanceId: instanceId,
|
|
11143
|
-
|
|
11144
|
-
clientForGdr: clientForGdr,
|
|
11145
|
-
refSurface: refSurface,
|
|
11871
|
+
...operationContext,
|
|
11146
11872
|
clock: clock,
|
|
11147
11873
|
executionContext: executionContext,
|
|
11148
11874
|
telemetry: args.telemetry
|
|
@@ -11162,7 +11888,7 @@ const workflow = {
|
|
|
11162
11888
|
return runCommitVerb({
|
|
11163
11889
|
args: args,
|
|
11164
11890
|
op: "setStage",
|
|
11165
|
-
run: async ({actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, record: record, before: before}) => {
|
|
11891
|
+
run: async ({actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock, record: record, before: before}) => {
|
|
11166
11892
|
const result = await setStage({
|
|
11167
11893
|
client: client,
|
|
11168
11894
|
instanceId: instanceId,
|
|
@@ -11178,6 +11904,7 @@ const workflow = {
|
|
|
11178
11904
|
clock: clock,
|
|
11179
11905
|
clientForGdr: clientForGdr,
|
|
11180
11906
|
refSurface: refSurface,
|
|
11907
|
+
memberRolesLoader: memberRolesLoader,
|
|
11181
11908
|
executionContext: executionContext,
|
|
11182
11909
|
telemetry: args.telemetry
|
|
11183
11910
|
})
|
|
@@ -11187,6 +11914,7 @@ const workflow = {
|
|
|
11187
11914
|
actor: actor,
|
|
11188
11915
|
clientForGdr: clientForGdr,
|
|
11189
11916
|
refSurface: refSurface,
|
|
11917
|
+
memberRolesLoader: memberRolesLoader,
|
|
11190
11918
|
clock: clock,
|
|
11191
11919
|
...executionContext !== void 0 ? {
|
|
11192
11920
|
executionContext: executionContext
|
|
@@ -11216,7 +11944,7 @@ const workflow = {
|
|
|
11216
11944
|
return runCommitVerb({
|
|
11217
11945
|
args: args,
|
|
11218
11946
|
op: "abortInstance",
|
|
11219
|
-
run: async ({actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, record: record, before: before}) => {
|
|
11947
|
+
run: async ({actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock, record: record, before: before}) => {
|
|
11220
11948
|
const changed = await abortAndPropagate({
|
|
11221
11949
|
client: client,
|
|
11222
11950
|
instanceId: instanceId,
|
|
@@ -11224,6 +11952,7 @@ const workflow = {
|
|
|
11224
11952
|
actor: actor,
|
|
11225
11953
|
clientForGdr: clientForGdr,
|
|
11226
11954
|
refSurface: refSurface,
|
|
11955
|
+
memberRolesLoader: memberRolesLoader,
|
|
11227
11956
|
clock: clock,
|
|
11228
11957
|
...executionContext !== void 0 ? {
|
|
11229
11958
|
executionContext: executionContext
|
|
@@ -11257,7 +11986,7 @@ const workflow = {
|
|
|
11257
11986
|
return runCommitVerb({
|
|
11258
11987
|
args: args,
|
|
11259
11988
|
op: "resetActivity",
|
|
11260
|
-
run: async ({actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, clock: clock, record: record, before: before}) => {
|
|
11989
|
+
run: async ({actor: actor, clientForGdr: clientForGdr, refSurface: refSurface, memberRolesLoader: memberRolesLoader, clock: clock, record: record, before: before}) => {
|
|
11261
11990
|
const result = await resetActivity({
|
|
11262
11991
|
client: client,
|
|
11263
11992
|
instanceId: instanceId,
|
|
@@ -11271,6 +12000,7 @@ const workflow = {
|
|
|
11271
12000
|
clock: clock,
|
|
11272
12001
|
clientForGdr: clientForGdr,
|
|
11273
12002
|
refSurface: refSurface,
|
|
12003
|
+
memberRolesLoader: memberRolesLoader,
|
|
11274
12004
|
executionContext: executionContext,
|
|
11275
12005
|
telemetry: args.telemetry
|
|
11276
12006
|
})
|
|
@@ -11280,6 +12010,7 @@ const workflow = {
|
|
|
11280
12010
|
actor: actor,
|
|
11281
12011
|
clientForGdr: clientForGdr,
|
|
11282
12012
|
refSurface: refSurface,
|
|
12013
|
+
memberRolesLoader: memberRolesLoader,
|
|
11283
12014
|
clock: clock,
|
|
11284
12015
|
...executionContext !== void 0 ? {
|
|
11285
12016
|
executionContext: executionContext
|
|
@@ -11585,7 +12316,7 @@ async function startRequirementVerdict(args) {
|
|
|
11585
12316
|
}
|
|
11586
12317
|
|
|
11587
12318
|
async function startFreshInstance(args) {
|
|
11588
|
-
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({
|
|
12319
|
+
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({
|
|
11589
12320
|
client: client,
|
|
11590
12321
|
definition: definitionName,
|
|
11591
12322
|
version: version,
|
|
@@ -11609,6 +12340,7 @@ async function startFreshInstance(args) {
|
|
|
11609
12340
|
id: id,
|
|
11610
12341
|
now: now,
|
|
11611
12342
|
refSurface: refSurface,
|
|
12343
|
+
memberRolesLoader: memberRolesLoader,
|
|
11612
12344
|
...perspective !== void 0 ? {
|
|
11613
12345
|
perspective: perspective
|
|
11614
12346
|
} : {}
|
|
@@ -11640,6 +12372,7 @@ async function startFreshInstance(args) {
|
|
|
11640
12372
|
actor: actor,
|
|
11641
12373
|
clientForGdr: clientForGdr,
|
|
11642
12374
|
refSurface: refSurface,
|
|
12375
|
+
memberRolesLoader: memberRolesLoader,
|
|
11643
12376
|
clock: clock,
|
|
11644
12377
|
...executionContext !== void 0 ? {
|
|
11645
12378
|
executionContext: executionContext
|
|
@@ -11695,7 +12428,10 @@ async function assertStartInputs(args) {
|
|
|
11695
12428
|
}
|
|
11696
12429
|
|
|
11697
12430
|
async function resolveStartFields(args) {
|
|
11698
|
-
const {client: client, tag: tag, workflowResource: workflowResource, definition: definition, initialFields: initialFields, id: id, now: now, refSurface: refSurface, perspective: perspective} = args, fieldDiscards = []
|
|
12431
|
+
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({
|
|
12432
|
+
workflowResource: workflowResource,
|
|
12433
|
+
definition: definition
|
|
12434
|
+
});
|
|
11699
12435
|
return {
|
|
11700
12436
|
resolvedFields: await resolveDeclaredFields({
|
|
11701
12437
|
entryDefs: definition.fields ?? [],
|
|
@@ -11708,6 +12444,8 @@ async function resolveStartFields(args) {
|
|
|
11708
12444
|
workflowResource: workflowResource,
|
|
11709
12445
|
definitionName: definition.name,
|
|
11710
12446
|
refSurface: refSurface,
|
|
12447
|
+
memberRoles: memberRoles,
|
|
12448
|
+
roleAliases: definition.roleAliases,
|
|
11711
12449
|
...perspective !== void 0 ? {
|
|
11712
12450
|
perspective: perspective
|
|
11713
12451
|
} : {},
|
|
@@ -12348,7 +13086,7 @@ function createInstanceSession(args) {
|
|
|
12348
13086
|
refSurface: evalScope.refSurface
|
|
12349
13087
|
});
|
|
12350
13088
|
}, evaluateWith = async ({held: held, guards: guards, self: self}) => {
|
|
12351
|
-
const {actor: actor, localPrincipalId: localPrincipalId, grants: grants} = await access(), resourceGrants = await subjectResourceGrants({
|
|
13089
|
+
const [{actor: actor, localPrincipalId: localPrincipalId, grants: grants}, attributes] = await Promise.all([ access(), resolveUserAttributes(client) ]), resourceGrants = await subjectResourceGrants({
|
|
12352
13090
|
clientForGdr: evalScope.clientForGdr,
|
|
12353
13091
|
instance: instance
|
|
12354
13092
|
}), normalizedSelf = await normalizeInstanceIdentities({
|
|
@@ -12370,13 +13108,17 @@ function createInstanceSession(args) {
|
|
|
12370
13108
|
} : {},
|
|
12371
13109
|
...grants !== void 0 ? {
|
|
12372
13110
|
grants: grants
|
|
13111
|
+
} : {},
|
|
13112
|
+
...attributes !== void 0 ? {
|
|
13113
|
+
attributes: attributes
|
|
12373
13114
|
} : {}
|
|
12374
13115
|
});
|
|
12375
|
-
}, settleAfterApply = async ({actor: actor, held: held, ranOps: ranOps, scope: scope}) => {
|
|
13116
|
+
}, settleAfterApply = async ({actor: actor, held: held, ranOps: ranOps, scope: scope, memberRolesLoader: memberRolesLoader}) => {
|
|
12376
13117
|
const cascaded = await cascadeHeld({
|
|
12377
13118
|
scope: scope,
|
|
12378
13119
|
actor: actor,
|
|
12379
|
-
held: held
|
|
13120
|
+
held: held,
|
|
13121
|
+
memberRolesLoader: memberRolesLoader
|
|
12380
13122
|
});
|
|
12381
13123
|
return instance = await reload({
|
|
12382
13124
|
client: scope.client,
|
|
@@ -12390,12 +13132,13 @@ function createInstanceSession(args) {
|
|
|
12390
13132
|
ranOps: ranOps
|
|
12391
13133
|
} : {}
|
|
12392
13134
|
};
|
|
12393
|
-
}, cascadeHeld = ({scope: scope, actor: actor, held: held}) => cascade({
|
|
13135
|
+
}, cascadeHeld = ({scope: scope, actor: actor, held: held, memberRolesLoader: memberRolesLoader}) => cascade({
|
|
12394
13136
|
client: scope.client,
|
|
12395
13137
|
instanceId: instance._id,
|
|
12396
13138
|
actor: actor,
|
|
12397
13139
|
clientForGdr: scope.clientForGdr,
|
|
12398
13140
|
refSurface: scope.refSurface,
|
|
13141
|
+
memberRolesLoader: memberRolesLoader,
|
|
12399
13142
|
...clock !== void 0 ? {
|
|
12400
13143
|
clock: clock
|
|
12401
13144
|
} : {},
|
|
@@ -12492,6 +13235,7 @@ function createInstanceSession(args) {
|
|
|
12492
13235
|
},
|
|
12493
13236
|
tick() {
|
|
12494
13237
|
return commit(async ({actor: actor, localPrincipalId: localPrincipalId}, held) => {
|
|
13238
|
+
const memberRolesLoader = createAssignmentMemberRolesLoader(tickScope.client);
|
|
12495
13239
|
await assertInstanceWriteAllowed({
|
|
12496
13240
|
instance: instance,
|
|
12497
13241
|
guards: heldGuards,
|
|
@@ -12507,7 +13251,8 @@ function createInstanceSession(args) {
|
|
|
12507
13251
|
}), cascaded = await cascadeHeld({
|
|
12508
13252
|
scope: tickScope,
|
|
12509
13253
|
actor: actor,
|
|
12510
|
-
held: held
|
|
13254
|
+
held: held,
|
|
13255
|
+
memberRolesLoader: memberRolesLoader
|
|
12511
13256
|
});
|
|
12512
13257
|
return instance = await reload({
|
|
12513
13258
|
client: tickScope.client,
|
|
@@ -12526,6 +13271,7 @@ function createInstanceSession(args) {
|
|
|
12526
13271
|
},
|
|
12527
13272
|
fireAction({activity: activity, action: action, params: params}) {
|
|
12528
13273
|
return commit(async ({actor: actor, localPrincipalId: localPrincipalId}, held) => {
|
|
13274
|
+
const memberRolesLoader = createAssignmentMemberRolesLoader(fireScope.client);
|
|
12529
13275
|
assertActionAllowed({
|
|
12530
13276
|
evaluation: await evaluateWith({
|
|
12531
13277
|
held: held,
|
|
@@ -12546,6 +13292,7 @@ function createInstanceSession(args) {
|
|
|
12546
13292
|
} : {},
|
|
12547
13293
|
clientForGdr: fireScope.clientForGdr,
|
|
12548
13294
|
refSurface: fireScope.refSurface,
|
|
13295
|
+
memberRolesLoader: memberRolesLoader,
|
|
12549
13296
|
...grants !== void 0 ? {
|
|
12550
13297
|
grants: grants
|
|
12551
13298
|
} : {},
|
|
@@ -12565,7 +13312,8 @@ function createInstanceSession(args) {
|
|
|
12565
13312
|
actor: actor,
|
|
12566
13313
|
held: held,
|
|
12567
13314
|
ranOps: ranOps,
|
|
12568
|
-
scope: fireScope
|
|
13315
|
+
scope: fireScope,
|
|
13316
|
+
memberRolesLoader: memberRolesLoader
|
|
12569
13317
|
});
|
|
12570
13318
|
return telemetry.log(WorkflowActionFired, actionFiredData({
|
|
12571
13319
|
instance: preOp,
|
|
@@ -12587,6 +13335,7 @@ function createInstanceSession(args) {
|
|
|
12587
13335
|
return Promise.reject(err);
|
|
12588
13336
|
}
|
|
12589
13337
|
return commit(async ({actor: actor, localPrincipalId: localPrincipalId}, held) => {
|
|
13338
|
+
const memberRolesLoader = createAssignmentMemberRolesLoader(editScope.client);
|
|
12590
13339
|
assertEditAllowed(await evaluateWith({
|
|
12591
13340
|
held: held,
|
|
12592
13341
|
guards: heldGuards,
|
|
@@ -12608,6 +13357,7 @@ function createInstanceSession(args) {
|
|
|
12608
13357
|
} : {},
|
|
12609
13358
|
clientForGdr: editScope.clientForGdr,
|
|
12610
13359
|
refSurface: editScope.refSurface,
|
|
13360
|
+
memberRolesLoader: memberRolesLoader,
|
|
12611
13361
|
...grants !== void 0 ? {
|
|
12612
13362
|
grants: grants
|
|
12613
13363
|
} : {},
|
|
@@ -12624,7 +13374,8 @@ function createInstanceSession(args) {
|
|
|
12624
13374
|
actor: actor,
|
|
12625
13375
|
held: held,
|
|
12626
13376
|
ranOps: ranOps,
|
|
12627
|
-
scope: editScope
|
|
13377
|
+
scope: editScope,
|
|
13378
|
+
memberRolesLoader: memberRolesLoader
|
|
12628
13379
|
});
|
|
12629
13380
|
return telemetry.log(WorkflowFieldEdited, fieldEditedData({
|
|
12630
13381
|
instance: preOp,
|
|
@@ -12943,8 +13694,11 @@ function attributeMember({member: member, group: group, chain: chain}) {
|
|
|
12943
13694
|
}
|
|
12944
13695
|
|
|
12945
13696
|
function diffEntry({def: rawDef, latestRaw: latestRaw, target: target}) {
|
|
12946
|
-
|
|
12947
|
-
|
|
13697
|
+
const def = parseDefinitionInput(rawDef, "diffEntry");
|
|
13698
|
+
assertReaderModelAcknowledgement(target.expectedMinReaderModel, {
|
|
13699
|
+
requiredMinReaderModel: requiredDefinitionReaderModel([ def ])
|
|
13700
|
+
});
|
|
13701
|
+
const plan = planDefinitionDeploy({
|
|
12948
13702
|
def: def,
|
|
12949
13703
|
latest: asLatest(latestRaw),
|
|
12950
13704
|
target: target
|
|
@@ -12975,10 +13729,13 @@ function asLatest(raw) {
|
|
|
12975
13729
|
}
|
|
12976
13730
|
|
|
12977
13731
|
async function computeDiffEntries({client: client, defs: defs, target: target}) {
|
|
12978
|
-
|
|
13732
|
+
const definitions = defs.map(def => parseDefinitionInput(def, "computeDiffEntries"));
|
|
13733
|
+
assertReaderModelAcknowledgement(target.expectedMinReaderModel, {
|
|
13734
|
+
requiredMinReaderModel: requiredDefinitionReaderModel(definitions)
|
|
13735
|
+
});
|
|
12979
13736
|
const entries = [];
|
|
12980
|
-
for (const
|
|
12981
|
-
const
|
|
13737
|
+
for (const def of definitions) {
|
|
13738
|
+
const latest = await loadLatestDeployed({
|
|
12982
13739
|
client: client,
|
|
12983
13740
|
definition: def.name,
|
|
12984
13741
|
tag: target.tag
|
|
@@ -13065,7 +13822,7 @@ const HISTORY_DISPLAY = {
|
|
|
13065
13822
|
},
|
|
13066
13823
|
opApplied: {
|
|
13067
13824
|
title: "Op applied",
|
|
13068
|
-
description: "An
|
|
13825
|
+
description: "An action, direct edit, or effect completion executed an operation and recorded its audit payload."
|
|
13069
13826
|
},
|
|
13070
13827
|
fieldQueryDiscarded: {
|
|
13071
13828
|
title: "Query result discarded",
|
|
@@ -13170,6 +13927,10 @@ const HISTORY_DISPLAY = {
|
|
|
13170
13927
|
title: "Set field entry",
|
|
13171
13928
|
description: "Overwrite a field entry's value with a resolved value expression."
|
|
13172
13929
|
},
|
|
13930
|
+
"field.setIfMissing": {
|
|
13931
|
+
title: "Set field entry if missing",
|
|
13932
|
+
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."
|
|
13933
|
+
},
|
|
13173
13934
|
"field.unset": {
|
|
13174
13935
|
title: "Unset field entry",
|
|
13175
13936
|
description: "Reset a field entry to its default (null for scalars, [] for array kinds)."
|
|
@@ -13178,6 +13939,14 @@ const HISTORY_DISPLAY = {
|
|
|
13178
13939
|
title: "Append to field entry",
|
|
13179
13940
|
description: "Push a resolved item onto an array-kind entry (array, assignees, doc.refs)."
|
|
13180
13941
|
},
|
|
13942
|
+
"field.inc": {
|
|
13943
|
+
title: "Increment field entry",
|
|
13944
|
+
description: "Add a resolved numeric delta, defaulting to 1, to a number entry that already holds a finite number."
|
|
13945
|
+
},
|
|
13946
|
+
"field.dec": {
|
|
13947
|
+
title: "Decrement field entry",
|
|
13948
|
+
description: "Subtract a resolved numeric delta, defaulting to 1, from a number entry that already holds a finite number."
|
|
13949
|
+
},
|
|
13181
13950
|
"field.updateWhere": {
|
|
13182
13951
|
title: "Update matching rows",
|
|
13183
13952
|
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)."
|
|
@@ -13291,4 +14060,4 @@ function displayDescription(typeKey) {
|
|
|
13291
14060
|
if (typeKey) return DISPLAY[typeKey]?.description;
|
|
13292
14061
|
}
|
|
13293
14062
|
|
|
13294
|
-
export { ACTION_SEMANTICS, ACTIVITY_KINDS, ACTIVITY_KIND_DISPLAY, ACTOR_KINDS, ANONYMOUS_IDENTITY, AUTHORING_DISPLAY, ActionDisabledError, ActionParamsInvalidError, CONDITION_VARS, CONTEXT_ENTRY_DISPLAY, CascadeLimitError, ConcurrentCommitEffectOpsError, ConcurrentCompleteEffectError, ConcurrentEditFieldError, ConcurrentFireActionError, ContractViolationError, DATA_MODEL_CHANGES, DATA_MODEL_MIN_READER, DATA_MODEL_VERSION, DEFAULT_CONTENT_PERSPECTIVE, DEFAULT_EFFECT_LEASE_MS, DEFAULT_IDEMPOTENCY_TTL_MS, DEFAULT_TRANSITION_WHEN, DISPLAY, DRIVER_KINDS, DRIVER_KIND_DISPLAY, DefinitionInUseError, DefinitionNotFoundError, EFFECT_COMMIT_DISPATCH_CAP, EFFECT_COMMIT_QUEUE_DEPTH, ENGINE_API_VERSION, EXECUTION_KINDS, EXECUTOR_CLASSIFICATIONS, EXECUTOR_CLASSIFICATION_DISPLAY, EditFieldDeniedError, EffectCommitQueueOverflowError, EffectNotFoundError, EffectOpsInvalidError, EffectOutputsInvalidError, FIELD_KIND_DISPLAY, FILTER_SCOPE_VARS, FieldValueShapeError, GROUP_KINDS, GROUP_KIND_DISPLAY, GUARD_DOC_TYPE, GUARD_OWNER, GUARD_PREDICATE_VARS, HISTORY_DISPLAY, InitialFieldsInvalidError, InstanceNotFoundError, MAX_COUNTERFACTUAL_INDEX2 as MAX_COUNTERFACTUAL_INDEX, MissingHandlerError, ModelVersionAheadError, MutationGuardDeniedError, MutationGuardDocSchema, NEUTRAL_MARK, OP_DISPLAY, OUTCOME_MARKS, PartialGuardDeployError, PersistedDocShapeError, READER_MODEL_ROLLOUT_URL, RESERVED_CONDITION_VARS, ReaderModelAcknowledgementError, RefResourceUndeclaredError, RequiredFieldNotProvidedError, START_FILTER_VARS, START_REQUIREMENT_VARS, SYSTEM_IDENTITY, SpawnContractsInvalidError, StaleEffectClaimError, StartNotAllowedError, StartNotPrimedError, StartNotSettledError, WORKFLOW_DEFINITION_TYPE, WORKFLOW_INSTANCE_TYPE, WorkflowActionFired, WorkflowActivityReset, WorkflowDefinitionDeleted, WorkflowDefinitionDeployed, WorkflowEffectCompleted, WorkflowEffectStateReported, WorkflowEffectsDrained, WorkflowError, WorkflowFieldEdited, WorkflowInstanceAborted, WorkflowInstanceSchema, WorkflowInstanceStarted, WorkflowInstanceTicked, WorkflowStageSet, WorkflowStageTransitioned, WorkflowStateDivergedError, abortReason, acceptsDocumentType, aclPathForResource, actionDisabledDetail, actionRendering, actionVerdict, activityAutonomyOf, analyzeCondition2 as analyzeCondition, applicableDefinitions, assertReadableModel, assertReaderModelAcknowledgement, atomReadsDataset2 as atomReadsDataset, autonomySummary, availableActions, buildInitialFields, buildSnapshot, checklistLines, classifyPrincipalId, clientConfigFromResource, clientProjectUserDirectory, compileGuard, computeDiffEntries, conditionFieldReadNames, conditionSitesOf, contentDocQuery, contentDraftFallback, contentReleaseName, contextMap, createEngine, createTelemetryIntake, datasetResourceParts, defaultLoggerFactory, definitionDeployedData, definitionLookupGroq, definitionTagsGroq, definitionsListGroq, deniedGuardLabels, deniedGuardRefs, denyingGuards, deployStageGuards, deployedTagsGroq, deriveActivityKind, deriveExecutorClassification, deriveWorkflowAutonomy, describeAtom, describeAutonomyWait, describeCondition, describeDefinition, describeFieldInsight, describeNode, describeSite, describeSiteHeading, diagnoseInputFromEvaluation, diagnoseInstance, diffEntry, displayDescription, displayTitle, documentActionDenials, documentPrefilter, driverKind, effectOutputsMap, entryDocRefs, errorMessage, evaluateFromSnapshot, evaluateMutationGuard, evaluateStartFilter, expandResourceAliases, explainCondition2 as explainCondition, explainStartRequirement, extractDocumentId, fieldTreeShape, findCurrentActivityEntry, findOpenStageEntry, formatRead, gdrFromResource, gdrRef, gdrUri, groupMembershipNames, groupSitesOf, guardMatches, guardsForDefinition, guardsForInstance, guardsForResource, guillemets2 as guillemets, hasSingleSubjectRequirement, hashDefinitionContent, humanize2 as humanize, inFlightFilter, initialFieldIssues, instanceDocId, instanceGuardQuery, instanceWatchesDocument, instancesGuardQuery, instancesQuery, isCascadeFired, isClaimExpired, isClientProjectUser, isComparisonOp, isDefinitionApplicable, isFilterScopedOut, isGdr, isInputSourced, isNotesEntry, isProjectUserNotFoundError, isRevisionConflict, isSingleDocRefEntry, isSingleDocRefKind, isStartableDefinition, isSubjectEntry, isTelemetryEnvDenied, isTerminalActivityStatus, isTerminalStage, isTodoListEntry, isTodoListItem, isUnprimed, lakeGuardId, lakePrincipalId, latestDefinitionsGroq, latestDeployedDefinitions, lintEffectOutputs, minReaderModelOf, missingRequiredInputs, modelVersionOf, narrateAutonomyWaits, noopTelemetry, parentRef, parseDefinitionInput, parseDefinitionSnapshot, parseDefinitionSnapshotValue, parseGdr, parseGuardDocument, parseInstanceDocument, parseResourceGdr, processShellUserProperties, projectStartSliceRow, projectToWatchRef, quoted2 as quoted, readInstanceDoc, readsRaw, readsRootDocument, refCanvas, refDashboard, refDataset, refKindAcceptsTypes, refMediaLibrary, refsOf, rejectedRefTypes, releaseDocId, releaseRef, remediationsFor, requiredModelFeatures, requiredReaderModel, resolveAccess, resolveActor, resolveClientActor, resolveFieldEntry$1 as resolveFieldEntry, resourceAliasesToMap, resourceFromParsed, resourceGdr, retractStageGuards, sameResource, scalarValidationIssues, schemaTreeShape, sentenceCase, silentLogger, singleSubjectRequirementRefused, stageAutonomyOf, startFieldsParam, startKindOf, startRefusal, stripSystemFields, subjectDenialLabels, subscriptionDocument, subscriptionDocumentsForInstance, sweepStaleClaims, tagScopeFilter, terminalState, toBareId, tryParseGdr, unboundRequirementReads, unsatisfiedTransitionSummaries, userLoginProvider, validateDefinition, validateTag, verdictGuardsForInstance, wallClock, whatIfCondition2 as whatIfCondition, withAssignment, workflow };
|
|
14063
|
+
export { ACTION_SEMANTICS, ACTIVITY_KINDS, ACTIVITY_KIND_DISPLAY, ACTOR_KINDS, ANONYMOUS_IDENTITY, AUTHORING_DISPLAY, ActionDisabledError, ActionParamsInvalidError, CONDITION_VARS, CONTEXT_ENTRY_DISPLAY, CascadeLimitError, ConcurrentCommitEffectOpsError, ConcurrentCompleteEffectError, ConcurrentEditFieldError, ConcurrentFireActionError, ContractViolationError, DATA_MODEL_CHANGES, DATA_MODEL_MAX_READER, DATA_MODEL_MIN_READER, DATA_MODEL_VERSION, DECISION_SEMANTICS, DEFAULT_CONTENT_PERSPECTIVE, DEFAULT_EFFECT_LEASE_MS, DEFAULT_IDEMPOTENCY_TTL_MS, DEFAULT_TRANSITION_WHEN, DISPLAY, DRIVER_KINDS, DRIVER_KIND_DISPLAY, DefinitionInUseError, DefinitionNotFoundError, EFFECT_COMMIT_DISPATCH_CAP, EFFECT_COMMIT_QUEUE_DEPTH, ENGINE_API_VERSION, EXECUTION_KINDS, EXECUTOR_CLASSIFICATIONS, EXECUTOR_CLASSIFICATION_DISPLAY, EditFieldDeniedError, EffectCommitQueueOverflowError, EffectNotFoundError, EffectOpsInvalidError, EffectOutputsInvalidError, FIELD_KIND_DISPLAY, FILTER_SCOPE_VARS, FieldValueShapeError, GROUP_KINDS, GROUP_KIND_DISPLAY, GUARD_DOC_TYPE, GUARD_OWNER, GUARD_PREDICATE_VARS, HISTORY_DISPLAY, InitialFieldsInvalidError, InstanceNotFoundError, MAX_COUNTERFACTUAL_INDEX2 as MAX_COUNTERFACTUAL_INDEX, MissingHandlerError, ModelVersionAheadError, MutationGuardDeniedError, MutationGuardDocSchema, NEUTRAL_MARK, OP_DISPLAY, OUTCOME_MARKS, PartialGuardDeployError, PersistedDocShapeError, READER_MODEL_ROLLOUT_URL, RESERVED_CONDITION_VARS, ReaderModelAcknowledgementError, RefResourceUndeclaredError, RequiredFieldNotProvidedError, SIGNAL_SEMANTICS, START_FILTER_VARS, START_REQUIREMENT_VARS, SYSTEM_IDENTITY, SpawnContractsInvalidError, StaleEffectClaimError, StartNotAllowedError, StartNotPrimedError, StartNotSettledError, WORKFLOW_DEFINITION_TYPE, WORKFLOW_INSTANCE_TYPE, WorkflowActionFired, WorkflowActivityReset, WorkflowDefinitionDeleted, WorkflowDefinitionDeployed, WorkflowEffectCompleted, WorkflowEffectStateReported, WorkflowEffectsDrained, WorkflowError, WorkflowFieldEdited, WorkflowInstanceAborted, WorkflowInstancePreviewSchema, WorkflowInstanceSchema, WorkflowInstanceStarted, WorkflowInstanceTicked, WorkflowStageSet, WorkflowStageTransitioned, WorkflowStateDivergedError, abortReason, acceptsDocumentType, aclPathForResource, actionDisabledDetail, actionRendering, actionVerdict, activityAutonomyOf, actorFulfillsRole, analyzeCondition2 as analyzeCondition, applicableDefinitions, assertReadableModel, assertReaderModelAcknowledgement, atomReadsDataset2 as atomReadsDataset, autonomySummary, availableActions, buildInitialFields, buildSnapshot, checklistLines, classifyPrincipalId, clientConfigFromResource, clientProjectUserDirectory, compileGuard, computeDiffEntries, conditionFieldReadNames, conditionSitesOf, contentDocQuery, contentDraftFallback, contentReleaseName, contextMap, createEngine, createTelemetryIntake, datasetResourceParts, defaultLoggerFactory, definitionDeployedData, definitionLookupGroq, definitionTagsGroq, definitionsListGroq, deniedGuardLabels, deniedGuardRefs, denyingGuards, deployStageGuards, deployedTagsGroq, deriveActivityKind, deriveExecutorClassification, deriveWorkflowAutonomy, describeAtom, describeAutonomyWait, describeCondition, describeDefinition, describeFieldInsight, describeNode, describeSite, describeSiteHeading, diagnoseInputFromEvaluation, diagnoseInstance, diffEntry, displayDescription, displayTitle, documentActionDenials, documentPrefilter, documentStuckCause, driverKind, effectOutputsMap, entryDocRefs, errorMessage, evaluateFromSnapshot, evaluateMutationGuard, evaluateStartFilter, expandResourceAliases, explainCondition2 as explainCondition, explainStartRequirement, extractDocumentId, fieldTreeShape, findActivityNode, findCurrentActivityEntry, findOpenStageEntry, findStageNode, formatRead, gdrFromResource, gdrRef, gdrUri, groupMembershipNames, groupSitesOf, guardMatches, guardsForDefinition, guardsForInstance, guardsForResource, guillemets2 as guillemets, hasSingleSubjectRequirement, hashDefinitionContent, humanize2 as humanize, inFlightFilter, initialFieldIssues, instanceChangesQuery, instanceDocId, instanceGuardQuery, instancePreviewsQuery, instanceWatchesDocument, instancesGuardQuery, instancesQuery, isCascadeFired, isClaimExpired, isClientProjectUser, isComparisonOp, isDefinitionApplicable, isFilterScopedOut, isGdr, isInputSourced, isNotesEntry, isProjectUserNotFoundError, isRevisionConflict, isSingleDocRefEntry, isSingleDocRefKind, isStartableDefinition, isSubjectEntry, isTelemetryEnvDenied, isTerminalActivityStatus, isTerminalStage, isTodoListEntry, isTodoListItem, isUnprimed, lakeGuardId, lakePrincipalId, latestDefinitionsGroq, latestDeployedDefinitions, lintEffectOutputs, minReaderModelOf, missingRequiredInputs, modelVersionOf, narrateAutonomyWaits, noopTelemetry, parentRef, parseDefinitionInput, parseDefinitionSnapshot, parseDefinitionSnapshotValue, parseGdr, parseGuardDocument, parseInstanceDocument, parseInstancePreviewDocument, parseResourceGdr, processShellUserProperties, projectStartSliceRow, projectToWatchRef, quoted2 as quoted, readInstanceDoc, readInstancePreviewDoc, readsRaw, readsRootDocument, refCanvas, refDashboard, refDataset, refKindAcceptsTypes, refMediaLibrary, refsOf, rejectedRefTypes, releaseDocId, releaseRef, remediationsFor, requiredDefinitionReaderModel, requiredModelFeatures, requiredReaderModel, resolveAccess, resolveActor, resolveClientActor, resolveFieldEntry$1 as resolveFieldEntry, resolveUserAttributes, resourceAliasesToMap, resourceFromParsed, resourceGdr, retractStageGuards, sameResource, scalarValidationIssues, schemaTreeShape, sentenceCase, silentLogger, singleSubjectRequirementRefused, stageAutonomyOf, startFieldsParam, startKindOf, startRefusal, stripSystemFields, subjectDenialLabels, subscriptionDocument, subscriptionDocumentsForInstance, sweepStaleClaims, tagScopeFilter, terminalState, toBareId, tryParseGdr, unboundRequirementReads, unsatisfiedTransitionSummaries, userLoginProvider, validateDefinition, validateTag, verdictGuardsForInstance, wallClock, whatIfCondition2 as whatIfCondition, withAssignment, workflow };
|