@ghostry/fabricator 0.0.7 → 0.0.9

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 (96) hide show
  1. package/dist/esm/Bound.js +6 -1
  2. package/dist/esm/Distribution/index.js +10 -1
  3. package/dist/esm/Enumeration/Plan.js +16 -0
  4. package/dist/esm/Error/index.js +8 -0
  5. package/dist/esm/Fabricator/Constructor.js +13 -0
  6. package/dist/esm/Instance/Core.js +8 -8
  7. package/dist/esm/Primitive/always/Schema.js +2 -0
  8. package/dist/esm/Primitive/array/Fabricator.js +4 -9
  9. package/dist/esm/Primitive/array/Schema.js +2 -0
  10. package/dist/esm/Primitive/bigint/Schema.js +2 -0
  11. package/dist/esm/Primitive/boolean/Schema.js +2 -0
  12. package/dist/esm/Primitive/choice/Schema.js +2 -0
  13. package/dist/esm/Primitive/date/Schema.js +2 -0
  14. package/dist/esm/Primitive/derive/Fabricator.js +31 -0
  15. package/dist/esm/Primitive/derive/Registry.js +17 -0
  16. package/dist/esm/Primitive/derive/Schema.js +12 -0
  17. package/dist/esm/Primitive/derive/Types.js +1 -0
  18. package/dist/esm/Primitive/derive/index.js +5 -0
  19. package/dist/esm/Primitive/enum/Schema.js +2 -0
  20. package/dist/esm/Primitive/index.js +1 -0
  21. package/dist/esm/Primitive/namespace.js +2 -1
  22. package/dist/esm/Primitive/null/Schema.js +2 -0
  23. package/dist/esm/Primitive/nullable/Schema.js +2 -0
  24. package/dist/esm/Primitive/nullish/Schema.js +2 -0
  25. package/dist/esm/Primitive/number/Fabricator.js +3 -7
  26. package/dist/esm/Primitive/number/Schema.js +2 -0
  27. package/dist/esm/Primitive/object/Registry.js +8 -8
  28. package/dist/esm/Primitive/object/Schema.js +3 -1
  29. package/dist/esm/Primitive/object/compute/Schema.js +2 -0
  30. package/dist/esm/Primitive/object/omittable/Schema.js +2 -0
  31. package/dist/esm/Primitive/object/optional/Schema.js +2 -0
  32. package/dist/esm/Primitive/opaque/Schema.js +2 -0
  33. package/dist/esm/Primitive/record/Fabricator.js +6 -1
  34. package/dist/esm/Primitive/record/Schema.js +2 -0
  35. package/dist/esm/Primitive/recursive/Schema.js +2 -0
  36. package/dist/esm/Primitive/recursive/Terminate.js +17 -0
  37. package/dist/esm/Primitive/recursive/self/Schema.js +2 -0
  38. package/dist/esm/Primitive/string/Fabricator.js +6 -2
  39. package/dist/esm/Primitive/string/Schema.js +2 -0
  40. package/dist/esm/Primitive/symbol/Schema.js +2 -0
  41. package/dist/esm/Primitive/tuple/Schema.js +2 -0
  42. package/dist/esm/Primitive/undefinable/Schema.js +2 -0
  43. package/dist/esm/Primitive/undefined/Schema.js +2 -0
  44. package/dist/esm/Schema/Core.js +13 -1
  45. package/dist/esm/Schema/Satisfies.js +5 -0
  46. package/dist/esm/index.js +2 -0
  47. package/dist/types/Bound.d.ts +20 -4
  48. package/dist/types/Distribution/index.d.ts +19 -0
  49. package/dist/types/Enumeration/Types.d.ts +4 -3
  50. package/dist/types/Error/index.d.ts +37 -7
  51. package/dist/types/Fabricator/Types.d.ts +1 -1
  52. package/dist/types/Harnessing/Core.d.ts +4 -4
  53. package/dist/types/Primitive/always/Schema.d.ts +8 -1
  54. package/dist/types/Primitive/array/Registry.d.ts +7 -5
  55. package/dist/types/Primitive/array/Schema.d.ts +7 -0
  56. package/dist/types/Primitive/array/Types.d.ts +3 -9
  57. package/dist/types/Primitive/bigint/Schema.d.ts +7 -0
  58. package/dist/types/Primitive/boolean/Schema.d.ts +7 -0
  59. package/dist/types/Primitive/choice/Registry.d.ts +16 -6
  60. package/dist/types/Primitive/choice/Schema.d.ts +7 -0
  61. package/dist/types/Primitive/date/Schema.d.ts +7 -0
  62. package/dist/types/Primitive/derive/Fabricator.d.ts +44 -0
  63. package/dist/types/Primitive/derive/Registry.d.ts +6 -0
  64. package/dist/types/Primitive/derive/Schema.d.ts +44 -0
  65. package/dist/types/Primitive/derive/Types.d.ts +38 -0
  66. package/dist/types/Primitive/derive/index.d.ts +5 -0
  67. package/dist/types/Primitive/enum/Registry.d.ts +19 -9
  68. package/dist/types/Primitive/enum/Schema.d.ts +7 -0
  69. package/dist/types/Primitive/index.d.ts +3 -2
  70. package/dist/types/Primitive/namespace.d.ts +1 -0
  71. package/dist/types/Primitive/null/Schema.d.ts +9 -2
  72. package/dist/types/Primitive/nullable/Schema.d.ts +7 -0
  73. package/dist/types/Primitive/nullish/Schema.d.ts +7 -0
  74. package/dist/types/Primitive/number/Schema.d.ts +7 -0
  75. package/dist/types/Primitive/object/Schema.d.ts +12 -2
  76. package/dist/types/Primitive/object/compute/Schema.d.ts +8 -0
  77. package/dist/types/Primitive/object/omittable/Schema.d.ts +10 -1
  78. package/dist/types/Primitive/object/optional/Schema.d.ts +9 -1
  79. package/dist/types/Primitive/opaque/Schema.d.ts +8 -1
  80. package/dist/types/Primitive/record/Schema.d.ts +7 -0
  81. package/dist/types/Primitive/record/Types.d.ts +2 -2
  82. package/dist/types/Primitive/recursive/Schema.d.ts +8 -1
  83. package/dist/types/Primitive/recursive/self/Schema.d.ts +11 -1
  84. package/dist/types/Primitive/string/Registry.d.ts +13 -9
  85. package/dist/types/Primitive/string/Schema.d.ts +7 -0
  86. package/dist/types/Primitive/string/Types.d.ts +7 -11
  87. package/dist/types/Primitive/symbol/Schema.d.ts +7 -0
  88. package/dist/types/Primitive/tuple/Schema.d.ts +7 -0
  89. package/dist/types/Primitive/undefinable/Schema.d.ts +7 -0
  90. package/dist/types/Primitive/undefined/Schema.d.ts +9 -2
  91. package/dist/types/Schema/Core.d.ts +13 -0
  92. package/dist/types/Schema/Satisfies.d.ts +84 -0
  93. package/dist/types/Schema/Types.d.ts +17 -1
  94. package/dist/types/Types.d.ts +4 -3
  95. package/dist/types/index.d.ts +18 -0
  96. package/package.json +1 -1
