effect 3.9.2 → 3.10.1
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/Arbitrary/package.json +6 -0
- package/FastCheck/package.json +6 -0
- package/JSONSchema/package.json +6 -0
- package/ParseResult/package.json +6 -0
- package/Pretty/package.json +6 -0
- package/Schema/package.json +6 -0
- package/SchemaAST/package.json +6 -0
- package/TSubscriptionRef/package.json +6 -0
- package/dist/cjs/Arbitrary.js +490 -0
- package/dist/cjs/Arbitrary.js.map +1 -0
- package/dist/cjs/Effect.js +247 -16
- package/dist/cjs/Effect.js.map +1 -1
- package/dist/cjs/FastCheck.js +17 -0
- package/dist/cjs/FastCheck.js.map +1 -0
- package/dist/cjs/Inspectable.js +43 -3
- package/dist/cjs/Inspectable.js.map +1 -1
- package/dist/cjs/JSONSchema.js +418 -0
- package/dist/cjs/JSONSchema.js.map +1 -0
- package/dist/cjs/ParseResult.js +1539 -0
- package/dist/cjs/ParseResult.js.map +1 -0
- package/dist/cjs/Predicate.js +3 -1
- package/dist/cjs/Predicate.js.map +1 -1
- package/dist/cjs/Pretty.js +183 -0
- package/dist/cjs/Pretty.js.map +1 -0
- package/dist/cjs/Schema.js +5529 -0
- package/dist/cjs/Schema.js.map +1 -0
- package/dist/cjs/SchemaAST.js +2365 -0
- package/dist/cjs/SchemaAST.js.map +1 -0
- package/dist/cjs/Stream.js +17 -3
- package/dist/cjs/Stream.js.map +1 -1
- package/dist/cjs/TPubSub.js +9 -1
- package/dist/cjs/TPubSub.js.map +1 -1
- package/dist/cjs/TQueue.js.map +1 -1
- package/dist/cjs/TRef.js.map +1 -1
- package/dist/cjs/TSubscriptionRef.js +96 -0
- package/dist/cjs/TSubscriptionRef.js.map +1 -0
- package/dist/cjs/index.js +18 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/internal/cause.js +2 -2
- package/dist/cjs/internal/cause.js.map +1 -1
- package/dist/cjs/internal/channel/channelExecutor.js +160 -161
- package/dist/cjs/internal/channel/channelExecutor.js.map +1 -1
- package/dist/cjs/internal/core.js +4 -4
- package/dist/cjs/internal/core.js.map +1 -1
- package/dist/cjs/internal/fiberRuntime.js +14 -12
- package/dist/cjs/internal/fiberRuntime.js.map +1 -1
- package/dist/cjs/internal/logger.js +7 -6
- package/dist/cjs/internal/logger.js.map +1 -1
- package/dist/cjs/internal/redacted.js +4 -0
- package/dist/cjs/internal/redacted.js.map +1 -1
- package/dist/cjs/internal/schema/errors.js +116 -0
- package/dist/cjs/internal/schema/errors.js.map +1 -0
- package/dist/cjs/internal/schema/filters.js +41 -0
- package/dist/cjs/internal/schema/filters.js.map +1 -0
- package/dist/cjs/internal/schema/util.js +96 -0
- package/dist/cjs/internal/schema/util.js.map +1 -0
- package/dist/cjs/internal/stm/core.js +2 -3
- package/dist/cjs/internal/stm/core.js.map +1 -1
- package/dist/cjs/internal/stm/tPubSub.js.map +1 -1
- package/dist/cjs/internal/stm/tQueue.js +1 -2
- package/dist/cjs/internal/stm/tQueue.js.map +1 -1
- package/dist/cjs/internal/stm/tRef.js +6 -2
- package/dist/cjs/internal/stm/tRef.js.map +1 -1
- package/dist/cjs/internal/stm/tSubscriptionRef.js +178 -0
- package/dist/cjs/internal/stm/tSubscriptionRef.js.map +1 -0
- package/dist/cjs/internal/stream.js +36 -16
- package/dist/cjs/internal/stream.js.map +1 -1
- package/dist/cjs/internal/version.js +1 -1
- package/dist/cjs/internal/version.js.map +1 -1
- package/dist/dts/Arbitrary.d.ts +45 -0
- package/dist/dts/Arbitrary.d.ts.map +1 -0
- package/dist/dts/Effect.d.ts +298 -30
- package/dist/dts/Effect.d.ts.map +1 -1
- package/dist/dts/FastCheck.d.ts +9 -0
- package/dist/dts/FastCheck.d.ts.map +1 -0
- package/dist/dts/Inspectable.d.ts +28 -0
- package/dist/dts/Inspectable.d.ts.map +1 -1
- package/dist/dts/JSONSchema.d.ts +181 -0
- package/dist/dts/JSONSchema.d.ts.map +1 -0
- package/dist/dts/ParseResult.d.ts +551 -0
- package/dist/dts/ParseResult.d.ts.map +1 -0
- package/dist/dts/Predicate.d.ts.map +1 -1
- package/dist/dts/Pretty.d.ts +26 -0
- package/dist/dts/Pretty.d.ts.map +1 -0
- package/dist/dts/Schema.d.ts +4562 -0
- package/dist/dts/Schema.d.ts.map +1 -0
- package/dist/dts/SchemaAST.d.ts +1321 -0
- package/dist/dts/SchemaAST.d.ts.map +1 -0
- package/dist/dts/Stream.d.ts +67 -2
- package/dist/dts/Stream.d.ts.map +1 -1
- package/dist/dts/TPubSub.d.ts +8 -0
- package/dist/dts/TPubSub.d.ts.map +1 -1
- package/dist/dts/TQueue.d.ts +7 -7
- package/dist/dts/TQueue.d.ts.map +1 -1
- package/dist/dts/TRef.d.ts +2 -1
- package/dist/dts/TRef.d.ts.map +1 -1
- package/dist/dts/TSubscriptionRef.d.ts +251 -0
- package/dist/dts/TSubscriptionRef.d.ts.map +1 -0
- package/dist/dts/index.d.ts +32 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/fiberRuntime.d.ts.map +1 -1
- package/dist/dts/internal/schema/errors.d.ts +2 -0
- package/dist/dts/internal/schema/errors.d.ts.map +1 -0
- package/dist/dts/internal/schema/filters.d.ts +2 -0
- package/dist/dts/internal/schema/filters.d.ts.map +1 -0
- package/dist/dts/internal/schema/util.d.ts +2 -0
- package/dist/dts/internal/schema/util.d.ts.map +1 -0
- package/dist/dts/internal/stm/tRef.d.ts +3 -1
- package/dist/dts/internal/stm/tRef.d.ts.map +1 -1
- package/dist/dts/internal/stm/tSubscriptionRef.d.ts +2 -0
- package/dist/dts/internal/stm/tSubscriptionRef.d.ts.map +1 -0
- package/dist/dts/internal/stream.d.ts.map +1 -1
- package/dist/esm/Arbitrary.js +472 -0
- package/dist/esm/Arbitrary.js.map +1 -0
- package/dist/esm/Effect.js +256 -18
- package/dist/esm/Effect.js.map +1 -1
- package/dist/esm/FastCheck.js +9 -0
- package/dist/esm/FastCheck.js.map +1 -0
- package/dist/esm/Inspectable.js +39 -2
- package/dist/esm/Inspectable.js.map +1 -1
- package/dist/esm/JSONSchema.js +408 -0
- package/dist/esm/JSONSchema.js.map +1 -0
- package/dist/esm/ParseResult.js +1503 -0
- package/dist/esm/ParseResult.js.map +1 -0
- package/dist/esm/Predicate.js +2 -1
- package/dist/esm/Predicate.js.map +1 -1
- package/dist/esm/Pretty.js +173 -0
- package/dist/esm/Pretty.js.map +1 -0
- package/dist/esm/Schema.js +5328 -0
- package/dist/esm/Schema.js.map +1 -0
- package/dist/esm/SchemaAST.js +2300 -0
- package/dist/esm/SchemaAST.js.map +1 -0
- package/dist/esm/Stream.js +14 -0
- package/dist/esm/Stream.js.map +1 -1
- package/dist/esm/TPubSub.js +8 -0
- package/dist/esm/TPubSub.js.map +1 -1
- package/dist/esm/TQueue.js.map +1 -1
- package/dist/esm/TRef.js.map +1 -1
- package/dist/esm/TSubscriptionRef.js +87 -0
- package/dist/esm/TSubscriptionRef.js.map +1 -0
- package/dist/esm/index.js +32 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/cause.js +3 -3
- package/dist/esm/internal/cause.js.map +1 -1
- package/dist/esm/internal/channel/channelExecutor.js +160 -161
- package/dist/esm/internal/channel/channelExecutor.js.map +1 -1
- package/dist/esm/internal/core.js +4 -4
- package/dist/esm/internal/core.js.map +1 -1
- package/dist/esm/internal/fiberRuntime.js +14 -12
- package/dist/esm/internal/fiberRuntime.js.map +1 -1
- package/dist/esm/internal/logger.js +7 -6
- package/dist/esm/internal/logger.js.map +1 -1
- package/dist/esm/internal/redacted.js +4 -0
- package/dist/esm/internal/redacted.js.map +1 -1
- package/dist/esm/internal/schema/errors.js +87 -0
- package/dist/esm/internal/schema/errors.js.map +1 -0
- package/dist/esm/internal/schema/filters.js +35 -0
- package/dist/esm/internal/schema/filters.js.map +1 -0
- package/dist/esm/internal/schema/util.js +78 -0
- package/dist/esm/internal/schema/util.js.map +1 -0
- package/dist/esm/internal/stm/core.js +1 -2
- package/dist/esm/internal/stm/core.js.map +1 -1
- package/dist/esm/internal/stm/tPubSub.js.map +1 -1
- package/dist/esm/internal/stm/tQueue.js +1 -2
- package/dist/esm/internal/stm/tQueue.js.map +1 -1
- package/dist/esm/internal/stm/tRef.js +5 -1
- package/dist/esm/internal/stm/tRef.js.map +1 -1
- package/dist/esm/internal/stm/tSubscriptionRef.js +166 -0
- package/dist/esm/internal/stm/tSubscriptionRef.js.map +1 -0
- package/dist/esm/internal/stream.js +33 -15
- package/dist/esm/internal/stream.js.map +1 -1
- package/dist/esm/internal/version.js +1 -1
- package/dist/esm/internal/version.js.map +1 -1
- package/package.json +68 -1
- package/src/Arbitrary.ts +563 -0
- package/src/Effect.ts +302 -31
- package/src/FastCheck.ts +9 -0
- package/src/Inspectable.ts +56 -2
- package/src/JSONSchema.ts +601 -0
- package/src/ParseResult.ts +2027 -0
- package/src/Predicate.ts +3 -1
- package/src/Pretty.ts +204 -0
- package/src/Schema.ts +10388 -0
- package/src/SchemaAST.ts +2827 -0
- package/src/Stream.ts +77 -9
- package/src/TPubSub.ts +9 -0
- package/src/TQueue.ts +7 -7
- package/src/TRef.ts +2 -1
- package/src/TSubscriptionRef.ts +284 -0
- package/src/index.ts +40 -0
- package/src/internal/cause.ts +3 -3
- package/src/internal/channel/channelExecutor.ts +213 -214
- package/src/internal/core-effect.ts +2 -2
- package/src/internal/core.ts +4 -4
- package/src/internal/fiberRuntime.ts +14 -12
- package/src/internal/logger.ts +7 -6
- package/src/internal/redacted.ts +4 -0
- package/src/internal/schema/errors.ts +189 -0
- package/src/internal/schema/filters.ts +86 -0
- package/src/internal/schema/util.ts +113 -0
- package/src/internal/stm/core.ts +1 -2
- package/src/internal/stm/tPubSub.ts +1 -0
- package/src/internal/stm/tQueue.ts +2 -2
- package/src/internal/stm/tRef.ts +7 -2
- package/src/internal/stm/tSubscriptionRef.ts +286 -0
- package/src/internal/stream.ts +97 -20
- package/src/internal/version.ts +1 -1
package/src/Arbitrary.ts
ADDED
|
@@ -0,0 +1,563 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since 3.10.0
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as Arr from "./Array.js"
|
|
6
|
+
import * as FastCheck from "./FastCheck.js"
|
|
7
|
+
import * as errors_ from "./internal/schema/errors.js"
|
|
8
|
+
import * as filters_ from "./internal/schema/filters.js"
|
|
9
|
+
import * as util_ from "./internal/schema/util.js"
|
|
10
|
+
import * as Option from "./Option.js"
|
|
11
|
+
import * as Predicate from "./Predicate.js"
|
|
12
|
+
import type * as Schema from "./Schema.js"
|
|
13
|
+
import * as AST from "./SchemaAST.js"
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @category model
|
|
17
|
+
* @since 3.10.0
|
|
18
|
+
*/
|
|
19
|
+
export interface LazyArbitrary<A> {
|
|
20
|
+
(fc: typeof FastCheck): FastCheck.Arbitrary<A>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @category annotations
|
|
25
|
+
* @since 3.10.0
|
|
26
|
+
*/
|
|
27
|
+
export interface ArbitraryGenerationContext {
|
|
28
|
+
readonly depthIdentifier?: string
|
|
29
|
+
readonly maxDepth: number
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @category annotations
|
|
34
|
+
* @since 3.10.0
|
|
35
|
+
*/
|
|
36
|
+
export type ArbitraryAnnotation<A, TypeParameters extends ReadonlyArray<any> = readonly []> = (
|
|
37
|
+
...arbitraries: [
|
|
38
|
+
...{ readonly [K in keyof TypeParameters]: LazyArbitrary<TypeParameters[K]> },
|
|
39
|
+
ctx: ArbitraryGenerationContext
|
|
40
|
+
]
|
|
41
|
+
) => LazyArbitrary<A>
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Returns a LazyArbitrary for the `A` type of the provided schema.
|
|
45
|
+
*
|
|
46
|
+
* @category arbitrary
|
|
47
|
+
* @since 3.10.0
|
|
48
|
+
*/
|
|
49
|
+
export const makeLazy = <A, I, R>(schema: Schema.Schema<A, I, R>): LazyArbitrary<A> =>
|
|
50
|
+
go(schema.ast, { maxDepth: 2 }, [])
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Returns a fast-check Arbitrary for the `A` type of the provided schema.
|
|
54
|
+
*
|
|
55
|
+
* @category arbitrary
|
|
56
|
+
* @since 3.10.0
|
|
57
|
+
*/
|
|
58
|
+
export const make = <A, I, R>(schema: Schema.Schema<A, I, R>): FastCheck.Arbitrary<A> => makeLazy(schema)(FastCheck)
|
|
59
|
+
|
|
60
|
+
const getArbitraryAnnotation = AST.getAnnotation<ArbitraryAnnotation<any, any>>(AST.ArbitraryAnnotationId)
|
|
61
|
+
|
|
62
|
+
const getRefinementFromArbitrary = (
|
|
63
|
+
ast: AST.Refinement,
|
|
64
|
+
ctx: Context,
|
|
65
|
+
path: ReadonlyArray<PropertyKey>
|
|
66
|
+
) => {
|
|
67
|
+
const constraints = combineConstraints(ctx.constraints, getConstraints(ast))
|
|
68
|
+
return go(ast.from, constraints ? { ...ctx, constraints } : ctx, path)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const getSuspendedContext = (
|
|
72
|
+
ctx: Context,
|
|
73
|
+
ast: AST.Suspend
|
|
74
|
+
): Context => {
|
|
75
|
+
if (ctx.depthIdentifier !== undefined) {
|
|
76
|
+
return ctx
|
|
77
|
+
}
|
|
78
|
+
const depthIdentifier = AST.getIdentifierAnnotation(ast).pipe(
|
|
79
|
+
Option.orElse(() => AST.getIdentifierAnnotation(ast.f())),
|
|
80
|
+
Option.getOrElse(() => "SuspendDefaultDepthIdentifier")
|
|
81
|
+
)
|
|
82
|
+
return { ...ctx, depthIdentifier }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const getSuspendedArray = (
|
|
86
|
+
fc: typeof FastCheck,
|
|
87
|
+
depthIdentifier: string,
|
|
88
|
+
maxDepth: number,
|
|
89
|
+
item: FastCheck.Arbitrary<any>,
|
|
90
|
+
constraints?: FastCheck.ArrayConstraints
|
|
91
|
+
) => {
|
|
92
|
+
let minLength = 1
|
|
93
|
+
let maxLength = 2
|
|
94
|
+
if (constraints && constraints.minLength !== undefined && constraints.minLength > minLength) {
|
|
95
|
+
minLength = constraints.minLength
|
|
96
|
+
if (minLength > maxLength) {
|
|
97
|
+
maxLength = minLength
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return fc.oneof(
|
|
101
|
+
{ maxDepth, depthIdentifier },
|
|
102
|
+
fc.constant([]),
|
|
103
|
+
fc.array(item, { minLength, maxLength })
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
interface Context extends ArbitraryGenerationContext {
|
|
108
|
+
readonly constraints?: Constraints
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const go = (
|
|
112
|
+
ast: AST.AST,
|
|
113
|
+
ctx: Context,
|
|
114
|
+
path: ReadonlyArray<PropertyKey>
|
|
115
|
+
): LazyArbitrary<any> => {
|
|
116
|
+
const hook = getArbitraryAnnotation(ast)
|
|
117
|
+
if (Option.isSome(hook)) {
|
|
118
|
+
switch (ast._tag) {
|
|
119
|
+
case "Declaration":
|
|
120
|
+
return hook.value(...ast.typeParameters.map((p) => go(p, ctx, path)), ctx)
|
|
121
|
+
case "Refinement":
|
|
122
|
+
return hook.value(getRefinementFromArbitrary(ast, ctx, path), ctx)
|
|
123
|
+
default:
|
|
124
|
+
return hook.value(ctx)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
switch (ast._tag) {
|
|
128
|
+
case "Declaration": {
|
|
129
|
+
throw new Error(errors_.getArbitraryMissingAnnotationErrorMessage(path, ast))
|
|
130
|
+
}
|
|
131
|
+
case "Literal":
|
|
132
|
+
return (fc) => fc.constant(ast.literal)
|
|
133
|
+
case "UniqueSymbol":
|
|
134
|
+
return (fc) => fc.constant(ast.symbol)
|
|
135
|
+
case "UndefinedKeyword":
|
|
136
|
+
return (fc) => fc.constant(undefined)
|
|
137
|
+
case "NeverKeyword":
|
|
138
|
+
return () => {
|
|
139
|
+
throw new Error(errors_.getArbitraryUnsupportedErrorMessage(path, ast))
|
|
140
|
+
}
|
|
141
|
+
case "UnknownKeyword":
|
|
142
|
+
case "AnyKeyword":
|
|
143
|
+
case "VoidKeyword":
|
|
144
|
+
return (fc) => fc.anything()
|
|
145
|
+
case "StringKeyword":
|
|
146
|
+
return (fc) => {
|
|
147
|
+
if (ctx.constraints) {
|
|
148
|
+
switch (ctx.constraints._tag) {
|
|
149
|
+
case "StringConstraints":
|
|
150
|
+
return fc.string(ctx.constraints.constraints)
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return fc.string()
|
|
154
|
+
}
|
|
155
|
+
case "NumberKeyword":
|
|
156
|
+
return (fc) => {
|
|
157
|
+
if (ctx.constraints) {
|
|
158
|
+
switch (ctx.constraints._tag) {
|
|
159
|
+
case "NumberConstraints":
|
|
160
|
+
return fc.float(ctx.constraints.constraints)
|
|
161
|
+
case "IntegerConstraints":
|
|
162
|
+
return fc.integer(ctx.constraints.constraints)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return fc.float()
|
|
166
|
+
}
|
|
167
|
+
case "BooleanKeyword":
|
|
168
|
+
return (fc) => fc.boolean()
|
|
169
|
+
case "BigIntKeyword":
|
|
170
|
+
return (fc) => {
|
|
171
|
+
if (ctx.constraints) {
|
|
172
|
+
switch (ctx.constraints._tag) {
|
|
173
|
+
case "BigIntConstraints":
|
|
174
|
+
return fc.bigInt(ctx.constraints.constraints)
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return fc.bigInt()
|
|
178
|
+
}
|
|
179
|
+
case "SymbolKeyword":
|
|
180
|
+
return (fc) => fc.string().map((s) => Symbol.for(s))
|
|
181
|
+
case "ObjectKeyword":
|
|
182
|
+
return (fc) => fc.oneof(fc.object(), fc.array(fc.anything()))
|
|
183
|
+
case "TemplateLiteral": {
|
|
184
|
+
return (fc) => {
|
|
185
|
+
const string = fc.string({ maxLength: 5 })
|
|
186
|
+
const number = fc.float({ noDefaultInfinity: true }).filter((n) => !Number.isNaN(n))
|
|
187
|
+
const components: Array<FastCheck.Arbitrary<string | number>> = [fc.constant(ast.head)]
|
|
188
|
+
for (const span of ast.spans) {
|
|
189
|
+
if (AST.isStringKeyword(span.type)) {
|
|
190
|
+
components.push(string)
|
|
191
|
+
} else {
|
|
192
|
+
components.push(number)
|
|
193
|
+
}
|
|
194
|
+
components.push(fc.constant(span.literal))
|
|
195
|
+
}
|
|
196
|
+
return fc.tuple(...components).map((spans) => spans.join(""))
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
case "TupleType": {
|
|
200
|
+
const elements: Array<LazyArbitrary<any>> = []
|
|
201
|
+
let hasOptionals = false
|
|
202
|
+
let i = 0
|
|
203
|
+
for (const element of ast.elements) {
|
|
204
|
+
elements.push(go(element.type, ctx, path.concat(i++)))
|
|
205
|
+
if (element.isOptional) {
|
|
206
|
+
hasOptionals = true
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
const rest = ast.rest.map((annotatedAST) => go(annotatedAST.type, ctx, path))
|
|
210
|
+
return (fc) => {
|
|
211
|
+
// ---------------------------------------------
|
|
212
|
+
// handle elements
|
|
213
|
+
// ---------------------------------------------
|
|
214
|
+
let output = fc.tuple(...elements.map((arb) => arb(fc)))
|
|
215
|
+
if (hasOptionals) {
|
|
216
|
+
const indexes = fc.tuple(
|
|
217
|
+
...ast.elements.map((element) => element.isOptional ? fc.boolean() : fc.constant(true))
|
|
218
|
+
)
|
|
219
|
+
output = output.chain((tuple) =>
|
|
220
|
+
indexes.map((booleans) => {
|
|
221
|
+
for (const [i, b] of booleans.reverse().entries()) {
|
|
222
|
+
if (!b) {
|
|
223
|
+
tuple.splice(booleans.length - i, 1)
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return tuple
|
|
227
|
+
})
|
|
228
|
+
)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// ---------------------------------------------
|
|
232
|
+
// handle rest element
|
|
233
|
+
// ---------------------------------------------
|
|
234
|
+
if (Arr.isNonEmptyReadonlyArray(rest)) {
|
|
235
|
+
const [head, ...tail] = rest
|
|
236
|
+
const item = head(fc)
|
|
237
|
+
const constraints: FastCheck.ArrayConstraints | undefined =
|
|
238
|
+
ctx.constraints && ctx.constraints._tag === "ArrayConstraints"
|
|
239
|
+
? ctx.constraints.constraints
|
|
240
|
+
: undefined
|
|
241
|
+
output = output.chain((as) => {
|
|
242
|
+
return (ctx.depthIdentifier !== undefined
|
|
243
|
+
? getSuspendedArray(fc, ctx.depthIdentifier, ctx.maxDepth, item, constraints)
|
|
244
|
+
: fc.array(item, constraints)).map((rest) => [...as, ...rest])
|
|
245
|
+
})
|
|
246
|
+
// ---------------------------------------------
|
|
247
|
+
// handle post rest elements
|
|
248
|
+
// ---------------------------------------------
|
|
249
|
+
for (let j = 0; j < tail.length; j++) {
|
|
250
|
+
output = output.chain((as) => tail[j](fc).map((a) => [...as, a]))
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return output
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
case "TypeLiteral": {
|
|
258
|
+
const propertySignaturesTypes = ast.propertySignatures.map((ps) => go(ps.type, ctx, path.concat(ps.name)))
|
|
259
|
+
const indexSignatures = ast.indexSignatures.map((is) =>
|
|
260
|
+
[go(is.parameter, ctx, path), go(is.type, ctx, path)] as const
|
|
261
|
+
)
|
|
262
|
+
return (fc) => {
|
|
263
|
+
const arbs: any = {}
|
|
264
|
+
const requiredKeys: Array<PropertyKey> = []
|
|
265
|
+
// ---------------------------------------------
|
|
266
|
+
// handle property signatures
|
|
267
|
+
// ---------------------------------------------
|
|
268
|
+
for (let i = 0; i < propertySignaturesTypes.length; i++) {
|
|
269
|
+
const ps = ast.propertySignatures[i]
|
|
270
|
+
const name = ps.name
|
|
271
|
+
if (!ps.isOptional) {
|
|
272
|
+
requiredKeys.push(name)
|
|
273
|
+
}
|
|
274
|
+
arbs[name] = propertySignaturesTypes[i](fc)
|
|
275
|
+
}
|
|
276
|
+
let output = fc.record<any, any>(arbs, { requiredKeys })
|
|
277
|
+
// ---------------------------------------------
|
|
278
|
+
// handle index signatures
|
|
279
|
+
// ---------------------------------------------
|
|
280
|
+
for (let i = 0; i < indexSignatures.length; i++) {
|
|
281
|
+
const key = indexSignatures[i][0](fc)
|
|
282
|
+
const value = indexSignatures[i][1](fc)
|
|
283
|
+
output = output.chain((o) => {
|
|
284
|
+
const item = fc.tuple(key, value)
|
|
285
|
+
const arr = ctx.depthIdentifier !== undefined ?
|
|
286
|
+
getSuspendedArray(fc, ctx.depthIdentifier, ctx.maxDepth, item) :
|
|
287
|
+
fc.array(item)
|
|
288
|
+
return arr.map((tuples) => ({ ...Object.fromEntries(tuples), ...o }))
|
|
289
|
+
})
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return output
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
case "Union": {
|
|
296
|
+
const types = ast.types.map((member) => go(member, ctx, path))
|
|
297
|
+
return (fc) => fc.oneof(...types.map((arb) => arb(fc)))
|
|
298
|
+
}
|
|
299
|
+
case "Enums": {
|
|
300
|
+
if (ast.enums.length === 0) {
|
|
301
|
+
throw new Error(errors_.getArbitraryEmptyEnumErrorMessage(path))
|
|
302
|
+
}
|
|
303
|
+
return (fc) => fc.oneof(...ast.enums.map(([_, value]) => fc.constant(value)))
|
|
304
|
+
}
|
|
305
|
+
case "Refinement": {
|
|
306
|
+
const from = getRefinementFromArbitrary(ast, ctx, path)
|
|
307
|
+
return (fc) => from(fc).filter((a) => Option.isNone(ast.filter(a, AST.defaultParseOption, ast)))
|
|
308
|
+
}
|
|
309
|
+
case "Suspend": {
|
|
310
|
+
const get = util_.memoizeThunk(() => {
|
|
311
|
+
return go(ast.f(), getSuspendedContext(ctx, ast), path)
|
|
312
|
+
})
|
|
313
|
+
return (fc) => fc.constant(null).chain(() => get()(fc))
|
|
314
|
+
}
|
|
315
|
+
case "Transformation":
|
|
316
|
+
return go(ast.to, ctx, path)
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/** @internal */
|
|
321
|
+
export class NumberConstraints {
|
|
322
|
+
readonly _tag = "NumberConstraints"
|
|
323
|
+
readonly constraints: FastCheck.FloatConstraints
|
|
324
|
+
constructor(options: {
|
|
325
|
+
readonly min?: number | undefined
|
|
326
|
+
readonly max?: number | undefined
|
|
327
|
+
readonly noNaN?: boolean | undefined
|
|
328
|
+
readonly noDefaultInfinity?: boolean | undefined
|
|
329
|
+
}) {
|
|
330
|
+
this.constraints = {}
|
|
331
|
+
if (Predicate.isNumber(options.min)) {
|
|
332
|
+
this.constraints.min = Math.fround(options.min)
|
|
333
|
+
}
|
|
334
|
+
if (Predicate.isNumber(options.max)) {
|
|
335
|
+
this.constraints.max = Math.fround(options.max)
|
|
336
|
+
}
|
|
337
|
+
if (Predicate.isBoolean(options.noNaN)) {
|
|
338
|
+
this.constraints.noNaN = options.noNaN
|
|
339
|
+
}
|
|
340
|
+
if (Predicate.isBoolean(options.noDefaultInfinity)) {
|
|
341
|
+
this.constraints.noDefaultInfinity = options.noDefaultInfinity
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/** @internal */
|
|
347
|
+
export class StringConstraints {
|
|
348
|
+
readonly _tag = "StringConstraints"
|
|
349
|
+
readonly constraints: FastCheck.StringSharedConstraints
|
|
350
|
+
constructor(options: {
|
|
351
|
+
readonly minLength?: number | undefined
|
|
352
|
+
readonly maxLength?: number | undefined
|
|
353
|
+
}) {
|
|
354
|
+
this.constraints = {}
|
|
355
|
+
if (Predicate.isNumber(options.minLength)) {
|
|
356
|
+
this.constraints.minLength = options.minLength
|
|
357
|
+
}
|
|
358
|
+
if (Predicate.isNumber(options.maxLength)) {
|
|
359
|
+
this.constraints.maxLength = options.maxLength
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/** @internal */
|
|
365
|
+
export class IntegerConstraints {
|
|
366
|
+
readonly _tag = "IntegerConstraints"
|
|
367
|
+
readonly constraints: FastCheck.IntegerConstraints
|
|
368
|
+
constructor(options: {
|
|
369
|
+
readonly min?: number | undefined
|
|
370
|
+
readonly max?: number | undefined
|
|
371
|
+
}) {
|
|
372
|
+
this.constraints = {}
|
|
373
|
+
if (Predicate.isNumber(options.min)) {
|
|
374
|
+
this.constraints.min = options.min
|
|
375
|
+
}
|
|
376
|
+
if (Predicate.isNumber(options.max)) {
|
|
377
|
+
this.constraints.max = options.max
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/** @internal */
|
|
383
|
+
export class ArrayConstraints {
|
|
384
|
+
readonly _tag = "ArrayConstraints"
|
|
385
|
+
readonly constraints: FastCheck.ArrayConstraints
|
|
386
|
+
constructor(options: {
|
|
387
|
+
readonly minLength?: number | undefined
|
|
388
|
+
readonly maxLength?: number | undefined
|
|
389
|
+
}) {
|
|
390
|
+
this.constraints = {}
|
|
391
|
+
if (Predicate.isNumber(options.minLength)) {
|
|
392
|
+
this.constraints.minLength = options.minLength
|
|
393
|
+
}
|
|
394
|
+
if (Predicate.isNumber(options.maxLength)) {
|
|
395
|
+
this.constraints.maxLength = options.maxLength
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/** @internal */
|
|
401
|
+
export class BigIntConstraints {
|
|
402
|
+
readonly _tag = "BigIntConstraints"
|
|
403
|
+
readonly constraints: FastCheck.BigIntConstraints
|
|
404
|
+
constructor(options: {
|
|
405
|
+
readonly min?: bigint | undefined
|
|
406
|
+
readonly max?: bigint | undefined
|
|
407
|
+
}) {
|
|
408
|
+
this.constraints = {}
|
|
409
|
+
if (Predicate.isBigInt(options.min)) {
|
|
410
|
+
this.constraints.min = options.min
|
|
411
|
+
}
|
|
412
|
+
if (Predicate.isBigInt(options.max)) {
|
|
413
|
+
this.constraints.max = options.max
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/** @internal */
|
|
419
|
+
export type Constraints =
|
|
420
|
+
| NumberConstraints
|
|
421
|
+
| StringConstraints
|
|
422
|
+
| IntegerConstraints
|
|
423
|
+
| ArrayConstraints
|
|
424
|
+
| BigIntConstraints
|
|
425
|
+
|
|
426
|
+
/** @internal */
|
|
427
|
+
export const getConstraints = (ast: AST.Refinement): Constraints | undefined => {
|
|
428
|
+
const TypeAnnotationId = ast.annotations[AST.SchemaIdAnnotationId]
|
|
429
|
+
const jsonSchema: any = ast.annotations[AST.JSONSchemaAnnotationId]
|
|
430
|
+
switch (TypeAnnotationId) {
|
|
431
|
+
// int
|
|
432
|
+
case filters_.IntSchemaId:
|
|
433
|
+
return new IntegerConstraints({})
|
|
434
|
+
// number
|
|
435
|
+
case filters_.GreaterThanSchemaId:
|
|
436
|
+
case filters_.GreaterThanOrEqualToSchemaId:
|
|
437
|
+
case filters_.LessThanSchemaId:
|
|
438
|
+
case filters_.LessThanOrEqualToSchemaId:
|
|
439
|
+
case filters_.BetweenSchemaId:
|
|
440
|
+
return new NumberConstraints({
|
|
441
|
+
min: jsonSchema.exclusiveMinimum ?? jsonSchema.minimum,
|
|
442
|
+
max: jsonSchema.exclusiveMaximum ?? jsonSchema.maximum
|
|
443
|
+
})
|
|
444
|
+
// bigint
|
|
445
|
+
case filters_.GreaterThanBigintSchemaId:
|
|
446
|
+
case filters_.GreaterThanOrEqualToBigIntSchemaId:
|
|
447
|
+
case filters_.LessThanBigIntSchemaId:
|
|
448
|
+
case filters_.LessThanOrEqualToBigIntSchemaId:
|
|
449
|
+
case filters_.BetweenBigintSchemaId: {
|
|
450
|
+
const constraints: any = ast.annotations[TypeAnnotationId]
|
|
451
|
+
return new BigIntConstraints(constraints)
|
|
452
|
+
}
|
|
453
|
+
// string
|
|
454
|
+
case filters_.MinLengthSchemaId:
|
|
455
|
+
case filters_.MaxLengthSchemaId:
|
|
456
|
+
case filters_.LengthSchemaId:
|
|
457
|
+
return new StringConstraints(jsonSchema)
|
|
458
|
+
// array
|
|
459
|
+
case filters_.MinItemsSchemaId:
|
|
460
|
+
case filters_.MaxItemsSchemaId:
|
|
461
|
+
case filters_.ItemsCountSchemaId:
|
|
462
|
+
return new ArrayConstraints({
|
|
463
|
+
minLength: jsonSchema.minItems,
|
|
464
|
+
maxLength: jsonSchema.maxItems
|
|
465
|
+
})
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/** @internal */
|
|
470
|
+
export const combineConstraints = (
|
|
471
|
+
c1: Constraints | undefined,
|
|
472
|
+
c2: Constraints | undefined
|
|
473
|
+
): Constraints | undefined => {
|
|
474
|
+
if (c1 === undefined) {
|
|
475
|
+
return c2
|
|
476
|
+
}
|
|
477
|
+
if (c2 === undefined) {
|
|
478
|
+
return c1
|
|
479
|
+
}
|
|
480
|
+
switch (c1._tag) {
|
|
481
|
+
case "ArrayConstraints": {
|
|
482
|
+
switch (c2._tag) {
|
|
483
|
+
case "ArrayConstraints":
|
|
484
|
+
return new ArrayConstraints({
|
|
485
|
+
minLength: getMax(c1.constraints.minLength, c2.constraints.minLength),
|
|
486
|
+
maxLength: getMin(c1.constraints.maxLength, c2.constraints.maxLength)
|
|
487
|
+
})
|
|
488
|
+
}
|
|
489
|
+
break
|
|
490
|
+
}
|
|
491
|
+
case "NumberConstraints": {
|
|
492
|
+
switch (c2._tag) {
|
|
493
|
+
case "NumberConstraints":
|
|
494
|
+
return new NumberConstraints({
|
|
495
|
+
min: getMax(c1.constraints.min, c2.constraints.min),
|
|
496
|
+
max: getMin(c1.constraints.max, c2.constraints.max),
|
|
497
|
+
noNaN: getOr(c1.constraints.noNaN, c2.constraints.noNaN),
|
|
498
|
+
noDefaultInfinity: getOr(c1.constraints.noDefaultInfinity, c2.constraints.noDefaultInfinity)
|
|
499
|
+
})
|
|
500
|
+
case "IntegerConstraints":
|
|
501
|
+
return new IntegerConstraints({
|
|
502
|
+
min: getMax(c1.constraints.min, c2.constraints.min),
|
|
503
|
+
max: getMin(c1.constraints.max, c2.constraints.max)
|
|
504
|
+
})
|
|
505
|
+
}
|
|
506
|
+
break
|
|
507
|
+
}
|
|
508
|
+
case "BigIntConstraints": {
|
|
509
|
+
switch (c2._tag) {
|
|
510
|
+
case "BigIntConstraints":
|
|
511
|
+
return new BigIntConstraints({
|
|
512
|
+
min: getMax(c1.constraints.min, c2.constraints.min),
|
|
513
|
+
max: getMin(c1.constraints.max, c2.constraints.max)
|
|
514
|
+
})
|
|
515
|
+
}
|
|
516
|
+
break
|
|
517
|
+
}
|
|
518
|
+
case "StringConstraints": {
|
|
519
|
+
switch (c2._tag) {
|
|
520
|
+
case "StringConstraints":
|
|
521
|
+
return new StringConstraints({
|
|
522
|
+
minLength: getMax(c1.constraints.minLength, c2.constraints.minLength),
|
|
523
|
+
maxLength: getMin(c1.constraints.maxLength, c2.constraints.maxLength)
|
|
524
|
+
})
|
|
525
|
+
}
|
|
526
|
+
break
|
|
527
|
+
}
|
|
528
|
+
case "IntegerConstraints": {
|
|
529
|
+
switch (c2._tag) {
|
|
530
|
+
case "NumberConstraints":
|
|
531
|
+
case "IntegerConstraints": {
|
|
532
|
+
return new IntegerConstraints({
|
|
533
|
+
min: getMax(c1.constraints.min, c2.constraints.min),
|
|
534
|
+
max: getMin(c1.constraints.max, c2.constraints.max)
|
|
535
|
+
})
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
break
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
const getOr = (a: boolean | undefined, b: boolean | undefined): boolean | undefined => {
|
|
544
|
+
return a === undefined ? b : b === undefined ? a : a || b
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
function getMax(n1: bigint | undefined, n2: bigint | undefined): bigint | undefined
|
|
548
|
+
function getMax(n1: number | undefined, n2: number | undefined): number | undefined
|
|
549
|
+
function getMax(
|
|
550
|
+
n1: bigint | number | undefined,
|
|
551
|
+
n2: bigint | number | undefined
|
|
552
|
+
): bigint | number | undefined {
|
|
553
|
+
return n1 === undefined ? n2 : n2 === undefined ? n1 : n1 <= n2 ? n2 : n1
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
function getMin(n1: bigint | undefined, n2: bigint | undefined): bigint | undefined
|
|
557
|
+
function getMin(n1: number | undefined, n2: number | undefined): number | undefined
|
|
558
|
+
function getMin(
|
|
559
|
+
n1: bigint | number | undefined,
|
|
560
|
+
n2: bigint | number | undefined
|
|
561
|
+
): bigint | number | undefined {
|
|
562
|
+
return n1 === undefined ? n2 : n2 === undefined ? n1 : n1 <= n2 ? n1 : n2
|
|
563
|
+
}
|