@ghostry/fabricator 0.0.1 → 0.0.3
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/README.md +18 -12
- package/dist/esm/Adapter/Core.js +3 -3
- package/dist/esm/Enumeration/Enumerate.js +16 -13
- package/dist/esm/Error/index.js +16 -8
- package/dist/esm/Fabricator/Constructor.js +12 -14
- package/dist/esm/Harnessing/Core.js +30 -0
- package/dist/esm/Harnessing/Salt.js +12 -0
- package/dist/esm/Harnessing/Types.js +1 -0
- package/dist/esm/Instance/Core.js +25 -41
- package/dist/esm/Instance/Stack/Async.js +10 -0
- package/dist/esm/Instance/Stack/Sync.js +16 -0
- package/dist/esm/Primitive/bigint/Registry.js +12 -12
- package/dist/esm/Primitive/boolean/Registry.js +2 -1
- package/dist/esm/Primitive/date/Registry.js +15 -14
- package/dist/esm/Primitive/null/Registry.js +2 -1
- package/dist/esm/Primitive/number/Registry.js +18 -17
- package/dist/esm/Primitive/recursive/Fabricator.js +1 -1
- package/dist/esm/Primitive/symbol/Registry.js +2 -1
- package/dist/esm/Primitive/undefined/Registry.js +2 -1
- package/dist/esm/Random/index.js +24 -79
- package/dist/esm/Utility/Core.js +6 -1
- package/dist/esm/adapting.js +2 -0
- package/dist/esm/harnessing.js +1 -0
- package/dist/esm/index.js +5 -4
- package/dist/esm/internal.js +2 -2
- package/dist/types/Adapter/Core.d.ts +30 -33
- package/dist/types/Adapter/Types.d.ts +78 -88
- package/dist/types/Bound.d.ts +15 -15
- package/dist/types/Distribution/index.d.ts +54 -61
- package/dist/types/Enumeration/Enumerate.d.ts +24 -24
- package/dist/types/Enumeration/Plan.d.ts +22 -26
- package/dist/types/Enumeration/Types.d.ts +38 -43
- package/dist/types/Error/index.d.ts +103 -89
- package/dist/types/Fabricator/Constructor.d.ts +24 -26
- package/dist/types/Fabricator/Types.d.ts +73 -81
- package/dist/types/Harnessing/Core.d.ts +43 -0
- package/dist/types/Harnessing/Salt.d.ts +31 -0
- package/dist/types/Harnessing/Types.d.ts +79 -0
- package/dist/types/Instance/Core.d.ts +38 -74
- package/dist/types/Instance/Stack/Async.d.ts +14 -0
- package/dist/types/Instance/Stack/Sync.d.ts +14 -0
- package/dist/types/Instance/Types.d.ts +98 -102
- package/dist/types/Primitive/always/Schema.d.ts +8 -8
- package/dist/types/Primitive/always/Types.d.ts +7 -7
- package/dist/types/Primitive/array/Registry.d.ts +10 -8
- package/dist/types/Primitive/array/Schema.d.ts +4 -5
- package/dist/types/Primitive/array/Types.d.ts +6 -6
- package/dist/types/Primitive/bigint/Registry.d.ts +6 -6
- package/dist/types/Primitive/bigint/Schema.d.ts +8 -8
- package/dist/types/Primitive/bigint/Types.d.ts +5 -5
- package/dist/types/Primitive/boolean/Outcomes.d.ts +8 -8
- package/dist/types/Primitive/boolean/Registry.d.ts +2 -12
- package/dist/types/Primitive/boolean/Schema.d.ts +8 -8
- package/dist/types/Primitive/boolean/Types.d.ts +3 -3
- package/dist/types/Primitive/choice/Fabricator.d.ts +6 -7
- package/dist/types/Primitive/choice/Registry.d.ts +13 -13
- package/dist/types/Primitive/choice/Schema.d.ts +6 -6
- package/dist/types/Primitive/choice/Types.d.ts +11 -11
- package/dist/types/Primitive/date/Registry.d.ts +25 -48
- package/dist/types/Primitive/date/Schema.d.ts +9 -10
- package/dist/types/Primitive/date/Types.d.ts +4 -4
- package/dist/types/Primitive/enum/Registry.d.ts +13 -13
- package/dist/types/Primitive/enum/Schema.d.ts +5 -5
- package/dist/types/Primitive/enum/Types.d.ts +17 -19
- package/dist/types/Primitive/namespace.d.ts +10 -10
- package/dist/types/Primitive/null/Registry.d.ts +2 -2
- package/dist/types/Primitive/null/Schema.d.ts +2 -2
- package/dist/types/Primitive/null/Types.d.ts +3 -3
- package/dist/types/Primitive/nullable/Fabricator.d.ts +7 -7
- package/dist/types/Primitive/nullable/Schema.d.ts +13 -13
- package/dist/types/Primitive/nullable/Types.d.ts +9 -10
- package/dist/types/Primitive/nullish/Fabricator.d.ts +12 -13
- package/dist/types/Primitive/nullish/Schema.d.ts +8 -8
- package/dist/types/Primitive/nullish/Types.d.ts +12 -13
- package/dist/types/Primitive/number/Registry.d.ts +20 -38
- package/dist/types/Primitive/number/Schema.d.ts +11 -12
- package/dist/types/Primitive/number/Types.d.ts +13 -13
- package/dist/types/Primitive/number/defaults.d.ts +3 -3
- package/dist/types/Primitive/object/Fabricator.d.ts +15 -15
- package/dist/types/Primitive/object/Registry.d.ts +8 -8
- package/dist/types/Primitive/object/Schema.d.ts +10 -10
- package/dist/types/Primitive/object/Types.d.ts +20 -22
- package/dist/types/Primitive/object/compute/Fabricator.d.ts +4 -5
- package/dist/types/Primitive/object/compute/Schema.d.ts +4 -4
- package/dist/types/Primitive/object/compute/Types.d.ts +19 -20
- package/dist/types/Primitive/object/omittable/Fabricator.d.ts +10 -10
- package/dist/types/Primitive/object/omittable/Outcomes.d.ts +2 -2
- package/dist/types/Primitive/object/omittable/Schema.d.ts +11 -11
- package/dist/types/Primitive/object/omittable/Types.d.ts +14 -15
- package/dist/types/Primitive/object/optional/Fabricator.d.ts +16 -18
- package/dist/types/Primitive/object/optional/Outcomes.d.ts +2 -2
- package/dist/types/Primitive/object/optional/Schema.d.ts +4 -4
- package/dist/types/Primitive/object/optional/Types.d.ts +17 -17
- package/dist/types/Primitive/opaque/Registry.d.ts +3 -3
- package/dist/types/Primitive/opaque/Schema.d.ts +8 -9
- package/dist/types/Primitive/record/Registry.d.ts +8 -6
- package/dist/types/Primitive/record/Schema.d.ts +9 -11
- package/dist/types/Primitive/record/Types.d.ts +25 -25
- package/dist/types/Primitive/recursive/Fabricator.d.ts +20 -21
- package/dist/types/Primitive/recursive/Registry.d.ts +6 -7
- package/dist/types/Primitive/recursive/Schema.d.ts +8 -8
- package/dist/types/Primitive/recursive/Terminate.d.ts +13 -14
- package/dist/types/Primitive/recursive/Types.d.ts +31 -31
- package/dist/types/Primitive/recursive/self/Fabricator.d.ts +11 -12
- package/dist/types/Primitive/recursive/self/Schema.d.ts +10 -10
- package/dist/types/Primitive/recursive/self/Types.d.ts +7 -8
- package/dist/types/Primitive/string/Constants.d.ts +12 -13
- package/dist/types/Primitive/string/Fabricator.d.ts +2 -2
- package/dist/types/Primitive/string/Registry.d.ts +10 -16
- package/dist/types/Primitive/string/Schema.d.ts +5 -5
- package/dist/types/Primitive/string/Types.d.ts +17 -17
- package/dist/types/Primitive/symbol/Fabricator.d.ts +2 -2
- package/dist/types/Primitive/symbol/Registry.d.ts +4 -11
- package/dist/types/Primitive/symbol/Schema.d.ts +6 -6
- package/dist/types/Primitive/symbol/Types.d.ts +2 -2
- package/dist/types/Primitive/tuple/Fabricator.d.ts +7 -8
- package/dist/types/Primitive/tuple/Schema.d.ts +5 -5
- package/dist/types/Primitive/tuple/Types.d.ts +24 -25
- package/dist/types/Primitive/undefinable/Fabricator.d.ts +7 -7
- package/dist/types/Primitive/undefinable/Schema.d.ts +13 -13
- package/dist/types/Primitive/undefinable/Types.d.ts +10 -10
- package/dist/types/Primitive/undefined/Registry.d.ts +2 -2
- package/dist/types/Primitive/undefined/Schema.d.ts +4 -4
- package/dist/types/Primitive/undefined/Types.d.ts +3 -3
- package/dist/types/Random/Generator/sfc32.d.ts +4 -4
- package/dist/types/Random/Types.d.ts +151 -293
- package/dist/types/Random/index.d.ts +56 -81
- package/dist/types/Schema/Core.d.ts +19 -21
- package/dist/types/Schema/Registry.d.ts +3 -3
- package/dist/types/Schema/Types.d.ts +41 -48
- package/dist/types/Types.d.ts +39 -45
- package/dist/types/Utility/Core.d.ts +18 -9
- package/dist/types/adapting.d.ts +32 -0
- package/dist/types/harnessing.d.ts +30 -0
- package/dist/types/index.d.ts +95 -128
- package/dist/types/internal.d.ts +53 -40
- package/package.json +39 -7
- package/dist/esm/Random/CallSite.js +0 -56
- package/dist/types/Random/CallSite.d.ts +0 -59
|
@@ -8,10 +8,10 @@ export type Definition<$Schema = AnySchema> = {
|
|
|
8
8
|
[_ in string]: $Schema;
|
|
9
9
|
};
|
|
10
10
|
/**
|
|
11
|
-
* Constraint for a refinement's values. The source schema differs per
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* Constraint for a refinement's values. The source schema differs per property,
|
|
12
|
+
* so it must be `any` (not `AnySchema`) to stay assignable across every
|
|
13
|
+
* property's own `$Source`. Constraint only: precise types still flow via
|
|
14
|
+
* `$Refinement`.
|
|
15
15
|
*/
|
|
16
16
|
export type Refinement<$Definition extends Definition> = Definition<ComputeSchema<Fabricated<$Definition>, any>>;
|
|
17
17
|
export type Extender<$Definition extends Definition, $Extension extends Definition> = (params: {
|
|
@@ -21,12 +21,11 @@ export type Refinements = ReadonlyArray<Definition>;
|
|
|
21
21
|
/**
|
|
22
22
|
* Every `object.omittable`- or `object.optional`-kind field's key, so
|
|
23
23
|
* `Fabricated` can mark exactly those `?:` instead of required — matching
|
|
24
|
-
* runtime, where a field whose roll lands on omission never has its key
|
|
25
|
-
*
|
|
24
|
+
* runtime, where a field whose roll lands on omission never has its key appear
|
|
25
|
+
* (`object/omittable/Fabricator.ts`, `object/optional/Fabricator.ts`).
|
|
26
26
|
* `object.optional`'s `ValueOf` already carries `| undefined` (its
|
|
27
|
-
* `Fabricated`), so combined with the `?:` here a field lands on
|
|
28
|
-
*
|
|
29
|
-
* present-with-a-value.
|
|
27
|
+
* `Fabricated`), so combined with the `?:` here a field lands on `{ a?: T |
|
|
28
|
+
* undefined }` — omitted, present-as-`undefined`, or present-with-a-value.
|
|
30
29
|
*/
|
|
31
30
|
type OmittableKeys<$Definition extends Definition> = {
|
|
32
31
|
[$K in keyof $Definition]: $Definition[$K] extends {
|
|
@@ -39,19 +38,18 @@ export type Fabricated<$Definition extends Definition, $Bindings extends unknown
|
|
|
39
38
|
[$K in OmittableKeys<$Definition>]?: ValueOf<$Definition[$K], $Bindings>;
|
|
40
39
|
}>;
|
|
41
40
|
/**
|
|
42
|
-
* The shape `.override()` accepts: every field optional, so a present key
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* fabricates to (`ValueOf`).
|
|
41
|
+
* The shape `.override()` accepts: every field optional, so a present key skips
|
|
42
|
+
* generation for that field. A nested `object`-kind field recurses into its own
|
|
43
|
+
* `Override` (deep-merge); an `object.omittable` or `object.optional` field
|
|
44
|
+
* additionally accepts `Omitted`, to force that field off rather than only
|
|
45
|
+
* forcing a value on (`object.optional` already accepts `undefined` via
|
|
46
|
+
* `ValueOf`); every other field — including `object.compute` — is a
|
|
47
|
+
* full-replacement leaf, typed as whatever it fabricates to (`ValueOf`).
|
|
50
48
|
*
|
|
51
49
|
* Checked via a bare structural `[Kind]`/`[Meta]` shape, never `Schema`/
|
|
52
|
-
* `Fabricator` — either carries `refine`'s contravariant use of
|
|
53
|
-
*
|
|
54
|
-
*
|
|
50
|
+
* `Fabricator` — either carries `refine`'s contravariant use of `$Definition`,
|
|
51
|
+
* and referencing it here would leak that contravariance into every recursive
|
|
52
|
+
* `Override` instantiation.
|
|
55
53
|
*/
|
|
56
54
|
export type Override<$Definition extends Definition> = Pretty<{
|
|
57
55
|
[$K in keyof $Definition]?: $Definition[$K] extends {
|
|
@@ -64,8 +62,8 @@ export type Override<$Definition extends Definition> = Pretty<{
|
|
|
64
62
|
} ? ValueOf<$Definition[$K]> | typeof Omitted : ValueOf<$Definition[$K]>;
|
|
65
63
|
}>;
|
|
66
64
|
/**
|
|
67
|
-
* `definition`/`refinements` stay required regardless of `produce` — an
|
|
68
|
-
*
|
|
65
|
+
* `definition`/`refinements` stay required regardless of `produce` — an opaque
|
|
66
|
+
* `as` production layers on top rather than replacing them, so
|
|
69
67
|
* `extend`/`refine`/`override` and `ToTypeBox`'s structural derivation keep
|
|
70
68
|
* working, and a prior definition survives `as` for future validation of
|
|
71
69
|
* `produce`.
|
|
@@ -22,10 +22,9 @@ export type Fabricator<$Fabricated, $Source extends Source, $Adaptations extends
|
|
|
22
22
|
export declare function isObjectComputeFabricator(candidate: BaseFabricator<unknown>): candidate is Fabricator<unknown, Source>;
|
|
23
23
|
/**
|
|
24
24
|
* Turn an `object.compute` Schema into a live Fabricator. Unlike every other
|
|
25
|
-
* kind, there's nothing of `source` to build here — a computed field's
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* `DetachedComputeError`.
|
|
25
|
+
* kind, there's nothing of `source` to build here — a computed field's value
|
|
26
|
+
* comes entirely from `resolve`, given the rest of the object. The node still
|
|
27
|
+
* records `trace` so it can be rebuilt from a parent field's captured trace;
|
|
28
|
+
* `.fabricate()` without the parent object throws `DetachedComputeError`.
|
|
30
29
|
*/
|
|
31
30
|
export declare function Fabricator<$Fabricated, $Source extends Source>(context: FabricatorContext<Schema<$Fabricated, $Source>>): Fabricator<$Fabricated, $Source>;
|
|
@@ -10,10 +10,10 @@ export type Computer<$Definition extends object.Definition> = <const $Source ext
|
|
|
10
10
|
};
|
|
11
11
|
export interface Schema<$Fabricated, $Source extends Source, $Adaptations extends Adaptations = {}> extends Core<$Fabricated, $Source, $Adaptations> {
|
|
12
12
|
/**
|
|
13
|
-
* Override what this schema maps to in one or more external schema
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* Override what this schema maps to in one or more external schema libraries
|
|
14
|
+
* — see `string/Schema.ts`'s `adapt` for the full contract. Adapting the
|
|
15
|
+
* computed field itself, rather than the `source` it derives its shape from,
|
|
16
|
+
* is the way to say the two differ.
|
|
17
17
|
*/
|
|
18
18
|
adapt: <const $Adapter extends Adapter, $Returnable extends ReturnType<$Adapter["convert"]>>(adapter: $Adapter, produce: (adapting: Adapting<Schema<$Fabricated, $Source, $Adaptations>>) => $Returnable) => Schema<$Fabricated, $Source, WithAdaptations<$Adaptations, AdaptationEntry<$Adapter, $Returnable>>>;
|
|
19
19
|
}
|
|
@@ -3,22 +3,22 @@ import type { AnySchema, ValueOf } from "../../../Schema/Types";
|
|
|
3
3
|
import { Kind, type Adaptation, type Meta, type Produces } from "../../../Types";
|
|
4
4
|
/**
|
|
5
5
|
* A builder that can mint a Schema via `as` — e.g. `T.string`, `T.bigint`.
|
|
6
|
-
* `compute` accepts one alongside a plain Schema so a caller needn't
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* `compute` accepts one alongside a plain Schema so a caller needn't satisfy a
|
|
7
|
+
* `whereby` just to name a computed field's type: the resolver supplies the
|
|
8
|
+
* value, so the field's length/range is irrelevant.
|
|
9
9
|
*/
|
|
10
10
|
export type Builder<$Schema extends AnySchema = AnySchema> = {
|
|
11
11
|
[Kind]: $Schema[typeof Kind];
|
|
12
12
|
as: (produce: () => any) => $Schema;
|
|
13
13
|
};
|
|
14
14
|
/**
|
|
15
|
-
* A `compute` source: the Schema whose value and shape a computed field
|
|
16
|
-
*
|
|
15
|
+
* A `compute` source: the Schema whose value and shape a computed field adopts,
|
|
16
|
+
* or a builder that denotes one.
|
|
17
17
|
*/
|
|
18
18
|
export type Source = AnySchema | Builder;
|
|
19
19
|
/**
|
|
20
|
-
* The Schema a source denotes: a plain Schema is itself; a builder is
|
|
21
|
-
*
|
|
20
|
+
* The Schema a source denotes: a plain Schema is itself; a builder is the
|
|
21
|
+
* Schema its `as` mints.
|
|
22
22
|
*/
|
|
23
23
|
export type Denoted<$Source> = $Source extends AnySchema ? $Source : $Source extends Builder<infer $Schema> ? $Schema : never;
|
|
24
24
|
/**
|
|
@@ -26,20 +26,19 @@ export type Denoted<$Source> = $Source extends AnySchema ? $Source : $Source ext
|
|
|
26
26
|
*/
|
|
27
27
|
export type Resolved<$Source, $Bindings extends unknown[] = []> = ValueOf<Denoted<$Source>, $Bindings>;
|
|
28
28
|
/**
|
|
29
|
-
* Source and resolver are stored raw — the source whether a Schema or a
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* `T.string`/`T.bigint`).
|
|
29
|
+
* Source and resolver are stored raw — the source whether a Schema or a builder
|
|
30
|
+
* (both carry a `[Kind]`, which is all schema derivation needs), and the
|
|
31
|
+
* resolver as plain data from the moment `compute(source).as(resolve)` is
|
|
32
|
+
* called: `compute` never builds anything, so unlike a Fabricator's closure
|
|
33
|
+
* there's nothing lossy about storing it. `source` is only used for its
|
|
34
|
+
* shape/type (`Adapter/TypeBox` reflects a computed field as its source's
|
|
35
|
+
* shape, unless the field itself is adapted) — the resolver draws entirely from
|
|
36
|
+
* `fabricated`, never from `source`, which may not even have a buildable recipe
|
|
37
|
+
* (a bare `T.string`/`T.bigint`).
|
|
39
38
|
*
|
|
40
|
-
* Unlike every other kind's `Meta`, this one is generic over the
|
|
41
|
-
* object'
|
|
42
|
-
*
|
|
39
|
+
* Unlike every other kind's `Meta`, this one is generic over the _enclosing
|
|
40
|
+
* object's_ fabricated type as well as the source — that is what the resolver
|
|
41
|
+
* is handed.
|
|
43
42
|
*/
|
|
44
43
|
export type Meta<$Fabricated, $Source extends Source> = {
|
|
45
44
|
source: $Source;
|
|
@@ -16,22 +16,22 @@ export type Fabricator<$Schema extends {
|
|
|
16
16
|
[Children]: BaseFabricator<any>;
|
|
17
17
|
readonly [Adaptation]?: AdaptationsOf<$Schema>;
|
|
18
18
|
/**
|
|
19
|
-
* `Omitted` on the empty roll (or when an `.as(...)` producer returns it)
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
19
|
+
* `Omitted` on the empty roll (or when an `.as(...)` producer returns it) —
|
|
20
|
+
* read only by `object/Fabricator.ts`'s fabricate loop, which omits the key
|
|
21
|
+
* entirely rather than writing `undefined`. Fabricating this outside a parent
|
|
22
|
+
* `object` hands the sentinel straight back.
|
|
23
23
|
*/
|
|
24
24
|
fabricate: () => Resolved<$Schema[typeof Meta]["definition"]>;
|
|
25
25
|
};
|
|
26
26
|
export declare function isObjectOmittableFabricator(candidate: BaseFabricator<unknown>): candidate is Fabricator;
|
|
27
27
|
/**
|
|
28
|
-
* A presence roll on this field's private stream, drawn only when present
|
|
29
|
-
*
|
|
28
|
+
* A presence roll on this field's private stream, drawn only when present is
|
|
29
|
+
* decided — an omission roll never advances `source`'s stream, and since
|
|
30
30
|
* `source` is already dispatched into its own independent stream by
|
|
31
|
-
* `Constructor.ts` regardless of this roll, skipping its draw here can
|
|
32
|
-
*
|
|
31
|
+
* `Constructor.ts` regardless of this roll, skipping its draw here can never
|
|
32
|
+
* perturb any other field's reproducibility (`Random/index.ts`'s
|
|
33
33
|
* `toStreamFromTrace`: every field's stream is private from the moment it's
|
|
34
|
-
* minted). 50/50 by default; `.weighted(...)` (`Schema.ts`) reweights
|
|
35
|
-
*
|
|
34
|
+
* minted). 50/50 by default; `.weighted(...)` (`Schema.ts`) reweights either
|
|
35
|
+
* outcome relative to that same default of `1`.
|
|
36
36
|
*/
|
|
37
37
|
export declare function Fabricator<$Definition extends Definition>(context: FabricatorContext<Schema<$Definition>>, source: BaseFabricator<any>): Fabricator<Schema<$Definition>>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The two outcomes an omittable field's presence roll can land on. Also
|
|
3
|
-
*
|
|
2
|
+
* The two outcomes an omittable field's presence roll can land on. Also the key
|
|
3
|
+
* space `.weighted(...)` weighs — see `Types.ts`'s `Weights`.
|
|
4
4
|
*
|
|
5
5
|
* Lives here rather than `Types.ts` so that file stays type-only (see
|
|
6
6
|
* `boolean/Outcomes.ts`).
|
|
@@ -6,25 +6,25 @@ import type { Core, Definition, Resolved, Weights } from "./Types";
|
|
|
6
6
|
export interface Schema<$Definition extends Definition = Definition, $Adaptations extends Adaptations = {}> extends Core<$Definition, $Adaptations> {
|
|
7
7
|
/**
|
|
8
8
|
* Layer an opaque production on this schema's existing `[Meta]` — carrying
|
|
9
|
-
* `definition` forward, not discarding it, so a later `.as(...)` (or
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* `definition` forward, not discarding it, so a later `.as(...)` (or future
|
|
10
|
+
* validation of `produce`) still has it to check against. `produce` may
|
|
11
|
+
* return `Omitted`, so custom presence logic composes the same way the
|
|
12
|
+
* built-in roll does.
|
|
13
13
|
*/
|
|
14
14
|
as: (produce: Produce<Resolved<$Definition>>) => Schema<$Definition, $Adaptations>;
|
|
15
15
|
/**
|
|
16
16
|
* Reweight the built-in presence roll. Keys are optional — an omitted key
|
|
17
|
-
* keeps baseline weight `1`, the same weight the 50/50 split already uses
|
|
18
|
-
*
|
|
17
|
+
* keeps baseline weight `1`, the same weight the 50/50 split already uses —
|
|
18
|
+
* but that baseline is still relative to whatever else is specified, so
|
|
19
19
|
* `.weighted({ omitted: 0.1 })` shifts both outcomes' shares, not just
|
|
20
|
-
* `omitted`'s (see `Types.ts`'s `Weights`). Chaining `.weighted(...)`
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* `omitted`'s (see `Types.ts`'s `Weights`). Chaining `.weighted(...)` merges
|
|
21
|
+
* into previous weights rather than replacing them, the same layering
|
|
22
|
+
* `.as(...)` uses for `produce`.
|
|
23
23
|
*/
|
|
24
24
|
weighted: (weights: Weights) => Schema<$Definition, $Adaptations>;
|
|
25
25
|
/**
|
|
26
|
-
* Override what this schema maps to in one or more external schema
|
|
27
|
-
*
|
|
26
|
+
* Override what this schema maps to in one or more external schema libraries
|
|
27
|
+
* — see `string/Schema.ts`'s `adapt` for the full contract.
|
|
28
28
|
*/
|
|
29
29
|
adapt: <const $Adapter extends Adapter, $Returnable extends ReturnType<$Adapter["convert"]>>(adapter: $Adapter, produce: (adapting: Adapting<Schema<$Definition, $Adaptations>>) => $Returnable) => Schema<$Definition, WithAdaptations<$Adaptations, AdaptationEntry<$Adapter, $Returnable>>>;
|
|
30
30
|
}
|
|
@@ -3,32 +3,31 @@ import type { Produce } from "../../../Random/Types";
|
|
|
3
3
|
import type { AnySchema, ValueOf } from "../../../Schema/Types";
|
|
4
4
|
import { Kind, Meta, Omitted, type Adaptation, type Produces } from "../../../Types";
|
|
5
5
|
/**
|
|
6
|
-
* The wrapped field's own Schema — the value type an omittable field
|
|
7
|
-
*
|
|
6
|
+
* The wrapped field's own Schema — the value type an omittable field produces
|
|
7
|
+
* when its presence roll comes up present.
|
|
8
8
|
*/
|
|
9
9
|
export type Definition = AnySchema;
|
|
10
10
|
export type Fabricated<$Definition extends Definition, $Bindings extends unknown[] = []> = ValueOf<$Definition, $Bindings>;
|
|
11
11
|
/**
|
|
12
|
-
* What an omittable field's Fabricator returns: the wrapped value, or
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* What an omittable field's Fabricator returns: the wrapped value, or `Omitted`
|
|
13
|
+
* when it should not appear — whether from the built-in presence roll or, via
|
|
14
|
+
* `.as(...)`, an opaque producer.
|
|
15
15
|
*/
|
|
16
16
|
export type Resolved<$Definition extends Definition> = Fabricated<$Definition> | typeof Omitted;
|
|
17
17
|
export type { Outcome } from "./Outcomes";
|
|
18
18
|
/**
|
|
19
|
-
* Relative weights for `.weighted(...)`, keyed by `Outcome`. Keys optional —
|
|
20
|
-
*
|
|
21
|
-
*
|
|
19
|
+
* Relative weights for `.weighted(...)`, keyed by `Outcome`. Keys optional — an
|
|
20
|
+
* omitted key falls back to baseline `1`, the same weight the 50/50 split
|
|
21
|
+
* already uses. Values are relative, exactly like `weighted()`
|
|
22
22
|
* (`Distribution/index.ts`) — they need not sum to one, and are fed to
|
|
23
23
|
* `weighted()` unchanged alongside each unspecified key's baseline `1`.
|
|
24
24
|
*
|
|
25
|
-
* Specifying one outcome's weight shifts the
|
|
26
|
-
* probability too, even though its weight stays at `1` — its share of the
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* full set in play.
|
|
25
|
+
* Specifying one outcome's weight shifts the _other_ outcome's resulting
|
|
26
|
+
* probability too, even though its weight stays at `1` — its share of the total
|
|
27
|
+
* still moves, since the total changed. `.weighted({ omitted: 0.1 })` is not
|
|
28
|
+
* "10% omitted, 90% present" — with `value` at default `1`, the split is `0.1 /
|
|
29
|
+
* 1.1 ≈ 9.1%` omitted, `≈90.9%` present. No independent "absolute probability"
|
|
30
|
+
* mode; weights are only meaningful relative to the full set in play.
|
|
32
31
|
*/
|
|
33
32
|
export type Weights = {
|
|
34
33
|
omitted: number;
|
|
@@ -17,29 +17,27 @@ export type Fabricator<$Schema extends {
|
|
|
17
17
|
readonly [Adaptation]?: AdaptationsOf<$Schema>;
|
|
18
18
|
/**
|
|
19
19
|
* `Omitted` on the omission roll (or when an `.as(...)` producer returns it)
|
|
20
|
-
* — read only by `object/Fabricator.ts`'s fabricate loop, which omits the
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* verbatim.
|
|
20
|
+
* — read only by `object/Fabricator.ts`'s fabricate loop, which omits the key
|
|
21
|
+
* entirely rather than writing `undefined`. A "present as `undefined`" roll
|
|
22
|
+
* returns `undefined` directly, which the loop assigns like any ordinary
|
|
23
|
+
* value — the difference from `object.omittable`. Fabricating this outside a
|
|
24
|
+
* parent `object` hands whichever of the three results back verbatim.
|
|
26
25
|
*/
|
|
27
26
|
fabricate: () => Resolved<$Schema[typeof Meta]["definition"]>;
|
|
28
27
|
};
|
|
29
28
|
export declare function isObjectOptionalFabricator(candidate: BaseFabricator<unknown>): candidate is Fabricator;
|
|
30
29
|
/**
|
|
31
|
-
* Three-way roll: omitted, present-as-`undefined`, or the wrapped value —
|
|
32
|
-
*
|
|
30
|
+
* Three-way roll: omitted, present-as-`undefined`, or the wrapped value — on
|
|
31
|
+
* this field's private stream; `source` is drawn only when "value" wins.
|
|
33
32
|
* Uniform (1/3 each) by default; not achievable by composing
|
|
34
|
-
* `object.omittable(T.undefinable(inner))`'s two independent 50/50 rolls
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* CLAUDE.md's "Randomness").
|
|
33
|
+
* `object.omittable(T.undefinable(inner))`'s two independent 50/50 rolls (that
|
|
34
|
+
* is 50/25/25, not 33/33/33), hence the dedicated three-way `weighted()` here —
|
|
35
|
+
* see CLAUDE.md's "Why `T.optional` isn't `omittable(undefinable(inner))`"
|
|
36
|
+
* under "Compound / field-only kinds". `.weighted(...)` (`Schema.ts`) reweights
|
|
37
|
+
* individual outcomes relative to that same default of `1`; an unspecified
|
|
38
|
+
* outcome keeps it. Skipping `source`'s draw on the two non-"value" outcomes is
|
|
39
|
+
* safe for the same reason as `object/omittable/Fabricator.ts`: `source`
|
|
40
|
+
* already has its own independent stream, minted at build time regardless of
|
|
41
|
+
* this roll (see CLAUDE.md's "Randomness").
|
|
44
42
|
*/
|
|
45
43
|
export declare function Fabricator<$Definition extends Definition>(context: FabricatorContext<Schema<$Definition>>, source: BaseFabricator<any>): Fabricator<Schema<$Definition>>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The three outcomes an optional field's roll can land on. Also the key
|
|
3
|
-
*
|
|
2
|
+
* The three outcomes an optional field's roll can land on. Also the key space
|
|
3
|
+
* `.weighted(...)` weighs — see `Types.ts`'s `Weights`.
|
|
4
4
|
*
|
|
5
5
|
* Lives here rather than `Types.ts` so that file stays type-only (see
|
|
6
6
|
* `boolean/Outcomes.ts`).
|
|
@@ -8,8 +8,8 @@ export interface Schema<$Definition extends Definition = Definition, $Adaptation
|
|
|
8
8
|
* Layer an opaque production on this schema's existing `[Meta]` — carrying
|
|
9
9
|
* `definition` forward, not discarding it, so a later `.as(...)` (or future
|
|
10
10
|
* validation of `produce`) still has it to check against. `produce` may
|
|
11
|
-
* return `undefined` or `Omitted`, so custom logic composes the same way
|
|
12
|
-
*
|
|
11
|
+
* return `undefined` or `Omitted`, so custom logic composes the same way the
|
|
12
|
+
* built-in three-way roll does.
|
|
13
13
|
*/
|
|
14
14
|
as: (produce: Produce<Resolved<$Definition>>) => Schema<$Definition, $Adaptations>;
|
|
15
15
|
/**
|
|
@@ -23,8 +23,8 @@ export interface Schema<$Definition extends Definition = Definition, $Adaptation
|
|
|
23
23
|
*/
|
|
24
24
|
weighted: (weights: Weights) => Schema<$Definition, $Adaptations>;
|
|
25
25
|
/**
|
|
26
|
-
* Override what this schema maps to in one or more external schema
|
|
27
|
-
*
|
|
26
|
+
* Override what this schema maps to in one or more external schema libraries
|
|
27
|
+
* — see `string/Schema.ts`'s `adapt` for the full contract.
|
|
28
28
|
*/
|
|
29
29
|
adapt: <const $Adapter extends Adapter, $Returnable extends ReturnType<$Adapter["convert"]>>(adapter: $Adapter, produce: (adapting: Adapting<Schema<$Definition, $Adaptations>>) => $Returnable) => Schema<$Definition, WithAdaptations<$Adaptations, AdaptationEntry<$Adapter, $Returnable>>>;
|
|
30
30
|
}
|
|
@@ -11,33 +11,33 @@ export type Definition = AnySchema;
|
|
|
11
11
|
* The value an optional field's key holds when present at all — the wrapped
|
|
12
12
|
* value, or `undefined` (present-as-`undefined` is one of three outcomes,
|
|
13
13
|
* distinct from the key not appearing). Flows through `[Produces]` into
|
|
14
|
-
* `object/Types.ts`'s per-field type, so a `T.optional`-wrapped field types
|
|
15
|
-
*
|
|
16
|
-
* covers this kind)
|
|
14
|
+
* `object/Types.ts`'s per-field type, so a `T.optional`-wrapped field types as
|
|
15
|
+
* `{ a?: T | undefined }` — a real `?:` (from `OmittableKeys`, which also
|
|
16
|
+
* covers this kind) _and_ a real `| undefined`.
|
|
17
17
|
*/
|
|
18
18
|
export type Fabricated<$Definition extends Definition, $Bindings extends unknown[] = []> = ValueOf<$Definition, $Bindings> | undefined;
|
|
19
19
|
/**
|
|
20
|
-
* What an optional field's Fabricator returns: the wrapped value,
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* What an optional field's Fabricator returns: the wrapped value, `undefined`,
|
|
21
|
+
* or `Omitted` when the key should not appear — whether from the built-in
|
|
22
|
+
* three-way roll or, via `.as(...)`, an opaque producer.
|
|
23
23
|
*/
|
|
24
24
|
export type Resolved<$Definition extends Definition> = Fabricated<$Definition> | typeof Omitted;
|
|
25
25
|
export type { Outcome } from "./Outcomes";
|
|
26
26
|
/**
|
|
27
|
-
* Relative weights for `.weighted(...)`, keyed by `Outcome`. Keys optional —
|
|
28
|
-
*
|
|
29
|
-
*
|
|
27
|
+
* Relative weights for `.weighted(...)`, keyed by `Outcome`. Keys optional — an
|
|
28
|
+
* omitted key falls back to baseline `1`, the same weight the uniform 1/3 split
|
|
29
|
+
* already uses. Values are relative, exactly like `weighted()`
|
|
30
30
|
* (`Distribution/index.ts`) — they need not sum to one, and are fed to
|
|
31
31
|
* `weighted()` unchanged alongside each unspecified key's baseline `1`.
|
|
32
32
|
*
|
|
33
|
-
* Specifying one outcome's weight shifts
|
|
34
|
-
* probability, not just the named one — unspecified ones stay at weight `1`
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
33
|
+
* Specifying one outcome's weight shifts _every_ outcome's resulting
|
|
34
|
+
* probability, not just the named one — unspecified ones stay at weight `1` but
|
|
35
|
+
* their share of the total still moves, since the total changed. `.weighted({
|
|
36
|
+
* omitted: 0.1 })` on `T.optional` is not "10% omitted, other two still 33%" —
|
|
37
|
+
* with `undefined`/`value` at default `1`, the split is `0.1 / 2.1 ≈ 4.8%`
|
|
38
|
+
* omitted and `≈47.6%` each for the other two. No independent "absolute
|
|
39
|
+
* probability" mode; weights are only meaningful relative to the full set in
|
|
40
|
+
* play.
|
|
41
41
|
*/
|
|
42
42
|
export type Weights = {
|
|
43
43
|
omitted: number;
|
|
@@ -5,8 +5,8 @@ import { Schema } from "./Schema";
|
|
|
5
5
|
* instance — produced by `produce` and typed as whatever it returns, so
|
|
6
6
|
* `T.opaque((random) => new Map<string, number>())` needs no annotation.
|
|
7
7
|
*
|
|
8
|
-
* `produce` receives this schema's own seeded stream, so an opaque value
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* `produce` receives this schema's own seeded stream, so an opaque value still
|
|
9
|
+
* replays from a salt; see `Types.ts`'s `Produce`. No bare form and no `.as()`
|
|
10
|
+
* — `produce` is the whole schema.
|
|
11
11
|
*/
|
|
12
12
|
export default function <$T>(produce: Produce<$T>): Schema<$T>;
|
|
@@ -2,20 +2,19 @@ import { type AdaptationEntry } from "../../Adapter/Core";
|
|
|
2
2
|
import type { Adaptations, Adapter, Adapting, WithAdaptations } from "../../Adapter/Types";
|
|
3
3
|
import type { Core } from "./Types";
|
|
4
4
|
/**
|
|
5
|
-
* Escape hatch for values no kind models — a `Map`, a `Set`, a `URL`, a
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Escape hatch for values no kind models — a `Map`, a `Set`, a `URL`, a class
|
|
6
|
+
* instance, a branded type. `produce` is supplied at construction and receives
|
|
7
|
+
* the schema's own seeded stream (`Types.ts`'s `Produce`).
|
|
8
8
|
*
|
|
9
9
|
* No `.as()`, for `always`'s reason: the constructor argument already fully
|
|
10
|
-
* determines production. `adapt` matters more here than for any other kind
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* more.
|
|
10
|
+
* determines production. `adapt` matters more here than for any other kind — an
|
|
11
|
+
* opaque value maps to TypeBox's `Unknown`, which is honest but maximally
|
|
12
|
+
* imprecise, and `.adapt(typebox, ...)` is the only way to say more.
|
|
14
13
|
*/
|
|
15
14
|
export interface Schema<$T = unknown, $Adaptations extends Adaptations = {}> extends Core<$T, $Adaptations> {
|
|
16
15
|
/**
|
|
17
|
-
* Override what this schema maps to in one or more external schema
|
|
18
|
-
*
|
|
16
|
+
* Override what this schema maps to in one or more external schema libraries
|
|
17
|
+
* — see `string/Schema.ts`'s `adapt` for the full contract.
|
|
19
18
|
*/
|
|
20
19
|
adapt: <const $Adapter extends Adapter, $Returnable extends ReturnType<$Adapter["convert"]>>(adapter: $Adapter, produce: (adapting: Adapting<Schema<$T, $Adaptations>>) => $Returnable) => Schema<$T, WithAdaptations<$Adaptations, AdaptationEntry<$Adapter, $Returnable>>>;
|
|
21
20
|
}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import type { Produce } from "../../Random/Types";
|
|
2
2
|
import { Schema } from "./Schema";
|
|
3
3
|
import type { Fabricated, Key, Value, Whereby } from "./Types";
|
|
4
|
-
|
|
4
|
+
type ThisRegistry<$Key extends Key, $Value extends Value> = {
|
|
5
5
|
/**
|
|
6
6
|
* A record of `value` keyed by `key`, attempted `whereby.size` times —
|
|
7
|
-
* uniformly across `[size.minTried, size.max]` (with `minTried`
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* uniformly across `[size.minTried, size.max]` (with `minTried` defaulting to
|
|
8
|
+
* 0). Colliding keys collapse, so the result holds _at most_ that many
|
|
9
|
+
* entries; see `Types.ts`'s `Whereby`.
|
|
10
10
|
*/
|
|
11
11
|
whereby: (whereby: Whereby) => Schema<$Key, $Value>;
|
|
12
12
|
/**
|
|
13
|
-
* A record whose production is `produce`, in full, instead of drawn
|
|
14
|
-
* entry
|
|
13
|
+
* A record whose production is `produce`, in full, instead of drawn entry by
|
|
14
|
+
* entry.
|
|
15
15
|
*/
|
|
16
16
|
as: (produce: Produce<Fabricated<$Key, $Value>>) => Schema<$Key, $Value>;
|
|
17
17
|
};
|
|
18
|
+
export default function <const $Key extends Key, const $Value extends Value>(key: $Key, value: $Value): ThisRegistry<$Key, $Value>;
|
|
19
|
+
export {};
|
|
@@ -3,24 +3,22 @@ import type { Adaptations, Adapter, Adapting, WithAdaptations } from "../../Adap
|
|
|
3
3
|
import type { Produce } from "../../Random/Types";
|
|
4
4
|
import type { Core, Fabricated, Key, Value } from "./Types";
|
|
5
5
|
/**
|
|
6
|
-
* The buildable recipe for a `record`: a key Schema and a value Schema,
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* The buildable recipe for a `record`: a key Schema and a value Schema, drawn
|
|
7
|
+
* `whereby.size` times. `array`'s sibling — one repeated value shape and a
|
|
8
|
+
* fuzzed count — but keyed rather than indexed.
|
|
9
9
|
*/
|
|
10
10
|
export interface Schema<$Key extends Key = Key, $Value extends Value = Value, $Adaptations extends Adaptations = {}> extends Core<$Key, $Value, $Adaptations> {
|
|
11
11
|
/**
|
|
12
12
|
* Layer an opaque production on this schema's existing `[Meta]` — carrying
|
|
13
|
-
* `whereby`/`key`/`value` forward, not discarding them, so a later
|
|
14
|
-
*
|
|
15
|
-
* against.
|
|
13
|
+
* `whereby`/`key`/`value` forward, not discarding them, so a later `.as(...)`
|
|
14
|
+
* (or future validation of `produce`) still has them to check against.
|
|
16
15
|
*/
|
|
17
16
|
as: (produce: Produce<Fabricated<$Key, $Value>>) => Schema<$Key, $Value, $Adaptations>;
|
|
18
17
|
/**
|
|
19
|
-
* Override what this schema maps to in one or more external schema
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* one a mapping.
|
|
18
|
+
* Override what this schema maps to in one or more external schema libraries
|
|
19
|
+
* — see `string/Schema.ts`'s `adapt`. Particularly relevant here: a
|
|
20
|
+
* symbol-keyed record has no TypeBox counterpart (`Adapter/TypeBox`'s
|
|
21
|
+
* `record` case), so this is the only way to give one a mapping.
|
|
24
22
|
*/
|
|
25
23
|
adapt: <const $Adapter extends Adapter, $Returnable extends ReturnType<$Adapter["convert"]>>(adapter: $Adapter, produce: (adapting: Adapting<Schema<$Key, $Value, $Adaptations>>) => $Returnable) => Schema<$Key, $Value, WithAdaptations<$Adaptations, AdaptationEntry<$Adapter, $Returnable>>>;
|
|
26
24
|
}
|