1+ export * from 'fast-check'
2+
3+ import * as fc from 'fast-check'
4+ import type { Entries , Force } from '@traversable/registry'
5+ import { symbol as Symbol } from '@traversable/registry'
6+ import type { Guard } from '@traversable/schema-core'
7+
8+ export interface Arbitrary < T = unknown > extends fc . Arbitrary < T > {
9+ readonly [ Symbol . optional ] ?: true
10+ }
11+
12+ export type { typeOf as typeof }
13+ type typeOf < S > = S extends fc . Arbitrary < infer T > ? T : never
14+
15+ /** @internal */
16+ const Object_keys = globalThis . Object . keys
17+ /** @internal */
18+ const Array_isArray = globalThis . Array . isArray
19+ /** @internal */
20+ const isString : Guard < string > = ( u ) : u is never => typeof u === 'string'
21+ /** @internal */
22+ const arrayOf
23+ : < T > ( p : Guard < T > ) => Guard < T [ ] >
24+ = ( p ) => ( u ) : u is never => Array_isArray ( u ) && u . every ( p )
25+ /** @internal */
26+ const has
27+ : < K extends keyof any , T > ( k : K , p : Guard < T > ) => Guard < { [ P in K ] : T } >
28+ = ( k , p ) => ( u : unknown ) : u is never =>
29+ ! ! u &&
30+ typeof u === 'object' &&
31+ Object . hasOwn ( u , k ) &&
32+ p ( u [ k as never ] )
33+
34+ const PATTERN = {
35+ identifier : / ^ [ $ _ a - z A - Z ] [ $ _ a - z A - Z 0 - 9 ] * $ / ,
36+ } as const
37+
38+ /** @internal */
39+ type Keyword = keyof typeof KEYWORD
40+ const KEYWORD = {
41+ break : "break" , case : "case" , catch : "catch" , class : "class" , const : "const" ,
42+ continue : "continue" , debugger : "debugger" , default : "default" , delete : "delete" ,
43+ do : "do" , else : "else" , export : "export" , extends : "extends" , false : "false" ,
44+ finally : "finally" , for : "for" , function : "function" , if : "if" , import : "import" ,
45+ in : "in" , instanceof : "instanceof" , new : "new" , null : "null" , return : "return" ,
46+ super : "super" , switch : "switch" , this : "this" , throw : "throw" , true : "true" ,
47+ try : "try" , typeof : "typeof" , var : "var" , void : "void" , while : "while" ,
48+ with : "with" , let : "let" , static : "static" , yield : "yield" ,
49+ } as const satisfies Record < string , string >
50+
51+ export type UniqueArrayDefaults < T = unknown , U = unknown > = fc . UniqueArrayConstraintsRecommended < T , U >
52+
53+ export function identifier ( constraints ?: fc . StringMatchingConstraints ) : fc . Arbitrary < string >
54+ export function identifier ( constraints ?: fc . StringMatchingConstraints ) {
55+ return fc . stringMatching ( PATTERN . identifier , constraints ) //.filter((ident) => !(ident in KEYWORD))
56+ }
57+
58+ export const entries
59+ : < T , U > ( model : fc . Arbitrary < T > , constraints ?: UniqueArrayDefaults < T , U > ) => fc . Arbitrary < Entries < T > >
60+ = ( model , constraints ) => fc . uniqueArray (
61+ fc . tuple ( identifier ( ) , model ) ,
62+ { ...constraints , selector : ( [ k ] ) => k } ,
63+ )
64+
65+ /**
66+ * ### {@link optional `fc.optional`}
67+ */
68+ export function optional < T > ( model : fc . Arbitrary < T > , constraints ?: fc . OneOfConstraints ) : Arbitrary < T >
69+ export function optional < T > ( model : fc . Arbitrary < T > , constraints : fc . OneOfConstraints = { } ) : fc . Arbitrary < T | undefined > {
70+ // const arbitrary = fc.oneof(constraints, model, fc.constant(undefined));
71+ ( model as any ) [ Symbol . optional ] = true ;
72+ return model
73+ // arbitrary
74+ }
75+
76+ export declare namespace record {
77+ type Keep < T , K extends keyof T > = never | { [ P in K ] : T [ P ] }
78+ type Part < T , K extends keyof T = keyof T > = never | { [ P in K ] +?: T [ P ] }
79+ type Forget < T > = never | { [ K in keyof T ] : T [ K ] }
80+ type Require < T , K extends keyof T = never > = [ K ] extends [ never ] ? T : Forget <
81+ & Keep < T , K >
82+ & Part < T , globalThis . Exclude < keyof T , K > >
83+ >
84+ }
85+
86+ export function record <
87+ T extends globalThis . Record < string , fc . Arbitrary < unknown > > ,
88+ _K extends keyof T = keyof T ,
89+ Opt extends
90+ | _K extends _K ? T [ _K ] extends { [ Symbol . optional ] : true } ? _K : never : never
91+ = _K extends _K ? T [ _K ] extends { [ Symbol . optional ] : true } ? _K : never : never ,
92+ Req extends Exclude < _K , Opt > = Exclude < _K , Opt >
93+ > ( model : T ) : fc . Arbitrary < Force <
94+ & { [ K in Opt ] +?: typeOf < T [ K ] > }
95+ & { [ K in Req ] -?: typeOf < T [ K ] > }
96+ > >
97+
98+ export function record < T > ( model : { [ K in keyof T ] : fc . Arbitrary < T [ K ] > } ) : fc . Arbitrary < T >
99+
100+ export function record < T , K extends never > (
101+ model : { [ K in keyof T ] : fc . Arbitrary < T [ K ] > } ,
102+ constraints : { requiredKeys ?: readonly [ ] }
103+ ) : fc . Arbitrary < { [ K in keyof T ] +?: T [ K ] } >
104+
105+ export function record < T , K extends keyof T > (
106+ model : { [ K in keyof T ] : fc . Arbitrary < T [ K ] > } ,
107+ constraints : { requiredKeys ?: K [ ] }
108+ ) : fc . Arbitrary < record . Require < T , K > >
109+
110+ export function record < T , K extends keyof T > (
111+ model : { [ K in keyof T ] : fc . Arbitrary < T [ K ] > } ,
112+ constraints : { withDeletedKeys ?: boolean , requiredKeys ?: never }
113+ ) : fc . Arbitrary < record . Require < T , K > >
114+
115+ export function record < T , K extends keyof T > (
116+ model : { [ K in keyof T ] : fc . Arbitrary < T [ K ] > } ,
117+ constraints : { withDeletedKeys : never , requiredKeys : never }
118+ ) : fc . Arbitrary < record . Require < T , K > >
119+
120+ // export function record<T, K extends keyof T>(
121+ // model: { [K in keyof T]: fc.Arbitrary<T[K]> },
122+ // constraints?: fc.RecordConstraints<T>
123+ // ): fc.Arbitrary<record.Require<T, K>>
124+
125+ export function record (
126+ model : { [ x : string ] : fc . Arbitrary < unknown > } ,
127+ constraints : { requiredKeys ?: readonly string [ ] } = { }
128+ ) {
129+ const keys = Object_keys ( model )
130+ const opt = keys . filter ( ( k ) => ( Symbol . optional in model [ k ] ) )
131+ const requiredKeys = has ( "requiredKeys" , arrayOf ( isString ) ) ( constraints )
132+ ? keys
133+ . filter ( ( k ) => constraints . requiredKeys ?. includes ( k ) )
134+ . filter ( ( k ) => ! opt . includes ( k ) )
135+ : keys
136+ . filter ( ( k ) => ! opt . includes ( k ) )
137+
138+ return fc . record ( model , { ...constraints , requiredKeys } )
139+ }
0 commit comments