@@ -0,0 +1,44 @@
1
+ import type { AdaptationsOf } from "../../Adapter/Types";
2
+ import type { FabricatorContext, NaiveFabricator } from "../../Fabricator/Types";
3
+ import type { Trace } from "../../Random/Types";
4
+ import { Children, Kind, Meta, type Adaptation } from "../../Types";
5
+ import type { Fabricated as FromValues } from "../tuple/Types";
6
+ import { Schema } from "./Schema";
7
+ import type { From, Meta as ThisMeta, Resolved, Source } from "./Types";
8
+ export type Fabrication<$Fabricator extends Fabricator> = $Fabricator extends Fabricator<infer $Schema extends {
9
+ [Meta]: ThisMeta;
10
+ }> ? Resolved<$Schema[typeof Meta]["to"]> : never;
11
+ export type Fabricator<$Schema extends {
12
+ [Meta]: ThisMeta;
13
+ } = {
14
+ [Meta]: ThisMeta;
15
+ }> = NaiveFabricator<Resolved<$Schema[typeof Meta]["to"]>> & {
16
+ [Kind]: "derive";
17
+ [Meta]: $Schema[typeof Meta];
18
+ readonly trace: Trace;
19
+ [Children]: ReadonlyArray<NaiveFabricator<any>>;
20
+ readonly [Adaptation]?: AdaptationsOf<$Schema>;
21
+ /**
22
+ * Given `from`, resolves those values instead of fabricating each slot.
23
+ * Enumeration uses this to pin `from` slots and still run `resolve` on them
24
+ * (see `Enumeration/Plan.ts`).
25
+ */
26
+ fabricate: (params?: {
27
+ from: FromValues<$Schema[typeof Meta]["from"]>;
28
+ }) => Resolved<$Schema[typeof Meta]["to"]>;
29
+ schema: Schema<$Schema[typeof Meta]["from"], $Schema[typeof Meta]["to"], AdaptationsOf<$Schema>>;
30
+ };
31
+ /**
32
+ * `from` are each input slot's _already-dispatched_ Fabricator, one per
33
+ * `[Meta].from` entry, built by `Constructor.ts`'s `make` before this call —
34
+ * the same shape `tuple.Fabricator`'s `elements` take. Each slot gets its own
35
+ * private stream, so two same-kind inputs produce independent sequences rather
36
+ * than a correlated shared one.
37
+ *
38
+ * `toStreamFromTrace` is always consulted: `resolve` is required (there is no
39
+ * bare path) and is handed this node's `ProduceContext`, so any extra
40
+ * randomness it draws still replays under a salt. Don't collapse that into a
41
+ * conditional — `resolve` is the equivalent of every other kind's `produce`,
42
+ * and here it is always present.
43
+ */
44
+ export declare function Fabricator<$From extends From, $To extends Source>(context: FabricatorContext<Schema<$From, $To>>, from: ReadonlyArray<NaiveFabricator<any>>): Fabricator<Schema<$From, $To>>;
@@ -0,0 +1,6 @@
1
+ import { type Deriver } from "./Schema";
2
+ import type { From, Source } from "./Types";
3
+ export default function <const $From extends From, const $To extends Source>({ to, from, }: {
4
+ to: $To;
5
+ from: $From;
6
+ }): Deriver<$From, $To>;
@@ -0,0 +1,44 @@
1
+ import { type AdaptationEntry } from "../../Adapter/Core";
2
+ import type { Adaptations, Adapter, Adapting, WithAdaptations } from "../../Adapter/Types";
3
+ import type { ProduceContext } from "../../Random/Types";
4
+ import { type SatisfiesThis } from "../../Schema/Satisfies";
5
+ import type * as tuple from "../tuple/Types";
6
+ import type { Core, From, Resolved, Source } from "./Types";
7
+ /**
8
+ * What `T.derive({ to, from })` returns: not yet a Schema — `.as(resolve)` is
9
+ * what produces one, matching `compute(source).as(resolve)`. There is no
10
+ * re-`.as()` on the Schema; the resolver fully determines production.
11
+ */
12
+ export type Deriver<$From extends From, $To extends Source> = {
13
+ /**
14
+ * Supply the function that turns `from`'s fabricated values into the result
15
+ * `to` names. `values` is the positional tuple of those values; `context` is
16
+ * this node's own `{ random, clock }`, so any extra draw still replays under
17
+ * a salt.
18
+ */
19
+ as: (resolve: (values: tuple.Fabricated<$From>, context: ProduceContext) => NoInfer<Resolved<$To>>) => Schema<$From, $To>;
20
+ };
21
+ /**
22
+ * Buildable `derive` recipe: a value computed from other schemas' fabricated
23
+ * output. `from` is fabricated independently (one Fabricator per slot, like
24
+ * `tuple`); `to` declares only the result's type and shape. See `Fabricator.ts`
25
+ * for the mismatch check against `to`.
26
+ */
27
+ export interface Schema<$From extends From = From, $To extends Source = Source, $Adaptations extends Adaptations = {}> extends Core<$From, $To, $Adaptations> {
28
+ /**
29
+ * Check that this schema's fabricated value type is assignable to `$Target`.
30
+ * Identity at runtime; the target is not carried into later chained calls —
31
+ * see `object/Schema.ts`'s `satisfies`. The produced type is `to`'s
32
+ * (`Resolved<$To>`), not `from`'s.
33
+ */
34
+ satisfies<$Target>(this: this & SatisfiesThis<Resolved<$To>, $Target>): Schema<$From, $To, $Adaptations>;
35
+ /**
36
+ * Override what this schema maps to in one or more external schema libraries
37
+ * — see `string/Schema.ts`'s `adapt` for the full contract. An unadapted
38
+ * derive maps to whatever `to` maps to, honoring any adaptation already on
39
+ * `to`. Adapting the derive itself overrides that, which is how to say the
40
+ * derive's mapping differs from `to`'s.
41
+ */
42
+ adapt: <const $Adapter extends Adapter, $Returnable extends ReturnType<$Adapter["convert"]>>(adapter: $Adapter, produce: (adapting: Adapting<Schema<$From, $To, $Adaptations>>) => $Returnable) => Schema<$From, $To, WithAdaptations<$Adaptations, AdaptationEntry<$Adapter, $Returnable>>>;
43
+ }
44
+ export declare function Schema<$From extends From, $To extends Source, $Adaptations extends Adaptations = {}>(schema: Core<$From, $To, $Adaptations>): Schema<$From, $To, $Adaptations>;
@@ -0,0 +1,38 @@
1
+ import type { Adaptations } from "../../Adapter/Types";
2
+ import type { ProduceContext } from "../../Random/Types";
3
+ import type { Adaptation, Kind, Meta, Produces } from "../../Types";
4
+ import type { Resolved, Source } from "../object/compute/Types";
5
+ import type * as tuple from "../tuple/Types";
6
+ /**
7
+ * `from` is a tuple of schemas, one per input slot — the same shape
8
+ * `tuple.Items` already is, so `tuple.Fabricated` can type `resolve`'s `values`
9
+ * as a positional `[A, B]` rather than `(A | B)[]`.
10
+ */
11
+ export type From = tuple.Items;
12
+ /**
13
+ * Re-exported so this kind's other files (and `Primitive.derive.Source`) name
14
+ * the same `to` contract `object.compute` uses, rather than restating it.
15
+ */
16
+ export type { Denoted, Resolved, Source } from "../object/compute/Types";
17
+ /**
18
+ * `from` is stored after `toSchema` (inert per-slot schemas, same as `tuple`).
19
+ * `to` is stored exactly as given, whether a Schema or a builder, so its
20
+ * `[Meta]` and `[Adaptation]` survive: adapters convert it as a nested schema
21
+ * (honoring its own adaptation unless the derive is adapted), and `toValueKind`
22
+ * follows it to the kind a result or override is checked against. `resolve` is
23
+ * plain data from the moment `.as(resolve)` is called. `to` is only used for
24
+ * its shape/type — the value comes entirely from `resolve`, which is why `to`
25
+ * may not even have a buildable recipe (a bare `T.string`/`T.bigint`).
26
+ */
27
+ export type Meta<$From extends From = From, $To extends Source = Source> = {
28
+ from: $From;
29
+ to: $To;
30
+ resolve: (values: tuple.Fabricated<$From>, context: ProduceContext) => Resolved<$To>;
31
+ };
32
+ export interface Core<$From extends From = From, $To extends Source = Source, $Adaptations extends Adaptations = {}> {
33
+ [Kind]: "derive";
34
+ [Meta]: Meta<$From, $To>;
35
+ bindings?: unknown[];
36
+ readonly [Produces]?: Resolved<$To, NonNullable<this["bindings"]>>;
37
+ readonly [Adaptation]?: $Adaptations;
38
+ }
@@ -0,0 +1,5 @@
1
+ export * from "./Types";
2
+ export * from "./Schema";
3
+ export * from "./Fabricator";
4
+ export * from "./Registry";
5
+ export { default } from "./Registry";
@@ -13,14 +13,24 @@ type Weighted<$Items extends ReadonlyArray<Item>> = {
13
13
  [$K in keyof $Items]: readonly [number, $Items[$K]];
14
14
  };
