@toist/spec 0.7.1 → 0.8.1

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/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  All notable changes to `@toist/spec` are recorded here.
4
4
 
5
+ ## 0.8.1 — 2026-05-08
6
+
7
+ Lockstep version bump. No functional changes in this package.
8
+
9
+ ## 0.8.0 — 2026-05-08
10
+
11
+ - **Structural `DataHandle` / `DataStatement` interfaces** replace the
12
+ `bun:sqlite` `Database` import for `PlatformCtx.db`. Bun's real
13
+ `Database` structurally satisfies the interface; non-Bun runtimes can
14
+ supply their own implementation. Keeps `@toist/spec` source free of
15
+ Bun-specific imports.
16
+ - `validateSpec(input, options)` accepts an optional `registry` for
17
+ scope-aware validation (used by `@toist/core`'s runner-aware wrapper).
18
+
5
19
  ## 0.7.1 — 2026-05-06
6
20
 
7
21
  Lockstep version bump. No functional changes in this package.
package/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # `@toist/spec`
2
+
3
+ Pure Toist pipeline-format tooling: YAML parsing, discriminator/expression parsing, JSON Schema helpers, and offline validation.
4
+
5
+ ```ts
6
+ import { parseYaml, validateSpec } from "@toist/spec"
7
+
8
+ const spec = parseYaml(`
9
+ apiVersion: "2121.fi/v1"
10
+ id: hello
11
+ nodes:
12
+ - id: greet
13
+ kind: data.json
14
+ params:
15
+ value: { message: "hello" }
16
+ `)
17
+
18
+ const result = validateSpec(spec)
19
+ if (!result.ok) throw new Error(result.errors.join("; "))
20
+ console.log(result.parsed?.id)
21
+ ```
22
+
23
+ ## What it exports
24
+
25
+ - `parseYaml` / `YamlError`
26
+ - `parseExpr`, `evalExpr`
27
+ - `parseDisc`, `resolveDisc`
28
+ - `validateSpec`
29
+ - kind-contract types like `NodeKind`, `ExecContext`, `PlatformCtx`
30
+ - JSON Schema helpers like `pipelineSchema` and `kindToNodeSchema`
31
+
32
+ ## Validation
33
+
34
+ `validateSpec(input)` is pure. It checks pipeline shape, refs, cycles, payload schema, and returns parsed graph data:
35
+
36
+ ```ts
37
+ const result = validateSpec(spec)
38
+ if (result.ok) {
39
+ console.log(result.parsed?.parsedNodes)
40
+ console.log(result.parsed?.edges)
41
+ }
42
+ ```
43
+
44
+ If you have a live kind registry, pass kind resolvers through `ValidateOptions`.
45
+
46
+ ## Kind-facing types
47
+
48
+ Kinds depend on the spec package for their contract:
49
+
50
+ ```ts
51
+ import type { NodeKind } from "@toist/spec"
52
+ ```
53
+
54
+ That keeps pipeline tooling and kind authoring free of runner/server dependencies.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toist/spec",
3
- "version": "0.7.1",
3
+ "version": "0.8.1",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -9,7 +9,8 @@
9
9
  },
10
10
  "files": [
11
11
  "src/",
12
- "CHANGELOG.md"
12
+ "CHANGELOG.md",
13
+ "README.md"
13
14
  ],
14
15
  "dependencies": {
15
16
  "@babel/parser": "^7.25.0",
package/src/index.ts CHANGED
@@ -35,6 +35,8 @@ export {
35
35
  type SubRunOutcome,
36
36
  type OnErrorPolicy,
37
37
  type ErrorReviewSpec,
38
+ type DataHandle,
39
+ type DataStatement,
38
40
  type ParamDef,
39
41
  type PortDef,
40
42
  type Cache,
package/src/kinds.ts CHANGED
@@ -10,7 +10,17 @@
10
10
  // the dependency graph. The split between this file and `validate.ts` is
11
11
  // for human clarity, not for bundle isolation.
12
12
 
13
- import type { Database } from "bun:sqlite"
13
+ export interface DataStatement {
14
+ run(...args: unknown[]): unknown
15
+ get(...args: unknown[]): unknown
16
+ all(...args: unknown[]): unknown[]
17
+ }
18
+
19
+ export interface DataHandle {
20
+ exec(sql: string): unknown
21
+ prepare(sql: string): DataStatement
22
+ transaction(fn: (...args: any[]) => unknown): (...args: any[]) => unknown
23
+ }
14
24
 
15
25
  export interface ParamDef {
16
26
  type: "string" | "number" | "boolean" | "expression" | "json" | "select"
@@ -121,7 +131,7 @@ export type SubRun = (pipelineId: string, payload: Record<string, unknown>) => P
121
131
  export interface PlatformCtx {
122
132
  runId: number
123
133
  log: (level: "info" | "warn" | "error", msg: string) => void
124
- db: Database
134
+ db: DataHandle
125
135
  cache: Cache
126
136
  /** Resolved resource instances. ctx.resource.<name>.<field> in { expr } nodes. */
127
137
  resource: Record<string, Record<string, unknown>>