@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.
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,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"}
@@ -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"}
@@ -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"}