@sanity/workflow-engine 0.1.0 → 0.3.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 +431 -0
- package/dist/_chunks-cjs/schema.cjs.map +1 -0
- package/dist/_chunks-es/schema.js +416 -0
- package/dist/_chunks-es/schema.js.map +1 -0
- package/dist/define.cjs +57 -435
- package/dist/define.cjs.map +1 -1
- package/dist/define.d.cts +5035 -2647
- package/dist/define.d.ts +5035 -2647
- package/dist/define.js +34 -427
- package/dist/define.js.map +1 -1
- package/dist/index.cjs +1737 -1289
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6141 -3196
- package/dist/index.d.ts +6141 -3196
- package/dist/index.js +1624 -1191
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var v = require("valibot");
|
|
3
|
+
function _interopNamespaceCompat(e) {
|
|
4
|
+
if (e && typeof e == "object" && "default" in e) return e;
|
|
5
|
+
var n = /* @__PURE__ */ Object.create(null);
|
|
6
|
+
return e && Object.keys(e).forEach(function(k) {
|
|
7
|
+
if (k !== "default") {
|
|
8
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
9
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
10
|
+
enumerable: !0,
|
|
11
|
+
get: function() {
|
|
12
|
+
return e[k];
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}), n.default = e, Object.freeze(n);
|
|
17
|
+
}
|
|
18
|
+
var v__namespace = /* @__PURE__ */ _interopNamespaceCompat(v);
|
|
19
|
+
const TASK_STATUSES = ["pending", "active", "done", "skipped", "failed"], STATE_SCOPES = ["workflow", "stage", "task"], DOCUMENT_VALUE_PERMISSIONS = ["create", "read", "update"], MUTATION_GUARD_ACTIONS = [
|
|
20
|
+
"create",
|
|
21
|
+
"update",
|
|
22
|
+
"delete",
|
|
23
|
+
"publish",
|
|
24
|
+
"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));
|
|
26
|
+
function picklist(options) {
|
|
27
|
+
return v__namespace.picklist(
|
|
28
|
+
options,
|
|
29
|
+
`Invalid option: expected one of ${options.map((o) => `"${o}"`).join("|")}`
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
const GdrSchema = v__namespace.strictObject({
|
|
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(
|
|
42
|
+
() => v__namespace.union([
|
|
43
|
+
v__namespace.strictObject({
|
|
44
|
+
source: v__namespace.literal("literal"),
|
|
45
|
+
value: v__namespace.union([v__namespace.string(), v__namespace.number(), v__namespace.boolean(), v__namespace.null()])
|
|
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())
|
|
57
|
+
}),
|
|
58
|
+
// effectsContext lookup — reads from `instance.effectsContext[id === ID].value`.
|
|
59
|
+
// Used by chained effects where one handler's output feeds another's binding.
|
|
60
|
+
v__namespace.strictObject({
|
|
61
|
+
source: v__namespace.literal("effectOutput"),
|
|
62
|
+
contextId: NonEmpty,
|
|
63
|
+
path: v__namespace.optional(v__namespace.string())
|
|
64
|
+
}),
|
|
65
|
+
v__namespace.strictObject({ source: v__namespace.literal("row"), path: v__namespace.optional(v__namespace.string()) }),
|
|
66
|
+
v__namespace.strictObject({
|
|
67
|
+
source: v__namespace.literal("parentState"),
|
|
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"),
|
|
78
|
+
fields: v__namespace.record(NonEmpty, SourceSchema)
|
|
79
|
+
})
|
|
80
|
+
])
|
|
81
|
+
), ScopeKeySchema = v__namespace.strictObject({
|
|
82
|
+
scope: picklist(STATE_SCOPES),
|
|
83
|
+
slotId: NonEmpty
|
|
84
|
+
}), OpPredicateSchema = v__namespace.lazy(
|
|
85
|
+
() => v__namespace.union([
|
|
86
|
+
v__namespace.strictObject({
|
|
87
|
+
field: NonEmpty,
|
|
88
|
+
equals: SourceSchema
|
|
89
|
+
}),
|
|
90
|
+
v__namespace.strictObject({ all: v__namespace.array(OpPredicateSchema) }),
|
|
91
|
+
v__namespace.strictObject({ any: v__namespace.array(OpPredicateSchema) })
|
|
92
|
+
])
|
|
93
|
+
), OpSchema = v__namespace.variant("type", [
|
|
94
|
+
v__namespace.strictObject({
|
|
95
|
+
type: v__namespace.literal("workflow.op.state.set"),
|
|
96
|
+
target: ScopeKeySchema,
|
|
97
|
+
value: SourceSchema
|
|
98
|
+
}),
|
|
99
|
+
v__namespace.strictObject({
|
|
100
|
+
type: v__namespace.literal("workflow.op.state.append"),
|
|
101
|
+
target: ScopeKeySchema,
|
|
102
|
+
item: SourceSchema
|
|
103
|
+
}),
|
|
104
|
+
v__namespace.strictObject({
|
|
105
|
+
type: v__namespace.literal("workflow.op.state.updateWhere"),
|
|
106
|
+
target: ScopeKeySchema,
|
|
107
|
+
where: OpPredicateSchema,
|
|
108
|
+
merge: v__namespace.record(NonEmpty, SourceSchema)
|
|
109
|
+
}),
|
|
110
|
+
v__namespace.strictObject({
|
|
111
|
+
type: v__namespace.literal("workflow.op.state.removeWhere"),
|
|
112
|
+
target: ScopeKeySchema,
|
|
113
|
+
where: OpPredicateSchema
|
|
114
|
+
}),
|
|
115
|
+
v__namespace.strictObject({
|
|
116
|
+
type: v__namespace.literal("workflow.op.status.set"),
|
|
117
|
+
taskId: NonEmpty,
|
|
118
|
+
status: picklist(TASK_STATUSES)
|
|
119
|
+
})
|
|
120
|
+
]), StateSlotSourceSchema = v__namespace.union([
|
|
121
|
+
v__namespace.strictObject({ kind: v__namespace.literal("init") }),
|
|
122
|
+
v__namespace.strictObject({
|
|
123
|
+
kind: v__namespace.literal("query"),
|
|
124
|
+
query: NonEmpty,
|
|
125
|
+
resource: v__namespace.optional(v__namespace.union([v__namespace.literal("workflow"), v__namespace.literal("subject"), GdrSchema]))
|
|
126
|
+
}),
|
|
127
|
+
v__namespace.strictObject({ kind: v__namespace.literal("write") }),
|
|
128
|
+
/**
|
|
129
|
+
* Pre-populate the slot at resolution time with a constant value.
|
|
130
|
+
* Useful for stage- or task-scope slots that should start non-empty
|
|
131
|
+
* (e.g. a default headline, a starting tally).
|
|
132
|
+
*/
|
|
133
|
+
v__namespace.strictObject({ kind: v__namespace.literal("literal"), value: v__namespace.unknown() }),
|
|
134
|
+
/**
|
|
135
|
+
* Pre-populate by reading another already-resolved slot. `scope:
|
|
136
|
+
* "workflow"` reads from the workflow-scope `state[]` (resolved at
|
|
137
|
+
* startInstance). `scope: "stage"` reads from an earlier slot in
|
|
138
|
+
* this same stage entry's `state[]` (sequential resolution).
|
|
139
|
+
* Optional `path` selects a nested field (e.g. `path: "id"` on a
|
|
140
|
+
* doc.ref slot).
|
|
141
|
+
*/
|
|
142
|
+
v__namespace.strictObject({
|
|
143
|
+
kind: v__namespace.literal("stateRead"),
|
|
144
|
+
scope: v__namespace.union([v__namespace.literal("workflow"), v__namespace.literal("stage")]),
|
|
145
|
+
slotId: NonEmpty,
|
|
146
|
+
path: v__namespace.optional(v__namespace.string())
|
|
147
|
+
})
|
|
148
|
+
]), StateSlotKindSchema = picklist([
|
|
149
|
+
"workflow.state.doc.ref",
|
|
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,
|
|
182
|
+
title: v__namespace.optional(v__namespace.string()),
|
|
183
|
+
description: v__namespace.optional(v__namespace.string()),
|
|
184
|
+
type: picklist(["string", "number", "boolean", "string[]", "reference"]),
|
|
185
|
+
enum: v__namespace.optional(v__namespace.array(v__namespace.string()))
|
|
186
|
+
}), PredicateSchema = v__namespace.strictObject({
|
|
187
|
+
type: v__namespace.optional(v__namespace.literal("workflow.predicate")),
|
|
188
|
+
id: NonEmpty,
|
|
189
|
+
title: v__namespace.optional(v__namespace.string()),
|
|
190
|
+
description: v__namespace.optional(v__namespace.string()),
|
|
191
|
+
groq: NonEmpty,
|
|
192
|
+
params: v__namespace.optional(v__namespace.array(PredicateParamSchema))
|
|
193
|
+
}), EffectSchema = v__namespace.strictObject({
|
|
194
|
+
type: v__namespace.optional(v__namespace.literal("workflow.effect")),
|
|
195
|
+
id: NonEmpty,
|
|
196
|
+
title: v__namespace.optional(v__namespace.string()),
|
|
197
|
+
description: v__namespace.optional(v__namespace.string()),
|
|
198
|
+
// Bindings resolve typed Source values at commit time, producing
|
|
199
|
+
// concrete JSON in the queued effect's `params`. NO GROQ.
|
|
200
|
+
bindings: v__namespace.optional(v__namespace.record(v__namespace.string(), SourceSchema)),
|
|
201
|
+
input: v__namespace.optional(v__namespace.record(v__namespace.string(), v__namespace.unknown()))
|
|
202
|
+
}), TerminalTaskStatus = picklist(["done", "skipped", "failed"]), PermissionSchema = picklist(DOCUMENT_VALUE_PERMISSIONS), ActionParamSchema = v__namespace.strictObject({
|
|
203
|
+
type: v__namespace.optional(v__namespace.literal("workflow.action.param")),
|
|
204
|
+
id: NonEmpty,
|
|
205
|
+
title: v__namespace.optional(v__namespace.string()),
|
|
206
|
+
description: v__namespace.optional(v__namespace.string()),
|
|
207
|
+
paramType: picklist([
|
|
208
|
+
"string",
|
|
209
|
+
"number",
|
|
210
|
+
"boolean",
|
|
211
|
+
"url",
|
|
212
|
+
"dateTime",
|
|
213
|
+
"actor",
|
|
214
|
+
"doc.ref",
|
|
215
|
+
"doc.refs",
|
|
216
|
+
"json"
|
|
217
|
+
]),
|
|
218
|
+
required: v__namespace.optional(v__namespace.boolean())
|
|
219
|
+
}), ActionSchema = v__namespace.strictObject({
|
|
220
|
+
type: v__namespace.optional(v__namespace.literal("workflow.action")),
|
|
221
|
+
id: NonEmpty,
|
|
222
|
+
title: v__namespace.optional(v__namespace.string()),
|
|
223
|
+
description: v__namespace.optional(v__namespace.string()),
|
|
224
|
+
filter: v__namespace.optional(FilterSchema),
|
|
225
|
+
/** Caller-supplied params, validated before ops/effects run. */
|
|
226
|
+
params: v__namespace.optional(v__namespace.array(ActionParamSchema)),
|
|
227
|
+
/**
|
|
228
|
+
* Status the task flips to when this action fires. Omit to leave
|
|
229
|
+
* the task status unchanged — used by intermediate `claim` /
|
|
230
|
+
* `assign` / partial-update actions where the task should stay
|
|
231
|
+
* active so a later action can fire on it. Declared values must
|
|
232
|
+
* be terminal (`done` / `skipped` / `failed`); the engine never
|
|
233
|
+
* mid-flip back to `active` outside of the `workflow.op.status.set`
|
|
234
|
+
* op explicit path.
|
|
235
|
+
*/
|
|
236
|
+
setStatus: v__namespace.optional(TerminalTaskStatus),
|
|
237
|
+
/**
|
|
238
|
+
* Inline state-mutation primitives executed during the action commit.
|
|
239
|
+
* Each op runs against the in-memory mutation (deterministic, no
|
|
240
|
+
* external I/O). Resolved Sources turn into concrete JSON before the
|
|
241
|
+
* op applies. Logged on `history[]` as `workflow.history.opApplied`
|
|
242
|
+
* and surfaced on the `ActionResult.ranOps`.
|
|
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
|
+
*/
|
|
250
|
+
roles: v__namespace.optional(v__namespace.array(NonEmpty)),
|
|
251
|
+
/**
|
|
252
|
+
* When true, the actor must appear in the task's `assignees[]` (as a
|
|
253
|
+
* user-kind assignee matching by id) for the action to be allowed.
|
|
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()),
|
|
289
|
+
title: v__namespace.optional(v__namespace.string()),
|
|
290
|
+
description: v__namespace.optional(v__namespace.string()),
|
|
291
|
+
definitionRef: LogicalDefinitionRefSchema,
|
|
292
|
+
forEach: SpawnForEachSchema,
|
|
293
|
+
completionPolicy: v__namespace.optional(CompletionPolicySchema)
|
|
294
|
+
}), AssigneeSchema = v__namespace.variant("kind", [
|
|
295
|
+
v__namespace.strictObject({ kind: v__namespace.literal("user"), id: NonEmpty }),
|
|
296
|
+
v__namespace.strictObject({ kind: v__namespace.literal("role"), role: NonEmpty })
|
|
297
|
+
]), TaskSchema = v__namespace.strictObject({
|
|
298
|
+
type: v__namespace.optional(v__namespace.literal("workflow.task")),
|
|
299
|
+
id: NonEmpty,
|
|
300
|
+
title: v__namespace.optional(v__namespace.string()),
|
|
301
|
+
description: v__namespace.optional(v__namespace.string()),
|
|
302
|
+
assignees: v__namespace.optional(v__namespace.array(AssigneeSchema)),
|
|
303
|
+
filter: v__namespace.optional(FilterSchema),
|
|
304
|
+
invokeOn: v__namespace.optional(picklist(["stageEnter", "manual"])),
|
|
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),
|
|
312
|
+
/**
|
|
313
|
+
* Auto-failure predicate — symmetric to `completeWhen`. Same shape,
|
|
314
|
+
* same evaluation cadence (activation + every cascade), but flips
|
|
315
|
+
* the task to `failed` (not `done`) with a `{ kind: "system",
|
|
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.
|
|
320
|
+
*/
|
|
321
|
+
failWhen: v__namespace.optional(FilterSchema),
|
|
322
|
+
effects: v__namespace.optional(v__namespace.array(EffectSchema)),
|
|
323
|
+
actions: v__namespace.optional(v__namespace.array(ActionSchema)),
|
|
324
|
+
spawns: v__namespace.optional(SpawnSchema),
|
|
325
|
+
contentRefs: v__namespace.optional(v__namespace.array(v__namespace.unknown())),
|
|
326
|
+
/** Task-scoped state slots. Resolved at task activation time. */
|
|
327
|
+
state: v__namespace.optional(v__namespace.array(StateSlotSchema))
|
|
328
|
+
}), TransitionSchema = v__namespace.strictObject({
|
|
329
|
+
type: v__namespace.optional(v__namespace.literal("workflow.transition")),
|
|
330
|
+
id: NonEmpty,
|
|
331
|
+
title: v__namespace.optional(v__namespace.string()),
|
|
332
|
+
description: v__namespace.optional(v__namespace.string()),
|
|
333
|
+
to: NonEmpty,
|
|
334
|
+
on: v__namespace.optional(v__namespace.string()),
|
|
335
|
+
filter: v__namespace.optional(FilterSchema),
|
|
336
|
+
effects: v__namespace.optional(v__namespace.array(EffectSchema))
|
|
337
|
+
}), GuardActionSchema = picklist(MUTATION_GUARD_ACTIONS), GuardMatchSchema = v__namespace.strictObject({
|
|
338
|
+
/** Subject `_type`(s); empty matches any type. */
|
|
339
|
+
types: v__namespace.optional(v__namespace.array(NonEmpty)),
|
|
340
|
+
/** Target docs as `Source`s resolved at deploy to bare ids + the resource. */
|
|
341
|
+
idRefs: v__namespace.optional(v__namespace.array(SourceSchema)),
|
|
342
|
+
/** Glob id patterns (bare, resource-local). */
|
|
343
|
+
idPatterns: v__namespace.optional(v__namespace.array(NonEmpty)),
|
|
344
|
+
actions: v__namespace.pipe(
|
|
345
|
+
v__namespace.array(GuardActionSchema),
|
|
346
|
+
v__namespace.minLength(1, "a guard must match at least one action")
|
|
347
|
+
)
|
|
348
|
+
}), GuardSchema = v__namespace.strictObject({
|
|
349
|
+
name: v__namespace.optional(v__namespace.string()),
|
|
350
|
+
description: v__namespace.optional(v__namespace.string()),
|
|
351
|
+
match: GuardMatchSchema,
|
|
352
|
+
/**
|
|
353
|
+
* Lake GROQ predicate. Reads `document.before`/`document.after`, `mutation`,
|
|
354
|
+
* `guard`, and `identity()`. Bare ids/fields only — no GDRs. Omitted or
|
|
355
|
+
* empty means UNCONDITIONAL DENY.
|
|
356
|
+
*/
|
|
357
|
+
predicate: v__namespace.optional(v__namespace.string()),
|
|
358
|
+
/**
|
|
359
|
+
* Projected workflow state the predicate reads as `guard.metadata.*`. Values
|
|
360
|
+
* are `Source`s resolved at deploy and re-synced by the engine. Copied data,
|
|
361
|
+
* never a cross-resource pointer.
|
|
362
|
+
*/
|
|
363
|
+
metadata: v__namespace.optional(v__namespace.record(NonEmpty, SourceSchema))
|
|
364
|
+
}), StageKindSchema = picklist(["initial", "intermediate", "terminal", "waiting"]), StageSchema = v__namespace.strictObject({
|
|
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).
|
|
379
|
+
*/
|
|
380
|
+
guards: v__namespace.optional(v__namespace.array(GuardSchema)),
|
|
381
|
+
contentRefs: v__namespace.optional(v__namespace.array(v__namespace.unknown())),
|
|
382
|
+
/** Stage-scoped state slots. Resolved at stage entry and persisted on
|
|
383
|
+
* the StageEntry. */
|
|
384
|
+
state: v__namespace.optional(v__namespace.array(StateSlotSchema))
|
|
385
|
+
}), WorkflowDefinitionSchema = v__namespace.strictObject({
|
|
386
|
+
workflowId: NonEmpty,
|
|
387
|
+
version: PositiveInt,
|
|
388
|
+
title: NonEmpty,
|
|
389
|
+
description: v__namespace.optional(v__namespace.string()),
|
|
390
|
+
initialStageId: NonEmpty,
|
|
391
|
+
/**
|
|
392
|
+
* Workflow-level state slots. Persist for the instance lifetime.
|
|
393
|
+
* Every stage's filters/ops can read them via
|
|
394
|
+
* `*[_id == $self][0].state[key == "<key>"][0].value`. Init-sourced
|
|
395
|
+
* slots are supplied at `startInstance` via `initialState`.
|
|
396
|
+
*/
|
|
397
|
+
state: v__namespace.optional(v__namespace.array(StateSlotSchema)),
|
|
398
|
+
stages: v__namespace.pipe(v__namespace.array(StageSchema), v__namespace.minLength(1, "must declare at least one stage")),
|
|
399
|
+
predicates: v__namespace.optional(v__namespace.array(PredicateSchema))
|
|
400
|
+
}), WORKFLOW_DEFINITION_TYPE = "workflow.definition";
|
|
401
|
+
function formatValidationError(label, issues) {
|
|
402
|
+
const lines = issues.map((issue) => ` - ${issue.path.length === 0 ? "(root)" : formatPath(issue.path)}: ${issue.message}`);
|
|
403
|
+
return `${label} failed validation (${issues.length} issue${issues.length === 1 ? "" : "s"}):
|
|
404
|
+
${lines.join(`
|
|
405
|
+
`)}`;
|
|
406
|
+
}
|
|
407
|
+
function issuesFromValibot(issues) {
|
|
408
|
+
return issues.map((issue) => ({
|
|
409
|
+
path: issue.path ? issue.path.map((item) => item.key) : [],
|
|
410
|
+
message: issue.message
|
|
411
|
+
}));
|
|
412
|
+
}
|
|
413
|
+
function formatPath(path) {
|
|
414
|
+
let out = "";
|
|
415
|
+
for (const seg of path)
|
|
416
|
+
typeof seg == "number" ? out += `[${seg}]` : out += out.length === 0 ? String(seg) : `.${String(seg)}`;
|
|
417
|
+
return out;
|
|
418
|
+
}
|
|
419
|
+
exports.ActionSchema = ActionSchema;
|
|
420
|
+
exports.AssigneeSchema = AssigneeSchema;
|
|
421
|
+
exports.EffectSchema = EffectSchema;
|
|
422
|
+
exports.FilterSchema = FilterSchema;
|
|
423
|
+
exports.PredicateSchema = PredicateSchema;
|
|
424
|
+
exports.StageSchema = StageSchema;
|
|
425
|
+
exports.TaskSchema = TaskSchema;
|
|
426
|
+
exports.TransitionSchema = TransitionSchema;
|
|
427
|
+
exports.WORKFLOW_DEFINITION_TYPE = WORKFLOW_DEFINITION_TYPE;
|
|
428
|
+
exports.WorkflowDefinitionSchema = WorkflowDefinitionSchema;
|
|
429
|
+
exports.formatValidationError = formatValidationError;
|
|
430
|
+
exports.issuesFromValibot = issuesFromValibot;
|
|
431
|
+
//# sourceMappingURL=schema.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.cjs","sources":["../../src/types/enums.ts","../../src/define/schema.ts"],"sourcesContent":["/**\n * Leaf enums — the const arrays (and their derived union types) that both\n * the authoring schema and the engine address by name.\n *\n * This module imports nothing. It is the schema-free foundation that\n * `../define/schema.ts` reads its value constants from, which is what keeps\n * the type model and the valibot schema free of an import cycle: the value edge\n * `schema.ts → enums.ts` terminates here.\n */\n\n// Task status — used by instance state. Authoring code references this\n// via `Action.setStatus`, which the valibot schema constrains to the\n// terminal subset.\nexport const TASK_STATUSES = ['pending', 'active', 'done', 'skipped', 'failed'] as const\nexport type TaskStatus = (typeof TASK_STATUSES)[number]\n\n// The three state scopes a slot can live in. Authoring (`ScopeKey`,\n// `stateRead` sources) and the engine both address slots by scope.\nexport const STATE_SCOPES = ['workflow', 'stage', 'task'] as const\nexport type StateScope = (typeof STATE_SCOPES)[number]\n\n// Document-value permissions. Grants (`Grant` in ./authorization.ts) compose\n// most-permissive-wins.\nexport const DOCUMENT_VALUE_PERMISSIONS = ['create', 'read', 'update'] as const\nexport type DocumentValuePermission = (typeof DOCUMENT_VALUE_PERMISSIONS)[number]\n\n// Mutation-guard actions — the lake operations a guard can gate. See the\n// guard types in ./authorization.ts.\nexport const MUTATION_GUARD_ACTIONS = [\n 'create',\n 'update',\n 'delete',\n 'publish',\n 'unpublish',\n] as const\nexport type MutationGuardAction = (typeof MUTATION_GUARD_ACTIONS)[number]\n","/**\n * Valibot schemas for the workflow authoring surface — the things a workflow\n * author writes by hand and feeds to `defineWorkflow`. Types in this\n * file are the **canonical** authoring types: they are inferred from\n * the schemas, so the runtime schema and the compile-time type cannot\n * drift.\n *\n * Engine-produced shapes (`WorkflowInstance`, `TaskStatusEntry`,\n * `HistoryEntry`, etc.) stay as plain TS interfaces in `../types.ts` —\n * those are outputs, not inputs.\n *\n * Strictness: every object schema is `v.strictObject` so unknown keys\n * produce a parse error. That catches typos like `verison: 1` instead\n * of `version: 1` at deploy time, with the path pointing exactly at\n * the offender.\n */\n\nimport * as v from 'valibot'\n\nimport {\n DOCUMENT_VALUE_PERMISSIONS,\n MUTATION_GUARD_ACTIONS,\n STATE_SCOPES,\n TASK_STATUSES,\n type StateScope,\n} from '../types/enums.ts'\n\nconst NonEmpty = v.pipe(v.string(), v.minLength(1, 'must be a non-empty string'))\n\nconst PositiveInt = v.pipe(v.number(), v.integer(), v.minValue(1))\n\n/**\n * Picklist with a zod-compatible \"Invalid option\" message that lists every\n * allowed value, so a typo'd discriminator or enum lands with a message an\n * author can act on (e.g. `Invalid option: expected one of \"done\"|\"skipped\"`).\n */\nfunction picklist<const TOptions extends readonly [string, ...string[]]>(options: TOptions) {\n return v.picklist(\n options,\n `Invalid option: expected one of ${options.map((o) => `\"${o}\"`).join('|')}`,\n )\n}\n\n/**\n * GDR (Global Document Reference) — see `../refs.ts`. URI form\n * `<scheme>:<...id-parts>`, e.g. `dataset:proj:ds:doc` or\n * `canvas:resourceId:doc`. Every cross-doc reference in the engine API\n * uses this shape.\n */\nconst GdrSchema = v.strictObject({\n id: v.pipe(\n v.string(),\n v.regex(\n /^(dataset|canvas|media-library|dashboard):/,\n \"must be a GDR URI of form '<scheme>:<...id-parts>' where scheme is one of: dataset, canvas, media-library, dashboard\",\n ),\n ),\n type: NonEmpty,\n})\n\n// Source — typed binding union. Op fields and effect bindings resolve\n// concrete values through this discriminated union; no GROQ in the binding\n// language. Anywhere a concrete value is needed at commit time, the engine\n// resolves a Source.\n\ntype SourceInternal =\n | {source: 'literal'; value: string | number | boolean | null}\n | {source: 'param'; paramId: string}\n | {source: 'actor'}\n | {source: 'now'}\n | {source: 'self'}\n | {source: 'stageId'}\n | {\n source: 'stateRead'\n scope: StateScope\n slotId: string\n path?: string | undefined\n }\n | {source: 'effectOutput'; contextId: string; path?: string | undefined}\n /**\n * Spawn-only sources. Resolved at spawn-time inside `Spawn.forEach.as`\n * projection. `row` reads from the current iteration row (the GROQ\n * result item). `parentState` reads from the spawning parent's\n * resolved workflow-scope state — the slot envelope as on the\n * parent (`{ id, _type, value, ... }`), with an optional path dive.\n */\n | {source: 'row'; path?: string | undefined}\n | {source: 'parentState'; slotId: string; path?: string | undefined}\n | {source: 'object'; fields: Record<string, SourceInternal>}\n\nconst SourceSchema: v.GenericSchema<SourceInternal> = v.lazy(() =>\n v.union([\n v.strictObject({\n source: v.literal('literal'),\n value: v.union([v.string(), v.number(), v.boolean(), v.null()]),\n }),\n v.strictObject({source: v.literal('param'), paramId: NonEmpty}),\n v.strictObject({source: v.literal('actor')}),\n v.strictObject({source: v.literal('now')}),\n v.strictObject({source: v.literal('self')}),\n v.strictObject({source: v.literal('stageId')}),\n v.strictObject({\n source: v.literal('stateRead'),\n scope: picklist(STATE_SCOPES),\n slotId: NonEmpty,\n path: v.optional(v.string()),\n }),\n // effectsContext lookup — reads from `instance.effectsContext[id === ID].value`.\n // Used by chained effects where one handler's output feeds another's binding.\n v.strictObject({\n source: v.literal('effectOutput'),\n contextId: NonEmpty,\n path: v.optional(v.string()),\n }),\n v.strictObject({source: v.literal('row'), path: v.optional(v.string())}),\n v.strictObject({\n source: v.literal('parentState'),\n slotId: NonEmpty,\n path: v.optional(v.string()),\n }),\n // Compound object source — resolves each field's Source recursively\n // and packages the result into a JSON object. Lets ops append rich\n // rows to `checklist` / `notes` / `assignees` slots, e.g.\n // `{ source: \"object\", fields: { signer: { source: \"actor\" },\n // at: { source: \"now\" } } }`.\n v.strictObject({\n source: v.literal('object'),\n fields: v.record(NonEmpty, SourceSchema),\n }),\n ]),\n)\nexport type Source = SourceInternal\n\n// ScopeKey — { scope, key } addressing a state slot in one of the three\n// state scopes (workflow, stage, task).\n\nconst ScopeKeySchema = v.strictObject({\n scope: picklist(STATE_SCOPES),\n slotId: NonEmpty,\n})\nexport type ScopeKey = v.InferOutput<typeof ScopeKeySchema>\n\n// Op predicates — small typed predicate for op.state.updateWhere /\n// op.state.removeWhere. Separate from filter GROQ.\n\ntype OpPredicateInternal =\n | {field: string; equals: Source}\n | {all: OpPredicateInternal[]}\n | {any: OpPredicateInternal[]}\n\nconst OpPredicateSchema: v.GenericSchema<OpPredicateInternal> = v.lazy(() =>\n v.union([\n v.strictObject({\n field: NonEmpty,\n equals: SourceSchema,\n }),\n v.strictObject({all: v.array(OpPredicateSchema)}),\n v.strictObject({any: v.array(OpPredicateSchema)}),\n ]),\n)\nexport type OpPredicate = OpPredicateInternal\n\n// Ops — workflow.op.* primitives that run inline during an action commit.\n// Each op type has structured fields, NOT a GROQ binding language.\n\nconst OpSchema = v.variant('type', [\n v.strictObject({\n type: v.literal('workflow.op.state.set'),\n target: ScopeKeySchema,\n value: SourceSchema,\n }),\n v.strictObject({\n type: v.literal('workflow.op.state.append'),\n target: ScopeKeySchema,\n item: SourceSchema,\n }),\n v.strictObject({\n type: v.literal('workflow.op.state.updateWhere'),\n target: ScopeKeySchema,\n where: OpPredicateSchema,\n merge: v.record(NonEmpty, SourceSchema),\n }),\n v.strictObject({\n type: v.literal('workflow.op.state.removeWhere'),\n target: ScopeKeySchema,\n where: OpPredicateSchema,\n }),\n v.strictObject({\n type: v.literal('workflow.op.status.set'),\n taskId: NonEmpty,\n status: picklist(TASK_STATUSES),\n }),\n])\nexport type Op = v.InferOutput<typeof OpSchema>\n\n// State slots — each declares its `source.kind` (init / query / write /\n// literal / stateRead). Authoring shape only; engine resolves slots into\n// `ResolvedStateSlot` at runtime (types.ts).\n\nconst StateSlotSourceSchema = v.union([\n v.strictObject({kind: v.literal('init')}),\n v.strictObject({\n kind: v.literal('query'),\n query: NonEmpty,\n resource: v.optional(v.union([v.literal('workflow'), v.literal('subject'), GdrSchema])),\n }),\n v.strictObject({kind: v.literal('write')}),\n /**\n * Pre-populate the slot at resolution time with a constant value.\n * Useful for stage- or task-scope slots that should start non-empty\n * (e.g. a default headline, a starting tally).\n */\n v.strictObject({kind: v.literal('literal'), value: v.unknown()}),\n /**\n * Pre-populate by reading another already-resolved slot. `scope:\n * \"workflow\"` reads from the workflow-scope `state[]` (resolved at\n * startInstance). `scope: \"stage\"` reads from an earlier slot in\n * this same stage entry's `state[]` (sequential resolution).\n * Optional `path` selects a nested field (e.g. `path: \"id\"` on a\n * doc.ref slot).\n */\n v.strictObject({\n kind: v.literal('stateRead'),\n scope: v.union([v.literal('workflow'), v.literal('stage')]),\n slotId: NonEmpty,\n path: v.optional(v.string()),\n }),\n])\nexport type StateSlotSource = v.InferOutput<typeof StateSlotSourceSchema>\n\n/**\n * Canonical set of state-slot kinds — the discriminator for both\n * authored {@link StateSlot}s and runtime `StateSlotValueMap`. Spawn\n * projections reuse it so a typo'd slot type is rejected at deploy\n * rather than silently dropped at projection time.\n */\nconst StateSlotKindSchema = picklist([\n 'workflow.state.doc.ref',\n 'workflow.state.doc.refs',\n // Release reference. A workflow declares this slot to say \"I target a\n // Content Release\"; the runtime fills it with a specific release at\n // start time, and the engine auto-derives the instance's read\n // perspective from it.\n 'workflow.state.release.ref',\n 'workflow.state.query',\n 'workflow.state.value.string',\n 'workflow.state.value.url',\n 'workflow.state.value.number',\n 'workflow.state.value.boolean',\n 'workflow.state.value.dateTime',\n 'workflow.state.value.actor',\n 'workflow.state.checklist',\n 'workflow.state.notes',\n 'workflow.state.assignees',\n])\n\n// Every kind shares one shape — only the `type` discriminator differs —\n// so a single object keyed by the kind picklist expresses the slot\n// exactly, and a typo'd `type` is rejected with an \"Invalid option\" path.\nconst StateSlotSchema = v.strictObject({\n type: StateSlotKindSchema,\n id: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n source: StateSlotSourceSchema,\n})\nexport type StateSlot = v.InferOutput<typeof StateSlotSchema>\n\n// Filters & predicates\n\nexport const FilterSchema = v.union([\n // Inline GROQ — only reserved params allowed at runtime.\n NonEmpty,\n // Reference to a named predicate, optionally with named args.\n v.strictObject({\n ref: NonEmpty,\n args: v.optional(v.record(v.string(), v.unknown())),\n }),\n])\nexport type Filter = v.InferOutput<typeof FilterSchema>\n\nconst PredicateParamSchema = v.strictObject({\n id: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n type: picklist(['string', 'number', 'boolean', 'string[]', 'reference']),\n enum: v.optional(v.array(v.string())),\n})\nexport type PredicateParam = v.InferOutput<typeof PredicateParamSchema>\n\nexport const PredicateSchema = v.strictObject({\n type: v.optional(v.literal('workflow.predicate')),\n id: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n groq: NonEmpty,\n params: v.optional(v.array(PredicateParamSchema)),\n})\nexport type Predicate = v.InferOutput<typeof PredicateSchema>\n\n// Effects\n\nexport const EffectSchema = v.strictObject({\n type: v.optional(v.literal('workflow.effect')),\n id: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n // Bindings resolve typed Source values at commit time, producing\n // concrete JSON in the queued effect's `params`. NO GROQ.\n bindings: v.optional(v.record(v.string(), SourceSchema)),\n input: v.optional(v.record(v.string(), v.unknown())),\n})\nexport type Effect = v.InferOutput<typeof EffectSchema>\n\n// Actions\n\nconst TerminalTaskStatus = picklist(['done', 'skipped', 'failed'])\n\nconst PermissionSchema = picklist(DOCUMENT_VALUE_PERMISSIONS)\n\n/**\n * Caller-supplied params declared on an action. The engine validates\n * incoming `params` against this list before running ops or queuing\n * effects: missing required params → ActionParamsInvalidError, action\n * does not commit. Resolved values feed `Source.param` lookups.\n */\nconst ActionParamSchema = v.strictObject({\n type: v.optional(v.literal('workflow.action.param')),\n id: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n paramType: picklist([\n 'string',\n 'number',\n 'boolean',\n 'url',\n 'dateTime',\n 'actor',\n 'doc.ref',\n 'doc.refs',\n 'json',\n ]),\n required: v.optional(v.boolean()),\n})\nexport type ActionParam = v.InferOutput<typeof ActionParamSchema>\n\nexport const ActionSchema = v.strictObject({\n type: v.optional(v.literal('workflow.action')),\n id: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n filter: v.optional(FilterSchema),\n /** Caller-supplied params, validated before ops/effects run. */\n params: v.optional(v.array(ActionParamSchema)),\n /**\n * Status the task flips to when this action fires. Omit to leave\n * the task status unchanged — used by intermediate `claim` /\n * `assign` / partial-update actions where the task should stay\n * active so a later action can fire on it. Declared values must\n * be terminal (`done` / `skipped` / `failed`); the engine never\n * mid-flip back to `active` outside of the `workflow.op.status.set`\n * op explicit path.\n */\n setStatus: v.optional(TerminalTaskStatus),\n /**\n * Inline state-mutation primitives executed during the action commit.\n * Each op runs against the in-memory mutation (deterministic, no\n * external I/O). Resolved Sources turn into concrete JSON before the\n * op applies. Logged on `history[]` as `workflow.history.opApplied`\n * and surfaced on the `ActionResult.ranOps`.\n */\n ops: v.optional(v.array(OpSchema)),\n effects: v.optional(v.array(EffectSchema)),\n /**\n * Role gating — OR-match against `Actor.roles[]`. If omitted, no role\n * gate. `\"*\"` in Actor.roles always matches (bench / all-access).\n */\n roles: v.optional(v.array(NonEmpty)),\n /**\n * When true, the actor must appear in the task's `assignees[]` (as a\n * user-kind assignee matching by id) for the action to be allowed.\n */\n requireAssignment: v.optional(v.boolean()),\n /**\n * Which permission on the workflow.instance document the actor must\n * hold (per supplied `grants`). Defaults to \"update\". Only checked\n * when grants are supplied at evaluate/fireAction time.\n */\n requiredPermission: v.optional(PermissionSchema),\n})\nexport type Action = v.InferOutput<typeof ActionSchema>\n\n// Spawn (nested workflows)\n\nconst CompletionPolicySchema = v.union([\n v.strictObject({kind: v.literal('all')}),\n v.strictObject({kind: v.literal('any')}),\n v.strictObject({\n kind: v.literal('count'),\n n: PositiveInt,\n }),\n])\n\n/**\n * Logical reference to a deployed workflow definition. The engine\n * resolves it at spawn time by querying its own workflow resource for\n * a matching (workflowId, tags ∩ engine.tags, version) tuple, ordering\n * by `version desc` and picking the first — or the matching `version`\n * if explicitly specified.\n *\n * Authors never have a stable GDR URI to reference (tags can be\n * renamed, workflows redeployed). They have the stable contract: the\n * `workflowId`.\n */\nconst LogicalDefinitionRefSchema = v.strictObject({\n workflowId: NonEmpty,\n version: v.optional(v.union([PositiveInt, v.literal('latest')])),\n})\n\n/**\n * `forEach` — spawn fan-out projection.\n *\n * - `groq` runs against the lake (paramsForLake-stripped reserved\n * params: `$self`, `$state`, `$parent`, `$ancestors`, `$stage`,\n * `$now`). Result is an array; engine creates one child per row.\n * - `as.initialState` is a typed projection from each row to the\n * child's initial state slots. Values use the `Source` union with\n * two spawn-only variants:\n * - `{ source: \"row\", path? }` — pull from the current row.\n * - `{ source: \"parentState\", slotId, path? }` — pull from the\n * spawning parent's resolved workflow-scope state.\n * - `as.effectsContext` optionally seeds the child's effectsContext.\n *\n * The spawn does not auto-stamp anything onto the child. Whatever\n * slots the child needs, the author must declare on the child's\n * workflow definition AND project from each row via `as.initialState`.\n */\nconst SpawnForEachSchema = v.strictObject({\n groq: NonEmpty,\n as: v.strictObject({\n initialState: v.optional(\n v.array(\n v.strictObject({\n type: StateSlotKindSchema,\n id: NonEmpty,\n value: SourceSchema,\n }),\n ),\n ),\n effectsContext: v.optional(v.record(v.string(), SourceSchema)),\n }),\n})\n\nconst SpawnSchema = v.strictObject({\n type: v.optional(v.literal('workflow.spawn')),\n id: v.optional(v.string()),\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n definitionRef: LogicalDefinitionRefSchema,\n forEach: SpawnForEachSchema,\n completionPolicy: v.optional(CompletionPolicySchema),\n})\nexport type Spawn = v.InferOutput<typeof SpawnSchema>\n\n// Assignees — typed. `kind: \"user\"` matches `Actor.id`; `kind: \"role\"`\n// matches if `Actor.roles[]` contains the role string.\n\nexport const AssigneeSchema = v.variant('kind', [\n v.strictObject({kind: v.literal('user'), id: NonEmpty}),\n v.strictObject({kind: v.literal('role'), role: NonEmpty}),\n])\nexport type Assignee = v.InferOutput<typeof AssigneeSchema>\n\n// Tasks\n\nexport const TaskSchema = v.strictObject({\n type: v.optional(v.literal('workflow.task')),\n id: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n assignees: v.optional(v.array(AssigneeSchema)),\n filter: v.optional(FilterSchema),\n invokeOn: v.optional(picklist(['stageEnter', 'manual'])),\n /**\n * Auto-completion predicate — same shape as `transition.filter`. When\n * truthy at activation or on any subsequent cascade, the engine\n * flips the task to `done` with a `{ kind: \"system\", id: \"engine.completeWhen\" }`\n * actor. A full filter, not just a wall-clock deadline.\n */\n completeWhen: v.optional(FilterSchema),\n /**\n * Auto-failure predicate — symmetric to `completeWhen`. Same shape,\n * same evaluation cadence (activation + every cascade), but flips\n * the task to `failed` (not `done`) with a `{ kind: \"system\",\n * id: \"engine.failWhen\" }` actor. When both `completeWhen` and\n * `failWhen` resolve truthy on the same evaluation, `failWhen`\n * wins — failure is the more notable signal and should not be\n * silently swallowed.\n */\n failWhen: v.optional(FilterSchema),\n effects: v.optional(v.array(EffectSchema)),\n actions: v.optional(v.array(ActionSchema)),\n spawns: v.optional(SpawnSchema),\n contentRefs: v.optional(v.array(v.unknown())),\n /** Task-scoped state slots. Resolved at task activation time. */\n state: v.optional(v.array(StateSlotSchema)),\n})\nexport type Task = v.InferOutput<typeof TaskSchema>\n\n// Transitions\n\nexport const TransitionSchema = v.strictObject({\n type: v.optional(v.literal('workflow.transition')),\n id: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n to: NonEmpty,\n on: v.optional(v.string()),\n filter: v.optional(FilterSchema),\n effects: v.optional(v.array(EffectSchema)),\n})\nexport type Transition = v.InferOutput<typeof TransitionSchema>\n\n// Guards — lake mutation guards (Content Lake). DISTINCT from `Filter`\n// above: a `Filter` is the engine's in-memory soft predicate that gates\n// transitions/tasks/actions; a `Guard` compiles to a `temp.system.guard`\n// document the lake evaluates at mutation time and that fails closed.\n//\n// The authoring shape is match + predicate + metadata. Targets in\n// `match.idRefs` are `Source`s resolved at deploy — `{source:\"self\"}`\n// targets the workflow instance; a `stateRead` of a doc-ref slot targets that\n// doc. The engine resolves each Source to a GDR, then splits it into the guard's\n// resource (resourceType/resourceId — the engine's outer-layer encapsulation;\n// the content lake is per-datasource) plus a BARE id. A GDR never appears in\n// `predicate`. All idRefs of one guard must resolve to the same resource (a\n// guard is single-resource).\n\nconst GuardActionSchema = picklist(MUTATION_GUARD_ACTIONS)\nexport type GuardAction = v.InferOutput<typeof GuardActionSchema>\n\nconst GuardMatchSchema = v.strictObject({\n /** Subject `_type`(s); empty matches any type. */\n types: v.optional(v.array(NonEmpty)),\n /** Target docs as `Source`s resolved at deploy to bare ids + the resource. */\n idRefs: v.optional(v.array(SourceSchema)),\n /** Glob id patterns (bare, resource-local). */\n idPatterns: v.optional(v.array(NonEmpty)),\n actions: v.pipe(\n v.array(GuardActionSchema),\n v.minLength(1, 'a guard must match at least one action'),\n ),\n})\nexport type GuardMatch = v.InferOutput<typeof GuardMatchSchema>\n\nconst GuardSchema = v.strictObject({\n name: v.optional(v.string()),\n description: v.optional(v.string()),\n match: GuardMatchSchema,\n /**\n * Lake GROQ predicate. Reads `document.before`/`document.after`, `mutation`,\n * `guard`, and `identity()`. Bare ids/fields only — no GDRs. Omitted or\n * empty means UNCONDITIONAL DENY.\n */\n predicate: v.optional(v.string()),\n /**\n * Projected workflow state the predicate reads as `guard.metadata.*`. Values\n * are `Source`s resolved at deploy and re-synced by the engine. Copied data,\n * never a cross-resource pointer.\n */\n metadata: v.optional(v.record(NonEmpty, SourceSchema)),\n})\nexport type Guard = v.InferOutput<typeof GuardSchema>\n\n// Stages\n\nconst StageKindSchema = picklist(['initial', 'intermediate', 'terminal', 'waiting'])\nexport type StageKind = v.InferOutput<typeof StageKindSchema>\n\nexport const StageSchema = v.strictObject({\n type: v.optional(v.literal('workflow.stage')),\n id: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n kind: v.optional(StageKindSchema),\n tasks: v.optional(v.array(TaskSchema)),\n transitions: v.optional(v.array(TransitionSchema)),\n completion: v.optional(FilterSchema),\n onEnter: v.optional(v.array(EffectSchema)),\n onExit: v.optional(v.array(EffectSchema)),\n /**\n * Lake mutation guards active while this stage holds. Each compiles to a\n * `temp.system.guard` doc deployed on stage entry and retracted on exit.\n * Plural because one stage's intent may span resources (one guard each).\n */\n guards: v.optional(v.array(GuardSchema)),\n contentRefs: v.optional(v.array(v.unknown())),\n /** Stage-scoped state slots. Resolved at stage entry and persisted on\n * the StageEntry. */\n state: v.optional(v.array(StateSlotSchema)),\n})\nexport type Stage = v.InferOutput<typeof StageSchema>\n\n// Workflow definition (the root)\n\n/**\n * Structural schema for a workflow definition. Cross-field invariants\n * (unique ids, transition/predicate references, terminal-stage rules)\n * are checked separately by `checkWorkflowInvariants` after this parse\n * succeeds — see `defineWorkflow`.\n */\nexport const WorkflowDefinitionSchema = v.strictObject({\n workflowId: NonEmpty,\n version: PositiveInt,\n title: NonEmpty,\n description: v.optional(v.string()),\n initialStageId: NonEmpty,\n /**\n * Workflow-level state slots. Persist for the instance lifetime.\n * Every stage's filters/ops can read them via\n * `*[_id == $self][0].state[key == \"<key>\"][0].value`. Init-sourced\n * slots are supplied at `startInstance` via `initialState`.\n */\n state: v.optional(v.array(StateSlotSchema)),\n stages: v.pipe(v.array(StageSchema), v.minLength(1, 'must declare at least one stage')),\n predicates: v.optional(v.array(PredicateSchema)),\n})\n\n/**\n * Workflow definition — inferred from the schema so authoring types\n * and runtime validation share one source of truth.\n */\nexport type WorkflowDefinition = v.InferOutput<typeof WorkflowDefinitionSchema>\n\n/**\n * The lake document type for a deployed workflow definition. Single source of\n * truth — every tag-scoped lookup query and the deploy write derive their\n * `_type` from here, mirroring {@link WORKFLOW_INSTANCE_TYPE}.\n */\nexport const WORKFLOW_DEFINITION_TYPE = 'workflow.definition'\n\n// Error formatting — turn validation issues into a multi-line,\n// path-prefixed message that points at the exact field the author got\n// wrong. Shared by structural parse errors (via {@link issuesFromValibot})\n// and cross-field invariant issues.\n\nexport interface ValidationIssue {\n path: ReadonlyArray<PropertyKey>\n message: string\n}\n\nexport function formatValidationError(label: string, issues: readonly ValidationIssue[]): string {\n const lines = issues.map((issue) => {\n const path = issue.path.length === 0 ? '(root)' : formatPath(issue.path)\n return ` - ${path}: ${issue.message}`\n })\n return `${label} failed validation (${issues.length} issue${\n issues.length === 1 ? '' : 's'\n }):\\n${lines.join('\\n')}`\n}\n\nexport function issuesFromValibot(issues: readonly v.BaseIssue<unknown>[]): ValidationIssue[] {\n return issues.map((issue) => ({\n path: issue.path ? issue.path.map((item) => item.key as PropertyKey) : [],\n message: issue.message,\n }))\n}\n\nfunction formatPath(path: ReadonlyArray<PropertyKey>): string {\n let out = ''\n for (const seg of path) {\n if (typeof seg === 'number') out += `[${seg}]`\n else out += out.length === 0 ? String(seg) : `.${String(seg)}`\n }\n return out\n}\n"],"names":["v"],"mappings":"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"}
|