@sanity/workflow-engine 0.11.0 → 0.13.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 +237 -116
- package/dist/_chunks-cjs/schema.cjs.map +1 -1
- package/dist/_chunks-es/schema.js +238 -117
- package/dist/_chunks-es/schema.js.map +1 -1
- package/dist/define.cjs +461 -210
- package/dist/define.cjs.map +1 -1
- package/dist/define.d.cts +1123 -9270
- package/dist/define.d.ts +1123 -9270
- package/dist/define.js +462 -211
- package/dist/define.js.map +1 -1
- package/dist/index.cjs +2244 -1384
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1706 -12804
- package/dist/index.d.ts +1706 -12804
- package/dist/index.js +2246 -1386
- 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,25 +17,29 @@ 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
|
-
function actorFulfillsRole(
|
|
23
|
+
function actorFulfillsRole({
|
|
24
|
+
actorRoles,
|
|
25
|
+
required,
|
|
26
|
+
aliases
|
|
27
|
+
}) {
|
|
18
28
|
if (actorRoles === void 0 || actorRoles.length === 0) return !1;
|
|
19
29
|
const accepted = new Set(expandRequiredRoles([required], aliases));
|
|
20
30
|
return actorRoles.some((role) => accepted.has(role));
|
|
21
31
|
}
|
|
22
|
-
const
|
|
23
|
-
function
|
|
24
|
-
return
|
|
32
|
+
const ACTIVITY_STATUSES = ["pending", "active", "done", "skipped", "failed"], TERMINAL_ACTIVITY_STATUSES = ["done", "skipped", "failed"];
|
|
33
|
+
function isTerminalActivityStatus(status) {
|
|
34
|
+
return TERMINAL_ACTIVITY_STATUSES.includes(status);
|
|
25
35
|
}
|
|
26
|
-
const FIELD_SCOPES = ["workflow", "stage", "
|
|
36
|
+
const FIELD_SCOPES = ["workflow", "stage", "activity"], DOCUMENT_VALUE_PERMISSIONS = ["create", "read", "update"], MUTATION_GUARD_ACTIONS = [
|
|
27
37
|
"create",
|
|
28
38
|
"update",
|
|
29
39
|
"delete",
|
|
30
40
|
"publish",
|
|
31
41
|
"unpublish"
|
|
32
|
-
],
|
|
42
|
+
], 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
43
|
function groqIdentifier(referencedAs) {
|
|
34
44
|
return v.pipe(
|
|
35
45
|
v.string(),
|
|
@@ -45,32 +55,31 @@ function picklist(options) {
|
|
|
45
55
|
`Invalid option: expected one of ${options.map((o) => `"${o}"`).join("|")}`
|
|
46
56
|
);
|
|
47
57
|
}
|
|
48
|
-
|
|
58
|
+
function pinned() {
|
|
59
|
+
return (schema, ..._exact) => schema;
|
|
60
|
+
}
|
|
61
|
+
const LiteralSchema = v.strictObject({ type: v.literal("literal"), value: v.unknown() }), FieldReadSchema = v.strictObject({
|
|
62
|
+
type: v.literal("fieldRead"),
|
|
63
|
+
scope: v.optional(v.union([v.literal("workflow"), v.literal("stage")])),
|
|
64
|
+
field: NonEmpty,
|
|
65
|
+
path: v.optional(v.string())
|
|
66
|
+
}), FieldSourceSchema = v.union([
|
|
67
|
+
// The caller supplies it at start/spawn (`initialFields` / `subworkflows.with`).
|
|
68
|
+
v.strictObject({ type: v.literal("input") }),
|
|
69
|
+
// Computed once by running GROQ against the lake at materialisation.
|
|
70
|
+
v.strictObject({ type: v.literal("query"), query: NonEmpty }),
|
|
71
|
+
LiteralSchema,
|
|
72
|
+
FieldReadSchema
|
|
73
|
+
]), ValueExprSchema = v.lazy(
|
|
49
74
|
() => 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() }),
|
|
75
|
+
LiteralSchema,
|
|
76
|
+
FieldReadSchema,
|
|
59
77
|
v.strictObject({ type: v.literal("param"), param: NonEmpty }),
|
|
60
78
|
v.strictObject({ type: v.literal("actor") }),
|
|
61
79
|
v.strictObject({ type: v.literal("now") }),
|
|
62
80
|
v.strictObject({ type: v.literal("self") }),
|
|
63
81
|
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
|
-
})
|
|
82
|
+
v.strictObject({ type: v.literal("object"), fields: v.record(NonEmpty, ValueExprSchema) })
|
|
74
83
|
])
|
|
75
84
|
), StoredFieldRefSchema = v.strictObject({
|
|
76
85
|
scope: picklist(FIELD_SCOPES),
|
|
@@ -102,7 +111,7 @@ const StoredManualTargetSchema = manualTargetSchema(StoredFieldRefSchema), Autho
|
|
|
102
111
|
v.strictObject({
|
|
103
112
|
type: v.literal("field"),
|
|
104
113
|
field: NonEmpty,
|
|
105
|
-
equals:
|
|
114
|
+
equals: ValueExprSchema
|
|
106
115
|
}),
|
|
107
116
|
v.strictObject({ type: v.literal("all"), of: v.array(OpPredicateSchema) }),
|
|
108
117
|
v.strictObject({ type: v.literal("any"), of: v.array(OpPredicateSchema) })
|
|
@@ -113,7 +122,7 @@ function opSchemas(targetSchema) {
|
|
|
113
122
|
v.strictObject({
|
|
114
123
|
type: v.literal("field.set"),
|
|
115
124
|
target: targetSchema,
|
|
116
|
-
value:
|
|
125
|
+
value: ValueExprSchema
|
|
117
126
|
}),
|
|
118
127
|
v.strictObject({
|
|
119
128
|
type: v.literal("field.unset"),
|
|
@@ -122,13 +131,13 @@ function opSchemas(targetSchema) {
|
|
|
122
131
|
v.strictObject({
|
|
123
132
|
type: v.literal("field.append"),
|
|
124
133
|
target: targetSchema,
|
|
125
|
-
value:
|
|
134
|
+
value: ValueExprSchema
|
|
126
135
|
}),
|
|
127
136
|
v.strictObject({
|
|
128
137
|
type: v.literal("field.updateWhere"),
|
|
129
138
|
target: targetSchema,
|
|
130
139
|
where: OpPredicateSchema,
|
|
131
|
-
value:
|
|
140
|
+
value: ValueExprSchema
|
|
132
141
|
}),
|
|
133
142
|
v.strictObject({
|
|
134
143
|
type: v.literal("field.removeWhere"),
|
|
@@ -137,17 +146,17 @@ function opSchemas(targetSchema) {
|
|
|
137
146
|
})
|
|
138
147
|
];
|
|
139
148
|
}
|
|
140
|
-
const StoredOpSchema = v.variant("type", [
|
|
149
|
+
const StoredFieldOpSchema = v.variant("type", [...opSchemas(StoredFieldRefSchema)]), StoredOpSchema = v.variant("type", [
|
|
141
150
|
...opSchemas(StoredFieldRefSchema),
|
|
142
151
|
v.strictObject({
|
|
143
152
|
type: v.literal("status.set"),
|
|
144
|
-
|
|
145
|
-
status: picklist(
|
|
153
|
+
activity: NonEmpty,
|
|
154
|
+
status: picklist(ACTIVITY_STATUSES)
|
|
146
155
|
})
|
|
147
|
-
]), StoredTransitionOpSchema =
|
|
156
|
+
]), StoredTransitionOpSchema = StoredFieldOpSchema, AuditOpSchema = v.strictObject({
|
|
148
157
|
type: v.literal("audit"),
|
|
149
158
|
target: AuthoringFieldRefSchema,
|
|
150
|
-
value:
|
|
159
|
+
value: ValueExprSchema,
|
|
151
160
|
stampFields: v.optional(
|
|
152
161
|
v.strictObject({
|
|
153
162
|
actor: v.optional(NonEmpty),
|
|
@@ -158,33 +167,83 @@ const StoredOpSchema = v.variant("type", [
|
|
|
158
167
|
...opSchemas(AuthoringFieldRefSchema),
|
|
159
168
|
v.strictObject({
|
|
160
169
|
type: v.literal("status.set"),
|
|
161
|
-
|
|
162
|
-
status: picklist(
|
|
170
|
+
activity: v.optional(NonEmpty),
|
|
171
|
+
status: picklist(ACTIVITY_STATUSES)
|
|
163
172
|
}),
|
|
164
173
|
AuditOpSchema
|
|
165
|
-
]),
|
|
174
|
+
]), FIELD_VALUE_KINDS = [
|
|
166
175
|
"doc.ref",
|
|
167
176
|
"doc.refs",
|
|
168
177
|
// Release reference. A workflow declares this entry to say "I target a
|
|
169
178
|
// Content Release"; the runtime fills it at start time and auto-derives
|
|
170
179
|
// the instance's read perspective from it.
|
|
171
180
|
"release.ref",
|
|
172
|
-
"
|
|
173
|
-
"
|
|
174
|
-
"
|
|
175
|
-
"
|
|
176
|
-
"
|
|
177
|
-
"
|
|
178
|
-
"
|
|
179
|
-
"
|
|
180
|
-
|
|
181
|
+
"string",
|
|
182
|
+
"text",
|
|
183
|
+
"number",
|
|
184
|
+
"boolean",
|
|
185
|
+
"date",
|
|
186
|
+
"datetime",
|
|
187
|
+
"url",
|
|
188
|
+
"actor",
|
|
189
|
+
// A single {@link Assignee} — the singular of `assignees`.
|
|
190
|
+
"assignee",
|
|
181
191
|
// The WHO-FOR entry: the inbox reverse-query reads it by kind, and the
|
|
182
192
|
// rendered `$assigned` gate matches the caller against it.
|
|
183
|
-
"assignees"
|
|
184
|
-
|
|
185
|
-
|
|
193
|
+
"assignees",
|
|
194
|
+
// Compositional kinds — mirror Sanity's `object.fields` / `array.of`.
|
|
195
|
+
"object",
|
|
196
|
+
"array"
|
|
197
|
+
], FieldValueKindSchema = picklist(FIELD_VALUE_KINDS), FieldKindSchema = picklist(FIELD_VALUE_KINDS), FieldEntryName = groqIdentifier("`$fields.<name>`");
|
|
198
|
+
function asShape(input) {
|
|
199
|
+
return typeof input == "object" && input !== null ? input : {};
|
|
200
|
+
}
|
|
201
|
+
function compositeShapeOk(input) {
|
|
202
|
+
const shape = asShape(input);
|
|
203
|
+
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;
|
|
204
|
+
}
|
|
205
|
+
function compositeShapeMessage(input) {
|
|
206
|
+
const shape = asShape(input);
|
|
207
|
+
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)}"`;
|
|
208
|
+
}
|
|
209
|
+
function duplicateSubfieldName(input) {
|
|
210
|
+
const shape = asShape(input);
|
|
211
|
+
let list = [];
|
|
212
|
+
Array.isArray(shape.fields) ? list = shape.fields : Array.isArray(shape.of) && (list = shape.of);
|
|
213
|
+
const seen = /* @__PURE__ */ new Set();
|
|
214
|
+
for (const item of list) {
|
|
215
|
+
const name = asShape(item).name;
|
|
216
|
+
if (typeof name == "string") {
|
|
217
|
+
if (seen.has(name)) return name;
|
|
218
|
+
seen.add(name);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function compositeChecked(entries) {
|
|
223
|
+
return v.pipe(
|
|
224
|
+
v.strictObject(entries),
|
|
225
|
+
v.check(
|
|
226
|
+
(input) => compositeShapeOk(input),
|
|
227
|
+
(issue) => compositeShapeMessage(issue.input)
|
|
228
|
+
),
|
|
229
|
+
v.check(
|
|
230
|
+
(input) => duplicateSubfieldName(input) === void 0,
|
|
231
|
+
(issue) => `duplicate sub-field name "${duplicateSubfieldName(issue.input)}" \u2014 sub-field names must be unique within \`fields\` / \`of\``
|
|
232
|
+
)
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
const FieldShapeSchema = v.lazy(
|
|
236
|
+
() => compositeChecked({
|
|
237
|
+
type: FieldValueKindSchema,
|
|
238
|
+
name: FieldEntryName,
|
|
239
|
+
title: v.optional(v.string()),
|
|
240
|
+
description: v.optional(v.string()),
|
|
241
|
+
fields: v.optional(v.array(FieldShapeSchema)),
|
|
242
|
+
of: v.optional(v.array(FieldShapeSchema))
|
|
243
|
+
})
|
|
244
|
+
), StoredEditableSchema = v.union([v.literal(!0), NonEmpty]), AuthoringEditableSchema = v.union([v.literal(!0), v.array(NonEmpty), NonEmpty]);
|
|
245
|
+
function slotFields(editable) {
|
|
186
246
|
return {
|
|
187
|
-
type: FieldKindSchema,
|
|
188
247
|
name: FieldEntryName,
|
|
189
248
|
title: v.optional(v.string()),
|
|
190
249
|
description: v.optional(v.string()),
|
|
@@ -193,20 +252,50 @@ function fieldEntryFields(editable) {
|
|
|
193
252
|
* `initialFields`) or spawn (via the parent's `subworkflows.with`). A
|
|
194
253
|
* missing required entry throws rather than silently defaulting to
|
|
195
254
|
* `null`/`[]` — the same fail-fast an action's `required` param gets.
|
|
196
|
-
* Valid only on a workflow-scope `
|
|
255
|
+
* Valid only on a workflow-scope `input`-sourced entry (deploy invariant).
|
|
197
256
|
*/
|
|
198
257
|
required: v.optional(v.boolean()),
|
|
199
|
-
|
|
258
|
+
/**
|
|
259
|
+
* How this field SEEDS its value at materialisation — see
|
|
260
|
+
* {@link FieldSourceSchema}. Optional: an absent `initialValue` is working
|
|
261
|
+
* memory (the slot starts empty and an op fills it later), the common case.
|
|
262
|
+
*/
|
|
263
|
+
initialValue: v.optional(FieldSourceSchema),
|
|
200
264
|
/** Who-may-edit this slot via the edit seam — see {@link StoredEditableSchema}. */
|
|
201
265
|
editable: v.optional(editable)
|
|
202
266
|
};
|
|
203
267
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
268
|
+
function fieldEntryFields(editable) {
|
|
269
|
+
return {
|
|
270
|
+
type: FieldKindSchema,
|
|
271
|
+
...slotFields(editable),
|
|
272
|
+
/** Sub-field shapes for an `object` kind (see {@link compositeShapeOk}). */
|
|
273
|
+
fields: v.optional(v.array(FieldShapeSchema)),
|
|
274
|
+
/** Item sub-field shapes for an `array` kind (see {@link compositeShapeOk}). */
|
|
275
|
+
of: v.optional(v.array(FieldShapeSchema))
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
const FieldEntrySchema = pinned()(
|
|
279
|
+
compositeChecked(fieldEntryFields(StoredEditableSchema))
|
|
280
|
+
), RawAuthoringFieldEntrySchema = pinned()(
|
|
281
|
+
compositeChecked(fieldEntryFields(AuthoringEditableSchema))
|
|
282
|
+
), ClaimFieldSchema = pinned()(
|
|
283
|
+
v.strictObject({
|
|
284
|
+
type: v.literal("claim"),
|
|
285
|
+
name: FieldEntryName,
|
|
286
|
+
title: v.optional(v.string()),
|
|
287
|
+
description: v.optional(v.string())
|
|
288
|
+
})
|
|
289
|
+
);
|
|
290
|
+
function listSugarFields(type) {
|
|
291
|
+
return {
|
|
292
|
+
type: v.literal(type),
|
|
293
|
+
...slotFields(AuthoringEditableSchema)
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
const TodoListFieldSchema = pinned()(v.strictObject(listSugarFields("todoList"))), NotesFieldSchema = pinned()(v.strictObject(listSugarFields("notes"))), AuthoringFieldEntrySchema = pinned()(
|
|
297
|
+
v.union([RawAuthoringFieldEntrySchema, ClaimFieldSchema, TodoListFieldSchema, NotesFieldSchema])
|
|
298
|
+
), ConditionSchema = NonEmpty, EffectSchema = v.strictObject({
|
|
210
299
|
name: NonEmpty,
|
|
211
300
|
title: v.optional(v.string()),
|
|
212
301
|
description: v.optional(v.string()),
|
|
@@ -247,21 +336,27 @@ function actionFields(op) {
|
|
|
247
336
|
effects: v.optional(v.array(EffectSchema))
|
|
248
337
|
};
|
|
249
338
|
}
|
|
250
|
-
const StoredActionSchema = v.strictObject(actionFields(StoredOpSchema)),
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
339
|
+
const StoredActionSchema = pinned()(v.strictObject(actionFields(StoredOpSchema))), TerminalActivityStatus = picklist(TERMINAL_ACTIVITY_STATUSES), RawAuthoringActionSchema = pinned()(
|
|
340
|
+
v.strictObject({
|
|
341
|
+
...actionFields(AuthoringOpSchema),
|
|
342
|
+
roles: v.optional(v.array(NonEmpty)),
|
|
343
|
+
status: v.optional(TerminalActivityStatus)
|
|
344
|
+
})
|
|
345
|
+
), ClaimActionSchema = pinned()(
|
|
346
|
+
v.strictObject({
|
|
347
|
+
type: v.literal("claim"),
|
|
348
|
+
name: NonEmpty,
|
|
349
|
+
title: v.optional(v.string()),
|
|
350
|
+
description: v.optional(v.string()),
|
|
351
|
+
field: v.union([NonEmpty, AuthoringFieldRefSchema]),
|
|
352
|
+
roles: v.optional(v.array(NonEmpty)),
|
|
353
|
+
filter: v.optional(ConditionSchema),
|
|
354
|
+
params: v.optional(v.array(ActionParamSchema)),
|
|
355
|
+
effects: v.optional(v.array(EffectSchema))
|
|
356
|
+
})
|
|
357
|
+
), AuthoringActionSchema = pinned()(
|
|
358
|
+
v.union([RawAuthoringActionSchema, ClaimActionSchema])
|
|
359
|
+
), DefinitionRefSchema = v.strictObject({
|
|
265
360
|
name: NonEmpty,
|
|
266
361
|
version: v.optional(v.union([PositiveInt, v.literal("latest")]))
|
|
267
362
|
}), SubworkflowsSchema = v.strictObject({
|
|
@@ -277,27 +372,27 @@ const StoredActionSchema = v.strictObject(actionFields(StoredOpSchema)), Termina
|
|
|
277
372
|
*/
|
|
278
373
|
context: v.optional(v.record(NonEmpty, ConditionSchema))
|
|
279
374
|
});
|
|
280
|
-
function
|
|
375
|
+
function activityFields({ field, action, op, target }) {
|
|
281
376
|
return {
|
|
282
377
|
name: NonEmpty,
|
|
283
378
|
title: v.optional(v.string()),
|
|
284
379
|
description: v.optional(v.string()),
|
|
285
380
|
/**
|
|
286
|
-
* Advisory BPMN-aligned classification of this
|
|
287
|
-
* {@link
|
|
381
|
+
* Advisory BPMN-aligned classification of this activity by its executor (see
|
|
382
|
+
* {@link ACTIVITY_KINDS}). Optional and derived from the activity's shape when
|
|
288
383
|
* omitted; declaring it lets deploy check the shape matches the lane.
|
|
289
384
|
* Changes no gating or resolution — a label for tooling, like `assignees`.
|
|
290
385
|
*/
|
|
291
|
-
kind: v.optional(picklist(
|
|
292
|
-
/** Deep-link target for a `kind: "manual"`
|
|
293
|
-
* metadata; only valid on a manual
|
|
386
|
+
kind: v.optional(picklist(ACTIVITY_KINDS)),
|
|
387
|
+
/** Deep-link target for a `kind: "manual"` activity (off-system work). Render-only
|
|
388
|
+
* metadata; only valid on a manual activity (deploy-checked). */
|
|
294
389
|
target: v.optional(target),
|
|
295
390
|
activation: v.optional(picklist(["auto", "manual"])),
|
|
296
391
|
filter: v.optional(ConditionSchema),
|
|
297
392
|
/**
|
|
298
393
|
* Readiness gates, by name — conditions over the rendered scope that must
|
|
299
|
-
* hold for the
|
|
300
|
-
* (visibility). An unmet requirement keeps the
|
|
394
|
+
* hold for the activity to be *executable*, orthogonal to `filter`
|
|
395
|
+
* (visibility). An unmet requirement keeps the activity visible but disables
|
|
301
396
|
* its actions with a `requirements-unmet` verdict naming the unmet keys;
|
|
302
397
|
* all must hold (any-of lives inside one condition). Advisory like every
|
|
303
398
|
* engine gate — the lake still enforces. Distinct from ACL (authorization)
|
|
@@ -306,8 +401,8 @@ function taskFields(field, action, op, target) {
|
|
|
306
401
|
requirements: v.optional(v.record(NonEmpty, ConditionSchema)),
|
|
307
402
|
/**
|
|
308
403
|
* Auto-completion condition — evaluated at activation and on every
|
|
309
|
-
* cascade; truthy flips the
|
|
310
|
-
* spawning
|
|
404
|
+
* cascade; truthy flips the activity to `done` with a system actor. On a
|
|
405
|
+
* spawning activity it typically reads `$subworkflows`.
|
|
311
406
|
*/
|
|
312
407
|
completeWhen: v.optional(ConditionSchema),
|
|
313
408
|
/**
|
|
@@ -320,18 +415,27 @@ function taskFields(field, action, op, target) {
|
|
|
320
415
|
effects: v.optional(v.array(EffectSchema)),
|
|
321
416
|
actions: v.optional(v.array(action)),
|
|
322
417
|
subworkflows: v.optional(SubworkflowsSchema),
|
|
323
|
-
/**
|
|
418
|
+
/** Activity-scoped field entries. Resolved at activity activation time. */
|
|
324
419
|
fields: v.optional(v.array(field))
|
|
325
420
|
};
|
|
326
421
|
}
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
422
|
+
const StoredActivitySchema = pinned()(
|
|
423
|
+
v.strictObject(
|
|
424
|
+
activityFields({
|
|
425
|
+
field: FieldEntrySchema,
|
|
426
|
+
action: StoredActionSchema,
|
|
427
|
+
op: StoredOpSchema,
|
|
428
|
+
target: StoredManualTargetSchema
|
|
429
|
+
})
|
|
430
|
+
)
|
|
431
|
+
), AuthoringActivitySchema = pinned()(
|
|
432
|
+
v.strictObject(
|
|
433
|
+
activityFields({
|
|
434
|
+
field: AuthoringFieldEntrySchema,
|
|
435
|
+
action: AuthoringActionSchema,
|
|
436
|
+
op: AuthoringOpSchema,
|
|
437
|
+
target: AuthoringManualTargetSchema
|
|
438
|
+
})
|
|
335
439
|
)
|
|
336
440
|
);
|
|
337
441
|
function transitionFields(op, filter) {
|
|
@@ -346,13 +450,13 @@ function transitionFields(op, filter) {
|
|
|
346
450
|
effects: v.optional(v.array(EffectSchema))
|
|
347
451
|
};
|
|
348
452
|
}
|
|
349
|
-
const StoredTransitionSchema =
|
|
350
|
-
transitionFields(StoredTransitionOpSchema, ConditionSchema)
|
|
453
|
+
const StoredTransitionSchema = pinned()(
|
|
454
|
+
v.strictObject(transitionFields(StoredTransitionOpSchema, ConditionSchema))
|
|
351
455
|
), AuthoringTransitionOpSchema = v.variant("type", [
|
|
352
456
|
...opSchemas(AuthoringFieldRefSchema),
|
|
353
457
|
AuditOpSchema
|
|
354
|
-
]), AuthoringTransitionSchema =
|
|
355
|
-
transitionFields(AuthoringTransitionOpSchema, v.optional(ConditionSchema))
|
|
458
|
+
]), AuthoringTransitionSchema = pinned()(
|
|
459
|
+
v.strictObject(transitionFields(AuthoringTransitionOpSchema, v.optional(ConditionSchema)))
|
|
356
460
|
), GuardActionSchema = picklist(MUTATION_GUARD_ACTIONS), GuardMatchSchema = v.strictObject({
|
|
357
461
|
/** Subject `_type`(s); empty matches any type. */
|
|
358
462
|
types: v.optional(v.array(NonEmpty)),
|
|
@@ -386,12 +490,17 @@ const StoredTransitionSchema = v.strictObject(
|
|
|
386
490
|
*/
|
|
387
491
|
metadata: v.optional(v.record(NonEmpty, NonEmpty))
|
|
388
492
|
});
|
|
389
|
-
function stageFields(
|
|
493
|
+
function stageFields({
|
|
494
|
+
field,
|
|
495
|
+
activity,
|
|
496
|
+
transition,
|
|
497
|
+
editable
|
|
498
|
+
}) {
|
|
390
499
|
return {
|
|
391
500
|
name: NonEmpty,
|
|
392
501
|
title: v.optional(v.string()),
|
|
393
502
|
description: v.optional(v.string()),
|
|
394
|
-
|
|
503
|
+
activities: v.optional(v.array(activity)),
|
|
395
504
|
transitions: v.optional(v.array(transition)),
|
|
396
505
|
/**
|
|
397
506
|
* Lake mutation guards active while this stage holds. Each compiles to a
|
|
@@ -410,14 +519,23 @@ function stageFields(field, task, transition, editable) {
|
|
|
410
519
|
editable: v.optional(v.record(FieldEntryName, editable))
|
|
411
520
|
};
|
|
412
521
|
}
|
|
413
|
-
const StoredStageSchema =
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
522
|
+
const StoredStageSchema = pinned()(
|
|
523
|
+
v.strictObject(
|
|
524
|
+
stageFields({
|
|
525
|
+
field: FieldEntrySchema,
|
|
526
|
+
activity: StoredActivitySchema,
|
|
527
|
+
transition: StoredTransitionSchema,
|
|
528
|
+
editable: StoredEditableSchema
|
|
529
|
+
})
|
|
530
|
+
)
|
|
531
|
+
), AuthoringStageSchema = pinned()(
|
|
532
|
+
v.strictObject(
|
|
533
|
+
stageFields({
|
|
534
|
+
field: AuthoringFieldEntrySchema,
|
|
535
|
+
activity: AuthoringActivitySchema,
|
|
536
|
+
transition: AuthoringTransitionSchema,
|
|
537
|
+
editable: AuthoringEditableSchema
|
|
538
|
+
})
|
|
421
539
|
)
|
|
422
540
|
), RoleAliasesSchema = v.record(
|
|
423
541
|
NonEmpty,
|
|
@@ -426,12 +544,11 @@ const StoredStageSchema = v.strictObject(
|
|
|
426
544
|
function workflowFields(field, stage) {
|
|
427
545
|
return {
|
|
428
546
|
name: NonEmpty,
|
|
429
|
-
version: PositiveInt,
|
|
430
547
|
title: NonEmpty,
|
|
431
548
|
description: v.optional(v.string()),
|
|
432
549
|
/**
|
|
433
550
|
* Whether a human may start this workflow standalone. `'child'` marks a
|
|
434
|
-
* spawn-only definition — instantiated by a parent via `
|
|
551
|
+
* spawn-only definition — instantiated by a parent via `activity.subworkflows`,
|
|
435
552
|
* never started cold from a picker. Omitted ⇒ `'workflow'` (startable).
|
|
436
553
|
* Advisory: consumers filter their start pickers on it (see
|
|
437
554
|
* {@link isStartableDefinition}); the engine does NOT refuse a
|
|
@@ -454,9 +571,11 @@ function workflowFields(field, stage) {
|
|
|
454
571
|
roleAliases: v.optional(RoleAliasesSchema)
|
|
455
572
|
};
|
|
456
573
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
574
|
+
pinned()(
|
|
575
|
+
v.strictObject(workflowFields(FieldEntrySchema, StoredStageSchema))
|
|
576
|
+
);
|
|
577
|
+
const AuthoringWorkflowSchema = pinned()(
|
|
578
|
+
v.strictObject(workflowFields(AuthoringFieldEntrySchema, AuthoringStageSchema))
|
|
460
579
|
), WORKFLOW_DEFINITION_TYPE = "sanity.workflow.definition";
|
|
461
580
|
function isStartableDefinition(definition) {
|
|
462
581
|
return definition.role !== "child";
|
|
@@ -480,11 +599,12 @@ function formatPath(path) {
|
|
|
480
599
|
return out;
|
|
481
600
|
}
|
|
482
601
|
export {
|
|
602
|
+
ACTIVITY_KINDS,
|
|
483
603
|
AuthoringActionSchema,
|
|
604
|
+
AuthoringActivitySchema,
|
|
484
605
|
AuthoringFieldEntrySchema,
|
|
485
606
|
AuthoringOpSchema,
|
|
486
607
|
AuthoringStageSchema,
|
|
487
|
-
AuthoringTaskSchema,
|
|
488
608
|
AuthoringTransitionSchema,
|
|
489
609
|
AuthoringWorkflowSchema,
|
|
490
610
|
DOCUMENT_VALUE_PERMISSIONS,
|
|
@@ -492,14 +612,15 @@ export {
|
|
|
492
612
|
EffectSchema,
|
|
493
613
|
GROQ_IDENTIFIER,
|
|
494
614
|
GuardSchema,
|
|
495
|
-
|
|
615
|
+
StoredFieldOpSchema,
|
|
496
616
|
WORKFLOW_DEFINITION_TYPE,
|
|
497
617
|
actorFulfillsRole,
|
|
498
618
|
andConditions,
|
|
499
619
|
expandRequiredRoles,
|
|
500
620
|
formatValidationError,
|
|
501
621
|
isStartableDefinition,
|
|
502
|
-
|
|
503
|
-
issuesFromValibot
|
|
622
|
+
isTerminalActivityStatus,
|
|
623
|
+
issuesFromValibot,
|
|
624
|
+
normalizeRoleAliases
|
|
504
625
|
};
|
|
505
626
|
//# sourceMappingURL=schema.js.map
|