@sanity/workflow-engine 0.28.0 → 0.29.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 +150 -0
- package/DATAMODEL.md +107 -0
- package/dist/_chunks-cjs/invariants.cjs +179 -88
- package/dist/_chunks-es/invariants.js +174 -89
- package/dist/define.d.cts +187 -9
- package/dist/define.d.ts +187 -9
- package/dist/index.cjs +883 -468
- package/dist/index.d.cts +414 -19
- package/dist/index.d.ts +414 -19
- package/dist/index.js +880 -478
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { rethrowWithContext, andConditions, deriveActivityKind, WorkflowError, CALLER_BOUND_VARS, START_REQUIREMENT_VARS, CONDITION_VARS, isSubjectEntry, isUnevaluable, ContractViolationError, isStartableDefinition, conditionFieldReadNames, isGdr, errorMessage, conditionParameterNames, START_FILTER_VARS, gdrFromResource, selfGdr, isSingleDocRefKind, actorFulfillsRole, toBareId, sameResource, resourceFromParsed, tryParseGdr, isTerminalActivityStatus, FieldValueShapeError, validateFieldValue, validateFieldAppendItem, evaluateCondition, isSingleDocRefEntry, choiceValueIssues, scalarValidationIssues, StoredFieldOpSchema, formatIssues, conditionSyntaxIssues, checkWorkflowInvariants, formatIssuePath, isGuardReadExpr, conditionEffectReads, EFFECTS_READ, datasetResourceParts, evaluatePredicates, WORKFLOW_DEFINITION_TYPE, tagScopeFilter, isCascadeFired, parseGdr, isGdrUri, gdrRef, isInputSourced, parseFieldValue, VersionSpecificDatasetGdrError, toPhysicalGdr, isBareSeedId, tolerantEntries, NonEmptyString, FIELD_VALUE_KINDS, tolerantObject, ActorShape, IsoTimestamp, ACTIVITY_STATUSES, GdrShape, DRIVER_KINDS, FIELD_SCOPES, fieldValueSchemas, parsePersistedDoc, ACTOR_KINDS, classifyPrincipalId, directoryBridgeId, InstanceNotFoundError, evaluateConditionOutcome, runGroq, FIELD_READ, MUTATION_GUARD_ACTIONS, resourceGdr, resourceFromGdrUri, refTypeIssues, rejectedRefTypes, DOCUMENT_VALUE_PERMISSIONS, lakePrincipalId, driverKind, EffectNotFoundError,
|
|
1
|
+
import { rethrowWithContext, andConditions, deriveActivityKind, WorkflowError, CALLER_BOUND_VARS, START_REQUIREMENT_VARS, CONDITION_VARS, isSubjectEntry, isUnevaluable, ContractViolationError, isStartableDefinition, conditionFieldReadNames, isGdr, errorMessage, conditionParameterNames, START_FILTER_VARS, gdrFromResource, selfGdr, isSingleDocRefKind, actorFulfillsRole, toBareId, sameResource, resourceFromParsed, tryParseGdr, isTerminalActivityStatus, FieldValueShapeError, validateFieldValue, validateFieldAppendItem, isAlwaysArrayFieldKind, evaluateCondition, isSingleDocRefEntry, choiceValueIssues, scalarValidationIssues, StoredFieldOpSchema, formatIssues, conditionSyntaxIssues, checkWorkflowInvariants, formatIssuePath, isGuardReadExpr, conditionEffectReads, EFFECTS_READ, datasetResourceParts, evaluatePredicates, WORKFLOW_DEFINITION_TYPE, tagScopeFilter, isCascadeFired, parseGdr, isGdrUri, gdrRef, isInputSourced, parseFieldValue, VersionSpecificDatasetGdrError, toPhysicalGdr, isBareSeedId, tolerantEntries, NonEmptyString, FIELD_VALUE_KINDS, tolerantObject, ActorShape, IsoTimestamp, ACTIVITY_STATUSES, GdrShape, DRIVER_KINDS, FIELD_SCOPES, fieldValueSchemas, parsePersistedDoc, ACTOR_KINDS, classifyPrincipalId, directoryBridgeId, 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
|
|
|
@@ -435,7 +435,7 @@ function fieldEditedData(args) {
|
|
|
435
435
|
};
|
|
436
436
|
}
|
|
437
437
|
|
|
438
|
-
const DATA_MODEL_VERSION =
|
|
438
|
+
const DATA_MODEL_VERSION = 7, DATA_MODEL_MIN_READER = 4, READER_MODEL_ROLLOUT_URL = "https://www.sanity.io/docs/editorial-workflows/prerelease";
|
|
439
439
|
|
|
440
440
|
class ReaderModelAcknowledgementError extends WorkflowError {
|
|
441
441
|
code="WORKFLOW_READER_MODEL_ACKNOWLEDGEMENT_MISMATCH";
|
|
@@ -485,7 +485,7 @@ const DATA_MODEL_CHANGES = Object.freeze([ Object.freeze({
|
|
|
485
485
|
documentTypes: Object.freeze([ "definition" ]),
|
|
486
486
|
compatibility: "additive",
|
|
487
487
|
applicability: "detectable",
|
|
488
|
-
summary: "Ordinary actions may carry
|
|
488
|
+
summary: "Ordinary actions may carry advisory workflow semantics."
|
|
489
489
|
}), Object.freeze({
|
|
490
490
|
id: "inclusive-scalar-bounds",
|
|
491
491
|
introducedInModel: 2,
|
|
@@ -534,6 +534,30 @@ const DATA_MODEL_CHANGES = Object.freeze([ Object.freeze({
|
|
|
534
534
|
compatibility: "additive",
|
|
535
535
|
applicability: "detectable",
|
|
536
536
|
summary: "Due-date field kinds (dueDate, dueDatetime) mark a level deadline, elevated aliases of date/datetime carrying the same stored value."
|
|
537
|
+
}), Object.freeze({
|
|
538
|
+
id: "node-semantics",
|
|
539
|
+
introducedInModel: 6,
|
|
540
|
+
minReaderModel: 0,
|
|
541
|
+
documentTypes: Object.freeze([ "definition" ]),
|
|
542
|
+
compatibility: "additive",
|
|
543
|
+
applicability: "detectable",
|
|
544
|
+
summary: "Workflow, stage, activity, and action nodes may carry signal or custom advisory semantics."
|
|
545
|
+
}), Object.freeze({
|
|
546
|
+
id: "field-patch-ops",
|
|
547
|
+
introducedInModel: 6,
|
|
548
|
+
minReaderModel: 0,
|
|
549
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
550
|
+
compatibility: "additive",
|
|
551
|
+
applicability: "detectable",
|
|
552
|
+
summary: "Field ops may increment, decrement, or initialize a missing field value."
|
|
553
|
+
}), Object.freeze({
|
|
554
|
+
id: "attributes-condition-var",
|
|
555
|
+
introducedInModel: 7,
|
|
556
|
+
minReaderModel: 0,
|
|
557
|
+
documentTypes: Object.freeze([ "definition" ]),
|
|
558
|
+
compatibility: "additive",
|
|
559
|
+
applicability: "unconditional",
|
|
560
|
+
summary: "Caller-bound $attributes condition variable binds the acting token's org-level User Attributes (advisory; absent when unavailable)."
|
|
537
561
|
}) ]);
|
|
538
562
|
|
|
539
563
|
function recordOf(value) {
|
|
@@ -556,13 +580,34 @@ function parsedDefinitionSnapshot(root) {
|
|
|
556
580
|
}));
|
|
557
581
|
}
|
|
558
582
|
|
|
559
|
-
function
|
|
583
|
+
function persistedDefinitionTree(document) {
|
|
560
584
|
const root = recordOf(document);
|
|
561
|
-
if (root === void 0) return
|
|
562
|
-
const snapshot = parsedDefinitionSnapshot(root), roots = snapshot === void 0 ? [ root ] : [ root, snapshot ], stages
|
|
585
|
+
if (root === void 0) return;
|
|
586
|
+
const snapshot = parsedDefinitionSnapshot(root), roots = snapshot === void 0 ? [ root ] : [ root, snapshot ], {stages: stages, activities: activities, actions: actions} = definitionDescendants(roots);
|
|
587
|
+
return {
|
|
588
|
+
roots: roots,
|
|
589
|
+
stages: stages,
|
|
590
|
+
activities: activities,
|
|
591
|
+
actions: actions
|
|
592
|
+
};
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
function persistedFieldEntries(document) {
|
|
596
|
+
const tree = persistedDefinitionTree(document);
|
|
597
|
+
if (tree === void 0) return [];
|
|
598
|
+
const {roots: roots, stages: stages, activities: activities, actions: actions} = tree, effects = actions.flatMap(action => recordsAt(action, "effects"));
|
|
563
599
|
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
600
|
}
|
|
565
601
|
|
|
602
|
+
function definitionDescendants(roots) {
|
|
603
|
+
const stages = roots.flatMap(root => recordsAt(root, "stages")), activities = stages.flatMap(stage => recordsAt(stage, "activities")), actions = activities.flatMap(activity => recordsAt(activity, "actions"));
|
|
604
|
+
return {
|
|
605
|
+
stages: stages,
|
|
606
|
+
activities: activities,
|
|
607
|
+
actions: actions
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
|
|
566
611
|
function hasChoiceList(document) {
|
|
567
612
|
return persistedFieldEntries(document).some(entry => {
|
|
568
613
|
const options = recordOf(entry.options);
|
|
@@ -574,9 +619,34 @@ function hasFieldKind(document, kind) {
|
|
|
574
619
|
return persistedFieldEntries(document).some(entry => entry.type === kind || entry._type === kind);
|
|
575
620
|
}
|
|
576
621
|
|
|
577
|
-
function
|
|
622
|
+
function definitionNodes(document) {
|
|
578
623
|
const root = recordOf(document);
|
|
579
|
-
|
|
624
|
+
if (root !== void 0) return {
|
|
625
|
+
root: root,
|
|
626
|
+
...definitionDescendants([ root ])
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
function hasActionSemantics(document) {
|
|
631
|
+
return definitionNodes(document)?.actions.some(hasSemantics) ?? !1;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
function hasNodeSemantics(document) {
|
|
635
|
+
const nodes = definitionNodes(document);
|
|
636
|
+
return nodes === void 0 ? !1 : [ nodes.root, ...nodes.stages, ...nodes.activities ].some(hasSemantics) ? !0 : nodes.actions.some(action => hasSemantics(action) && action.semantics.some(isNodeSemanticValue));
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
function isNodeSemanticValue(semantic) {
|
|
640
|
+
return typeof semantic == "string" && (semantic.startsWith("signal.") || semantic.startsWith("custom."));
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
function hasSemantics(node) {
|
|
644
|
+
return Array.isArray(node.semantics);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
function hasPersistedOpType(document, types) {
|
|
648
|
+
const tree = persistedDefinitionTree(document);
|
|
649
|
+
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)));
|
|
580
650
|
}
|
|
581
651
|
|
|
582
652
|
function hasScalarValidation(document) {
|
|
@@ -609,7 +679,10 @@ const featureDetectors = {
|
|
|
609
679
|
"effect-claim-tokens": hasClaimTokens,
|
|
610
680
|
"classified-principal-ids": () => !0,
|
|
611
681
|
"readiness-requirements": hasReadinessRequirements,
|
|
612
|
-
"due-date-field-kinds": document => hasFieldKind(document, "dueDate") || hasFieldKind(document, "dueDatetime")
|
|
682
|
+
"due-date-field-kinds": document => hasFieldKind(document, "dueDate") || hasFieldKind(document, "dueDatetime"),
|
|
683
|
+
"node-semantics": hasNodeSemantics,
|
|
684
|
+
"field-patch-ops": document => hasPersistedOpType(document, [ "field.inc", "field.dec", "field.setIfMissing" ]),
|
|
685
|
+
"attributes-condition-var": () => !0
|
|
613
686
|
};
|
|
614
687
|
|
|
615
688
|
function requiredModelFeatures(documentType, document) {
|
|
@@ -1143,12 +1216,8 @@ function renderWorkflowRead(read, ctx) {
|
|
|
1143
1216
|
text: guillemets(title)
|
|
1144
1217
|
});
|
|
1145
1218
|
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
permission: read.path[0]
|
|
1149
|
-
},
|
|
1150
|
-
text: `your ${read.path[0]} permission`
|
|
1151
|
-
});
|
|
1219
|
+
const keyed = keyedCallerRead(read);
|
|
1220
|
+
if (keyed !== void 0) return keyed;
|
|
1152
1221
|
if (read.variable === "actor" && read.path.length === 1 && read.path[0] === "id") return phrase("read.actor-id", {
|
|
1153
1222
|
params: {},
|
|
1154
1223
|
text: "your id"
|
|
@@ -1170,6 +1239,24 @@ function renderWorkflowRead(read, ctx) {
|
|
|
1170
1239
|
});
|
|
1171
1240
|
}
|
|
1172
1241
|
|
|
1242
|
+
function keyedCallerRead(read) {
|
|
1243
|
+
const key = read.path[0];
|
|
1244
|
+
if (typeof key == "string") {
|
|
1245
|
+
if (read.variable === "can") return phrase("read.permission", {
|
|
1246
|
+
params: {
|
|
1247
|
+
permission: key
|
|
1248
|
+
},
|
|
1249
|
+
text: `your ${key} permission`
|
|
1250
|
+
});
|
|
1251
|
+
if (read.variable === "attributes") return phrase("read.attribute", {
|
|
1252
|
+
params: {
|
|
1253
|
+
attribute: key
|
|
1254
|
+
},
|
|
1255
|
+
text: `your ${guillemets(key)} attribute`
|
|
1256
|
+
});
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1173
1260
|
function workflowRequirement(requirement, ctx) {
|
|
1174
1261
|
const {target: target} = requirement, clause = clauseVarRequirement(requirement);
|
|
1175
1262
|
if (clause !== void 0) return clause;
|
|
@@ -2070,6 +2157,10 @@ function derefBase(ref, snapshot) {
|
|
|
2070
2157
|
};
|
|
2071
2158
|
}
|
|
2072
2159
|
|
|
2160
|
+
function isRecord(value) {
|
|
2161
|
+
return typeof value == "object" && value !== null && !Array.isArray(value);
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2073
2164
|
function buildParams(args) {
|
|
2074
2165
|
const {instance: instance, now: now, snapshot: snapshot, extra: extra} = args, currentActivities2 = findOpenStageEntry(instance)?.activities ?? [];
|
|
2075
2166
|
return {
|
|
@@ -2597,7 +2688,7 @@ class CascadeLimitError extends WorkflowError {
|
|
|
2597
2688
|
}
|
|
2598
2689
|
}
|
|
2599
2690
|
|
|
2600
|
-
const FIELD_OP_TYPES = [ "field.set", "field.unset", "field.append", "field.updateWhere", "field.removeWhere" ];
|
|
2691
|
+
const FIELD_OP_TYPES = [ "field.set", "field.setIfMissing", "field.unset", "field.append", "field.inc", "field.dec", "field.updateWhere", "field.removeWhere" ];
|
|
2601
2692
|
|
|
2602
2693
|
function isFieldOp(summary) {
|
|
2603
2694
|
return FIELD_OP_TYPES.includes(summary.opType);
|
|
@@ -2698,7 +2789,7 @@ async function runOps(args) {
|
|
|
2698
2789
|
refSurface: refSurface,
|
|
2699
2790
|
opsFromDefinition: opsFromDefinition
|
|
2700
2791
|
});
|
|
2701
|
-
summaries.push(summary), mutation.history.push(opAppliedEntry({
|
|
2792
|
+
summaries.push(summary), shouldRecordOpApplied(summary) && mutation.history.push(opAppliedEntry({
|
|
2702
2793
|
origin: origin,
|
|
2703
2794
|
summary: summary,
|
|
2704
2795
|
stage: stage,
|
|
@@ -2709,6 +2800,10 @@ async function runOps(args) {
|
|
|
2709
2800
|
return summaries;
|
|
2710
2801
|
}
|
|
2711
2802
|
|
|
2803
|
+
function shouldRecordOpApplied(summary) {
|
|
2804
|
+
return summary.opType !== "field.setIfMissing" || summary.resolved !== void 0;
|
|
2805
|
+
}
|
|
2806
|
+
|
|
2712
2807
|
function opAppliedEntry(args) {
|
|
2713
2808
|
const {origin: origin, summary: summary, stage: stage, actor: actor, now: now} = args;
|
|
2714
2809
|
return {
|
|
@@ -2780,12 +2875,19 @@ async function applyOp(op, ctx) {
|
|
|
2780
2875
|
case "field.set":
|
|
2781
2876
|
return applyFieldSet(op, ctx);
|
|
2782
2877
|
|
|
2878
|
+
case "field.setIfMissing":
|
|
2879
|
+
return applyFieldSetIfMissing(op, ctx);
|
|
2880
|
+
|
|
2783
2881
|
case "field.unset":
|
|
2784
2882
|
return applyFieldUnset(op, ctx);
|
|
2785
2883
|
|
|
2786
2884
|
case "field.append":
|
|
2787
2885
|
return applyFieldAppend(op, ctx);
|
|
2788
2886
|
|
|
2887
|
+
case "field.inc":
|
|
2888
|
+
case "field.dec":
|
|
2889
|
+
return applyFieldArithmetic(op, ctx);
|
|
2890
|
+
|
|
2789
2891
|
case "field.updateWhere":
|
|
2790
2892
|
return applyFieldUpdateWhere(op, ctx);
|
|
2791
2893
|
|
|
@@ -2824,6 +2926,78 @@ function applyFieldSet(op, ctx) {
|
|
|
2824
2926
|
};
|
|
2825
2927
|
}
|
|
2826
2928
|
|
|
2929
|
+
function applyFieldSetIfMissing(op, ctx) {
|
|
2930
|
+
const entry = locateEntry(ctx, op.target);
|
|
2931
|
+
return isAlwaysArrayFieldKind(entry._type) && rejectFieldOpTarget({
|
|
2932
|
+
entry: entry,
|
|
2933
|
+
op: op,
|
|
2934
|
+
issue: "is always array-valued — setIfMissing applies to nullable entries only; an empty array entry already holds []"
|
|
2935
|
+
}), entry.value !== null && entry.value !== void 0 ? {
|
|
2936
|
+
opType: op.type,
|
|
2937
|
+
target: op.target
|
|
2938
|
+
} : {
|
|
2939
|
+
...applyFieldSet({
|
|
2940
|
+
...op,
|
|
2941
|
+
type: "field.set"
|
|
2942
|
+
}, ctx),
|
|
2943
|
+
opType: op.type
|
|
2944
|
+
};
|
|
2945
|
+
}
|
|
2946
|
+
|
|
2947
|
+
function applyFieldArithmetic(op, ctx) {
|
|
2948
|
+
const entry = locateEntry(ctx, op.target);
|
|
2949
|
+
entry._type !== "number" && rejectFieldOpTarget({
|
|
2950
|
+
entry: entry,
|
|
2951
|
+
op: op,
|
|
2952
|
+
issue: `is a ${entry._type} entry — arithmetic ops target \`number\` entries only`
|
|
2953
|
+
}), typeof entry.value != "number" && rejectFieldOpTarget({
|
|
2954
|
+
entry: entry,
|
|
2955
|
+
op: op,
|
|
2956
|
+
issue: "has no numeric value — initialize it before applying arithmetic"
|
|
2957
|
+
});
|
|
2958
|
+
const resolvedDelta = op.value === void 0 ? 1 : resolveOpValue({
|
|
2959
|
+
src: op.value,
|
|
2960
|
+
ctx: ctx,
|
|
2961
|
+
target: {
|
|
2962
|
+
kind: "number"
|
|
2963
|
+
}
|
|
2964
|
+
});
|
|
2965
|
+
(typeof resolvedDelta != "number" || !Number.isFinite(resolvedDelta)) && rejectFieldOpTarget({
|
|
2966
|
+
entry: entry,
|
|
2967
|
+
op: op,
|
|
2968
|
+
issue: "value must resolve to a finite number"
|
|
2969
|
+
});
|
|
2970
|
+
const nextValue = entry.value + (op.type === "field.inc" ? resolvedDelta : -resolvedDelta);
|
|
2971
|
+
Number.isFinite(nextValue) || rejectFieldOpTarget({
|
|
2972
|
+
entry: entry,
|
|
2973
|
+
op: op,
|
|
2974
|
+
issue: "result must be a finite number"
|
|
2975
|
+
});
|
|
2976
|
+
const value = validateFieldValue({
|
|
2977
|
+
entryType: entry._type,
|
|
2978
|
+
entryName: entry.name,
|
|
2979
|
+
value: nextValue,
|
|
2980
|
+
...entryShape(entry)
|
|
2981
|
+
});
|
|
2982
|
+
return setEntryValue(entry, value), {
|
|
2983
|
+
opType: op.type,
|
|
2984
|
+
target: op.target,
|
|
2985
|
+
resolved: {
|
|
2986
|
+
value: value
|
|
2987
|
+
}
|
|
2988
|
+
};
|
|
2989
|
+
}
|
|
2990
|
+
|
|
2991
|
+
function rejectFieldOpTarget(args) {
|
|
2992
|
+
const {entry: entry, op: op, issue: issue} = args;
|
|
2993
|
+
throw new FieldValueShapeError({
|
|
2994
|
+
entryType: entry._type,
|
|
2995
|
+
entryName: entry.name,
|
|
2996
|
+
mode: "value",
|
|
2997
|
+
issues: [ `${op.type} target ${op.target.scope}:"${op.target.field}" ${issue}` ]
|
|
2998
|
+
});
|
|
2999
|
+
}
|
|
3000
|
+
|
|
2827
3001
|
function entryShape(entry) {
|
|
2828
3002
|
return entry._type === "object" ? {
|
|
2829
3003
|
fields: entry.fields
|
|
@@ -2859,15 +3033,9 @@ function appendItemSlot(entry) {
|
|
|
2859
3033
|
};
|
|
2860
3034
|
}
|
|
2861
3035
|
|
|
2862
|
-
const EMPTY_BY_KIND = {
|
|
2863
|
-
"doc.refs": [],
|
|
2864
|
-
array: [],
|
|
2865
|
-
assignees: []
|
|
2866
|
-
};
|
|
2867
|
-
|
|
2868
3036
|
function applyFieldUnset(op, ctx) {
|
|
2869
3037
|
const entry = locateEntry(ctx, op.target);
|
|
2870
|
-
return setEntryValue(entry,
|
|
3038
|
+
return setEntryValue(entry, isAlwaysArrayFieldKind(entry._type) ? [] : null), {
|
|
2871
3039
|
opType: op.type,
|
|
2872
3040
|
target: op.target
|
|
2873
3041
|
};
|
|
@@ -2906,7 +3074,7 @@ function applyFieldAppend(op, ctx) {
|
|
|
2906
3074
|
}
|
|
2907
3075
|
|
|
2908
3076
|
function withRowKey(item) {
|
|
2909
|
-
return
|
|
3077
|
+
return isRecord(item) && !("_key" in item) ? {
|
|
2910
3078
|
_key: randomKey(),
|
|
2911
3079
|
...item
|
|
2912
3080
|
} : item;
|
|
@@ -3605,6 +3773,14 @@ function latestDeployedDefinitions(rows) {
|
|
|
3605
3773
|
return [ ...byName.values() ];
|
|
3606
3774
|
}
|
|
3607
3775
|
|
|
3776
|
+
function findStageNode(args) {
|
|
3777
|
+
return args.definition?.stages.find(entry => entry.name === args.stageName);
|
|
3778
|
+
}
|
|
3779
|
+
|
|
3780
|
+
function findActivityNode(args) {
|
|
3781
|
+
return findStageNode(args)?.activities?.find(entry => entry.name === args.activityName);
|
|
3782
|
+
}
|
|
3783
|
+
|
|
3608
3784
|
function liveChildrenField(instance) {
|
|
3609
3785
|
const live = liveSubworkflows(instance).length;
|
|
3610
3786
|
return live > 0 ? {
|
|
@@ -3693,6 +3869,27 @@ function noTransitionFiresCause(input) {
|
|
|
3693
3869
|
};
|
|
3694
3870
|
}
|
|
3695
3871
|
|
|
3872
|
+
function stuckFromDocumentState(input) {
|
|
3873
|
+
return failedEffectCause(input) ?? failedActivityCause(input) ?? hungEffectCause(input);
|
|
3874
|
+
}
|
|
3875
|
+
|
|
3876
|
+
function documentStuckCause(args) {
|
|
3877
|
+
const stage = findOpenStageEntry(args.instance);
|
|
3878
|
+
if (stage !== void 0) return stuckFromDocumentState({
|
|
3879
|
+
instance: args.instance,
|
|
3880
|
+
activities: stage.activities.map(entry => ({
|
|
3881
|
+
status: entry.status,
|
|
3882
|
+
activity: findActivityNode({
|
|
3883
|
+
activityName: entry.name,
|
|
3884
|
+
definition: args.definition,
|
|
3885
|
+
stageName: stage.name
|
|
3886
|
+
}) ?? {
|
|
3887
|
+
name: entry.name
|
|
3888
|
+
}
|
|
3889
|
+
}))
|
|
3890
|
+
});
|
|
3891
|
+
}
|
|
3892
|
+
|
|
3696
3893
|
function diagnoseInstance(input) {
|
|
3697
3894
|
const {instance: instance} = input, terminal = terminalState(instance);
|
|
3698
3895
|
if (terminal === "aborted" && instance.abortedAt !== void 0) {
|
|
@@ -3711,7 +3908,7 @@ function diagnoseInstance(input) {
|
|
|
3711
3908
|
at: instance.completedAt,
|
|
3712
3909
|
...liveChildrenField(instance)
|
|
3713
3910
|
};
|
|
3714
|
-
const cause =
|
|
3911
|
+
const cause = stuckFromDocumentState(input) ?? noTransitionFiresCause(input);
|
|
3715
3912
|
return cause !== void 0 ? {
|
|
3716
3913
|
state: "stuck",
|
|
3717
3914
|
cause: cause
|
|
@@ -4090,10 +4287,8 @@ function assertRequiredInputProvided({entryDefs: entryDefs, initialFields: initi
|
|
|
4090
4287
|
});
|
|
4091
4288
|
}
|
|
4092
4289
|
|
|
4093
|
-
const ARRAY_FIELD_TYPES = /* @__PURE__ */ new Set([ "doc.refs", "array", "assignees" ]);
|
|
4094
|
-
|
|
4095
4290
|
function defaultEntryValue(entryType) {
|
|
4096
|
-
return
|
|
4291
|
+
return isAlwaysArrayFieldKind(entryType) ? [] : null;
|
|
4097
4292
|
}
|
|
4098
4293
|
|
|
4099
4294
|
function resolveInputValue({entry: entry, initialFields: initialFields, defaultValue: defaultValue}) {
|
|
@@ -4694,7 +4889,9 @@ const SYNC_COMMIT = {
|
|
|
4694
4889
|
effect: "workflow.effect",
|
|
4695
4890
|
verifyDefinitions: "workflow.verify-definitions",
|
|
4696
4891
|
accessResolveActor: "workflow.access.resolve-actor",
|
|
4697
|
-
accessGrants: "workflow.access.grants"
|
|
4892
|
+
accessGrants: "workflow.access.grants",
|
|
4893
|
+
accessResolveOrg: "workflow.access.resolve-org",
|
|
4894
|
+
accessAttributes: "workflow.access.attributes"
|
|
4698
4895
|
}, RAW_PATCH = /* @__PURE__ */ Symbol("workflow-engine.raw-patch");
|
|
4699
4896
|
|
|
4700
4897
|
function unwrapPatch(patch) {
|
|
@@ -5662,10 +5859,6 @@ function userLoginProvider(user) {
|
|
|
5662
5859
|
return user?.provider ?? user?.loginProvider;
|
|
5663
5860
|
}
|
|
5664
5861
|
|
|
5665
|
-
function isRecord(value) {
|
|
5666
|
-
return typeof value == "object" && value !== null && !Array.isArray(value);
|
|
5667
|
-
}
|
|
5668
|
-
|
|
5669
5862
|
function optionalString(value) {
|
|
5670
5863
|
return value === void 0 || typeof value == "string";
|
|
5671
5864
|
}
|
|
@@ -7202,117 +7395,524 @@ async function advisoryCan({instance: instance, identity: identity, grants: gran
|
|
|
7202
7395
|
return can;
|
|
7203
7396
|
}
|
|
7204
7397
|
|
|
7205
|
-
|
|
7206
|
-
return {
|
|
7207
|
-
name: requirement.name,
|
|
7208
|
-
...requirement.title !== void 0 ? {
|
|
7209
|
-
title: requirement.title
|
|
7210
|
-
} : {},
|
|
7211
|
-
...requirement.description !== void 0 ? {
|
|
7212
|
-
description: requirement.description
|
|
7213
|
-
} : {}
|
|
7214
|
-
};
|
|
7215
|
-
}
|
|
7398
|
+
const DANGEROUS_ATTRIBUTE_KEYS = /* @__PURE__ */ new Set([ "__proto__", "constructor", "prototype" ]);
|
|
7216
7399
|
|
|
7217
|
-
function
|
|
7218
|
-
|
|
7400
|
+
function attributeEntry(row) {
|
|
7401
|
+
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 ];
|
|
7219
7402
|
}
|
|
7220
7403
|
|
|
7221
|
-
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
|
|
7229
|
-
reason: args.reason
|
|
7230
|
-
})), this.name = "ActionDisabledError", this.reason = args.reason, this.activity = args.activity,
|
|
7231
|
-
this.action = args.action;
|
|
7404
|
+
function normalizeUserAttributes(response) {
|
|
7405
|
+
if (!isRecord(response)) return;
|
|
7406
|
+
const rows = response.attributes;
|
|
7407
|
+
if (!Array.isArray(rows)) return;
|
|
7408
|
+
const out = {};
|
|
7409
|
+
for (const row of rows) {
|
|
7410
|
+
const entry = attributeEntry(row);
|
|
7411
|
+
entry !== void 0 && (out[entry[0]] = entry[1]);
|
|
7232
7412
|
}
|
|
7413
|
+
return out;
|
|
7233
7414
|
}
|
|
7234
7415
|
|
|
7235
|
-
|
|
7236
|
-
definition;
|
|
7237
|
-
unmetRequirements;
|
|
7238
|
-
constructor(args) {
|
|
7239
|
-
super("start-not-allowed", `startInstance refused definition "${args.definition}": ${args.unmetRequirements.map(requirement => requirement.title ?? requirement.name).join(", ")}. Pre-flight the verdict with evaluateStart.`),
|
|
7240
|
-
this.name = "StartNotAllowedError", this.definition = args.definition, this.unmetRequirements = args.unmetRequirements;
|
|
7241
|
-
}
|
|
7242
|
-
}
|
|
7416
|
+
const actorCache = /* @__PURE__ */ new WeakMap, grantsCache = /* @__PURE__ */ new WeakMap, orgIdCache = /* @__PURE__ */ new WeakMap, attributesCache = /* @__PURE__ */ new WeakMap;
|
|
7243
7417
|
|
|
7244
|
-
function
|
|
7245
|
-
const
|
|
7246
|
-
|
|
7418
|
+
async function resolveAccess(taggedClient, args = {}) {
|
|
7419
|
+
const client = unwrapRequestTag(taggedClient), requestFn = lazyRequest(client);
|
|
7420
|
+
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).");
|
|
7421
|
+
const grantsPromise = args.grantsFromPath !== void 0 ? cachedGrants({
|
|
7422
|
+
client: client,
|
|
7423
|
+
requestFn: requestFn,
|
|
7424
|
+
resourcePath: args.grantsFromPath
|
|
7425
|
+
}) : Promise.resolve(void 0), [identity, grants] = await Promise.all([ cachedActor(client, requestFn), grantsPromise ]);
|
|
7426
|
+
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.");
|
|
7427
|
+
return {
|
|
7428
|
+
actor: identity.actor,
|
|
7429
|
+
...identity.localPrincipalId !== void 0 ? {
|
|
7430
|
+
localPrincipalId: identity.localPrincipalId
|
|
7431
|
+
} : {},
|
|
7432
|
+
...grants !== void 0 ? {
|
|
7433
|
+
grants: grants
|
|
7434
|
+
} : {}
|
|
7435
|
+
};
|
|
7247
7436
|
}
|
|
7248
7437
|
|
|
7249
|
-
|
|
7250
|
-
|
|
7251
|
-
|
|
7252
|
-
|
|
7253
|
-
|
|
7254
|
-
|
|
7255
|
-
"instance-aborted": r => `instance aborted at ${r.abortedAt}`,
|
|
7256
|
-
"requirements-unmet": r => `unmet requirement(s): ${r.unmetRequirements.map(requirement => requirement.name).join(", ")}`,
|
|
7257
|
-
"subject-permission-denied": r => `missing subject permission(s): ${subjectDenialLabels(r.denied).join(", ")}`
|
|
7258
|
-
};
|
|
7259
|
-
|
|
7260
|
-
function actionDisabledDetail(reason) {
|
|
7261
|
-
return disabledReasonDetail[reason.kind](reason);
|
|
7438
|
+
async function resolveUserAttributes(taggedClient) {
|
|
7439
|
+
const client = unwrapRequestTag(taggedClient), requestFn = lazyRequest(client);
|
|
7440
|
+
if (requestFn !== void 0) return cachedAttributes({
|
|
7441
|
+
client: client,
|
|
7442
|
+
requestFn: requestFn
|
|
7443
|
+
});
|
|
7262
7444
|
}
|
|
7263
7445
|
|
|
7264
|
-
function
|
|
7265
|
-
|
|
7446
|
+
function cachedActor(client, requestFn) {
|
|
7447
|
+
const cached = actorCache.get(client);
|
|
7448
|
+
if (cached !== void 0) return cached;
|
|
7449
|
+
const pending = fetchActor(client, requestFn).catch(err => {
|
|
7450
|
+
throw actorCache.get(client) === pending && actorCache.delete(client), err;
|
|
7451
|
+
});
|
|
7452
|
+
return actorCache.set(client, pending), pending;
|
|
7266
7453
|
}
|
|
7267
7454
|
|
|
7268
|
-
|
|
7269
|
-
|
|
7270
|
-
|
|
7271
|
-
|
|
7272
|
-
|
|
7273
|
-
|
|
7274
|
-
}
|
|
7455
|
+
function grantsForClientPath(taggedClient, resourcePath) {
|
|
7456
|
+
const client = unwrapRequestTag(taggedClient), requestFn = lazyRequest(client);
|
|
7457
|
+
return requestFn === void 0 ? Promise.resolve(void 0) : cachedGrants({
|
|
7458
|
+
client: client,
|
|
7459
|
+
requestFn: requestFn,
|
|
7460
|
+
resourcePath: resourcePath
|
|
7461
|
+
});
|
|
7275
7462
|
}
|
|
7276
7463
|
|
|
7277
|
-
|
|
7278
|
-
|
|
7279
|
-
"instance-completed": r => `instance completed at ${r.completedAt}`,
|
|
7280
|
-
"instance-aborted": r => `instance aborted at ${r.abortedAt}`,
|
|
7281
|
-
"edit-window-closed": r => `edit window closed (${r.detail})`,
|
|
7282
|
-
"editor-not-permitted": r => `editor not permitted (${r.predicate})`
|
|
7283
|
-
};
|
|
7284
|
-
|
|
7285
|
-
function formatEditDisabledReason(target, reason) {
|
|
7286
|
-
const detail = editDisabledReasonDetail[reason.kind](reason), where = target.activity !== void 0 ? `${target.activity}.${target.field}` : target.field;
|
|
7287
|
-
return `Field "${target.scope}:${where}" is not editable: ${detail}`;
|
|
7464
|
+
function lazyRequest(client) {
|
|
7465
|
+
return client.request === void 0 ? void 0 : opts => client.request(opts);
|
|
7288
7466
|
}
|
|
7289
7467
|
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
|
|
7468
|
+
function cachedGrants({client: client, requestFn: requestFn, resourcePath: resourcePath}) {
|
|
7469
|
+
return cachedByKey({
|
|
7470
|
+
store: grantsCache,
|
|
7293
7471
|
client: client,
|
|
7294
|
-
|
|
7295
|
-
|
|
7296
|
-
commit: ctx => commitAction({
|
|
7297
|
-
ctx: ctx,
|
|
7298
|
-
activityName: activity,
|
|
7299
|
-
actionName: action,
|
|
7300
|
-
callerParams: params,
|
|
7301
|
-
requestRecord: requestRecord,
|
|
7302
|
-
options: options
|
|
7303
|
-
}),
|
|
7304
|
-
onExhausted: () => new ConcurrentFireActionError({
|
|
7305
|
-
instanceId: instanceId,
|
|
7306
|
-
activity: activity,
|
|
7307
|
-
action: action,
|
|
7308
|
-
attempts: CONCURRENT_COMMIT_MAX_ATTEMPTS
|
|
7309
|
-
})
|
|
7472
|
+
key: resourcePath,
|
|
7473
|
+
load: () => fetchGrantsCached(requestFn, resourcePath)
|
|
7310
7474
|
});
|
|
7311
7475
|
}
|
|
7312
7476
|
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
|
|
7477
|
+
function cachedByKey(args) {
|
|
7478
|
+
let byKey = args.store.get(args.client);
|
|
7479
|
+
byKey === void 0 && (byKey = /* @__PURE__ */ new Map, args.store.set(args.client, byKey));
|
|
7480
|
+
const cached = byKey.get(args.key);
|
|
7481
|
+
if (cached !== void 0) return cached;
|
|
7482
|
+
const pending = args.evictOnRejection ? args.load().catch(err => {
|
|
7483
|
+
throw byKey.get(args.key) === pending && byKey.delete(args.key), err;
|
|
7484
|
+
}) : args.load();
|
|
7485
|
+
return byKey.set(args.key, pending), pending;
|
|
7486
|
+
}
|
|
7487
|
+
|
|
7488
|
+
async function fetchActor(client, requestFn) {
|
|
7489
|
+
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;
|
|
7490
|
+
if (sessionId === void 0) return;
|
|
7491
|
+
const bridge = carriedId === void 0 ? await bridgeProjectPrincipal({
|
|
7492
|
+
client: client,
|
|
7493
|
+
sessionId: sessionId,
|
|
7494
|
+
resourceId: resourceId
|
|
7495
|
+
}) : NO_BRIDGE, id = bridge.status === "resolved" ? bridge.globalId : sessionId;
|
|
7496
|
+
refuseProjectScopedActor({
|
|
7497
|
+
id: id,
|
|
7498
|
+
globalUser: globalUser,
|
|
7499
|
+
globalHostId: globalHostId,
|
|
7500
|
+
bridgeFailure: bridge.status === "unavailable" ? bridge : void 0
|
|
7501
|
+
});
|
|
7502
|
+
const roleNames = roleNamesFor(resourceUser, globalUser);
|
|
7503
|
+
return {
|
|
7504
|
+
actor: {
|
|
7505
|
+
kind: "person",
|
|
7506
|
+
id: id,
|
|
7507
|
+
...roleNames.length > 0 ? {
|
|
7508
|
+
roles: roleNames
|
|
7509
|
+
} : {}
|
|
7510
|
+
},
|
|
7511
|
+
...resourceId !== void 0 && resourceId !== id ? {
|
|
7512
|
+
localPrincipalId: resourceId
|
|
7513
|
+
} : {}
|
|
7514
|
+
};
|
|
7515
|
+
}
|
|
7516
|
+
|
|
7517
|
+
function roleNamesFor(resourceUser, globalUser) {
|
|
7518
|
+
return (resourceUser?.roles?.length ? resourceUser : globalUser.user)?.roles?.map(r => r.name).filter(n => !!n) ?? [];
|
|
7519
|
+
}
|
|
7520
|
+
|
|
7521
|
+
const NO_BRIDGE = {
|
|
7522
|
+
status: "not-applicable"
|
|
7523
|
+
};
|
|
7524
|
+
|
|
7525
|
+
function globalRouteReason(globalUser, globalHostId) {
|
|
7526
|
+
return "reason" in globalUser ? globalUser.reason : globalHostId === void 0 ? "no record" : `the global host answered with project-scoped principal "${globalHostId}"`;
|
|
7527
|
+
}
|
|
7528
|
+
|
|
7529
|
+
async function bridgeProjectPrincipal(args) {
|
|
7530
|
+
const {client: client, sessionId: sessionId, resourceId: resourceId} = args;
|
|
7531
|
+
return classifyPrincipalId(sessionId).namespace !== "project" ? NO_BRIDGE : resourceId === void 0 || classifyPrincipalId(resourceId).namespace !== "project" ? {
|
|
7532
|
+
status: "unavailable",
|
|
7533
|
+
reason: "no project-scoped principal from the resource host to address the directory with"
|
|
7534
|
+
} : directoryGlobalId({
|
|
7535
|
+
client: client,
|
|
7536
|
+
principalId: resourceId
|
|
7537
|
+
});
|
|
7538
|
+
}
|
|
7539
|
+
|
|
7540
|
+
async function directoryGlobalId(args) {
|
|
7541
|
+
const {client: client, principalId: principalId} = args, projectId = projectIdOf(client);
|
|
7542
|
+
if (projectId === void 0) return {
|
|
7543
|
+
status: "unavailable",
|
|
7544
|
+
reason: "the client reports no projectId, so its user directory has no address"
|
|
7545
|
+
};
|
|
7546
|
+
const lookup = await clientProjectUserDirectory(withRequestTag(client, REQUEST_TAG.accessResolveActor), projectId).findById(principalId);
|
|
7547
|
+
if (lookup.status !== "resolved") return {
|
|
7548
|
+
status: "unavailable",
|
|
7549
|
+
reason: `project "${projectId}"'s user directory reported the principal ${lookup.status}`,
|
|
7550
|
+
...lookup.status === "inaccessible" && lookup.cause !== void 0 ? {
|
|
7551
|
+
cause: lookup.cause
|
|
7552
|
+
} : {}
|
|
7553
|
+
};
|
|
7554
|
+
const globalId = directoryBridgeId(lookup.user.sanityUserId);
|
|
7555
|
+
return globalId === void 0 ? {
|
|
7556
|
+
status: "unavailable",
|
|
7557
|
+
reason: `project "${projectId}"'s user directory row for the principal carries no account-global sanityUserId`
|
|
7558
|
+
} : {
|
|
7559
|
+
status: "resolved",
|
|
7560
|
+
globalId: globalId
|
|
7561
|
+
};
|
|
7562
|
+
}
|
|
7563
|
+
|
|
7564
|
+
function refuseProjectScopedActor(args) {
|
|
7565
|
+
const {id: id, globalUser: globalUser, globalHostId: globalHostId, bridgeFailure: bridgeFailure} = args;
|
|
7566
|
+
if (classifyPrincipalId(id).namespace !== "project") return;
|
|
7567
|
+
const routes = [ `The account-global record: ${globalRouteReason(globalUser, globalHostId)}.` ];
|
|
7568
|
+
bridgeFailure !== void 0 && routes.push(`The project user directory: ${bridgeFailure.reason}.`);
|
|
7569
|
+
const cause = bridgeFailure?.cause ?? ("cause" in globalUser ? globalUser.cause : void 0);
|
|
7570
|
+
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 : {
|
|
7571
|
+
cause: cause
|
|
7572
|
+
});
|
|
7573
|
+
}
|
|
7574
|
+
|
|
7575
|
+
function usableId(user) {
|
|
7576
|
+
if (!(!user || typeof user.id != "string" || user.id.length === 0)) return user.id;
|
|
7577
|
+
}
|
|
7578
|
+
|
|
7579
|
+
async function fetchCurrentUser(requestFn, hostDescription) {
|
|
7580
|
+
try {
|
|
7581
|
+
return await requestFn({
|
|
7582
|
+
uri: "/users/me",
|
|
7583
|
+
tag: REQUEST_TAG.accessResolveActor
|
|
7584
|
+
});
|
|
7585
|
+
} catch (err) {
|
|
7586
|
+
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.`, {
|
|
7587
|
+
cause: err
|
|
7588
|
+
});
|
|
7589
|
+
}
|
|
7590
|
+
}
|
|
7591
|
+
|
|
7592
|
+
async function fetchGlobalUser(client) {
|
|
7593
|
+
const sibling = globalHostRequestOf(client);
|
|
7594
|
+
if ("reason" in sibling) return {
|
|
7595
|
+
user: void 0,
|
|
7596
|
+
reason: sibling.reason,
|
|
7597
|
+
...sibling.cause !== void 0 ? {
|
|
7598
|
+
cause: sibling.cause
|
|
7599
|
+
} : {}
|
|
7600
|
+
};
|
|
7601
|
+
try {
|
|
7602
|
+
const user = await sibling.request({
|
|
7603
|
+
uri: "/users/me",
|
|
7604
|
+
tag: REQUEST_TAG.accessResolveActor
|
|
7605
|
+
}), id = usableId(user);
|
|
7606
|
+
return sibling.requireGlobalPrincipal && id !== void 0 && classifyPrincipalId(id).namespace === "project" ? {
|
|
7607
|
+
user: void 0,
|
|
7608
|
+
reason: `global-host /users/me returned project-scoped principal "${id}"; the sibling client is still bound to a project API host`
|
|
7609
|
+
} : {
|
|
7610
|
+
user: user
|
|
7611
|
+
};
|
|
7612
|
+
} catch (err) {
|
|
7613
|
+
return {
|
|
7614
|
+
user: void 0,
|
|
7615
|
+
reason: `global-host /users/me failed: ${errorMessage(err)}`,
|
|
7616
|
+
cause: err
|
|
7617
|
+
};
|
|
7618
|
+
}
|
|
7619
|
+
}
|
|
7620
|
+
|
|
7621
|
+
function globalHostRequestOf(client) {
|
|
7622
|
+
if (typeof client.withConfig != "function") return {
|
|
7623
|
+
reason: "the client cannot reach the global API host (no withConfig)"
|
|
7624
|
+
};
|
|
7625
|
+
const hostResolution = resolveGlobalApiHost(client);
|
|
7626
|
+
try {
|
|
7627
|
+
const globalClient = client.withConfig({
|
|
7628
|
+
useProjectHostname: !1,
|
|
7629
|
+
apiVersion: ENGINE_API_VERSION,
|
|
7630
|
+
...hostResolution.apiHost === void 0 ? {} : {
|
|
7631
|
+
apiHost: hostResolution.apiHost
|
|
7632
|
+
}
|
|
7633
|
+
}), request = lazyRequest(globalClient);
|
|
7634
|
+
return request === void 0 ? {
|
|
7635
|
+
reason: "the global-host sibling client cannot issue requests"
|
|
7636
|
+
} : {
|
|
7637
|
+
request: request,
|
|
7638
|
+
requireGlobalPrincipal: hostResolution.requireGlobalPrincipal
|
|
7639
|
+
};
|
|
7640
|
+
} catch (err) {
|
|
7641
|
+
return {
|
|
7642
|
+
reason: `building the global-host sibling client failed: ${errorMessage(err)}`,
|
|
7643
|
+
cause: err
|
|
7644
|
+
};
|
|
7645
|
+
}
|
|
7646
|
+
}
|
|
7647
|
+
|
|
7648
|
+
function resolveGlobalApiHost(client) {
|
|
7649
|
+
if (typeof client.config != "function") return {
|
|
7650
|
+
requireGlobalPrincipal: !1
|
|
7651
|
+
};
|
|
7652
|
+
const apiHost = client.config().apiHost;
|
|
7653
|
+
if (apiHost === void 0) return {
|
|
7654
|
+
requireGlobalPrincipal: !1
|
|
7655
|
+
};
|
|
7656
|
+
let parsed;
|
|
7657
|
+
try {
|
|
7658
|
+
parsed = new URL(apiHost);
|
|
7659
|
+
} catch {
|
|
7660
|
+
return {
|
|
7661
|
+
requireGlobalPrincipal: !0
|
|
7662
|
+
};
|
|
7663
|
+
}
|
|
7664
|
+
if (/^api\.sanity\.(io|work)$/.test(parsed.hostname)) return {
|
|
7665
|
+
requireGlobalPrincipal: !1
|
|
7666
|
+
};
|
|
7667
|
+
const match = /^[^.]+\.api\.sanity\.(io|work)$/.exec(parsed.hostname);
|
|
7668
|
+
return match === null ? {
|
|
7669
|
+
requireGlobalPrincipal: !0
|
|
7670
|
+
} : (parsed.hostname = `api.sanity.${match[1]}`, {
|
|
7671
|
+
apiHost: parsed.origin,
|
|
7672
|
+
requireGlobalPrincipal: !0
|
|
7673
|
+
});
|
|
7674
|
+
}
|
|
7675
|
+
|
|
7676
|
+
async function fetchGrantsCached(requestFn, resourcePath) {
|
|
7677
|
+
try {
|
|
7678
|
+
return await fetchGrants({
|
|
7679
|
+
client: {
|
|
7680
|
+
request: requestFn
|
|
7681
|
+
},
|
|
7682
|
+
resourcePath: resourcePath
|
|
7683
|
+
});
|
|
7684
|
+
} catch (err) {
|
|
7685
|
+
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)}`);
|
|
7686
|
+
return;
|
|
7687
|
+
}
|
|
7688
|
+
}
|
|
7689
|
+
|
|
7690
|
+
function projectIdOf(client) {
|
|
7691
|
+
if (typeof client.config != "function") return;
|
|
7692
|
+
const projectId = client.config().projectId;
|
|
7693
|
+
return typeof projectId == "string" && projectId.length > 0 ? projectId : void 0;
|
|
7694
|
+
}
|
|
7695
|
+
|
|
7696
|
+
function cachedAttributes(args) {
|
|
7697
|
+
const projectId = projectIdOf(args.client);
|
|
7698
|
+
return projectId === void 0 ? Promise.resolve(void 0) : resolveOrganizationId({
|
|
7699
|
+
client: args.client,
|
|
7700
|
+
requestFn: args.requestFn,
|
|
7701
|
+
projectId: projectId
|
|
7702
|
+
}).then(orgId => {
|
|
7703
|
+
if (orgId !== void 0) return cachedByKey({
|
|
7704
|
+
store: attributesCache,
|
|
7705
|
+
client: args.client,
|
|
7706
|
+
key: orgId,
|
|
7707
|
+
evictOnRejection: !0,
|
|
7708
|
+
load: () => fetchAttributesCached({
|
|
7709
|
+
client: args.client,
|
|
7710
|
+
orgId: orgId
|
|
7711
|
+
})
|
|
7712
|
+
});
|
|
7713
|
+
});
|
|
7714
|
+
}
|
|
7715
|
+
|
|
7716
|
+
async function resolveOrganizationId(args) {
|
|
7717
|
+
const {client: client, requestFn: requestFn, projectId: projectId} = args;
|
|
7718
|
+
return cachedByKey({
|
|
7719
|
+
store: orgIdCache,
|
|
7720
|
+
client: client,
|
|
7721
|
+
key: projectId,
|
|
7722
|
+
evictOnRejection: !0,
|
|
7723
|
+
load: async () => {
|
|
7724
|
+
try {
|
|
7725
|
+
const project = await requestFn({
|
|
7726
|
+
uri: `/projects/${encodeURIComponent(projectId)}`,
|
|
7727
|
+
tag: REQUEST_TAG.accessResolveOrg
|
|
7728
|
+
});
|
|
7729
|
+
if (!isRecord(project)) return;
|
|
7730
|
+
const orgId = project.organizationId;
|
|
7731
|
+
return typeof orgId == "string" && orgId.length > 0 ? orgId : void 0;
|
|
7732
|
+
} catch (err) {
|
|
7733
|
+
const status = httpStatusOf(err);
|
|
7734
|
+
if (status !== void 0 && EXPECTED_ATTRIBUTES_ABSENCE.has(status)) return;
|
|
7735
|
+
throw new Error(`workflow: failed to resolve organizationId for project "${projectId}"; advisory $attributes cannot be bound. Original error: ${errorMessage(err)}`, {
|
|
7736
|
+
cause: err
|
|
7737
|
+
});
|
|
7738
|
+
}
|
|
7739
|
+
}
|
|
7740
|
+
});
|
|
7741
|
+
}
|
|
7742
|
+
|
|
7743
|
+
const ATTRIBUTES_FETCH_LIMIT = 100, EXPECTED_ATTRIBUTES_ABSENCE = /* @__PURE__ */ new Set([ 401, 402, 403, 404 ]);
|
|
7744
|
+
|
|
7745
|
+
function httpStatusOf(err) {
|
|
7746
|
+
if (!isRecord(err)) return;
|
|
7747
|
+
const status = err.statusCode;
|
|
7748
|
+
return typeof status == "number" ? status : void 0;
|
|
7749
|
+
}
|
|
7750
|
+
|
|
7751
|
+
async function fetchAttributesCached(args) {
|
|
7752
|
+
const {client: client, orgId: orgId} = args, sibling = globalHostRequestOf(client);
|
|
7753
|
+
if ("reason" in sibling) {
|
|
7754
|
+
console.warn(`workflow: skipped org attributes fetch (${sibling.reason}); advisory $attributes stays undefined (conditions referencing it fail closed).`);
|
|
7755
|
+
return;
|
|
7756
|
+
}
|
|
7757
|
+
try {
|
|
7758
|
+
const response = await sibling.request({
|
|
7759
|
+
uri: `/organizations/${encodeURIComponent(orgId)}/users/me/attributes?limit=${ATTRIBUTES_FETCH_LIMIT}`,
|
|
7760
|
+
tag: REQUEST_TAG.accessAttributes
|
|
7761
|
+
}), envelope = isRecord(response) ? response : void 0;
|
|
7762
|
+
if (envelope?.hasMore === !0) {
|
|
7763
|
+
const page = Array.isArray(envelope.attributes) ? envelope.attributes : [];
|
|
7764
|
+
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.`);
|
|
7765
|
+
}
|
|
7766
|
+
const normalized = normalizeUserAttributes(response);
|
|
7767
|
+
return normalized === void 0 && console.warn(`workflow: org attributes response for organization "${orgId}" was unusable; advisory $attributes stays undefined (conditions referencing it fail closed).`),
|
|
7768
|
+
normalized;
|
|
7769
|
+
} catch (err) {
|
|
7770
|
+
const status = httpStatusOf(err);
|
|
7771
|
+
if (status !== void 0 && EXPECTED_ATTRIBUTES_ABSENCE.has(status)) return;
|
|
7772
|
+
throw new Error(`workflow: failed to fetch org attributes for organization "${orgId}". Original error: ${errorMessage(err)}`, {
|
|
7773
|
+
cause: err
|
|
7774
|
+
});
|
|
7775
|
+
}
|
|
7776
|
+
}
|
|
7777
|
+
|
|
7778
|
+
function callerBoundVars(args) {
|
|
7779
|
+
const vars = {
|
|
7780
|
+
...args.can !== void 0 ? {
|
|
7781
|
+
can: args.can
|
|
7782
|
+
} : {},
|
|
7783
|
+
...args.attributes !== void 0 ? {
|
|
7784
|
+
attributes: args.attributes
|
|
7785
|
+
} : {}
|
|
7786
|
+
};
|
|
7787
|
+
return Object.keys(vars).length > 0 ? vars : void 0;
|
|
7788
|
+
}
|
|
7789
|
+
|
|
7790
|
+
async function callerBoundVarsForCall(args) {
|
|
7791
|
+
const can = await advisoryCanForCall({
|
|
7792
|
+
instance: args.instance,
|
|
7793
|
+
options: args.options
|
|
7794
|
+
}), attributes = args.options?.attributes !== void 0 ? args.options.attributes : await resolveUserAttributes(args.client);
|
|
7795
|
+
return callerBoundVars({
|
|
7796
|
+
...can !== void 0 ? {
|
|
7797
|
+
can: can
|
|
7798
|
+
} : {},
|
|
7799
|
+
...attributes !== void 0 ? {
|
|
7800
|
+
attributes: attributes
|
|
7801
|
+
} : {}
|
|
7802
|
+
});
|
|
7803
|
+
}
|
|
7804
|
+
|
|
7805
|
+
function requirementDescriptor(requirement) {
|
|
7806
|
+
return {
|
|
7807
|
+
name: requirement.name,
|
|
7808
|
+
...requirement.title !== void 0 ? {
|
|
7809
|
+
title: requirement.title
|
|
7810
|
+
} : {},
|
|
7811
|
+
...requirement.description !== void 0 ? {
|
|
7812
|
+
description: requirement.description
|
|
7813
|
+
} : {}
|
|
7814
|
+
};
|
|
7815
|
+
}
|
|
7816
|
+
|
|
7817
|
+
function subjectDenialLabels(denied) {
|
|
7818
|
+
return denied.map(d => `${d.permission} on ${d.subject} (${d.resource})`);
|
|
7819
|
+
}
|
|
7820
|
+
|
|
7821
|
+
class ActionDisabledError extends WorkflowError {
|
|
7822
|
+
reason;
|
|
7823
|
+
activity;
|
|
7824
|
+
action;
|
|
7825
|
+
constructor(args) {
|
|
7826
|
+
super("action-disabled", formatDisabledReason({
|
|
7827
|
+
activity: args.activity,
|
|
7828
|
+
action: args.action,
|
|
7829
|
+
reason: args.reason
|
|
7830
|
+
})), this.name = "ActionDisabledError", this.reason = args.reason, this.activity = args.activity,
|
|
7831
|
+
this.action = args.action;
|
|
7832
|
+
}
|
|
7833
|
+
}
|
|
7834
|
+
|
|
7835
|
+
class StartNotAllowedError extends WorkflowError {
|
|
7836
|
+
definition;
|
|
7837
|
+
unmetRequirements;
|
|
7838
|
+
constructor(args) {
|
|
7839
|
+
super("start-not-allowed", `startInstance refused definition "${args.definition}": ${args.unmetRequirements.map(requirement => requirement.title ?? requirement.name).join(", ")}. Pre-flight the verdict with evaluateStart.`),
|
|
7840
|
+
this.name = "StartNotAllowedError", this.definition = args.definition, this.unmetRequirements = args.unmetRequirements;
|
|
7841
|
+
}
|
|
7842
|
+
}
|
|
7843
|
+
|
|
7844
|
+
function actionRendering(action) {
|
|
7845
|
+
const kind = action.disabledReason?.kind;
|
|
7846
|
+
return kind === "filter-failed" ? "absent" : action.triggered === !0 || kind === "cascade-fired" ? "automation" : "button";
|
|
7847
|
+
}
|
|
7848
|
+
|
|
7849
|
+
const disabledReasonDetail = {
|
|
7850
|
+
"filter-failed": r => `action filter returned false${r.detail ? ` (${r.detail})` : ""}`,
|
|
7851
|
+
"cascade-fired": r => `the action is cascade-fired (when: ${JSON.stringify(r.when)}) — the engine fires it on truth; it cannot be invoked via fireAction`,
|
|
7852
|
+
"activity-not-active": r => `activity status is "${r.status}"`,
|
|
7853
|
+
"stage-terminal": r => `stage "${r.stage}" is terminal`,
|
|
7854
|
+
"instance-completed": r => `instance completed at ${r.completedAt}`,
|
|
7855
|
+
"instance-aborted": r => `instance aborted at ${r.abortedAt}`,
|
|
7856
|
+
"requirements-unmet": r => `unmet requirement(s): ${r.unmetRequirements.map(requirement => requirement.name).join(", ")}`,
|
|
7857
|
+
"subject-permission-denied": r => `missing subject permission(s): ${subjectDenialLabels(r.denied).join(", ")}`
|
|
7858
|
+
};
|
|
7859
|
+
|
|
7860
|
+
function actionDisabledDetail(reason) {
|
|
7861
|
+
return disabledReasonDetail[reason.kind](reason);
|
|
7862
|
+
}
|
|
7863
|
+
|
|
7864
|
+
function formatDisabledReason({activity: activity, action: action, reason: reason}) {
|
|
7865
|
+
return `Action "${activity}:${action}" is not allowed: ${actionDisabledDetail(reason)}`;
|
|
7866
|
+
}
|
|
7867
|
+
|
|
7868
|
+
class EditFieldDeniedError extends WorkflowError {
|
|
7869
|
+
reason;
|
|
7870
|
+
target;
|
|
7871
|
+
constructor(args) {
|
|
7872
|
+
super("edit-field-denied", formatEditDisabledReason(args.target, args.reason)),
|
|
7873
|
+
this.name = "EditFieldDeniedError", this.reason = args.reason, this.target = args.target;
|
|
7874
|
+
}
|
|
7875
|
+
}
|
|
7876
|
+
|
|
7877
|
+
const editDisabledReasonDetail = {
|
|
7878
|
+
"not-editable": () => "field is not declared editable",
|
|
7879
|
+
"instance-completed": r => `instance completed at ${r.completedAt}`,
|
|
7880
|
+
"instance-aborted": r => `instance aborted at ${r.abortedAt}`,
|
|
7881
|
+
"edit-window-closed": r => `edit window closed (${r.detail})`,
|
|
7882
|
+
"editor-not-permitted": r => `editor not permitted (${r.predicate})`
|
|
7883
|
+
};
|
|
7884
|
+
|
|
7885
|
+
function formatEditDisabledReason(target, reason) {
|
|
7886
|
+
const detail = editDisabledReasonDetail[reason.kind](reason), where = target.activity !== void 0 ? `${target.activity}.${target.field}` : target.field;
|
|
7887
|
+
return `Field "${target.scope}:${where}" is not editable: ${detail}`;
|
|
7888
|
+
}
|
|
7889
|
+
|
|
7890
|
+
async function fireAction(args) {
|
|
7891
|
+
const {client: client, instanceId: instanceId, activity: activity, action: action, params: params, requestRecord: requestRecord, options: options} = args;
|
|
7892
|
+
return retryOnRevisionConflict({
|
|
7893
|
+
client: client,
|
|
7894
|
+
instanceId: instanceId,
|
|
7895
|
+
options: options,
|
|
7896
|
+
commit: ctx => commitAction({
|
|
7897
|
+
ctx: ctx,
|
|
7898
|
+
activityName: activity,
|
|
7899
|
+
actionName: action,
|
|
7900
|
+
callerParams: params,
|
|
7901
|
+
requestRecord: requestRecord,
|
|
7902
|
+
options: options
|
|
7903
|
+
}),
|
|
7904
|
+
onExhausted: () => new ConcurrentFireActionError({
|
|
7905
|
+
instanceId: instanceId,
|
|
7906
|
+
activity: activity,
|
|
7907
|
+
action: action,
|
|
7908
|
+
attempts: CONCURRENT_COMMIT_MAX_ATTEMPTS
|
|
7909
|
+
})
|
|
7910
|
+
});
|
|
7911
|
+
}
|
|
7912
|
+
|
|
7913
|
+
async function resolveActionCommit({ctx: ctx, activityName: activityName, actionName: actionName, callerParams: callerParams, options: options}) {
|
|
7914
|
+
const actor = options?.actor, {stage: stage, activity: activity} = findActivityInCurrentStage(ctx, activityName), action = (activity.actions ?? []).find(a => a.name === actionName);
|
|
7915
|
+
if (action === void 0) throw new ContractViolationError(`Action "${actionName}" not declared on activity "${activityName}"`);
|
|
7316
7916
|
if (action.when !== void 0) throw new ActionDisabledError({
|
|
7317
7917
|
activity: activityName,
|
|
7318
7918
|
action: actionName,
|
|
@@ -7322,7 +7922,8 @@ async function resolveActionCommit({ctx: ctx, activityName: activityName, action
|
|
|
7322
7922
|
}
|
|
7323
7923
|
});
|
|
7324
7924
|
if (action.filter !== void 0) {
|
|
7325
|
-
const
|
|
7925
|
+
const vars = await callerBoundVarsForCall({
|
|
7926
|
+
client: ctx.client,
|
|
7326
7927
|
instance: ctx.instance,
|
|
7327
7928
|
options: options
|
|
7328
7929
|
});
|
|
@@ -7334,10 +7935,8 @@ async function resolveActionCommit({ctx: ctx, activityName: activityName, action
|
|
|
7334
7935
|
...actor !== void 0 ? {
|
|
7335
7936
|
actor: actor
|
|
7336
7937
|
} : {},
|
|
7337
|
-
...
|
|
7338
|
-
vars:
|
|
7339
|
-
can: can
|
|
7340
|
-
}
|
|
7938
|
+
...vars !== void 0 ? {
|
|
7939
|
+
vars: vars
|
|
7341
7940
|
} : {}
|
|
7342
7941
|
}
|
|
7343
7942
|
})) throw new ActionDisabledError({
|
|
@@ -8592,340 +9191,97 @@ async function commitReport({ctx: ctx, effectKey: effectKey, claimToken: claimTo
|
|
|
8592
9191
|
if (validatedOps.length === 0) throw new EffectOpsInvalidError({
|
|
8593
9192
|
effect: pending.name,
|
|
8594
9193
|
issues: [ "a mid-dispatch report must carry at least one field op — there is nothing to commit" ]
|
|
8595
|
-
});
|
|
8596
|
-
const mutation = startMutation(ctx.instance);
|
|
8597
|
-
return recordProcessedRequest({
|
|
8598
|
-
mutation: mutation,
|
|
8599
|
-
record: requestRecord,
|
|
8600
|
-
now: ctx.now
|
|
8601
|
-
}), renewClaimLease({
|
|
8602
|
-
mutation: mutation,
|
|
8603
|
-
effectKey: effectKey,
|
|
8604
|
-
now: ctx.now,
|
|
8605
|
-
leaseMs: leaseMs
|
|
8606
|
-
}), await runOps({
|
|
8607
|
-
ops: validatedOps,
|
|
8608
|
-
mutation: mutation,
|
|
8609
|
-
stage: ctx.instance.currentStage,
|
|
8610
|
-
origin: {
|
|
8611
|
-
effect: pending.name
|
|
8612
|
-
},
|
|
8613
|
-
params: pending.params,
|
|
8614
|
-
actor: ctx.actor,
|
|
8615
|
-
self: selfGdr(ctx.instance),
|
|
8616
|
-
now: ctx.now,
|
|
8617
|
-
snapshot: ctx.snapshot,
|
|
8618
|
-
refSurface: ctx.refSurface
|
|
8619
|
-
}), await persistThenMaybeRefresh({
|
|
8620
|
-
ctx: ctx,
|
|
8621
|
-
mutation: mutation,
|
|
8622
|
-
stageName: ctx.instance.currentStage,
|
|
8623
|
-
didChangeState: !0
|
|
8624
|
-
}), {
|
|
8625
|
-
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
|
-
} : {}
|
|
9194
|
+
});
|
|
9195
|
+
const mutation = startMutation(ctx.instance);
|
|
9196
|
+
return recordProcessedRequest({
|
|
9197
|
+
mutation: mutation,
|
|
9198
|
+
record: requestRecord,
|
|
9199
|
+
now: ctx.now
|
|
9200
|
+
}), renewClaimLease({
|
|
9201
|
+
mutation: mutation,
|
|
9202
|
+
effectKey: effectKey,
|
|
9203
|
+
now: ctx.now,
|
|
9204
|
+
leaseMs: leaseMs
|
|
9205
|
+
}), await runOps({
|
|
9206
|
+
ops: validatedOps,
|
|
9207
|
+
mutation: mutation,
|
|
9208
|
+
stage: ctx.instance.currentStage,
|
|
9209
|
+
origin: {
|
|
9210
|
+
effect: pending.name
|
|
8762
9211
|
},
|
|
8763
|
-
|
|
8764
|
-
|
|
8765
|
-
|
|
9212
|
+
params: pending.params,
|
|
9213
|
+
actor: ctx.actor,
|
|
9214
|
+
self: selfGdr(ctx.instance),
|
|
9215
|
+
now: ctx.now,
|
|
9216
|
+
snapshot: ctx.snapshot,
|
|
9217
|
+
refSurface: ctx.refSurface
|
|
9218
|
+
}), await persistThenMaybeRefresh({
|
|
9219
|
+
ctx: ctx,
|
|
9220
|
+
mutation: mutation,
|
|
9221
|
+
stageName: ctx.instance.currentStage,
|
|
9222
|
+
didChangeState: !0
|
|
9223
|
+
}), {
|
|
9224
|
+
effectKey: effectKey,
|
|
9225
|
+
effect: pending.name
|
|
8766
9226
|
};
|
|
8767
9227
|
}
|
|
8768
9228
|
|
|
8769
|
-
|
|
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
|
-
};
|
|
9229
|
+
const RESET_ACTIVITY_TARGETS = [ "active", "skipped" ];
|
|
8776
9230
|
|
|
8777
|
-
function
|
|
8778
|
-
return
|
|
9231
|
+
function isResetActivityTarget(value) {
|
|
9232
|
+
return RESET_ACTIVITY_TARGETS.includes(value);
|
|
8779
9233
|
}
|
|
8780
9234
|
|
|
8781
|
-
async function
|
|
8782
|
-
const {client: client,
|
|
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({
|
|
9235
|
+
async function resetActivity(args) {
|
|
9236
|
+
const {client: client, instanceId: instanceId, activity: activity, to: to, requestRecord: requestRecord, options: options} = args, ctx = await loadCallContext({
|
|
8787
9237
|
client: client,
|
|
8788
|
-
|
|
9238
|
+
instanceId: instanceId,
|
|
9239
|
+
options: options
|
|
8789
9240
|
});
|
|
8790
|
-
|
|
8791
|
-
|
|
8792
|
-
|
|
8793
|
-
|
|
8794
|
-
|
|
8795
|
-
|
|
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
|
|
9241
|
+
return commitResetActivity({
|
|
9242
|
+
ctx: ctx,
|
|
9243
|
+
activity: activity,
|
|
9244
|
+
to: to,
|
|
9245
|
+
requestRecord: requestRecord,
|
|
9246
|
+
actor: options?.actor
|
|
8824
9247
|
});
|
|
8825
9248
|
}
|
|
8826
9249
|
|
|
8827
|
-
function
|
|
8828
|
-
if (
|
|
8829
|
-
|
|
8830
|
-
|
|
8831
|
-
|
|
8832
|
-
|
|
8833
|
-
|
|
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
|
-
}
|
|
8842
|
-
}
|
|
8843
|
-
|
|
8844
|
-
async function fetchGlobalUser(client) {
|
|
8845
|
-
if (typeof client.withConfig != "function") return {
|
|
8846
|
-
user: void 0,
|
|
8847
|
-
reason: "the client cannot reach the global API host (no withConfig)"
|
|
8848
|
-
};
|
|
8849
|
-
let globalRequest, globalClient;
|
|
8850
|
-
const hostResolution = resolveGlobalApiHost(client);
|
|
8851
|
-
try {
|
|
8852
|
-
globalClient = client.withConfig({
|
|
8853
|
-
useProjectHostname: !1,
|
|
8854
|
-
...hostResolution.apiHost === void 0 ? {} : {
|
|
8855
|
-
apiHost: hostResolution.apiHost
|
|
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
|
-
}
|
|
8887
|
-
}
|
|
8888
|
-
|
|
8889
|
-
function resolveGlobalApiHost(client) {
|
|
8890
|
-
if (typeof client.config != "function") return {
|
|
8891
|
-
requireGlobalPrincipal: !1
|
|
9250
|
+
async function commitResetActivity({ctx: ctx, activity: activity, to: to, requestRecord: requestRecord, actor: actor}) {
|
|
9251
|
+
if (assertRequestUnprocessed({
|
|
9252
|
+
instance: ctx.instance,
|
|
9253
|
+
record: requestRecord,
|
|
9254
|
+
now: ctx.now
|
|
9255
|
+
}), isTerminal(ctx)) return {
|
|
9256
|
+
fired: !1
|
|
8892
9257
|
};
|
|
8893
|
-
const
|
|
8894
|
-
if (
|
|
8895
|
-
|
|
9258
|
+
const mutation = startMutation(ctx.instance), openStage2 = findOpenStageEntry(mutation), entry = findCurrentActivityEntry(mutation, activity);
|
|
9259
|
+
if (openStage2 === void 0 || entry === void 0) throw new ContractViolationError(`resetActivity: activity "${activity}" is not in the current stage of instance "${ctx.instance._id}"`);
|
|
9260
|
+
const from = entry.status;
|
|
9261
|
+
if (from === to) return {
|
|
9262
|
+
fired: !1
|
|
8896
9263
|
};
|
|
8897
|
-
|
|
8898
|
-
|
|
8899
|
-
|
|
8900
|
-
|
|
8901
|
-
|
|
8902
|
-
|
|
8903
|
-
|
|
8904
|
-
|
|
8905
|
-
|
|
8906
|
-
|
|
9264
|
+
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.`);
|
|
9265
|
+
return recordProcessedRequest({
|
|
9266
|
+
mutation: mutation,
|
|
9267
|
+
record: requestRecord,
|
|
9268
|
+
now: ctx.now
|
|
9269
|
+
}), applyActivityStatusChange({
|
|
9270
|
+
entry: entry,
|
|
9271
|
+
history: mutation.history,
|
|
9272
|
+
stage: openStage2.name,
|
|
9273
|
+
to: to,
|
|
9274
|
+
at: ctx.now,
|
|
9275
|
+
...actor !== void 0 ? {
|
|
9276
|
+
actor: actor
|
|
9277
|
+
} : {}
|
|
9278
|
+
}), await persist(ctx, mutation), {
|
|
9279
|
+
fired: !0,
|
|
9280
|
+
stage: openStage2.name,
|
|
9281
|
+
activity: activity,
|
|
9282
|
+
from: from,
|
|
9283
|
+
to: to
|
|
8907
9284
|
};
|
|
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
9285
|
}
|
|
8930
9286
|
|
|
8931
9287
|
const REPLAY_SURFACE = {
|
|
@@ -9109,7 +9465,7 @@ async function resourceActorId(client) {
|
|
|
9109
9465
|
async function evaluateInstance(args) {
|
|
9110
9466
|
const {client: client, tag: tag, workflowResource: workflowResource, instanceId: instanceId, resourceClients: resourceClients} = args, now = (args.clock ?? wallClock)();
|
|
9111
9467
|
validateTag(tag);
|
|
9112
|
-
const [access, instance] = await Promise.all([ resolveAccess(client, {
|
|
9468
|
+
const [access, instance, attributes] = await Promise.all([ resolveAccess(client, {
|
|
9113
9469
|
...args.grantsFromPath !== void 0 ? {
|
|
9114
9470
|
grantsFromPath: args.grantsFromPath
|
|
9115
9471
|
} : {}
|
|
@@ -9117,7 +9473,7 @@ async function evaluateInstance(args) {
|
|
|
9117
9473
|
client: client,
|
|
9118
9474
|
instanceId: instanceId,
|
|
9119
9475
|
tag: tag
|
|
9120
|
-
}) ]), {actor: actor, grants: grants, localPrincipalId: localPrincipalId} = access, definition = parseDefinitionSnapshot(instance), clientForGdr = buildClientForGdr({
|
|
9476
|
+
}), resolveUserAttributes(client) ]), {actor: actor, grants: grants, localPrincipalId: localPrincipalId} = access, definition = parseDefinitionSnapshot(instance), clientForGdr = buildClientForGdr({
|
|
9121
9477
|
client: client,
|
|
9122
9478
|
workflowResource: workflowResource,
|
|
9123
9479
|
resourceClients: resourceClients
|
|
@@ -9142,6 +9498,9 @@ async function evaluateInstance(args) {
|
|
|
9142
9498
|
} : {},
|
|
9143
9499
|
...grants !== void 0 ? {
|
|
9144
9500
|
grants: grants
|
|
9501
|
+
} : {},
|
|
9502
|
+
...attributes !== void 0 ? {
|
|
9503
|
+
attributes: attributes
|
|
9145
9504
|
} : {}
|
|
9146
9505
|
});
|
|
9147
9506
|
}
|
|
@@ -9156,6 +9515,33 @@ function memoizedByName(render) {
|
|
|
9156
9515
|
};
|
|
9157
9516
|
}
|
|
9158
9517
|
|
|
9518
|
+
async function callerBoundProjectionScopes(args) {
|
|
9519
|
+
const can = await advisoryCan({
|
|
9520
|
+
instance: args.instance,
|
|
9521
|
+
identity: args.identity,
|
|
9522
|
+
grants: args.grants
|
|
9523
|
+
}), vars = callerBoundVars({
|
|
9524
|
+
...can !== void 0 ? {
|
|
9525
|
+
can: can
|
|
9526
|
+
} : {},
|
|
9527
|
+
...args.attributes !== void 0 ? {
|
|
9528
|
+
attributes: args.attributes
|
|
9529
|
+
} : {}
|
|
9530
|
+
}), opts = {
|
|
9531
|
+
actor: args.actor,
|
|
9532
|
+
...vars !== void 0 ? {
|
|
9533
|
+
vars: vars
|
|
9534
|
+
} : {}
|
|
9535
|
+
};
|
|
9536
|
+
return {
|
|
9537
|
+
scope: await renderConditionScope(args.scopeSource, opts),
|
|
9538
|
+
scopeForActivity: memoizedByName(activityName => renderConditionScope(args.scopeSource, {
|
|
9539
|
+
activityName: activityName,
|
|
9540
|
+
...opts
|
|
9541
|
+
}))
|
|
9542
|
+
};
|
|
9543
|
+
}
|
|
9544
|
+
|
|
9159
9545
|
function currentStageOf(instance, definition) {
|
|
9160
9546
|
try {
|
|
9161
9547
|
return findStage(definition, instance.currentStage);
|
|
@@ -9181,7 +9567,7 @@ async function explainSite(args) {
|
|
|
9181
9567
|
}
|
|
9182
9568
|
|
|
9183
9569
|
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({
|
|
9570
|
+
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
9571
|
instance: instance,
|
|
9186
9572
|
definition: definition,
|
|
9187
9573
|
snapshot: snapshot,
|
|
@@ -9198,22 +9584,14 @@ async function evaluateFromSnapshot(args) {
|
|
|
9198
9584
|
}, anchorIdentity = lakePrincipalId({
|
|
9199
9585
|
actor: actor,
|
|
9200
9586
|
localPrincipalId: args.localPrincipalId
|
|
9201
|
-
}),
|
|
9202
|
-
|
|
9203
|
-
identity: anchorIdentity,
|
|
9204
|
-
grants: grants
|
|
9205
|
-
}), scope = await renderConditionScope(scopeSource, {
|
|
9206
|
-
actor: actor,
|
|
9207
|
-
vars: {
|
|
9208
|
-
can: can
|
|
9209
|
-
}
|
|
9210
|
-
}), scopeForActivity = memoizedByName(activityName => renderConditionScope(scopeSource, {
|
|
9211
|
-
activityName: activityName,
|
|
9587
|
+
}), {scope: scope, scopeForActivity: scopeForActivity} = await callerBoundProjectionScopes({
|
|
9588
|
+
scopeSource: scopeSource,
|
|
9212
9589
|
actor: actor,
|
|
9213
|
-
|
|
9214
|
-
|
|
9215
|
-
|
|
9216
|
-
|
|
9590
|
+
instance: instance,
|
|
9591
|
+
grants: grants,
|
|
9592
|
+
attributes: attributes,
|
|
9593
|
+
identity: anchorIdentity
|
|
9594
|
+
}), cascadeScopeForActivity = memoizedByName(activityName => renderConditionScope(scopeSource, {
|
|
9217
9595
|
activityName: activityName
|
|
9218
9596
|
})), currentActivityEntries = findOpenStageEntry(instance)?.activities ?? [], guardDenial = await instanceGuardReason({
|
|
9219
9597
|
instance: instance,
|
|
@@ -9262,6 +9640,7 @@ async function evaluateFromSnapshot(args) {
|
|
|
9262
9640
|
}
|
|
9263
9641
|
const currentStage = {
|
|
9264
9642
|
stage: stage,
|
|
9643
|
+
...semanticsOf(stage),
|
|
9265
9644
|
activities: activityEvaluations,
|
|
9266
9645
|
transitions: transitionEvaluations,
|
|
9267
9646
|
autonomy: stageAutonomy2
|
|
@@ -9278,6 +9657,7 @@ async function evaluateFromSnapshot(args) {
|
|
|
9278
9657
|
return {
|
|
9279
9658
|
instance: instance,
|
|
9280
9659
|
definition: definition,
|
|
9660
|
+
...semanticsOf(definition),
|
|
9281
9661
|
actor: actor,
|
|
9282
9662
|
currentStage: currentStage,
|
|
9283
9663
|
pendingOnYou: pendingOnYou,
|
|
@@ -9433,6 +9813,7 @@ async function evaluateActivity(args) {
|
|
|
9433
9813
|
}));
|
|
9434
9814
|
return {
|
|
9435
9815
|
activity: activity,
|
|
9816
|
+
...semanticsOf(activity),
|
|
9436
9817
|
status: status,
|
|
9437
9818
|
kind: deriveActivityKind(activity),
|
|
9438
9819
|
classification: deriveExecutorClassification(activity),
|
|
@@ -9603,9 +9984,13 @@ function fireableActionVerdict({args: args, insights: insights}) {
|
|
|
9603
9984
|
function actionEvaluationIdentity(action) {
|
|
9604
9985
|
return {
|
|
9605
9986
|
action: action,
|
|
9606
|
-
...action
|
|
9607
|
-
|
|
9608
|
-
|
|
9987
|
+
...semanticsOf(action)
|
|
9988
|
+
};
|
|
9989
|
+
}
|
|
9990
|
+
|
|
9991
|
+
function semanticsOf(node) {
|
|
9992
|
+
return node.semantics === void 0 ? {} : {
|
|
9993
|
+
semantics: node.semantics
|
|
9609
9994
|
};
|
|
9610
9995
|
}
|
|
9611
9996
|
|
|
@@ -10084,7 +10469,8 @@ async function commitEdit({ctx: ctx, target: target, mode: mode, value: value, r
|
|
|
10084
10469
|
}
|
|
10085
10470
|
|
|
10086
10471
|
async function assertFieldEditable({ctx: ctx, site: site, options: options}) {
|
|
10087
|
-
const actor = options?.actor, window = fieldWindowOpen(ctx.instance, site),
|
|
10472
|
+
const actor = options?.actor, window = fieldWindowOpen(ctx.instance, site), vars = await callerBoundVarsForCall({
|
|
10473
|
+
client: ctx.client,
|
|
10088
10474
|
instance: ctx.instance,
|
|
10089
10475
|
options: options
|
|
10090
10476
|
}), predicateSatisfied = window.open && site.effective !== !0 && site.effective !== void 0 ? await ctxEvaluateCondition({
|
|
@@ -10097,10 +10483,8 @@ async function assertFieldEditable({ctx: ctx, site: site, options: options}) {
|
|
|
10097
10483
|
...actor !== void 0 ? {
|
|
10098
10484
|
actor: actor
|
|
10099
10485
|
} : {},
|
|
10100
|
-
...
|
|
10101
|
-
vars:
|
|
10102
|
-
can: can
|
|
10103
|
-
}
|
|
10486
|
+
...vars !== void 0 ? {
|
|
10487
|
+
vars: vars
|
|
10104
10488
|
} : {}
|
|
10105
10489
|
}
|
|
10106
10490
|
}) : site.effective === !0, reason = editDisabledReason({
|
|
@@ -10590,6 +10974,9 @@ function buildEngineCallOptions(args) {
|
|
|
10590
10974
|
...args.grants !== void 0 ? {
|
|
10591
10975
|
grants: args.grants
|
|
10592
10976
|
} : {},
|
|
10977
|
+
...args.attributes !== void 0 ? {
|
|
10978
|
+
attributes: args.attributes
|
|
10979
|
+
} : {},
|
|
10593
10980
|
...args.clock !== void 0 ? {
|
|
10594
10981
|
clock: args.clock
|
|
10595
10982
|
} : {},
|
|
@@ -12348,7 +12735,7 @@ function createInstanceSession(args) {
|
|
|
12348
12735
|
refSurface: evalScope.refSurface
|
|
12349
12736
|
});
|
|
12350
12737
|
}, evaluateWith = async ({held: held, guards: guards, self: self}) => {
|
|
12351
|
-
const {actor: actor, localPrincipalId: localPrincipalId, grants: grants} = await access(), resourceGrants = await subjectResourceGrants({
|
|
12738
|
+
const [{actor: actor, localPrincipalId: localPrincipalId, grants: grants}, attributes] = await Promise.all([ access(), resolveUserAttributes(client) ]), resourceGrants = await subjectResourceGrants({
|
|
12352
12739
|
clientForGdr: evalScope.clientForGdr,
|
|
12353
12740
|
instance: instance
|
|
12354
12741
|
}), normalizedSelf = await normalizeInstanceIdentities({
|
|
@@ -12370,6 +12757,9 @@ function createInstanceSession(args) {
|
|
|
12370
12757
|
} : {},
|
|
12371
12758
|
...grants !== void 0 ? {
|
|
12372
12759
|
grants: grants
|
|
12760
|
+
} : {},
|
|
12761
|
+
...attributes !== void 0 ? {
|
|
12762
|
+
attributes: attributes
|
|
12373
12763
|
} : {}
|
|
12374
12764
|
});
|
|
12375
12765
|
}, settleAfterApply = async ({actor: actor, held: held, ranOps: ranOps, scope: scope}) => {
|
|
@@ -13065,7 +13455,7 @@ const HISTORY_DISPLAY = {
|
|
|
13065
13455
|
},
|
|
13066
13456
|
opApplied: {
|
|
13067
13457
|
title: "Op applied",
|
|
13068
|
-
description: "An
|
|
13458
|
+
description: "An action, direct edit, or effect completion executed an operation and recorded its audit payload."
|
|
13069
13459
|
},
|
|
13070
13460
|
fieldQueryDiscarded: {
|
|
13071
13461
|
title: "Query result discarded",
|
|
@@ -13170,6 +13560,10 @@ const HISTORY_DISPLAY = {
|
|
|
13170
13560
|
title: "Set field entry",
|
|
13171
13561
|
description: "Overwrite a field entry's value with a resolved value expression."
|
|
13172
13562
|
},
|
|
13563
|
+
"field.setIfMissing": {
|
|
13564
|
+
title: "Set field entry if missing",
|
|
13565
|
+
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."
|
|
13566
|
+
},
|
|
13173
13567
|
"field.unset": {
|
|
13174
13568
|
title: "Unset field entry",
|
|
13175
13569
|
description: "Reset a field entry to its default (null for scalars, [] for array kinds)."
|
|
@@ -13178,6 +13572,14 @@ const HISTORY_DISPLAY = {
|
|
|
13178
13572
|
title: "Append to field entry",
|
|
13179
13573
|
description: "Push a resolved item onto an array-kind entry (array, assignees, doc.refs)."
|
|
13180
13574
|
},
|
|
13575
|
+
"field.inc": {
|
|
13576
|
+
title: "Increment field entry",
|
|
13577
|
+
description: "Add a resolved numeric delta, defaulting to 1, to a number entry that already holds a finite number."
|
|
13578
|
+
},
|
|
13579
|
+
"field.dec": {
|
|
13580
|
+
title: "Decrement field entry",
|
|
13581
|
+
description: "Subtract a resolved numeric delta, defaulting to 1, from a number entry that already holds a finite number."
|
|
13582
|
+
},
|
|
13181
13583
|
"field.updateWhere": {
|
|
13182
13584
|
title: "Update matching rows",
|
|
13183
13585
|
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 +13693,4 @@ function displayDescription(typeKey) {
|
|
|
13291
13693
|
if (typeKey) return DISPLAY[typeKey]?.description;
|
|
13292
13694
|
}
|
|
13293
13695
|
|
|
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 };
|
|
13696
|
+
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, 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, 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, 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, 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, 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 };
|