@sanity/workflow-engine 0.32.0 → 0.33.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 +193 -0
- package/DATAMODEL.md +144 -8
- package/README.md +2 -2
- package/dist/_chunks-cjs/invariants.cjs +2017 -1891
- package/dist/_chunks-es/invariants.js +2047 -1923
- package/dist/define.cjs +6 -3
- package/dist/define.d.cts +431 -255
- package/dist/define.d.ts +431 -255
- package/dist/define.js +7 -4
- package/dist/index.cjs +745 -210
- package/dist/index.d.cts +845 -429
- package/dist/index.d.ts +845 -429
- package/dist/index.js +737 -214
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { rethrowWithContext, findOpenStageEntry, findCurrentActivityEntry, andConditions, deriveActivityKind, CALLER_BOUND_VARS, START_REQUIREMENT_VARS, CONDITION_VARS, isSubjectEntry, isUnevaluable, ContractViolationError, isStartableDefinition, conditionFieldReadNames, isGdr, errorMessage, conditionParameterNames, START_FILTER_VARS, WorkflowError, gdrFromResource, selfGdr, isGdrUri, MUTATION_GUARD_ID_SPACES, mutationGuardActionIdSpace, LAKE_MUTATION_GUARD_ACTIONS, isBareDocumentId, toBareId, normalizeAssignmentMembers, isSingleDocRefKind, actorMatchesAssignment, assignmentMembers, resolvedChildStatus, sameResource, resourceFromParsed, tryParseGdr, isTerminalActivityStatus, FieldValueShapeError, validateFieldValue, validateFieldAppendItem, isAssignmentFieldEntry, isAlwaysArrayFieldKind, evaluateCondition, isRecord, isSingleDocRefEntry, choiceValueIssues, scalarValidationIssues, StoredFieldOpSchema, formatIssues, conditionSyntaxIssues, checkWorkflowInvariants, formatIssuePath, isGuardReadExpr, GUARD_ACTIONS_REQUIRED_MESSAGE, conditionEffectReads, EFFECTS_READ, datasetResourceParts, mutationGuardRequiresSplitEmission, MUTATION_GUARD_ACTIONS, assignmentKindAcceptsRoles, evaluatePredicates, WORKFLOW_DEFINITION_TYPE, tagScopeFilter, liveSubworkflows, isCascadeFired, classifyPrincipalId, directoryBridgeId, parseGdr, gdrRef, isInputSourced, parseFieldValue, VersionSpecificDatasetGdrError, toPhysicalGdr, isBareSeedId, isParseableInstant, NonEmptyString, tolerantEntries, FIELD_VALUE_KINDS, tolerantObject, ActorShape, IsoTimestamp, ACTIVITY_STATUSES, GdrShape, DRIVER_KINDS, FIELD_SCOPES, fieldValueSchemas, parsePersistedDoc, ACTOR_KINDS, InstanceNotFoundError, evaluateConditionOutcome, runGroq as runGroq$1, FIELD_READ, resourceGdr, condemnSubworkflow, resourceFromGdrUri, refTypeIssues, rejectedRefTypes, DOCUMENT_VALUE_PERMISSIONS, lakePrincipalId, firstCarriedGlobalId, driverKind, actorFulfillsRole, condemnedSubworkflows, EffectNotFoundError, isFilterScopedOut, deriveExecutorClassification, validateTag, activeAssignmentMembers, extractDocumentId, UNIVERSAL_ROLE_ALIAS_KEY, parseStoredDefinition, validateResourceAliasName, labelFor, DefinitionNotFoundError, definitionDocId, SpawnContractsInvalidError, gdrResourcePrefix, RESOURCE_ALIAS_NAME_SOURCE, DefinitionInUseError, groupMembershipNames } from "./_chunks-es/invariants.js";
|
|
1
|
+
import { rethrowWithContext, findOpenStageEntry, findCurrentActivityEntry, andConditions, deriveActivityKind, CALLER_BOUND_VARS, START_REQUIREMENT_VARS, CONDITION_VARS, isSubjectEntry, isUnevaluable, ContractViolationError, isStartableDefinition, conditionFieldReadNames, isGdr, errorMessage, conditionParameterNames, START_FILTER_VARS, WorkflowError, gdrFromResource, selfGdr, isGdrUri, MUTATION_GUARD_ID_SPACES, mutationGuardActionIdSpace, LAKE_MUTATION_GUARD_ACTIONS, isBareDocumentId, toBareId, normalizeAssignmentMembers, isSingleDocRefKind, actorMatchesAssignment, assignmentMembers, resolvedChildStatus, sameResource, resourceFromParsed, tryParseGdr, isTerminalActivityStatus, FieldValueShapeError, validateFieldValue, validateFieldAppendItem, isAssignmentFieldEntry, isAlwaysArrayFieldKind, evaluateCondition, isRecord, isSingleDocRefEntry, choiceValueIssues, scalarValidationIssues, StoredFieldOpSchema, formatIssues, conditionSyntaxIssues, checkWorkflowInvariants, formatIssuePath, isGuardReadExpr, GUARD_ACTIONS_REQUIRED_MESSAGE, conditionEffectReads, EFFECTS_READ, datasetResourceParts, refKindAcceptsTypes, mutationGuardRequiresSplitEmission, MUTATION_GUARD_ACTIONS, assignmentKindAcceptsRoles, evaluatePredicates, WORKFLOW_DEFINITION_TYPE, tagScopeFilter, liveSubworkflows, isCascadeFired, classifyPrincipalId, directoryBridgeId, parseGdr, gdrRef, isInputSourced, parseFieldValue, VersionSpecificDatasetGdrError, toPhysicalGdr, isBareSeedId, isParseableInstant, NonEmptyString, tolerantEntries, FIELD_VALUE_KINDS, tolerantObject, ActorShape, IsoTimestamp, ACTIVITY_STATUSES, GdrShape, DRIVER_KINDS, FIELD_SCOPES, fieldValueSchemas, parsePersistedDoc, ACTOR_KINDS, InstanceNotFoundError, evaluateConditionOutcome, runGroq as runGroq$1, FIELD_READ, resourceGdr, condemnSubworkflow, resourceFromGdrUri, refTypeIssues, rejectedRefTypes, DOCUMENT_VALUE_PERMISSIONS, lakePrincipalId, firstCarriedGlobalId, driverKind, actorFulfillsRole, condemnedSubworkflows, EffectNotFoundError, isFilterScopedOut, deriveExecutorClassification, validateTag, activeAssignmentMembers, extractDocumentId, UNIVERSAL_ROLE_ALIAS_KEY, parseStoredDefinition, validateResourceAliasName, labelFor, DefinitionNotFoundError, definitionDocId, SpawnContractsInvalidError, gdrResourcePrefix, RESOURCE_ALIAS_NAME_SOURCE, DefinitionInUseError, effectBackoffMs, groupMembershipNames } from "./_chunks-es/invariants.js";
|
|
2
2
|
|
|
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, assignmentMatch, assignmentState, assignmentStateCounts, clientConfigFromResource, gdrUri, identityMatchesAssignment, instanceAssignmentStateCounts, isNotesEntry, isTodoListEntry, isTodoListItem, openActivityAssignments, parseResourceGdr, readsRootDocument, refCanvas, refDashboard, refDataset,
|
|
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, assignmentMatch, assignmentState, assignmentStateCounts, clientConfigFromResource, gdrUri, identityMatchesAssignment, instanceAssignmentStateCounts, isNotesEntry, isTodoListEntry, isTodoListItem, openActivityAssignments, parseResourceGdr, readsRootDocument, refCanvas, refDashboard, refDataset, 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, _exhaustiveOptions, whatIfCondition, runGroq, formatRead, dedupeReads, MAX_COUNTERFACTUAL_INDEX } from "@sanity/groq-condition-describe";
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@ import { MAX_COUNTERFACTUAL_INDEX as MAX_COUNTERFACTUAL_INDEX2, NEUTRAL_MARK, OU
|
|
|
8
8
|
|
|
9
9
|
import { evaluate, parse } from "groq-js";
|
|
10
10
|
|
|
11
|
-
import { getPublishedId, getDraftId } from "@sanity/id-utils";
|
|
11
|
+
import { getPublishedId, getDraftId, DocumentId } from "@sanity/id-utils";
|
|
12
12
|
|
|
13
13
|
import * as v from "valibot";
|
|
14
14
|
|
|
@@ -69,6 +69,10 @@ function effectiveEditable(baseline, override) {
|
|
|
69
69
|
|
|
70
70
|
const DEFAULT_EDIT_MODE = "set";
|
|
71
71
|
|
|
72
|
+
function _fieldTargetLabel(target) {
|
|
73
|
+
return [ target.scope, target.activity, target.field ].filter(Boolean).join(".");
|
|
74
|
+
}
|
|
75
|
+
|
|
72
76
|
function fieldSites(definition, stage) {
|
|
73
77
|
const sites = [];
|
|
74
78
|
for (const entry of definition.fields ?? []) sites.push({
|
|
@@ -1045,6 +1049,7 @@ function describeSiteHeading(address, ctx) {
|
|
|
1045
1049
|
}
|
|
1046
1050
|
|
|
1047
1051
|
case "action":
|
|
1052
|
+
case "action-when":
|
|
1048
1053
|
{
|
|
1049
1054
|
const title = actionTitle(address, ctx), activity = activityTitle(address.activity, ctx);
|
|
1050
1055
|
return phrase(id, {
|
|
@@ -1052,7 +1057,7 @@ function describeSiteHeading(address, ctx) {
|
|
|
1052
1057
|
title: title,
|
|
1053
1058
|
activity: activity
|
|
1054
1059
|
},
|
|
1055
|
-
text: `action ${quoted(title)} on ${quoted(activity)} is available when:`
|
|
1060
|
+
text: `action ${quoted(title)} on ${quoted(activity)} ${address.kind === "action" ? "is available" : "fires automatically"} when:`
|
|
1056
1061
|
});
|
|
1057
1062
|
}
|
|
1058
1063
|
|
|
@@ -1079,18 +1084,6 @@ function describeSiteHeading(address, ctx) {
|
|
|
1079
1084
|
});
|
|
1080
1085
|
}
|
|
1081
1086
|
|
|
1082
|
-
case "action-when":
|
|
1083
|
-
{
|
|
1084
|
-
const title = actionTitle(address, ctx), activity = activityTitle(address.activity, ctx);
|
|
1085
|
-
return phrase(id, {
|
|
1086
|
-
params: {
|
|
1087
|
-
title: title,
|
|
1088
|
-
activity: activity
|
|
1089
|
-
},
|
|
1090
|
-
text: `action ${quoted(title)} on ${quoted(activity)} fires automatically when:`
|
|
1091
|
-
});
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
1087
|
case "editable-field":
|
|
1095
1088
|
{
|
|
1096
1089
|
const field = fieldTitleOf({
|
|
@@ -1134,6 +1127,7 @@ function describeSite(site, ctx) {
|
|
|
1134
1127
|
}
|
|
1135
1128
|
|
|
1136
1129
|
case "action":
|
|
1130
|
+
case "action-when":
|
|
1137
1131
|
{
|
|
1138
1132
|
const title = actionTitle(site, ctx), activity = activityTitle(site.activity, ctx);
|
|
1139
1133
|
return phrase(id, {
|
|
@@ -1141,7 +1135,7 @@ function describeSite(site, ctx) {
|
|
|
1141
1135
|
title: title,
|
|
1142
1136
|
activity: activity
|
|
1143
1137
|
},
|
|
1144
|
-
text: `the ${quoted(title)} action on ${quoted(activity)}`
|
|
1138
|
+
text: `the ${quoted(title)} ${site.kind === "action" ? "action" : "trigger"} on ${quoted(activity)}`
|
|
1145
1139
|
});
|
|
1146
1140
|
}
|
|
1147
1141
|
|
|
@@ -1157,18 +1151,6 @@ function describeSite(site, ctx) {
|
|
|
1157
1151
|
});
|
|
1158
1152
|
}
|
|
1159
1153
|
|
|
1160
|
-
case "action-when":
|
|
1161
|
-
{
|
|
1162
|
-
const title = actionTitle(site, ctx), activity = activityTitle(site.activity, ctx);
|
|
1163
|
-
return phrase(id, {
|
|
1164
|
-
params: {
|
|
1165
|
-
title: title,
|
|
1166
|
-
activity: activity
|
|
1167
|
-
},
|
|
1168
|
-
text: `the ${quoted(title)} trigger on ${quoted(activity)}`
|
|
1169
|
-
});
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
1154
|
case "activity-filter":
|
|
1173
1155
|
{
|
|
1174
1156
|
const activity = activityTitle(site.activity, ctx);
|
|
@@ -1226,10 +1208,10 @@ function unsatisfiedTransitionSummaries(evaluation) {
|
|
|
1226
1208
|
definition: evaluation.definition
|
|
1227
1209
|
};
|
|
1228
1210
|
return evaluation.currentStage.transitions.filter(t => !t.whenSatisfied).flatMap(t => {
|
|
1229
|
-
const
|
|
1230
|
-
return
|
|
1211
|
+
const summary2 = describeCondition(t.insight, ctx).summary;
|
|
1212
|
+
return summary2 !== void 0 ? [ {
|
|
1231
1213
|
transition: t.transition.name,
|
|
1232
|
-
summary:
|
|
1214
|
+
summary: summary2
|
|
1233
1215
|
} ] : [];
|
|
1234
1216
|
});
|
|
1235
1217
|
}
|
|
@@ -2859,8 +2841,8 @@ class CascadeLimitError extends WorkflowError {
|
|
|
2859
2841
|
|
|
2860
2842
|
const FIELD_OP_TYPES = [ "field.set", "field.setIfMissing", "field.unset", "field.append", "field.inc", "field.dec", "field.updateWhere", "field.removeWhere" ];
|
|
2861
2843
|
|
|
2862
|
-
function isFieldOp(
|
|
2863
|
-
return FIELD_OP_TYPES.includes(
|
|
2844
|
+
function isFieldOp(summary2) {
|
|
2845
|
+
return FIELD_OP_TYPES.includes(summary2.opType);
|
|
2864
2846
|
}
|
|
2865
2847
|
|
|
2866
2848
|
function validateActionParams({action: action, activityName: activityName, callerParams: callerParams}) {
|
|
@@ -2939,7 +2921,7 @@ async function runOps(args) {
|
|
|
2939
2921
|
if (ops === void 0 || ops.length === 0) return [];
|
|
2940
2922
|
const opsFromDefinition = origin.effect === void 0 && origin.edit !== !0, summaries = [];
|
|
2941
2923
|
for (const op of ops) {
|
|
2942
|
-
const
|
|
2924
|
+
const summary2 = await applyOp(op, {
|
|
2943
2925
|
mutation: mutation,
|
|
2944
2926
|
stage: stage,
|
|
2945
2927
|
activityName: origin.activity,
|
|
@@ -2953,9 +2935,9 @@ async function runOps(args) {
|
|
|
2953
2935
|
memberRoles: args.memberRoles,
|
|
2954
2936
|
roleAliases: args.roleAliases
|
|
2955
2937
|
});
|
|
2956
|
-
summaries.push(
|
|
2938
|
+
summaries.push(summary2), shouldRecordOpApplied(summary2) && mutation.history.push(opAppliedEntry({
|
|
2957
2939
|
origin: origin,
|
|
2958
|
-
summary:
|
|
2940
|
+
summary: summary2,
|
|
2959
2941
|
stage: stage,
|
|
2960
2942
|
actor: actor,
|
|
2961
2943
|
now: now
|
|
@@ -2964,12 +2946,12 @@ async function runOps(args) {
|
|
|
2964
2946
|
return summaries;
|
|
2965
2947
|
}
|
|
2966
2948
|
|
|
2967
|
-
function shouldRecordOpApplied(
|
|
2968
|
-
return
|
|
2949
|
+
function shouldRecordOpApplied(summary2) {
|
|
2950
|
+
return summary2.opType !== "field.setIfMissing" || summary2.resolved !== void 0;
|
|
2969
2951
|
}
|
|
2970
2952
|
|
|
2971
2953
|
function opAppliedEntry(args) {
|
|
2972
|
-
const {origin: origin, summary:
|
|
2954
|
+
const {origin: origin, summary: summary2, stage: stage, actor: actor, now: now} = args;
|
|
2973
2955
|
return {
|
|
2974
2956
|
_key: randomKey(),
|
|
2975
2957
|
_type: "opApplied",
|
|
@@ -2987,12 +2969,12 @@ function opAppliedEntry(args) {
|
|
|
2987
2969
|
...origin.effect !== void 0 ? {
|
|
2988
2970
|
effect: origin.effect
|
|
2989
2971
|
} : {},
|
|
2990
|
-
opType:
|
|
2991
|
-
...
|
|
2992
|
-
target:
|
|
2972
|
+
opType: summary2.opType,
|
|
2973
|
+
...summary2.target !== void 0 ? {
|
|
2974
|
+
target: summary2.target
|
|
2993
2975
|
} : {},
|
|
2994
|
-
...
|
|
2995
|
-
resolved:
|
|
2976
|
+
...summary2.resolved !== void 0 ? {
|
|
2977
|
+
resolved: summary2.resolved
|
|
2996
2978
|
} : {},
|
|
2997
2979
|
...actor !== void 0 ? {
|
|
2998
2980
|
actor: actor
|
|
@@ -3768,7 +3750,13 @@ function siblingConfig(target) {
|
|
|
3768
3750
|
};
|
|
3769
3751
|
}
|
|
3770
3752
|
|
|
3771
|
-
const wallClock = () => /* @__PURE__ */ (new Date).toISOString()
|
|
3753
|
+
const wallClock = () => /* @__PURE__ */ (new Date).toISOString(), tick = ms => new Promise(resolve => {
|
|
3754
|
+
setTimeout(resolve, ms);
|
|
3755
|
+
}), wallSleeper = async ms => {
|
|
3756
|
+
let left = ms;
|
|
3757
|
+
for (;left > 2147483647; ) await tick(2147483647), left -= 2147483647;
|
|
3758
|
+
await tick(left);
|
|
3759
|
+
};
|
|
3772
3760
|
|
|
3773
3761
|
function addMs(instant, ms) {
|
|
3774
3762
|
return new Date(Date.parse(instant) + ms).toISOString();
|
|
@@ -3778,7 +3766,7 @@ function hasPassed(instant, now) {
|
|
|
3778
3766
|
return Date.parse(instant) <= Date.parse(now);
|
|
3779
3767
|
}
|
|
3780
3768
|
|
|
3781
|
-
const DATA_MODEL_VERSION =
|
|
3769
|
+
const DATA_MODEL_VERSION = 10, DATA_MODEL_MIN_READER = 4, DATA_MODEL_MAX_READER = 10, READER_MODEL_ROLLOUT_URL = "https://www.sanity.io/docs/workflows/prerelease";
|
|
3782
3770
|
|
|
3783
3771
|
class ReaderModelAcknowledgementError extends WorkflowError {
|
|
3784
3772
|
code="WORKFLOW_READER_MODEL_ACKNOWLEDGEMENT_MISMATCH";
|
|
@@ -3934,6 +3922,22 @@ const DATA_MODEL_CHANGES = Object.freeze([ Object.freeze({
|
|
|
3934
3922
|
compatibility: "reader-floor",
|
|
3935
3923
|
applicability: "detectable",
|
|
3936
3924
|
summary: "Singular assignee fields use member lists with at most one user and any number of roles."
|
|
3925
|
+
}), Object.freeze({
|
|
3926
|
+
id: "required-content-references",
|
|
3927
|
+
introducedInModel: 10,
|
|
3928
|
+
minReaderModel: 10,
|
|
3929
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
3930
|
+
compatibility: "reader-floor",
|
|
3931
|
+
applicability: "detectable",
|
|
3932
|
+
summary: "Required content references must remain readable after initialization before actions or transitions advance."
|
|
3933
|
+
}), Object.freeze({
|
|
3934
|
+
id: "effect-retry-policy",
|
|
3935
|
+
introducedInModel: 10,
|
|
3936
|
+
minReaderModel: 10,
|
|
3937
|
+
documentTypes: Object.freeze([ "definition", "instance" ]),
|
|
3938
|
+
compatibility: "reader-floor",
|
|
3939
|
+
applicability: "detectable",
|
|
3940
|
+
summary: "An effect node declares a bounded retry policy the engine enforces on every runtime."
|
|
3937
3941
|
}) ]);
|
|
3938
3942
|
|
|
3939
3943
|
function recordOf(value) {
|
|
@@ -4065,6 +4069,10 @@ function hasSingularAssigneeLists(document) {
|
|
|
4065
4069
|
return typeof snapshot?.modelVersion == "number" && isAssignmentListModel(snapshot.modelVersion) && persistedFieldEntries(document).some(entry => entryHasKind(entry, "assignee"));
|
|
4066
4070
|
}
|
|
4067
4071
|
|
|
4072
|
+
function hasEffectRetryPolicy(document) {
|
|
4073
|
+
return persistedDefinitionTree(document)?.actions.some(action => recordsAt(action, "effects").some(effect => recordOf(effect.retry) !== void 0)) ?? !1;
|
|
4074
|
+
}
|
|
4075
|
+
|
|
4068
4076
|
function isMutationGuardAction(action) {
|
|
4069
4077
|
return typeof action == "string" && MUTATION_GUARD_ACTIONS.some(candidate => candidate === action);
|
|
4070
4078
|
}
|
|
@@ -4076,6 +4084,10 @@ function hasSplitGuardIdSpaces(document) {
|
|
|
4076
4084
|
})) ?? !1;
|
|
4077
4085
|
}
|
|
4078
4086
|
|
|
4087
|
+
function hasRequiredContentReferences(document) {
|
|
4088
|
+
return persistedDefinitionTree(document)?.roots.some(root => recordsAt(root, "fields").some(field => field.required === !0 && typeof field.type == "string" && refKindAcceptsTypes(field.type))) ?? !1;
|
|
4089
|
+
}
|
|
4090
|
+
|
|
4079
4091
|
const featureDetectors = {
|
|
4080
4092
|
"governed-model-stamps": () => !0,
|
|
4081
4093
|
"subject-field-kind": document => hasFieldKind(document, "subject"),
|
|
@@ -4090,6 +4102,8 @@ const featureDetectors = {
|
|
|
4090
4102
|
"role-constrained-assignment-fields": hasRoleConstrainedAssignments,
|
|
4091
4103
|
"singular-assignee-lists": hasSingularAssigneeLists,
|
|
4092
4104
|
"split-guard-id-spaces": hasSplitGuardIdSpaces,
|
|
4105
|
+
"required-content-references": hasRequiredContentReferences,
|
|
4106
|
+
"effect-retry-policy": hasEffectRetryPolicy,
|
|
4093
4107
|
"node-semantics": hasNodeSemantics,
|
|
4094
4108
|
"field-patch-ops": document => hasPersistedOpType(document, [ "field.inc", "field.dec", "field.setIfMissing" ]),
|
|
4095
4109
|
"attributes-condition-var": () => !0
|
|
@@ -4326,9 +4340,13 @@ function abortReason(instance) {
|
|
|
4326
4340
|
}
|
|
4327
4341
|
|
|
4328
4342
|
function diagnoseInputFromEvaluation(evaluation) {
|
|
4343
|
+
if (evaluation.missingDocuments?.length && evaluation.blockingMissingDocuments === void 0) throw new Error("Missing blocking document evidence in workflow evaluation");
|
|
4329
4344
|
const stage = openStage(evaluation.instance);
|
|
4330
4345
|
return {
|
|
4331
4346
|
instance: evaluation.instance,
|
|
4347
|
+
...evaluation.missingDocuments !== void 0 ? {
|
|
4348
|
+
missingDocuments: evaluation.blockingMissingDocuments ?? []
|
|
4349
|
+
} : {},
|
|
4332
4350
|
activities: evaluation.currentStage.activities,
|
|
4333
4351
|
transitions: evaluation.currentStage.transitions,
|
|
4334
4352
|
assignees: Object.fromEntries(evaluation.currentStage.activities.map(t => [ t.activity.name, assigneesOf(stage, t.activity.name) ]))
|
|
@@ -4447,7 +4465,7 @@ function diagnoseInstance(input) {
|
|
|
4447
4465
|
at: instance.completedAt,
|
|
4448
4466
|
...liveChildrenField(instance)
|
|
4449
4467
|
};
|
|
4450
|
-
const cause = stuckFromDocumentState(input) ?? noTransitionFiresCause(input);
|
|
4468
|
+
const cause = stuckFromDocumentState(input) ?? missingDocumentCause(input.missingDocuments) ?? noTransitionFiresCause(input);
|
|
4451
4469
|
return cause !== void 0 ? {
|
|
4452
4470
|
state: "stuck",
|
|
4453
4471
|
cause: cause
|
|
@@ -4456,10 +4474,27 @@ function diagnoseInstance(input) {
|
|
|
4456
4474
|
};
|
|
4457
4475
|
}
|
|
4458
4476
|
|
|
4477
|
+
function missingDocumentCause(documents = []) {
|
|
4478
|
+
return documents.length > 0 ? {
|
|
4479
|
+
kind: "document-missing",
|
|
4480
|
+
documents: documents
|
|
4481
|
+
} : void 0;
|
|
4482
|
+
}
|
|
4483
|
+
|
|
4484
|
+
function _additionalMissingDocuments(diagnosis, documents) {
|
|
4485
|
+
return diagnosis.state === "stuck" && diagnosis.cause.kind !== "document-missing" ? documents ?? [] : [];
|
|
4486
|
+
}
|
|
4487
|
+
|
|
4459
4488
|
const RUNNABLE_VERBS = /* @__PURE__ */ new Set([ "set-stage", "abort", "drain-effects", "reset-activity" ]);
|
|
4460
4489
|
|
|
4461
4490
|
function remediationsForCause(cause) {
|
|
4462
4491
|
switch (cause.kind) {
|
|
4492
|
+
case "document-missing":
|
|
4493
|
+
return [ {
|
|
4494
|
+
verb: "abort",
|
|
4495
|
+
rationale: "Required content cannot be read. Investigate the referenced documents, or abort the instance if it is no longer needed."
|
|
4496
|
+
} ];
|
|
4497
|
+
|
|
4463
4498
|
case "failed-effect":
|
|
4464
4499
|
return [ {
|
|
4465
4500
|
verb: "retry-effect",
|
|
@@ -4554,12 +4589,12 @@ function joinCacheFor(client) {
|
|
|
4554
4589
|
}
|
|
4555
4590
|
|
|
4556
4591
|
function isClientProjectMember(value) {
|
|
4557
|
-
return isRecord(value) && typeof value.id == "string";
|
|
4592
|
+
return isRecord(value) && typeof value.id == "string" && (value.isRobot === void 0 || typeof value.isRobot == "boolean");
|
|
4558
4593
|
}
|
|
4559
4594
|
|
|
4560
|
-
async function
|
|
4595
|
+
async function _requestProjectMembers(request, projectId) {
|
|
4561
4596
|
const project = await request({
|
|
4562
|
-
|
|
4597
|
+
url: `/projects/${encodeURIComponent(projectId)}`
|
|
4563
4598
|
}), members = isRecord(project) ? project.members : void 0;
|
|
4564
4599
|
if (!Array.isArray(members) || !members.every(isClientProjectMember)) throw new Error(`Project member directory response is invalid for project "${projectId}"`);
|
|
4565
4600
|
return members;
|
|
@@ -4567,7 +4602,7 @@ async function requestProjectMembers(request, projectId) {
|
|
|
4567
4602
|
|
|
4568
4603
|
async function requestProjectUsers(args) {
|
|
4569
4604
|
const {request: request, projectId: projectId, memberIds: memberIds} = args, response = await request({
|
|
4570
|
-
|
|
4605
|
+
url: `/projects/${encodeURIComponent(projectId)}/users/${memberIds.map(encodeURIComponent).join(",")}`
|
|
4571
4606
|
}), rows = Array.isArray(response) ? response : [ response ];
|
|
4572
4607
|
if (!rows.every(isClientProjectUser)) throw new Error(`Project user directory response is invalid for project "${projectId}"`);
|
|
4573
4608
|
const requested = new Set(memberIds);
|
|
@@ -4575,7 +4610,7 @@ async function requestProjectUsers(args) {
|
|
|
4575
4610
|
}
|
|
4576
4611
|
|
|
4577
4612
|
async function requestProjectMemberDirectory(args) {
|
|
4578
|
-
const {request: request, projectId: projectId} = args, members = await
|
|
4613
|
+
const {request: request, projectId: projectId} = args, members = await _requestProjectMembers(request, projectId), memberIds = members.map(member => member.id).filter(id => classifyPrincipalId(id).namespace === "project");
|
|
4579
4614
|
if (memberIds.length === 0) return {
|
|
4580
4615
|
members: members,
|
|
4581
4616
|
globalUsers: []
|
|
@@ -4650,7 +4685,7 @@ function clientProjectUserDirectory(client, projectId) {
|
|
|
4650
4685
|
});
|
|
4651
4686
|
try {
|
|
4652
4687
|
const response = await client.request({
|
|
4653
|
-
|
|
4688
|
+
url: `/projects/${encodeURIComponent(projectId)}/users/${encodeURIComponent(id)}`
|
|
4654
4689
|
}), candidate = Array.isArray(response) ? response[0] : response;
|
|
4655
4690
|
return candidate == null ? {
|
|
4656
4691
|
status: "missing"
|
|
@@ -4762,8 +4797,30 @@ function collectWatchRefs(instance) {
|
|
|
4762
4797
|
}
|
|
4763
4798
|
|
|
4764
4799
|
function collectSubjectRefs(instance) {
|
|
4765
|
-
const
|
|
4766
|
-
return [ ...entryDocRefs(
|
|
4800
|
+
const entries = activeFieldEntries(instance).map(({entry: entry}) => entry);
|
|
4801
|
+
return [ ...entryDocRefs(entries), ...entryReleaseRefs(entries) ];
|
|
4802
|
+
}
|
|
4803
|
+
|
|
4804
|
+
function activeFieldEntries(instance) {
|
|
4805
|
+
const stage = findOpenStageEntry(instance);
|
|
4806
|
+
return [ ...scopedEntries(instance.fields, {
|
|
4807
|
+
scope: "workflow"
|
|
4808
|
+
}), ...scopedEntries(stage?.fields, {
|
|
4809
|
+
scope: "stage"
|
|
4810
|
+
}), ...(stage?.activities ?? []).flatMap(activity => scopedEntries(activity.fields, {
|
|
4811
|
+
scope: "activity",
|
|
4812
|
+
activity: activity.name
|
|
4813
|
+
})) ];
|
|
4814
|
+
}
|
|
4815
|
+
|
|
4816
|
+
function scopedEntries(entries, scope) {
|
|
4817
|
+
return (entries ?? []).map(entry => ({
|
|
4818
|
+
target: {
|
|
4819
|
+
...scope,
|
|
4820
|
+
field: entry.name
|
|
4821
|
+
},
|
|
4822
|
+
entry: entry
|
|
4823
|
+
}));
|
|
4767
4824
|
}
|
|
4768
4825
|
|
|
4769
4826
|
function foreignSubjectRefs(instance) {
|
|
@@ -4864,6 +4921,10 @@ function entrySubjectRefs(entries) {
|
|
|
4864
4921
|
return fieldEntries(entries).flatMap(entry => (typeof entry._type == "string" && isSingleDocRefKind(entry._type) || entry._type === "release.ref") && isGdr(entry.value) ? [ entry.value ] : []);
|
|
4865
4922
|
}
|
|
4866
4923
|
|
|
4924
|
+
function missingEntryDocRefs(entries, knownIds) {
|
|
4925
|
+
return entryDocRefs(entries).filter(reference => !knownIds.has(reference.id));
|
|
4926
|
+
}
|
|
4927
|
+
|
|
4867
4928
|
function fieldEntries(entries) {
|
|
4868
4929
|
return Array.isArray(entries) ? entries.filter(entry => !!entry && typeof entry == "object") : [];
|
|
4869
4930
|
}
|
|
@@ -6134,7 +6195,7 @@ async function resolveThroughDirectory(args) {
|
|
|
6134
6195
|
if (safeMisses.length === 0 || client.request === void 0) return out;
|
|
6135
6196
|
try {
|
|
6136
6197
|
const response = await client.request({
|
|
6137
|
-
|
|
6198
|
+
url: `/projects/${encodeURIComponent(projectId)}/users/${safeMisses.map(encodeURIComponent).join(",")}`,
|
|
6138
6199
|
tag: REQUEST_TAG.accessResolveActor
|
|
6139
6200
|
});
|
|
6140
6201
|
ingestDirectoryRows({
|
|
@@ -6334,6 +6395,12 @@ function memoizedBy(compute) {
|
|
|
6334
6395
|
};
|
|
6335
6396
|
}
|
|
6336
6397
|
|
|
6398
|
+
function chunks(values, size) {
|
|
6399
|
+
return Array.from({
|
|
6400
|
+
length: Math.ceil(values.length / size)
|
|
6401
|
+
}, (_, index) => values.slice(index * size, (index + 1) * size));
|
|
6402
|
+
}
|
|
6403
|
+
|
|
6337
6404
|
async function hydrateSnapshot(args) {
|
|
6338
6405
|
const {client: client, clientForGdr: clientForGdr, instance: instance, overlay: overlay} = args, loaded = [], visited = /* @__PURE__ */ new Set;
|
|
6339
6406
|
loaded.push({
|
|
@@ -6444,12 +6511,6 @@ function groupReads(reads) {
|
|
|
6444
6511
|
return [ ...byClient.values() ].flatMap(groups => [ ...groups.values() ]);
|
|
6445
6512
|
}
|
|
6446
6513
|
|
|
6447
|
-
function chunks(values, size) {
|
|
6448
|
-
return Array.from({
|
|
6449
|
-
length: Math.ceil(values.length / size)
|
|
6450
|
-
}, (_, index) => values.slice(index * size, (index + 1) * size));
|
|
6451
|
-
}
|
|
6452
|
-
|
|
6453
6514
|
function collectEntryDocUris(resolvedFieldEntries) {
|
|
6454
6515
|
return entryDocRefs(resolvedFieldEntries).map(ref => ref.id);
|
|
6455
6516
|
}
|
|
@@ -7669,6 +7730,29 @@ async function refreshStageGuards({ctx: ctx, mutation: mutation, stageName: stag
|
|
|
7669
7730
|
});
|
|
7670
7731
|
}
|
|
7671
7732
|
|
|
7733
|
+
function missingRequiredDocuments({instance: instance, definition: definition, snapshot: snapshot}) {
|
|
7734
|
+
return (definition.fields ?? []).filter(field => field.required === !0 && refKindAcceptsTypes(field.type)).flatMap(field => {
|
|
7735
|
+
const entry = instance.fields.find(candidate => candidate.name === field.name && candidate._type === field.type);
|
|
7736
|
+
return missingEntryDocRefs(entry === void 0 ? [] : [ entry ], snapshot.knownIds).map(reference => ({
|
|
7737
|
+
target: {
|
|
7738
|
+
scope: "workflow",
|
|
7739
|
+
field: field.name
|
|
7740
|
+
},
|
|
7741
|
+
reference: reference
|
|
7742
|
+
}));
|
|
7743
|
+
});
|
|
7744
|
+
}
|
|
7745
|
+
|
|
7746
|
+
function requiredDocumentRequirements(args) {
|
|
7747
|
+
return [ ...new Set(missingRequiredDocuments(args).map(({target: target}) => target.field)) ].map(field => {
|
|
7748
|
+
const title = args.definition.fields?.find(entry => entry.name === field)?.title ?? field;
|
|
7749
|
+
return {
|
|
7750
|
+
name: `field:${field}`,
|
|
7751
|
+
title: `Documents selected for “${title}” must be readable`
|
|
7752
|
+
};
|
|
7753
|
+
});
|
|
7754
|
+
}
|
|
7755
|
+
|
|
7672
7756
|
async function discoverItems(args) {
|
|
7673
7757
|
const {client: client, groq: groq, params: params, perspective: perspective} = args;
|
|
7674
7758
|
return client.fetch(groq, paramsForLake(params), {
|
|
@@ -8244,7 +8328,7 @@ async function persistStageMove({ctx: ctx, mutation: mutation, exitedStage: exit
|
|
|
8244
8328
|
}
|
|
8245
8329
|
|
|
8246
8330
|
async function pickTransition(ctx, stage) {
|
|
8247
|
-
for (const candidate of stage.transitions ?? []) {
|
|
8331
|
+
if (!(missingRequiredDocuments(ctx).length > 0)) for (const candidate of stage.transitions ?? []) {
|
|
8248
8332
|
const outcome = await ctxEvaluateConditionOutcome({
|
|
8249
8333
|
ctx: ctx,
|
|
8250
8334
|
condition: candidate.when
|
|
@@ -8346,7 +8430,7 @@ const actorCache = /* @__PURE__ */ new WeakMap, grantsCache = /* @__PURE__ */ ne
|
|
|
8346
8430
|
|
|
8347
8431
|
async function resolveAccess(taggedClient, args = {}) {
|
|
8348
8432
|
const client = unwrapRequestTag(taggedClient), requestFn = lazyRequest(client);
|
|
8349
|
-
if (requestFn === void 0) throw new ContractViolationError("workflow: no actor available. The engine resolves the actor from the client's token via `client.request({
|
|
8433
|
+
if (requestFn === void 0) throw new ContractViolationError("workflow: no actor available. The engine resolves the actor from the client's token via `client.request({url: '/users/me'})`. Supply a real `@sanity/client` configured with a token (the test bench serves these endpoints per registered token).");
|
|
8350
8434
|
const grantsPromise = args.grantsFromPath !== void 0 ? cachedGrants({
|
|
8351
8435
|
client: client,
|
|
8352
8436
|
requestFn: requestFn,
|
|
@@ -8415,20 +8499,32 @@ function cachedByKey(args) {
|
|
|
8415
8499
|
}
|
|
8416
8500
|
|
|
8417
8501
|
async function fetchActor(client, requestFn) {
|
|
8418
|
-
const
|
|
8502
|
+
const resourceUser = await fetchCurrentUser(requestFn, "the workflow resource host"), resourceId = usableId(resourceUser), resourceGlobalId = firstCarriedGlobalId([ resourceId ]) ?? directoryBridgeId(resourceUser?.sanityUserId);
|
|
8503
|
+
if (resourceGlobalId !== void 0) return identityFromUsers({
|
|
8504
|
+
id: resourceGlobalId,
|
|
8505
|
+
resourceUser: resourceUser
|
|
8506
|
+
});
|
|
8507
|
+
const globalUser = await fetchGlobalUser(client), globalHostId = usableId(globalUser.user), carriedId = firstCarriedGlobalId([ globalHostId ]), sessionId = carriedId ?? globalHostId ?? resourceId;
|
|
8419
8508
|
if (sessionId === void 0) return;
|
|
8420
8509
|
const bridge = carriedId === void 0 ? await bridgeProjectPrincipal({
|
|
8421
8510
|
client: client,
|
|
8422
8511
|
sessionId: sessionId,
|
|
8423
8512
|
resourceId: resourceId
|
|
8424
8513
|
}) : NO_BRIDGE, id = bridge.status === "resolved" ? bridge.globalId : sessionId;
|
|
8425
|
-
refuseProjectScopedActor({
|
|
8514
|
+
return refuseProjectScopedActor({
|
|
8426
8515
|
id: id,
|
|
8427
8516
|
globalUser: globalUser,
|
|
8428
8517
|
globalHostId: globalHostId,
|
|
8429
8518
|
bridgeFailure: bridge.status === "unavailable" ? bridge : void 0
|
|
8519
|
+
}), identityFromUsers({
|
|
8520
|
+
id: id,
|
|
8521
|
+
resourceUser: resourceUser,
|
|
8522
|
+
globalUser: globalUser.user
|
|
8430
8523
|
});
|
|
8431
|
-
|
|
8524
|
+
}
|
|
8525
|
+
|
|
8526
|
+
function identityFromUsers(args) {
|
|
8527
|
+
const {id: id, resourceUser: resourceUser, globalUser: globalUser} = args, resourceId = usableId(resourceUser), roleNames = roleNamesFor(resourceUser, globalUser);
|
|
8432
8528
|
return {
|
|
8433
8529
|
actor: {
|
|
8434
8530
|
kind: "person",
|
|
@@ -8444,7 +8540,7 @@ async function fetchActor(client, requestFn) {
|
|
|
8444
8540
|
}
|
|
8445
8541
|
|
|
8446
8542
|
function roleNamesFor(resourceUser, globalUser) {
|
|
8447
|
-
return (resourceUser?.roles?.length ? resourceUser : globalUser
|
|
8543
|
+
return (resourceUser?.roles?.length ? resourceUser : globalUser)?.roles?.map(r => r.name).filter(n => !!n) ?? [];
|
|
8448
8544
|
}
|
|
8449
8545
|
|
|
8450
8546
|
const NO_BRIDGE = {
|
|
@@ -8508,11 +8604,11 @@ function usableId(user) {
|
|
|
8508
8604
|
async function fetchCurrentUser(requestFn, hostDescription) {
|
|
8509
8605
|
try {
|
|
8510
8606
|
return await requestFn({
|
|
8511
|
-
|
|
8607
|
+
url: "/users/me",
|
|
8512
8608
|
tag: REQUEST_TAG.accessResolveActor
|
|
8513
8609
|
});
|
|
8514
8610
|
} catch (err) {
|
|
8515
|
-
throw new Error(`workflow: /users/me request against ${hostDescription} failed. The engine resolves the actor from the client's token via \`client.request({
|
|
8611
|
+
throw new Error(`workflow: /users/me request against ${hostDescription} failed. The engine resolves the actor from the client's token via \`client.request({url: '/users/me'})\`. Check the token/connectivity.`, {
|
|
8516
8612
|
cause: err
|
|
8517
8613
|
});
|
|
8518
8614
|
}
|
|
@@ -8529,7 +8625,7 @@ async function fetchGlobalUser(client) {
|
|
|
8529
8625
|
};
|
|
8530
8626
|
try {
|
|
8531
8627
|
const user = await sibling.request({
|
|
8532
|
-
|
|
8628
|
+
url: "/users/me",
|
|
8533
8629
|
tag: REQUEST_TAG.accessResolveActor
|
|
8534
8630
|
}), id = usableId(user);
|
|
8535
8631
|
return sibling.requireGlobalPrincipal && id !== void 0 && classifyPrincipalId(id).namespace === "project" ? {
|
|
@@ -8652,7 +8748,7 @@ async function resolveOrganizationId(args) {
|
|
|
8652
8748
|
load: async () => {
|
|
8653
8749
|
try {
|
|
8654
8750
|
const project = await requestFn({
|
|
8655
|
-
|
|
8751
|
+
url: `/projects/${encodeURIComponent(projectId)}`,
|
|
8656
8752
|
tag: REQUEST_TAG.accessResolveOrg
|
|
8657
8753
|
});
|
|
8658
8754
|
if (!isRecord(project)) return;
|
|
@@ -8677,15 +8773,17 @@ function httpStatusOf(err) {
|
|
|
8677
8773
|
return typeof status == "number" ? status : void 0;
|
|
8678
8774
|
}
|
|
8679
8775
|
|
|
8776
|
+
function attributesRequestOf(client) {
|
|
8777
|
+
const version = client.config?.().apiVersion, request = typeof client.withConfig == "function" || version === void 0 || version === ENGINE_API_VERSION ? lazyRequest(pinApiVersion(client)) : void 0;
|
|
8778
|
+
return request === void 0 && console.warn("workflow: skipped org attributes fetch; the client cannot issue API-version-pinned requests. Advisory $attributes stays undefined (conditions referencing it fail closed)."),
|
|
8779
|
+
request;
|
|
8780
|
+
}
|
|
8781
|
+
|
|
8680
8782
|
async function fetchAttributesCached(args) {
|
|
8681
|
-
const {client: client, orgId: orgId} = args,
|
|
8682
|
-
if (
|
|
8683
|
-
|
|
8684
|
-
|
|
8685
|
-
}
|
|
8686
|
-
try {
|
|
8687
|
-
const response = await sibling.request({
|
|
8688
|
-
uri: `/organizations/${encodeURIComponent(orgId)}/users/me/attributes?limit=${ATTRIBUTES_FETCH_LIMIT}`,
|
|
8783
|
+
const {client: client, orgId: orgId} = args, request = attributesRequestOf(client);
|
|
8784
|
+
if (request !== void 0) try {
|
|
8785
|
+
const response = await request({
|
|
8786
|
+
url: `/organizations/${encodeURIComponent(orgId)}/users/me/attributes?limit=${ATTRIBUTES_FETCH_LIMIT}`,
|
|
8689
8787
|
tag: REQUEST_TAG.accessAttributes
|
|
8690
8788
|
}), envelope = isRecord(response) ? response : void 0;
|
|
8691
8789
|
if (envelope?.hasMore === !0) {
|
|
@@ -8799,6 +8897,15 @@ async function resolveActionCommit({ctx: ctx, activityName: activityName, action
|
|
|
8799
8897
|
actionName: actionName,
|
|
8800
8898
|
status: entry?.status
|
|
8801
8899
|
});
|
|
8900
|
+
const unmetRequirements = requiredDocumentRequirements(ctx);
|
|
8901
|
+
if (unmetRequirements.length > 0) throw new ActionDisabledError({
|
|
8902
|
+
activity: activityName,
|
|
8903
|
+
action: actionName,
|
|
8904
|
+
reason: {
|
|
8905
|
+
kind: "requirements-unmet",
|
|
8906
|
+
unmetRequirements: unmetRequirements
|
|
8907
|
+
}
|
|
8908
|
+
});
|
|
8802
8909
|
const params = validateActionParams({
|
|
8803
8910
|
action: action,
|
|
8804
8911
|
activityName: activityName,
|
|
@@ -8955,13 +9062,13 @@ async function runTriggeredActions({ctx: ctx, mutation: mutation, stage: stage})
|
|
|
8955
9062
|
async function runActivityTriggers({ctx: ctx, mutation: mutation, activity: activity}) {
|
|
8956
9063
|
let fires = 0, ranFieldOps = !1;
|
|
8957
9064
|
for (const action of activity.actions ?? []) {
|
|
8958
|
-
if (!isCascadeFired(action)) continue;
|
|
8959
9065
|
const entry = currentActivities(mutation).find(e => e.name === activity.name);
|
|
8960
9066
|
if (entry === void 0 || entry.status !== "active") break;
|
|
8961
|
-
if (
|
|
9067
|
+
if (!await triggerIsLive({
|
|
8962
9068
|
ctx: ctx,
|
|
8963
9069
|
activity: activity,
|
|
8964
|
-
action: action
|
|
9070
|
+
action: action,
|
|
9071
|
+
entry: entry
|
|
8965
9072
|
})) continue;
|
|
8966
9073
|
const result = await fireTriggeredAction({
|
|
8967
9074
|
ctx: ctx,
|
|
@@ -8978,8 +9085,12 @@ async function runActivityTriggers({ctx: ctx, mutation: mutation, activity: acti
|
|
|
8978
9085
|
};
|
|
8979
9086
|
}
|
|
8980
9087
|
|
|
8981
|
-
|
|
8982
|
-
|
|
9088
|
+
function isUnfiredTrigger(action, entry) {
|
|
9089
|
+
return isCascadeFired(action) && !(entry.firedActions ?? []).includes(action.name);
|
|
9090
|
+
}
|
|
9091
|
+
|
|
9092
|
+
async function triggerIsLive({ctx: ctx, activity: activity, action: action, entry: entry}) {
|
|
9093
|
+
if (!isUnfiredTrigger(action, entry) || missingRequiredDocuments(ctx).length > 0 || !tokenMayExecute({
|
|
8983
9094
|
actor: ctx.actor,
|
|
8984
9095
|
action: action,
|
|
8985
9096
|
ctx: ctx
|
|
@@ -10083,7 +10194,7 @@ function staleClaimReason(args) {
|
|
|
10083
10194
|
if (isClaimExpired(claim, args.now)) return "lease-expired";
|
|
10084
10195
|
}
|
|
10085
10196
|
|
|
10086
|
-
function renewClaimLease(args) {
|
|
10197
|
+
function renewClaimLease$1(args) {
|
|
10087
10198
|
const {mutation: mutation, effectKey: effectKey, now: now, leaseMs: leaseMs} = args;
|
|
10088
10199
|
mutation.pendingEffects = mutation.pendingEffects.map(entry => entry._key === effectKey && entry.claim !== void 0 ? {
|
|
10089
10200
|
...entry,
|
|
@@ -10120,7 +10231,7 @@ async function commitReport({ctx: ctx, effectKey: effectKey, claimToken: claimTo
|
|
|
10120
10231
|
mutation: mutation,
|
|
10121
10232
|
record: requestRecord,
|
|
10122
10233
|
now: ctx.now
|
|
10123
|
-
}), renewClaimLease({
|
|
10234
|
+
}), renewClaimLease$1({
|
|
10124
10235
|
mutation: mutation,
|
|
10125
10236
|
effectKey: effectKey,
|
|
10126
10237
|
now: ctx.now,
|
|
@@ -10209,6 +10320,100 @@ async function commitResetActivity({ctx: ctx, activity: activity, to: to, reques
|
|
|
10209
10320
|
};
|
|
10210
10321
|
}
|
|
10211
10322
|
|
|
10323
|
+
const AvailabilityResponse = v.object({
|
|
10324
|
+
documents: v.array(v.object({
|
|
10325
|
+
_id: v.string()
|
|
10326
|
+
})),
|
|
10327
|
+
omitted: v.array(v.object({
|
|
10328
|
+
id: v.string(),
|
|
10329
|
+
reason: v.picklist([ "existence", "permission" ])
|
|
10330
|
+
}))
|
|
10331
|
+
}), AVAILABILITY_BATCH_SIZE = 100, AVAILABILITY_CONCURRENCY = 4, pendingReads = /* @__PURE__ */ new WeakMap;
|
|
10332
|
+
|
|
10333
|
+
function groupsFor(documents, clientForGdr) {
|
|
10334
|
+
const groups = /* @__PURE__ */ new Map;
|
|
10335
|
+
for (const {reference: reference} of documents) {
|
|
10336
|
+
const parsed = parseGdr(reference.id), resource = resourceFromParsed(parsed), key = resourceGdr(resource), group = groups.get(key) ?? {
|
|
10337
|
+
client: clientForGdr(parsed),
|
|
10338
|
+
resource: resource,
|
|
10339
|
+
documents: /* @__PURE__ */ new Map
|
|
10340
|
+
};
|
|
10341
|
+
group.documents.set(reference.id, parsed.documentId), groups.set(key, group);
|
|
10342
|
+
}
|
|
10343
|
+
return [ ...groups.values() ];
|
|
10344
|
+
}
|
|
10345
|
+
|
|
10346
|
+
async function readGroup(group) {
|
|
10347
|
+
let response;
|
|
10348
|
+
try {
|
|
10349
|
+
const url = documentUrl(group);
|
|
10350
|
+
url !== void 0 && group.client.request !== void 0 ? response = await readResponse(group.client, url) : logUnavailable({
|
|
10351
|
+
resource: group.resource,
|
|
10352
|
+
reason: "unsupported-client"
|
|
10353
|
+
});
|
|
10354
|
+
} catch (error) {
|
|
10355
|
+
logUnavailable({
|
|
10356
|
+
resource: group.resource,
|
|
10357
|
+
reason: v.isValiError(error) ? "invalid-response" : "request-failed",
|
|
10358
|
+
error: error
|
|
10359
|
+
});
|
|
10360
|
+
}
|
|
10361
|
+
return [ ...group.documents ].map(([uri, id]) => [ uri, availabilityOf(response, id) ]);
|
|
10362
|
+
}
|
|
10363
|
+
|
|
10364
|
+
function logUnavailable({resource: resource, reason: reason, error: error}) {
|
|
10365
|
+
const statusCode = typeof error == "object" && error !== null && "statusCode" in error ? error.statusCode : void 0;
|
|
10366
|
+
console.warn("[workflows] Document availability could not be confirmed.", {
|
|
10367
|
+
resource: resourceGdr(resource),
|
|
10368
|
+
reason: reason,
|
|
10369
|
+
...typeof statusCode == "number" ? {
|
|
10370
|
+
statusCode: statusCode
|
|
10371
|
+
} : {}
|
|
10372
|
+
});
|
|
10373
|
+
}
|
|
10374
|
+
|
|
10375
|
+
function availabilityOf(response, id) {
|
|
10376
|
+
if (response === void 0) return "unreadable";
|
|
10377
|
+
const omissions = response.omitted.filter(entry => getPublishedId(DocumentId(entry.id)) === id);
|
|
10378
|
+
return omissions.some(entry => entry.reason === "permission") ? "unreadable" : response.documents.some(doc => getPublishedId(DocumentId(doc._id)) === id) ? "outside-perspective" : omissions.some(entry => entry.id === id && entry.reason === "existence") ? "deleted" : "unreadable";
|
|
10379
|
+
}
|
|
10380
|
+
|
|
10381
|
+
function documentUrl(group) {
|
|
10382
|
+
const ids = [ ...new Set(group.documents.values()) ].sort().map(encodeURIComponent).join(",");
|
|
10383
|
+
let url;
|
|
10384
|
+
if ("getDataUrl" in group.client && group.client.getDataUrl !== void 0) url = group.client.getDataUrl("doc", ids); else {
|
|
10385
|
+
if (group.resource.type !== "dataset") return;
|
|
10386
|
+
const {dataset: dataset} = datasetResourceParts(group.resource.id);
|
|
10387
|
+
url = `/data/doc/${dataset}/${ids}`;
|
|
10388
|
+
}
|
|
10389
|
+
return `${url}?includeAllVersions=true`;
|
|
10390
|
+
}
|
|
10391
|
+
|
|
10392
|
+
function readResponse(client, url) {
|
|
10393
|
+
const identity = unwrapRequestTag(client), pending = pendingReads.get(identity) ?? /* @__PURE__ */ new Map;
|
|
10394
|
+
pendingReads.set(identity, pending);
|
|
10395
|
+
const existing = pending.get(url);
|
|
10396
|
+
if (existing !== void 0) return existing;
|
|
10397
|
+
const result = client.request({
|
|
10398
|
+
url: url
|
|
10399
|
+
}).then(response => v.parse(AvailabilityResponse, response)).finally(() => pending.delete(url));
|
|
10400
|
+
return pending.set(url, result), result;
|
|
10401
|
+
}
|
|
10402
|
+
|
|
10403
|
+
function documentAvailabilityReader(args) {
|
|
10404
|
+
return async documents => {
|
|
10405
|
+
const result = /* @__PURE__ */ new Map, groups = groupsFor(documents, args.clientForGdr).flatMap(group => chunks([ ...group.documents ], AVAILABILITY_BATCH_SIZE).map(entries => ({
|
|
10406
|
+
...group,
|
|
10407
|
+
documents: new Map(entries)
|
|
10408
|
+
})));
|
|
10409
|
+
for (const wave of chunks(groups, AVAILABILITY_CONCURRENCY)) {
|
|
10410
|
+
const rows = await Promise.all(wave.map(readGroup));
|
|
10411
|
+
for (const [uri, availability] of rows.flat()) result.set(uri, availability);
|
|
10412
|
+
}
|
|
10413
|
+
return result;
|
|
10414
|
+
};
|
|
10415
|
+
}
|
|
10416
|
+
|
|
10212
10417
|
const REPLAY_SURFACE = {
|
|
10213
10418
|
allows: () => !0,
|
|
10214
10419
|
description: "any resource (in-memory replay; the committing surface enforces)"
|
|
@@ -10360,6 +10565,80 @@ function fabricatable(assignment) {
|
|
|
10360
10565
|
return assignment.target.path.every(segment => typeof segment != "number" || segment <= MAX_COUNTERFACTUAL_INDEX);
|
|
10361
10566
|
}
|
|
10362
10567
|
|
|
10568
|
+
function missingDocumentsOf({instance: instance, snapshot: snapshot, definition: definition}) {
|
|
10569
|
+
const stage = findStageNode({
|
|
10570
|
+
definition: definition,
|
|
10571
|
+
stageName: instance.currentStage
|
|
10572
|
+
});
|
|
10573
|
+
return activeFieldEntries(instance).flatMap(({target: target, entry: entry}) => {
|
|
10574
|
+
const declarations = {
|
|
10575
|
+
workflow: definition?.fields,
|
|
10576
|
+
stage: stage?.fields,
|
|
10577
|
+
activity: stage?.activities?.find(activity => activity.name === target.activity)?.fields
|
|
10578
|
+
}, title = entry.title ?? declarations[target.scope ?? "workflow"]?.find(field => field.name === target.field)?.title;
|
|
10579
|
+
return missingEntryDocRefs([ entry ], snapshot.knownIds).map(reference => ({
|
|
10580
|
+
target: target,
|
|
10581
|
+
reference: reference,
|
|
10582
|
+
...title !== void 0 ? {
|
|
10583
|
+
title: title
|
|
10584
|
+
} : {}
|
|
10585
|
+
}));
|
|
10586
|
+
});
|
|
10587
|
+
}
|
|
10588
|
+
|
|
10589
|
+
function blockingConditions(evaluation) {
|
|
10590
|
+
const transitions = evaluation.currentStage.transitions.some(entry => entry.whenSatisfied) ? [] : evaluation.currentStage.transitions;
|
|
10591
|
+
return [ ...evaluation.currentStage.activities.filter(entry => entry.status === "active" && (entry.activity.actions ?? []).length > 0).flatMap(entry => (entry.unmetRequirements ?? []).map(requirement => ({
|
|
10592
|
+
insight: entry.requirementInsights?.[requirement.name],
|
|
10593
|
+
activity: entry.activity.name
|
|
10594
|
+
}))), ...transitions.map(entry => ({
|
|
10595
|
+
insight: entry.insight
|
|
10596
|
+
})) ];
|
|
10597
|
+
}
|
|
10598
|
+
|
|
10599
|
+
function readsDocumentContent({entry: entry, read: read, atom: atom}) {
|
|
10600
|
+
return atomReadsDataset(atom) ? !0 : isSingleDocRefKind(entry._type) && read.path.length > 1 && read.path[1] !== "_id" && read.path[1] !== "_type";
|
|
10601
|
+
}
|
|
10602
|
+
|
|
10603
|
+
function contentTargets({atoms: atoms, fields: fields, activity: activity}) {
|
|
10604
|
+
return atoms.flatMap(atom => atom.reads.flatMap(read => {
|
|
10605
|
+
if (read.variable !== "fields") return [];
|
|
10606
|
+
const field = fields.findLast(({entry: entry, target: target}) => entry.name === read.path[0] && (target.scope !== "activity" || target.activity === activity));
|
|
10607
|
+
return field !== void 0 && readsDocumentContent({
|
|
10608
|
+
entry: field.entry,
|
|
10609
|
+
read: read,
|
|
10610
|
+
atom: atom
|
|
10611
|
+
}) ? [ _fieldTargetLabel(field.target) ] : [];
|
|
10612
|
+
}));
|
|
10613
|
+
}
|
|
10614
|
+
|
|
10615
|
+
async function blockingAtoms(condition, args) {
|
|
10616
|
+
const atoms = condition.insight?.blockedBy.map(({atom: atom}) => atom) ?? [], names = [ ...new Set(atoms.flatMap(atom => atom.reads).filter(read => read.path.length === 0 && args.definition.predicates?.[read.variable] !== void 0).map(read => read.variable)) ];
|
|
10617
|
+
if (names.length === 0) return atoms;
|
|
10618
|
+
const site = args.sites.find(entry => entry.insight === condition.insight);
|
|
10619
|
+
if (site === void 0) throw new Error("Missing evaluated scope for a blocking condition");
|
|
10620
|
+
const dependencies = await Promise.all(names.map(async name => {
|
|
10621
|
+
const predicate = args.definition.predicates?.[name];
|
|
10622
|
+
if (predicate === void 0) throw new Error(`Missing predicate "${name}"`);
|
|
10623
|
+
return (await explainCondition({
|
|
10624
|
+
condition: site.params[name] === !0 ? `!(${predicate})` : predicate,
|
|
10625
|
+
dataset: args.snapshot.docs,
|
|
10626
|
+
params: site.params
|
|
10627
|
+
})).blockedBy.map(({atom: atom}) => atom);
|
|
10628
|
+
}));
|
|
10629
|
+
return [ ...atoms, ...dependencies.flat() ];
|
|
10630
|
+
}
|
|
10631
|
+
|
|
10632
|
+
async function blockingMissingDocuments(args) {
|
|
10633
|
+
if (!args.missingDocuments?.length) return [];
|
|
10634
|
+
const fields = activeFieldEntries(args.instance), targets = (await Promise.all(blockingConditions(args).map(async condition => contentTargets({
|
|
10635
|
+
atoms: await blockingAtoms(condition, args),
|
|
10636
|
+
fields: fields,
|
|
10637
|
+
activity: condition.activity
|
|
10638
|
+
})))).flat(), blocked = /* @__PURE__ */ new Set([ ...targets, ...missingRequiredDocuments(args).map(({target: target}) => _fieldTargetLabel(target)) ]);
|
|
10639
|
+
return args.missingDocuments.filter(({target: target}) => blocked.has(_fieldTargetLabel(target)));
|
|
10640
|
+
}
|
|
10641
|
+
|
|
10363
10642
|
async function subjectResourceGrants(args) {
|
|
10364
10643
|
const {clientForGdr: clientForGdr, instance: instance} = args, clients = /* @__PURE__ */ new Map;
|
|
10365
10644
|
for (const {parsed: parsed, resource: resource} of foreignSubjectRefs(instance)) {
|
|
@@ -10422,6 +10701,9 @@ async function evaluateInstance(args) {
|
|
|
10422
10701
|
guards: guards,
|
|
10423
10702
|
now: now,
|
|
10424
10703
|
resourceGrants: resourceGrants,
|
|
10704
|
+
documentAvailability: documentAvailabilityReader({
|
|
10705
|
+
clientForGdr: clientForGdr
|
|
10706
|
+
}),
|
|
10425
10707
|
guardDereference: clientGuardDereference(client),
|
|
10426
10708
|
...localPrincipalId !== void 0 ? {
|
|
10427
10709
|
localPrincipalId: localPrincipalId
|
|
@@ -10529,7 +10811,11 @@ async function evaluateFromSnapshot(args) {
|
|
|
10529
10811
|
}), subjectPermissionReason = subjectDenials.length > 0 ? {
|
|
10530
10812
|
kind: "subject-permission-denied",
|
|
10531
10813
|
denied: subjectDenials
|
|
10532
|
-
} : void 0, sites = [], activityEvaluations = []
|
|
10814
|
+
} : void 0, sites = [], activityEvaluations = [], requiredDocuments = requiredDocumentRequirements({
|
|
10815
|
+
instance: instance,
|
|
10816
|
+
definition: definition,
|
|
10817
|
+
snapshot: snapshot
|
|
10818
|
+
});
|
|
10533
10819
|
for (const activity of stage.activities ?? []) activityEvaluations.push(await evaluateActivity({
|
|
10534
10820
|
activity: activity,
|
|
10535
10821
|
statusEntry: currentActivityEntries.find(t => t.name === activity.name),
|
|
@@ -10540,36 +10826,23 @@ async function evaluateFromSnapshot(args) {
|
|
|
10540
10826
|
stageHasExits: !isTerminalStage(stage),
|
|
10541
10827
|
guardDenial: guardDenial,
|
|
10542
10828
|
subjectPermissionReason: subjectPermissionReason,
|
|
10829
|
+
requiredDocuments: requiredDocuments,
|
|
10543
10830
|
sites: sites,
|
|
10544
10831
|
autonomy: activityAutonomyOf(stageAutonomy2, activity.name),
|
|
10545
10832
|
fireConsequence: fireConsequence
|
|
10546
10833
|
}));
|
|
10547
|
-
const cascadeParams = await renderConditionScope(scopeSource), transitionEvaluations =
|
|
10548
|
-
|
|
10549
|
-
|
|
10550
|
-
|
|
10551
|
-
|
|
10552
|
-
|
|
10553
|
-
},
|
|
10554
|
-
condition: transition.when,
|
|
10555
|
-
params: cascadeParams,
|
|
10556
|
-
snapshot: snapshot,
|
|
10557
|
-
sites: sites
|
|
10558
|
-
});
|
|
10559
|
-
transitionEvaluations.push({
|
|
10560
|
-
transition: transition,
|
|
10561
|
-
whenSatisfied: insight.outcome === "satisfied",
|
|
10562
|
-
unevaluable: insight.outcome === "unevaluable",
|
|
10563
|
-
insight: insight
|
|
10564
|
-
});
|
|
10565
|
-
}
|
|
10566
|
-
const currentStage = {
|
|
10834
|
+
const cascadeParams = await renderConditionScope(scopeSource), transitionEvaluations = await evaluateTransitions({
|
|
10835
|
+
stage: stage,
|
|
10836
|
+
cascadeParams: cascadeParams,
|
|
10837
|
+
snapshot: snapshot,
|
|
10838
|
+
sites: sites
|
|
10839
|
+
}), currentStage = {
|
|
10567
10840
|
stage: stage,
|
|
10568
10841
|
...semanticsOf(stage),
|
|
10569
10842
|
activities: activityEvaluations,
|
|
10570
10843
|
transitions: transitionEvaluations,
|
|
10571
10844
|
autonomy: stageAutonomy2
|
|
10572
|
-
}, pendingOnYou = activityEvaluations.filter(t => t.pendingOnActor), canInteract = activityEvaluations.some(t => t.actions.some(a => a.allowed)), editGuardDenial = guardDenial?.kind === "mutation-guard-denied" ? guardDenial : void 0, editableFields = await evaluateEditableFields({
|
|
10845
|
+
}, missingDocuments = await readMissingDocuments(args), pendingOnYou = activityEvaluations.filter(t => t.pendingOnActor), canInteract = activityEvaluations.some(t => t.actions.some(a => a.allowed)), editGuardDenial = guardDenial?.kind === "mutation-guard-denied" ? guardDenial : void 0, editableFields = await evaluateEditableFields({
|
|
10573
10846
|
instance: instance,
|
|
10574
10847
|
definition: definition,
|
|
10575
10848
|
stage: stage,
|
|
@@ -10596,6 +10869,17 @@ async function evaluateFromSnapshot(args) {
|
|
|
10596
10869
|
sites: sites,
|
|
10597
10870
|
snapshot: snapshot
|
|
10598
10871
|
}),
|
|
10872
|
+
...missingDocuments.length > 0 ? {
|
|
10873
|
+
missingDocuments: missingDocuments,
|
|
10874
|
+
blockingMissingDocuments: await blockingMissingDocuments({
|
|
10875
|
+
instance: instance,
|
|
10876
|
+
definition: definition,
|
|
10877
|
+
currentStage: currentStage,
|
|
10878
|
+
missingDocuments: missingDocuments,
|
|
10879
|
+
snapshot: snapshot,
|
|
10880
|
+
sites: sites
|
|
10881
|
+
})
|
|
10882
|
+
} : {},
|
|
10599
10883
|
autonomy: autonomy,
|
|
10600
10884
|
...nextEvaluationAt !== void 0 ? {
|
|
10601
10885
|
nextEvaluationAt: nextEvaluationAt
|
|
@@ -10603,6 +10887,42 @@ async function evaluateFromSnapshot(args) {
|
|
|
10603
10887
|
};
|
|
10604
10888
|
}
|
|
10605
10889
|
|
|
10890
|
+
async function readMissingDocuments(args) {
|
|
10891
|
+
const missingDocuments = missingDocumentsOf(args);
|
|
10892
|
+
if (args.documentAvailability === void 0 || missingDocuments.length === 0) return missingDocuments;
|
|
10893
|
+
const availability = await args.documentAvailability(missingDocuments);
|
|
10894
|
+
return missingDocuments.map(document => {
|
|
10895
|
+
const verdict = availability.get(document.reference.id);
|
|
10896
|
+
return verdict === void 0 ? document : {
|
|
10897
|
+
...document,
|
|
10898
|
+
availability: verdict
|
|
10899
|
+
};
|
|
10900
|
+
});
|
|
10901
|
+
}
|
|
10902
|
+
|
|
10903
|
+
async function evaluateTransitions(args) {
|
|
10904
|
+
const {stage: stage, cascadeParams: cascadeParams, snapshot: snapshot, sites: sites} = args, evaluations = [];
|
|
10905
|
+
for (const transition of stage.transitions ?? []) {
|
|
10906
|
+
const insight = await explainSite({
|
|
10907
|
+
site: {
|
|
10908
|
+
kind: "transition",
|
|
10909
|
+
transition: transition.name
|
|
10910
|
+
},
|
|
10911
|
+
condition: transition.when,
|
|
10912
|
+
params: cascadeParams,
|
|
10913
|
+
snapshot: snapshot,
|
|
10914
|
+
sites: sites
|
|
10915
|
+
});
|
|
10916
|
+
evaluations.push({
|
|
10917
|
+
transition: transition,
|
|
10918
|
+
whenSatisfied: insight.outcome === "satisfied",
|
|
10919
|
+
unevaluable: insight.outcome === "unevaluable",
|
|
10920
|
+
insight: insight
|
|
10921
|
+
});
|
|
10922
|
+
}
|
|
10923
|
+
return evaluations;
|
|
10924
|
+
}
|
|
10925
|
+
|
|
10606
10926
|
const AUTONOMY_CACHE = /* @__PURE__ */ new WeakMap;
|
|
10607
10927
|
|
|
10608
10928
|
function autonomyOf(definition) {
|
|
@@ -10613,54 +10933,56 @@ function autonomyOf(definition) {
|
|
|
10613
10933
|
}
|
|
10614
10934
|
|
|
10615
10935
|
async function evaluateEditableFields(args) {
|
|
10616
|
-
const
|
|
10617
|
-
for (const site of editableFieldsInStage(definition, stage))
|
|
10618
|
-
const window = fieldWindowOpen(instance, site), insight = await editPredicateInsight({
|
|
10619
|
-
site: site,
|
|
10620
|
-
snapshot: snapshot,
|
|
10621
|
-
scope: scope,
|
|
10622
|
-
scopeForActivity: scopeForActivity,
|
|
10623
|
-
sites: sites
|
|
10624
|
-
}), predicateSatisfied = insight === void 0 || insight.outcome === "satisfied", reason = editDisabledReason({
|
|
10625
|
-
effective: site.effective,
|
|
10626
|
-
instance: instance,
|
|
10627
|
-
window: window,
|
|
10628
|
-
guardDenial: guardDenial,
|
|
10629
|
-
predicateSatisfied: predicateSatisfied
|
|
10630
|
-
}), value = readFieldValue(instance, site);
|
|
10631
|
-
fields.push({
|
|
10632
|
-
scope: site.scope,
|
|
10633
|
-
...site.activity !== void 0 ? {
|
|
10634
|
-
activity: site.activity
|
|
10635
|
-
} : {},
|
|
10636
|
-
name: site.name,
|
|
10637
|
-
type: site.type,
|
|
10638
|
-
...site.title !== void 0 ? {
|
|
10639
|
-
title: site.title
|
|
10640
|
-
} : {},
|
|
10641
|
-
...site.validation !== void 0 ? {
|
|
10642
|
-
validation: site.validation
|
|
10643
|
-
} : {},
|
|
10644
|
-
...site.roles !== void 0 ? {
|
|
10645
|
-
roles: site.roles,
|
|
10646
|
-
...definition.roleAliases !== void 0 ? {
|
|
10647
|
-
roleAliases: definition.roleAliases
|
|
10648
|
-
} : {}
|
|
10649
|
-
} : {},
|
|
10650
|
-
value: value,
|
|
10651
|
-
editable: reason === void 0,
|
|
10652
|
-
...reason !== void 0 ? {
|
|
10653
|
-
disabledReason: reason
|
|
10654
|
-
} : {},
|
|
10655
|
-
...fieldProvenance(instance, site.ref),
|
|
10656
|
-
...insight !== void 0 ? {
|
|
10657
|
-
insight: insight
|
|
10658
|
-
} : {}
|
|
10659
|
-
});
|
|
10660
|
-
}
|
|
10936
|
+
const fields = [];
|
|
10937
|
+
for (const site of editableFieldsInStage(args.definition, args.stage)) fields.push(await evaluateEditableField(args, site));
|
|
10661
10938
|
return fields;
|
|
10662
10939
|
}
|
|
10663
10940
|
|
|
10941
|
+
async function evaluateEditableField(args, site) {
|
|
10942
|
+
const {instance: instance, definition: definition, snapshot: snapshot, scope: scope, scopeForActivity: scopeForActivity, guardDenial: guardDenial, sites: sites} = args, window = fieldWindowOpen(instance, site), insight = await editPredicateInsight({
|
|
10943
|
+
site: site,
|
|
10944
|
+
snapshot: snapshot,
|
|
10945
|
+
scope: scope,
|
|
10946
|
+
scopeForActivity: scopeForActivity,
|
|
10947
|
+
sites: sites
|
|
10948
|
+
}), predicateSatisfied = insight === void 0 || insight.outcome === "satisfied", reason = editDisabledReason({
|
|
10949
|
+
effective: site.effective,
|
|
10950
|
+
instance: instance,
|
|
10951
|
+
window: window,
|
|
10952
|
+
guardDenial: guardDenial,
|
|
10953
|
+
predicateSatisfied: predicateSatisfied
|
|
10954
|
+
});
|
|
10955
|
+
return {
|
|
10956
|
+
scope: site.scope,
|
|
10957
|
+
...site.activity !== void 0 ? {
|
|
10958
|
+
activity: site.activity
|
|
10959
|
+
} : {},
|
|
10960
|
+
name: site.name,
|
|
10961
|
+
type: site.type,
|
|
10962
|
+
...site.title !== void 0 ? {
|
|
10963
|
+
title: site.title
|
|
10964
|
+
} : {},
|
|
10965
|
+
...site.validation !== void 0 ? {
|
|
10966
|
+
validation: site.validation
|
|
10967
|
+
} : {},
|
|
10968
|
+
...site.roles !== void 0 ? {
|
|
10969
|
+
roles: site.roles,
|
|
10970
|
+
...definition.roleAliases !== void 0 ? {
|
|
10971
|
+
roleAliases: definition.roleAliases
|
|
10972
|
+
} : {}
|
|
10973
|
+
} : {},
|
|
10974
|
+
value: readFieldValue(instance, site),
|
|
10975
|
+
editable: reason === void 0,
|
|
10976
|
+
...reason !== void 0 ? {
|
|
10977
|
+
disabledReason: reason
|
|
10978
|
+
} : {},
|
|
10979
|
+
...fieldProvenance(instance, site.ref),
|
|
10980
|
+
...insight !== void 0 ? {
|
|
10981
|
+
insight: insight
|
|
10982
|
+
} : {}
|
|
10983
|
+
};
|
|
10984
|
+
}
|
|
10985
|
+
|
|
10664
10986
|
async function editPredicateInsight(args) {
|
|
10665
10987
|
const {site: site, snapshot: snapshot, scope: scope, scopeForActivity: scopeForActivity, sites: sites} = args;
|
|
10666
10988
|
if (typeof site.effective != "string") return;
|
|
@@ -10684,14 +11006,10 @@ async function editPredicateInsight(args) {
|
|
|
10684
11006
|
async function forecastSubjectDenials(args) {
|
|
10685
11007
|
const {instance: instance, snapshot: snapshot, resourceGrants: resourceGrants} = args;
|
|
10686
11008
|
if (resourceGrants === void 0 || resourceGrants.size === 0) return [];
|
|
10687
|
-
const denials = [],
|
|
10688
|
-
for (const {ref: ref, parsed: parsed, resource: resource} of
|
|
10689
|
-
|
|
10690
|
-
|
|
10691
|
-
const access = resourceGrants.get(resourceGdr(resource));
|
|
10692
|
-
if (access === void 0) continue;
|
|
10693
|
-
const doc = snapshot.docs.find(d => d._id === ref.id);
|
|
10694
|
-
doc !== void 0 && await subjectUpdateAllowed({
|
|
11009
|
+
const denials = [], subjects = new Map(foreignSubjectRefs(instance).map(subject => [ subject.ref.id, subject ]));
|
|
11010
|
+
for (const {ref: ref, parsed: parsed, resource: resource} of subjects.values()) {
|
|
11011
|
+
const access = resourceGrants.get(resourceGdr(resource)), doc = snapshot.docs.find(d => d._id === ref.id);
|
|
11012
|
+
access === void 0 || doc === void 0 || await subjectUpdateAllowed({
|
|
10695
11013
|
doc: doc,
|
|
10696
11014
|
parsed: parsed,
|
|
10697
11015
|
grants: access.grants,
|
|
@@ -10724,13 +11042,13 @@ async function subjectUpdateAllowed(args) {
|
|
|
10724
11042
|
}
|
|
10725
11043
|
|
|
10726
11044
|
async function evaluateActivity(args) {
|
|
10727
|
-
const {activity: activity, statusEntry: statusEntry, instance: instance, snapshot: snapshot, activityScope: activityScope, cascadeActivityScope: cascadeActivityScope, stageHasExits: stageHasExits, guardDenial: guardDenial, subjectPermissionReason: subjectPermissionReason, sites: sites, autonomy: autonomy, fireConsequence: fireConsequence} = args, status = statusEntry?.status ?? "skipped", assigned = activityScope.assigned === !0, {unmetRequirements:
|
|
11045
|
+
const {activity: activity, statusEntry: statusEntry, instance: instance, snapshot: snapshot, activityScope: activityScope, cascadeActivityScope: cascadeActivityScope, stageHasExits: stageHasExits, guardDenial: guardDenial, subjectPermissionReason: subjectPermissionReason, requiredDocuments: requiredDocuments, sites: sites, autonomy: autonomy, fireConsequence: fireConsequence} = args, status = statusEntry?.status ?? "skipped", assigned = activityScope.assigned === !0, {unmetRequirements: activityRequirements, ...conditionInsights} = await explainActivityConditions({
|
|
10728
11046
|
activity: activity,
|
|
10729
11047
|
activityScope: activityScope,
|
|
10730
11048
|
cascadeActivityScope: cascadeActivityScope,
|
|
10731
11049
|
snapshot: snapshot,
|
|
10732
11050
|
sites: sites
|
|
10733
|
-
}), requirementsReason = unmetRequirements.length > 0 ? {
|
|
11051
|
+
}), unmetRequirements = [ ...requiredDocuments, ...activityRequirements ], requirementsReason = unmetRequirements.length > 0 ? {
|
|
10734
11052
|
kind: "requirements-unmet",
|
|
10735
11053
|
unmetRequirements: unmetRequirements
|
|
10736
11054
|
} : void 0, actions = [];
|
|
@@ -11106,6 +11424,46 @@ function claimReleasedEntry(args) {
|
|
|
11106
11424
|
};
|
|
11107
11425
|
}
|
|
11108
11426
|
|
|
11427
|
+
const RENEW_MAX_ATTEMPTS = 3;
|
|
11428
|
+
|
|
11429
|
+
async function claimOf(args) {
|
|
11430
|
+
const {client: client, tag: tag, instanceId: instanceId, effectKey: effectKey} = args, instance = await reload({
|
|
11431
|
+
client: client,
|
|
11432
|
+
instanceId: instanceId,
|
|
11433
|
+
tag: tag
|
|
11434
|
+
});
|
|
11435
|
+
return {
|
|
11436
|
+
instance: instance,
|
|
11437
|
+
claim: instance.pendingEffects.find(e => e._key === effectKey)?.claim
|
|
11438
|
+
};
|
|
11439
|
+
}
|
|
11440
|
+
|
|
11441
|
+
async function claimStillHeld(args) {
|
|
11442
|
+
const {claimToken: claimToken, ...where} = args, {claim: claim} = await claimOf(where);
|
|
11443
|
+
return claim?.claimToken === claimToken;
|
|
11444
|
+
}
|
|
11445
|
+
|
|
11446
|
+
async function renewClaimLease(args) {
|
|
11447
|
+
const {client: client, tag: tag, instanceId: instanceId, effectKey: effectKey, claimToken: claimToken, holdMs: holdMs, clock: clock} = args;
|
|
11448
|
+
for (let attempt = 1; attempt <= RENEW_MAX_ATTEMPTS; attempt++) {
|
|
11449
|
+
const {instance: instance, claim: claim} = await claimOf({
|
|
11450
|
+
client: client,
|
|
11451
|
+
tag: tag,
|
|
11452
|
+
instanceId: instanceId,
|
|
11453
|
+
effectKey: effectKey
|
|
11454
|
+
});
|
|
11455
|
+
if (claim?.claimToken !== claimToken) return;
|
|
11456
|
+
const until = addMs(clock(), holdMs);
|
|
11457
|
+
try {
|
|
11458
|
+
return await client.patch(instance._id).ifRevisionId(instance._rev).set({
|
|
11459
|
+
[`pendingEffects[_key=="${effectKey}"].claim.leaseExpiresAt`]: until
|
|
11460
|
+
}).commit(SYNC_COMMIT), until;
|
|
11461
|
+
} catch (error) {
|
|
11462
|
+
if (!isRevisionConflict(error)) throw error;
|
|
11463
|
+
}
|
|
11464
|
+
}
|
|
11465
|
+
}
|
|
11466
|
+
|
|
11109
11467
|
const SWEEP_MAX_ATTEMPTS = 5;
|
|
11110
11468
|
|
|
11111
11469
|
async function sweepStaleClaims(args) {
|
|
@@ -11153,7 +11511,7 @@ function isProjectRole(value) {
|
|
|
11153
11511
|
|
|
11154
11512
|
async function projectRoleNames(request, projectId) {
|
|
11155
11513
|
const result = await request({
|
|
11156
|
-
|
|
11514
|
+
url: `/projects/${encodeURIComponent(projectId)}/roles`
|
|
11157
11515
|
});
|
|
11158
11516
|
if (!Array.isArray(result) || !result.every(isProjectRole)) throw new Error(`Project role catalog response is invalid for project "${projectId}"`);
|
|
11159
11517
|
return new Set(result.map(role => role.name));
|
|
@@ -11349,7 +11707,7 @@ async function validateDefinitionRoles(args) {
|
|
|
11349
11707
|
const references = args.definitions.flatMap(definitionRoleReferences);
|
|
11350
11708
|
if (references.length === 0) /* @__PURE__ */ return new Map;
|
|
11351
11709
|
if (args.client.request === void 0) throw new Error("workflow.deployDefinitions: definitions reference project roles, but the client cannot read the project role catalog");
|
|
11352
|
-
const projectId = roleCatalogProjectId(args.client, args.workflowResource), [known, members] = await Promise.all([ projectRoleNames(args.client.request, projectId),
|
|
11710
|
+
const projectId = roleCatalogProjectId(args.client, args.workflowResource), [known, members] = await Promise.all([ projectRoleNames(args.client.request, projectId), _requestProjectMembers(args.client.request, projectId) ]), unknown = references.filter(reference => !known.has(reference.role));
|
|
11353
11711
|
if (unknown.length > 0) {
|
|
11354
11712
|
const lines = unknown.map(({definition: definition, path: path, role: role}) => ` - ${definition}: ${path} references unknown role "${role}"`);
|
|
11355
11713
|
throw new Error(`workflow.deployDefinitions: unknown project roles for project "${projectId}":\n${lines.join(`\n`)}`);
|
|
@@ -11479,7 +11837,7 @@ function refsOf(def) {
|
|
|
11479
11837
|
}
|
|
11480
11838
|
|
|
11481
11839
|
function hashDefinitionContent(def) {
|
|
11482
|
-
const canonical = stableStringify(def);
|
|
11840
|
+
const canonical = stableStringify(withoutAuthoringRuntime(def));
|
|
11483
11841
|
let hash = 0xcbf29ce484222325n;
|
|
11484
11842
|
for (let i = 0; i < canonical.length; i++) hash ^= BigInt(canonical.charCodeAt(i)),
|
|
11485
11843
|
hash = hash * 0x100000001b3n & 0xffffffffffffffffn;
|
|
@@ -11492,7 +11850,7 @@ function planDefinitionDeploy({def: def, latest: latest, target: target}) {
|
|
|
11492
11850
|
definition: def,
|
|
11493
11851
|
workflowResource: target.workflowResource
|
|
11494
11852
|
});
|
|
11495
|
-
const expanded = expandResourceAliases(def, target.resourceAliases), contentHash = hashDefinitionContent(expanded), unchanged = latest !== void 0 && latest.contentHash === contentHash, version = unchanged ? latest.version : (latest?.version ?? 0) + 1, docId = definitionDocId({
|
|
11853
|
+
const expanded = withoutAuthoringRuntime(expandResourceAliases(def, target.resourceAliases)), contentHash = hashDefinitionContent(expanded), unchanged = latest !== void 0 && latest.contentHash === contentHash, version = unchanged ? latest.version : (latest?.version ?? 0) + 1, docId = definitionDocId({
|
|
11496
11854
|
tag: target.tag,
|
|
11497
11855
|
definition: expanded.name,
|
|
11498
11856
|
version: version
|
|
@@ -11549,10 +11907,17 @@ function isDocumentEnvelopeKey(key) {
|
|
|
11549
11907
|
return key.startsWith("_") || DEPLOY_STAMPED_KEYS.has(key);
|
|
11550
11908
|
}
|
|
11551
11909
|
|
|
11910
|
+
const AUTHORING_RUNTIME_KEY = "runtime";
|
|
11911
|
+
|
|
11912
|
+
function withoutAuthoringRuntime(def) {
|
|
11913
|
+
const content = Object.entries(def).filter(([key]) => key !== AUTHORING_RUNTIME_KEY);
|
|
11914
|
+
return Object.fromEntries(content);
|
|
11915
|
+
}
|
|
11916
|
+
|
|
11552
11917
|
function parseDefinitionInput(def, caller) {
|
|
11553
11918
|
const label = labelFor(caller, def);
|
|
11554
11919
|
if (def._type !== void 0 && def._type !== WORKFLOW_DEFINITION_TYPE) throw new Error(`${label}: expected a workflow definition or a "${WORKFLOW_DEFINITION_TYPE}" document, got _type "${String(def._type)}"`);
|
|
11555
|
-
const content = Object.fromEntries(Object.entries(def).filter(([key]) => !isDocumentEnvelopeKey(key)));
|
|
11920
|
+
const content = Object.fromEntries(Object.entries(withoutAuthoringRuntime(def)).filter(([key]) => !isDocumentEnvelopeKey(key)));
|
|
11556
11921
|
return parseStoredDefinition(content, label);
|
|
11557
11922
|
}
|
|
11558
11923
|
|
|
@@ -13472,7 +13837,7 @@ function pendingEntry(args) {
|
|
|
13472
13837
|
}
|
|
13473
13838
|
|
|
13474
13839
|
function createEffectCommitQueue(args) {
|
|
13475
|
-
const {effectKey: effectKey, claimToken: claimToken, commit: commit} = args, pending = [];
|
|
13840
|
+
const {effectKey: effectKey, claimToken: claimToken, attempt: attempt, commit: commit} = args, pending = [];
|
|
13476
13841
|
let admitted = 0, dead, closed = !1, tail = Promise.resolve();
|
|
13477
13842
|
function assertOpen() {
|
|
13478
13843
|
if (dead !== void 0) throw dead;
|
|
@@ -13527,7 +13892,7 @@ function createEffectCommitQueue(args) {
|
|
|
13527
13892
|
value: entry.latestValue
|
|
13528
13893
|
}
|
|
13529
13894
|
} ],
|
|
13530
|
-
idempotencyKey: `effect:${effectKey}:${claimToken}:progress:${coalesceKey}:${admitted}`,
|
|
13895
|
+
idempotencyKey: `effect:${effectKey}:${claimToken}:${attempt}:progress:${coalesceKey}:${admitted}`,
|
|
13531
13896
|
coalesceKey: coalesceKey,
|
|
13532
13897
|
latestValue: value
|
|
13533
13898
|
});
|
|
@@ -13537,6 +13902,29 @@ function createEffectCommitQueue(args) {
|
|
|
13537
13902
|
};
|
|
13538
13903
|
}
|
|
13539
13904
|
|
|
13905
|
+
function effectRetryPolicy(definition, effectName) {
|
|
13906
|
+
return findEffect(definition, effectName)?.retry;
|
|
13907
|
+
}
|
|
13908
|
+
|
|
13909
|
+
function retryWindowClosed(policy, elapsedMs) {
|
|
13910
|
+
return policy.expiryMs !== void 0 && elapsedMs >= policy.expiryMs;
|
|
13911
|
+
}
|
|
13912
|
+
|
|
13913
|
+
function nextRetryDelayMs(policy, at) {
|
|
13914
|
+
if (at.attempt >= policy.attempts) return;
|
|
13915
|
+
const delay = effectBackoffMs(policy, at.attempt);
|
|
13916
|
+
return retryWindowClosed(policy, at.elapsedMs + delay) ? void 0 : delay;
|
|
13917
|
+
}
|
|
13918
|
+
|
|
13919
|
+
function retryFailedDetail(args) {
|
|
13920
|
+
const window = args.windowClosed ? ", retry window expired" : "";
|
|
13921
|
+
return `failed after ${args.at.attempt} of ${args.attempts} attempts${window}: ${args.error.message}`;
|
|
13922
|
+
}
|
|
13923
|
+
|
|
13924
|
+
function retrySucceededDetail(args) {
|
|
13925
|
+
if (args.at.attempt !== 1) return `succeeded on attempt ${args.at.attempt} of ${args.attempts}`;
|
|
13926
|
+
}
|
|
13927
|
+
|
|
13540
13928
|
class MissingHandlerError extends WorkflowError {
|
|
13541
13929
|
info;
|
|
13542
13930
|
constructor(args) {
|
|
@@ -13619,7 +14007,7 @@ function isCancelledCompletion(data) {
|
|
|
13619
14007
|
}
|
|
13620
14008
|
|
|
13621
14009
|
async function drainEffectsInternal(args) {
|
|
13622
|
-
const {tag: tag, workflowResource: workflowResource, instanceId: instanceId, handlers: handlers, missingHandler: missingHandler, logger: logger, handlerClient: rawHandlerClient, handlerResourceClients: rawHandlerResourceClients} = args, cascadeTelemetry = drainCascadeTelemetry(args.telemetry), {client: client, resourceClients: resourceClients} = taggedScope(args, REQUEST_TAG.drain), leaseMs = args.leaseMs ?? DEFAULT_EFFECT_LEASE_MS, clock = args.clock ?? wallClock, handlerClient = effectHandlerClient(rawHandlerClient), handlerResourceClients = effectHandlerResolver(rawHandlerResourceClients), routeGdr = buildClientForGdr({
|
|
14010
|
+
const {tag: tag, workflowResource: workflowResource, instanceId: instanceId, handlers: handlers, missingHandler: missingHandler, logger: logger, handlerClient: rawHandlerClient, handlerResourceClients: rawHandlerResourceClients} = args, cascadeTelemetry = drainCascadeTelemetry(args.telemetry), {client: client, resourceClients: resourceClients} = taggedScope(args, REQUEST_TAG.drain), leaseMs = args.leaseMs ?? DEFAULT_EFFECT_LEASE_MS, clock = args.clock ?? wallClock, sleep = args.sleep ?? wallSleeper, handlerClient = effectHandlerClient(rawHandlerClient), handlerResourceClients = effectHandlerResolver(rawHandlerResourceClients), routeGdr = buildClientForGdr({
|
|
13623
14011
|
client: handlerClient,
|
|
13624
14012
|
workflowResource: workflowResource,
|
|
13625
14013
|
resourceClients: handlerResourceClients
|
|
@@ -13645,6 +14033,7 @@ async function drainEffectsInternal(args) {
|
|
|
13645
14033
|
log: log,
|
|
13646
14034
|
leaseMs: leaseMs,
|
|
13647
14035
|
clock: clock,
|
|
14036
|
+
sleep: sleep,
|
|
13648
14037
|
...executionContext !== void 0 ? {
|
|
13649
14038
|
executionContext: executionContext
|
|
13650
14039
|
} : {},
|
|
@@ -13652,14 +14041,14 @@ async function drainEffectsInternal(args) {
|
|
|
13652
14041
|
drainerActor: drainerActor,
|
|
13653
14042
|
clientFor: clientFor,
|
|
13654
14043
|
buckets: buckets,
|
|
13655
|
-
|
|
14044
|
+
handledKeys: /* @__PURE__ */ new Set
|
|
13656
14045
|
};
|
|
13657
14046
|
for (;await drainOneCandidate(pass); ) ;
|
|
13658
14047
|
return buckets;
|
|
13659
14048
|
}
|
|
13660
14049
|
|
|
13661
14050
|
async function drainOneCandidate(pass) {
|
|
13662
|
-
const {client: client, tag: tag, instanceId: instanceId, buckets: buckets,
|
|
14051
|
+
const {client: client, tag: tag, instanceId: instanceId, buckets: buckets, handledKeys: handledKeys} = pass, now = pass.clock(), before = await reload({
|
|
13663
14052
|
client: client,
|
|
13664
14053
|
instanceId: instanceId,
|
|
13665
14054
|
tag: tag
|
|
@@ -13668,7 +14057,7 @@ async function drainOneCandidate(pass) {
|
|
|
13668
14057
|
const candidate = findClaimableCandidate({
|
|
13669
14058
|
instance: before,
|
|
13670
14059
|
now: now,
|
|
13671
|
-
|
|
14060
|
+
handledKeys: handledKeys
|
|
13672
14061
|
});
|
|
13673
14062
|
if (candidate === void 0) return !1;
|
|
13674
14063
|
const handler = pass.handlers[candidate.name];
|
|
@@ -13677,7 +14066,7 @@ async function drainOneCandidate(pass) {
|
|
|
13677
14066
|
candidate: candidate,
|
|
13678
14067
|
instanceId: instanceId,
|
|
13679
14068
|
log: pass.log
|
|
13680
|
-
}), buckets.skipped.push(candidate),
|
|
14069
|
+
}), buckets.skipped.push(candidate), handledKeys.add(candidate._key), !0;
|
|
13681
14070
|
const claimed = await claimPendingEffect({
|
|
13682
14071
|
client: client,
|
|
13683
14072
|
instance: before,
|
|
@@ -13690,11 +14079,15 @@ async function drainOneCandidate(pass) {
|
|
|
13690
14079
|
} : {}
|
|
13691
14080
|
});
|
|
13692
14081
|
if (claimed === void 0) return !0;
|
|
13693
|
-
const outcome = await dispatchAndReport({
|
|
14082
|
+
const retry = effectRetryPolicy(parseDefinitionSnapshot(before), candidate.name), outcome = await dispatchAndReport({
|
|
13694
14083
|
handler: handler,
|
|
13695
14084
|
candidate: candidate,
|
|
13696
14085
|
claimToken: claimed.claimToken,
|
|
14086
|
+
...retry !== void 0 ? {
|
|
14087
|
+
retry: retry
|
|
14088
|
+
} : {},
|
|
13697
14089
|
leaseMs: pass.leaseMs,
|
|
14090
|
+
sleep: pass.sleep,
|
|
13698
14091
|
client: client,
|
|
13699
14092
|
handlerClient: pass.handlerClient,
|
|
13700
14093
|
tag: tag,
|
|
@@ -13712,50 +14105,80 @@ async function drainOneCandidate(pass) {
|
|
|
13712
14105
|
telemetry: pass.telemetry,
|
|
13713
14106
|
clock: pass.clock
|
|
13714
14107
|
});
|
|
13715
|
-
return buckets[outcome].push(candidate),
|
|
14108
|
+
return buckets[outcome].push(candidate), outcome === "lost" && handledKeys.add(candidate._key),
|
|
14109
|
+
!0;
|
|
13716
14110
|
}
|
|
13717
14111
|
|
|
13718
|
-
function findClaimableCandidate({instance: instance, now: now,
|
|
13719
|
-
return instance.pendingEffects.find(e => (e.claim === void 0 || isClaimExpired(e.claim, now)) && !
|
|
14112
|
+
function findClaimableCandidate({instance: instance, now: now, handledKeys: handledKeys}) {
|
|
14113
|
+
return instance.pendingEffects.find(e => (e.claim === void 0 || isClaimExpired(e.claim, now)) && !handledKeys.has(e._key));
|
|
13720
14114
|
}
|
|
13721
14115
|
|
|
13722
14116
|
async function dispatchAndReport(args) {
|
|
13723
|
-
const {handler: handler, candidate: candidate, claimToken: claimToken, leaseMs: leaseMs, client: client, handlerClient: handlerClient, tag: tag, workflowResource: workflowResource, resourceClients: resourceClients, instanceId: instanceId, clientFor: clientFor, logger: logger, log: log, executionContext: executionContext, telemetry: telemetry, clock: clock} = args,
|
|
13724
|
-
effectKey: candidate._key,
|
|
13725
|
-
claimToken: claimToken,
|
|
13726
|
-
commit: async req => {
|
|
13727
|
-
await workflow.commitEffectOps({
|
|
13728
|
-
client: client,
|
|
13729
|
-
tag: tag,
|
|
13730
|
-
workflowResource: workflowResource,
|
|
13731
|
-
...resourceClients !== void 0 ? {
|
|
13732
|
-
resourceClients: resourceClients
|
|
13733
|
-
} : {},
|
|
13734
|
-
...executionContext !== void 0 ? {
|
|
13735
|
-
executionContext: executionContext
|
|
13736
|
-
} : {},
|
|
13737
|
-
...telemetry !== void 0 ? {
|
|
13738
|
-
telemetry: telemetry
|
|
13739
|
-
} : {},
|
|
13740
|
-
instanceId: instanceId,
|
|
13741
|
-
effectKey: candidate._key,
|
|
13742
|
-
claimToken: claimToken,
|
|
13743
|
-
ops: req.ops,
|
|
13744
|
-
idempotencyKey: req.idempotencyKey,
|
|
13745
|
-
leaseMs: leaseMs,
|
|
13746
|
-
clock: clock
|
|
13747
|
-
});
|
|
13748
|
-
}
|
|
13749
|
-
}), {outputs: outputs, ops: ops, dispatchError: dispatchError} = await dispatchEffect({
|
|
14117
|
+
const {handler: handler, candidate: candidate, claimToken: claimToken, retry: retry, leaseMs: leaseMs, sleep: sleep, client: client, handlerClient: handlerClient, tag: tag, workflowResource: workflowResource, resourceClients: resourceClients, instanceId: instanceId, clientFor: clientFor, logger: logger, log: log, executionContext: executionContext, telemetry: telemetry, clock: clock} = args, attemptOnce = attempt => dispatchEffect({
|
|
13750
14118
|
handler: handler,
|
|
13751
14119
|
candidate: candidate,
|
|
13752
|
-
queue:
|
|
14120
|
+
queue: createEffectCommitQueue({
|
|
14121
|
+
effectKey: candidate._key,
|
|
14122
|
+
claimToken: claimToken,
|
|
14123
|
+
attempt: attempt,
|
|
14124
|
+
commit: async req => {
|
|
14125
|
+
await workflow.commitEffectOps({
|
|
14126
|
+
client: client,
|
|
14127
|
+
tag: tag,
|
|
14128
|
+
workflowResource: workflowResource,
|
|
14129
|
+
...resourceClients !== void 0 ? {
|
|
14130
|
+
resourceClients: resourceClients
|
|
14131
|
+
} : {},
|
|
14132
|
+
...executionContext !== void 0 ? {
|
|
14133
|
+
executionContext: executionContext
|
|
14134
|
+
} : {},
|
|
14135
|
+
...telemetry !== void 0 ? {
|
|
14136
|
+
telemetry: telemetry
|
|
14137
|
+
} : {},
|
|
14138
|
+
instanceId: instanceId,
|
|
14139
|
+
effectKey: candidate._key,
|
|
14140
|
+
claimToken: claimToken,
|
|
14141
|
+
ops: req.ops,
|
|
14142
|
+
idempotencyKey: req.idempotencyKey,
|
|
14143
|
+
leaseMs: leaseMs,
|
|
14144
|
+
clock: clock
|
|
14145
|
+
});
|
|
14146
|
+
}
|
|
14147
|
+
}),
|
|
13753
14148
|
ctx: {
|
|
13754
14149
|
client: handlerClient,
|
|
13755
14150
|
clientFor: clientFor,
|
|
13756
14151
|
instanceId: instanceId,
|
|
13757
14152
|
logger: logger
|
|
13758
14153
|
}
|
|
14154
|
+
}), claimed = {
|
|
14155
|
+
client: client,
|
|
14156
|
+
tag: tag,
|
|
14157
|
+
instanceId: instanceId,
|
|
14158
|
+
effectKey: candidate._key,
|
|
14159
|
+
claimToken: claimToken
|
|
14160
|
+
}, run = await runRetryPolicy({
|
|
14161
|
+
attemptOnce: attemptOnce,
|
|
14162
|
+
...retry !== void 0 ? {
|
|
14163
|
+
retry: retry
|
|
14164
|
+
} : {},
|
|
14165
|
+
clock: clock,
|
|
14166
|
+
sleep: sleep,
|
|
14167
|
+
holdThrough: holdMs => renewClaimLease({
|
|
14168
|
+
...claimed,
|
|
14169
|
+
holdMs: holdMs,
|
|
14170
|
+
clock: clock
|
|
14171
|
+
}),
|
|
14172
|
+
stillHeld: () => claimStillHeld(claimed),
|
|
14173
|
+
leaseMs: leaseMs
|
|
14174
|
+
});
|
|
14175
|
+
if (run.abandoned !== void 0) return log.warn(run.abandoned === "lease" ? `Effect "${candidate.name}" could not hold its claim between retry attempts — the run stopped with attempts left` : `Effect "${candidate.name}" was settled by another party during a retry backoff — the run stopped without dispatching again`, {
|
|
14176
|
+
effectKey: candidate._key,
|
|
14177
|
+
instanceId: instanceId
|
|
14178
|
+
}), "lost";
|
|
14179
|
+
const {outputs: outputs, ops: ops, dispatchError: dispatchError} = run.dispatch, detail = retry === void 0 ? void 0 : completionDetail({
|
|
14180
|
+
run: run,
|
|
14181
|
+
retry: retry
|
|
13759
14182
|
});
|
|
13760
14183
|
try {
|
|
13761
14184
|
await reportEffectOutcome({
|
|
@@ -13776,6 +14199,9 @@ async function dispatchAndReport(args) {
|
|
|
13776
14199
|
outputs: outputs,
|
|
13777
14200
|
ops: ops,
|
|
13778
14201
|
dispatchError: dispatchError,
|
|
14202
|
+
...detail !== void 0 ? {
|
|
14203
|
+
detail: detail
|
|
14204
|
+
} : {},
|
|
13779
14205
|
clock: clock
|
|
13780
14206
|
});
|
|
13781
14207
|
} catch (error) {
|
|
@@ -13788,6 +14214,71 @@ async function dispatchAndReport(args) {
|
|
|
13788
14214
|
return dispatchError === void 0 ? "drained" : "failed";
|
|
13789
14215
|
}
|
|
13790
14216
|
|
|
14217
|
+
async function runRetryPolicy(args) {
|
|
14218
|
+
const {attemptOnce: attemptOnce, retry: retry, clock: clock} = args, startedAt = Date.parse(clock()), elapsed = () => Date.parse(clock()) - startedAt;
|
|
14219
|
+
let attempt = 1, dispatch = await attemptOnce(attempt);
|
|
14220
|
+
for (;dispatch.dispatchError !== void 0 && retry !== void 0; ) {
|
|
14221
|
+
const at = {
|
|
14222
|
+
attempt: attempt,
|
|
14223
|
+
elapsedMs: elapsed()
|
|
14224
|
+
}, stop = await waitForNextAttempt({
|
|
14225
|
+
retry: retry,
|
|
14226
|
+
at: at,
|
|
14227
|
+
elapsed: elapsed,
|
|
14228
|
+
pace: args
|
|
14229
|
+
});
|
|
14230
|
+
if (stop !== void 0) return {
|
|
14231
|
+
...stop,
|
|
14232
|
+
dispatch: dispatch,
|
|
14233
|
+
at: at
|
|
14234
|
+
};
|
|
14235
|
+
attempt += 1, dispatch = await attemptOnce(attempt);
|
|
14236
|
+
}
|
|
14237
|
+
return {
|
|
14238
|
+
dispatch: dispatch,
|
|
14239
|
+
at: {
|
|
14240
|
+
attempt: attempt,
|
|
14241
|
+
elapsedMs: elapsed()
|
|
14242
|
+
},
|
|
14243
|
+
windowClosed: !1
|
|
14244
|
+
};
|
|
14245
|
+
}
|
|
14246
|
+
|
|
14247
|
+
async function waitForNextAttempt(args) {
|
|
14248
|
+
const {retry: retry, at: at, elapsed: elapsed} = args, {clock: clock, sleep: sleep, holdThrough: holdThrough, stillHeld: stillHeld, leaseMs: leaseMs} = args.pace, delay = nextRetryDelayMs(retry, at);
|
|
14249
|
+
if (delay === void 0) return {
|
|
14250
|
+
windowClosed: at.attempt < retry.attempts
|
|
14251
|
+
};
|
|
14252
|
+
const heldUntil = await holdThrough(delay + leaseMs);
|
|
14253
|
+
if (heldUntil === void 0 || hasPassed(heldUntil, addMs(clock(), delay))) return {
|
|
14254
|
+
windowClosed: !1,
|
|
14255
|
+
abandoned: "lease"
|
|
14256
|
+
};
|
|
14257
|
+
if (retryWindowClosed(retry, elapsed() + delay)) return {
|
|
14258
|
+
windowClosed: !0
|
|
14259
|
+
};
|
|
14260
|
+
if (await sleep(delay), !await stillHeld()) return {
|
|
14261
|
+
windowClosed: !1,
|
|
14262
|
+
abandoned: "settled"
|
|
14263
|
+
};
|
|
14264
|
+
if (retryWindowClosed(retry, elapsed())) return {
|
|
14265
|
+
windowClosed: !0
|
|
14266
|
+
};
|
|
14267
|
+
}
|
|
14268
|
+
|
|
14269
|
+
function completionDetail(args) {
|
|
14270
|
+
const {run: run, retry: retry} = args, {dispatchError: dispatchError} = run.dispatch;
|
|
14271
|
+
return dispatchError === void 0 ? retrySucceededDetail({
|
|
14272
|
+
at: run.at,
|
|
14273
|
+
attempts: retry.attempts
|
|
14274
|
+
}) : retryFailedDetail({
|
|
14275
|
+
at: run.at,
|
|
14276
|
+
attempts: retry.attempts,
|
|
14277
|
+
error: dispatchError,
|
|
14278
|
+
windowClosed: run.windowClosed
|
|
14279
|
+
});
|
|
14280
|
+
}
|
|
14281
|
+
|
|
13791
14282
|
async function reportEffectOutcome(args) {
|
|
13792
14283
|
const {outputs: outputs, ops: ops, dispatchError: dispatchError, resourceClients: resourceClients, ...rest} = args;
|
|
13793
14284
|
await workflow.completeEffect({
|
|
@@ -14078,6 +14569,9 @@ function createInstanceSession(args) {
|
|
|
14078
14569
|
definition: definitionOf(),
|
|
14079
14570
|
actor: actor,
|
|
14080
14571
|
snapshot: snapshotFrom(held, normalizedSelf),
|
|
14572
|
+
documentAvailability: documentAvailabilityReader({
|
|
14573
|
+
clientForGdr: evalScope.clientForGdr
|
|
14574
|
+
}),
|
|
14081
14575
|
guards: guards,
|
|
14082
14576
|
resourceGrants: resourceGrants,
|
|
14083
14577
|
guardDereference: clientGuardDereference(evalScope.client),
|
|
@@ -14491,6 +14985,9 @@ function createEngine(args) {
|
|
|
14491
14985
|
telemetry: telemetry,
|
|
14492
14986
|
...args.effects?.leaseMs !== void 0 ? {
|
|
14493
14987
|
leaseMs: args.effects.leaseMs
|
|
14988
|
+
} : {},
|
|
14989
|
+
...args.sleep !== void 0 ? {
|
|
14990
|
+
sleep: args.sleep
|
|
14494
14991
|
} : {}
|
|
14495
14992
|
}), drained = result.drained;
|
|
14496
14993
|
return (drained.length > 0 || emptyDrainDue()) && telemetry.log(WorkflowEffectsDrained, {
|
|
@@ -14512,27 +15009,43 @@ function createEngine(args) {
|
|
|
14512
15009
|
const CONSENT_TAG = "telemetry.consent", BATCH_TAG = "telemetry.batch";
|
|
14513
15010
|
|
|
14514
15011
|
function createTelemetryIntake(args) {
|
|
14515
|
-
const {client: client, projectId: projectId, denied: denied = !1} = args;
|
|
15012
|
+
const {client: client, projectId: projectId, denied: denied = !1, context: context} = args;
|
|
14516
15013
|
let cachedConsent;
|
|
14517
15014
|
return {
|
|
14518
15015
|
resolveConsent: async () => denied ? {
|
|
14519
15016
|
status: "denied"
|
|
14520
15017
|
} : (cachedConsent !== void 0 || (cachedConsent = await client.request({
|
|
14521
|
-
|
|
15018
|
+
url: "/intake/telemetry-status",
|
|
14522
15019
|
tag: CONSENT_TAG
|
|
14523
15020
|
})), cachedConsent),
|
|
14524
15021
|
sendEvents: batch => client.request({
|
|
14525
|
-
|
|
15022
|
+
url: "/intake/batch",
|
|
14526
15023
|
method: "POST",
|
|
14527
15024
|
body: {
|
|
14528
15025
|
projectId: projectId,
|
|
14529
|
-
batch: batch
|
|
15026
|
+
batch: context === void 0 ? batch : batch.map(event => withContext(event, context))
|
|
14530
15027
|
},
|
|
14531
15028
|
tag: BATCH_TAG
|
|
14532
15029
|
})
|
|
14533
15030
|
};
|
|
14534
15031
|
}
|
|
14535
15032
|
|
|
15033
|
+
function withContext(event, context) {
|
|
15034
|
+
if (!isRecord(event)) return event;
|
|
15035
|
+
const existing = isRecord(event.context) ? event.context : {};
|
|
15036
|
+
return {
|
|
15037
|
+
...event,
|
|
15038
|
+
context: {
|
|
15039
|
+
...existing,
|
|
15040
|
+
...context
|
|
15041
|
+
}
|
|
15042
|
+
};
|
|
15043
|
+
}
|
|
15044
|
+
|
|
15045
|
+
function _resolveTelemetryEnvironment(nodeEnv, fallback) {
|
|
15046
|
+
return nodeEnv === "production" ? "production" : nodeEnv === "development" || nodeEnv === "test" ? "development" : fallback;
|
|
15047
|
+
}
|
|
15048
|
+
|
|
14536
15049
|
function isTelemetryEnvDenied(env) {
|
|
14537
15050
|
return isTrueish(env.CI) || isTrueish(env.DO_NOT_TRACK);
|
|
14538
15051
|
}
|
|
@@ -14555,6 +15068,16 @@ function isTrueish(value) {
|
|
|
14555
15068
|
return normalized !== "0" && normalized !== "false";
|
|
14556
15069
|
}
|
|
14557
15070
|
|
|
15071
|
+
function summary(documents, deleted) {
|
|
15072
|
+
if (documents.length === 0) return "";
|
|
15073
|
+
const titles = [ ...new Set(documents.map(document => document.title ?? document.target.field)) ].map(title => `“${title}”`).join(", ");
|
|
15074
|
+
return documents.length === 1 ? `A document selected for ${titles} ${deleted ? "has been deleted" : "can’t be read by this workflow"}` : `${documents.length} documents selected for ${titles} ${deleted ? "have been deleted" : "can’t be read by this workflow"}`;
|
|
15075
|
+
}
|
|
15076
|
+
|
|
15077
|
+
function _missingDocumentsSummary(documents) {
|
|
15078
|
+
return [ summary(documents.filter(document => document.availability === "deleted"), !0), summary(documents.filter(document => document.availability !== "deleted"), !1) ].filter(Boolean).join(". ");
|
|
15079
|
+
}
|
|
15080
|
+
|
|
14558
15081
|
function groupSitesOf(definition) {
|
|
14559
15082
|
const sites = [], workflow2 = declarationIndex({
|
|
14560
15083
|
groups: definition.groups,
|
|
@@ -15042,4 +15565,4 @@ function displayDescription(typeKey) {
|
|
|
15042
15565
|
if (typeKey) return DISPLAY[typeKey]?.description;
|
|
15043
15566
|
}
|
|
15044
15567
|
|
|
15045
|
-
export { ACTION_SEMANTICS, ACTIVITY_KINDS, ACTIVITY_KIND_DISPLAY, ACTOR_KINDS, ANONYMOUS_IDENTITY, AUTHORING_DISPLAY, ActionDisabledError, ActionParamsInvalidError, CONDITION_VARS, CONTEXT_ENTRY_DISPLAY, CascadeLimitError, ConcurrentCascadeError, ConcurrentCommitEffectOpsError, ConcurrentCompleteEffectError, ConcurrentEditFieldError, ConcurrentFireActionError, ContractViolationError, DATA_MODEL_CHANGES, DATA_MODEL_MAX_READER, DATA_MODEL_MIN_READER, DATA_MODEL_VERSION, DECISION_SEMANTICS, DEFAULT_CONTENT_PERSPECTIVE, DEFAULT_EFFECT_LEASE_MS, DEFAULT_IDEMPOTENCY_TTL_MS, DEFAULT_TRANSITION_WHEN, DISPLAY, DOCUMENT_VALUE_PERMISSIONS, DRIVER_KINDS, DRIVER_KIND_DISPLAY, DefinitionInUseError, DefinitionNotFoundError, EFFECT_COMMIT_DISPATCH_CAP, EFFECT_COMMIT_QUEUE_DEPTH, ENGINE_API_VERSION, EXECUTION_KINDS, EXECUTOR_CLASSIFICATIONS, EXECUTOR_CLASSIFICATION_DISPLAY, EditFieldDeniedError, EffectCommitQueueOverflowError, EffectNotFoundError, EffectOpsInvalidError, EffectOutputsInvalidError, FIELD_KIND_DISPLAY, FILTER_SCOPE_VARS, FieldValueShapeError, GROUP_KINDS, GROUP_KIND_DISPLAY, GUARD_DOC_TYPE, GUARD_OWNER, GUARD_PREDICATE_VARS, HISTORY_DISPLAY, InitialFieldsInvalidError, InstanceNotFoundError, MAX_COUNTERFACTUAL_INDEX2 as MAX_COUNTERFACTUAL_INDEX, MissingHandlerError, ModelVersionAheadError, MutationGuardDeniedError, MutationGuardDocSchema, NEUTRAL_MARK, OP_DISPLAY, OUTCOME_MARKS, PartialGuardDeployError, PersistedDocShapeError, READER_MODEL_ROLLOUT_URL, RESERVED_CONDITION_VARS, ReaderModelAcknowledgementError, RefResourceUndeclaredError, RequiredFieldNotProvidedError, SIGNAL_SEMANTICS, START_FILTER_VARS, START_REQUIREMENT_VARS, SYSTEM_IDENTITY, SpawnContractsInvalidError, StaleEffectClaimError, StartNotAllowedError, StartNotPrimedError, StartNotSettledError, WORKFLOW_DEFINITION_TYPE, WORKFLOW_INSTANCE_TYPE, WorkflowActionFired, WorkflowActivityReset, WorkflowDefinitionDeleted, WorkflowDefinitionDeployed, WorkflowEffectCompleted, WorkflowEffectStateReported, WorkflowEffectsDrained, WorkflowError, WorkflowFieldEdited, WorkflowInstanceAborted, WorkflowInstancePreviewSchema, WorkflowInstanceSchema, WorkflowInstanceStarted, WorkflowInstanceTicked, WorkflowStageSet, WorkflowStageTransitioned, WorkflowStateDivergedError, abortReason, acceptsDocumentType, aclPathForResource, actionDisabledDetail, actionRendering, actionVerdict, activeAssignmentMembers, activityAutonomyOf, actorFulfillsRole, actorMatchesAssignment, analyzeCondition2 as analyzeCondition, applicableDefinitions, assertReadableModel, assertReaderModelAcknowledgement, assignmentMatch, assignmentMembers, assignmentPrefilter, assignmentState, assignmentStateCounts, atomReadsDataset2 as atomReadsDataset, autonomySummary, availableActions, buildInitialFields, buildSnapshot, checklistLines, classifyPrincipalId, clientConfigFromResource, clientGuardDereference, clientProjectUserDirectory, compileGuards, computeDiffEntries, conditionFieldReadNames, conditionSitesOf, contentDocQuery, contentDraftFallback, contentReleaseName, contextMap, createEngine, createTelemetryIntake, datasetResourceParts, defaultLoggerFactory, definitionDeployedData, definitionLookupGroq, definitionRoleNames, 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, formatRead2 as formatRead, gdrFromResource, gdrRef, gdrUri, groupMembershipNames, groupSitesOf, guardMatches, guardsForDefinition, guardsForInstance, guardsForResource, guillemets2 as guillemets, hasSingleSubjectRequirement, hashDefinitionContent, humanize2 as humanize, identityMatchesAssignment, inFlightFilter, initialFieldIssues, instanceAssignmentStateCounts, instanceChangesQuery, instanceDocId, instanceGuardQuery, instancePreviewsQuery, instanceWatchesDocument, instancesGuardQuery, instancesQuery, isCascadeFired, isClaimExpired, isClientProjectUser, isComparisonOp, isDefinitionApplicable, isFilterScopedOut, isGdr, isInputSourced, isNotesEntry, isProjectUserNotFoundError, isRevisionConflict, isSingleDocRefEntry, isSingleDocRefKind, isStartableDefinition, isSubjectEntry, isTelemetryEnvDenied, isTerminalActivityStatus, isTerminalStage, isTodoListEntry, isTodoListItem, isUnprimed, lakeGuardId, lakePrincipalId, latestDefinitionsGroq, latestDeployedDefinitions, lintEffectOutputs, minReaderModelOf, missingRequiredInputs, modelVersionOf, narrateAutonomyWaits, noopTelemetry, openActivityAssignments, parentRef, parseDefinitionInput, parseDefinitionSnapshot, parseDefinitionSnapshotValue, parseGdr, parseGuardDocument, parseInstanceDocument, parseInstancePreviewDocument, parseResourceGdr, processShellUserProperties, projectStartSliceRow, projectToWatchRef, quoted2 as quoted, readInstanceDoc, readInstancePreviewDoc, readsRaw, readsRootDocument, refCanvas, refDashboard, refDataset, refKindAcceptsTypes, refMediaLibrary, refsOf, rejectedRefTypes, releaseDocId, releaseRef, remediationsFor, requiredDefinitionReaderModel, requiredModelFeatures, requiredReaderModel, resolveAccess, resolveActor, resolveClientActor, resolveFieldEntry$1 as resolveFieldEntry, resolveUserAttributes, resourceAliasesToMap, resourceFromParsed, resourceGdr, retractStageGuards, sameResource, scalarValidationIssues, schemaTreeShape, sentenceCase, silentLogger, singleSubjectRequirementRefused, snapshotGuardDereference, 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 };
|
|
15568
|
+
export { ACTION_SEMANTICS, ACTIVITY_KINDS, ACTIVITY_KIND_DISPLAY, ACTOR_KINDS, ANONYMOUS_IDENTITY, AUTHORING_DISPLAY, ActionDisabledError, ActionParamsInvalidError, CONDITION_VARS, CONTEXT_ENTRY_DISPLAY, CascadeLimitError, ConcurrentCascadeError, ConcurrentCommitEffectOpsError, ConcurrentCompleteEffectError, ConcurrentEditFieldError, ConcurrentFireActionError, ContractViolationError, DATA_MODEL_CHANGES, DATA_MODEL_MAX_READER, DATA_MODEL_MIN_READER, DATA_MODEL_VERSION, DECISION_SEMANTICS, DEFAULT_CONTENT_PERSPECTIVE, DEFAULT_EFFECT_LEASE_MS, DEFAULT_IDEMPOTENCY_TTL_MS, DEFAULT_TRANSITION_WHEN, DISPLAY, DOCUMENT_VALUE_PERMISSIONS, DRIVER_KINDS, DRIVER_KIND_DISPLAY, DefinitionInUseError, DefinitionNotFoundError, EFFECT_COMMIT_DISPATCH_CAP, EFFECT_COMMIT_QUEUE_DEPTH, ENGINE_API_VERSION, EXECUTION_KINDS, EXECUTOR_CLASSIFICATIONS, EXECUTOR_CLASSIFICATION_DISPLAY, EditFieldDeniedError, EffectCommitQueueOverflowError, EffectNotFoundError, EffectOpsInvalidError, EffectOutputsInvalidError, FIELD_KIND_DISPLAY, FILTER_SCOPE_VARS, FieldValueShapeError, GROUP_KINDS, GROUP_KIND_DISPLAY, GUARD_DOC_TYPE, GUARD_OWNER, GUARD_PREDICATE_VARS, HISTORY_DISPLAY, InitialFieldsInvalidError, InstanceNotFoundError, MAX_COUNTERFACTUAL_INDEX2 as MAX_COUNTERFACTUAL_INDEX, MissingHandlerError, ModelVersionAheadError, MutationGuardDeniedError, MutationGuardDocSchema, NEUTRAL_MARK, OP_DISPLAY, OUTCOME_MARKS, PartialGuardDeployError, PersistedDocShapeError, READER_MODEL_ROLLOUT_URL, RESERVED_CONDITION_VARS, ReaderModelAcknowledgementError, RefResourceUndeclaredError, RequiredFieldNotProvidedError, SIGNAL_SEMANTICS, START_FILTER_VARS, START_REQUIREMENT_VARS, SYSTEM_IDENTITY, SpawnContractsInvalidError, StaleEffectClaimError, StartNotAllowedError, StartNotPrimedError, StartNotSettledError, WORKFLOW_DEFINITION_TYPE, WORKFLOW_INSTANCE_TYPE, WorkflowActionFired, WorkflowActivityReset, WorkflowDefinitionDeleted, WorkflowDefinitionDeployed, WorkflowEffectCompleted, WorkflowEffectStateReported, WorkflowEffectsDrained, WorkflowError, WorkflowFieldEdited, WorkflowInstanceAborted, WorkflowInstancePreviewSchema, WorkflowInstanceSchema, WorkflowInstanceStarted, WorkflowInstanceTicked, WorkflowStageSet, WorkflowStageTransitioned, WorkflowStateDivergedError, _additionalMissingDocuments, _fieldTargetLabel, _missingDocumentsSummary, _requestProjectMembers, _resolveTelemetryEnvironment, abortReason, acceptsDocumentType, aclPathForResource, actionDisabledDetail, actionRendering, actionVerdict, activeAssignmentMembers, activityAutonomyOf, actorFulfillsRole, actorMatchesAssignment, analyzeCondition2 as analyzeCondition, applicableDefinitions, assertReadableModel, assertReaderModelAcknowledgement, assignmentMatch, assignmentMembers, assignmentPrefilter, assignmentState, assignmentStateCounts, atomReadsDataset2 as atomReadsDataset, autonomySummary, availableActions, buildInitialFields, buildSnapshot, checklistLines, classifyPrincipalId, clientConfigFromResource, clientGuardDereference, clientProjectUserDirectory, compileGuards, computeDiffEntries, conditionFieldReadNames, conditionSitesOf, contentDocQuery, contentDraftFallback, contentReleaseName, contextMap, createEngine, createTelemetryIntake, datasetResourceParts, defaultLoggerFactory, definitionDeployedData, definitionLookupGroq, definitionRoleNames, 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, effectSites, entryDocRefs, errorMessage, evaluateFromSnapshot, evaluateMutationGuard, evaluateStartFilter, expandResourceAliases, explainCondition2 as explainCondition, explainStartRequirement, extractDocumentId, fieldTreeShape, findActivityNode, findCurrentActivityEntry, findOpenStageEntry, findStageNode, formatRead2 as formatRead, gdrFromResource, gdrRef, gdrUri, groupMembershipNames, groupSitesOf, guardMatches, guardsForDefinition, guardsForInstance, guardsForResource, guillemets2 as guillemets, hasSingleSubjectRequirement, hashDefinitionContent, humanize2 as humanize, identityMatchesAssignment, inFlightFilter, initialFieldIssues, instanceAssignmentStateCounts, instanceChangesQuery, instanceDocId, instanceGuardQuery, instancePreviewsQuery, instanceWatchesDocument, instancesGuardQuery, instancesQuery, isCascadeFired, isClaimExpired, isClientProjectUser, isComparisonOp, isDefinitionApplicable, isFilterScopedOut, isGdr, isInputSourced, isNotesEntry, isProjectUserNotFoundError, isRevisionConflict, isSingleDocRefEntry, isSingleDocRefKind, isStartableDefinition, isSubjectEntry, isTelemetryEnvDenied, isTerminalActivityStatus, isTerminalStage, isTodoListEntry, isTodoListItem, isUnprimed, lakeGuardId, lakePrincipalId, latestDefinitionsGroq, latestDeployedDefinitions, lintEffectOutputs, minReaderModelOf, missingRequiredInputs, modelVersionOf, narrateAutonomyWaits, noopTelemetry, openActivityAssignments, parentRef, parseDefinitionInput, parseDefinitionSnapshot, parseDefinitionSnapshotValue, parseGdr, parseGuardDocument, parseInstanceDocument, parseInstancePreviewDocument, parseResourceGdr, processShellUserProperties, projectStartSliceRow, projectToWatchRef, quoted2 as quoted, readInstanceDoc, readInstancePreviewDoc, readsRaw, readsRootDocument, refCanvas, refDashboard, refDataset, refKindAcceptsTypes, refMediaLibrary, refsOf, rejectedRefTypes, releaseDocId, releaseRef, remediationsFor, requiredDefinitionReaderModel, requiredModelFeatures, requiredReaderModel, resolveAccess, resolveActor, resolveClientActor, resolveFieldEntry$1 as resolveFieldEntry, resolveUserAttributes, resourceAliasesToMap, resourceFromParsed, resourceGdr, retractStageGuards, sameResource, scalarValidationIssues, schemaTreeShape, sentenceCase, silentLogger, singleSubjectRequirementRefused, snapshotGuardDereference, 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 };
|