@databehave/schema 0.1.2 → 0.1.4
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/dataset/dataset.d.ts +47 -0
- package/dist/dataset/dataset.d.ts.map +1 -0
- package/dist/dataset/dataset.js +96 -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 +101 -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 +99 -0
- package/dist/foundation/errors.d.ts.map +1 -0
- package/dist/foundation/errors.js +91 -0
- package/dist/foundation/errors.js.map +1 -0
- package/dist/foundation/hash.d.ts +12 -0
- package/dist/foundation/hash.d.ts.map +1 -0
- package/dist/foundation/hash.js +21 -0
- package/dist/foundation/hash.js.map +1 -0
- package/dist/foundation/ir.d.ts +91 -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 +116 -0
- package/dist/foundation/types.d.ts.map +1 -0
- package/dist/foundation/types.js +188 -0
- package/dist/foundation/types.js.map +1 -0
- package/dist/foundation/walk.d.ts +72 -0
- package/dist/foundation/walk.d.ts.map +1 -0
- package/dist/foundation/walk.js +265 -0
- package/dist/foundation/walk.js.map +1 -0
- package/dist/generator/engine.d.ts +100 -0
- package/dist/generator/engine.d.ts.map +1 -0
- package/dist/generator/engine.js +575 -0
- package/dist/generator/engine.js.map +1 -0
- package/dist/generator/replay.d.ts +42 -0
- package/dist/generator/replay.d.ts.map +1 -0
- package/dist/generator/replay.js +61 -0
- package/dist/generator/replay.js.map +1 -0
- package/dist/generator/trace.d.ts +49 -0
- package/dist/generator/trace.d.ts.map +1 -0
- package/dist/generator/trace.js +38 -0
- package/dist/generator/trace.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +22 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +25 -0
- package/dist/internal.js.map +1 -0
- package/dist/schema/composites.d.ts +104 -0
- package/dist/schema/composites.d.ts.map +1 -0
- package/dist/schema/composites.js +134 -0
- package/dist/schema/composites.js.map +1 -0
- package/dist/schema/conditional.d.ts +28 -0
- package/dist/schema/conditional.d.ts.map +1 -0
- package/dist/schema/conditional.js +52 -0
- package/dist/schema/conditional.js.map +1 -0
- package/dist/schema/decimal.d.ts +33 -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 +47 -0
- package/dist/schema/primitives.d.ts.map +1 -0
- package/dist/schema/primitives.js +78 -0
- package/dist/schema/primitives.js.map +1 -0
- package/dist/validator/parse.d.ts +22 -0
- package/dist/validator/parse.d.ts.map +1 -0
- package/dist/validator/parse.js +427 -0
- package/dist/validator/parse.js.map +1 -0
- package/package.json +3 -1
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replay / snapshot helpers — thin layer over `mock()` for tests.
|
|
3
|
+
*
|
|
4
|
+
* `replay(schema, opts)` returns a function bound to a fixed (seed, input)
|
|
5
|
+
* pair. Calling it twice always returns deep-equal values; the function is
|
|
6
|
+
* the canonical way to assert determinism in test suites.
|
|
7
|
+
*
|
|
8
|
+
* `expectStable(schema, opts)` runs the generator twice and throws if the
|
|
9
|
+
* outputs differ — surfaces non-determinism introduced by misuse of
|
|
10
|
+
* `derivedFrom` (e.g. reading `Date.now()`).
|
|
11
|
+
*/
|
|
12
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
13
|
+
import { mock } from './engine.js';
|
|
14
|
+
/** Build a deterministic, repeatedly-callable generator. */
|
|
15
|
+
export const replay = (schema, options = {}) => {
|
|
16
|
+
const frozen = deepFreeze({ ...options });
|
|
17
|
+
const fn = (() => mock(schema, frozen));
|
|
18
|
+
Object.defineProperty(fn, 'options', { value: frozen, enumerable: true });
|
|
19
|
+
return fn;
|
|
20
|
+
};
|
|
21
|
+
/** Recursively `Object.freeze` plain objects and arrays so callers cannot
|
|
22
|
+
* mutate bound options through nested references (e.g. `options.input`). */
|
|
23
|
+
const deepFreeze = (value) => {
|
|
24
|
+
if (value === null || typeof value !== 'object')
|
|
25
|
+
return value;
|
|
26
|
+
if (Object.isFrozen(value))
|
|
27
|
+
return value;
|
|
28
|
+
Object.freeze(value);
|
|
29
|
+
for (const k of Object.keys(value)) {
|
|
30
|
+
deepFreeze(value[k]);
|
|
31
|
+
}
|
|
32
|
+
return value;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Run the generator twice with identical inputs and assert deep equality.
|
|
36
|
+
* Returns the produced value on success; throws on divergence.
|
|
37
|
+
*
|
|
38
|
+
* **This is a diagnostic, not a determinism guarantee.** It runs the
|
|
39
|
+
* schema *twice* with the same seed and compares the outputs
|
|
40
|
+
* structurally — useful for catching obvious non-determinism (a
|
|
41
|
+
* `derivedFrom` reading `Date.now()`, a stray `Math.random()`,
|
|
42
|
+
* iteration over a `Set`), but two iterations cannot prove the entire
|
|
43
|
+
* RNG sequence is fixed. The strong contract is {@link replay}, which
|
|
44
|
+
* binds a (seed, input) pair and lets the caller pin the value at the
|
|
45
|
+
* snapshot site.
|
|
46
|
+
*
|
|
47
|
+
* Treat `expectStable` as the equivalent of a smoke test: cheap to
|
|
48
|
+
* keep in a regression suite, fast to fail loudly when a callback
|
|
49
|
+
* goes off-piste, but not a substitute for `replay`-backed snapshots
|
|
50
|
+
* for surfaces that must round-trip across releases.
|
|
51
|
+
*/
|
|
52
|
+
export const expectStable = (schema, options = {}) => {
|
|
53
|
+
const a = mock(schema, options);
|
|
54
|
+
const b = mock(schema, options);
|
|
55
|
+
if (!isDeepStrictEqual(a, b)) {
|
|
56
|
+
throw new Error('expectStable: generator produced different values for identical seed/input — ' +
|
|
57
|
+
'likely a non-deterministic derivedFrom callback (e.g. Date.now, Math.random, network).');
|
|
58
|
+
}
|
|
59
|
+
return a;
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=replay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay.js","sourceRoot":"","sources":["../../src/generator/replay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAE7C,OAAO,EAAE,IAAI,EAAoB,MAAM,aAAa,CAAA;AAWpD,4DAA4D;AAC5D,MAAM,CAAC,MAAM,MAAM,GAAG,CAAmB,MAAS,EAAE,UAAuB,EAAE,EAAa,EAAE;IAC1F,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,GAAG,OAAO,EAAE,CAAgB,CAAA;IACxD,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAyB,CAAA;IAC/D,MAAM,CAAC,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAA;IACzE,OAAO,EAAE,CAAA;AACX,CAAC,CAAA;AAED;6EAC6E;AAC7E,MAAM,UAAU,GAAG,CAAI,KAAQ,EAAK,EAAE;IACpC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC7D,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACxC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACpB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAgC,CAAC,EAAE,CAAC;QAC9D,UAAU,CAAE,KAAiC,CAAC,CAAC,CAAC,CAAC,CAAA;IACnD,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAmB,MAAS,EAAE,UAAuB,EAAE,EAAY,EAAE;IAC/F,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,+EAA+E;YAC7E,wFAAwF,CAC3F,CAAA;IACH,CAAC;IACD,OAAO,CAAC,CAAA;AACV,CAAC,CAAA"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trace collector — records which axis fired at each path during a
|
|
3
|
+
* single `mock()` call.
|
|
4
|
+
*
|
|
5
|
+
* The trace is a read-only audit of the generator's decisions: every
|
|
6
|
+
* produced value is annotated with the axis that won.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
*
|
|
10
|
+
* const trace = createTrace()
|
|
11
|
+
* const value = mock(schema, { seed: 's', trace })
|
|
12
|
+
* console.log(trace.entries) // → TraceEntry[]
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Which axis decided a value at a given path.
|
|
16
|
+
*
|
|
17
|
+
* - `default` : pure value (`undefined` slot in optional/default)
|
|
18
|
+
* - `optional-skip` : optional field rolled `undefined`
|
|
19
|
+
* - `nullable-null` : nullable field rolled `null`
|
|
20
|
+
* - `derived` : produced by `derivedFrom(...)`
|
|
21
|
+
* - `occasionally` : forced by an `occasionally(...)` override
|
|
22
|
+
* - `eventually` : forced by an `eventually(...)` override (modulo `index`)
|
|
23
|
+
* - `invariant-pass` : sampled then accepted by all `invariant(...)`
|
|
24
|
+
* - `invariant-fail` : retry exhausted before invariants held
|
|
25
|
+
* - `domain` : sampled from `in([...])` candidate set
|
|
26
|
+
* - `distribution` : sampled via `weighted|normal|typically`
|
|
27
|
+
* - `type` : fell through to type-default sampling
|
|
28
|
+
*/
|
|
29
|
+
export type TraceAxis = 'default' | 'optional-skip' | 'nullable-null' | 'derived' | 'occasionally' | 'eventually' | 'invariant-pass' | 'invariant-fail' | 'domain' | 'distribution' | 'type';
|
|
30
|
+
export type TraceEntry = {
|
|
31
|
+
readonly path: readonly (string | number)[];
|
|
32
|
+
readonly axis: TraceAxis;
|
|
33
|
+
/** Attempts taken before invariants accepted (only meaningful when invariants run). */
|
|
34
|
+
readonly attempts?: number;
|
|
35
|
+
/** Free-form annotation (e.g. distribution kind, picked literal). */
|
|
36
|
+
readonly note?: string;
|
|
37
|
+
};
|
|
38
|
+
export type TraceCollector = {
|
|
39
|
+
/** Append a single entry. Called by the engine — do not call from user code. */
|
|
40
|
+
readonly emit: (entry: TraceEntry) => void;
|
|
41
|
+
/** Read-only view of entries collected so far. */
|
|
42
|
+
readonly entries: readonly TraceEntry[];
|
|
43
|
+
/** All paths where a specific axis fired. */
|
|
44
|
+
readonly axisFiredAt: (axis: TraceAxis) => readonly (readonly (string | number)[])[];
|
|
45
|
+
/** Pretty multi-line dump (one entry per line, JSON-pointer-style paths). */
|
|
46
|
+
readonly format: () => string;
|
|
47
|
+
};
|
|
48
|
+
export declare const createTrace: () => TraceCollector;
|
|
49
|
+
//# sourceMappingURL=trace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../src/generator/trace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,eAAe,GACf,eAAe,GACf,SAAS,GACT,cAAc,GACd,YAAY,GACZ,gBAAgB,GAChB,gBAAgB,GAChB,QAAQ,GACR,cAAc,GACd,MAAM,CAAA;AAEV,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;IAC3C,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,uFAAuF;IACvF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,qEAAqE;IACrE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IAC1C,kDAAkD;IAClD,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,CAAA;IACvC,6CAA6C;IAC7C,QAAQ,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,EAAE,CAAA;IACpF,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,EAAE,MAAM,MAAM,CAAA;CAC9B,CAAA;AAED,eAAO,MAAM,WAAW,QAAO,cAuB9B,CAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trace collector — records which axis fired at each path during a
|
|
3
|
+
* single `mock()` call.
|
|
4
|
+
*
|
|
5
|
+
* The trace is a read-only audit of the generator's decisions: every
|
|
6
|
+
* produced value is annotated with the axis that won.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
*
|
|
10
|
+
* const trace = createTrace()
|
|
11
|
+
* const value = mock(schema, { seed: 's', trace })
|
|
12
|
+
* console.log(trace.entries) // → TraceEntry[]
|
|
13
|
+
*/
|
|
14
|
+
export const createTrace = () => {
|
|
15
|
+
const entries = [];
|
|
16
|
+
return {
|
|
17
|
+
emit(entry) {
|
|
18
|
+
entries.push(entry);
|
|
19
|
+
},
|
|
20
|
+
get entries() {
|
|
21
|
+
return entries;
|
|
22
|
+
},
|
|
23
|
+
axisFiredAt(axis) {
|
|
24
|
+
return entries.filter((e) => e.axis === axis).map((e) => e.path);
|
|
25
|
+
},
|
|
26
|
+
format() {
|
|
27
|
+
return entries
|
|
28
|
+
.map((e) => {
|
|
29
|
+
const ptr = '/' + e.path.map((p) => String(p)).join('/');
|
|
30
|
+
const attempts = e.attempts !== undefined ? ` attempts=${e.attempts}` : '';
|
|
31
|
+
const note = e.note !== undefined ? ` (${e.note})` : '';
|
|
32
|
+
return `${ptr.padEnd(40)} ${e.axis}${attempts}${note}`;
|
|
33
|
+
})
|
|
34
|
+
.join('\n');
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=trace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace.js","sourceRoot":"","sources":["../../src/generator/trace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAkDH,MAAM,CAAC,MAAM,WAAW,GAAG,GAAmB,EAAE;IAC9C,MAAM,OAAO,GAAiB,EAAE,CAAA;IAChC,OAAO;QACL,IAAI,CAAC,KAAK;YACR,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACrB,CAAC;QACD,IAAI,OAAO;YACT,OAAO,OAAO,CAAA;QAChB,CAAC;QACD,WAAW,CAAC,IAAI;YACd,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QAClE,CAAC;QACD,MAAM;YACJ,OAAO,OAAO;iBACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBACT,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBACxD,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;gBAC1E,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;gBACvD,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,QAAQ,GAAG,IAAI,EAAE,CAAA;YACxD,CAAC,CAAC;iBACD,IAAI,CAAC,IAAI,CAAC,CAAA;QACf,CAAC;KACF,CAAA;AACH,CAAC,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* databehave — Zero-dependency data schema DSL.
|
|
3
|
+
*
|
|
4
|
+
* Public surface:
|
|
5
|
+
* - schema DSL (primitives, composites, decimal, conditional)
|
|
6
|
+
* - data-schema axes (distribution, derived, invariants, domain,
|
|
7
|
+
* discriminated unions, dataset with identity, eventually, correlate)
|
|
8
|
+
* - generator (`mock`) + validator (`parse`/`safeParse`)
|
|
9
|
+
* - debug / determinism (`createTrace`, `replay`, `expectStable`)
|
|
10
|
+
* - cross-dataset FK (`relate`)
|
|
11
|
+
* - extensibility (`walkSchema`, `fromIR`, low-level PRNG, IR types) for
|
|
12
|
+
* third-party packages (CLI, OpenAPI ingestion, zod adapters, …)
|
|
13
|
+
*
|
|
14
|
+
* databehave intentionally ships NO HTTP/server/framework integration. Wire it
|
|
15
|
+
* into your transport of choice (Fastify/Express/msw/node:http) in ~80 LOC.
|
|
16
|
+
*/
|
|
17
|
+
export { str, num, int, bool, null_, StringSchema, NumberSchema, IntSchema, BooleanSchema, NullSchema, } from './schema/primitives.js';
|
|
18
|
+
export { decimal, DecimalSchema } from './schema/decimal.js';
|
|
19
|
+
export { obj, arr, tuple, union, literal, enum_, ObjectSchema, ArraySchema, TupleSchema, UnionSchema, LiteralSchema, EnumSchema, } from './schema/composites.js';
|
|
20
|
+
export { discriminated } from './schema/conditional.js';
|
|
21
|
+
export { mock, type MockOptions, type ModifierProbs, type StableByFn } from './generator/engine.js';
|
|
22
|
+
export type { Rng } from './foundation/prng.js';
|
|
23
|
+
export { parse, safeParse, type SafeParseResult } from './validator/parse.js';
|
|
24
|
+
export { createTrace, type TraceAxis, type TraceCollector, type TraceEntry, } from './generator/trace.js';
|
|
25
|
+
export { replay, expectStable, type Replay } from './generator/replay.js';
|
|
26
|
+
export { mockDataset, identityFor, type DatasetOptions } from './dataset/dataset.js';
|
|
27
|
+
export { relate, type RelateOptions } from './dataset/relate.js';
|
|
28
|
+
export { Schema, type Infer, type Modifiers, type SchemaNode } from './foundation/types.js';
|
|
29
|
+
export type { Axes, DerivedFn, Distribution, DomainConstraint, EventuallyOverride, GenContext, InvariantFn, NormalDistribution, OccasionalOverride, TypicalDistribution, WeightedDistribution, } from './foundation/axes.js';
|
|
30
|
+
export { DataBehaveError, ConformError, SchemaConflictError, type Issue, type IssueCode, } from './foundation/errors.js';
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EACL,GAAG,EACH,GAAG,EACH,GAAG,EACH,IAAI,EACJ,KAAK,EACL,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,aAAa,EACb,UAAU,GACX,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAC5D,OAAO,EACL,GAAG,EACH,GAAG,EACH,KAAK,EACL,KAAK,EACL,OAAO,EACP,KAAK,EACL,YAAY,EACZ,WAAW,EACX,WAAW,EACX,WAAW,EACX,aAAa,EACb,UAAU,GACX,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAGvD,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAA;AACnG,YAAY,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC7E,OAAO,EACL,WAAW,EACX,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,UAAU,GAChB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAGzE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACpF,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAGhE,OAAO,EAAE,MAAM,EAAE,KAAK,KAAK,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAC3F,YAAY,EACV,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,sBAAsB,CAAA;AAG7B,OAAO,EACL,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,KAAK,KAAK,EACV,KAAK,SAAS,GACf,MAAM,wBAAwB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* databehave — Zero-dependency data schema DSL.
|
|
3
|
+
*
|
|
4
|
+
* Public surface:
|
|
5
|
+
* - schema DSL (primitives, composites, decimal, conditional)
|
|
6
|
+
* - data-schema axes (distribution, derived, invariants, domain,
|
|
7
|
+
* discriminated unions, dataset with identity, eventually, correlate)
|
|
8
|
+
* - generator (`mock`) + validator (`parse`/`safeParse`)
|
|
9
|
+
* - debug / determinism (`createTrace`, `replay`, `expectStable`)
|
|
10
|
+
* - cross-dataset FK (`relate`)
|
|
11
|
+
* - extensibility (`walkSchema`, `fromIR`, low-level PRNG, IR types) for
|
|
12
|
+
* third-party packages (CLI, OpenAPI ingestion, zod adapters, …)
|
|
13
|
+
*
|
|
14
|
+
* databehave intentionally ships NO HTTP/server/framework integration. Wire it
|
|
15
|
+
* into your transport of choice (Fastify/Express/msw/node:http) in ~80 LOC.
|
|
16
|
+
*/
|
|
17
|
+
// ── schema DSL ────────────────────────────────────────────────────────────
|
|
18
|
+
export { str, num, int, bool, null_, StringSchema, NumberSchema, IntSchema, BooleanSchema, NullSchema, } from './schema/primitives.js';
|
|
19
|
+
export { decimal, DecimalSchema } from './schema/decimal.js';
|
|
20
|
+
export { obj, arr, tuple, union, literal, enum_, ObjectSchema, ArraySchema, TupleSchema, UnionSchema, LiteralSchema, EnumSchema, } from './schema/composites.js';
|
|
21
|
+
export { discriminated } from './schema/conditional.js';
|
|
22
|
+
// ── generator + validator ─────────────────────────────────────────────────
|
|
23
|
+
export { mock } from './generator/engine.js';
|
|
24
|
+
export { parse, safeParse } from './validator/parse.js';
|
|
25
|
+
export { createTrace, } from './generator/trace.js';
|
|
26
|
+
export { replay, expectStable } from './generator/replay.js';
|
|
27
|
+
// ── dataset ───────────────────────────────────────────────────────────────
|
|
28
|
+
export { mockDataset, identityFor } from './dataset/dataset.js';
|
|
29
|
+
export { relate } from './dataset/relate.js';
|
|
30
|
+
// ── foundation types & axes ───────────────────────────────────────────────
|
|
31
|
+
export { Schema } from './foundation/types.js';
|
|
32
|
+
// ── errors ────────────────────────────────────────────────────────────────
|
|
33
|
+
export { DataBehaveError, ConformError, SchemaConflictError, } from './foundation/errors.js';
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,6EAA6E;AAC7E,OAAO,EACL,GAAG,EACH,GAAG,EACH,GAAG,EACH,IAAI,EACJ,KAAK,EACL,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,aAAa,EACb,UAAU,GACX,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAC5D,OAAO,EACL,GAAG,EACH,GAAG,EACH,KAAK,EACL,KAAK,EACL,OAAO,EACP,KAAK,EACL,YAAY,EACZ,WAAW,EACX,WAAW,EACX,WAAW,EACX,aAAa,EACb,UAAU,GACX,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAEvD,6EAA6E;AAC7E,OAAO,EAAE,IAAI,EAAyD,MAAM,uBAAuB,CAAA;AAEnG,OAAO,EAAE,KAAK,EAAE,SAAS,EAAwB,MAAM,sBAAsB,CAAA;AAC7E,OAAO,EACL,WAAW,GAIZ,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,MAAM,EAAE,YAAY,EAAe,MAAM,uBAAuB,CAAA;AAEzE,6EAA6E;AAC7E,OAAO,EAAE,WAAW,EAAE,WAAW,EAAuB,MAAM,sBAAsB,CAAA;AACpF,OAAO,EAAE,MAAM,EAAsB,MAAM,qBAAqB,CAAA;AAEhE,6EAA6E;AAC7E,OAAO,EAAE,MAAM,EAA+C,MAAM,uBAAuB,CAAA;AAe3F,6EAA6E;AAC7E,OAAO,EACL,eAAe,EACf,YAAY,EACZ,mBAAmB,GAGpB,MAAM,wBAAwB,CAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @databehave/schema/internal — low-level extensibility surface.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the IR walker, the IR discriminants, the axis types, and
|
|
5
|
+
* seeded PRNG primitives that exist for third-party packages (CLI tools,
|
|
6
|
+
* OpenAPI ingestion, zod adapters, …) to build on. These are versioned
|
|
7
|
+
* more loosely than the main DSL:
|
|
8
|
+
*
|
|
9
|
+
* • SchemaNode / IR shape changes are MAJOR (see docs/stability.md).
|
|
10
|
+
* • PRNG output is deterministic across PATCH/MINOR for a given seed.
|
|
11
|
+
*
|
|
12
|
+
* **Do not import from `@databehave/schema/internal` in application code.**
|
|
13
|
+
* Prefer the high-level `mock()` / `parse()` / `safeParse()` from the package
|
|
14
|
+
* root. Importing internals couples you to the IR and bypasses fail-loud guards.
|
|
15
|
+
*/
|
|
16
|
+
export { walkSchema, fromIR, serializeSchema, deserializeSchema, IR_VERSION, type SchemaEnvelope, type SchemaVisitor, type WalkPath, } from './foundation/walk.js';
|
|
17
|
+
export { mulberry32, rngFromString, seedFromString, type Rng, } from './foundation/prng.js';
|
|
18
|
+
export { Schema } from './foundation/types.js';
|
|
19
|
+
export type { Infer } from './foundation/types.js';
|
|
20
|
+
export type { ArrayKind, BooleanKind, DecimalKind, DiscriminatedKind, EnumKind, LiteralKind, Modifiers, NullKind, NumberKind, ObjectKind, SchemaCore, SchemaNode, StringFormat, StringKind, TupleKind, UnionKind, } from './foundation/ir.js';
|
|
21
|
+
export type { Axes, DerivedFn, Distribution, DomainConstraint, EventuallyOverride, GenContext, InvariantFn, NormalDistribution, OccasionalOverride, TypicalDistribution, WeightedDistribution, } from './foundation/axes.js';
|
|
22
|
+
//# sourceMappingURL=internal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACL,UAAU,EACV,MAAM,EACN,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,QAAQ,GACd,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,UAAU,EACV,aAAa,EACb,cAAc,EACd,KAAK,GAAG,GACT,MAAM,sBAAsB,CAAA;AAS7B,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAC9C,YAAY,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAElD,YAAY,EAEV,SAAS,EACT,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,QAAQ,EACR,WAAW,EACX,SAAS,EACT,QAAQ,EACR,UAAU,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,YAAY,EACZ,UAAU,EACV,SAAS,EACT,SAAS,GACV,MAAM,oBAAoB,CAAA;AAE3B,YAAY,EAEV,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,sBAAsB,CAAA"}
|
package/dist/internal.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @databehave/schema/internal — low-level extensibility surface.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the IR walker, the IR discriminants, the axis types, and
|
|
5
|
+
* seeded PRNG primitives that exist for third-party packages (CLI tools,
|
|
6
|
+
* OpenAPI ingestion, zod adapters, …) to build on. These are versioned
|
|
7
|
+
* more loosely than the main DSL:
|
|
8
|
+
*
|
|
9
|
+
* • SchemaNode / IR shape changes are MAJOR (see docs/stability.md).
|
|
10
|
+
* • PRNG output is deterministic across PATCH/MINOR for a given seed.
|
|
11
|
+
*
|
|
12
|
+
* **Do not import from `@databehave/schema/internal` in application code.**
|
|
13
|
+
* Prefer the high-level `mock()` / `parse()` / `safeParse()` from the package
|
|
14
|
+
* root. Importing internals couples you to the IR and bypasses fail-loud guards.
|
|
15
|
+
*/
|
|
16
|
+
export { walkSchema, fromIR, serializeSchema, deserializeSchema, IR_VERSION, } from './foundation/walk.js';
|
|
17
|
+
export { mulberry32, rngFromString, seedFromString, } from './foundation/prng.js';
|
|
18
|
+
// ── extension-author types ─────────────────────────────────────────
|
|
19
|
+
//
|
|
20
|
+
// Surfaced so extension code (codegen, IR transforms, OpenAPI adapters)
|
|
21
|
+
// can name the IR discriminants and the `_applyAxes` argument shape
|
|
22
|
+
// without reaching into deep paths. Type-only re-exports — they emit
|
|
23
|
+
// no runtime JS.
|
|
24
|
+
export { Schema } from './foundation/types.js';
|
|
25
|
+
//# sourceMappingURL=internal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACL,UAAU,EACV,MAAM,EACN,eAAe,EACf,iBAAiB,EACjB,UAAU,GAIX,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,UAAU,EACV,aAAa,EACb,cAAc,GAEf,MAAM,sBAAsB,CAAA;AAE7B,sEAAsE;AACtE,EAAE;AACF,wEAAwE;AACxE,oEAAoE;AACpE,qEAAqE;AACrE,iBAAiB;AAEjB,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composite schema builders: obj, arr, tuple, union, literal, enum_.
|
|
3
|
+
*
|
|
4
|
+
* These produce TS types derived from their inputs via mapped / conditional
|
|
5
|
+
* types so that {@link Infer} yields the exact composite shape.
|
|
6
|
+
*/
|
|
7
|
+
import type { ArrayKind, EnumKind, LiteralKind, ObjectKind, TupleKind, UnionKind } from '../foundation/ir.js';
|
|
8
|
+
import { Discrete, Schema, type Infer } from '../foundation/types.js';
|
|
9
|
+
type Fields = Record<string, Schema>;
|
|
10
|
+
/** Keys whose schema carries `optional: true` become optional in the output. */
|
|
11
|
+
type OptionalKeys<F extends Fields> = {
|
|
12
|
+
[K in keyof F]: F[K]['_node']['mods'] extends {
|
|
13
|
+
optional: true;
|
|
14
|
+
} ? K : never;
|
|
15
|
+
}[keyof F];
|
|
16
|
+
type RequiredKeys<F extends Fields> = Exclude<keyof F, OptionalKeys<F>>;
|
|
17
|
+
export type InferObject<F extends Fields> = {
|
|
18
|
+
[K in RequiredKeys<F>]: Infer<F[K]>;
|
|
19
|
+
} & {
|
|
20
|
+
[K in OptionalKeys<F>]?: Infer<F[K]>;
|
|
21
|
+
};
|
|
22
|
+
export declare class ObjectSchema<F extends Fields = Fields> extends Schema<{
|
|
23
|
+
[K in keyof InferObject<F>]: InferObject<F>[K];
|
|
24
|
+
}> {
|
|
25
|
+
readonly _node: ObjectKind & {
|
|
26
|
+
mods?: import('../foundation/ir.js').Modifiers;
|
|
27
|
+
};
|
|
28
|
+
readonly _fields: F;
|
|
29
|
+
constructor(fields: F);
|
|
30
|
+
/**
|
|
31
|
+
* Multi-field invariant — a predicate over the whole assembled object.
|
|
32
|
+
*
|
|
33
|
+
* Equivalent to `.invariant(...)` but typed against the object's inferred
|
|
34
|
+
* shape, so cross-field rules (e.g. `start <= end`) get full type-checking.
|
|
35
|
+
* The engine rejection-samples the object up to MAX_ATTEMPTS until the
|
|
36
|
+
* predicate holds.
|
|
37
|
+
*/
|
|
38
|
+
correlate(fn: (row: InferObject<F>) => boolean): this;
|
|
39
|
+
}
|
|
40
|
+
export declare const obj: <F extends Fields>(fields: F) => ObjectSchema<F>;
|
|
41
|
+
export declare class ArraySchema<S extends Schema> extends Schema<Infer<S>[]> {
|
|
42
|
+
readonly _node: ArrayKind & {
|
|
43
|
+
mods?: import('../foundation/ir.js').Modifiers;
|
|
44
|
+
};
|
|
45
|
+
readonly _item: S;
|
|
46
|
+
constructor(item: S, opts?: {
|
|
47
|
+
length?: number;
|
|
48
|
+
minLength?: number;
|
|
49
|
+
maxLength?: number;
|
|
50
|
+
});
|
|
51
|
+
/**
|
|
52
|
+
* Rebuild a fresh `ArraySchema` while preserving every previously-set
|
|
53
|
+
* bound *and* every modifier (axes, occasionally, derivedFrom,
|
|
54
|
+
* describe, weighted, …). Without this, `.min(2).max(10)` would
|
|
55
|
+
* silently drop the `min` and `arr(int()).typically(1,5).min(2)`
|
|
56
|
+
* would lose the distribution axis because the constructor builds
|
|
57
|
+
* the IR node from scratch. Mods live in `_node.mods`, which is
|
|
58
|
+
* outside the bounds-only constructor surface, so they have to be
|
|
59
|
+
* grafted back on after construction via `withMods`.
|
|
60
|
+
*/
|
|
61
|
+
private rebuild;
|
|
62
|
+
length(n: number): ArraySchema<S>;
|
|
63
|
+
min(n: number): ArraySchema<S>;
|
|
64
|
+
max(n: number): ArraySchema<S>;
|
|
65
|
+
}
|
|
66
|
+
export declare const arr: <S extends Schema>(item: S) => ArraySchema<S>;
|
|
67
|
+
type InferTuple<T extends readonly Schema[]> = {
|
|
68
|
+
[K in keyof T]: T[K] extends Schema ? Infer<T[K]> : never;
|
|
69
|
+
};
|
|
70
|
+
export declare class TupleSchema<T extends readonly Schema[]> extends Schema<InferTuple<T>> {
|
|
71
|
+
readonly _node: TupleKind & {
|
|
72
|
+
mods?: import('../foundation/ir.js').Modifiers;
|
|
73
|
+
};
|
|
74
|
+
readonly _items: T;
|
|
75
|
+
constructor(items: T);
|
|
76
|
+
}
|
|
77
|
+
export declare const tuple: <T extends readonly Schema[]>(...items: T) => TupleSchema<T>;
|
|
78
|
+
type InferUnion<T extends readonly Schema[]> = T[number] extends Schema ? Infer<T[number]> : never;
|
|
79
|
+
export declare class UnionSchema<T extends readonly Schema[]> extends Schema<InferUnion<T>> {
|
|
80
|
+
readonly _node: UnionKind & {
|
|
81
|
+
mods?: import('../foundation/ir.js').Modifiers;
|
|
82
|
+
};
|
|
83
|
+
readonly _options: T;
|
|
84
|
+
constructor(options: T);
|
|
85
|
+
}
|
|
86
|
+
export declare const union: <T extends readonly Schema[]>(...options: T) => UnionSchema<T>;
|
|
87
|
+
export declare class LiteralSchema<V extends string | number | boolean | null> extends Schema<V> {
|
|
88
|
+
readonly _node: LiteralKind & {
|
|
89
|
+
mods?: import('../foundation/ir.js').Modifiers;
|
|
90
|
+
};
|
|
91
|
+
readonly [Discrete]: true;
|
|
92
|
+
}
|
|
93
|
+
export declare const literal: <V extends string | number | boolean | null>(value: V) => LiteralSchema<V>;
|
|
94
|
+
export declare class EnumSchema<V extends string | number> extends Schema<V> {
|
|
95
|
+
readonly _node: EnumKind & {
|
|
96
|
+
mods?: import('../foundation/ir.js').Modifiers;
|
|
97
|
+
};
|
|
98
|
+
readonly [Discrete]: true;
|
|
99
|
+
readonly _values: readonly V[];
|
|
100
|
+
constructor(values: readonly V[]);
|
|
101
|
+
}
|
|
102
|
+
export declare const enum_: <V extends string | number>(values: readonly V[]) => EnumSchema<V>;
|
|
103
|
+
export {};
|
|
104
|
+
//# sourceMappingURL=composites.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composites.d.ts","sourceRoot":"","sources":["../../src/schema/composites.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composite schema builders: obj, arr, tuple, union, literal, enum_.
|
|
3
|
+
*
|
|
4
|
+
* These produce TS types derived from their inputs via mapped / conditional
|
|
5
|
+
* types so that {@link Infer} yields the exact composite shape.
|
|
6
|
+
*/
|
|
7
|
+
import { withMods } from '../foundation/ir.js';
|
|
8
|
+
import { Discrete, Schema } from '../foundation/types.js';
|
|
9
|
+
/** Field names that would clobber Object.prototype or pollute the prototype chain. */
|
|
10
|
+
const FORBIDDEN_FIELD_NAMES = new Set(['__proto__', 'prototype', 'constructor']);
|
|
11
|
+
const assertSafeFieldNames = (fields) => {
|
|
12
|
+
for (const k of Object.keys(fields)) {
|
|
13
|
+
if (FORBIDDEN_FIELD_NAMES.has(k)) {
|
|
14
|
+
throw new RangeError(`obj(): field name ${JSON.stringify(k)} is forbidden ` +
|
|
15
|
+
`(would shadow Object.prototype; rename the field).`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
export class ObjectSchema extends Schema {
|
|
20
|
+
_fields;
|
|
21
|
+
constructor(fields) {
|
|
22
|
+
assertSafeFieldNames(fields);
|
|
23
|
+
const irFields = {};
|
|
24
|
+
for (const k of Object.keys(fields)) {
|
|
25
|
+
irFields[k] = fields[k]._node;
|
|
26
|
+
}
|
|
27
|
+
super({ kind: 'object', fields: irFields });
|
|
28
|
+
this._fields = fields;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Multi-field invariant — a predicate over the whole assembled object.
|
|
32
|
+
*
|
|
33
|
+
* Equivalent to `.invariant(...)` but typed against the object's inferred
|
|
34
|
+
* shape, so cross-field rules (e.g. `start <= end`) get full type-checking.
|
|
35
|
+
* The engine rejection-samples the object up to MAX_ATTEMPTS until the
|
|
36
|
+
* predicate holds.
|
|
37
|
+
*/
|
|
38
|
+
correlate(fn) {
|
|
39
|
+
return this.invariant((v) => fn(v));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export const obj = (fields) => new ObjectSchema(fields);
|
|
43
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
44
|
+
// array
|
|
45
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
46
|
+
export class ArraySchema extends Schema {
|
|
47
|
+
_item;
|
|
48
|
+
constructor(item, opts = {}) {
|
|
49
|
+
const base = {
|
|
50
|
+
kind: 'array',
|
|
51
|
+
item: item._node,
|
|
52
|
+
...(opts.length !== undefined ? { length: opts.length } : {}),
|
|
53
|
+
...(opts.minLength !== undefined ? { minLength: opts.minLength } : {}),
|
|
54
|
+
...(opts.maxLength !== undefined ? { maxLength: opts.maxLength } : {}),
|
|
55
|
+
};
|
|
56
|
+
super(base);
|
|
57
|
+
this._item = item;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Rebuild a fresh `ArraySchema` while preserving every previously-set
|
|
61
|
+
* bound *and* every modifier (axes, occasionally, derivedFrom,
|
|
62
|
+
* describe, weighted, …). Without this, `.min(2).max(10)` would
|
|
63
|
+
* silently drop the `min` and `arr(int()).typically(1,5).min(2)`
|
|
64
|
+
* would lose the distribution axis because the constructor builds
|
|
65
|
+
* the IR node from scratch. Mods live in `_node.mods`, which is
|
|
66
|
+
* outside the bounds-only constructor surface, so they have to be
|
|
67
|
+
* grafted back on after construction via `withMods`.
|
|
68
|
+
*/
|
|
69
|
+
rebuild(patch) {
|
|
70
|
+
const node = this._node;
|
|
71
|
+
const next = new ArraySchema(this._item, {
|
|
72
|
+
...(node.length !== undefined ? { length: node.length } : {}),
|
|
73
|
+
...(node.minLength !== undefined ? { minLength: node.minLength } : {}),
|
|
74
|
+
...(node.maxLength !== undefined ? { maxLength: node.maxLength } : {}),
|
|
75
|
+
...patch,
|
|
76
|
+
});
|
|
77
|
+
if (node.mods) {
|
|
78
|
+
// `_node` is declared `readonly` for the public API but we own
|
|
79
|
+
// both ends of the assignment here — the just-built instance is
|
|
80
|
+
// not observable to anyone else yet, so re-seating its IR node
|
|
81
|
+
// is safe and avoids an extra clone.
|
|
82
|
+
;
|
|
83
|
+
next._node = withMods(next._node, node.mods);
|
|
84
|
+
}
|
|
85
|
+
return next;
|
|
86
|
+
}
|
|
87
|
+
length(n) {
|
|
88
|
+
return this.rebuild({ length: n });
|
|
89
|
+
}
|
|
90
|
+
min(n) {
|
|
91
|
+
return this.rebuild({ minLength: n });
|
|
92
|
+
}
|
|
93
|
+
max(n) {
|
|
94
|
+
return this.rebuild({ maxLength: n });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export const arr = (item) => new ArraySchema(item);
|
|
98
|
+
export class TupleSchema extends Schema {
|
|
99
|
+
_items;
|
|
100
|
+
constructor(items) {
|
|
101
|
+
super({ kind: 'tuple', items: items.map((s) => s._node) });
|
|
102
|
+
this._items = items;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export const tuple = (...items) => new TupleSchema(items);
|
|
106
|
+
export class UnionSchema extends Schema {
|
|
107
|
+
_options;
|
|
108
|
+
constructor(options) {
|
|
109
|
+
if (options.length === 0) {
|
|
110
|
+
throw new RangeError('union: requires at least one option');
|
|
111
|
+
}
|
|
112
|
+
super({ kind: 'union', options: options.map((s) => s._node) });
|
|
113
|
+
this._options = options;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
export const union = (...options) => new UnionSchema(options);
|
|
117
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
118
|
+
// literal / enum
|
|
119
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
120
|
+
export class LiteralSchema extends Schema {
|
|
121
|
+
}
|
|
122
|
+
export const literal = (value) => new LiteralSchema({ kind: 'literal', value });
|
|
123
|
+
export class EnumSchema extends Schema {
|
|
124
|
+
_values;
|
|
125
|
+
constructor(values) {
|
|
126
|
+
if (values.length === 0) {
|
|
127
|
+
throw new RangeError('enum: requires at least one value');
|
|
128
|
+
}
|
|
129
|
+
super({ kind: 'enum', values });
|
|
130
|
+
this._values = values;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export const enum_ = (values) => new EnumSchema(values);
|
|
134
|
+
//# sourceMappingURL=composites.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composites.js","sourceRoot":"","sources":["../../src/schema/composites.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discriminated union.
|
|
3
|
+
*
|
|
4
|
+
* `discriminated(key, map)` builds a schema whose branches are selected by
|
|
5
|
+
* the value of the named discriminator field, both during generation and
|
|
6
|
+
* during validation.
|
|
7
|
+
*
|
|
8
|
+
* Each entry in `map` must be an object-kind schema whose `key` field is a
|
|
9
|
+
* `literal(...)` matching the map key. This is enforced at build time so
|
|
10
|
+
* the discriminator is genuinely useful: generation picks one branch and
|
|
11
|
+
* sets the key; validation reads the key and dispatches to the matching
|
|
12
|
+
* branch (O(1), with errors keyed on the discriminator).
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* const Variant = discriminated('kind', {
|
|
16
|
+
* alpha: obj({ kind: literal('alpha'), score: decimal(10, 4) }),
|
|
17
|
+
* beta: obj({ kind: literal('beta'), weight: decimal(10, 4) }),
|
|
18
|
+
* })
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
import { Schema, type Infer } from '../foundation/types.js';
|
|
22
|
+
/**
|
|
23
|
+
* Build a discriminated union keyed on `key`. Each value in `map` must be a
|
|
24
|
+
* schema (typically `obj({...})`) whose `key` field is a `literal(...)`
|
|
25
|
+
* matching the map key.
|
|
26
|
+
*/
|
|
27
|
+
export declare const discriminated: <K extends string, M extends Readonly<Record<string, Schema<unknown>>>>(key: K, map: M) => Schema<{ [P in keyof M]: Infer<M[P]>; }[keyof M]>;
|
|
28
|
+
//# sourceMappingURL=conditional.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conditional.d.ts","sourceRoot":"","sources":["../../src/schema/conditional.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,MAAM,EAAE,KAAK,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAK3D;;;;GAIG;AACH,eAAO,MAAM,aAAa,GACxB,CAAC,SAAS,MAAM,EAGhB,CAAC,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAEnD,KAAK,CAAC,EACN,KAAK,CAAC,KACL,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAE,CAAC,MAAM,CAAC,CAAC,CA+BjD,CAAA"}
|