@sanity/workflow-engine 0.3.0 → 0.4.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 +291 -317
- package/dist/_chunks-cjs/schema.cjs.map +1 -1
- package/dist/_chunks-es/schema.js +291 -317
- package/dist/_chunks-es/schema.js.map +1 -1
- package/dist/define.cjs +480 -74
- package/dist/define.cjs.map +1 -1
- package/dist/define.d.cts +7404 -4450
- package/dist/define.d.ts +7404 -4450
- package/dist/define.js +482 -76
- package/dist/define.js.map +1 -1
- package/dist/index.cjs +1650 -1521
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10557 -5214
- package/dist/index.d.ts +10557 -5214
- package/dist/index.js +1651 -1522
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -16,195 +16,170 @@ function _interopNamespaceCompat(e) {
|
|
|
16
16
|
}), n.default = e, Object.freeze(n);
|
|
17
17
|
}
|
|
18
18
|
var v__namespace = /* @__PURE__ */ _interopNamespaceCompat(v);
|
|
19
|
-
const TASK_STATUSES = ["pending", "active", "done", "skipped", "failed"],
|
|
19
|
+
const TASK_STATUSES = ["pending", "active", "done", "skipped", "failed"], TERMINAL_TASK_STATUSES = ["done", "skipped", "failed"];
|
|
20
|
+
function isTerminalTaskStatus(status) {
|
|
21
|
+
return TERMINAL_TASK_STATUSES.includes(status);
|
|
22
|
+
}
|
|
23
|
+
const STATE_SCOPES = ["workflow", "stage", "task"], DOCUMENT_VALUE_PERMISSIONS = ["create", "read", "update"], MUTATION_GUARD_ACTIONS = [
|
|
20
24
|
"create",
|
|
21
25
|
"update",
|
|
22
26
|
"delete",
|
|
23
27
|
"publish",
|
|
24
28
|
"unpublish"
|
|
25
|
-
], NonEmpty = v__namespace.pipe(v__namespace.string(), v__namespace.minLength(1, "must be a non-empty string")), PositiveInt = v__namespace.pipe(v__namespace.number(), v__namespace.integer(), v__namespace.minValue(1))
|
|
29
|
+
], NonEmpty = v__namespace.pipe(v__namespace.string(), v__namespace.minLength(1, "must be a non-empty string")), PositiveInt = v__namespace.pipe(v__namespace.number(), v__namespace.integer(), v__namespace.minValue(1)), GROQ_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
30
|
+
function groqIdentifier(referencedAs) {
|
|
31
|
+
return v__namespace.pipe(
|
|
32
|
+
v__namespace.string(),
|
|
33
|
+
v__namespace.regex(
|
|
34
|
+
GROQ_IDENTIFIER,
|
|
35
|
+
`must be a GROQ-safe identifier (letters, digits, underscore; not starting with a digit) because it is referenced as ${referencedAs} in GROQ conditions`
|
|
36
|
+
)
|
|
37
|
+
);
|
|
38
|
+
}
|
|
26
39
|
function picklist(options) {
|
|
27
40
|
return v__namespace.picklist(
|
|
28
41
|
options,
|
|
29
42
|
`Invalid option: expected one of ${options.map((o) => `"${o}"`).join("|")}`
|
|
30
43
|
);
|
|
31
44
|
}
|
|
32
|
-
const
|
|
33
|
-
id: v__namespace.pipe(
|
|
34
|
-
v__namespace.string(),
|
|
35
|
-
v__namespace.regex(
|
|
36
|
-
/^(dataset|canvas|media-library|dashboard):/,
|
|
37
|
-
"must be a GDR URI of form '<scheme>:<...id-parts>' where scheme is one of: dataset, canvas, media-library, dashboard"
|
|
38
|
-
)
|
|
39
|
-
),
|
|
40
|
-
type: NonEmpty
|
|
41
|
-
}), SourceSchema = v__namespace.lazy(
|
|
45
|
+
const SourceSchema = v__namespace.lazy(
|
|
42
46
|
() => v__namespace.union([
|
|
47
|
+
// State-entry origins: who fills the entry, and when.
|
|
48
|
+
v__namespace.strictObject({ type: v__namespace.literal("init") }),
|
|
49
|
+
v__namespace.strictObject({ type: v__namespace.literal("write") }),
|
|
43
50
|
v__namespace.strictObject({
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}),
|
|
47
|
-
v__namespace.strictObject({ source: v__namespace.literal("param"), paramId: NonEmpty }),
|
|
48
|
-
v__namespace.strictObject({ source: v__namespace.literal("actor") }),
|
|
49
|
-
v__namespace.strictObject({ source: v__namespace.literal("now") }),
|
|
50
|
-
v__namespace.strictObject({ source: v__namespace.literal("self") }),
|
|
51
|
-
v__namespace.strictObject({ source: v__namespace.literal("stageId") }),
|
|
52
|
-
v__namespace.strictObject({
|
|
53
|
-
source: v__namespace.literal("stateRead"),
|
|
54
|
-
scope: picklist(STATE_SCOPES),
|
|
55
|
-
slotId: NonEmpty,
|
|
56
|
-
path: v__namespace.optional(v__namespace.string())
|
|
51
|
+
type: v__namespace.literal("query"),
|
|
52
|
+
query: NonEmpty
|
|
57
53
|
}),
|
|
58
|
-
//
|
|
59
|
-
|
|
54
|
+
// Value sources: resolved to concrete JSON when an op or seed applies.
|
|
55
|
+
v__namespace.strictObject({ type: v__namespace.literal("literal"), value: v__namespace.unknown() }),
|
|
56
|
+
v__namespace.strictObject({ type: v__namespace.literal("param"), param: NonEmpty }),
|
|
57
|
+
v__namespace.strictObject({ type: v__namespace.literal("actor") }),
|
|
58
|
+
v__namespace.strictObject({ type: v__namespace.literal("now") }),
|
|
59
|
+
v__namespace.strictObject({ type: v__namespace.literal("self") }),
|
|
60
|
+
v__namespace.strictObject({ type: v__namespace.literal("stage") }),
|
|
60
61
|
v__namespace.strictObject({
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
type: v__namespace.literal("stateRead"),
|
|
63
|
+
scope: v__namespace.optional(v__namespace.union([v__namespace.literal("workflow"), v__namespace.literal("stage")])),
|
|
64
|
+
state: NonEmpty,
|
|
63
65
|
path: v__namespace.optional(v__namespace.string())
|
|
64
66
|
}),
|
|
65
|
-
v__namespace.strictObject({ source: v__namespace.literal("row"), path: v__namespace.optional(v__namespace.string()) }),
|
|
66
67
|
v__namespace.strictObject({
|
|
67
|
-
|
|
68
|
-
slotId: NonEmpty,
|
|
69
|
-
path: v__namespace.optional(v__namespace.string())
|
|
70
|
-
}),
|
|
71
|
-
// Compound object source — resolves each field's Source recursively
|
|
72
|
-
// and packages the result into a JSON object. Lets ops append rich
|
|
73
|
-
// rows to `checklist` / `notes` / `assignees` slots, e.g.
|
|
74
|
-
// `{ source: "object", fields: { signer: { source: "actor" },
|
|
75
|
-
// at: { source: "now" } } }`.
|
|
76
|
-
v__namespace.strictObject({
|
|
77
|
-
source: v__namespace.literal("object"),
|
|
68
|
+
type: v__namespace.literal("object"),
|
|
78
69
|
fields: v__namespace.record(NonEmpty, SourceSchema)
|
|
79
70
|
})
|
|
80
71
|
])
|
|
81
|
-
),
|
|
72
|
+
), StoredStateRefSchema = v__namespace.strictObject({
|
|
82
73
|
scope: picklist(STATE_SCOPES),
|
|
83
|
-
|
|
74
|
+
state: NonEmpty
|
|
75
|
+
}), AuthoringStateRefSchema = v__namespace.strictObject({
|
|
76
|
+
scope: v__namespace.optional(picklist(STATE_SCOPES)),
|
|
77
|
+
state: NonEmpty
|
|
84
78
|
}), OpPredicateSchema = v__namespace.lazy(
|
|
85
79
|
() => v__namespace.union([
|
|
86
80
|
v__namespace.strictObject({
|
|
81
|
+
type: v__namespace.literal("field"),
|
|
87
82
|
field: NonEmpty,
|
|
88
83
|
equals: SourceSchema
|
|
89
84
|
}),
|
|
90
|
-
v__namespace.strictObject({ all: v__namespace.array(OpPredicateSchema) }),
|
|
91
|
-
v__namespace.strictObject({ any: v__namespace.array(OpPredicateSchema) })
|
|
85
|
+
v__namespace.strictObject({ type: v__namespace.literal("all"), of: v__namespace.array(OpPredicateSchema) }),
|
|
86
|
+
v__namespace.strictObject({ type: v__namespace.literal("any"), of: v__namespace.array(OpPredicateSchema) })
|
|
92
87
|
])
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
88
|
+
);
|
|
89
|
+
function opSchemas(targetSchema) {
|
|
90
|
+
return [
|
|
91
|
+
v__namespace.strictObject({
|
|
92
|
+
type: v__namespace.literal("state.set"),
|
|
93
|
+
target: targetSchema,
|
|
94
|
+
value: SourceSchema
|
|
95
|
+
}),
|
|
96
|
+
v__namespace.strictObject({
|
|
97
|
+
type: v__namespace.literal("state.unset"),
|
|
98
|
+
target: targetSchema
|
|
99
|
+
}),
|
|
100
|
+
v__namespace.strictObject({
|
|
101
|
+
type: v__namespace.literal("state.append"),
|
|
102
|
+
target: targetSchema,
|
|
103
|
+
value: SourceSchema
|
|
104
|
+
}),
|
|
105
|
+
v__namespace.strictObject({
|
|
106
|
+
type: v__namespace.literal("state.updateWhere"),
|
|
107
|
+
target: targetSchema,
|
|
108
|
+
where: OpPredicateSchema,
|
|
109
|
+
value: SourceSchema
|
|
110
|
+
}),
|
|
111
|
+
v__namespace.strictObject({
|
|
112
|
+
type: v__namespace.literal("state.removeWhere"),
|
|
113
|
+
target: targetSchema,
|
|
114
|
+
where: OpPredicateSchema
|
|
115
|
+
})
|
|
116
|
+
];
|
|
117
|
+
}
|
|
118
|
+
const StoredOpSchema = v__namespace.variant("type", [
|
|
119
|
+
...opSchemas(StoredStateRefSchema),
|
|
115
120
|
v__namespace.strictObject({
|
|
116
|
-
type: v__namespace.literal("
|
|
117
|
-
|
|
121
|
+
type: v__namespace.literal("status.set"),
|
|
122
|
+
task: NonEmpty,
|
|
118
123
|
status: picklist(TASK_STATUSES)
|
|
119
124
|
})
|
|
120
|
-
]),
|
|
121
|
-
|
|
125
|
+
]), StoredTransitionOpSchema = v__namespace.variant("type", [...opSchemas(StoredStateRefSchema)]), AuditOpSchema = v__namespace.strictObject({
|
|
126
|
+
type: v__namespace.literal("audit"),
|
|
127
|
+
target: AuthoringStateRefSchema,
|
|
128
|
+
value: SourceSchema,
|
|
129
|
+
stampFields: v__namespace.optional(
|
|
130
|
+
v__namespace.strictObject({
|
|
131
|
+
actor: v__namespace.optional(NonEmpty),
|
|
132
|
+
at: v__namespace.optional(NonEmpty)
|
|
133
|
+
})
|
|
134
|
+
)
|
|
135
|
+
}), AuthoringOpSchema = v__namespace.variant("type", [
|
|
136
|
+
...opSchemas(AuthoringStateRefSchema),
|
|
122
137
|
v__namespace.strictObject({
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
138
|
+
type: v__namespace.literal("status.set"),
|
|
139
|
+
task: v__namespace.optional(NonEmpty),
|
|
140
|
+
status: picklist(TASK_STATUSES)
|
|
126
141
|
}),
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
"workflow.state.doc.refs",
|
|
151
|
-
// Release reference. A workflow declares this slot to say "I target a
|
|
152
|
-
// Content Release"; the runtime fills it with a specific release at
|
|
153
|
-
// start time, and the engine auto-derives the instance's read
|
|
154
|
-
// perspective from it.
|
|
155
|
-
"workflow.state.release.ref",
|
|
156
|
-
"workflow.state.query",
|
|
157
|
-
"workflow.state.value.string",
|
|
158
|
-
"workflow.state.value.url",
|
|
159
|
-
"workflow.state.value.number",
|
|
160
|
-
"workflow.state.value.boolean",
|
|
161
|
-
"workflow.state.value.dateTime",
|
|
162
|
-
"workflow.state.value.actor",
|
|
163
|
-
"workflow.state.checklist",
|
|
164
|
-
"workflow.state.notes",
|
|
165
|
-
"workflow.state.assignees"
|
|
166
|
-
]), StateSlotSchema = v__namespace.strictObject({
|
|
167
|
-
type: StateSlotKindSchema,
|
|
168
|
-
id: NonEmpty,
|
|
169
|
-
title: v__namespace.optional(v__namespace.string()),
|
|
170
|
-
description: v__namespace.optional(v__namespace.string()),
|
|
171
|
-
source: StateSlotSourceSchema
|
|
172
|
-
}), FilterSchema = v__namespace.union([
|
|
173
|
-
// Inline GROQ — only reserved params allowed at runtime.
|
|
174
|
-
NonEmpty,
|
|
175
|
-
// Reference to a named predicate, optionally with named args.
|
|
176
|
-
v__namespace.strictObject({
|
|
177
|
-
ref: NonEmpty,
|
|
178
|
-
args: v__namespace.optional(v__namespace.record(v__namespace.string(), v__namespace.unknown()))
|
|
179
|
-
})
|
|
180
|
-
]), PredicateParamSchema = v__namespace.strictObject({
|
|
181
|
-
id: NonEmpty,
|
|
142
|
+
AuditOpSchema
|
|
143
|
+
]), StateKindSchema = picklist([
|
|
144
|
+
"doc.ref",
|
|
145
|
+
"doc.refs",
|
|
146
|
+
// Release reference. A workflow declares this entry to say "I target a
|
|
147
|
+
// Content Release"; the runtime fills it at start time and auto-derives
|
|
148
|
+
// the instance's read perspective from it.
|
|
149
|
+
"release.ref",
|
|
150
|
+
"query",
|
|
151
|
+
"value.string",
|
|
152
|
+
"value.url",
|
|
153
|
+
"value.number",
|
|
154
|
+
"value.boolean",
|
|
155
|
+
"value.dateTime",
|
|
156
|
+
"value.actor",
|
|
157
|
+
"checklist",
|
|
158
|
+
"notes",
|
|
159
|
+
// The WHO-FOR entry: the inbox reverse-query reads it by kind, and the
|
|
160
|
+
// rendered `$assigned` gate matches the caller against it.
|
|
161
|
+
"assignees"
|
|
162
|
+
]), StateEntryName = groqIdentifier("`$state.<name>`"), StateEntrySchema = v__namespace.strictObject({
|
|
163
|
+
type: StateKindSchema,
|
|
164
|
+
name: StateEntryName,
|
|
182
165
|
title: v__namespace.optional(v__namespace.string()),
|
|
183
166
|
description: v__namespace.optional(v__namespace.string()),
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
id: NonEmpty,
|
|
167
|
+
source: SourceSchema
|
|
168
|
+
}), ClaimStateSchema = v__namespace.strictObject({
|
|
169
|
+
type: v__namespace.literal("claim"),
|
|
170
|
+
name: StateEntryName,
|
|
189
171
|
title: v__namespace.optional(v__namespace.string()),
|
|
190
|
-
description: v__namespace.optional(v__namespace.string())
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}), EffectSchema = v__namespace.strictObject({
|
|
194
|
-
type: v__namespace.optional(v__namespace.literal("workflow.effect")),
|
|
195
|
-
id: NonEmpty,
|
|
172
|
+
description: v__namespace.optional(v__namespace.string())
|
|
173
|
+
}), AuthoringStateEntrySchema = v__namespace.union([StateEntrySchema, ClaimStateSchema]), ConditionSchema = NonEmpty, EffectSchema = v__namespace.strictObject({
|
|
174
|
+
name: NonEmpty,
|
|
196
175
|
title: v__namespace.optional(v__namespace.string()),
|
|
197
176
|
description: v__namespace.optional(v__namespace.string()),
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
177
|
+
/** GROQ reads over the rendered scope, resolved to concrete JSON at queue time. */
|
|
178
|
+
bindings: v__namespace.optional(v__namespace.record(v__namespace.string(), ConditionSchema)),
|
|
179
|
+
/** Static config, passed through to the handler verbatim. */
|
|
201
180
|
input: v__namespace.optional(v__namespace.record(v__namespace.string(), v__namespace.unknown()))
|
|
202
|
-
}),
|
|
203
|
-
type:
|
|
204
|
-
id: NonEmpty,
|
|
205
|
-
title: v__namespace.optional(v__namespace.string()),
|
|
206
|
-
description: v__namespace.optional(v__namespace.string()),
|
|
207
|
-
paramType: picklist([
|
|
181
|
+
}), ActionParamSchema = v__namespace.strictObject({
|
|
182
|
+
type: picklist([
|
|
208
183
|
"string",
|
|
209
184
|
"number",
|
|
210
185
|
"boolean",
|
|
@@ -215,130 +190,113 @@ const GdrSchema = v__namespace.strictObject({
|
|
|
215
190
|
"doc.refs",
|
|
216
191
|
"json"
|
|
217
192
|
]),
|
|
218
|
-
|
|
219
|
-
}), ActionSchema = v__namespace.strictObject({
|
|
220
|
-
type: v__namespace.optional(v__namespace.literal("workflow.action")),
|
|
221
|
-
id: NonEmpty,
|
|
193
|
+
name: NonEmpty,
|
|
222
194
|
title: v__namespace.optional(v__namespace.string()),
|
|
223
195
|
description: v__namespace.optional(v__namespace.string()),
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
ops: v__namespace.optional(v__namespace.array(OpSchema)),
|
|
245
|
-
effects: v__namespace.optional(v__namespace.array(EffectSchema)),
|
|
246
|
-
/**
|
|
247
|
-
* Role gating — OR-match against `Actor.roles[]`. If omitted, no role
|
|
248
|
-
* gate. `"*"` in Actor.roles always matches (bench / all-access).
|
|
249
|
-
*/
|
|
196
|
+
required: v__namespace.optional(v__namespace.boolean())
|
|
197
|
+
});
|
|
198
|
+
function actionFields(op) {
|
|
199
|
+
return {
|
|
200
|
+
name: NonEmpty,
|
|
201
|
+
title: v__namespace.optional(v__namespace.string()),
|
|
202
|
+
description: v__namespace.optional(v__namespace.string()),
|
|
203
|
+
/**
|
|
204
|
+
* The one gate mechanism: a condition over the rendered scope. Hard
|
|
205
|
+
* enforcement lives outside the engine entirely (the lake ACL on the
|
|
206
|
+
* documents, and guards) — every engine-evaluated gate is authoring/UX.
|
|
207
|
+
*/
|
|
208
|
+
filter: v__namespace.optional(ConditionSchema),
|
|
209
|
+
params: v__namespace.optional(v__namespace.array(ActionParamSchema)),
|
|
210
|
+
ops: v__namespace.optional(v__namespace.array(op)),
|
|
211
|
+
effects: v__namespace.optional(v__namespace.array(EffectSchema))
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
const StoredActionSchema = v__namespace.strictObject(actionFields(StoredOpSchema)), TerminalTaskStatus = picklist(TERMINAL_TASK_STATUSES), RawAuthoringActionSchema = v__namespace.strictObject({
|
|
215
|
+
...actionFields(AuthoringOpSchema),
|
|
250
216
|
roles: v__namespace.optional(v__namespace.array(NonEmpty)),
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
requireAssignment: v__namespace.optional(v__namespace.boolean()),
|
|
256
|
-
/**
|
|
257
|
-
* Which permission on the workflow.instance document the actor must
|
|
258
|
-
* hold (per supplied `grants`). Defaults to "update". Only checked
|
|
259
|
-
* when grants are supplied at evaluate/fireAction time.
|
|
260
|
-
*/
|
|
261
|
-
requiredPermission: v__namespace.optional(PermissionSchema)
|
|
262
|
-
}), CompletionPolicySchema = v__namespace.union([
|
|
263
|
-
v__namespace.strictObject({ kind: v__namespace.literal("all") }),
|
|
264
|
-
v__namespace.strictObject({ kind: v__namespace.literal("any") }),
|
|
265
|
-
v__namespace.strictObject({
|
|
266
|
-
kind: v__namespace.literal("count"),
|
|
267
|
-
n: PositiveInt
|
|
268
|
-
})
|
|
269
|
-
]), LogicalDefinitionRefSchema = v__namespace.strictObject({
|
|
270
|
-
workflowId: NonEmpty,
|
|
271
|
-
version: v__namespace.optional(v__namespace.union([PositiveInt, v__namespace.literal("latest")]))
|
|
272
|
-
}), SpawnForEachSchema = v__namespace.strictObject({
|
|
273
|
-
groq: NonEmpty,
|
|
274
|
-
as: v__namespace.strictObject({
|
|
275
|
-
initialState: v__namespace.optional(
|
|
276
|
-
v__namespace.array(
|
|
277
|
-
v__namespace.strictObject({
|
|
278
|
-
type: StateSlotKindSchema,
|
|
279
|
-
id: NonEmpty,
|
|
280
|
-
value: SourceSchema
|
|
281
|
-
})
|
|
282
|
-
)
|
|
283
|
-
),
|
|
284
|
-
effectsContext: v__namespace.optional(v__namespace.record(v__namespace.string(), SourceSchema))
|
|
285
|
-
})
|
|
286
|
-
}), SpawnSchema = v__namespace.strictObject({
|
|
287
|
-
type: v__namespace.optional(v__namespace.literal("workflow.spawn")),
|
|
288
|
-
id: v__namespace.optional(v__namespace.string()),
|
|
217
|
+
status: v__namespace.optional(TerminalTaskStatus)
|
|
218
|
+
}), ClaimActionSchema = v__namespace.strictObject({
|
|
219
|
+
type: v__namespace.literal("claim"),
|
|
220
|
+
name: NonEmpty,
|
|
289
221
|
title: v__namespace.optional(v__namespace.string()),
|
|
290
222
|
description: v__namespace.optional(v__namespace.string()),
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
v__namespace.
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
/**
|
|
306
|
-
* Auto-completion predicate — same shape as `transition.filter`. When
|
|
307
|
-
* truthy at activation or on any subsequent cascade, the engine
|
|
308
|
-
* flips the task to `done` with a `{ kind: "system", id: "engine.completeWhen" }`
|
|
309
|
-
* actor. A full filter, not just a wall-clock deadline.
|
|
310
|
-
*/
|
|
311
|
-
completeWhen: v__namespace.optional(FilterSchema),
|
|
223
|
+
state: v__namespace.union([NonEmpty, AuthoringStateRefSchema]),
|
|
224
|
+
roles: v__namespace.optional(v__namespace.array(NonEmpty)),
|
|
225
|
+
filter: v__namespace.optional(ConditionSchema),
|
|
226
|
+
params: v__namespace.optional(v__namespace.array(ActionParamSchema)),
|
|
227
|
+
effects: v__namespace.optional(v__namespace.array(EffectSchema))
|
|
228
|
+
}), AuthoringActionSchema = v__namespace.union([RawAuthoringActionSchema, ClaimActionSchema]), DefinitionRefSchema = v__namespace.strictObject({
|
|
229
|
+
name: NonEmpty,
|
|
230
|
+
version: v__namespace.optional(v__namespace.union([PositiveInt, v__namespace.literal("latest")]))
|
|
231
|
+
}), SubworkflowsSchema = v__namespace.strictObject({
|
|
232
|
+
/** GROQ producing one row per subworkflow; each row binds as `$row`. */
|
|
233
|
+
forEach: NonEmpty,
|
|
234
|
+
definition: DefinitionRefSchema,
|
|
235
|
+
/** Initial state for each subworkflow — entry name → GROQ over `$row` + the parent scope. */
|
|
236
|
+
with: v__namespace.optional(v__namespace.record(NonEmpty, ConditionSchema)),
|
|
312
237
|
/**
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
* id: "engine.failWhen" }` actor. When both `completeWhen` and
|
|
317
|
-
* `failWhen` resolve truthy on the same evaluation, `failWhen`
|
|
318
|
-
* wins — failure is the more notable signal and should not be
|
|
319
|
-
* silently swallowed.
|
|
238
|
+
* Extra values evaluated in the parent's rendered scope at spawn time and
|
|
239
|
+
* delivered into each subworkflow's `$effects` bag — the parent→child
|
|
240
|
+
* handoff, read exactly like an effect output.
|
|
320
241
|
*/
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
242
|
+
context: v__namespace.optional(v__namespace.record(NonEmpty, ConditionSchema))
|
|
243
|
+
});
|
|
244
|
+
function taskFields(state, action, op) {
|
|
245
|
+
return {
|
|
246
|
+
name: NonEmpty,
|
|
247
|
+
title: v__namespace.optional(v__namespace.string()),
|
|
248
|
+
description: v__namespace.optional(v__namespace.string()),
|
|
249
|
+
activation: v__namespace.optional(picklist(["auto", "manual"])),
|
|
250
|
+
filter: v__namespace.optional(ConditionSchema),
|
|
251
|
+
/**
|
|
252
|
+
* Auto-completion condition — evaluated at activation and on every
|
|
253
|
+
* cascade; truthy flips the task to `done` with a system actor. On a
|
|
254
|
+
* spawning task it typically reads `$subworkflows`.
|
|
255
|
+
*/
|
|
256
|
+
completeWhen: v__namespace.optional(ConditionSchema),
|
|
257
|
+
/**
|
|
258
|
+
* Auto-failure condition — symmetric to `completeWhen`, flips to
|
|
259
|
+
* `failed`. When both are truthy on the same evaluation, `failWhen`
|
|
260
|
+
* wins — failure is the more notable signal.
|
|
261
|
+
*/
|
|
262
|
+
failWhen: v__namespace.optional(ConditionSchema),
|
|
263
|
+
ops: v__namespace.optional(v__namespace.array(op)),
|
|
264
|
+
effects: v__namespace.optional(v__namespace.array(EffectSchema)),
|
|
265
|
+
actions: v__namespace.optional(v__namespace.array(action)),
|
|
266
|
+
subworkflows: v__namespace.optional(SubworkflowsSchema),
|
|
267
|
+
/** Task-scoped state entries. Resolved at task activation time. */
|
|
268
|
+
state: v__namespace.optional(v__namespace.array(state))
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
const StoredTaskSchema = v__namespace.strictObject(
|
|
272
|
+
taskFields(StateEntrySchema, StoredActionSchema, StoredOpSchema)
|
|
273
|
+
), AuthoringTaskSchema = v__namespace.strictObject(
|
|
274
|
+
taskFields(AuthoringStateEntrySchema, AuthoringActionSchema, AuthoringOpSchema)
|
|
275
|
+
);
|
|
276
|
+
function transitionFields(op, filter) {
|
|
277
|
+
return {
|
|
278
|
+
name: NonEmpty,
|
|
279
|
+
title: v__namespace.optional(v__namespace.string()),
|
|
280
|
+
description: v__namespace.optional(v__namespace.string()),
|
|
281
|
+
to: NonEmpty,
|
|
282
|
+
filter,
|
|
283
|
+
/** The `state.*` subset — state-write-on-move, the stage's EXIT/ARRIVAL payload. */
|
|
284
|
+
ops: v__namespace.optional(v__namespace.array(op)),
|
|
285
|
+
effects: v__namespace.optional(v__namespace.array(EffectSchema))
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
const StoredTransitionSchema = v__namespace.strictObject(
|
|
289
|
+
transitionFields(StoredTransitionOpSchema, ConditionSchema)
|
|
290
|
+
), AuthoringTransitionOpSchema = v__namespace.variant("type", [
|
|
291
|
+
...opSchemas(AuthoringStateRefSchema),
|
|
292
|
+
AuditOpSchema
|
|
293
|
+
]), AuthoringTransitionSchema = v__namespace.strictObject(
|
|
294
|
+
transitionFields(AuthoringTransitionOpSchema, v__namespace.optional(ConditionSchema))
|
|
295
|
+
), GuardActionSchema = picklist(MUTATION_GUARD_ACTIONS), GuardMatchSchema = v__namespace.strictObject({
|
|
338
296
|
/** Subject `_type`(s); empty matches any type. */
|
|
339
297
|
types: v__namespace.optional(v__namespace.array(NonEmpty)),
|
|
340
|
-
/** Target docs as `
|
|
341
|
-
idRefs: v__namespace.optional(v__namespace.array(
|
|
298
|
+
/** Target docs as `$state` reads (or `"$self"`), resolved at deploy to bare ids + the resource. */
|
|
299
|
+
idRefs: v__namespace.optional(v__namespace.array(NonEmpty)),
|
|
342
300
|
/** Glob id patterns (bare, resource-local). */
|
|
343
301
|
idPatterns: v__namespace.optional(v__namespace.array(NonEmpty)),
|
|
344
302
|
actions: v__namespace.pipe(
|
|
@@ -346,58 +304,71 @@ const GdrSchema = v__namespace.strictObject({
|
|
|
346
304
|
v__namespace.minLength(1, "a guard must match at least one action")
|
|
347
305
|
)
|
|
348
306
|
}), GuardSchema = v__namespace.strictObject({
|
|
349
|
-
name:
|
|
307
|
+
name: NonEmpty,
|
|
308
|
+
title: v__namespace.optional(v__namespace.string()),
|
|
350
309
|
description: v__namespace.optional(v__namespace.string()),
|
|
351
310
|
match: GuardMatchSchema,
|
|
352
311
|
/**
|
|
353
|
-
* Lake GROQ predicate
|
|
354
|
-
* `
|
|
355
|
-
*
|
|
312
|
+
* Lake GROQ predicate — a distinct eval context reading
|
|
313
|
+
* `document.before`/`document.after`, `mutation`, `guard`, and
|
|
314
|
+
* `identity()`. Bare ids/fields only. Omitted or empty means
|
|
315
|
+
* UNCONDITIONAL DENY.
|
|
356
316
|
*/
|
|
357
317
|
predicate: v__namespace.optional(v__namespace.string()),
|
|
358
318
|
/**
|
|
359
|
-
* Projected workflow state the predicate reads as `guard.metadata
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
type: v__namespace.optional(v__namespace.literal("workflow.stage")),
|
|
366
|
-
id: NonEmpty,
|
|
367
|
-
title: v__namespace.optional(v__namespace.string()),
|
|
368
|
-
description: v__namespace.optional(v__namespace.string()),
|
|
369
|
-
kind: v__namespace.optional(StageKindSchema),
|
|
370
|
-
tasks: v__namespace.optional(v__namespace.array(TaskSchema)),
|
|
371
|
-
transitions: v__namespace.optional(v__namespace.array(TransitionSchema)),
|
|
372
|
-
completion: v__namespace.optional(FilterSchema),
|
|
373
|
-
onEnter: v__namespace.optional(v__namespace.array(EffectSchema)),
|
|
374
|
-
onExit: v__namespace.optional(v__namespace.array(EffectSchema)),
|
|
375
|
-
/**
|
|
376
|
-
* Lake mutation guards active while this stage holds. Each compiles to a
|
|
377
|
-
* `temp.system.guard` doc deployed on stage entry and retracted on exit.
|
|
378
|
-
* Plural because one stage's intent may span resources (one guard each).
|
|
319
|
+
* Projected workflow state the predicate reads as `guard.metadata.*` —
|
|
320
|
+
* the only bridge from the lake eval context (which cannot see `$state`)
|
|
321
|
+
* to workflow state. Values are NOT GROQ: each is a deploy-time read in
|
|
322
|
+
* the guard mini-language — `"$self"`, `"$now"`, or
|
|
323
|
+
* `"$state.<name>[.path]"` — resolved into a bare value at deploy and
|
|
324
|
+
* re-synced by the post-state-op guard refresh.
|
|
379
325
|
*/
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
326
|
+
metadata: v__namespace.optional(v__namespace.record(NonEmpty, NonEmpty))
|
|
327
|
+
});
|
|
328
|
+
function stageFields(state, task, transition) {
|
|
329
|
+
return {
|
|
330
|
+
name: NonEmpty,
|
|
331
|
+
title: v__namespace.optional(v__namespace.string()),
|
|
332
|
+
description: v__namespace.optional(v__namespace.string()),
|
|
333
|
+
tasks: v__namespace.optional(v__namespace.array(task)),
|
|
334
|
+
transitions: v__namespace.optional(v__namespace.array(transition)),
|
|
335
|
+
/**
|
|
336
|
+
* Lake mutation guards active while this stage holds. Each compiles to a
|
|
337
|
+
* `temp.system.guard` doc deployed on stage entry and retracted on exit.
|
|
338
|
+
*/
|
|
339
|
+
guards: v__namespace.optional(v__namespace.array(GuardSchema)),
|
|
340
|
+
/** Stage-scoped state entries. Resolved at stage entry. */
|
|
341
|
+
state: v__namespace.optional(v__namespace.array(state))
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
const StoredStageSchema = v__namespace.strictObject(
|
|
345
|
+
stageFields(StateEntrySchema, StoredTaskSchema, StoredTransitionSchema)
|
|
346
|
+
), AuthoringStageSchema = v__namespace.strictObject(
|
|
347
|
+
stageFields(AuthoringStateEntrySchema, AuthoringTaskSchema, AuthoringTransitionSchema)
|
|
348
|
+
);
|
|
349
|
+
function workflowFields(state, stage) {
|
|
350
|
+
return {
|
|
351
|
+
name: NonEmpty,
|
|
352
|
+
version: PositiveInt,
|
|
353
|
+
title: NonEmpty,
|
|
354
|
+
description: v__namespace.optional(v__namespace.string()),
|
|
355
|
+
/** Reference field: named for the target, holds the stage's `name`. */
|
|
356
|
+
initialStage: NonEmpty,
|
|
357
|
+
/** Workflow-scope state entries. Persist for the instance lifetime. */
|
|
358
|
+
state: v__namespace.optional(v__namespace.array(state)),
|
|
359
|
+
stages: v__namespace.pipe(v__namespace.array(stage), v__namespace.minLength(1, "must declare at least one stage")),
|
|
360
|
+
/**
|
|
361
|
+
* Nullary named conditions — each `name: groq` entry is pre-evaluated
|
|
362
|
+
* and bound as the boolean `$name` var, composable with native GROQ.
|
|
363
|
+
* Redefining a built-in var is a deploy error (never silently shadow).
|
|
364
|
+
*/
|
|
365
|
+
predicates: v__namespace.optional(v__namespace.record(groqIdentifier("`$<name>`"), ConditionSchema))
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
v__namespace.strictObject(workflowFields(StateEntrySchema, StoredStageSchema));
|
|
369
|
+
const AuthoringWorkflowSchema = v__namespace.strictObject(
|
|
370
|
+
workflowFields(AuthoringStateEntrySchema, AuthoringStageSchema)
|
|
371
|
+
), WORKFLOW_DEFINITION_TYPE = "sanity.workflow.definition";
|
|
401
372
|
function formatValidationError(label, issues) {
|
|
402
373
|
const lines = issues.map((issue) => ` - ${issue.path.length === 0 ? "(root)" : formatPath(issue.path)}: ${issue.message}`);
|
|
403
374
|
return `${label} failed validation (${issues.length} issue${issues.length === 1 ? "" : "s"}):
|
|
@@ -416,16 +387,19 @@ function formatPath(path) {
|
|
|
416
387
|
typeof seg == "number" ? out += `[${seg}]` : out += out.length === 0 ? String(seg) : `.${String(seg)}`;
|
|
417
388
|
return out;
|
|
418
389
|
}
|
|
419
|
-
exports.
|
|
420
|
-
exports.
|
|
390
|
+
exports.AuthoringActionSchema = AuthoringActionSchema;
|
|
391
|
+
exports.AuthoringOpSchema = AuthoringOpSchema;
|
|
392
|
+
exports.AuthoringStageSchema = AuthoringStageSchema;
|
|
393
|
+
exports.AuthoringStateEntrySchema = AuthoringStateEntrySchema;
|
|
394
|
+
exports.AuthoringTaskSchema = AuthoringTaskSchema;
|
|
395
|
+
exports.AuthoringTransitionSchema = AuthoringTransitionSchema;
|
|
396
|
+
exports.AuthoringWorkflowSchema = AuthoringWorkflowSchema;
|
|
397
|
+
exports.DOCUMENT_VALUE_PERMISSIONS = DOCUMENT_VALUE_PERMISSIONS;
|
|
421
398
|
exports.EffectSchema = EffectSchema;
|
|
422
|
-
exports.
|
|
423
|
-
exports.
|
|
424
|
-
exports.StageSchema = StageSchema;
|
|
425
|
-
exports.TaskSchema = TaskSchema;
|
|
426
|
-
exports.TransitionSchema = TransitionSchema;
|
|
399
|
+
exports.GROQ_IDENTIFIER = GROQ_IDENTIFIER;
|
|
400
|
+
exports.GuardSchema = GuardSchema;
|
|
427
401
|
exports.WORKFLOW_DEFINITION_TYPE = WORKFLOW_DEFINITION_TYPE;
|
|
428
|
-
exports.WorkflowDefinitionSchema = WorkflowDefinitionSchema;
|
|
429
402
|
exports.formatValidationError = formatValidationError;
|
|
403
|
+
exports.isTerminalTaskStatus = isTerminalTaskStatus;
|
|
430
404
|
exports.issuesFromValibot = issuesFromValibot;
|
|
431
405
|
//# sourceMappingURL=schema.cjs.map
|