smokin 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/CHANGELOG.md +45 -0
- package/LICENSE +21 -0
- package/README.md +366 -0
- package/dist/dataset/dataset.d.ts +43 -0
- package/dist/dataset/dataset.d.ts.map +1 -0
- package/dist/dataset/dataset.js +63 -0
- package/dist/dataset/dataset.js.map +1 -0
- package/dist/dataset/relate.d.ts +32 -0
- package/dist/dataset/relate.d.ts.map +1 -0
- package/dist/dataset/relate.js +46 -0
- package/dist/dataset/relate.js.map +1 -0
- package/dist/foundation/axes.d.ts +92 -0
- package/dist/foundation/axes.d.ts.map +1 -0
- package/dist/foundation/axes.js +42 -0
- package/dist/foundation/axes.js.map +1 -0
- package/dist/foundation/errors.d.ts +30 -0
- package/dist/foundation/errors.d.ts.map +1 -0
- package/dist/foundation/errors.js +53 -0
- package/dist/foundation/errors.js.map +1 -0
- package/dist/foundation/hash.d.ts +16 -0
- package/dist/foundation/hash.d.ts.map +1 -0
- package/dist/foundation/hash.js +26 -0
- package/dist/foundation/hash.js.map +1 -0
- package/dist/foundation/ir.d.ts +79 -0
- package/dist/foundation/ir.d.ts.map +1 -0
- package/dist/foundation/ir.js +16 -0
- package/dist/foundation/ir.js.map +1 -0
- package/dist/foundation/prng.d.ts +27 -0
- package/dist/foundation/prng.d.ts.map +1 -0
- package/dist/foundation/prng.js +56 -0
- package/dist/foundation/prng.js.map +1 -0
- package/dist/foundation/types.d.ts +59 -0
- package/dist/foundation/types.d.ts.map +1 -0
- package/dist/foundation/types.js +99 -0
- package/dist/foundation/types.js.map +1 -0
- package/dist/foundation/walk.d.ts +43 -0
- package/dist/foundation/walk.d.ts.map +1 -0
- package/dist/foundation/walk.js +156 -0
- package/dist/foundation/walk.js.map +1 -0
- package/dist/generator/engine.d.ts +62 -0
- package/dist/generator/engine.d.ts.map +1 -0
- package/dist/generator/engine.js +369 -0
- package/dist/generator/engine.js.map +1 -0
- package/dist/generator/replay.d.ts +31 -0
- package/dist/generator/replay.d.ts.map +1 -0
- package/dist/generator/replay.js +66 -0
- package/dist/generator/replay.js.map +1 -0
- package/dist/generator/trace.d.ts +50 -0
- package/dist/generator/trace.d.ts.map +1 -0
- package/dist/generator/trace.js +39 -0
- package/dist/generator/trace.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/schema/composites.d.ts +91 -0
- package/dist/schema/composites.d.ts.map +1 -0
- package/dist/schema/composites.js +94 -0
- package/dist/schema/composites.js.map +1 -0
- package/dist/schema/conditional.d.ts +22 -0
- package/dist/schema/conditional.d.ts.map +1 -0
- package/dist/schema/conditional.js +29 -0
- package/dist/schema/conditional.js.map +1 -0
- package/dist/schema/decimal.d.ts +31 -0
- package/dist/schema/decimal.d.ts.map +1 -0
- package/dist/schema/decimal.js +39 -0
- package/dist/schema/decimal.js.map +1 -0
- package/dist/schema/primitives.d.ts +29 -0
- package/dist/schema/primitives.d.ts.map +1 -0
- package/dist/schema/primitives.js +44 -0
- package/dist/schema/primitives.js.map +1 -0
- package/dist/validator/parse.d.ts +17 -0
- package/dist/validator/parse.d.ts.map +1 -0
- package/dist/validator/parse.js +218 -0
- package/dist/validator/parse.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phantom-typed schema builder + Infer<>.
|
|
3
|
+
*
|
|
4
|
+
* Every builder carries:
|
|
5
|
+
* - `_node`: serializable IR (runtime)
|
|
6
|
+
* - `_type`: phantom TS type parameter for inference (compile-time only)
|
|
7
|
+
*
|
|
8
|
+
* Modifiers (.nullable / .optional / .default / .describe) return a *new*
|
|
9
|
+
* builder with updated phantom type and updated IR.
|
|
10
|
+
*/
|
|
11
|
+
import { withMods } from './ir.js';
|
|
12
|
+
/** Base builder. Subclasses (StringSchema, NumberSchema, …) extend this. */
|
|
13
|
+
export class Schema {
|
|
14
|
+
_node;
|
|
15
|
+
constructor(node) {
|
|
16
|
+
this._node = node;
|
|
17
|
+
}
|
|
18
|
+
nullable() {
|
|
19
|
+
return new Schema(withMods(this._node, { nullable: true }));
|
|
20
|
+
}
|
|
21
|
+
optional() {
|
|
22
|
+
return new Schema(withMods(this._node, { optional: true }));
|
|
23
|
+
}
|
|
24
|
+
default(value) {
|
|
25
|
+
return new Schema(withMods(this._node, { hasDefault: true, defaultValue: value }));
|
|
26
|
+
}
|
|
27
|
+
describe(text) {
|
|
28
|
+
return this.withModsPreserveType({ description: text });
|
|
29
|
+
}
|
|
30
|
+
// ── data-schema axes (Phase 2) ────────────────────────────────────────────
|
|
31
|
+
/** Weighted distribution over discrete values. Weights are relative. */
|
|
32
|
+
weighted(weights) {
|
|
33
|
+
return this.withAxes({
|
|
34
|
+
distribution: {
|
|
35
|
+
kind: 'weighted',
|
|
36
|
+
weights: weights,
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/** Normal (Gaussian) distribution for numeric schemas. */
|
|
41
|
+
normal(mean, stddev) {
|
|
42
|
+
return this.withAxes({ distribution: { kind: 'normal', mean, stddev } });
|
|
43
|
+
}
|
|
44
|
+
/** Typical range — values concentrate uniformly inside [from, to]. */
|
|
45
|
+
typically(from, to) {
|
|
46
|
+
return this.withAxes({ distribution: { kind: 'typical', from, to } });
|
|
47
|
+
}
|
|
48
|
+
/** Force `value` with probability `p` (stacks before base distribution). */
|
|
49
|
+
occasionally(value, p) {
|
|
50
|
+
if (!(p >= 0 && p <= 1))
|
|
51
|
+
throw new RangeError(`occasionally: p must be in [0,1], got ${p}`);
|
|
52
|
+
const override = { value, p };
|
|
53
|
+
return this.withAxes({ occasionally: [override] });
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Force `value` every `every` rows (deterministic, driven by `ctx.index`).
|
|
57
|
+
*
|
|
58
|
+
* Useful for periodic rare events that must hit at a guaranteed cadence
|
|
59
|
+
* (e.g. monthly maintenance shutdown). Skipped when `ctx.index` is undefined.
|
|
60
|
+
*/
|
|
61
|
+
eventually(every, value, opts) {
|
|
62
|
+
if (!Number.isInteger(every) || every < 1) {
|
|
63
|
+
throw new RangeError(`eventually: every must be a positive integer, got ${every}`);
|
|
64
|
+
}
|
|
65
|
+
const override = {
|
|
66
|
+
value,
|
|
67
|
+
every,
|
|
68
|
+
...(opts?.offset !== undefined ? { offset: opts.offset } : {}),
|
|
69
|
+
};
|
|
70
|
+
return this.withAxes({ eventually: [override] });
|
|
71
|
+
}
|
|
72
|
+
/** Field is computed from sibling/root context — generator skips sampling. */
|
|
73
|
+
derivedFrom(fn) {
|
|
74
|
+
return this.withAxes({ derived: fn });
|
|
75
|
+
}
|
|
76
|
+
/** Single-record predicate. Generator retries up to MAX_ATTEMPTS to satisfy. */
|
|
77
|
+
invariant(fn) {
|
|
78
|
+
return this.withAxes({ invariants: [fn] });
|
|
79
|
+
}
|
|
80
|
+
/** Restrict to a closed candidate set or a lookup-by-sibling-field map. */
|
|
81
|
+
in(constraint) {
|
|
82
|
+
const dom = Array.isArray(constraint)
|
|
83
|
+
? { kind: 'values', values: constraint }
|
|
84
|
+
: constraint;
|
|
85
|
+
return this.withAxes({ domain: dom });
|
|
86
|
+
}
|
|
87
|
+
// ── internal helpers ──────────────────────────────────────────────────────
|
|
88
|
+
withAxes(axes) {
|
|
89
|
+
return this.withModsPreserveType({ axes });
|
|
90
|
+
}
|
|
91
|
+
withModsPreserveType(patch) {
|
|
92
|
+
const next = Object.create(Object.getPrototypeOf(this));
|
|
93
|
+
Object.assign(next, this, {
|
|
94
|
+
_node: withMods(this._node, patch),
|
|
95
|
+
});
|
|
96
|
+
return next;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/foundation/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extensibility API — IR walker and IR-to-builder reconstruction.
|
|
3
|
+
*
|
|
4
|
+
* smokin intentionally ships no CLI, no OpenAPI ingestion, no zod adapter,
|
|
5
|
+
* no GUI — these belong in *external* packages. This module exposes the
|
|
6
|
+
* minimum surface those packages need:
|
|
7
|
+
*
|
|
8
|
+
* - `walkSchema(node, visitor)` : pre/post-order traversal with paths
|
|
9
|
+
* - `fromIR(node)` : reconstruct a `Schema` builder from IR
|
|
10
|
+
*
|
|
11
|
+
* Combined with the already-public `SchemaNode`, `Modifiers`, `Axes`,
|
|
12
|
+
* `mock`, `parse`, `mockDataset`, `createTrace`, and `seedFromString` /
|
|
13
|
+
* `rngFromString`, this is the full plugin contract.
|
|
14
|
+
*
|
|
15
|
+
* Plugin authors do NOT subclass `Schema`. They build IR (or compose
|
|
16
|
+
* existing builders) and call `fromIR` to obtain a typed builder back.
|
|
17
|
+
*/
|
|
18
|
+
import { Schema } from './types.js';
|
|
19
|
+
import type { SchemaNode } from './ir.js';
|
|
20
|
+
export type WalkPath = readonly (string | number)[];
|
|
21
|
+
export type SchemaVisitor = {
|
|
22
|
+
/** Called before descending into a node's children. Return false to skip subtree. */
|
|
23
|
+
readonly enter?: (node: SchemaNode, path: WalkPath) => void | boolean;
|
|
24
|
+
/** Called after all children have been visited. */
|
|
25
|
+
readonly leave?: (node: SchemaNode, path: WalkPath) => void;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Depth-first pre/post-order traversal of a schema IR tree.
|
|
29
|
+
*
|
|
30
|
+
* The visitor receives every node (including composites) with its
|
|
31
|
+
* JSON-pointer-style path. Use this to power codegen (OpenAPI, zod, SQL DDL,
|
|
32
|
+
* documentation) without coupling to the builder classes.
|
|
33
|
+
*/
|
|
34
|
+
export declare const walkSchema: (schemaOrNode: Schema | SchemaNode, visitor: SchemaVisitor) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Reconstruct a `Schema` builder from an IR node.
|
|
37
|
+
*
|
|
38
|
+
* Modifiers (`nullable`, `optional`, `default`, `describe`, axes) are
|
|
39
|
+
* preserved. Returns `Schema<unknown>` — plugin authors that know the shape
|
|
40
|
+
* statically can cast to a more precise type.
|
|
41
|
+
*/
|
|
42
|
+
export declare const fromIR: (node: SchemaNode) => Schema<unknown>;
|
|
43
|
+
//# sourceMappingURL=walk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk.d.ts","sourceRoot":"","sources":["../../src/foundation/walk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAYH,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEzC,MAAM,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;AAEnD,MAAM,MAAM,aAAa,GAAG;IAC1B,qFAAqF;IACrF,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAA;IACrE,mDAAmD;IACnD,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAA;CAC5D,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,iBACP,MAAM,GAAG,UAAU,WACxB,aAAa,KACrB,IAGF,CAAA;AA2BD;;;;;;GAMG;AACH,eAAO,MAAM,MAAM,SAAU,UAAU,KAAG,OAAO,OAAO,CAGvD,CAAA"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extensibility API — IR walker and IR-to-builder reconstruction.
|
|
3
|
+
*
|
|
4
|
+
* smokin intentionally ships no CLI, no OpenAPI ingestion, no zod adapter,
|
|
5
|
+
* no GUI — these belong in *external* packages. This module exposes the
|
|
6
|
+
* minimum surface those packages need:
|
|
7
|
+
*
|
|
8
|
+
* - `walkSchema(node, visitor)` : pre/post-order traversal with paths
|
|
9
|
+
* - `fromIR(node)` : reconstruct a `Schema` builder from IR
|
|
10
|
+
*
|
|
11
|
+
* Combined with the already-public `SchemaNode`, `Modifiers`, `Axes`,
|
|
12
|
+
* `mock`, `parse`, `mockDataset`, `createTrace`, and `seedFromString` /
|
|
13
|
+
* `rngFromString`, this is the full plugin contract.
|
|
14
|
+
*
|
|
15
|
+
* Plugin authors do NOT subclass `Schema`. They build IR (or compose
|
|
16
|
+
* existing builders) and call `fromIR` to obtain a typed builder back.
|
|
17
|
+
*/
|
|
18
|
+
import { arr, enum_, literal, obj, tuple, union, } from '../schema/composites.js';
|
|
19
|
+
import { decimal } from '../schema/decimal.js';
|
|
20
|
+
import { bool, int, null_, num, str } from '../schema/primitives.js';
|
|
21
|
+
import { Schema } from './types.js';
|
|
22
|
+
/**
|
|
23
|
+
* Depth-first pre/post-order traversal of a schema IR tree.
|
|
24
|
+
*
|
|
25
|
+
* The visitor receives every node (including composites) with its
|
|
26
|
+
* JSON-pointer-style path. Use this to power codegen (OpenAPI, zod, SQL DDL,
|
|
27
|
+
* documentation) without coupling to the builder classes.
|
|
28
|
+
*/
|
|
29
|
+
export const walkSchema = (schemaOrNode, visitor) => {
|
|
30
|
+
const root = schemaOrNode instanceof Schema ? schemaOrNode._node : schemaOrNode;
|
|
31
|
+
walk(root, [], visitor);
|
|
32
|
+
};
|
|
33
|
+
const walk = (node, path, v) => {
|
|
34
|
+
const shouldDescend = v.enter ? v.enter(node, path) !== false : true;
|
|
35
|
+
if (shouldDescend) {
|
|
36
|
+
switch (node.kind) {
|
|
37
|
+
case 'object':
|
|
38
|
+
for (const k of Object.keys(node.fields)) {
|
|
39
|
+
walk(node.fields[k], [...path, k], v);
|
|
40
|
+
}
|
|
41
|
+
break;
|
|
42
|
+
case 'array':
|
|
43
|
+
walk(node.item, [...path, '[]'], v);
|
|
44
|
+
break;
|
|
45
|
+
case 'tuple':
|
|
46
|
+
node.items.forEach((it, i) => walk(it, [...path, i], v));
|
|
47
|
+
break;
|
|
48
|
+
case 'union':
|
|
49
|
+
node.options.forEach((o, i) => walk(o, [...path, `|${i}`], v));
|
|
50
|
+
break;
|
|
51
|
+
default:
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
v.leave?.(node, path);
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Reconstruct a `Schema` builder from an IR node.
|
|
59
|
+
*
|
|
60
|
+
* Modifiers (`nullable`, `optional`, `default`, `describe`, axes) are
|
|
61
|
+
* preserved. Returns `Schema<unknown>` — plugin authors that know the shape
|
|
62
|
+
* statically can cast to a more precise type.
|
|
63
|
+
*/
|
|
64
|
+
export const fromIR = (node) => {
|
|
65
|
+
const base = buildBase(node);
|
|
66
|
+
return applyMods(base, node);
|
|
67
|
+
};
|
|
68
|
+
const buildBase = (node) => {
|
|
69
|
+
switch (node.kind) {
|
|
70
|
+
case 'string': {
|
|
71
|
+
let s = str();
|
|
72
|
+
if (node.min !== undefined)
|
|
73
|
+
s = s.min(node.min);
|
|
74
|
+
if (node.max !== undefined)
|
|
75
|
+
s = s.max(node.max);
|
|
76
|
+
if (node.pattern !== undefined)
|
|
77
|
+
s = s.pattern(node.pattern);
|
|
78
|
+
return s;
|
|
79
|
+
}
|
|
80
|
+
case 'number': {
|
|
81
|
+
let n = node.int ? int() : num();
|
|
82
|
+
if (node.min !== undefined)
|
|
83
|
+
n = n.min(node.min);
|
|
84
|
+
if (node.max !== undefined)
|
|
85
|
+
n = n.max(node.max);
|
|
86
|
+
return n;
|
|
87
|
+
}
|
|
88
|
+
case 'decimal': {
|
|
89
|
+
let d = decimal(node.precision, node.scale);
|
|
90
|
+
if (node.min !== undefined)
|
|
91
|
+
d = d.min(node.min);
|
|
92
|
+
if (node.max !== undefined)
|
|
93
|
+
d = d.max(node.max);
|
|
94
|
+
return d;
|
|
95
|
+
}
|
|
96
|
+
case 'boolean':
|
|
97
|
+
return bool();
|
|
98
|
+
case 'null':
|
|
99
|
+
return null_();
|
|
100
|
+
case 'literal':
|
|
101
|
+
return literal(node.value);
|
|
102
|
+
case 'enum':
|
|
103
|
+
return enum_(node.values);
|
|
104
|
+
case 'object': {
|
|
105
|
+
const fields = {};
|
|
106
|
+
for (const k of Object.keys(node.fields)) {
|
|
107
|
+
fields[k] = fromIR(node.fields[k]);
|
|
108
|
+
}
|
|
109
|
+
return obj(fields);
|
|
110
|
+
}
|
|
111
|
+
case 'array': {
|
|
112
|
+
let a = arr(fromIR(node.item));
|
|
113
|
+
if (node.length !== undefined)
|
|
114
|
+
a = a.length(node.length);
|
|
115
|
+
else {
|
|
116
|
+
if (node.minLength !== undefined)
|
|
117
|
+
a = a.min(node.minLength);
|
|
118
|
+
if (node.maxLength !== undefined)
|
|
119
|
+
a = a.max(node.maxLength);
|
|
120
|
+
}
|
|
121
|
+
return a;
|
|
122
|
+
}
|
|
123
|
+
case 'tuple': {
|
|
124
|
+
const items = node.items.map((it) => fromIR(it));
|
|
125
|
+
return tuple(...items);
|
|
126
|
+
}
|
|
127
|
+
case 'union': {
|
|
128
|
+
const opts = node.options.map((o) => fromIR(o));
|
|
129
|
+
return union(...opts);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
const applyMods = (schema, node) => {
|
|
134
|
+
const mods = node.mods;
|
|
135
|
+
if (mods === undefined)
|
|
136
|
+
return schema;
|
|
137
|
+
let out = schema;
|
|
138
|
+
if (mods.nullable === true)
|
|
139
|
+
out = out.nullable();
|
|
140
|
+
if (mods.optional === true)
|
|
141
|
+
out = out.optional();
|
|
142
|
+
if (mods.hasDefault === true)
|
|
143
|
+
out = out.default(mods.defaultValue);
|
|
144
|
+
if (mods.description !== undefined)
|
|
145
|
+
out = out.describe(mods.description);
|
|
146
|
+
if (mods.axes !== undefined) {
|
|
147
|
+
// Re-apply axes by mutating internal IR through the existing helper.
|
|
148
|
+
// Cast through `unknown` to reach the protected hook.
|
|
149
|
+
const withAxes = out.withAxes;
|
|
150
|
+
if (typeof withAxes === 'function') {
|
|
151
|
+
out = withAxes.call(out, mods.axes);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return out;
|
|
155
|
+
};
|
|
156
|
+
//# sourceMappingURL=walk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk.js","sourceRoot":"","sources":["../../src/foundation/walk.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generator engine — turns a SchemaNode + context into a deterministic value.
|
|
3
|
+
*
|
|
4
|
+
* Phase 2 wires the 8 data-schema axes (Z_PLAN §4.5) into the pipeline.
|
|
5
|
+
* Resolution priority during sampling (Z_PLAN §4.6.1):
|
|
6
|
+
*
|
|
7
|
+
* 1. invariants (rejection-sample until they hold; bounded by MAX_ATTEMPTS)
|
|
8
|
+
* 2. identity (handled at dataset layer; not seen here)
|
|
9
|
+
* 3. derived (computed from sibling/root context — skip sampling entirely)
|
|
10
|
+
* 4. conditional (union / discriminated branch selection)
|
|
11
|
+
* 5. domain (closed candidate set)
|
|
12
|
+
* 6. distribution (weighted / normal / typical)
|
|
13
|
+
* 7. type (fall-back bounds from the IR)
|
|
14
|
+
*/
|
|
15
|
+
import type { GenContext } from '../foundation/axes.js';
|
|
16
|
+
import type { SchemaNode } from '../foundation/ir.js';
|
|
17
|
+
import { type Rng } from '../foundation/prng.js';
|
|
18
|
+
import type { Infer, Schema } from '../foundation/types.js';
|
|
19
|
+
import type { TraceCollector } from './trace.js';
|
|
20
|
+
/**
|
|
21
|
+
* Per-leaf stable-seed hook.
|
|
22
|
+
*
|
|
23
|
+
* Called for every leaf-value sampling (string/number/decimal/boolean/enum/domain).
|
|
24
|
+
* Return a non-empty string to deterministically reseed *just this leaf*
|
|
25
|
+
* (path-scoped) — useful for snapshot/CI runs where a subset of rows must
|
|
26
|
+
* stay identical regardless of the outer `seed`.
|
|
27
|
+
* Return `null`/`undefined`/`''` to fall back to the shared rng (normal random).
|
|
28
|
+
*
|
|
29
|
+
* Composite kinds (object/array/tuple/union) are unaffected; their children
|
|
30
|
+
* re-enter this hook with their own path.
|
|
31
|
+
*/
|
|
32
|
+
export type StableByFn = (ctx: GenContext) => string | null | undefined;
|
|
33
|
+
export type MockOptions = {
|
|
34
|
+
/** Override the deterministic seed. Either a string or unsigned 32-bit int. */
|
|
35
|
+
readonly seed?: string | number;
|
|
36
|
+
/** Caller-supplied context channel exposed to derived/invariants as `ctx.input`. */
|
|
37
|
+
readonly input?: Readonly<Record<string, unknown>>;
|
|
38
|
+
/** Top-level row index (used by `mockDataset` so per-row derived can read `ctx.index`). */
|
|
39
|
+
readonly index?: number;
|
|
40
|
+
/** Optional trace collector — receives one entry per resolved field (A2). */
|
|
41
|
+
readonly trace?: TraceCollector;
|
|
42
|
+
/** Reseed leaf sampling deterministically from a caller-chosen key. */
|
|
43
|
+
readonly stableBy?: StableByFn;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Generate a value that conforms to the given schema.
|
|
47
|
+
*
|
|
48
|
+
* Deterministic: identical `schema` + `options.seed` always yields the same
|
|
49
|
+
* value, on every machine, every run.
|
|
50
|
+
*/
|
|
51
|
+
export declare const mock: <S extends Schema<unknown>>(schema: S, options?: MockOptions) => Infer<S>;
|
|
52
|
+
export type GenState = {
|
|
53
|
+
rng: Rng;
|
|
54
|
+
rootSeed: string;
|
|
55
|
+
root: unknown;
|
|
56
|
+
input?: Readonly<Record<string, unknown>>;
|
|
57
|
+
rootIndex?: number;
|
|
58
|
+
trace?: TraceCollector;
|
|
59
|
+
stableBy?: StableByFn;
|
|
60
|
+
};
|
|
61
|
+
export declare const generateNode: (node: SchemaNode, path: readonly (string | number)[], parent: Readonly<Record<string, unknown>>, state: GenState) => unknown;
|
|
62
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/generator/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAMV,UAAU,EAEX,MAAM,uBAAuB,CAAA;AAE9B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,EAA6B,KAAK,GAAG,EAAE,MAAM,uBAAuB,CAAA;AAC3E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,UAAU,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;AAEvE,MAAM,MAAM,WAAW,GAAG;IACxB,+EAA+E;IAC/E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC/B,oFAAoF;IACpF,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IAClD,2FAA2F;IAC3F,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,6EAA6E;IAC7E,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAA;IAC/B,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAA;CAC/B,CAAA;AAKD;;;;;GAKG;AACH,eAAO,MAAM,IAAI,sCAA8B,CAAC,YAAW,WAAW,KAAQ,MAAM,CAAC,CAiBpF,CAAA;AAMD,MAAM,MAAM,QAAQ,GAAG;IACrB,GAAG,EAAE,GAAG,CAAA;IACR,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IACzC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,cAAc,CAAA;IACtB,QAAQ,CAAC,EAAE,UAAU,CAAA;CACtB,CAAA;AA0DD,eAAO,MAAM,YAAY,SACjB,UAAU,QACV,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,UAC1B,SAAS,OAAO,MAAM,EAAE,OAAO,CAAC,CAAC,SAClC,QAAQ,KACd,OA4DF,CAAA"}
|