@databehave/schema 0.1.3 → 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.
Files changed (77) hide show
  1. package/dist/dataset/dataset.d.ts +47 -0
  2. package/dist/dataset/dataset.d.ts.map +1 -0
  3. package/dist/dataset/dataset.js +96 -0
  4. package/dist/dataset/dataset.js.map +1 -0
  5. package/dist/dataset/relate.d.ts +32 -0
  6. package/dist/dataset/relate.d.ts.map +1 -0
  7. package/dist/dataset/relate.js +46 -0
  8. package/dist/dataset/relate.js.map +1 -0
  9. package/dist/foundation/axes.d.ts +101 -0
  10. package/dist/foundation/axes.d.ts.map +1 -0
  11. package/dist/foundation/axes.js +42 -0
  12. package/dist/foundation/axes.js.map +1 -0
  13. package/dist/foundation/errors.d.ts +99 -0
  14. package/dist/foundation/errors.d.ts.map +1 -0
  15. package/dist/foundation/errors.js +91 -0
  16. package/dist/foundation/errors.js.map +1 -0
  17. package/dist/foundation/hash.d.ts +12 -0
  18. package/dist/foundation/hash.d.ts.map +1 -0
  19. package/dist/foundation/hash.js +21 -0
  20. package/dist/foundation/hash.js.map +1 -0
  21. package/dist/foundation/ir.d.ts +91 -0
  22. package/dist/foundation/ir.d.ts.map +1 -0
  23. package/dist/foundation/ir.js +16 -0
  24. package/dist/foundation/ir.js.map +1 -0
  25. package/dist/foundation/prng.d.ts +27 -0
  26. package/dist/foundation/prng.d.ts.map +1 -0
  27. package/dist/foundation/prng.js +56 -0
  28. package/dist/foundation/prng.js.map +1 -0
  29. package/dist/foundation/types.d.ts +116 -0
  30. package/dist/foundation/types.d.ts.map +1 -0
  31. package/dist/foundation/types.js +188 -0
  32. package/dist/foundation/types.js.map +1 -0
  33. package/dist/foundation/walk.d.ts +72 -0
  34. package/dist/foundation/walk.d.ts.map +1 -0
  35. package/dist/foundation/walk.js +265 -0
  36. package/dist/foundation/walk.js.map +1 -0
  37. package/dist/generator/engine.d.ts +100 -0
  38. package/dist/generator/engine.d.ts.map +1 -0
  39. package/dist/generator/engine.js +575 -0
  40. package/dist/generator/engine.js.map +1 -0
  41. package/dist/generator/replay.d.ts +42 -0
  42. package/dist/generator/replay.d.ts.map +1 -0
  43. package/dist/generator/replay.js +61 -0
  44. package/dist/generator/replay.js.map +1 -0
  45. package/dist/generator/trace.d.ts +49 -0
  46. package/dist/generator/trace.d.ts.map +1 -0
  47. package/dist/generator/trace.js +38 -0
  48. package/dist/generator/trace.js.map +1 -0
  49. package/dist/index.d.ts +31 -0
  50. package/dist/index.d.ts.map +1 -0
  51. package/dist/index.js +34 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/internal.d.ts +22 -0
  54. package/dist/internal.d.ts.map +1 -0
  55. package/dist/internal.js +25 -0
  56. package/dist/internal.js.map +1 -0
  57. package/dist/schema/composites.d.ts +104 -0
  58. package/dist/schema/composites.d.ts.map +1 -0
  59. package/dist/schema/composites.js +134 -0
  60. package/dist/schema/composites.js.map +1 -0
  61. package/dist/schema/conditional.d.ts +28 -0
  62. package/dist/schema/conditional.d.ts.map +1 -0
  63. package/dist/schema/conditional.js +52 -0
  64. package/dist/schema/conditional.js.map +1 -0
  65. package/dist/schema/decimal.d.ts +33 -0
  66. package/dist/schema/decimal.d.ts.map +1 -0
  67. package/dist/schema/decimal.js +39 -0
  68. package/dist/schema/decimal.js.map +1 -0
  69. package/dist/schema/primitives.d.ts +47 -0
  70. package/dist/schema/primitives.d.ts.map +1 -0
  71. package/dist/schema/primitives.js +78 -0
  72. package/dist/schema/primitives.js.map +1 -0
  73. package/dist/validator/parse.d.ts +22 -0
  74. package/dist/validator/parse.d.ts.map +1 -0
  75. package/dist/validator/parse.js +427 -0
  76. package/dist/validator/parse.js.map +1 -0
  77. package/package.json +3 -1
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Internal Representation (IR) of a databehave schema.
3
+ *
4
+ * Every schema builder compiles to one of these serializable nodes.
5
+ * The generator and validator operate on IR — never on builder classes —
6
+ * so IR can be inspected, logged, transformed, or transported.
7
+ */
8
+ export type StringFormat = 'plain' | 'uuid' | 'email' | 'url' | 'ipv4' | 'ipv6' | 'date' | 'datetime' | 'time';
9
+ export type NumberKind = {
10
+ readonly kind: 'number';
11
+ readonly int: boolean;
12
+ readonly bits?: 8 | 16 | 32 | 64;
13
+ readonly unsigned?: boolean;
14
+ readonly min?: number;
15
+ readonly max?: number;
16
+ };
17
+ export type StringKind = {
18
+ readonly kind: 'string';
19
+ readonly format: StringFormat;
20
+ readonly min?: number;
21
+ readonly max?: number;
22
+ readonly pattern?: string;
23
+ };
24
+ export type DecimalKind = {
25
+ readonly kind: 'decimal';
26
+ readonly precision: number;
27
+ readonly scale: number;
28
+ readonly min?: string;
29
+ readonly max?: string;
30
+ };
31
+ export type BooleanKind = {
32
+ readonly kind: 'boolean';
33
+ };
34
+ export type NullKind = {
35
+ readonly kind: 'null';
36
+ };
37
+ export type LiteralKind = {
38
+ readonly kind: 'literal';
39
+ readonly value: string | number | boolean | null;
40
+ };
41
+ export type EnumKind = {
42
+ readonly kind: 'enum';
43
+ readonly values: readonly (string | number)[];
44
+ };
45
+ export type ArrayKind = {
46
+ readonly kind: 'array';
47
+ readonly item: SchemaNode;
48
+ readonly length?: number;
49
+ readonly minLength?: number;
50
+ readonly maxLength?: number;
51
+ };
52
+ export type ObjectKind = {
53
+ readonly kind: 'object';
54
+ readonly fields: Readonly<Record<string, SchemaNode>>;
55
+ };
56
+ export type TupleKind = {
57
+ readonly kind: 'tuple';
58
+ readonly items: readonly SchemaNode[];
59
+ };
60
+ export type UnionKind = {
61
+ readonly kind: 'union';
62
+ readonly options: readonly SchemaNode[];
63
+ };
64
+ /**
65
+ * A discriminated union — selects exactly one branch by the value of `key`.
66
+ *
67
+ * Each entry in `branches` must be an object-kind schema whose `key` field is
68
+ * a `literal(...)` matching the map key. Generator and validator both use
69
+ * the discriminator for O(1) branch selection.
70
+ */
71
+ export type DiscriminatedKind = {
72
+ readonly kind: 'discriminated';
73
+ readonly key: string;
74
+ readonly branches: Readonly<Record<string, SchemaNode>>;
75
+ };
76
+ import type { Axes } from './axes.js';
77
+ export type Modifiers = {
78
+ readonly nullable?: boolean;
79
+ readonly optional?: boolean;
80
+ readonly hasDefault?: boolean;
81
+ readonly defaultValue?: unknown;
82
+ readonly description?: string;
83
+ readonly axes?: Axes;
84
+ };
85
+ export type SchemaCore = NumberKind | StringKind | DecimalKind | BooleanKind | NullKind | LiteralKind | EnumKind | ArrayKind | ObjectKind | TupleKind | UnionKind | DiscriminatedKind;
86
+ export type SchemaNode = SchemaCore & {
87
+ readonly mods?: Modifiers;
88
+ };
89
+ /** Helper: produce a fresh node with merged modifiers. `axes` are deep-merged. */
90
+ export declare const withMods: (node: SchemaNode, patch: Partial<Modifiers>) => SchemaNode;
91
+ //# sourceMappingURL=ir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ir.d.ts","sourceRoot":"","sources":["../../src/foundation/ir.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Internal Representation (IR) of a databehave schema.
3
+ *
4
+ * Every schema builder compiles to one of these serializable nodes.
5
+ * The generator and validator operate on IR — never on builder classes —
6
+ * so IR can be inspected, logged, transformed, or transported.
7
+ */
8
+ import { mergeAxes } from './axes.js';
9
+ /** Helper: produce a fresh node with merged modifiers. `axes` are deep-merged. */
10
+ export const withMods = (node, patch) => {
11
+ const prev = node.mods ?? {};
12
+ const mergedAxes = patch.axes !== undefined ? mergeAxes(prev.axes, patch.axes) : prev.axes;
13
+ const next = mergedAxes !== undefined ? { ...prev, ...patch, axes: mergedAxes } : { ...prev, ...patch };
14
+ return { ...node, mods: next };
15
+ };
16
+ //# sourceMappingURL=ir.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ir.js","sourceRoot":"","sources":["../../src/foundation/ir.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAwFH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AA6BrC,kFAAkF;AAClF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAgB,EAAE,KAAyB,EAAc,EAAE;IAClF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAA;IAC5B,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAA;IAC1F,MAAM,IAAI,GAAc,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,CAAA;IAClH,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;AAChC,CAAC,CAAA"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * mulberry32 — tiny, fast, deterministic 32-bit PRNG.
3
+ *
4
+ * Zero-dependency. Identical seed → identical sequence on every machine.
5
+ * Period ≈ 2^32, ample for mock generation.
6
+ *
7
+ * Reference: https://gist.github.com/tommyettinger/46a3a48c0d7fe27ea3aaa5fa8f1ba0e8
8
+ */
9
+ export type Rng = {
10
+ /** Next uniformly-distributed float in `[0, 1)`. */
11
+ next(): number;
12
+ /** Next integer in `[min, max]` (inclusive). */
13
+ int(min: number, max: number): number;
14
+ /** Pick one element of `items` uniformly. */
15
+ pick<T>(items: readonly T[]): T;
16
+ };
17
+ /**
18
+ * Create a deterministic PRNG seeded by a 32-bit unsigned integer.
19
+ *
20
+ * For string seeds, use {@link rngFromString}.
21
+ */
22
+ export declare const mulberry32: (seed: number) => Rng;
23
+ /** Derive a 32-bit unsigned seed from an arbitrary string (FNV-1a 32-bit). */
24
+ export declare const seedFromString: (s: string) => number;
25
+ /** Convenience: build an Rng from a string seed. */
26
+ export declare const rngFromString: (s: string) => Rng;
27
+ //# sourceMappingURL=prng.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prng.d.ts","sourceRoot":"","sources":["../../src/foundation/prng.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,GAAG,GAAG;IAChB,oDAAoD;IACpD,IAAI,IAAI,MAAM,CAAA;IACd,gDAAgD;IAChD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;IACrC,6CAA6C;IAC7C,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,CAAA;CAChC,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,KAAG,GA8BzC,CAAA;AAED,8EAA8E;AAC9E,eAAO,MAAM,cAAc,GAAI,GAAG,MAAM,KAAG,MAO1C,CAAA;AAED,oDAAoD;AACpD,eAAO,MAAM,aAAa,GAAI,GAAG,MAAM,KAAG,GAAoC,CAAA"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * mulberry32 — tiny, fast, deterministic 32-bit PRNG.
3
+ *
4
+ * Zero-dependency. Identical seed → identical sequence on every machine.
5
+ * Period ≈ 2^32, ample for mock generation.
6
+ *
7
+ * Reference: https://gist.github.com/tommyettinger/46a3a48c0d7fe27ea3aaa5fa8f1ba0e8
8
+ */
9
+ /**
10
+ * Create a deterministic PRNG seeded by a 32-bit unsigned integer.
11
+ *
12
+ * For string seeds, use {@link rngFromString}.
13
+ */
14
+ export const mulberry32 = (seed) => {
15
+ // Force u32.
16
+ let state = seed >>> 0;
17
+ const next = () => {
18
+ state = (state + 0x6d2b79f5) >>> 0;
19
+ let t = state;
20
+ t = Math.imul(t ^ (t >>> 15), t | 1);
21
+ t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
22
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
23
+ };
24
+ return {
25
+ next,
26
+ int(min, max) {
27
+ if (!Number.isFinite(min) || !Number.isFinite(max)) {
28
+ throw new RangeError(`rng.int requires finite bounds, got [${min}, ${max}]`);
29
+ }
30
+ if (min > max)
31
+ throw new RangeError(`rng.int: min (${min}) > max (${max})`);
32
+ const lo = Math.ceil(min);
33
+ const hi = Math.floor(max);
34
+ return lo + Math.floor(next() * (hi - lo + 1));
35
+ },
36
+ pick(items) {
37
+ if (items.length === 0)
38
+ throw new RangeError('rng.pick: empty array');
39
+ const idx = Math.floor(next() * items.length);
40
+ // Safe: idx ∈ [0, items.length-1]
41
+ return items[idx];
42
+ },
43
+ };
44
+ };
45
+ /** Derive a 32-bit unsigned seed from an arbitrary string (FNV-1a 32-bit). */
46
+ export const seedFromString = (s) => {
47
+ let h = 0x811c9dc5;
48
+ for (let i = 0; i < s.length; i += 1) {
49
+ h ^= s.charCodeAt(i);
50
+ h = Math.imul(h, 0x01000193);
51
+ }
52
+ return h >>> 0;
53
+ };
54
+ /** Convenience: build an Rng from a string seed. */
55
+ export const rngFromString = (s) => mulberry32(seedFromString(s));
56
+ //# sourceMappingURL=prng.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prng.js","sourceRoot":"","sources":["../../src/foundation/prng.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAO,EAAE;IAC9C,aAAa;IACb,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC,CAAA;IAEtB,MAAM,IAAI,GAAG,GAAW,EAAE;QACxB,KAAK,GAAG,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;QAClC,IAAI,CAAC,GAAG,KAAK,CAAA;QACb,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;QACpC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAA;QACzC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,UAAU,CAAA;IAC9C,CAAC,CAAA;IAED,OAAO;QACL,IAAI;QACJ,GAAG,CAAC,GAAG,EAAE,GAAG;YACV,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnD,MAAM,IAAI,UAAU,CAAC,wCAAwC,GAAG,KAAK,GAAG,GAAG,CAAC,CAAA;YAC9E,CAAC;YACD,IAAI,GAAG,GAAG,GAAG;gBAAE,MAAM,IAAI,UAAU,CAAC,iBAAiB,GAAG,YAAY,GAAG,GAAG,CAAC,CAAA;YAC3E,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACzB,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAC1B,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;QAChD,CAAC;QACD,IAAI,CAAI,KAAmB;YACzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAM,IAAI,UAAU,CAAC,uBAAuB,CAAC,CAAA;YACrE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAA;YAC7C,kCAAkC;YAClC,OAAO,KAAK,CAAC,GAAG,CAAM,CAAA;QACxB,CAAC;KACF,CAAA;AACH,CAAC,CAAA;AAED,8EAA8E;AAC9E,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAS,EAAU,EAAE;IAClD,IAAI,CAAC,GAAG,UAAU,CAAA;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QACpB,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;IAC9B,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,CAAA;AAChB,CAAC,CAAA;AAED,oDAAoD;AACpD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAS,EAAO,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAA"}
@@ -0,0 +1,116 @@
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 type { Axes, DerivedFn, Distribution, DomainConstraint, InvariantFn } from './axes.js';
12
+ import type { Modifiers, SchemaNode } from './ir.js';
13
+ /**
14
+ * Module-private capability marker symbol keys.
15
+ *
16
+ * Schemas opt into a capability by `declare`ing the corresponding bracketed
17
+ * property as the literal `true`. Methods like `.weighted` / `.normal` /
18
+ * `.typically` then gate themselves with a `this:` constraint that requires
19
+ * the marker. Symbols (rather than string keys like `_capDiscrete`) keep the
20
+ * markers out of consumer IntelliSense and out of any `Object.keys` loop.
21
+ *
22
+ * Three caps are required to mirror the runtime allow-list cleanly:
23
+ *
24
+ * - `Discrete` — values are enumerable; `.weighted` is meaningful.
25
+ * Carried by `str / int / bool / literal / enum`.
26
+ * - `Numeric` — values are bounded numerics; `.typically(from, to)` is
27
+ * meaningful (the generator clamps and, for integers,
28
+ * rounds). Carried by `num / int / decimal`.
29
+ * - `Continuous` — values are real-valued; `.normal(mean, σ)` is
30
+ * meaningful (Gaussian on integers would silently lose
31
+ * σ to rounding, so int is excluded). Carried by
32
+ * `num / decimal`.
33
+ *
34
+ * The symbols are real runtime values so subclass files can `import` them
35
+ * to redeclare the marker. They are NOT re-exported from the package root
36
+ * or from `@databehave/schema/internal`; the package's `exports` field
37
+ * limits deep-path imports to those two entries.
38
+ */
39
+ export declare const Discrete: unique symbol;
40
+ export declare const Numeric: unique symbol;
41
+ export declare const Continuous: unique symbol;
42
+ /** Base builder. Subclasses (StringSchema, NumberSchema, …) extend this. */
43
+ export declare class Schema<T = unknown> {
44
+ readonly _type: T;
45
+ readonly _node: SchemaNode;
46
+ readonly [Discrete]: boolean;
47
+ readonly [Numeric]: boolean;
48
+ readonly [Continuous]: boolean;
49
+ constructor(node: SchemaNode);
50
+ nullable(): Schema<T | null>;
51
+ optional(): Schema<T | undefined>;
52
+ default(value: T): Schema<T>;
53
+ describe(text: string): this;
54
+ /** Weighted distribution over discrete values. Weights are relative. */
55
+ weighted(this: this & {
56
+ readonly [Discrete]: true;
57
+ }, weights: ReadonlyArray<readonly [T & (string | number | boolean), number]>): this;
58
+ /** Normal (Gaussian) distribution for numeric schemas. */
59
+ normal(this: this & {
60
+ readonly [Continuous]: true;
61
+ }, mean: number, stddev: number): this;
62
+ /** Typical range — values concentrate uniformly inside [from, to]. */
63
+ typically(this: this & {
64
+ readonly [Numeric]: true;
65
+ }, from: number, to: number): this;
66
+ /** Force `value` with probability `p` (stacks before base distribution). */
67
+ occasionally(value: T, p: number): this;
68
+ /**
69
+ * Force `value` every `every` rows (deterministic, driven by `ctx.index`).
70
+ *
71
+ * Useful for periodic rare events that must hit at a guaranteed cadence
72
+ * (e.g. a recurring reset every N rows). Skipped when `ctx.index` is undefined.
73
+ */
74
+ eventually(every: number, value: T, opts?: {
75
+ readonly offset?: number;
76
+ }): this;
77
+ /**
78
+ * Field is computed from sibling/root context — generator skips sampling.
79
+ *
80
+ * The generic `U extends T` ensures the function's return type is
81
+ * assignable to the schema's value type. Combined with `relate(rows, field)`
82
+ * (which propagates `R[K]` through `DerivedFn<R[K]>`), this catches
83
+ * FK-type mismatches at compile time
84
+ * (e.g. `int().derivedFrom(relate(rowsWithStringSku, 'sku'))`).
85
+ */
86
+ derivedFrom<U extends T>(fn: DerivedFn<U>): this;
87
+ /** Single-record predicate. Generator retries up to MAX_ATTEMPTS to satisfy. */
88
+ invariant(fn: InvariantFn): this;
89
+ /** Restrict to a closed candidate set or a lookup-by-sibling-field map. */
90
+ in(constraint: DomainConstraint | readonly unknown[]): this;
91
+ /**
92
+ * Re-apply a complete `Axes` record to this schema. Public so that
93
+ * IR-reconstruction helpers (e.g. `fromIR`) can replay axes without
94
+ * reaching through a protected method via casts. Prefer the fluent axis
95
+ * builders (`.weighted`, `.in`, `.derivedFrom`, ...) in user code.
96
+ *
97
+ * Note: this is a low-level escape hatch — it does NOT run the
98
+ * capability allow-list that `.weighted` / `.normal` / `.typically`
99
+ * apply. Callers that round-trip IR are trusted to keep the IR coherent.
100
+ */
101
+ _applyAxes(axes: Axes): this;
102
+ protected withAxes(axes: Axes): this;
103
+ protected withModsPreserveType(patch: Partial<Modifiers>): this;
104
+ }
105
+ /**
106
+ * Infer the TypeScript type a schema generates / accepts.
107
+ *
108
+ * ```ts
109
+ * const User = obj({ id: int(), name: str() })
110
+ * type User = Infer<typeof User> // { id: number; name: string }
111
+ * ```
112
+ */
113
+ export type Infer<S> = S extends Schema<infer T> ? T : never;
114
+ /** Re-export modifier shape for advanced consumers. */
115
+ export type { Distribution, DomainConstraint, Modifiers, SchemaNode };
116
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/foundation/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,188 @@
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 { SchemaConflictError } from './errors.js';
12
+ import { withMods } from './ir.js';
13
+ /**
14
+ * Module-private capability marker symbol keys.
15
+ *
16
+ * Schemas opt into a capability by `declare`ing the corresponding bracketed
17
+ * property as the literal `true`. Methods like `.weighted` / `.normal` /
18
+ * `.typically` then gate themselves with a `this:` constraint that requires
19
+ * the marker. Symbols (rather than string keys like `_capDiscrete`) keep the
20
+ * markers out of consumer IntelliSense and out of any `Object.keys` loop.
21
+ *
22
+ * Three caps are required to mirror the runtime allow-list cleanly:
23
+ *
24
+ * - `Discrete` — values are enumerable; `.weighted` is meaningful.
25
+ * Carried by `str / int / bool / literal / enum`.
26
+ * - `Numeric` — values are bounded numerics; `.typically(from, to)` is
27
+ * meaningful (the generator clamps and, for integers,
28
+ * rounds). Carried by `num / int / decimal`.
29
+ * - `Continuous` — values are real-valued; `.normal(mean, σ)` is
30
+ * meaningful (Gaussian on integers would silently lose
31
+ * σ to rounding, so int is excluded). Carried by
32
+ * `num / decimal`.
33
+ *
34
+ * The symbols are real runtime values so subclass files can `import` them
35
+ * to redeclare the marker. They are NOT re-exported from the package root
36
+ * or from `@databehave/schema/internal`; the package's `exports` field
37
+ * limits deep-path imports to those two entries.
38
+ */
39
+ export const Discrete = Symbol('databehave.cap.discrete');
40
+ export const Numeric = Symbol('databehave.cap.numeric');
41
+ export const Continuous = Symbol('databehave.cap.continuous');
42
+ /**
43
+ * Allow-list for which IR kinds may legally carry each axis distribution.
44
+ *
45
+ * Mirrors the type-system `this:` gating on `.weighted` / `.normal` /
46
+ * `.typically`. Used by the runtime guard in those methods to fail-loud
47
+ * when a caller bypasses TypeScript (`as any`, plain JS, `// @ts-ignore`).
48
+ *
49
+ * Stays in sync with `docs/stability.md` "capability matrix".
50
+ */
51
+ const CAP_BY_OP = {
52
+ // .weighted: discrete-valued kinds. For `kind:'number'` it is allowed only
53
+ // when `int === true` (further check below).
54
+ weighted: new Set(['number', 'string', 'literal', 'enum', 'boolean']),
55
+ // .normal: continuous-numeric kinds. For `kind:'number'` it is allowed
56
+ // only when `int === false` (further check below).
57
+ normal: new Set(['number', 'decimal']),
58
+ // .typically: any numeric kind (int or float or decimal — for ints the
59
+ // generator clamps and rounds).
60
+ typically: new Set(['number', 'decimal']),
61
+ };
62
+ const checkAxisAllowed = (op, node) => {
63
+ if (!CAP_BY_OP[op].has(node.kind)) {
64
+ throw new SchemaConflictError(`.${op}() is not applicable to schema kind '${node.kind}'`, [], `see docs/stability.md (capability matrix)`);
65
+ }
66
+ // Number-kind is split between `int()` (discrete) and `num()` (continuous).
67
+ if (node.kind === 'number') {
68
+ const isInt = node.int === true;
69
+ if (op === 'weighted' && !isInt) {
70
+ throw new SchemaConflictError(`.weighted() is not applicable to num() (continuous); use int().weighted([...]) for discrete numeric weighting`, [], `see docs/stability.md (capability matrix)`);
71
+ }
72
+ if (op === 'normal' && isInt) {
73
+ throw new SchemaConflictError(`.normal() is not applicable to int() (discrete); use num().normal(...) for a continuous Gaussian`, [], `see docs/stability.md (capability matrix)`);
74
+ }
75
+ }
76
+ };
77
+ /** Base builder. Subclasses (StringSchema, NumberSchema, …) extend this. */
78
+ export class Schema {
79
+ _node;
80
+ constructor(node) {
81
+ this._node = node;
82
+ }
83
+ nullable() {
84
+ return new Schema(withMods(this._node, { nullable: true }));
85
+ }
86
+ optional() {
87
+ return new Schema(withMods(this._node, { optional: true }));
88
+ }
89
+ default(value) {
90
+ return new Schema(withMods(this._node, { hasDefault: true, defaultValue: value }));
91
+ }
92
+ describe(text) {
93
+ return this.withModsPreserveType({ description: text });
94
+ }
95
+ // ── data-schema axes ──────────────────────────────────────────────────────
96
+ /** Weighted distribution over discrete values. Weights are relative. */
97
+ weighted(weights) {
98
+ checkAxisAllowed('weighted', this._node);
99
+ return this.withAxes({
100
+ distribution: {
101
+ kind: 'weighted',
102
+ weights: weights,
103
+ },
104
+ });
105
+ }
106
+ /** Normal (Gaussian) distribution for numeric schemas. */
107
+ normal(mean, stddev) {
108
+ checkAxisAllowed('normal', this._node);
109
+ return this.withAxes({ distribution: { kind: 'normal', mean, stddev } });
110
+ }
111
+ /** Typical range — values concentrate uniformly inside [from, to]. */
112
+ typically(from, to) {
113
+ checkAxisAllowed('typically', this._node);
114
+ return this.withAxes({ distribution: { kind: 'typical', from, to } });
115
+ }
116
+ /** Force `value` with probability `p` (stacks before base distribution). */
117
+ occasionally(value, p) {
118
+ if (!(p >= 0 && p <= 1))
119
+ throw new RangeError(`occasionally: p must be in [0,1], got ${p}`);
120
+ const override = { value, p };
121
+ return this.withAxes({ occasionally: [override] });
122
+ }
123
+ /**
124
+ * Force `value` every `every` rows (deterministic, driven by `ctx.index`).
125
+ *
126
+ * Useful for periodic rare events that must hit at a guaranteed cadence
127
+ * (e.g. a recurring reset every N rows). Skipped when `ctx.index` is undefined.
128
+ */
129
+ eventually(every, value, opts) {
130
+ if (!Number.isInteger(every) || every < 1) {
131
+ throw new RangeError(`eventually: every must be a positive integer, got ${every}`);
132
+ }
133
+ const override = {
134
+ value,
135
+ every,
136
+ ...(opts?.offset !== undefined ? { offset: opts.offset } : {}),
137
+ };
138
+ return this.withAxes({ eventually: [override] });
139
+ }
140
+ /**
141
+ * Field is computed from sibling/root context — generator skips sampling.
142
+ *
143
+ * The generic `U extends T` ensures the function's return type is
144
+ * assignable to the schema's value type. Combined with `relate(rows, field)`
145
+ * (which propagates `R[K]` through `DerivedFn<R[K]>`), this catches
146
+ * FK-type mismatches at compile time
147
+ * (e.g. `int().derivedFrom(relate(rowsWithStringSku, 'sku'))`).
148
+ */
149
+ derivedFrom(fn) {
150
+ return this.withAxes({ derived: fn });
151
+ }
152
+ /** Single-record predicate. Generator retries up to MAX_ATTEMPTS to satisfy. */
153
+ invariant(fn) {
154
+ return this.withAxes({ invariants: [fn] });
155
+ }
156
+ /** Restrict to a closed candidate set or a lookup-by-sibling-field map. */
157
+ in(constraint) {
158
+ const dom = Array.isArray(constraint)
159
+ ? { kind: 'values', values: constraint }
160
+ : constraint;
161
+ return this.withAxes({ domain: dom });
162
+ }
163
+ // ── internal helpers ──────────────────────────────────────────────────────
164
+ /**
165
+ * Re-apply a complete `Axes` record to this schema. Public so that
166
+ * IR-reconstruction helpers (e.g. `fromIR`) can replay axes without
167
+ * reaching through a protected method via casts. Prefer the fluent axis
168
+ * builders (`.weighted`, `.in`, `.derivedFrom`, ...) in user code.
169
+ *
170
+ * Note: this is a low-level escape hatch — it does NOT run the
171
+ * capability allow-list that `.weighted` / `.normal` / `.typically`
172
+ * apply. Callers that round-trip IR are trusted to keep the IR coherent.
173
+ */
174
+ _applyAxes(axes) {
175
+ return this.withModsPreserveType({ axes });
176
+ }
177
+ withAxes(axes) {
178
+ return this.withModsPreserveType({ axes });
179
+ }
180
+ withModsPreserveType(patch) {
181
+ const next = Object.create(Object.getPrototypeOf(this));
182
+ Object.assign(next, this, {
183
+ _node: withMods(this._node, patch),
184
+ });
185
+ return next;
186
+ }
187
+ }
188
+ //# 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,72 @@
1
+ /**
2
+ * Extensibility API — IR walker and IR-to-builder reconstruction.
3
+ *
4
+ * databehave 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 extension contract.
14
+ *
15
+ * Extension 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>` — extension 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
+ /** Current IR contract version. Bumped on every MAJOR release. */
44
+ export declare const IR_VERSION: 1;
45
+ /** Envelope produced by {@link serializeSchema}. */
46
+ export interface SchemaEnvelope {
47
+ /** Reserved for forward compatibility; do not vary. */
48
+ readonly $databehaveVersion: typeof IR_VERSION;
49
+ readonly node: SchemaNode;
50
+ }
51
+ /**
52
+ * Wrap a schema's IR in a versioned envelope safe for serialisation
53
+ * (JSON, disk, IPC). Pair with {@link deserializeSchema} on the
54
+ * receiving end.
55
+ *
56
+ * Throws {@link SchemaConflictError} (`code: 'serialize.closure-axis'`)
57
+ * when any node in the tree carries a closure-bearing axis — `derived`,
58
+ * `invariants`, or an `occasionally` override whose `value` is a
59
+ * function. Closures cannot survive a JSON round-trip, so encoding such
60
+ * a schema would silently drop the axis on the receiving end and
61
+ * produce subtly wrong values. The check is loud at the encode site so
62
+ * callers reach for {@link replay} or hand-coded carriers instead.
63
+ */
64
+ export declare const serializeSchema: (schema: Schema<unknown>) => SchemaEnvelope;
65
+ /**
66
+ * Inverse of {@link serializeSchema}. Throws when the envelope was
67
+ * produced by an incompatible MAJOR version — the failure is loud
68
+ * because silently loading a node with a renamed or removed field
69
+ * would manifest as a subtle generation/parse bug far from the cause.
70
+ */
71
+ export declare const deserializeSchema: (envelope: unknown) => Schema<unknown>;
72
+ //# 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;AAcH,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,GACrB,cAAc,MAAM,GAAG,UAAU,EACjC,SAAS,aAAa,KACrB,IAGF,CAAA;AAkCD;;;;;;GAMG;AACH,eAAO,MAAM,MAAM,GAAI,MAAM,UAAU,KAAG,MAAM,CAAC,OAAO,CAGvD,CAAA;AA2FD,kEAAkE;AAClE,eAAO,MAAM,UAAU,EAAG,CAAU,CAAA;AAEpC,oDAAoD;AACpD,MAAM,WAAW,cAAc;IAC7B,uDAAuD;IACvD,QAAQ,CAAC,kBAAkB,EAAE,OAAO,UAAU,CAAA;IAC9C,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAC1B;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,CAAC,OAAO,CAAC,KAAG,cAMzD,CAAA;AA+DD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAU,OAAO,KAAG,MAAM,CAAC,OAAO,CAmBnE,CAAA"}