15
15
  /**
16
- * At least one element — an empty `enum` has no member to draw, which would
17
- * otherwise fail inside `weighted()` (`Distribution/index.ts`) with an opaque
18
- * `TypeError` at fabricate time (weight sum is `0`, so `.find` returns
19
- * `undefined` and `chosen![1]` throws). Rejecting emptiness here is a
20
- * construction-time compile error; the runtime check below is the backstop for
21
- * an `as any` call that bypasses it.
16
+ * At least one element — an `enum` with no member has nothing to draw, which
17
+ * would otherwise fail inside `weighted()` (`Distribution/index.ts`) with an
18
+ * opaque `TypeError` at fabricate time (weight sum is `0`, so `.find` returns
19
+ * `undefined` and `chosen![1]` throws).
20
+ *
21
+ * Only a _statically_ empty tuple (a literal `[]`) is a compile error. A
22
+ * dynamically built array — e.g. `.map()` over an `as const` array — is
23
+ * accepted: its element union survives but its arity doesn't, so it can't be
24
+ * proven non-empty and a tuple-shaped `readonly [$T, ...$T[]]` constraint would
25
+ * wrongly reject it. The runtime check below is the backstop for that case, and
26
+ * for an `as any` call.
27
+ *
28
+ * Intersected onto the parameter (`items: $Items & NonEmpty<$Items>`) rather
29
+ * than written as a conditional parameter type (`$Items extends readonly [] ?
30
+ * never : $Items`): the latter blocks `const` inference, widening `["a", "b"]`
31
+ * to `string[]` and losing the tuple `Weighted` depends on.
22
32
  */
