@sanity/workflow-engine 0.10.0 → 0.12.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/dist/_chunks-cjs/schema.cjs +189 -74
- package/dist/_chunks-cjs/schema.cjs.map +1 -1
- package/dist/_chunks-es/schema.js +190 -75
- package/dist/_chunks-es/schema.js.map +1 -1
- package/dist/define.cjs +220 -121
- package/dist/define.cjs.map +1 -1
- package/dist/define.d.cts +6473 -3502
- package/dist/define.d.ts +6473 -3502
- package/dist/define.js +221 -122
- package/dist/define.js.map +1 -1
- package/dist/index.cjs +1131 -921
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14866 -10827
- package/dist/index.d.ts +14866 -10827
- package/dist/index.js +1133 -923
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -4,6 +4,12 @@ function andConditions(parts) {
|
|
|
4
4
|
if (present.length !== 0)
|
|
5
5
|
return present.length === 1 ? present[0] : present.map((p) => `(${p})`).join(" && ");
|
|
6
6
|
}
|
|
7
|
+
const UNIVERSAL_ROLE_ALIAS_KEY = "$all";
|
|
8
|
+
function normalizeRoleAliases(aliases) {
|
|
9
|
+
if (aliases === void 0 || !("*" in aliases)) return aliases;
|
|
10
|
+
const { ["*"]: universal, ...perRole } = aliases;
|
|
11
|
+
return { ...perRole, [UNIVERSAL_ROLE_ALIAS_KEY]: universal };
|
|
12
|
+
}
|
|
7
13
|
function expandRequiredRoles(required, aliases) {
|
|
8
14
|
if (aliases === void 0) return [...required];
|
|
9
15
|
const out = /* @__PURE__ */ new Set();
|
|
@@ -11,7 +17,7 @@ function expandRequiredRoles(required, aliases) {
|
|
|
11
17
|
out.add(role);
|
|
12
18
|
for (const fulfiller of aliases[role] ?? []) out.add(fulfiller);
|
|
13
19
|
}
|
|
14
|
-
for (const fulfiller of aliases[
|
|
20
|
+
for (const fulfiller of aliases[UNIVERSAL_ROLE_ALIAS_KEY] ?? []) out.add(fulfiller);
|
|
15
21
|
return [...out];
|
|
16
22
|
}
|
|
17
23
|
function actorFulfillsRole(actorRoles, required, aliases) {
|
|
@@ -19,17 +25,17 @@ function actorFulfillsRole(actorRoles, required, aliases) {
|
|
|
19
25
|
const accepted = new Set(expandRequiredRoles([required], aliases));
|
|
20
26
|
return actorRoles.some((role) => accepted.has(role));
|
|
21
27
|
}
|
|
22
|
-
const
|
|
23
|
-
function
|
|
24
|
-
return
|
|
28
|
+
const ACTIVITY_STATUSES = ["pending", "active", "done", "skipped", "failed"], TERMINAL_ACTIVITY_STATUSES = ["done", "skipped", "failed"];
|
|
29
|
+
function isTerminalActivityStatus(status) {
|
|
30
|
+
return TERMINAL_ACTIVITY_STATUSES.includes(status);
|
|
25
31
|
}
|
|
26
|
-
const FIELD_SCOPES = ["workflow", "stage", "
|
|
32
|
+
const FIELD_SCOPES = ["workflow", "stage", "activity"], DOCUMENT_VALUE_PERMISSIONS = ["create", "read", "update"], MUTATION_GUARD_ACTIONS = [
|
|
27
33
|
"create",
|
|
28
34
|
"update",
|
|
29
35
|
"delete",
|
|
30
36
|
"publish",
|
|
31
37
|
"unpublish"
|
|
32
|
-
], NonEmpty = v.pipe(v.string(), v.minLength(1, "must be a non-empty string")), PositiveInt = v.pipe(v.number(), v.integer(), v.minValue(1)), GROQ_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
38
|
+
], ACTIVITY_KINDS = ["user", "service", "script", "manual", "receive"], DRIVER_KINDS = ["person", "agent", "service", "engine"], NonEmpty = v.pipe(v.string(), v.minLength(1, "must be a non-empty string")), PositiveInt = v.pipe(v.number(), v.integer(), v.minValue(1)), GROQ_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
33
39
|
function groqIdentifier(referencedAs) {
|
|
34
40
|
return v.pipe(
|
|
35
41
|
v.string(),
|
|
@@ -45,32 +51,28 @@ function picklist(options) {
|
|
|
45
51
|
`Invalid option: expected one of ${options.map((o) => `"${o}"`).join("|")}`
|
|
46
52
|
);
|
|
47
53
|
}
|
|
48
|
-
const
|
|
54
|
+
const LiteralSchema = v.strictObject({ type: v.literal("literal"), value: v.unknown() }), FieldReadSchema = v.strictObject({
|
|
55
|
+
type: v.literal("fieldRead"),
|
|
56
|
+
scope: v.optional(v.union([v.literal("workflow"), v.literal("stage")])),
|
|
57
|
+
field: NonEmpty,
|
|
58
|
+
path: v.optional(v.string())
|
|
59
|
+
}), FieldSourceSchema = v.union([
|
|
60
|
+
// The caller supplies it at start/spawn (`initialFields` / `subworkflows.with`).
|
|
61
|
+
v.strictObject({ type: v.literal("input") }),
|
|
62
|
+
// Computed once by running GROQ against the lake at materialisation.
|
|
63
|
+
v.strictObject({ type: v.literal("query"), query: NonEmpty }),
|
|
64
|
+
LiteralSchema,
|
|
65
|
+
FieldReadSchema
|
|
66
|
+
]), ValueExprSchema = v.lazy(
|
|
49
67
|
() => v.union([
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
v.strictObject({ type: v.literal("write") }),
|
|
53
|
-
v.strictObject({
|
|
54
|
-
type: v.literal("query"),
|
|
55
|
-
query: NonEmpty
|
|
56
|
-
}),
|
|
57
|
-
// Value sources: resolved to concrete JSON when an op or seed applies.
|
|
58
|
-
v.strictObject({ type: v.literal("literal"), value: v.unknown() }),
|
|
68
|
+
LiteralSchema,
|
|
69
|
+
FieldReadSchema,
|
|
59
70
|
v.strictObject({ type: v.literal("param"), param: NonEmpty }),
|
|
60
71
|
v.strictObject({ type: v.literal("actor") }),
|
|
61
72
|
v.strictObject({ type: v.literal("now") }),
|
|
62
73
|
v.strictObject({ type: v.literal("self") }),
|
|
63
74
|
v.strictObject({ type: v.literal("stage") }),
|
|
64
|
-
v.strictObject({
|
|
65
|
-
type: v.literal("fieldRead"),
|
|
66
|
-
scope: v.optional(v.union([v.literal("workflow"), v.literal("stage")])),
|
|
67
|
-
field: NonEmpty,
|
|
68
|
-
path: v.optional(v.string())
|
|
69
|
-
}),
|
|
70
|
-
v.strictObject({
|
|
71
|
-
type: v.literal("object"),
|
|
72
|
-
fields: v.record(NonEmpty, SourceSchema)
|
|
73
|
-
})
|
|
75
|
+
v.strictObject({ type: v.literal("object"), fields: v.record(NonEmpty, ValueExprSchema) })
|
|
74
76
|
])
|
|
75
77
|
), StoredFieldRefSchema = v.strictObject({
|
|
76
78
|
scope: picklist(FIELD_SCOPES),
|
|
@@ -78,12 +80,31 @@ const SourceSchema = v.lazy(
|
|
|
78
80
|
}), AuthoringFieldRefSchema = v.strictObject({
|
|
79
81
|
scope: v.optional(picklist(FIELD_SCOPES)),
|
|
80
82
|
field: NonEmpty
|
|
81
|
-
}),
|
|
83
|
+
}), HREF_SCHEMES = ["http:", "https:"];
|
|
84
|
+
function isHttpUrl(value) {
|
|
85
|
+
try {
|
|
86
|
+
return HREF_SCHEMES.includes(new URL(value).protocol);
|
|
87
|
+
} catch {
|
|
88
|
+
return !1;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const UrlString = v.pipe(
|
|
92
|
+
v.string(),
|
|
93
|
+
v.url("must be a valid URL"),
|
|
94
|
+
v.check(isHttpUrl, "must be an http(s) URL")
|
|
95
|
+
);
|
|
96
|
+
function manualTargetSchema(ref) {
|
|
97
|
+
return v.variant("type", [
|
|
98
|
+
v.strictObject({ type: v.literal("url"), url: UrlString }),
|
|
99
|
+
v.strictObject({ type: v.literal("field"), field: ref })
|
|
100
|
+
]);
|
|
101
|
+
}
|
|
102
|
+
const StoredManualTargetSchema = manualTargetSchema(StoredFieldRefSchema), AuthoringManualTargetSchema = manualTargetSchema(v.union([NonEmpty, AuthoringFieldRefSchema])), OpPredicateSchema = v.lazy(
|
|
82
103
|
() => v.union([
|
|
83
104
|
v.strictObject({
|
|
84
105
|
type: v.literal("field"),
|
|
85
106
|
field: NonEmpty,
|
|
86
|
-
equals:
|
|
107
|
+
equals: ValueExprSchema
|
|
87
108
|
}),
|
|
88
109
|
v.strictObject({ type: v.literal("all"), of: v.array(OpPredicateSchema) }),
|
|
89
110
|
v.strictObject({ type: v.literal("any"), of: v.array(OpPredicateSchema) })
|
|
@@ -94,7 +115,7 @@ function opSchemas(targetSchema) {
|
|
|
94
115
|
v.strictObject({
|
|
95
116
|
type: v.literal("field.set"),
|
|
96
117
|
target: targetSchema,
|
|
97
|
-
value:
|
|
118
|
+
value: ValueExprSchema
|
|
98
119
|
}),
|
|
99
120
|
v.strictObject({
|
|
100
121
|
type: v.literal("field.unset"),
|
|
@@ -103,13 +124,13 @@ function opSchemas(targetSchema) {
|
|
|
103
124
|
v.strictObject({
|
|
104
125
|
type: v.literal("field.append"),
|
|
105
126
|
target: targetSchema,
|
|
106
|
-
value:
|
|
127
|
+
value: ValueExprSchema
|
|
107
128
|
}),
|
|
108
129
|
v.strictObject({
|
|
109
130
|
type: v.literal("field.updateWhere"),
|
|
110
131
|
target: targetSchema,
|
|
111
132
|
where: OpPredicateSchema,
|
|
112
|
-
value:
|
|
133
|
+
value: ValueExprSchema
|
|
113
134
|
}),
|
|
114
135
|
v.strictObject({
|
|
115
136
|
type: v.literal("field.removeWhere"),
|
|
@@ -122,13 +143,13 @@ const StoredOpSchema = v.variant("type", [
|
|
|
122
143
|
...opSchemas(StoredFieldRefSchema),
|
|
123
144
|
v.strictObject({
|
|
124
145
|
type: v.literal("status.set"),
|
|
125
|
-
|
|
126
|
-
status: picklist(
|
|
146
|
+
activity: NonEmpty,
|
|
147
|
+
status: picklist(ACTIVITY_STATUSES)
|
|
127
148
|
})
|
|
128
149
|
]), StoredTransitionOpSchema = v.variant("type", [...opSchemas(StoredFieldRefSchema)]), AuditOpSchema = v.strictObject({
|
|
129
150
|
type: v.literal("audit"),
|
|
130
151
|
target: AuthoringFieldRefSchema,
|
|
131
|
-
value:
|
|
152
|
+
value: ValueExprSchema,
|
|
132
153
|
stampFields: v.optional(
|
|
133
154
|
v.strictObject({
|
|
134
155
|
actor: v.optional(NonEmpty),
|
|
@@ -139,33 +160,83 @@ const StoredOpSchema = v.variant("type", [
|
|
|
139
160
|
...opSchemas(AuthoringFieldRefSchema),
|
|
140
161
|
v.strictObject({
|
|
141
162
|
type: v.literal("status.set"),
|
|
142
|
-
|
|
143
|
-
status: picklist(
|
|
163
|
+
activity: v.optional(NonEmpty),
|
|
164
|
+
status: picklist(ACTIVITY_STATUSES)
|
|
144
165
|
}),
|
|
145
166
|
AuditOpSchema
|
|
146
|
-
]),
|
|
167
|
+
]), FIELD_VALUE_KINDS = [
|
|
147
168
|
"doc.ref",
|
|
148
169
|
"doc.refs",
|
|
149
170
|
// Release reference. A workflow declares this entry to say "I target a
|
|
150
171
|
// Content Release"; the runtime fills it at start time and auto-derives
|
|
151
172
|
// the instance's read perspective from it.
|
|
152
173
|
"release.ref",
|
|
153
|
-
"
|
|
154
|
-
"
|
|
155
|
-
"
|
|
156
|
-
"
|
|
157
|
-
"
|
|
158
|
-
"
|
|
159
|
-
"
|
|
160
|
-
"
|
|
161
|
-
|
|
174
|
+
"string",
|
|
175
|
+
"text",
|
|
176
|
+
"number",
|
|
177
|
+
"boolean",
|
|
178
|
+
"date",
|
|
179
|
+
"datetime",
|
|
180
|
+
"url",
|
|
181
|
+
"actor",
|
|
182
|
+
// A single {@link Assignee} — the singular of `assignees`.
|
|
183
|
+
"assignee",
|
|
162
184
|
// The WHO-FOR entry: the inbox reverse-query reads it by kind, and the
|
|
163
185
|
// rendered `$assigned` gate matches the caller against it.
|
|
164
|
-
"assignees"
|
|
165
|
-
|
|
166
|
-
|
|
186
|
+
"assignees",
|
|
187
|
+
// Compositional kinds — mirror Sanity's `object.fields` / `array.of`.
|
|
188
|
+
"object",
|
|
189
|
+
"array"
|
|
190
|
+
], FieldValueKindSchema = picklist(FIELD_VALUE_KINDS), FieldKindSchema = picklist(FIELD_VALUE_KINDS), FieldEntryName = groqIdentifier("`$fields.<name>`");
|
|
191
|
+
function asShape(input) {
|
|
192
|
+
return typeof input == "object" && input !== null ? input : {};
|
|
193
|
+
}
|
|
194
|
+
function compositeShapeOk(input) {
|
|
195
|
+
const shape = asShape(input);
|
|
196
|
+
return shape.type === "object" ? Array.isArray(shape.fields) && shape.fields.length > 0 && shape.of === void 0 : shape.type === "array" ? Array.isArray(shape.of) && shape.of.length > 0 && shape.fields === void 0 : shape.fields === void 0 && shape.of === void 0;
|
|
197
|
+
}
|
|
198
|
+
function compositeShapeMessage(input) {
|
|
199
|
+
const shape = asShape(input);
|
|
200
|
+
return shape.type === "object" ? shape.of !== void 0 ? "an `object` kind declares its sub-fields with `fields`, not `of`" : "an `object` kind needs a non-empty `fields` list of sub-field shapes" : shape.type === "array" ? shape.fields !== void 0 ? "an `array` kind declares its item shape with `of`, not `fields`" : "an `array` kind needs a non-empty `of` list of sub-field shapes" : `\`fields\` / \`of\` are only valid on the \`object\` / \`array\` kinds, not "${String(shape.type)}"`;
|
|
201
|
+
}
|
|
202
|
+
function duplicateSubfieldName(input) {
|
|
203
|
+
const shape = asShape(input);
|
|
204
|
+
let list = [];
|
|
205
|
+
Array.isArray(shape.fields) ? list = shape.fields : Array.isArray(shape.of) && (list = shape.of);
|
|
206
|
+
const seen = /* @__PURE__ */ new Set();
|
|
207
|
+
for (const item of list) {
|
|
208
|
+
const name = asShape(item).name;
|
|
209
|
+
if (typeof name == "string") {
|
|
210
|
+
if (seen.has(name)) return name;
|
|
211
|
+
seen.add(name);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
function compositeChecked(entries) {
|
|
216
|
+
return v.pipe(
|
|
217
|
+
v.strictObject(entries),
|
|
218
|
+
v.check(
|
|
219
|
+
(input) => compositeShapeOk(input),
|
|
220
|
+
(issue) => compositeShapeMessage(issue.input)
|
|
221
|
+
),
|
|
222
|
+
v.check(
|
|
223
|
+
(input) => duplicateSubfieldName(input) === void 0,
|
|
224
|
+
(issue) => `duplicate sub-field name "${duplicateSubfieldName(issue.input)}" \u2014 sub-field names must be unique within \`fields\` / \`of\``
|
|
225
|
+
)
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
const FieldShapeSchema = v.lazy(
|
|
229
|
+
() => compositeChecked({
|
|
230
|
+
type: FieldValueKindSchema,
|
|
231
|
+
name: FieldEntryName,
|
|
232
|
+
title: v.optional(v.string()),
|
|
233
|
+
description: v.optional(v.string()),
|
|
234
|
+
fields: v.optional(v.array(FieldShapeSchema)),
|
|
235
|
+
of: v.optional(v.array(FieldShapeSchema))
|
|
236
|
+
})
|
|
237
|
+
), StoredEditableSchema = v.union([v.literal(!0), NonEmpty]), AuthoringEditableSchema = v.union([v.literal(!0), v.array(NonEmpty), NonEmpty]);
|
|
238
|
+
function slotFields(editable) {
|
|
167
239
|
return {
|
|
168
|
-
type: FieldKindSchema,
|
|
169
240
|
name: FieldEntryName,
|
|
170
241
|
title: v.optional(v.string()),
|
|
171
242
|
description: v.optional(v.string()),
|
|
@@ -174,20 +245,47 @@ function fieldEntryFields(editable) {
|
|
|
174
245
|
* `initialFields`) or spawn (via the parent's `subworkflows.with`). A
|
|
175
246
|
* missing required entry throws rather than silently defaulting to
|
|
176
247
|
* `null`/`[]` — the same fail-fast an action's `required` param gets.
|
|
177
|
-
* Valid only on a workflow-scope `
|
|
248
|
+
* Valid only on a workflow-scope `input`-sourced entry (deploy invariant).
|
|
178
249
|
*/
|
|
179
250
|
required: v.optional(v.boolean()),
|
|
180
|
-
|
|
251
|
+
/**
|
|
252
|
+
* How this field SEEDS its value at materialisation — see
|
|
253
|
+
* {@link FieldSourceSchema}. Optional: an absent `initialValue` is working
|
|
254
|
+
* memory (the slot starts empty and an op fills it later), the common case.
|
|
255
|
+
*/
|
|
256
|
+
initialValue: v.optional(FieldSourceSchema),
|
|
181
257
|
/** Who-may-edit this slot via the edit seam — see {@link StoredEditableSchema}. */
|
|
182
258
|
editable: v.optional(editable)
|
|
183
259
|
};
|
|
184
260
|
}
|
|
185
|
-
|
|
261
|
+
function fieldEntryFields(editable) {
|
|
262
|
+
return {
|
|
263
|
+
type: FieldKindSchema,
|
|
264
|
+
...slotFields(editable),
|
|
265
|
+
/** Sub-field shapes for an `object` kind (see {@link compositeShapeOk}). */
|
|
266
|
+
fields: v.optional(v.array(FieldShapeSchema)),
|
|
267
|
+
/** Item sub-field shapes for an `array` kind (see {@link compositeShapeOk}). */
|
|
268
|
+
of: v.optional(v.array(FieldShapeSchema))
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
const FieldEntrySchema = compositeChecked(fieldEntryFields(StoredEditableSchema)), RawAuthoringFieldEntrySchema = compositeChecked(fieldEntryFields(AuthoringEditableSchema)), ClaimFieldSchema = v.strictObject({
|
|
186
272
|
type: v.literal("claim"),
|
|
187
273
|
name: FieldEntryName,
|
|
188
274
|
title: v.optional(v.string()),
|
|
189
275
|
description: v.optional(v.string())
|
|
190
|
-
})
|
|
276
|
+
});
|
|
277
|
+
function listSugarFields(type) {
|
|
278
|
+
return {
|
|
279
|
+
type: v.literal(type),
|
|
280
|
+
...slotFields(AuthoringEditableSchema)
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
const TodoListFieldSchema = v.strictObject(listSugarFields("todoList")), NotesFieldSchema = v.strictObject(listSugarFields("notes")), AuthoringFieldEntrySchema = v.union([
|
|
284
|
+
RawAuthoringFieldEntrySchema,
|
|
285
|
+
ClaimFieldSchema,
|
|
286
|
+
TodoListFieldSchema,
|
|
287
|
+
NotesFieldSchema
|
|
288
|
+
]), ConditionSchema = NonEmpty, EffectSchema = v.strictObject({
|
|
191
289
|
name: NonEmpty,
|
|
192
290
|
title: v.optional(v.string()),
|
|
193
291
|
description: v.optional(v.string()),
|
|
@@ -228,10 +326,10 @@ function actionFields(op) {
|
|
|
228
326
|
effects: v.optional(v.array(EffectSchema))
|
|
229
327
|
};
|
|
230
328
|
}
|
|
231
|
-
const StoredActionSchema = v.strictObject(actionFields(StoredOpSchema)),
|
|
329
|
+
const StoredActionSchema = v.strictObject(actionFields(StoredOpSchema)), TerminalActivityStatus = picklist(TERMINAL_ACTIVITY_STATUSES), RawAuthoringActionSchema = v.strictObject({
|
|
232
330
|
...actionFields(AuthoringOpSchema),
|
|
233
331
|
roles: v.optional(v.array(NonEmpty)),
|
|
234
|
-
status: v.optional(
|
|
332
|
+
status: v.optional(TerminalActivityStatus)
|
|
235
333
|
}), ClaimActionSchema = v.strictObject({
|
|
236
334
|
type: v.literal("claim"),
|
|
237
335
|
name: NonEmpty,
|
|
@@ -258,17 +356,27 @@ const StoredActionSchema = v.strictObject(actionFields(StoredOpSchema)), Termina
|
|
|
258
356
|
*/
|
|
259
357
|
context: v.optional(v.record(NonEmpty, ConditionSchema))
|
|
260
358
|
});
|
|
261
|
-
function
|
|
359
|
+
function activityFields(field, action, op, target) {
|
|
262
360
|
return {
|
|
263
361
|
name: NonEmpty,
|
|
264
362
|
title: v.optional(v.string()),
|
|
265
363
|
description: v.optional(v.string()),
|
|
364
|
+
/**
|
|
365
|
+
* Advisory BPMN-aligned classification of this activity by its executor (see
|
|
366
|
+
* {@link ACTIVITY_KINDS}). Optional and derived from the activity's shape when
|
|
367
|
+
* omitted; declaring it lets deploy check the shape matches the lane.
|
|
368
|
+
* Changes no gating or resolution — a label for tooling, like `assignees`.
|
|
369
|
+
*/
|
|
370
|
+
kind: v.optional(picklist(ACTIVITY_KINDS)),
|
|
371
|
+
/** Deep-link target for a `kind: "manual"` activity (off-system work). Render-only
|
|
372
|
+
* metadata; only valid on a manual activity (deploy-checked). */
|
|
373
|
+
target: v.optional(target),
|
|
266
374
|
activation: v.optional(picklist(["auto", "manual"])),
|
|
267
375
|
filter: v.optional(ConditionSchema),
|
|
268
376
|
/**
|
|
269
377
|
* Readiness gates, by name — conditions over the rendered scope that must
|
|
270
|
-
* hold for the
|
|
271
|
-
* (visibility). An unmet requirement keeps the
|
|
378
|
+
* hold for the activity to be *executable*, orthogonal to `filter`
|
|
379
|
+
* (visibility). An unmet requirement keeps the activity visible but disables
|
|
272
380
|
* its actions with a `requirements-unmet` verdict naming the unmet keys;
|
|
273
381
|
* all must hold (any-of lives inside one condition). Advisory like every
|
|
274
382
|
* engine gate — the lake still enforces. Distinct from ACL (authorization)
|
|
@@ -277,8 +385,8 @@ function taskFields(field, action, op) {
|
|
|
277
385
|
requirements: v.optional(v.record(NonEmpty, ConditionSchema)),
|
|
278
386
|
/**
|
|
279
387
|
* Auto-completion condition — evaluated at activation and on every
|
|
280
|
-
* cascade; truthy flips the
|
|
281
|
-
* spawning
|
|
388
|
+
* cascade; truthy flips the activity to `done` with a system actor. On a
|
|
389
|
+
* spawning activity it typically reads `$subworkflows`.
|
|
282
390
|
*/
|
|
283
391
|
completeWhen: v.optional(ConditionSchema),
|
|
284
392
|
/**
|
|
@@ -291,14 +399,19 @@ function taskFields(field, action, op) {
|
|
|
291
399
|
effects: v.optional(v.array(EffectSchema)),
|
|
292
400
|
actions: v.optional(v.array(action)),
|
|
293
401
|
subworkflows: v.optional(SubworkflowsSchema),
|
|
294
|
-
/**
|
|
402
|
+
/** Activity-scoped field entries. Resolved at activity activation time. */
|
|
295
403
|
fields: v.optional(v.array(field))
|
|
296
404
|
};
|
|
297
405
|
}
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
),
|
|
301
|
-
|
|
406
|
+
const StoredActivitySchema = v.strictObject(
|
|
407
|
+
activityFields(FieldEntrySchema, StoredActionSchema, StoredOpSchema, StoredManualTargetSchema)
|
|
408
|
+
), AuthoringActivitySchema = v.strictObject(
|
|
409
|
+
activityFields(
|
|
410
|
+
AuthoringFieldEntrySchema,
|
|
411
|
+
AuthoringActionSchema,
|
|
412
|
+
AuthoringOpSchema,
|
|
413
|
+
AuthoringManualTargetSchema
|
|
414
|
+
)
|
|
302
415
|
);
|
|
303
416
|
function transitionFields(op, filter) {
|
|
304
417
|
return {
|
|
@@ -352,12 +465,12 @@ const StoredTransitionSchema = v.strictObject(
|
|
|
352
465
|
*/
|
|
353
466
|
metadata: v.optional(v.record(NonEmpty, NonEmpty))
|
|
354
467
|
});
|
|
355
|
-
function stageFields(field,
|
|
468
|
+
function stageFields(field, activity, transition, editable) {
|
|
356
469
|
return {
|
|
357
470
|
name: NonEmpty,
|
|
358
471
|
title: v.optional(v.string()),
|
|
359
472
|
description: v.optional(v.string()),
|
|
360
|
-
|
|
473
|
+
activities: v.optional(v.array(activity)),
|
|
361
474
|
transitions: v.optional(v.array(transition)),
|
|
362
475
|
/**
|
|
363
476
|
* Lake mutation guards active while this stage holds. Each compiles to a
|
|
@@ -377,11 +490,11 @@ function stageFields(field, task, transition, editable) {
|
|
|
377
490
|
};
|
|
378
491
|
}
|
|
379
492
|
const StoredStageSchema = v.strictObject(
|
|
380
|
-
stageFields(FieldEntrySchema,
|
|
493
|
+
stageFields(FieldEntrySchema, StoredActivitySchema, StoredTransitionSchema, StoredEditableSchema)
|
|
381
494
|
), AuthoringStageSchema = v.strictObject(
|
|
382
495
|
stageFields(
|
|
383
496
|
AuthoringFieldEntrySchema,
|
|
384
|
-
|
|
497
|
+
AuthoringActivitySchema,
|
|
385
498
|
AuthoringTransitionSchema,
|
|
386
499
|
AuthoringEditableSchema
|
|
387
500
|
)
|
|
@@ -392,12 +505,11 @@ const StoredStageSchema = v.strictObject(
|
|
|
392
505
|
function workflowFields(field, stage) {
|
|
393
506
|
return {
|
|
394
507
|
name: NonEmpty,
|
|
395
|
-
version: PositiveInt,
|
|
396
508
|
title: NonEmpty,
|
|
397
509
|
description: v.optional(v.string()),
|
|
398
510
|
/**
|
|
399
511
|
* Whether a human may start this workflow standalone. `'child'` marks a
|
|
400
|
-
* spawn-only definition — instantiated by a parent via `
|
|
512
|
+
* spawn-only definition — instantiated by a parent via `activity.subworkflows`,
|
|
401
513
|
* never started cold from a picker. Omitted ⇒ `'workflow'` (startable).
|
|
402
514
|
* Advisory: consumers filter their start pickers on it (see
|
|
403
515
|
* {@link isStartableDefinition}); the engine does NOT refuse a
|
|
@@ -446,14 +558,16 @@ function formatPath(path) {
|
|
|
446
558
|
return out;
|
|
447
559
|
}
|
|
448
560
|
export {
|
|
561
|
+
ACTIVITY_KINDS,
|
|
449
562
|
AuthoringActionSchema,
|
|
563
|
+
AuthoringActivitySchema,
|
|
450
564
|
AuthoringFieldEntrySchema,
|
|
451
565
|
AuthoringOpSchema,
|
|
452
566
|
AuthoringStageSchema,
|
|
453
|
-
AuthoringTaskSchema,
|
|
454
567
|
AuthoringTransitionSchema,
|
|
455
568
|
AuthoringWorkflowSchema,
|
|
456
569
|
DOCUMENT_VALUE_PERMISSIONS,
|
|
570
|
+
DRIVER_KINDS,
|
|
457
571
|
EffectSchema,
|
|
458
572
|
GROQ_IDENTIFIER,
|
|
459
573
|
GuardSchema,
|
|
@@ -463,7 +577,8 @@ export {
|
|
|
463
577
|
expandRequiredRoles,
|
|
464
578
|
formatValidationError,
|
|
465
579
|
isStartableDefinition,
|
|
466
|
-
|
|
467
|
-
issuesFromValibot
|
|
580
|
+
isTerminalActivityStatus,
|
|
581
|
+
issuesFromValibot,
|
|
582
|
+
normalizeRoleAliases
|
|
468
583
|
};
|
|
469
584
|
//# sourceMappingURL=schema.js.map
|