@sanity/workflow-engine 0.29.0 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +51 -0
- package/DATAMODEL.md +67 -22
- package/dist/_chunks-cjs/invariants.cjs +286 -87
- package/dist/_chunks-es/invariants.js +281 -88
- package/dist/define.d.cts +289 -276
- package/dist/define.d.ts +289 -276
- package/dist/index.cjs +1297 -914
- package/dist/index.d.cts +915 -1053
- package/dist/index.d.ts +915 -1053
- package/dist/index.js +1116 -749
- package/package.json +3 -3
|
@@ -41,79 +41,6 @@ function andConditions(parts) {
|
|
|
41
41
|
if (present.length !== 0) return present.length === 1 ? present[0] : present.map(p => `(${p})`).join(" && ");
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
class WorkflowError extends Error {
|
|
45
|
-
kind;
|
|
46
|
-
constructor(kind, message, options) {
|
|
47
|
-
super(message, options), this.kind = kind;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
class ContractViolationError extends WorkflowError {
|
|
52
|
-
constructor(message) {
|
|
53
|
-
super("contract-violation", message), this.name = "ContractViolationError";
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
class InstanceNotFoundError extends WorkflowError {
|
|
58
|
-
instanceId;
|
|
59
|
-
constructor(args) {
|
|
60
|
-
super("instance-not-found", `Workflow instance ${args.instanceId} not found${args.detail ? ` (${args.detail})` : ""}`),
|
|
61
|
-
this.name = "InstanceNotFoundError", this.instanceId = args.instanceId;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
class DefinitionNotFoundError extends WorkflowError {
|
|
66
|
-
definition;
|
|
67
|
-
version;
|
|
68
|
-
constructor(args) {
|
|
69
|
-
super("definition-not-found", args.version !== void 0 ? `Workflow definition ${args.definition} v${args.version} not deployed` : `Workflow definition ${args.definition} has no deployed versions`),
|
|
70
|
-
this.name = "DefinitionNotFoundError", this.definition = args.definition, args.version !== void 0 && (this.version = args.version);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
class SpawnContractsInvalidError extends WorkflowError {
|
|
75
|
-
issues;
|
|
76
|
-
constructor(args) {
|
|
77
|
-
super("spawn-contracts-invalid", args.message), this.name = "SpawnContractsInvalidError",
|
|
78
|
-
this.issues = args.issues;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
class DefinitionInUseError extends WorkflowError {
|
|
83
|
-
definition;
|
|
84
|
-
blockedBy;
|
|
85
|
-
constructor(args) {
|
|
86
|
-
super("definition-in-use", definitionInUseMessage(args.definition, args.blockedBy)),
|
|
87
|
-
this.name = "DefinitionInUseError", this.definition = args.definition, this.blockedBy = args.blockedBy;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function definitionInUseMessage(definition, blockedBy) {
|
|
92
|
-
if (blockedBy.reason === "non-terminal-instances") {
|
|
93
|
-
const head = blockedBy.instanceIds.slice(0, 3).join(", "), preview = blockedBy.instanceIds.length > 3 ? `${head}, …` : head;
|
|
94
|
-
return `Cannot delete ${definition}: ${blockedBy.instanceIds.length} non-terminal instance(s) exist (${preview}). Pass cascade to abort them first — instances are aborted in place, never deleted.`;
|
|
95
|
-
}
|
|
96
|
-
const names = blockedBy.referrers.map(r => `${r.definition} v${r.version}`).join(", ");
|
|
97
|
-
return `Cannot delete ${definition}: still spawn-referenced by deployed definition(s) ${names}. Delete or redeploy the referrer(s) first.`;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
class EffectNotFoundError extends WorkflowError {
|
|
101
|
-
instanceId;
|
|
102
|
-
effectKey;
|
|
103
|
-
settled;
|
|
104
|
-
constructor(args) {
|
|
105
|
-
super("effect-not-found", effectNotFoundMessage(args)), this.name = "EffectNotFoundError",
|
|
106
|
-
this.instanceId = args.instanceId, this.effectKey = args.effectKey, args.settled !== void 0 && (this.settled = args.settled);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function effectNotFoundMessage(args) {
|
|
111
|
-
const base = `Pending effect "${args.effectKey}" not found on instance ${args.instanceId}`;
|
|
112
|
-
if (args.settled === void 0) return base;
|
|
113
|
-
const cause = args.settled.detail !== void 0 ? ` (${args.settled.detail})` : "";
|
|
114
|
-
return args.settled.status === "cancelled" ? `${base} — it was cancelled at ${args.settled.ranAt}${cause}` : `${base} — it already settled "${args.settled.status}" at ${args.settled.ranAt}${cause}`;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
44
|
const KNOWN_SCHEMES = /* @__PURE__ */ new Set([ "dataset", "canvas", "media-library", "dashboard" ]), KNOWN_SCHEMES_TEXT = [ ...KNOWN_SCHEMES ].join(", ");
|
|
118
45
|
|
|
119
46
|
class VersionSpecificDatasetGdrError extends Error {
|
|
@@ -329,6 +256,79 @@ function isGdr(value) {
|
|
|
329
256
|
return typeof value == "object" && value !== null && typeof value.id == "string" && typeof value.type == "string";
|
|
330
257
|
}
|
|
331
258
|
|
|
259
|
+
class WorkflowError extends Error {
|
|
260
|
+
kind;
|
|
261
|
+
constructor(kind, message, options) {
|
|
262
|
+
super(message, options), this.kind = kind;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
class ContractViolationError extends WorkflowError {
|
|
267
|
+
constructor(message) {
|
|
268
|
+
super("contract-violation", message), this.name = "ContractViolationError";
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
class InstanceNotFoundError extends WorkflowError {
|
|
273
|
+
instanceId;
|
|
274
|
+
constructor(args) {
|
|
275
|
+
super("instance-not-found", `Workflow instance ${args.instanceId} not found${args.detail ? ` (${args.detail})` : ""}`),
|
|
276
|
+
this.name = "InstanceNotFoundError", this.instanceId = args.instanceId;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
class DefinitionNotFoundError extends WorkflowError {
|
|
281
|
+
definition;
|
|
282
|
+
version;
|
|
283
|
+
constructor(args) {
|
|
284
|
+
super("definition-not-found", args.version !== void 0 ? `Workflow definition ${args.definition} v${args.version} not deployed` : `Workflow definition ${args.definition} has no deployed versions`),
|
|
285
|
+
this.name = "DefinitionNotFoundError", this.definition = args.definition, args.version !== void 0 && (this.version = args.version);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
class SpawnContractsInvalidError extends WorkflowError {
|
|
290
|
+
issues;
|
|
291
|
+
constructor(args) {
|
|
292
|
+
super("spawn-contracts-invalid", args.message), this.name = "SpawnContractsInvalidError",
|
|
293
|
+
this.issues = args.issues;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
class DefinitionInUseError extends WorkflowError {
|
|
298
|
+
definition;
|
|
299
|
+
blockedBy;
|
|
300
|
+
constructor(args) {
|
|
301
|
+
super("definition-in-use", definitionInUseMessage(args.definition, args.blockedBy)),
|
|
302
|
+
this.name = "DefinitionInUseError", this.definition = args.definition, this.blockedBy = args.blockedBy;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function definitionInUseMessage(definition, blockedBy) {
|
|
307
|
+
if (blockedBy.reason === "non-terminal-instances") {
|
|
308
|
+
const head = blockedBy.instanceIds.slice(0, 3).join(", "), preview = blockedBy.instanceIds.length > 3 ? `${head}, …` : head;
|
|
309
|
+
return `Cannot delete ${definition}: ${blockedBy.instanceIds.length} non-terminal instance(s) exist (${preview}). Pass cascade to abort them first — instances are aborted in place, never deleted.`;
|
|
310
|
+
}
|
|
311
|
+
const names = blockedBy.referrers.map(r => `${r.definition} v${r.version}`).join(", ");
|
|
312
|
+
return `Cannot delete ${definition}: still spawn-referenced by deployed definition(s) ${names}. Delete or redeploy the referrer(s) first.`;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
class EffectNotFoundError extends WorkflowError {
|
|
316
|
+
instanceId;
|
|
317
|
+
effectKey;
|
|
318
|
+
settled;
|
|
319
|
+
constructor(args) {
|
|
320
|
+
super("effect-not-found", effectNotFoundMessage(args)), this.name = "EffectNotFoundError",
|
|
321
|
+
this.instanceId = args.instanceId, this.effectKey = args.effectKey, args.settled !== void 0 && (this.settled = args.settled);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function effectNotFoundMessage(args) {
|
|
326
|
+
const base = `Pending effect "${args.effectKey}" not found on instance ${args.instanceId}`;
|
|
327
|
+
if (args.settled === void 0) return base;
|
|
328
|
+
const cause = args.settled.detail !== void 0 ? ` (${args.settled.detail})` : "";
|
|
329
|
+
return args.settled.status === "cancelled" ? `${base} — it was cancelled at ${args.settled.ranAt}${cause}` : `${base} — it already settled "${args.settled.status}" at ${args.settled.ranAt}${cause}`;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
332
|
const LAKE_ID_SEGMENT_RE = /^[a-z0-9][a-z0-9-]*$/, LAKE_ID_SEGMENT_GLOSS = "ASCII lowercase + digits + dashes, no leading dash, no dots";
|
|
333
333
|
|
|
334
334
|
function validateTag(tag) {
|
|
@@ -654,6 +654,7 @@ function desugarFieldEntry({entry: entry, path: path, ctx: ctx}) {
|
|
|
654
654
|
options: entry.options,
|
|
655
655
|
validation: entry.validation,
|
|
656
656
|
types: entry.types,
|
|
657
|
+
roles: entry.roles,
|
|
657
658
|
fields: entry.fields,
|
|
658
659
|
of: entry.of
|
|
659
660
|
})
|
|
@@ -1275,10 +1276,18 @@ function refKindAcceptsTypes(kind) {
|
|
|
1275
1276
|
return isSingleDocRefKind(kind) || kind === "doc.refs";
|
|
1276
1277
|
}
|
|
1277
1278
|
|
|
1279
|
+
function assignmentKindAcceptsRoles(kind) {
|
|
1280
|
+
return kind === "assignee" || kind === "assignees";
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1278
1283
|
function isSingleDocRefEntry(entry) {
|
|
1279
1284
|
return isSingleDocRefKind(entry._type);
|
|
1280
1285
|
}
|
|
1281
1286
|
|
|
1287
|
+
function isAssignmentFieldEntry(entry) {
|
|
1288
|
+
return assignmentKindAcceptsRoles(entry._type);
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1282
1291
|
function isTodoListItem(row) {
|
|
1283
1292
|
if (typeof row != "object" || row === null) return !1;
|
|
1284
1293
|
const candidate = row, status = candidate.status;
|
|
@@ -1587,6 +1596,10 @@ function lakePrincipalId(args) {
|
|
|
1587
1596
|
return args.localPrincipalId ?? args.actor.id;
|
|
1588
1597
|
}
|
|
1589
1598
|
|
|
1599
|
+
function isRecord(value) {
|
|
1600
|
+
return typeof value == "object" && value !== null && !Array.isArray(value);
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1590
1603
|
class FieldValueShapeError extends WorkflowError {
|
|
1591
1604
|
entryType;
|
|
1592
1605
|
entryName;
|
|
@@ -1683,9 +1696,16 @@ const fieldValueSchemas = {
|
|
|
1683
1696
|
query: v.any()
|
|
1684
1697
|
};
|
|
1685
1698
|
|
|
1686
|
-
function shapeValueSchema(
|
|
1687
|
-
|
|
1688
|
-
if (shape.type === "
|
|
1699
|
+
function shapeValueSchema(args) {
|
|
1700
|
+
const {shape: shape, leaf: leaf} = args;
|
|
1701
|
+
if (shape.type === "object") return objectSchema({
|
|
1702
|
+
fields: shape.fields ?? [],
|
|
1703
|
+
leaf: leaf
|
|
1704
|
+
});
|
|
1705
|
+
if (shape.type === "array") return v.array(objectSchema({
|
|
1706
|
+
fields: shape.of ?? [],
|
|
1707
|
+
leaf: leaf
|
|
1708
|
+
}));
|
|
1689
1709
|
const schema = leaf[shape.type] ?? v.any();
|
|
1690
1710
|
return constrainedScalarSchema({
|
|
1691
1711
|
schema: schema,
|
|
@@ -1736,19 +1756,31 @@ function constrainedScalarSchema(args) {
|
|
|
1736
1756
|
}) ?? [] ].join("; ")));
|
|
1737
1757
|
}
|
|
1738
1758
|
|
|
1739
|
-
function objectSchema(
|
|
1740
|
-
const entries = /* @__PURE__ */ Object.create(null);
|
|
1741
|
-
for (const f of fields) entries[f.name] = v.optional(shapeValueSchema(
|
|
1759
|
+
function objectSchema(args) {
|
|
1760
|
+
const {fields: fields, leaf: leaf} = args, entries = /* @__PURE__ */ Object.create(null);
|
|
1761
|
+
for (const f of fields) entries[f.name] = v.optional(shapeValueSchema({
|
|
1762
|
+
shape: f,
|
|
1763
|
+
leaf: leaf
|
|
1764
|
+
}));
|
|
1742
1765
|
return v.looseObject(entries);
|
|
1743
1766
|
}
|
|
1744
1767
|
|
|
1745
1768
|
function wholeValueSchema(args) {
|
|
1746
1769
|
const {entryType: entryType, shape: shape, leaf: leaf} = args;
|
|
1747
|
-
return entryType === "object" ? v.union([ v.null(), objectSchema(
|
|
1770
|
+
return entryType === "object" ? v.union([ v.null(), objectSchema({
|
|
1771
|
+
fields: shape.fields ?? [],
|
|
1772
|
+
leaf: leaf
|
|
1773
|
+
}) ]) : entryType === "array" ? v.array(objectSchema({
|
|
1774
|
+
fields: shape.of ?? [],
|
|
1775
|
+
leaf: leaf
|
|
1776
|
+
})) : leaf[entryType];
|
|
1748
1777
|
}
|
|
1749
1778
|
|
|
1750
1779
|
function appendItemSchema(entryType, shape) {
|
|
1751
|
-
if (entryType === "array") return objectSchema(
|
|
1780
|
+
if (entryType === "array") return objectSchema({
|
|
1781
|
+
fields: shape.of ?? [],
|
|
1782
|
+
leaf: valueSchemas
|
|
1783
|
+
});
|
|
1752
1784
|
if (entryType === "doc.refs") return GdrShape;
|
|
1753
1785
|
if (entryType === "assignees") return AssigneeWriteShape;
|
|
1754
1786
|
}
|
|
@@ -1800,7 +1832,7 @@ function checkValueAgainst(args, leaf) {
|
|
|
1800
1832
|
entryType: args.entryType,
|
|
1801
1833
|
validation: args.validation,
|
|
1802
1834
|
value: args.value
|
|
1803
|
-
});
|
|
1835
|
+
}) ?? assignmentValueIssues(args, result.output);
|
|
1804
1836
|
return postIssues !== void 0 ? {
|
|
1805
1837
|
issues: postIssues
|
|
1806
1838
|
} : {
|
|
@@ -1808,6 +1840,142 @@ function checkValueAgainst(args, leaf) {
|
|
|
1808
1840
|
};
|
|
1809
1841
|
}
|
|
1810
1842
|
|
|
1843
|
+
function assignmentIdentity(assignee) {
|
|
1844
|
+
return assignee.type === "user" ? `user:${assignee.id}` : `role:${assignee.role}`;
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
function assignmentCandidate(value) {
|
|
1848
|
+
const parsed = v.safeParse(AssigneeShape, value);
|
|
1849
|
+
return parsed.success ? parsed.output : void 0;
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1852
|
+
function assignmentValueIssues(args, value) {
|
|
1853
|
+
const retained = previousAssignmentIdentities(args), issues = [];
|
|
1854
|
+
return visitAssignmentEntries({
|
|
1855
|
+
entryType: args.entryType,
|
|
1856
|
+
value: value,
|
|
1857
|
+
roles: args.roles,
|
|
1858
|
+
fields: args.fields,
|
|
1859
|
+
of: args.of,
|
|
1860
|
+
path: "$"
|
|
1861
|
+
}, ({assignee: assignee, roles: roles, path: path}) => {
|
|
1862
|
+
consumeRetainedAssignment({
|
|
1863
|
+
retained: retained,
|
|
1864
|
+
path: path,
|
|
1865
|
+
identity: assignmentIdentity(assignee)
|
|
1866
|
+
}) || issues.push(...assignmentCandidateIssues({
|
|
1867
|
+
roles: roles,
|
|
1868
|
+
memberRoles: args.memberRoles,
|
|
1869
|
+
roleAliases: args.roleAliases
|
|
1870
|
+
}, assignee));
|
|
1871
|
+
}), issues.length === 0 ? void 0 : issues;
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
function consumeRetainedAssignment(args) {
|
|
1875
|
+
const identities = args.retained.get(args.path), remaining = identities?.get(args.identity) ?? 0;
|
|
1876
|
+
return remaining === 0 || identities === void 0 ? !1 : (remaining === 1 ? identities.delete(args.identity) : identities.set(args.identity, remaining - 1),
|
|
1877
|
+
!0);
|
|
1878
|
+
}
|
|
1879
|
+
|
|
1880
|
+
function previousAssignmentIdentities(args) {
|
|
1881
|
+
const retained = /* @__PURE__ */ new Map;
|
|
1882
|
+
if (args.previousValue === void 0 || args.entryType === "assignee") return retained;
|
|
1883
|
+
const schema = wholeValueSchema({
|
|
1884
|
+
entryType: args.entryType,
|
|
1885
|
+
shape: args,
|
|
1886
|
+
leaf: valueSchemas
|
|
1887
|
+
});
|
|
1888
|
+
if (schema === void 0) return retained;
|
|
1889
|
+
const previous = v.safeParse(schema, args.previousValue);
|
|
1890
|
+
return previous.success && visitAssignmentEntries({
|
|
1891
|
+
entryType: args.entryType,
|
|
1892
|
+
value: previous.output,
|
|
1893
|
+
roles: args.roles,
|
|
1894
|
+
fields: args.fields,
|
|
1895
|
+
of: args.of,
|
|
1896
|
+
path: "$"
|
|
1897
|
+
}, ({assignee: assignee, path: path}) => {
|
|
1898
|
+
const identities = retained.get(path) ?? /* @__PURE__ */ new Map, identity = assignmentIdentity(assignee);
|
|
1899
|
+
identities.set(identity, (identities.get(identity) ?? 0) + 1), retained.set(path, identities);
|
|
1900
|
+
}), retained;
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1903
|
+
function visitAssignmentEntries(args, visit) {
|
|
1904
|
+
if (assignmentKindAcceptsRoles(args.entryType)) {
|
|
1905
|
+
visitAssignmentCandidates(args, visit);
|
|
1906
|
+
return;
|
|
1907
|
+
}
|
|
1908
|
+
if (args.entryType === "object") {
|
|
1909
|
+
visitAssignmentFields({
|
|
1910
|
+
fields: args.fields,
|
|
1911
|
+
value: args.value,
|
|
1912
|
+
path: args.path
|
|
1913
|
+
}, visit);
|
|
1914
|
+
return;
|
|
1915
|
+
}
|
|
1916
|
+
if (!(args.entryType !== "array" || !Array.isArray(args.value))) for (const row of args.value) visitAssignmentFields({
|
|
1917
|
+
fields: args.of,
|
|
1918
|
+
value: row,
|
|
1919
|
+
path: `${args.path}[]`
|
|
1920
|
+
}, visit);
|
|
1921
|
+
}
|
|
1922
|
+
|
|
1923
|
+
function visitAssignmentCandidates(args, visit) {
|
|
1924
|
+
if (args.roles === void 0) return;
|
|
1925
|
+
const indexedValues = args.entryType === "assignees" && Array.isArray(args.value) ? args.value.map(value => ({
|
|
1926
|
+
value: value,
|
|
1927
|
+
path: args.path
|
|
1928
|
+
})) : [ {
|
|
1929
|
+
value: args.value,
|
|
1930
|
+
path: args.path
|
|
1931
|
+
} ];
|
|
1932
|
+
for (const {value: value, path: path} of indexedValues) {
|
|
1933
|
+
const assignee = assignmentCandidate(value);
|
|
1934
|
+
assignee !== void 0 && visit({
|
|
1935
|
+
assignee: assignee,
|
|
1936
|
+
roles: args.roles,
|
|
1937
|
+
path: path
|
|
1938
|
+
});
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
|
|
1942
|
+
function visitAssignmentFields(args, visit) {
|
|
1943
|
+
if (!(args.fields === void 0 || !isRecord(args.value))) for (const field of args.fields) visitAssignmentShape({
|
|
1944
|
+
shape: field,
|
|
1945
|
+
value: args.value[field.name],
|
|
1946
|
+
path: `${args.path}.${field.name}`
|
|
1947
|
+
}, visit);
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1950
|
+
function visitAssignmentShape(args, visit) {
|
|
1951
|
+
visitAssignmentEntries({
|
|
1952
|
+
entryType: args.shape.type,
|
|
1953
|
+
value: args.value,
|
|
1954
|
+
roles: args.shape.roles,
|
|
1955
|
+
fields: args.shape.fields,
|
|
1956
|
+
of: args.shape.of,
|
|
1957
|
+
path: args.path
|
|
1958
|
+
}, visit);
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
function assignmentCandidateIssues(args, assignee) {
|
|
1962
|
+
if (assignee.type === "role") return collectiveRoleIssues(args, assignee.role);
|
|
1963
|
+
const held = args.memberRoles?.[assignee.id];
|
|
1964
|
+
return held === void 0 ? args.memberRoles === void 0 ? [] : [ `user "${assignee.id}" has no available project membership for role eligibility` ] : args.roles.some(required => actorFulfillsRole({
|
|
1965
|
+
actorRoles: held,
|
|
1966
|
+
required: required,
|
|
1967
|
+
aliases: args.roleAliases
|
|
1968
|
+
})) ? [] : [ `user "${assignee.id}" does not fulfill any eligible role: ${formatEligibleRoles(args.roles)}` ];
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
function collectiveRoleIssues(args, role) {
|
|
1972
|
+
return args.roles.includes(role) ? [] : [ `collective role "${role}" is not eligible — this entry accepts ${formatEligibleRoles(args.roles)}` ];
|
|
1973
|
+
}
|
|
1974
|
+
|
|
1975
|
+
function formatEligibleRoles(roles) {
|
|
1976
|
+
return roles.map(role => `"${role}"`).join(", ");
|
|
1977
|
+
}
|
|
1978
|
+
|
|
1811
1979
|
function issuesOf(check) {
|
|
1812
1980
|
return "issues" in check ? check.issues : void 0;
|
|
1813
1981
|
}
|
|
@@ -1867,6 +2035,20 @@ function validateFieldAppendItem(args) {
|
|
|
1867
2035
|
issues: formatIssues(result.issues),
|
|
1868
2036
|
mode: "item"
|
|
1869
2037
|
});
|
|
2038
|
+
const assignmentArgs = {
|
|
2039
|
+
entryType: appendAssignmentEntryType(args.entryType),
|
|
2040
|
+
value: result.output,
|
|
2041
|
+
roles: args.roles,
|
|
2042
|
+
fields: args.entryType === "array" ? args.of : void 0,
|
|
2043
|
+
memberRoles: args.memberRoles,
|
|
2044
|
+
roleAliases: args.roleAliases
|
|
2045
|
+
}, assignmentIssues = assignmentValueIssues(assignmentArgs, result.output);
|
|
2046
|
+
if (assignmentIssues !== void 0) throw new FieldValueShapeError({
|
|
2047
|
+
entryType: args.entryType,
|
|
2048
|
+
entryName: args.entryName,
|
|
2049
|
+
issues: assignmentIssues,
|
|
2050
|
+
mode: "item"
|
|
2051
|
+
});
|
|
1870
2052
|
const typeIssues = refTypeIssues({
|
|
1871
2053
|
entryType: args.entryType,
|
|
1872
2054
|
types: args.types,
|
|
@@ -1881,6 +2063,10 @@ function validateFieldAppendItem(args) {
|
|
|
1881
2063
|
return result.output;
|
|
1882
2064
|
}
|
|
1883
2065
|
|
|
2066
|
+
function appendAssignmentEntryType(entryType) {
|
|
2067
|
+
return entryType === "assignees" ? "assignee" : entryType === "array" ? "object" : entryType;
|
|
2068
|
+
}
|
|
2069
|
+
|
|
1884
2070
|
function formatIssues(issues, formatMessage = issue => issue.message) {
|
|
1885
2071
|
const formatOne = (issue, prefix) => {
|
|
1886
2072
|
const keys = [ ...prefix, ...issue.path?.map(p => p.key) ?? [] ], sub = issue.issues?.filter(candidate => candidate.expected !== "null");
|
|
@@ -2073,16 +2259,17 @@ function compositeChecked(entries) {
|
|
|
2073
2259
|
return v.pipe(v.strictObject(entries), v.check(input => compositeShapeOk(input), issue => compositeShapeMessage(issue.input)), v.check(input => duplicateSubfieldName(input) === void 0, issue => `duplicate sub-field name "${duplicateSubfieldName(issue.input)}" — sub-field names must be unique within \`fields\` / \`of\``));
|
|
2074
2260
|
}
|
|
2075
2261
|
|
|
2076
|
-
const FieldShapeSchema = v.lazy(() => v.pipe(compositeChecked({
|
|
2262
|
+
const AssignmentRolesSchema = v.pipe(v.array(NonEmpty), v.minLength(1, "declare at least one eligible role, or omit `roles`")), FieldShapeSchema = v.lazy(() => v.pipe(compositeChecked({
|
|
2077
2263
|
type: FieldValueKindSchema,
|
|
2078
2264
|
name: FieldEntryName,
|
|
2079
2265
|
title: v.optional(v.string()),
|
|
2080
2266
|
description: v.optional(v.string()),
|
|
2081
2267
|
options: v.optional(ChoiceOptionsSchema),
|
|
2082
2268
|
validation: v.optional(ScalarValidationSchema),
|
|
2269
|
+
roles: v.optional(AssignmentRolesSchema),
|
|
2083
2270
|
fields: v.optional(v.array(FieldShapeSchema)),
|
|
2084
2271
|
of: v.optional(v.array(FieldShapeSchema))
|
|
2085
|
-
}), choiceOptionsCheck(), scalarValidationCheck())), StoredEditableSchema = v.union([ v.literal(!0), NonEmpty ]), AuthoringEditableSchema = v.union([ v.literal(!0), v.array(NonEmpty), NonEmpty ]);
|
|
2272
|
+
}), choiceOptionsCheck(), scalarValidationCheck(), assignmentRolesCheck())), StoredEditableSchema = v.union([ v.literal(!0), NonEmpty ]), AuthoringEditableSchema = v.union([ v.literal(!0), v.array(NonEmpty), NonEmpty ]);
|
|
2086
2273
|
|
|
2087
2274
|
function fieldBase(editable, group) {
|
|
2088
2275
|
return {
|
|
@@ -2103,6 +2290,7 @@ function fieldEntryFields({editable: editable, group: group, kind: kind = FieldK
|
|
|
2103
2290
|
options: v.optional(ChoiceOptionsSchema),
|
|
2104
2291
|
validation: v.optional(ScalarValidationSchema),
|
|
2105
2292
|
types: v.optional(v.pipe(v.array(NonEmpty), v.minLength(1, "declare at least one accepted type, or omit `types` to accept any"))),
|
|
2293
|
+
roles: v.optional(AssignmentRolesSchema),
|
|
2106
2294
|
fields: v.optional(v.array(FieldShapeSchema)),
|
|
2107
2295
|
of: v.optional(v.array(FieldShapeSchema))
|
|
2108
2296
|
};
|
|
@@ -2116,7 +2304,8 @@ function literalSeedIssues(entry) {
|
|
|
2116
2304
|
fields: entry.fields,
|
|
2117
2305
|
of: entry.of,
|
|
2118
2306
|
options: entry.options,
|
|
2119
|
-
validation: entry.validation
|
|
2307
|
+
validation: entry.validation,
|
|
2308
|
+
roles: entry.roles
|
|
2120
2309
|
});
|
|
2121
2310
|
}
|
|
2122
2311
|
|
|
@@ -2128,6 +2317,10 @@ function refTypesCheck() {
|
|
|
2128
2317
|
return v.check(entry => entry.types === void 0 || refKindAcceptsTypes(entry.type), issue => `\`types\` is only valid on \`doc.ref\` / \`doc.refs\` / \`subject\` entries, not "${issue.input.type}"`);
|
|
2129
2318
|
}
|
|
2130
2319
|
|
|
2320
|
+
function assignmentRolesCheck() {
|
|
2321
|
+
return v.check(entry => entry.roles === void 0 || assignmentKindAcceptsRoles(entry.type), issue => `\`roles\` is only valid on \`assignee\` / \`assignees\` entries, not "${issue.input.type}"`);
|
|
2322
|
+
}
|
|
2323
|
+
|
|
2131
2324
|
function choiceOptionsCheck() {
|
|
2132
2325
|
return v.check(entry => checkChoiceList({
|
|
2133
2326
|
entryType: entry.type,
|
|
@@ -2162,11 +2355,11 @@ function scalarValidationDeclarationIssues(entry) {
|
|
|
2162
2355
|
const FieldEntrySchema = pinned()(v.pipe(compositeChecked(fieldEntryFields({
|
|
2163
2356
|
editable: StoredEditableSchema,
|
|
2164
2357
|
group: StoredGroupMembershipSchema
|
|
2165
|
-
})), refTypesCheck(), choiceOptionsCheck(), scalarValidationCheck(), literalSeedCheck())), RawAuthoringFieldEntrySchema = pinned()(v.pipe(compositeChecked(fieldEntryFields({
|
|
2358
|
+
})), refTypesCheck(), assignmentRolesCheck(), choiceOptionsCheck(), scalarValidationCheck(), literalSeedCheck())), RawAuthoringFieldEntrySchema = pinned()(v.pipe(compositeChecked(fieldEntryFields({
|
|
2166
2359
|
editable: AuthoringEditableSchema,
|
|
2167
2360
|
group: AuthoringGroupMembershipSchema,
|
|
2168
2361
|
kind: AuthoringRawFieldKindSchema
|
|
2169
|
-
})), refTypesCheck(), choiceOptionsCheck(), scalarValidationCheck(), literalSeedCheck())), ClaimFieldSchema = pinned()(v.strictObject({
|
|
2362
|
+
})), refTypesCheck(), assignmentRolesCheck(), choiceOptionsCheck(), scalarValidationCheck(), literalSeedCheck())), ClaimFieldSchema = pinned()(v.strictObject({
|
|
2170
2363
|
type: v.literal("claim"),
|
|
2171
2364
|
name: FieldEntryName,
|
|
2172
2365
|
title: v.optional(v.string()),
|
|
@@ -3824,4 +4017,4 @@ function checkWorkflowInvariants(def) {
|
|
|
3824
4017
|
checkStoredRolesPlacement(def, issues), checkGroups(def, issues), issues;
|
|
3825
4018
|
}
|
|
3826
4019
|
|
|
3827
|
-
export { ACTION_SEMANTICS, ACTIVITY_KINDS, ACTIVITY_STATUSES, ACTOR_KINDS, ANONYMOUS_IDENTITY, ActorShape, AuthoringActionSchema, AuthoringActivitySchema, AuthoringFieldEntrySchema, AuthoringGuardSchema, AuthoringOpSchema, AuthoringStageSchema, AuthoringTransitionSchema, AuthoringWorkflowSchema, CALLER_BOUND_VARS, CONDITION_VARS, ContractViolationError, DECISION_SEMANTICS, DEFAULT_TRANSITION_WHEN, DOCUMENT_VALUE_PERMISSIONS, DRIVER_KINDS, DefinitionInUseError, DefinitionNotFoundError, EFFECTS_READ, EXECUTOR_CLASSIFICATIONS, EffectNotFoundError, EffectSchema, FIELD_READ, FIELD_SCOPES, FIELD_VALUE_KINDS, FILTER_SCOPE_VARS, FieldValueShapeError, GROUP_KINDS, GUARD_PREDICATE_VARS, GdrShape, GroupSchema, InstanceNotFoundError, IsoTimestamp, MUTATION_GUARD_ACTIONS, NonEmptyString, PersistedDocShapeError, RESERVED_CONDITION_VARS, RESOURCE_ALIAS_NAME_SOURCE, SIGNAL_SEMANTICS, START_FILTER_VARS, START_REQUIREMENT_VARS, SYSTEM_IDENTITY, SpawnContractsInvalidError, StoredFieldOpSchema, VersionSpecificDatasetGdrError, WORKFLOW_DEFINITION_TYPE, WorkflowConfigSchema, WorkflowError, actorFulfillsRole, andConditions, checkWorkflowInvariants, choiceValueIssues, classifyPrincipalId, clientConfigFromResource, conditionEffectReads, conditionFieldReadNames, conditionParameterNames, conditionSyntaxIssues, datasetResourceParts, definitionDocId, deriveActivityKind, deriveExecutorClassification, desugarWorkflow, directoryBridgeId, driverKind, errorMessage, evaluateCondition, evaluateConditionOutcome, evaluatePredicates, extractDocumentId, fieldValueSchemas, firstCarriedGlobalId, formatIssuePath, formatIssues, formatValidationError, gdrFromResource, gdrRef, gdrResourcePrefix, gdrUri, groq, groupMembershipNames, isAlwaysArrayFieldKind, isBareSeedId, isCascadeFired, isGdr, isGdrUri, isGuardReadExpr, isInputSourced, isNotesEntry, isParseableInstant, isSingleDocRefEntry, isSingleDocRefKind, isStartableDefinition, isSubjectEntry, isTerminalActivityStatus, isTodoListEntry, isTodoListItem, isUnevaluable, labelFor, lakePrincipalId, parseFieldValue, parseGdr, parseOrThrow, parsePersistedDoc, parseResourceGdr, parseStoredDefinition, readsRootDocument, refCanvas, refDashboard, refDataset, refKindAcceptsTypes, refMediaLibrary, refTypeIssues, rejectedRefTypes, releaseDocId, releaseRef, resourceAliasesToMap, resourceFromGdrUri, resourceFromParsed, resourceGdr, rethrowWithContext, runGroq, sameResource, scalarValidationIssues, schemaTreeShape, selfGdr, startKindOf, tagScopeFilter, toBareId, toPhysicalGdr, tolerantEntries, tolerantObject, tryParseGdr, validateFieldAppendItem, validateFieldValue, validateResourceAliasName, validateTag };
|
|
4020
|
+
export { ACTION_SEMANTICS, ACTIVITY_KINDS, ACTIVITY_STATUSES, ACTOR_KINDS, ANONYMOUS_IDENTITY, ActorShape, AuthoringActionSchema, AuthoringActivitySchema, AuthoringFieldEntrySchema, AuthoringGuardSchema, AuthoringOpSchema, AuthoringStageSchema, AuthoringTransitionSchema, AuthoringWorkflowSchema, CALLER_BOUND_VARS, CONDITION_VARS, ContractViolationError, DECISION_SEMANTICS, DEFAULT_TRANSITION_WHEN, DOCUMENT_VALUE_PERMISSIONS, DRIVER_KINDS, DefinitionInUseError, DefinitionNotFoundError, EFFECTS_READ, EXECUTOR_CLASSIFICATIONS, EffectNotFoundError, EffectSchema, FIELD_READ, FIELD_SCOPES, FIELD_VALUE_KINDS, FILTER_SCOPE_VARS, FieldValueShapeError, GROUP_KINDS, GUARD_PREDICATE_VARS, GdrShape, GroupSchema, InstanceNotFoundError, IsoTimestamp, MUTATION_GUARD_ACTIONS, NonEmptyString, PersistedDocShapeError, RESERVED_CONDITION_VARS, RESOURCE_ALIAS_NAME_SOURCE, SIGNAL_SEMANTICS, START_FILTER_VARS, START_REQUIREMENT_VARS, SYSTEM_IDENTITY, SpawnContractsInvalidError, StoredFieldOpSchema, VersionSpecificDatasetGdrError, WORKFLOW_DEFINITION_TYPE, WorkflowConfigSchema, WorkflowError, actorFulfillsRole, andConditions, assignmentKindAcceptsRoles, checkWorkflowInvariants, choiceValueIssues, classifyPrincipalId, clientConfigFromResource, conditionEffectReads, conditionFieldReadNames, conditionParameterNames, conditionSyntaxIssues, datasetResourceParts, definitionDocId, deriveActivityKind, deriveExecutorClassification, desugarWorkflow, directoryBridgeId, driverKind, errorMessage, evaluateCondition, evaluateConditionOutcome, evaluatePredicates, extractDocumentId, fieldValueSchemas, firstCarriedGlobalId, formatIssuePath, formatIssues, formatValidationError, gdrFromResource, gdrRef, gdrResourcePrefix, gdrUri, groq, groupMembershipNames, isAlwaysArrayFieldKind, isAssignmentFieldEntry, isBareSeedId, isCascadeFired, isGdr, isGdrUri, isGuardReadExpr, isInputSourced, isNotesEntry, isParseableInstant, isRecord, isSingleDocRefEntry, isSingleDocRefKind, isStartableDefinition, isSubjectEntry, isTerminalActivityStatus, isTodoListEntry, isTodoListItem, isUnevaluable, labelFor, lakePrincipalId, parseFieldValue, parseGdr, parseOrThrow, parsePersistedDoc, parseResourceGdr, parseStoredDefinition, readsRootDocument, refCanvas, refDashboard, refDataset, refKindAcceptsTypes, refMediaLibrary, refTypeIssues, rejectedRefTypes, releaseDocId, releaseRef, resourceAliasesToMap, resourceFromGdrUri, resourceFromParsed, resourceGdr, rethrowWithContext, runGroq, sameResource, scalarValidationIssues, schemaTreeShape, selfGdr, startKindOf, tagScopeFilter, toBareId, toPhysicalGdr, tolerantEntries, tolerantObject, tryParseGdr, validateFieldAppendItem, validateFieldValue, validateResourceAliasName, validateTag };
|