23
- type NonEmpty<$T> = readonly [$T, ...$T[]];
33
+ type NonEmpty<$Items extends ReadonlyArray<unknown>> = $Items extends readonly [] ? never : unknown;
24
34
  declare const _default: {
25
35
  /**
26
36
  * Equal probability across every member. Delegates to `weighted` with a
@@ -28,12 +38,12 @@ declare const _default: {
28
38
  * uniform draw when every weight is equal, so there is no separate unweighted
29
39
  * code path to keep in sync.
30
40
  */
31
- uniform: <const $Items extends NonEmpty<Item>>(items: $Items) => Schema<Weighted<$Items>>;
41
+ uniform: <const $Items extends ReadonlyArray<Item>>(items: $Items & NonEmpty<$Items>) => Schema<Weighted<$Items>>;
32
42
  /**
33
43
  * Relative probability across members, given as `[weight, item]` pairs — the
34
44
  * same tuple shape `weighted()` (`Distribution/index.ts`) itself accepts, not
35
45
  * an object keyed by member.
36
46
  */
37
- weighted: <const $Items extends NonEmpty<Items[number]>>(items: $Items) => Schema<$Items>;
47
+ weighted: <const $Items extends Items>(items: $Items & NonEmpty<$Items>) => Schema<$Items>;
38
48
  };
39
49
  export default _default;
@@ -1,6 +1,7 @@
1
1
  import { type AdaptationEntry } from "../../Adapter/Core";
2
2
  import type { Adaptations, Adapter, Adapting, WithAdaptations } from "../../Adapter/Types";
3
3
  import type { Produce } from "../../Random/Types";
4
+ import { type SatisfiesThis } from "../../Schema/Satisfies";
4
5
  import type { Core, Fabricated, Items } from "./Types";
5
6
  /**
6
7
  * The buildable recipe for an `enum`: a weighted set of member values, one of
@@ -14,6 +15,12 @@ export interface Schema<$Items extends Items = Items, $Adaptations extends Adapt
14
15
  * validation of `produce`) still has it to check against.
15
16
  */
16
17
  as: (produce: Produce<Fabricated<$Items>>) => Schema<$Items, $Adaptations>;
18
+ /**
19
+ * Check that this schema's fabricated value type is assignable to `$Target`.
20
+ * Identity at runtime; the target is not carried into later chained calls —
21
+ * see `object/Schema.ts`'s `satisfies`.
22
+ */
23
+ satisfies<$Target>(this: this & SatisfiesThis<Fabricated<$Items>, $Target>): Schema<$Items, $Adaptations>;
17
24
  /**
18
25
  * Override what this schema maps to in one or more external schema libraries
19
26
  * — see `string/Schema.ts`'s `adapt` for the full contract.
@@ -6,6 +6,7 @@ export { default as bigint } from "./bigint";
6
6
  export { default as boolean } from "./boolean";
7
7
  export { default as choice } from "./choice";
8
8
  export { default as date } from "./date";
9
+ export { default as derive } from "./derive";
9
10
  export { default as enum } from "./enum";
10
11
  export { default as null } from "./null";
11
12
  export { default as nullable } from "./nullable";
@@ -23,6 +24,6 @@ export { default as tuple } from "./tuple";
23
24
  export { default as undefinable } from "./undefinable";
24
25
  export { default as undefined } from "./undefined";
25
26
  export { Primitive };
26
- export type Fabricator = Primitive.always.Fabricator<any> | Primitive.array.Fabricator<any> | Primitive.bigint.Fabricator | Primitive.boolean.Fabricator | Primitive.choice.Fabricator<any> | Primitive.date.Fabricator | Primitive.enum.Fabricator<any> | Primitive.null.Fabricator | Primitive.nullable.Fabricator<any> | Primitive.nullish.Fabricator<any> | Primitive.number.Fabricator | Primitive.object.Fabricator<any> | Primitive.object.compute.Fabricator<any, any> | Primitive.object.omittable.Fabricator<any> | Primitive.object.optional.Fabricator<any> | Primitive.opaque.Fabricator<any> | Primitive.record.Fabricator<any> | Primitive.recursive.Fabricator<any> | Primitive.recursive.self.Fabricator<any> | Primitive.string.Fabricator | Primitive.symbol.Fabricator | Primitive.tuple.Fabricator<any> | Primitive.undefined.Fabricator | Primitive.undefinable.Fabricator<any>;
27
- export type Schema = Primitive.always.Schema<any> | Primitive.array.Schema<any> | Primitive.bigint.Schema | Primitive.boolean.Schema | Primitive.choice.Schema<any> | Primitive.date.Schema | Primitive.enum.Schema<any> | Primitive.null.Schema | Primitive.nullable.Schema<any> | Primitive.nullish.Schema<any> | Primitive.number.Schema | Primitive.object.Schema<any> | Primitive.object.compute.Schema<any, any> | Primitive.object.omittable.Schema<any> | Primitive.object.optional.Schema<any> | Primitive.opaque.Schema<any> | Primitive.record.Schema<any, any> | Primitive.recursive.Schema<any> | Primitive.recursive.self.Schema<any> | Primitive.string.Schema | Primitive.symbol.Schema | Primitive.tuple.Schema<any> | Primitive.undefined.Schema | Primitive.undefinable.Schema<any>;
27
+ export type Fabricator = Primitive.always.Fabricator<any> | Primitive.array.Fabricator<any> | Primitive.bigint.Fabricator | Primitive.boolean.Fabricator | Primitive.choice.Fabricator<any> | Primitive.date.Fabricator | Primitive.derive.Fabricator<any> | Primitive.enum.Fabricator<any> | Primitive.null.Fabricator | Primitive.nullable.Fabricator<any> | Primitive.nullish.Fabricator<any> | Primitive.number.Fabricator | Primitive.object.Fabricator<any> | Primitive.object.compute.Fabricator<any, any> | Primitive.object.omittable.Fabricator<any> | Primitive.object.optional.Fabricator<any> | Primitive.opaque.Fabricator<any> | Primitive.record.Fabricator<any> | Primitive.recursive.Fabricator<any> | Primitive.recursive.self.Fabricator<any> | Primitive.string.Fabricator | Primitive.symbol.Fabricator | Primitive.tuple.Fabricator<any> | Primitive.undefined.Fabricator | Primitive.undefinable.Fabricator<any>;
28
+ export type Schema = Primitive.always.Schema<any> | Primitive.array.Schema<any> | Primitive.bigint.Schema | Primitive.boolean.Schema | Primitive.choice.Schema<any> | Primitive.date.Schema | Primitive.derive.Schema<any, any> | Primitive.enum.Schema<any> | Primitive.null.Schema | Primitive.nullable.Schema<any> | Primitive.nullish.Schema<any> | Primitive.number.Schema | Primitive.object.Schema<any> | Primitive.object.compute.Schema<any, any> | Primitive.object.omittable.Schema<any> | Primitive.object.optional.Schema<any> | Primitive.opaque.Schema<any> | Primitive.record.Schema<any, any> | Primitive.recursive.Schema<any> | Primitive.recursive.self.Schema<any> | Primitive.string.Schema | Primitive.symbol.Schema | Primitive.tuple.Schema<any> | Primitive.undefined.Schema | Primitive.undefinable.Schema<any>;
28
29
  export type Kind = Schema[typeof Kind];
@@ -22,6 +22,7 @@ export * as bigint from "./bigint";
22
22
  export * as boolean from "./boolean";
23
23
  export * as choice from "./choice";
24
24
  export * as date from "./date";
25
+ export * as derive from "./derive";
25
26
  export * as enum from "./enum";
26
27
  export * as null from "./null";
27
28
  export * as nullable from "./nullable";
@@ -1,12 +1,19 @@
1
1
  import { type AdaptationEntry } from "../../Adapter/Core";
2
2
  import type { Adaptations, Adapter, Adapting, WithAdaptations } from "../../Adapter/Types";
3
- import type { Core, Meta as ThisMeta } from "./Types";
3
+ import { type SatisfiesThis } from "../../Schema/Satisfies";
4
+ import type { Core, Fabricated, Meta as ThisMeta } from "./Types";
4
5
  /**
5
6
  * Nothing to configure (see `Types.ts`'s `Meta`), so `adapt` is this kind's
6
- * only builder method — an external library that spells "null" differently
7
+ * only mapping method — an external library that spells "null" differently
7
8
  * still needs a way to say so.
8
9
  */
