@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/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.0.0",
4
- "description": "Placeholder reserving the name. Nothing is published here; see 0.1.0 and later.",
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
- "files": [
15
- "README.md"
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
  }
package/README.md DELETED
@@ -1,5 +0,0 @@
1
- # @hatua/schema
2
-
3
- This version reserves the package name and contains no code.
4
-
5
- Install `0.1.0` or later.