@hatua/schema 0.0.0 → 0.1.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/LICENSE +21 -0
- package/dist/contract.test.d.ts +1 -0
- package/dist/generated/component.d.ts +312 -0
- package/dist/generated/context.d.ts +43 -0
- package/dist/generated/definition.d.ts +309 -0
- package/dist/generated/execution.d.ts +148 -0
- package/dist/generated/function.d.ts +193 -0
- package/dist/generated/index.d.ts +5 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +335 -0
- package/dist/references.d.ts +77 -0
- package/package.json +25 -5
- package/README.md +0 -5
package/dist/index.js
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import { z as e } from "zod";
|
|
2
|
+
//#region src/generated/component.ts
|
|
3
|
+
var t = e.strictObject({
|
|
4
|
+
kind: e.enum(["component", "trigger"]),
|
|
5
|
+
use: e.string().min(1),
|
|
6
|
+
name: e.string().min(1),
|
|
7
|
+
group: e.string().optional(),
|
|
8
|
+
icon: e.string().min(1).optional(),
|
|
9
|
+
blurb: e.string().optional(),
|
|
10
|
+
once: e.boolean().optional(),
|
|
11
|
+
fixed: e.boolean().optional(),
|
|
12
|
+
get fields() {
|
|
13
|
+
return e.array(n);
|
|
14
|
+
},
|
|
15
|
+
get outputs() {
|
|
16
|
+
return e.array(r);
|
|
17
|
+
},
|
|
18
|
+
get metadata() {
|
|
19
|
+
return e.array(i).optional();
|
|
20
|
+
}
|
|
21
|
+
}), n = e.strictObject({
|
|
22
|
+
k: e.string().min(1),
|
|
23
|
+
label: e.string().min(1),
|
|
24
|
+
kind: e.enum([
|
|
25
|
+
"text",
|
|
26
|
+
"mono",
|
|
27
|
+
"number",
|
|
28
|
+
"textarea",
|
|
29
|
+
"ref",
|
|
30
|
+
"map",
|
|
31
|
+
"enum",
|
|
32
|
+
"bool",
|
|
33
|
+
"conn",
|
|
34
|
+
"secret"
|
|
35
|
+
]),
|
|
36
|
+
conn_type: e.string().optional(),
|
|
37
|
+
req: e.boolean().optional(),
|
|
38
|
+
hint: e.string().optional(),
|
|
39
|
+
ph: e.string().optional(),
|
|
40
|
+
mono: e.boolean().optional(),
|
|
41
|
+
options: e.array(e.strictObject({
|
|
42
|
+
value: e.string(),
|
|
43
|
+
label: e.string(),
|
|
44
|
+
hint: e.string().optional()
|
|
45
|
+
})).optional(),
|
|
46
|
+
toggleLabel: e.string().optional(),
|
|
47
|
+
entry_types: e.array(e.enum([
|
|
48
|
+
"text",
|
|
49
|
+
"number",
|
|
50
|
+
"boolean",
|
|
51
|
+
"datetime",
|
|
52
|
+
"list",
|
|
53
|
+
"object"
|
|
54
|
+
])).optional(),
|
|
55
|
+
when: e.array(e.string()).min(2).max(2).optional()
|
|
56
|
+
}), r = e.strictObject({
|
|
57
|
+
k: e.string().min(1),
|
|
58
|
+
label: e.string().min(1),
|
|
59
|
+
t: e.enum([
|
|
60
|
+
"text",
|
|
61
|
+
"number",
|
|
62
|
+
"boolean",
|
|
63
|
+
"datetime",
|
|
64
|
+
"object",
|
|
65
|
+
"list",
|
|
66
|
+
"item"
|
|
67
|
+
]),
|
|
68
|
+
get of() {
|
|
69
|
+
return e.array(r).optional();
|
|
70
|
+
}
|
|
71
|
+
}), i = e.strictObject({
|
|
72
|
+
k: e.string().min(1),
|
|
73
|
+
label: e.string().min(1),
|
|
74
|
+
t: e.enum([
|
|
75
|
+
"text",
|
|
76
|
+
"number",
|
|
77
|
+
"boolean",
|
|
78
|
+
"datetime"
|
|
79
|
+
]),
|
|
80
|
+
role: e.enum(["measure", "dimension"]),
|
|
81
|
+
unit: e.string().optional()
|
|
82
|
+
}), a = e.union([t, e.strictObject({ get components() {
|
|
83
|
+
return e.array(t);
|
|
84
|
+
} })]), o = e.strictObject({
|
|
85
|
+
k: e.string().regex(/^[a-z][a-z0-9_]*$/),
|
|
86
|
+
label: e.string().min(1),
|
|
87
|
+
t: e.enum([
|
|
88
|
+
"text",
|
|
89
|
+
"number",
|
|
90
|
+
"boolean",
|
|
91
|
+
"datetime",
|
|
92
|
+
"object",
|
|
93
|
+
"list"
|
|
94
|
+
]),
|
|
95
|
+
description: e.string().optional(),
|
|
96
|
+
get of() {
|
|
97
|
+
return e.array(o).optional();
|
|
98
|
+
}
|
|
99
|
+
}), s = e.strictObject({
|
|
100
|
+
kind: e.enum(["context"]),
|
|
101
|
+
get keys() {
|
|
102
|
+
return e.array(o);
|
|
103
|
+
}
|
|
104
|
+
}), c = e.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/), l = e.strictObject({
|
|
105
|
+
get id() {
|
|
106
|
+
return c;
|
|
107
|
+
},
|
|
108
|
+
name: e.string().optional(),
|
|
109
|
+
get params() {
|
|
110
|
+
return e.array(u).optional();
|
|
111
|
+
},
|
|
112
|
+
get outputs() {
|
|
113
|
+
return e.array(u).optional();
|
|
114
|
+
},
|
|
115
|
+
get vars() {
|
|
116
|
+
return e.array(p).optional();
|
|
117
|
+
},
|
|
118
|
+
get steps() {
|
|
119
|
+
return e.array(m);
|
|
120
|
+
}
|
|
121
|
+
}), u = e.strictObject({
|
|
122
|
+
get k() {
|
|
123
|
+
return c;
|
|
124
|
+
},
|
|
125
|
+
label: e.string().min(1),
|
|
126
|
+
t: e.enum([
|
|
127
|
+
"text",
|
|
128
|
+
"number",
|
|
129
|
+
"boolean",
|
|
130
|
+
"datetime",
|
|
131
|
+
"object",
|
|
132
|
+
"list"
|
|
133
|
+
]),
|
|
134
|
+
get of() {
|
|
135
|
+
return e.array(u).optional();
|
|
136
|
+
}
|
|
137
|
+
}), d = e.strictObject({
|
|
138
|
+
id: e.string().min(1),
|
|
139
|
+
ref: e.string().nullable()
|
|
140
|
+
}), f = e.strictObject({
|
|
141
|
+
get id() {
|
|
142
|
+
return c;
|
|
143
|
+
},
|
|
144
|
+
use: e.string().min(1),
|
|
145
|
+
name: e.string().optional(),
|
|
146
|
+
get with() {
|
|
147
|
+
return g.optional();
|
|
148
|
+
}
|
|
149
|
+
}), p = e.strictObject({
|
|
150
|
+
get key() {
|
|
151
|
+
return c;
|
|
152
|
+
},
|
|
153
|
+
t: e.enum([
|
|
154
|
+
"text",
|
|
155
|
+
"number",
|
|
156
|
+
"boolean",
|
|
157
|
+
"datetime",
|
|
158
|
+
"object",
|
|
159
|
+
"list"
|
|
160
|
+
]),
|
|
161
|
+
get of() {
|
|
162
|
+
return e.array(u).optional();
|
|
163
|
+
},
|
|
164
|
+
value: e.unknown()
|
|
165
|
+
}), m = e.strictObject({
|
|
166
|
+
get id() {
|
|
167
|
+
return c;
|
|
168
|
+
},
|
|
169
|
+
use: e.string().min(1),
|
|
170
|
+
name: e.string().optional(),
|
|
171
|
+
get with() {
|
|
172
|
+
return g.optional();
|
|
173
|
+
},
|
|
174
|
+
get branches() {
|
|
175
|
+
return e.array(h).min(1).optional();
|
|
176
|
+
},
|
|
177
|
+
get steps() {
|
|
178
|
+
return e.array(m).optional();
|
|
179
|
+
},
|
|
180
|
+
get handler() {
|
|
181
|
+
return e.array(m).optional();
|
|
182
|
+
},
|
|
183
|
+
until: e.string().optional()
|
|
184
|
+
}), h = e.strictObject({
|
|
185
|
+
label: e.string(),
|
|
186
|
+
when: e.string().optional(),
|
|
187
|
+
get steps() {
|
|
188
|
+
return e.array(m);
|
|
189
|
+
}
|
|
190
|
+
}), g = e.record(e.string(), e.unknown()), _ = e.strictObject({
|
|
191
|
+
id: e.string().min(1),
|
|
192
|
+
name: e.string(),
|
|
193
|
+
version: e.number().int().min(1),
|
|
194
|
+
status: e.enum([
|
|
195
|
+
"published",
|
|
196
|
+
"draft",
|
|
197
|
+
"archived"
|
|
198
|
+
]),
|
|
199
|
+
get connections() {
|
|
200
|
+
return e.array(d).optional();
|
|
201
|
+
},
|
|
202
|
+
get triggers() {
|
|
203
|
+
return e.array(f).optional();
|
|
204
|
+
},
|
|
205
|
+
get vars() {
|
|
206
|
+
return e.array(p).optional();
|
|
207
|
+
},
|
|
208
|
+
get blocks() {
|
|
209
|
+
return e.array(l).optional();
|
|
210
|
+
},
|
|
211
|
+
get steps() {
|
|
212
|
+
return e.array(m);
|
|
213
|
+
}
|
|
214
|
+
}), v = e.strictObject({
|
|
215
|
+
id: e.string().min(1),
|
|
216
|
+
status: e.enum([
|
|
217
|
+
"pending",
|
|
218
|
+
"running",
|
|
219
|
+
"succeeded",
|
|
220
|
+
"failed",
|
|
221
|
+
"skipped"
|
|
222
|
+
]),
|
|
223
|
+
duration_ms: e.number().min(0).optional(),
|
|
224
|
+
resolved_input: e.unknown().optional(),
|
|
225
|
+
output: e.unknown().optional(),
|
|
226
|
+
metadata: e.record(e.string(), e.unknown()).optional(),
|
|
227
|
+
get error() {
|
|
228
|
+
return b.optional();
|
|
229
|
+
},
|
|
230
|
+
get iterations() {
|
|
231
|
+
return e.array(y).optional();
|
|
232
|
+
}
|
|
233
|
+
}), y = e.strictObject({
|
|
234
|
+
index: e.number().int().min(0),
|
|
235
|
+
status: e.enum([
|
|
236
|
+
"pending",
|
|
237
|
+
"running",
|
|
238
|
+
"succeeded",
|
|
239
|
+
"failed",
|
|
240
|
+
"skipped"
|
|
241
|
+
]),
|
|
242
|
+
duration_ms: e.number().min(0).optional(),
|
|
243
|
+
get steps() {
|
|
244
|
+
return e.array(v).optional();
|
|
245
|
+
},
|
|
246
|
+
get error() {
|
|
247
|
+
return b.optional();
|
|
248
|
+
}
|
|
249
|
+
}), b = e.strictObject({
|
|
250
|
+
message: e.string(),
|
|
251
|
+
code: e.string().optional()
|
|
252
|
+
}), x = e.strictObject({
|
|
253
|
+
at: e.iso.datetime({ offset: !0 }),
|
|
254
|
+
step: e.string().optional(),
|
|
255
|
+
channel: e.string().optional(),
|
|
256
|
+
message: e.string()
|
|
257
|
+
}), S = e.strictObject({
|
|
258
|
+
run_id: e.string().min(1),
|
|
259
|
+
status: e.enum([
|
|
260
|
+
"running",
|
|
261
|
+
"succeeded",
|
|
262
|
+
"failed"
|
|
263
|
+
]),
|
|
264
|
+
workflow: e.strictObject({
|
|
265
|
+
id: e.string().min(1),
|
|
266
|
+
version: e.number().int().min(1)
|
|
267
|
+
}),
|
|
268
|
+
trigger: e.strictObject({
|
|
269
|
+
id: e.string().min(1),
|
|
270
|
+
payload: e.record(e.string(), e.unknown()).optional()
|
|
271
|
+
}).optional(),
|
|
272
|
+
started_at: e.iso.datetime({ offset: !0 }),
|
|
273
|
+
finished_at: e.iso.datetime({ offset: !0 }).optional(),
|
|
274
|
+
duration_ms: e.number().min(0).optional(),
|
|
275
|
+
get steps() {
|
|
276
|
+
return e.array(v);
|
|
277
|
+
},
|
|
278
|
+
get log() {
|
|
279
|
+
return e.array(x).optional();
|
|
280
|
+
}
|
|
281
|
+
}), C = e.strictObject({
|
|
282
|
+
kind: e.enum(["function"]),
|
|
283
|
+
namespace: e.string().regex(/^[a-z][a-z0-9_]*$/),
|
|
284
|
+
summary: e.string().optional(),
|
|
285
|
+
get functions() {
|
|
286
|
+
return e.array(w).min(1);
|
|
287
|
+
}
|
|
288
|
+
}), w = e.strictObject({
|
|
289
|
+
name: e.string().regex(/^[a-z][a-z0-9_]*$/),
|
|
290
|
+
summary: e.string().optional(),
|
|
291
|
+
get params() {
|
|
292
|
+
return e.array(T).optional();
|
|
293
|
+
},
|
|
294
|
+
get returns() {
|
|
295
|
+
return E;
|
|
296
|
+
}
|
|
297
|
+
}), T = e.strictObject({
|
|
298
|
+
name: e.string().regex(/^[a-z][a-z0-9_]*$/),
|
|
299
|
+
get type() {
|
|
300
|
+
return E;
|
|
301
|
+
},
|
|
302
|
+
description: e.string().optional(),
|
|
303
|
+
optional: e.boolean().optional(),
|
|
304
|
+
variadic: e.boolean().optional()
|
|
305
|
+
}), E = e.enum([
|
|
306
|
+
"text",
|
|
307
|
+
"number",
|
|
308
|
+
"boolean",
|
|
309
|
+
"datetime",
|
|
310
|
+
"list",
|
|
311
|
+
"object",
|
|
312
|
+
"item",
|
|
313
|
+
"unknown",
|
|
314
|
+
"null"
|
|
315
|
+
]), D = e.union([C, e.strictObject({ get namespaces() {
|
|
316
|
+
return e.array(C);
|
|
317
|
+
} })]), O = "TRIGGER", k = [
|
|
318
|
+
"text",
|
|
319
|
+
"mono",
|
|
320
|
+
"number",
|
|
321
|
+
"textarea",
|
|
322
|
+
"ref",
|
|
323
|
+
"map"
|
|
324
|
+
], A = (e) => k.includes(e);
|
|
325
|
+
function j(e) {
|
|
326
|
+
if (typeof e != "object" || !e) return null;
|
|
327
|
+
let t = e.kind;
|
|
328
|
+
return t === "component" || t === "trigger" || t === "context" ? t : null;
|
|
329
|
+
}
|
|
330
|
+
var M = (e) => e.filter((e) => {
|
|
331
|
+
let t = j(e);
|
|
332
|
+
return t === "component" || t === "trigger";
|
|
333
|
+
}), N = (e) => e.flatMap((e) => j(e) === "context" ? e.keys ?? [] : []);
|
|
334
|
+
//#endregion
|
|
335
|
+
export { k as MAPPABLE_FIELD_KINDS, O as TRIGGER_BUILTIN, l as block, h as branch, a as componentManifest, d as connection, o as contextKey, N as contextKeysIn, u as declaration, j as entryKind, b as error, n as field, D as functionManifest, C as functionNamespace, w as functionSpec, c as identifier, A as isMappable, y as iteration, x as logEntry, t as manifest, M as manifestsIn, i as metadataDescriptor, r as output, T as param, s as runContextManifest, m as step, v as stepExecution, f as trigger, E as valueType, g as values, p as variable, _ as workflowDefinition, S as workflowExecution };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { ContextKey, Manifest, RunContextManifest } from './generated';
|
|
2
|
+
/**
|
|
3
|
+
* What a mappable field is, and the one built-in name.
|
|
4
|
+
*
|
|
5
|
+
* There is deliberately no `REFERENCE_PATTERN` regex here. A regex would be a
|
|
6
|
+
* second definition of what a Reference is, and two definitions of one thing
|
|
7
|
+
* disagree eventually — a pattern loose enough to match `{{ steps.s2.count }}` also
|
|
8
|
+
* matches `{{ a + b }}` and calls the whole thing a reference path.
|
|
9
|
+
*
|
|
10
|
+
* A Reference is an AST shape — `isReference()` in `@hatua/expressions` —
|
|
11
|
+
* and this file keeps only what the schema layer genuinely owns.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* The built-in holding the id of whichever Trigger actually fired. Needed
|
|
15
|
+
* because a workflow may declare several triggers with different payloads, so
|
|
16
|
+
* an expression has to be able to branch on which one started this run.
|
|
17
|
+
*/
|
|
18
|
+
export declare const TRIGGER_BUILTIN = "TRIGGER";
|
|
19
|
+
/**
|
|
20
|
+
* Field kinds whose value is a Template. The rest hold literal values only.
|
|
21
|
+
*
|
|
22
|
+
* `map` is here because each of its entries holds one, even though the field
|
|
23
|
+
* itself holds a list rather than a string.
|
|
24
|
+
*/
|
|
25
|
+
export declare const MAPPABLE_FIELD_KINDS: readonly ["text", "mono", "number", "textarea", "ref", "map"];
|
|
26
|
+
export declare const isMappable: (kind: string) => boolean;
|
|
27
|
+
/**
|
|
28
|
+
* One entry of the flat array a Host serves.
|
|
29
|
+
*
|
|
30
|
+
* A Component Manifest declares a step type or a trigger type; a Run Context
|
|
31
|
+
* Manifest declares the ambient values the Host supplies to every execution.
|
|
32
|
+
* They travel together because they answer the same question — *what has this
|
|
33
|
+
* Host declared?* — and splitting them would buy a second store, a second
|
|
34
|
+
* loading state and a second failure state for a payload that is a handful of
|
|
35
|
+
* typed keys.
|
|
36
|
+
*
|
|
37
|
+
* **This union is discriminated and the parse-time one is not**, which is the
|
|
38
|
+
* whole difference. `ComponentManifest` is "one manifest OR a `components:`
|
|
39
|
+
* catalogue": its second arm carries no `kind`, so `[{ components: [...] }]`
|
|
40
|
+
* satisfies it, typechecks, and is then dropped by every consumer that reaches
|
|
41
|
+
* for `.kind`. Every arm here is an object with a required literal `kind`, so
|
|
42
|
+
* the catalogue shape satisfies neither arm and a Host serving one is told so
|
|
43
|
+
* by the compiler rather than by an empty screen. `entryKind()` is the runtime
|
|
44
|
+
* half of the same guarantee, for the endpoint that breaks the promise anyway.
|
|
45
|
+
*/
|
|
46
|
+
export type ManifestEntry = Manifest | RunContextManifest;
|
|
47
|
+
/**
|
|
48
|
+
* What an entry declares, or null when it declares nothing this build knows.
|
|
49
|
+
*
|
|
50
|
+
* Null is not the same as invalid: a Host serving an entry from a newer
|
|
51
|
+
* contract than the one embedded here should lose that entry, not the whole
|
|
52
|
+
* catalogue. What is *not* null-able is the check itself — an entry with no
|
|
53
|
+
* `kind` at all is the wiring mistake this exists to name.
|
|
54
|
+
*/
|
|
55
|
+
export declare function entryKind(entry: unknown): ManifestEntry['kind'] | null;
|
|
56
|
+
/**
|
|
57
|
+
* The Component Manifests among the entries — step types and trigger types
|
|
58
|
+
* alike.
|
|
59
|
+
*
|
|
60
|
+
* Through `entryKind`, which is the point of it: the store deliberately passes
|
|
61
|
+
* an entry it cannot read straight through, saying so by name — "a `kind` from
|
|
62
|
+
* a newer contract, a name the Host left off, an outright `null`" — because one
|
|
63
|
+
* bad row must not empty a catalogue. Reaching for `.kind` on that row instead
|
|
64
|
+
* throws from render and takes down the Host's tree, which is the outcome the
|
|
65
|
+
* store's `failed` state exists to avoid.
|
|
66
|
+
*/
|
|
67
|
+
export declare const manifestsIn: (entries: readonly ManifestEntry[]) => Manifest[];
|
|
68
|
+
/**
|
|
69
|
+
* The Run Context keys among the entries, flattened.
|
|
70
|
+
*
|
|
71
|
+
* Flattened rather than "the first `kind: context` entry" because nothing stops
|
|
72
|
+
* a Host assembling its array from several sources, and one declaration
|
|
73
|
+
* silently winning over another is the failure a `use` collision would be.
|
|
74
|
+
* Keys are addressed as `run.<k>`, so a duplicate `k` is the Host's to resolve;
|
|
75
|
+
* `boardScope` takes the first, the way every other lookup here does.
|
|
76
|
+
*/
|
|
77
|
+
export declare const contextKeysIn: (entries: readonly ManifestEntry[]) => ContextKey[];
|
package/package.json
CHANGED
|
@@ -1,17 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hatua/schema",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Internal to @hatua/react — published because it is an external of its build, not a supported API. Workflow Definition and Workflow Execution contract types and validation.",
|
|
5
6
|
"license": "MIT",
|
|
6
7
|
"repository": {
|
|
7
8
|
"type": "git",
|
|
8
9
|
"url": "git+https://github.com/pedromvgomes/hatua.git",
|
|
9
10
|
"directory": "source/packages/schema"
|
|
10
11
|
},
|
|
12
|
+
"sideEffects": false,
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
11
22
|
"publishConfig": {
|
|
12
23
|
"access": "public"
|
|
13
24
|
},
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"zod": "^4.5.4"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"yaml": "^2.9.0"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "vite build",
|
|
33
|
+
"typecheck": "tsc --noEmit",
|
|
34
|
+
"test": "vitest run --passWithNoTests",
|
|
35
|
+
"test:coverage": "vitest run --coverage --coverage.reporter=text-summary --coverage.reporter=json-summary --coverage.reporter=lcovonly --passWithNoTests"
|
|
36
|
+
}
|
|
17
37
|
}
|