9
10
  export interface Schema<$Adaptations extends Adaptations = {}> extends Core<ThisMeta, $Adaptations> {
11
+ /**
12
+ * Check that this schema's fabricated value type is assignable to `$Target`.
13
+ * Identity at runtime; the target is not carried into later chained calls —
14
+ * see `object/Schema.ts`'s `satisfies`.
15
+ */
16
+ satisfies<$Target>(this: this & SatisfiesThis<Fabricated, $Target>): Schema<$Adaptations>;
10
17
  /**
11
18
  * Override what this schema maps to in one or more external schema libraries
12
19
  * — see `string/Schema.ts`'s `adapt` for the full contract.
@@ -1,6 +1,7 @@
1
1
  import { type AdaptationEntry } from "../../Adapter/Core";
2
2
  import type { Adaptations, Adapter, Adapting, WithAdaptations } from "../../Adapter/Types";
3
3
  import type { Produce } from "../../Random/Types";
4
+ import { type SatisfiesThis } from "../../Schema/Satisfies";
4
5
  import type { AnySchema } from "../../Schema/Types";
5
6
  import type { Core, Definition, Fabricated, Weights } from "./Types";
6
7
  /**
@@ -16,6 +17,12 @@ export interface Schema<$Definition extends Definition = Definition, $Adaptation
16
17
  * does.
17
18
  */
18
19
  as: (produce: Produce<Fabricated<$Definition>>) => Schema<$Definition, $Adaptations>;
20
+ /**
21
+ * Check that this schema's fabricated value type is assignable to `$Target`.
22
+ * Identity at runtime; the target is not carried into later chained calls —
23
+ * see `object/Schema.ts`'s `satisfies`.
24
+ */
25
+ satisfies<$Target>(this: this & SatisfiesThis<Fabricated<$Definition>, $Target>): Schema<$Definition, $Adaptations>;
19
26
  /**
20
27
  * Reweight the built-in 50/50 roll. Keys are optional — an omitted key keeps
21
28
  * baseline weight `1`, the same weight the 50/50 split already uses — but
@@ -1,6 +1,7 @@
1
1
  import { type AdaptationEntry } from "../../Adapter/Core";
2
2
  import type { Adaptations, Adapter, Adapting, WithAdaptations } from "../../Adapter/Types";
3
3
  import type { Produce } from "../../Random/Types";
4
+ import { type SatisfiesThis } from "../../Schema/Satisfies";
4
5
  import type { AnySchema } from "../../Schema/Types";
5
6
  import type { Core, Definition, Fabricated, Weights } from "./Types";
6
7
  /**
@@ -16,6 +17,12 @@ export interface Schema<$Definition extends Definition = Definition, $Adaptation
16
17
  * built-in three-way roll does.
17
18
  */
18
19
  as: (produce: Produce<Fabricated<$Definition>>) => Schema<$Definition, $Adaptations>;
20
+ /**
21
+ * Check that this schema's fabricated value type is assignable to `$Target`.
22
+ * Identity at runtime; the target is not carried into later chained calls —
23
+ * see `object/Schema.ts`'s `satisfies`.
24
+ */
25
+ satisfies<$Target>(this: this & SatisfiesThis<Fabricated<$Definition>, $Target>): Schema<$Definition, $Adaptations>;
19
26
  /**
20
27
  * Reweight the built-in three-way roll. Keys are optional — an omitted key
21
28
  * keeps baseline weight `1`, the same weight the uniform 1/3 split already
@@ -1,6 +1,7 @@
1
1
  import { type AdaptationEntry } from "../../Adapter/Core";
2
2
  import type { Adaptations, Adapter, Adapting, WithAdaptations } from "../../Adapter/Types";
3
3
  import type { Produce } from "../../Random/Types";
4
+ import { type SatisfiesThis } from "../../Schema/Satisfies";
4
5
  import type { Core, Fabricated, JsonSchema, Meta as ThisMeta } from "./Types";
5
6
  /**
6
7
  * Buildable `number` recipe: a range/distribution (`whereby`, absent for the
@@ -22,6 +23,12 @@ export interface Schema<$Meta extends ThisMeta = ThisMeta, $Adaptations extends
22
23
  * against.
23
24
  */
24
25
  as: (produce: Produce<Fabricated>, hints?: JsonSchema) => Schema<$Meta, $Adaptations>;
26
+ /**
27
+ * Check that this schema's fabricated value type is assignable to `$Target`.
28
+ * Identity at runtime; the target is not carried into later chained calls —
29
+ * see `object/Schema.ts`'s `satisfies`.
30
+ */
31
+ satisfies<$Target>(this: this & SatisfiesThis<Fabricated, $Target>): Schema<$Meta, $Adaptations>;
25
32
  /**
26
33
  * Override what this schema maps to in one or more external schema libraries
27
34
  * — see `string/Schema.ts`'s `adapt` for the full contract.
@@ -1,6 +1,7 @@
1
1
  import type { AdaptationEntry } from "../../Adapter/Core";
2
2
  import type { Adaptations, Adapter, Adapting, WithAdaptations } from "../../Adapter/Types";
3
3
  import type { Produce } from "../../Random/Types";
4
+ import { type SatisfiesThis } from "../../Schema/Satisfies";
4
5
  import type { AnySchema } from "../../Schema/Types";
5
6
  import type { ShallowMerge } from "../../Utility/ShallowMerge";
6
7
  import type { Computer } from "./compute/Schema";
@@ -22,6 +23,14 @@ export interface Schema<$Definition extends Definition = Definition, $Adaptation
22
23
  * against.
23
24
  */
24
25
  as: (produce: Produce<Fabricated<$Definition>>) => Schema<$Definition, $Adaptations>;
26
+ /**
27
+ * Check that this schema's fabricated value type is assignable to `$Target`.
28
+ * Identity at runtime; the target is not carried into later chained calls.
29
+ * Canonical `.satisfies`; every other kind's method is the same and points
30
+ * here. See `Schema/Satisfies.ts` for the `this`-param signature and why the
31
+ * alternatives fail.
32
+ */
33
+ satisfies<$Target>(this: this & SatisfiesThis<Fabricated<$Definition>, $Target>): Schema<$Definition, $Adaptations>;
25
34
  /**
26
35
  * Override what this schema maps to in one or more external schema libraries
27
36
  * — see `string/Schema.ts`'s `adapt` for the full contract. Carried through
@@ -35,7 +44,8 @@ export interface Schema<$Definition extends Definition = Definition, $Adaptation
35
44
  * `make` alongside `extend`/`refine`/`override`: those three rebuild from
36
45
  * `definition`/`refinements` rather than deriving from this object, so the
37
46
  * adaptation map has to be threaded through `make` itself or chaining one of
38
- * them would drop it (see `make`'s `adapt`).
47
+ * them would drop it (see `make`'s `adapt`). `as` and `satisfies` are the
48
+ * methods this factory attaches, so they are what the parameter omits.
39
49
  */
40
- export declare function Schema<$Definition extends Definition, $Adaptations extends Adaptations = {}>(schema: Omit<Schema<$Definition, $Adaptations>, "as">): Schema<$Definition, $Adaptations>;
50
+ export declare function Schema<$Definition extends Definition, $Adaptations extends Adaptations = {}>(schema: Omit<Schema<$Definition, $Adaptations>, "as" | "satisfies">): Schema<$Definition, $Adaptations>;
41
51
  export declare function isObjectSchema(candidate: AnySchema): candidate is Schema;
@@ -1,6 +1,7 @@
1
1
  import { type AdaptationEntry } from "../../../Adapter/Core";
2
2
  import type { Adaptations, Adapter, Adapting, WithAdaptations } from "../../../Adapter/Types";
3
3
  import type { AnySchema } from "../../../Schema/Types";
4
+ import { type SatisfiesThis } from "../../../Schema/Satisfies";
4
5
  import type * as object from "../Types";
5
6
  import type { Core, Resolved, Source } from "./Types";
6
7
  export type Computer<$Definition extends object.Definition> = <const $Source extends Source>(source: $Source) => {
@@ -9,6 +10,13 @@ export type Computer<$Definition extends object.Definition> = <const $Source ext
9
10
  }) => NoInfer<Resolved<$Source>>) => Schema<object.Fabricated<$Definition>, $Source>;
