effect 3.11.5 → 3.11.7
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/dist/cjs/Arbitrary.js +357 -343
- package/dist/cjs/Arbitrary.js.map +1 -1
- package/dist/cjs/JSONSchema.js +157 -38
- package/dist/cjs/JSONSchema.js.map +1 -1
- package/dist/cjs/Schema.js +49 -33
- package/dist/cjs/Schema.js.map +1 -1
- package/dist/cjs/internal/schema/filters.js +24 -18
- package/dist/cjs/internal/schema/filters.js.map +1 -1
- package/dist/cjs/internal/version.js +1 -1
- package/dist/dts/Arbitrary.d.ts +21 -1
- package/dist/dts/Arbitrary.d.ts.map +1 -1
- package/dist/dts/JSONSchema.d.ts +11 -2
- package/dist/dts/JSONSchema.d.ts.map +1 -1
- package/dist/dts/Schema.d.ts +46 -18
- package/dist/dts/Schema.d.ts.map +1 -1
- package/dist/esm/Arbitrary.js +351 -335
- package/dist/esm/Arbitrary.js.map +1 -1
- package/dist/esm/JSONSchema.js +157 -38
- package/dist/esm/JSONSchema.js.map +1 -1
- package/dist/esm/Schema.js +49 -33
- package/dist/esm/Schema.js.map +1 -1
- package/dist/esm/internal/schema/filters.js +23 -17
- package/dist/esm/internal/schema/filters.js.map +1 -1
- package/dist/esm/internal/version.js +1 -1
- package/package.json +1 -1
- package/src/Arbitrary.ts +410 -361
- package/src/JSONSchema.ts +185 -40
- package/src/Schema.ts +161 -74
- package/src/internal/schema/filters.ts +32 -17
- package/src/internal/version.ts +1 -1
package/dist/cjs/Arbitrary.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.toOp = exports.makeStringConstraints = exports.makeNumberConstraints = exports.makeLazy = exports.makeBigIntConstraints = exports.makeArrayConstraints = exports.make = void 0;
|
|
7
7
|
var Arr = _interopRequireWildcard(require("./Array.js"));
|
|
8
8
|
var FastCheck = _interopRequireWildcard(require("./FastCheck.js"));
|
|
9
9
|
var errors_ = _interopRequireWildcard(require("./internal/schema/errors.js"));
|
|
@@ -37,39 +37,138 @@ exports.makeLazy = makeLazy;
|
|
|
37
37
|
const make = schema => makeLazy(schema)(FastCheck);
|
|
38
38
|
exports.make = make;
|
|
39
39
|
const getArbitraryAnnotation = /*#__PURE__*/AST.getAnnotation(AST.ArbitraryAnnotationId);
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Represents an arbitrary with optional filters.
|
|
42
|
+
*/
|
|
43
|
+
class Succeed {
|
|
44
|
+
lazyArbitrary;
|
|
45
|
+
filters;
|
|
46
|
+
_tag = "Succeed";
|
|
47
|
+
constructor(lazyArbitrary, filters = []) {
|
|
48
|
+
this.lazyArbitrary = lazyArbitrary;
|
|
49
|
+
this.filters = filters;
|
|
50
|
+
}
|
|
51
|
+
toLazyArbitrary() {
|
|
52
|
+
return fc => {
|
|
53
|
+
let out = this.lazyArbitrary(fc);
|
|
54
|
+
for (const f of this.filters) {
|
|
55
|
+
out = out.filter(f);
|
|
56
|
+
}
|
|
57
|
+
return out;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Represents a deferred arbitrary value generator with optional filters.
|
|
63
|
+
*/
|
|
64
|
+
class Deferred {
|
|
65
|
+
config;
|
|
66
|
+
filters;
|
|
67
|
+
_tag = "Deferred";
|
|
68
|
+
constructor(config, filters = []) {
|
|
69
|
+
this.config = config;
|
|
70
|
+
this.filters = filters;
|
|
71
|
+
}
|
|
72
|
+
toLazyArbitrary(ctx, path) {
|
|
73
|
+
const config = this.config;
|
|
74
|
+
switch (config._tag) {
|
|
75
|
+
case "StringConstraints":
|
|
76
|
+
{
|
|
77
|
+
const pattern = config.pattern;
|
|
78
|
+
return pattern !== undefined ? fc => fc.stringMatching(new RegExp(pattern)) : fc => fc.string(config.constraints);
|
|
79
|
+
}
|
|
80
|
+
case "NumberConstraints":
|
|
81
|
+
{
|
|
82
|
+
return config.isInteger ? fc => fc.integer(config.constraints) : fc => fc.float(config.constraints);
|
|
83
|
+
}
|
|
84
|
+
case "BigIntConstraints":
|
|
85
|
+
return fc => fc.bigInt(config.constraints);
|
|
86
|
+
case "ArrayConstraints":
|
|
87
|
+
return goTupleType(config.ast, ctx, path, config.constraints);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/** @internal */
|
|
92
|
+
const makeStringConstraints = options => {
|
|
93
|
+
const out = {
|
|
94
|
+
_tag: "StringConstraints",
|
|
95
|
+
constraints: {}
|
|
96
|
+
};
|
|
97
|
+
if (Predicate.isNumber(options.minLength)) {
|
|
98
|
+
out.constraints.minLength = options.minLength;
|
|
99
|
+
}
|
|
100
|
+
if (Predicate.isNumber(options.maxLength)) {
|
|
101
|
+
out.constraints.maxLength = options.maxLength;
|
|
102
|
+
}
|
|
103
|
+
if (Predicate.isString(options.pattern)) {
|
|
104
|
+
out.pattern = options.pattern;
|
|
105
|
+
}
|
|
106
|
+
return out;
|
|
46
107
|
};
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
108
|
+
/** @internal */
|
|
109
|
+
exports.makeStringConstraints = makeStringConstraints;
|
|
110
|
+
const makeNumberConstraints = options => {
|
|
111
|
+
const out = {
|
|
112
|
+
_tag: "NumberConstraints",
|
|
113
|
+
constraints: {},
|
|
114
|
+
isInteger: options.isInteger ?? false
|
|
115
|
+
};
|
|
116
|
+
if (Predicate.isNumber(options.min)) {
|
|
117
|
+
out.constraints.min = Math.fround(options.min);
|
|
50
118
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
119
|
+
if (Predicate.isBoolean(options.minExcluded)) {
|
|
120
|
+
out.constraints.minExcluded = options.minExcluded;
|
|
121
|
+
}
|
|
122
|
+
if (Predicate.isNumber(options.max)) {
|
|
123
|
+
out.constraints.max = Math.fround(options.max);
|
|
124
|
+
}
|
|
125
|
+
if (Predicate.isBoolean(options.maxExcluded)) {
|
|
126
|
+
out.constraints.maxExcluded = options.maxExcluded;
|
|
127
|
+
}
|
|
128
|
+
if (Predicate.isBoolean(options.noNaN)) {
|
|
129
|
+
out.constraints.noNaN = options.noNaN;
|
|
130
|
+
}
|
|
131
|
+
if (Predicate.isBoolean(options.noDefaultInfinity)) {
|
|
132
|
+
out.constraints.noDefaultInfinity = options.noDefaultInfinity;
|
|
133
|
+
}
|
|
134
|
+
return out;
|
|
135
|
+
};
|
|
136
|
+
/** @internal */
|
|
137
|
+
exports.makeNumberConstraints = makeNumberConstraints;
|
|
138
|
+
const makeBigIntConstraints = options => {
|
|
139
|
+
const out = {
|
|
140
|
+
_tag: "BigIntConstraints",
|
|
141
|
+
constraints: {}
|
|
55
142
|
};
|
|
143
|
+
if (Predicate.isBigInt(options.min)) {
|
|
144
|
+
out.constraints.min = options.min;
|
|
145
|
+
}
|
|
146
|
+
if (Predicate.isBigInt(options.max)) {
|
|
147
|
+
out.constraints.max = options.max;
|
|
148
|
+
}
|
|
149
|
+
return out;
|
|
56
150
|
};
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
151
|
+
/** @internal */
|
|
152
|
+
exports.makeBigIntConstraints = makeBigIntConstraints;
|
|
153
|
+
const makeArrayConstraints = options => {
|
|
154
|
+
const out = {
|
|
155
|
+
_tag: "ArrayConstraints",
|
|
156
|
+
constraints: {}
|
|
157
|
+
};
|
|
158
|
+
if (Predicate.isNumber(options.minLength)) {
|
|
159
|
+
out.constraints.minLength = options.minLength;
|
|
65
160
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
161
|
+
if (Predicate.isNumber(options.maxLength)) {
|
|
162
|
+
out.constraints.maxLength = options.maxLength;
|
|
163
|
+
}
|
|
164
|
+
return out;
|
|
165
|
+
};
|
|
166
|
+
exports.makeArrayConstraints = makeArrayConstraints;
|
|
167
|
+
const makeArrayConfig = (options, ast) => {
|
|
168
|
+
return {
|
|
169
|
+
ast,
|
|
170
|
+
...makeArrayConstraints(options)
|
|
171
|
+
};
|
|
73
172
|
};
|
|
74
173
|
const go = (ast, ctx, path) => {
|
|
75
174
|
const hook = getArbitraryAnnotation(ast);
|
|
@@ -78,152 +177,120 @@ const go = (ast, ctx, path) => {
|
|
|
78
177
|
case "Declaration":
|
|
79
178
|
return hook.value(...ast.typeParameters.map(p => go(p, ctx, path)), ctx);
|
|
80
179
|
case "Refinement":
|
|
81
|
-
|
|
180
|
+
{
|
|
181
|
+
const op = toOp(ast, ctx, path);
|
|
182
|
+
ctx = op._tag === "Deferred" ? {
|
|
183
|
+
...ctx,
|
|
184
|
+
constraints: op.config
|
|
185
|
+
} : ctx;
|
|
186
|
+
const from = go(ast.from, ctx, path);
|
|
187
|
+
return new Succeed(hook.value(from, ctx), op.filters).toLazyArbitrary();
|
|
188
|
+
}
|
|
82
189
|
default:
|
|
83
190
|
return hook.value(ctx);
|
|
84
191
|
}
|
|
85
192
|
}
|
|
193
|
+
if (AST.isDeclaration(ast)) {
|
|
194
|
+
throw new Error(errors_.getArbitraryMissingAnnotationErrorMessage(path, ast));
|
|
195
|
+
}
|
|
196
|
+
const op = toOp(ast, ctx, path);
|
|
197
|
+
switch (op._tag) {
|
|
198
|
+
case "Succeed":
|
|
199
|
+
return op.toLazyArbitrary();
|
|
200
|
+
case "Deferred":
|
|
201
|
+
return new Succeed(op.toLazyArbitrary(ctx, path), op.filters).toLazyArbitrary();
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
const constStringConstraints = /*#__PURE__*/makeStringConstraints({});
|
|
205
|
+
const constNumberConstraints = /*#__PURE__*/makeNumberConstraints({});
|
|
206
|
+
const constBigIntConstraints = /*#__PURE__*/makeBigIntConstraints({});
|
|
207
|
+
/** @internal */
|
|
208
|
+
const toOp = (ast, ctx, path) => {
|
|
86
209
|
switch (ast._tag) {
|
|
87
210
|
case "Declaration":
|
|
88
|
-
|
|
89
|
-
throw new Error(errors_.getArbitraryMissingAnnotationErrorMessage(path, ast));
|
|
90
|
-
}
|
|
211
|
+
return new Succeed(go(ast, ctx, path));
|
|
91
212
|
case "Literal":
|
|
92
|
-
return fc => fc.constant(ast.literal);
|
|
213
|
+
return new Succeed(fc => fc.constant(ast.literal));
|
|
93
214
|
case "UniqueSymbol":
|
|
94
|
-
return fc => fc.constant(ast.symbol);
|
|
215
|
+
return new Succeed(fc => fc.constant(ast.symbol));
|
|
95
216
|
case "UndefinedKeyword":
|
|
96
|
-
return fc => fc.constant(undefined);
|
|
217
|
+
return new Succeed(fc => fc.constant(undefined));
|
|
97
218
|
case "NeverKeyword":
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
};
|
|
219
|
+
throw new Error(errors_.getArbitraryMissingAnnotationErrorMessage(path, ast));
|
|
220
|
+
case "VoidKeyword":
|
|
101
221
|
case "UnknownKeyword":
|
|
102
222
|
case "AnyKeyword":
|
|
103
|
-
|
|
104
|
-
return fc => fc.anything();
|
|
223
|
+
return new Succeed(fc => fc.anything());
|
|
105
224
|
case "StringKeyword":
|
|
106
|
-
return
|
|
107
|
-
if (ctx.constraints) {
|
|
108
|
-
switch (ctx.constraints._tag) {
|
|
109
|
-
case "StringConstraints":
|
|
110
|
-
return fc.string(ctx.constraints.constraints);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return fc.string();
|
|
114
|
-
};
|
|
225
|
+
return new Deferred(constStringConstraints);
|
|
115
226
|
case "NumberKeyword":
|
|
116
|
-
return
|
|
117
|
-
if (ctx.constraints) {
|
|
118
|
-
switch (ctx.constraints._tag) {
|
|
119
|
-
case "NumberConstraints":
|
|
120
|
-
return fc.float(ctx.constraints.constraints);
|
|
121
|
-
case "IntegerConstraints":
|
|
122
|
-
return fc.integer(ctx.constraints.constraints);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
return fc.float();
|
|
126
|
-
};
|
|
227
|
+
return new Deferred(constNumberConstraints);
|
|
127
228
|
case "BooleanKeyword":
|
|
128
|
-
return fc => fc.boolean();
|
|
229
|
+
return new Succeed(fc => fc.boolean());
|
|
129
230
|
case "BigIntKeyword":
|
|
130
|
-
return
|
|
131
|
-
if (ctx.constraints) {
|
|
132
|
-
switch (ctx.constraints._tag) {
|
|
133
|
-
case "BigIntConstraints":
|
|
134
|
-
return fc.bigInt(ctx.constraints.constraints);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
return fc.bigInt();
|
|
138
|
-
};
|
|
231
|
+
return new Deferred(constBigIntConstraints);
|
|
139
232
|
case "SymbolKeyword":
|
|
140
|
-
return fc => fc.string().map(s => Symbol.for(s));
|
|
233
|
+
return new Succeed(fc => fc.string().map(s => Symbol.for(s)));
|
|
141
234
|
case "ObjectKeyword":
|
|
142
|
-
return fc => fc.oneof(fc.object(), fc.array(fc.anything()));
|
|
143
|
-
case "
|
|
235
|
+
return new Succeed(fc => fc.oneof(fc.object(), fc.array(fc.anything())));
|
|
236
|
+
case "Enums":
|
|
144
237
|
{
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
const number = fc.float({
|
|
150
|
-
noDefaultInfinity: true
|
|
151
|
-
}).filter(n => !Number.isNaN(n));
|
|
152
|
-
const components = ast.head !== "" ? [fc.constant(ast.head)] : [];
|
|
153
|
-
const addArb = ast => {
|
|
154
|
-
switch (ast._tag) {
|
|
155
|
-
case "StringKeyword":
|
|
156
|
-
return components.push(string);
|
|
157
|
-
case "NumberKeyword":
|
|
158
|
-
return components.push(number);
|
|
159
|
-
case "Literal":
|
|
160
|
-
return components.push(fc.constant(String(ast.literal)));
|
|
161
|
-
case "Union":
|
|
162
|
-
return ast.types.forEach(addArb);
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
ast.spans.forEach(span => {
|
|
166
|
-
addArb(span.type);
|
|
167
|
-
if (span.literal !== "") {
|
|
168
|
-
components.push(fc.constant(span.literal));
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
return fc.tuple(...components).map(spans => spans.join(""));
|
|
172
|
-
};
|
|
238
|
+
if (ast.enums.length === 0) {
|
|
239
|
+
throw new Error(errors_.getArbitraryEmptyEnumErrorMessage(path));
|
|
240
|
+
}
|
|
241
|
+
return new Succeed(fc => fc.oneof(...ast.enums.map(([_, value]) => fc.constant(value))));
|
|
173
242
|
}
|
|
174
|
-
case "
|
|
175
|
-
{
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
243
|
+
case "TemplateLiteral":
|
|
244
|
+
return new Succeed(fc => {
|
|
245
|
+
const string = fc.string({
|
|
246
|
+
maxLength: 5
|
|
247
|
+
});
|
|
248
|
+
const number = fc.float({
|
|
249
|
+
noDefaultInfinity: true
|
|
250
|
+
}).filter(n => !Number.isNaN(n));
|
|
251
|
+
const components = ast.head !== "" ? [fc.constant(ast.head)] : [];
|
|
252
|
+
const addArb = ast => {
|
|
253
|
+
switch (ast._tag) {
|
|
254
|
+
case "StringKeyword":
|
|
255
|
+
return components.push(string);
|
|
256
|
+
case "NumberKeyword":
|
|
257
|
+
return components.push(number);
|
|
258
|
+
case "Literal":
|
|
259
|
+
return components.push(fc.constant(String(ast.literal)));
|
|
260
|
+
case "Union":
|
|
261
|
+
return ast.types.forEach(addArb);
|
|
183
262
|
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
// ---------------------------------------------
|
|
190
|
-
let output = fc.tuple(...elements.map(arb => arb(fc)));
|
|
191
|
-
if (hasOptionals) {
|
|
192
|
-
const indexes = fc.tuple(...ast.elements.map(element => element.isOptional ? fc.boolean() : fc.constant(true)));
|
|
193
|
-
output = output.chain(tuple => indexes.map(booleans => {
|
|
194
|
-
for (const [i, b] of booleans.reverse().entries()) {
|
|
195
|
-
if (!b) {
|
|
196
|
-
tuple.splice(booleans.length - i, 1);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
return tuple;
|
|
200
|
-
}));
|
|
263
|
+
};
|
|
264
|
+
ast.spans.forEach(span => {
|
|
265
|
+
addArb(span.type);
|
|
266
|
+
if (span.literal !== "") {
|
|
267
|
+
components.push(fc.constant(span.literal));
|
|
201
268
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
// handle post rest elements
|
|
214
|
-
// ---------------------------------------------
|
|
215
|
-
for (let j = 0; j < tail.length; j++) {
|
|
216
|
-
output = output.chain(as => tail[j](fc).map(a => [...as, a]));
|
|
269
|
+
});
|
|
270
|
+
return fc.tuple(...components).map(spans => spans.join(""));
|
|
271
|
+
});
|
|
272
|
+
case "Refinement":
|
|
273
|
+
{
|
|
274
|
+
const from = toOp(ast.from, ctx, path);
|
|
275
|
+
const filters = [...from.filters, a => Option.isNone(ast.filter(a, AST.defaultParseOption, ast))];
|
|
276
|
+
switch (from._tag) {
|
|
277
|
+
case "Succeed":
|
|
278
|
+
{
|
|
279
|
+
return new Succeed(from.lazyArbitrary, filters);
|
|
217
280
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
281
|
+
case "Deferred":
|
|
282
|
+
{
|
|
283
|
+
return new Deferred(merge(from.config, getConstraints(from.config._tag, ast)), filters);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
221
286
|
}
|
|
287
|
+
case "TupleType":
|
|
288
|
+
return new Deferred(makeArrayConfig({}, ast));
|
|
222
289
|
case "TypeLiteral":
|
|
223
290
|
{
|
|
224
291
|
const propertySignaturesTypes = ast.propertySignatures.map(ps => go(ps.type, ctx, path.concat(ps.name)));
|
|
225
292
|
const indexSignatures = ast.indexSignatures.map(is => [go(is.parameter, ctx, path), go(is.type, ctx, path)]);
|
|
226
|
-
return fc => {
|
|
293
|
+
return new Succeed(fc => {
|
|
227
294
|
const arbs = {};
|
|
228
295
|
const requiredKeys = [];
|
|
229
296
|
// ---------------------------------------------
|
|
@@ -256,245 +323,192 @@ const go = (ast, ctx, path) => {
|
|
|
256
323
|
});
|
|
257
324
|
}
|
|
258
325
|
return output;
|
|
259
|
-
};
|
|
326
|
+
});
|
|
260
327
|
}
|
|
261
328
|
case "Union":
|
|
262
329
|
{
|
|
263
330
|
const types = ast.types.map(member => go(member, ctx, path));
|
|
264
|
-
return fc => fc.oneof(...types.map(arb => arb(fc)));
|
|
265
|
-
}
|
|
266
|
-
case "Enums":
|
|
267
|
-
{
|
|
268
|
-
if (ast.enums.length === 0) {
|
|
269
|
-
throw new Error(errors_.getArbitraryEmptyEnumErrorMessage(path));
|
|
270
|
-
}
|
|
271
|
-
return fc => fc.oneof(...ast.enums.map(([_, value]) => fc.constant(value)));
|
|
272
|
-
}
|
|
273
|
-
case "Refinement":
|
|
274
|
-
{
|
|
275
|
-
const from = getRefinementFromArbitrary(ast, ctx, path);
|
|
276
|
-
return fc => from(fc).filter(a => Option.isNone(ast.filter(a, AST.defaultParseOption, ast)));
|
|
331
|
+
return new Succeed(fc => fc.oneof(...types.map(arb => arb(fc))));
|
|
277
332
|
}
|
|
278
333
|
case "Suspend":
|
|
279
334
|
{
|
|
280
335
|
const get = util_.memoizeThunk(() => {
|
|
281
336
|
return go(ast.f(), getSuspendedContext(ctx, ast), path);
|
|
282
337
|
});
|
|
283
|
-
return fc => fc.constant(null).chain(() => get()(fc));
|
|
338
|
+
return new Succeed(fc => fc.constant(null).chain(() => get()(fc)));
|
|
284
339
|
}
|
|
285
340
|
case "Transformation":
|
|
286
|
-
return go(ast.to, ctx, path);
|
|
341
|
+
return new Succeed(go(ast.to, ctx, path));
|
|
287
342
|
}
|
|
288
343
|
};
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
if (Predicate.isNumber(options.max)) {
|
|
299
|
-
this.constraints.max = Math.fround(options.max);
|
|
300
|
-
}
|
|
301
|
-
if (Predicate.isBoolean(options.noNaN)) {
|
|
302
|
-
this.constraints.noNaN = options.noNaN;
|
|
303
|
-
}
|
|
304
|
-
if (Predicate.isBoolean(options.noDefaultInfinity)) {
|
|
305
|
-
this.constraints.noDefaultInfinity = options.noDefaultInfinity;
|
|
344
|
+
exports.toOp = toOp;
|
|
345
|
+
const goTupleType = (ast, ctx, path, constraints) => {
|
|
346
|
+
const elements = [];
|
|
347
|
+
let hasOptionals = false;
|
|
348
|
+
let i = 0;
|
|
349
|
+
for (const element of ast.elements) {
|
|
350
|
+
elements.push(go(element.type, ctx, path.concat(i++)));
|
|
351
|
+
if (element.isOptional) {
|
|
352
|
+
hasOptionals = true;
|
|
306
353
|
}
|
|
307
354
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
}
|
|
324
|
-
/** @internal */
|
|
325
|
-
exports.StringConstraints = StringConstraints;
|
|
326
|
-
class IntegerConstraints {
|
|
327
|
-
_tag = "IntegerConstraints";
|
|
328
|
-
constraints;
|
|
329
|
-
constructor(options) {
|
|
330
|
-
this.constraints = {};
|
|
331
|
-
if (Predicate.isNumber(options.min)) {
|
|
332
|
-
this.constraints.min = options.min;
|
|
333
|
-
}
|
|
334
|
-
if (Predicate.isNumber(options.max)) {
|
|
335
|
-
this.constraints.max = options.max;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
/** @internal */
|
|
340
|
-
exports.IntegerConstraints = IntegerConstraints;
|
|
341
|
-
class ArrayConstraints {
|
|
342
|
-
_tag = "ArrayConstraints";
|
|
343
|
-
constraints;
|
|
344
|
-
constructor(options) {
|
|
345
|
-
this.constraints = {};
|
|
346
|
-
if (Predicate.isNumber(options.minLength)) {
|
|
347
|
-
this.constraints.minLength = options.minLength;
|
|
348
|
-
}
|
|
349
|
-
if (Predicate.isNumber(options.maxLength)) {
|
|
350
|
-
this.constraints.maxLength = options.maxLength;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
/** @internal */
|
|
355
|
-
exports.ArrayConstraints = ArrayConstraints;
|
|
356
|
-
class BigIntConstraints {
|
|
357
|
-
_tag = "BigIntConstraints";
|
|
358
|
-
constraints;
|
|
359
|
-
constructor(options) {
|
|
360
|
-
this.constraints = {};
|
|
361
|
-
if (Predicate.isBigInt(options.min)) {
|
|
362
|
-
this.constraints.min = options.min;
|
|
355
|
+
const rest = ast.rest.map(annotatedAST => go(annotatedAST.type, ctx, path));
|
|
356
|
+
return fc => {
|
|
357
|
+
// ---------------------------------------------
|
|
358
|
+
// handle elements
|
|
359
|
+
// ---------------------------------------------
|
|
360
|
+
let output = fc.tuple(...elements.map(arb => arb(fc)));
|
|
361
|
+
if (hasOptionals) {
|
|
362
|
+
const indexes = fc.tuple(...ast.elements.map(element => element.isOptional ? fc.boolean() : fc.constant(true)));
|
|
363
|
+
output = output.chain(tuple => indexes.map(booleans => {
|
|
364
|
+
for (const [i, b] of booleans.reverse().entries()) {
|
|
365
|
+
if (!b) {
|
|
366
|
+
tuple.splice(booleans.length - i, 1);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return tuple;
|
|
370
|
+
}));
|
|
363
371
|
}
|
|
364
|
-
|
|
365
|
-
|
|
372
|
+
// ---------------------------------------------
|
|
373
|
+
// handle rest element
|
|
374
|
+
// ---------------------------------------------
|
|
375
|
+
if (Arr.isNonEmptyReadonlyArray(rest)) {
|
|
376
|
+
const [head, ...tail] = rest;
|
|
377
|
+
const item = head(fc);
|
|
378
|
+
output = output.chain(as => {
|
|
379
|
+
return (ctx.depthIdentifier !== undefined ? getSuspendedArray(fc, ctx.depthIdentifier, ctx.maxDepth, item, constraints) : fc.array(item, constraints)).map(rest => [...as, ...rest]);
|
|
380
|
+
});
|
|
381
|
+
// ---------------------------------------------
|
|
382
|
+
// handle post rest elements
|
|
383
|
+
// ---------------------------------------------
|
|
384
|
+
for (let j = 0; j < tail.length; j++) {
|
|
385
|
+
output = output.chain(as => tail[j](fc).map(a => [...as, a]));
|
|
386
|
+
}
|
|
366
387
|
}
|
|
367
|
-
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
const getConstraints = ast => {
|
|
388
|
+
return output;
|
|
389
|
+
};
|
|
390
|
+
};
|
|
391
|
+
const getConstraints = (_tag, ast) => {
|
|
372
392
|
const TypeAnnotationId = ast.annotations[AST.SchemaIdAnnotationId];
|
|
373
|
-
const jsonSchema =
|
|
374
|
-
switch (
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
// number
|
|
379
|
-
case filters_.GreaterThanSchemaId:
|
|
380
|
-
case filters_.GreaterThanOrEqualToSchemaId:
|
|
381
|
-
case filters_.LessThanSchemaId:
|
|
382
|
-
case filters_.LessThanOrEqualToSchemaId:
|
|
383
|
-
case filters_.BetweenSchemaId:
|
|
384
|
-
return new NumberConstraints({
|
|
385
|
-
min: jsonSchema.exclusiveMinimum ?? jsonSchema.minimum,
|
|
386
|
-
max: jsonSchema.exclusiveMaximum ?? jsonSchema.maximum
|
|
387
|
-
});
|
|
388
|
-
// bigint
|
|
389
|
-
case filters_.GreaterThanBigintSchemaId:
|
|
390
|
-
case filters_.GreaterThanOrEqualToBigIntSchemaId:
|
|
391
|
-
case filters_.LessThanBigIntSchemaId:
|
|
392
|
-
case filters_.LessThanOrEqualToBigIntSchemaId:
|
|
393
|
-
case filters_.BetweenBigintSchemaId:
|
|
393
|
+
const jsonSchema = Option.getOrElse(AST.getJSONSchemaAnnotation(ast), () => ({}));
|
|
394
|
+
switch (_tag) {
|
|
395
|
+
case "StringConstraints":
|
|
396
|
+
return makeStringConstraints(jsonSchema);
|
|
397
|
+
case "NumberConstraints":
|
|
394
398
|
{
|
|
395
|
-
|
|
396
|
-
|
|
399
|
+
switch (TypeAnnotationId) {
|
|
400
|
+
case filters_.NonNaNSchemaId:
|
|
401
|
+
return makeNumberConstraints({
|
|
402
|
+
noNaN: true
|
|
403
|
+
});
|
|
404
|
+
default:
|
|
405
|
+
return makeNumberConstraints({
|
|
406
|
+
isInteger: "type" in jsonSchema && jsonSchema.type === "integer",
|
|
407
|
+
noNaN: "type" in jsonSchema && jsonSchema.type === "number" ? true : undefined,
|
|
408
|
+
noDefaultInfinity: "type" in jsonSchema && jsonSchema.type === "number" ? true : undefined,
|
|
409
|
+
min: jsonSchema.exclusiveMinimum ?? jsonSchema.minimum,
|
|
410
|
+
minExcluded: "exclusiveMinimum" in jsonSchema ? true : undefined,
|
|
411
|
+
max: jsonSchema.exclusiveMaximum ?? jsonSchema.maximum,
|
|
412
|
+
maxExcluded: "exclusiveMaximum" in jsonSchema ? true : undefined
|
|
413
|
+
});
|
|
414
|
+
}
|
|
397
415
|
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
case
|
|
401
|
-
|
|
402
|
-
return new StringConstraints(jsonSchema);
|
|
403
|
-
// array
|
|
404
|
-
case filters_.MinItemsSchemaId:
|
|
405
|
-
case filters_.MaxItemsSchemaId:
|
|
406
|
-
case filters_.ItemsCountSchemaId:
|
|
407
|
-
return new ArrayConstraints({
|
|
416
|
+
case "BigIntConstraints":
|
|
417
|
+
return makeBigIntConstraints(ast.annotations[TypeAnnotationId]);
|
|
418
|
+
case "ArrayConstraints":
|
|
419
|
+
return makeArrayConstraints({
|
|
408
420
|
minLength: jsonSchema.minItems,
|
|
409
421
|
maxLength: jsonSchema.maxItems
|
|
410
422
|
});
|
|
411
423
|
}
|
|
412
424
|
};
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
425
|
+
function getMax(n1, n2) {
|
|
426
|
+
return n1 === undefined ? n2 : n2 === undefined ? n1 : n1 <= n2 ? n2 : n1;
|
|
427
|
+
}
|
|
428
|
+
function getMin(n1, n2) {
|
|
429
|
+
return n1 === undefined ? n2 : n2 === undefined ? n1 : n1 <= n2 ? n1 : n2;
|
|
430
|
+
}
|
|
431
|
+
const getOr = (a, b) => {
|
|
432
|
+
return a === undefined ? b : b === undefined ? a : a || b;
|
|
433
|
+
};
|
|
434
|
+
const merge = (c1, c2) => {
|
|
435
|
+
if (c2) {
|
|
436
|
+
switch (c1._tag) {
|
|
437
|
+
case "StringConstraints":
|
|
438
|
+
{
|
|
439
|
+
if (c2._tag === "StringConstraints") {
|
|
440
|
+
return makeStringConstraints({
|
|
428
441
|
minLength: getMax(c1.constraints.minLength, c2.constraints.minLength),
|
|
429
|
-
maxLength: getMin(c1.constraints.maxLength, c2.constraints.maxLength)
|
|
442
|
+
maxLength: getMin(c1.constraints.maxLength, c2.constraints.maxLength),
|
|
443
|
+
pattern: c1.pattern ?? c2.pattern
|
|
430
444
|
});
|
|
445
|
+
}
|
|
446
|
+
break;
|
|
431
447
|
}
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
case "NumberConstraints":
|
|
438
|
-
return new NumberConstraints({
|
|
448
|
+
case "NumberConstraints":
|
|
449
|
+
{
|
|
450
|
+
if (c2._tag === "NumberConstraints") {
|
|
451
|
+
return makeNumberConstraints({
|
|
452
|
+
isInteger: c1.isInteger || c2.isInteger,
|
|
439
453
|
min: getMax(c1.constraints.min, c2.constraints.min),
|
|
454
|
+
minExcluded: getOr(c1.constraints.minExcluded, c2.constraints.minExcluded),
|
|
440
455
|
max: getMin(c1.constraints.max, c2.constraints.max),
|
|
456
|
+
maxExcluded: getOr(c1.constraints.maxExcluded, c2.constraints.maxExcluded),
|
|
441
457
|
noNaN: getOr(c1.constraints.noNaN, c2.constraints.noNaN),
|
|
442
458
|
noDefaultInfinity: getOr(c1.constraints.noDefaultInfinity, c2.constraints.noDefaultInfinity)
|
|
443
459
|
});
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
min: getMax(c1.constraints.min, c2.constraints.min),
|
|
447
|
-
max: getMin(c1.constraints.max, c2.constraints.max)
|
|
448
|
-
});
|
|
460
|
+
}
|
|
461
|
+
break;
|
|
449
462
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
switch (c2._tag) {
|
|
455
|
-
case "BigIntConstraints":
|
|
456
|
-
return new BigIntConstraints({
|
|
463
|
+
case "BigIntConstraints":
|
|
464
|
+
{
|
|
465
|
+
if (c2._tag === "BigIntConstraints") {
|
|
466
|
+
return makeBigIntConstraints({
|
|
457
467
|
min: getMax(c1.constraints.min, c2.constraints.min),
|
|
458
468
|
max: getMin(c1.constraints.max, c2.constraints.max)
|
|
459
469
|
});
|
|
470
|
+
}
|
|
471
|
+
break;
|
|
460
472
|
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
switch (c2._tag) {
|
|
466
|
-
case "StringConstraints":
|
|
467
|
-
return new StringConstraints({
|
|
473
|
+
case "ArrayConstraints":
|
|
474
|
+
{
|
|
475
|
+
if (c2._tag === "ArrayConstraints") {
|
|
476
|
+
return makeArrayConfig({
|
|
468
477
|
minLength: getMax(c1.constraints.minLength, c2.constraints.minLength),
|
|
469
478
|
maxLength: getMin(c1.constraints.maxLength, c2.constraints.maxLength)
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
}
|
|
474
|
-
case "IntegerConstraints":
|
|
475
|
-
{
|
|
476
|
-
switch (c2._tag) {
|
|
477
|
-
case "NumberConstraints":
|
|
478
|
-
case "IntegerConstraints":
|
|
479
|
-
{
|
|
480
|
-
return new IntegerConstraints({
|
|
481
|
-
min: getMax(c1.constraints.min, c2.constraints.min),
|
|
482
|
-
max: getMin(c1.constraints.max, c2.constraints.max)
|
|
483
|
-
});
|
|
484
|
-
}
|
|
479
|
+
}, c1.ast);
|
|
480
|
+
}
|
|
481
|
+
break;
|
|
485
482
|
}
|
|
486
|
-
|
|
487
|
-
}
|
|
483
|
+
}
|
|
488
484
|
}
|
|
485
|
+
return c1;
|
|
489
486
|
};
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
487
|
+
const getSuspendedArray = (fc, depthIdentifier, maxDepth, item, constraints) => {
|
|
488
|
+
let minLength = 1;
|
|
489
|
+
let maxLength = 2;
|
|
490
|
+
if (constraints && constraints.minLength !== undefined && constraints.minLength > minLength) {
|
|
491
|
+
minLength = constraints.minLength;
|
|
492
|
+
if (minLength > maxLength) {
|
|
493
|
+
maxLength = minLength;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
return fc.oneof({
|
|
497
|
+
maxDepth,
|
|
498
|
+
depthIdentifier
|
|
499
|
+
}, fc.constant([]), fc.array(item, {
|
|
500
|
+
minLength,
|
|
501
|
+
maxLength
|
|
502
|
+
}));
|
|
503
|
+
};
|
|
504
|
+
const getSuspendedContext = (ctx, ast) => {
|
|
505
|
+
if (ctx.depthIdentifier !== undefined) {
|
|
506
|
+
return ctx;
|
|
507
|
+
}
|
|
508
|
+
const depthIdentifier = AST.getIdentifierAnnotation(ast).pipe(Option.orElse(() => AST.getIdentifierAnnotation(ast.f())), Option.getOrElse(() => "SuspendDefaultDepthIdentifier"));
|
|
509
|
+
return {
|
|
510
|
+
...ctx,
|
|
511
|
+
depthIdentifier
|
|
512
|
+
};
|
|
493
513
|
};
|
|
494
|
-
function getMax(n1, n2) {
|
|
495
|
-
return n1 === undefined ? n2 : n2 === undefined ? n1 : n1 <= n2 ? n2 : n1;
|
|
496
|
-
}
|
|
497
|
-
function getMin(n1, n2) {
|
|
498
|
-
return n1 === undefined ? n2 : n2 === undefined ? n1 : n1 <= n2 ? n1 : n2;
|
|
499
|
-
}
|
|
500
514
|
//# sourceMappingURL=Arbitrary.js.map
|