10
11
  };
11
12
  export interface Schema<$Fabricated, $Source extends Source, $Adaptations extends Adaptations = {}> extends Core<$Fabricated, $Source, $Adaptations> {
13
+ /**
14
+ * Check that this schema's fabricated value type is assignable to `$Target`.
15
+ * Identity at runtime; the target is not carried into later chained calls —
16
+ * see `object/Schema.ts`'s `satisfies`. The produced type is `source`'s
17
+ * (`Resolved<$Source>`), not the enclosing object's.
18
+ */
19
+ satisfies<$Target>(this: this & SatisfiesThis<Resolved<$Source>, $Target>): Schema<$Fabricated, $Source, $Adaptations>;
12
20
  /**
13
21
  * Override what this schema maps to in one or more external schema libraries
14
22
  * — see `string/Schema.ts`'s `adapt` for the full contract. Adapting the
@@ -1,8 +1,9 @@
1
1
  import { type AdaptationEntry } from "../../../Adapter/Core";
2
2
  import type { Adaptations, Adapter, Adapting, WithAdaptations } from "../../../Adapter/Types";
3
3
  import type { Produce } from "../../../Random/Types";
4
+ import { type SatisfiesThis } from "../../../Schema/Satisfies";
4
5
  import type { AnySchema } from "../../../Schema/Types";
5
- import type { Core, Definition, Resolved, Weights } from "./Types";
6
+ import type { Core, Definition, Fabricated, Resolved, Weights } from "./Types";
6
7
  export interface Schema<$Definition extends Definition = Definition, $Adaptations extends Adaptations = {}> extends Core<$Definition, $Adaptations> {
7
8
  /**
8
9
  * Layer an opaque production on this schema's existing `[Meta]` — carrying
@@ -12,6 +13,14 @@ export interface Schema<$Definition extends Definition = Definition, $Adaptation
12
13
  * built-in roll does.
13
14
  */
14
15
  as: (produce: Produce<Resolved<$Definition>>) => Schema<$Definition, $Adaptations>;
16
+ /**
17
+ * Check that this schema's fabricated value type is assignable to `$Target`.
18
+ * Identity at runtime; the target is not carried into later chained calls —
19
+ * see `object/Schema.ts`'s `satisfies`. The produced type is the wrapped
20
+ * value (not `Omitted`); omission is a fact about the enclosing object's
21
+ * keys, which is why this check lives more usefully on the object.
22
+ */
23
+ satisfies<$Target>(this: this & SatisfiesThis<Fabricated<$Definition>, $Target>): Schema<$Definition, $Adaptations>;
15
24
  /**
16
25
  * Reweight the built-in presence roll. Keys are optional — an omitted key
17
26
  * keeps baseline weight `1`, the same weight the 50/50 split already uses —
@@ -1,8 +1,9 @@
1
1
  import { type AdaptationEntry } from "../../../Adapter/Core";
2
2
  import type { Adaptations, Adapter, Adapting, WithAdaptations } from "../../../Adapter/Types";
3
3
  import type { Produce } from "../../../Random/Types";
4
+ import { type SatisfiesThis } from "../../../Schema/Satisfies";
4
5
  import type { AnySchema } from "../../../Schema/Types";
5
- import type { Core, Definition, Resolved, Weights } from "./Types";
6
+ import type { Core, Definition, Fabricated, Resolved, Weights } from "./Types";
6
7
  export interface Schema<$Definition extends Definition = Definition, $Adaptations extends Adaptations = {}> extends Core<$Definition, $Adaptations> {
7
8
  /**
8
9
  * Layer an opaque production on this schema's existing `[Meta]` — carrying
@@ -12,6 +13,13 @@ export interface Schema<$Definition extends Definition = Definition, $Adaptation
12
13
  * built-in three-way roll does.
13
14
  */
14
15
  as: (produce: Produce<Resolved<$Definition>>) => Schema<$Definition, $Adaptations>;
16
+ /**
17
+ * Check that this schema's fabricated value type is assignable to `$Target`.
18
+ * Identity at runtime; the target is not carried into later chained calls —
19
+ * see `object/Schema.ts`'s `satisfies`. The produced type includes `|
20
+ * undefined`; omission is a fact about the enclosing object's keys.
21
+ */
22
+ satisfies<$Target>(this: this & SatisfiesThis<Fabricated<$Definition>, $Target>): Schema<$Definition, $Adaptations>;
15
23
  /**
16
24
  * Reweight the built-in three-way roll. Keys are optional — an omitted key
17
25
  * keeps baseline weight `1`, the same weight the uniform 1/3 split already
@@ -1,6 +1,7 @@
1
1
  import { type AdaptationEntry } from "../../Adapter/Core";
2
2
  import type { Adaptations, Adapter, Adapting, WithAdaptations } from "../../Adapter/Types";
3
- import type { Core } from "./Types";
3
+ import { type SatisfiesThis } from "../../Schema/Satisfies";
4
+ import type { Core, Fabricated } from "./Types";
4
5
  /**
5
6
  * Escape hatch for values no kind models — a `Map`, a `Set`, a `URL`, a class
6
7
  * instance, a branded type. `produce` is supplied at construction and receives
@@ -12,6 +13,12 @@ import type { Core } from "./Types";
12
13
  * imprecise, and `.adapt(typebox, ...)` is the only way to say more.
13
14
  */
14
15
  export interface Schema<$T = unknown, $Adaptations extends Adaptations = {}> extends Core<$T, $Adaptations> {
16
+ /**
17
+ * Check that this schema's fabricated value type is assignable to `$Target`.
18
+ * Identity at runtime; the target is not carried into later chained calls —
19
+ * see `object/Schema.ts`'s `satisfies`.
20
+ */
21
+ satisfies<$Target>(this: this & SatisfiesThis<Fabricated<$T>, $Target>): Schema<$T, $Adaptations>;
15
22
  /**
16
23
  * Override what this schema maps to in one or more external schema libraries
17
24
  * — see `string/Schema.ts`'s `adapt` for the full contract.
@@ -1,6 +1,7 @@
1
1
  import { type AdaptationEntry } from "../../Adapter/Core";
2
2
  import type { Adaptations, Adapter, Adapting, WithAdaptations } from "../../Adapter/Types";
3
3
  import type { Produce } from "../../Random/Types";
4
+ import { type SatisfiesThis } from "../../Schema/Satisfies";
4
5
  import type { Core, Fabricated, Key, Value } from "./Types";
5
6
  /**
6
7
  * The buildable recipe for a `record`: a key Schema and a value Schema, drawn
@@ -14,6 +15,12 @@ export interface Schema<$Key extends Key = Key, $Value extends Value = Value, $A
14
15
  * (or future validation of `produce`) still has them to check against.
15
16
  */
16
17
  as: (produce: Produce<Fabricated<$Key, $Value>>) => Schema<$Key, $Value, $Adaptations>;
18
+ /**
19
+ * Check that this schema's fabricated value type is assignable to `$Target`.
20
+ * Identity at runtime; the target is not carried into later chained calls —
21
+ * see `object/Schema.ts`'s `satisfies`.
22
+ */
23
+ satisfies<$Target>(this: this & SatisfiesThis<Fabricated<$Key, $Value>, $Target>): Schema<$Key, $Value, $Adaptations>;
17
24
  /**
18
25
  * Override what this schema maps to in one or more external schema libraries
19
26
  * — see `string/Schema.ts`'s `adapt`. Particularly relevant here: a
@@ -48,8 +48,8 @@ export type Fabricated<$Key extends Key = Key, $Value extends Value = Value, $Bi
48
48
  * so. `minTried` is optional, default `0`, matching `string`'s
49
49
  * `whereby.length.min`.
50
50
  *
51
- * No bare-number form (unlike `array`'s `length`): "exactly N" is a promise a
52
- * collapsing key set cannot keep.
51
+ * No bare-number form (unlike `string`'s and `array`'s `length`): "exactly N"
52
+ * is a promise a collapsing key set cannot keep.
53
53
  */
54
54
  export type Whereby = {
55
55
  size: {
@@ -1,6 +1,7 @@
1
1
  import { type AdaptationEntry } from "../../Adapter/Core";
2
2
  import type { Adaptations, Adapter, Adapting, WithAdaptations } from "../../Adapter/Types";
3
- import type { Core } from "./Types";
3
+ import { type SatisfiesThis } from "../../Schema/Satisfies";
4
+ import type { Core, Fabricated } from "./Types";
4
5
  /**
5
6
  * A recursive schema, produced by `.whereby({ depth })` — see `Registry.ts` for
6
7
  * the builder `T.recursive(body)` itself returns. `terminal` is optional there;
@@ -12,6 +13,12 @@ import type { Core } from "./Types";
12
13
  * out, since adding it later is non-breaking.
13
14
  */
14
15
  export interface Schema<$Body = unknown, $Adaptations extends Adaptations = {}> extends Core<$Body, $Adaptations> {
16
+ /**
17
+ * Check that this schema's fabricated value type is assignable to `$Target`.
18
+ * Identity at runtime; the target is not carried into later chained calls —
19
+ * see `object/Schema.ts`'s `satisfies`.
20
+ */
21
+ satisfies<$Target>(this: this & SatisfiesThis<Fabricated<$Body>, $Target>): Schema<$Body, $Adaptations>;
15
22
  /**
16
23
  * Override what this schema maps to in one or more external schema libraries
17
24
  * — see `string/Schema.ts`'s `adapt` for the full contract.
@@ -1,6 +1,7 @@
1
1
  import { type AdaptationEntry } from "../../../Adapter/Core";
2
2
  import type { Adaptations, Adapter, Adapting, WithAdaptations } from "../../../Adapter/Types";
3
- import type { Core } from "./Types";
3
+ import { type SatisfiesThis } from "../../../Schema/Satisfies";
4
+ import type { Core, Fabricated } from "./Types";
4
5
  /**
5
6
  * The placeholder `T.recursive`'s body callback receives in place of the schema
6
7
  * being defined — everywhere `self` appears, it stands for "recurse one level
@@ -15,6 +16,15 @@ import type { Core } from "./Types";
15
16
  * other kind.
16
17
  */
17
18
  export interface Schema<$Adaptations extends Adaptations = {}> extends Core<$Adaptations> {
19
+ /**
20
+ * Check that this schema's fabricated value type is assignable to `$Target`.
21
+ * Identity at runtime; the target is not carried into later chained calls —
22
+ * see `object/Schema.ts`'s `satisfies`. Outside `ValueOf`'s `$Bindings`,
23
+ * `Fabricated` is `unknown` — a `self` has no value of its own. Put
24
+ * `.satisfies` on the enclosing `T.recursive(...).whereby(...)` to check the
25
+ * tree.
26
+ */
27
+ satisfies<$Target>(this: this & SatisfiesThis<Fabricated, $Target>): Schema<$Adaptations>;
18
28
  adapt: <const $Adapter extends Adapter, $Returnable extends ReturnType<$Adapter["convert"]>>(adapter: $Adapter, produce: (adapting: Adapting<Schema<$Adaptations>>) => $Returnable) => Schema<WithAdaptations<$Adaptations, AdaptationEntry<$Adapter, $Returnable>>>;
19
29
  }
20
30
  export declare function Schema<$Adaptations extends Adaptations = {}>(schema: Core<$Adaptations>): Schema<$Adaptations>;
@@ -19,17 +19,21 @@ declare const _default: {
19
19
  hints: JsonSchema | undefined;
20
20
  }>;
21
21
  /**
22
- * A string whose length falls uniformly within `[length.min, length.max]`;
23
- * `length.min` defaults to inclusive 0. Exclusive ends use a Bound object.
22
+ * A string of `length` UTF-16 code units. `length` is a bare `N` (exactly N)
23
+ * or `{ min?, max, distribution? }`. `min` defaults to inclusive 0. Exclusive
24
+ * ends use a Bound object. A bare `N` is stored as min = max = N inclusive
25
+ * and carries no distribution. Without `distribution`, the length is drawn
26
+ * uniformly across the inclusive interval; `distribution` shapes that draw
27
+ * the same way it does for `T.number.integer`.
28
+ *
24
29
  * Pass `composition` to control which characters appear and in what
25
30
  * proportion; without one, characters span all Unicode scalar values (the
26
- * codespace minus surrogates, so always well-formed UTF-16).
27
- *
28
- * `length` counts UTF-16 code units, so the result's `.length` equals the
29
- * chosen length exactly. When the composition cannot fill the final code
30
- * units — e.g. only astral, two-unit characters remain for a one-unit gap —
31
- * the gap is topped up with a well-formed BMP character outside the requested
32
- * `composition`, inserted at a random character boundary.
31
+ * codespace minus surrogates, so always well-formed UTF-16). The result's
32
+ * `.length` equals the chosen length exactly. When the composition cannot
33
+ * fill the final code units — e.g. only astral, two-unit characters remain
34
+ * for a one-unit gap — the gap is topped up with a well-formed BMP character
35
+ * outside the requested `composition`, inserted at a random character
36
+ * boundary.
33
37
  */
34
38
  whereby: (whereby: InputWhereby) => Schema<{
35
39
  whereby: Whereby;
@@ -1,6 +1,7 @@
1
1
  import { type AdaptationEntry } from "../../Adapter/Core";
2
2
  import type { Adaptations, Adapter, Adapting, WithAdaptations } from "../../Adapter/Types";
3
3
  import type { Produce } from "../../Random/Types";
4
+ import { type SatisfiesThis } from "../../Schema/Satisfies";
4
5
  import type { Core, Fabricated, JsonSchema, Meta as ThisMeta } from "./Types";
5
6
  /**
6
7
  * Buildable `string` recipe: length/composition (`whereby` — required, unlike
@@ -19,6 +20,12 @@ export interface Schema<$Meta extends ThisMeta = ThisMeta, $Adaptations extends
19
20
  * validation of `produce`) still has it to check against.
20
21
  */
21
22
  as: (produce: Produce<Fabricated>, hints?: JsonSchema) => Schema<$Meta, $Adaptations>;
23
+ /**
24
+ * Check that this schema's fabricated value type is assignable to `$Target`.
25
+ * Identity at runtime; the target is not carried into later chained calls —
26
+ * see `object/Schema.ts`'s `satisfies`.
27
+ */
28
+ satisfies<$Target>(this: this & SatisfiesThis<Fabricated, $Target>): Schema<$Meta, $Adaptations>;
22
29
  /**
23
30
  * Override what this schema maps to in one external schema library, for a
24
31
  * contract no native kind expresses — a `string` that is really an email, a