@arrirpc/schema 0.45.0
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/LICENSE +9 -0
- package/README.md +983 -0
- package/dist/index.cjs +2186 -0
- package/dist/index.d.cts +379 -0
- package/dist/index.d.mts +379 -0
- package/dist/index.d.ts +379 -0
- package/dist/index.mjs +2108 -0
- package/dist/shared/schema.34cb5fb7.cjs +1758 -0
- package/dist/shared/schema.66772201.mjs +1687 -0
- package/dist/shared/schema.b7c77149.d.cts +167 -0
- package/dist/shared/schema.b7c77149.d.mts +167 -0
- package/dist/shared/schema.b7c77149.d.ts +167 -0
- package/dist/testSuites.cjs +1305 -0
- package/dist/testSuites.d.cts +38 -0
- package/dist/testSuites.d.mts +38 -0
- package/dist/testSuites.d.ts +38 -0
- package/dist/testSuites.mjs +1300 -0
- package/package.json +34 -0
|
@@ -0,0 +1,1687 @@
|
|
|
1
|
+
import { TypeValues, isSchemaFormElements, isSchemaFormEnum, isSchemaFormDiscriminator, isSchemaFormValues, isSchemaFormProperties, isSchemaFormRef } from 'jtd-utils';
|
|
2
|
+
|
|
3
|
+
const SCHEMA_METADATA = Symbol.for("arri.schema_metadata");
|
|
4
|
+
function isASchema(input) {
|
|
5
|
+
if (typeof input !== "object") {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
if (!input || !("metadata" in input)) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
if (!input.metadata || typeof input.metadata !== "object" || !(SCHEMA_METADATA in input.metadata) || !input.metadata[SCHEMA_METADATA] || typeof input.metadata[SCHEMA_METADATA] !== "object") {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
return "parse" in input.metadata[SCHEMA_METADATA] && typeof input.metadata[SCHEMA_METADATA] === "object";
|
|
15
|
+
}
|
|
16
|
+
function isAScalarSchema(input) {
|
|
17
|
+
return isASchema(input) && "type" in input && typeof input.type === "string" && // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
18
|
+
(TypeValues.includes(input.type) || // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
19
|
+
NumberTypeValues.includes(input.type));
|
|
20
|
+
}
|
|
21
|
+
const NumberTypeValues = [
|
|
22
|
+
"float32",
|
|
23
|
+
"float64",
|
|
24
|
+
"int8",
|
|
25
|
+
"int16",
|
|
26
|
+
"int32",
|
|
27
|
+
"int64",
|
|
28
|
+
"uint8",
|
|
29
|
+
"uint16",
|
|
30
|
+
"uint32",
|
|
31
|
+
"uint64"
|
|
32
|
+
];
|
|
33
|
+
function isAAraySchema(input) {
|
|
34
|
+
return isASchema(input) && isSchemaFormElements(input);
|
|
35
|
+
}
|
|
36
|
+
function isAStringEnumSchema(input) {
|
|
37
|
+
return isASchema(input) && isSchemaFormEnum(input);
|
|
38
|
+
}
|
|
39
|
+
function isADiscriminatorSchema(input) {
|
|
40
|
+
return isASchema(input) && isSchemaFormDiscriminator(input);
|
|
41
|
+
}
|
|
42
|
+
function isARecordSchema(input) {
|
|
43
|
+
return isASchema(input) && isSchemaFormValues(input);
|
|
44
|
+
}
|
|
45
|
+
function isAObjectSchema(input) {
|
|
46
|
+
return isASchema(input) && isSchemaFormProperties(input);
|
|
47
|
+
}
|
|
48
|
+
function isObject(input) {
|
|
49
|
+
return typeof input === "object" && input !== null;
|
|
50
|
+
}
|
|
51
|
+
function isARefSchema(input) {
|
|
52
|
+
return isASchema(input) && isSchemaFormRef(input);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function any(options = {}) {
|
|
56
|
+
return {
|
|
57
|
+
metadata: {
|
|
58
|
+
id: options.id,
|
|
59
|
+
description: options.description,
|
|
60
|
+
isDeprecated: options.isDeprecated,
|
|
61
|
+
[SCHEMA_METADATA]: {
|
|
62
|
+
output: void 0,
|
|
63
|
+
parse: (input, data) => {
|
|
64
|
+
if (data.instancePath.length === 0 && typeof input === "string") {
|
|
65
|
+
try {
|
|
66
|
+
return JSON.parse(input);
|
|
67
|
+
} catch {
|
|
68
|
+
return input;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return input;
|
|
72
|
+
},
|
|
73
|
+
coerce: (input, data) => {
|
|
74
|
+
if (data.instancePath.length === 0 && typeof input === "string") {
|
|
75
|
+
try {
|
|
76
|
+
return JSON.parse(input);
|
|
77
|
+
} catch {
|
|
78
|
+
return input;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return input;
|
|
82
|
+
},
|
|
83
|
+
validate: (input) => true,
|
|
84
|
+
serialize(input) {
|
|
85
|
+
return JSON.stringify(input);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function array(schema, opts = {}) {
|
|
93
|
+
return {
|
|
94
|
+
elements: schema,
|
|
95
|
+
metadata: {
|
|
96
|
+
id: opts.id,
|
|
97
|
+
description: opts.description,
|
|
98
|
+
isDeprecated: opts.isDeprecated,
|
|
99
|
+
[SCHEMA_METADATA]: {
|
|
100
|
+
output: [],
|
|
101
|
+
parse(input, data) {
|
|
102
|
+
return parse$6(schema, input, data, false);
|
|
103
|
+
},
|
|
104
|
+
coerce(input, data) {
|
|
105
|
+
return parse$6(schema, input, data, true);
|
|
106
|
+
},
|
|
107
|
+
validate(input) {
|
|
108
|
+
return validate$5(schema, input);
|
|
109
|
+
},
|
|
110
|
+
serialize(input, data) {
|
|
111
|
+
const strParts = [];
|
|
112
|
+
for (let i = 0; i < input.length; i++) {
|
|
113
|
+
const item = input[i];
|
|
114
|
+
strParts.push(
|
|
115
|
+
schema.metadata[SCHEMA_METADATA].serialize(item, {
|
|
116
|
+
instancePath: `${data.instancePath}/${i}`,
|
|
117
|
+
schemaPath: `${data.schemaPath}/elements`,
|
|
118
|
+
errors: data.errors
|
|
119
|
+
})
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
return `[${strParts.join(",")}]`;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function validate$5(innerSchema, input) {
|
|
129
|
+
if (!Array.isArray(input)) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
for (const item of input) {
|
|
133
|
+
const isValid = innerSchema.metadata[SCHEMA_METADATA].validate(item);
|
|
134
|
+
if (!isValid) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
function parse$6(innerSchema, input, data, coerce = false) {
|
|
141
|
+
let parsedInput = input;
|
|
142
|
+
if (data.instancePath.length === 0 && typeof input === "string") {
|
|
143
|
+
try {
|
|
144
|
+
parsedInput = JSON.parse(input);
|
|
145
|
+
} catch (err) {
|
|
146
|
+
data.errors.push({
|
|
147
|
+
instancePath: data.instancePath,
|
|
148
|
+
schemaPath: `${data.schemaPath}/elements`,
|
|
149
|
+
message: `Error at ${data.instancePath}. Invalid JSON.`
|
|
150
|
+
});
|
|
151
|
+
return void 0;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (!Array.isArray(parsedInput)) {
|
|
155
|
+
data.errors.push({
|
|
156
|
+
instancePath: data.instancePath,
|
|
157
|
+
schemaPath: `${data.schemaPath}/elements`,
|
|
158
|
+
message: `Error at ${data.instancePath}. Expected array. Got ${typeof input}.`
|
|
159
|
+
});
|
|
160
|
+
return void 0;
|
|
161
|
+
}
|
|
162
|
+
const result = [];
|
|
163
|
+
for (let i = 0; i < parsedInput.length; i++) {
|
|
164
|
+
const item = parsedInput[i];
|
|
165
|
+
if (coerce) {
|
|
166
|
+
const parsedItem = innerSchema.metadata[SCHEMA_METADATA].coerce(
|
|
167
|
+
item,
|
|
168
|
+
{
|
|
169
|
+
instancePath: `${data.instancePath}/${i}`,
|
|
170
|
+
schemaPath: `${data.schemaPath}/elements`,
|
|
171
|
+
errors: data.errors
|
|
172
|
+
}
|
|
173
|
+
);
|
|
174
|
+
result.push(parsedItem);
|
|
175
|
+
} else {
|
|
176
|
+
const parsedItem = innerSchema.metadata[SCHEMA_METADATA].parse(
|
|
177
|
+
item,
|
|
178
|
+
{
|
|
179
|
+
instancePath: `${data.instancePath}/${i}`,
|
|
180
|
+
schemaPath: `${data.schemaPath}/elements`,
|
|
181
|
+
errors: data.errors
|
|
182
|
+
}
|
|
183
|
+
);
|
|
184
|
+
result.push(parsedItem);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (data.errors.length) {
|
|
188
|
+
return void 0;
|
|
189
|
+
}
|
|
190
|
+
return result;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function boolean(opts = {}) {
|
|
194
|
+
return {
|
|
195
|
+
type: "boolean",
|
|
196
|
+
metadata: {
|
|
197
|
+
id: opts.id,
|
|
198
|
+
description: opts.description,
|
|
199
|
+
isDeprecated: opts.isDeprecated,
|
|
200
|
+
[SCHEMA_METADATA]: {
|
|
201
|
+
output: false,
|
|
202
|
+
parse: parse$5,
|
|
203
|
+
validate: validate$4,
|
|
204
|
+
serialize: serialize$2,
|
|
205
|
+
coerce(input, data) {
|
|
206
|
+
if (validate$4(input)) {
|
|
207
|
+
return input;
|
|
208
|
+
}
|
|
209
|
+
switch (input) {
|
|
210
|
+
case "true":
|
|
211
|
+
case "TRUE":
|
|
212
|
+
case "1":
|
|
213
|
+
case 1:
|
|
214
|
+
return true;
|
|
215
|
+
case "false":
|
|
216
|
+
case "FALSE":
|
|
217
|
+
case "0":
|
|
218
|
+
case 0:
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
data.errors.push({
|
|
222
|
+
instancePath: data.instancePath,
|
|
223
|
+
schemaPath: data.schemaPath,
|
|
224
|
+
message: `Error at ${data.instancePath}. Unable to coerce ${input} to boolean.`
|
|
225
|
+
});
|
|
226
|
+
return void 0;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
function validate$4(input) {
|
|
233
|
+
return typeof input === "boolean";
|
|
234
|
+
}
|
|
235
|
+
function parse$5(input, data) {
|
|
236
|
+
if (validate$4(input)) {
|
|
237
|
+
return input;
|
|
238
|
+
}
|
|
239
|
+
if (data.instancePath.length === 0 && typeof input === "string") {
|
|
240
|
+
if (input === "true") {
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
if (input === "false") {
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
data.errors.push({
|
|
247
|
+
instancePath: data.instancePath,
|
|
248
|
+
schemaPath: `${data.schemaPath}/type`,
|
|
249
|
+
message: `Error at ${data.instancePath}. Expected boolean. Got ${typeof input}.`
|
|
250
|
+
});
|
|
251
|
+
return void 0;
|
|
252
|
+
}
|
|
253
|
+
data.errors.push({
|
|
254
|
+
instancePath: data.instancePath,
|
|
255
|
+
schemaPath: `${data.schemaPath}/type`,
|
|
256
|
+
message: `Error at ${data.instancePath}. Expected boolean. Got ${typeof input}.`
|
|
257
|
+
});
|
|
258
|
+
return void 0;
|
|
259
|
+
}
|
|
260
|
+
function serialize$2(input) {
|
|
261
|
+
return `${input}`;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
var __defProp = Object.defineProperty;
|
|
265
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
266
|
+
var __publicField = (obj, key, value) => {
|
|
267
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
268
|
+
return value;
|
|
269
|
+
};
|
|
270
|
+
function sanitizeJson(json) {
|
|
271
|
+
return json.replace(/[\b]/g, "\\b").replace(/[\f]/g, "\\f").replace(/[\n]/g, "\\n").replace(/[\r]/g, "\\r").replace(/[\t]/g, "\\t");
|
|
272
|
+
}
|
|
273
|
+
function validate$3(schema, input) {
|
|
274
|
+
return schema.metadata[SCHEMA_METADATA].validate(input);
|
|
275
|
+
}
|
|
276
|
+
function parse$4(schema, input) {
|
|
277
|
+
const errors2 = [];
|
|
278
|
+
const result = schema.metadata[SCHEMA_METADATA].parse(input, {
|
|
279
|
+
schemaPath: "",
|
|
280
|
+
instancePath: "",
|
|
281
|
+
errors: errors2
|
|
282
|
+
});
|
|
283
|
+
if (errors2.length) {
|
|
284
|
+
throw new ValidationError({
|
|
285
|
+
message: `Unable to parse input. ${errors2[0].message}`,
|
|
286
|
+
errors: errors2
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
return result;
|
|
290
|
+
}
|
|
291
|
+
function safeParse(schema, input) {
|
|
292
|
+
try {
|
|
293
|
+
const result = parse$4(schema, input);
|
|
294
|
+
return {
|
|
295
|
+
success: true,
|
|
296
|
+
value: result
|
|
297
|
+
};
|
|
298
|
+
} catch (err) {
|
|
299
|
+
if (isValidationError(err)) {
|
|
300
|
+
return {
|
|
301
|
+
success: false,
|
|
302
|
+
error: err
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
return {
|
|
306
|
+
success: false,
|
|
307
|
+
error: new ValidationError({
|
|
308
|
+
message: "Unable to parse input",
|
|
309
|
+
errors: []
|
|
310
|
+
})
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
function coerce$2(schema, input) {
|
|
315
|
+
const errors2 = [];
|
|
316
|
+
const result = schema.metadata[SCHEMA_METADATA].coerce(input, {
|
|
317
|
+
schemaPath: "",
|
|
318
|
+
instancePath: "",
|
|
319
|
+
errors: errors2
|
|
320
|
+
});
|
|
321
|
+
if (errors2.length) {
|
|
322
|
+
throw new ValidationError({
|
|
323
|
+
message: `Unable to coerce input. ${errors2[0]?.message}`,
|
|
324
|
+
errors: errors2
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
return result;
|
|
328
|
+
}
|
|
329
|
+
function safeCoerce(schema, input) {
|
|
330
|
+
try {
|
|
331
|
+
const result = coerce$2(schema, input);
|
|
332
|
+
return {
|
|
333
|
+
success: true,
|
|
334
|
+
value: result
|
|
335
|
+
};
|
|
336
|
+
} catch (err) {
|
|
337
|
+
if (isValidationError(err)) {
|
|
338
|
+
return {
|
|
339
|
+
success: false,
|
|
340
|
+
error: err
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
return {
|
|
344
|
+
success: false,
|
|
345
|
+
error: new ValidationError({
|
|
346
|
+
message: "Unable to coerce input",
|
|
347
|
+
errors: []
|
|
348
|
+
})
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
function serialize$1(schema, input) {
|
|
353
|
+
const data = {
|
|
354
|
+
instancePath: "",
|
|
355
|
+
schemaPath: "",
|
|
356
|
+
errors: []
|
|
357
|
+
};
|
|
358
|
+
return schema.metadata[SCHEMA_METADATA].serialize(input, data);
|
|
359
|
+
}
|
|
360
|
+
function errors(schema, input) {
|
|
361
|
+
const errorList = [];
|
|
362
|
+
try {
|
|
363
|
+
schema.metadata[SCHEMA_METADATA].parse(input, {
|
|
364
|
+
errors: errorList,
|
|
365
|
+
instancePath: "",
|
|
366
|
+
schemaPath: ""
|
|
367
|
+
});
|
|
368
|
+
} catch (err) {
|
|
369
|
+
errorList.push({ instancePath: "", schemaPath: "", message: `${err}` });
|
|
370
|
+
}
|
|
371
|
+
return errorList;
|
|
372
|
+
}
|
|
373
|
+
class ValidationError extends Error {
|
|
374
|
+
constructor(options) {
|
|
375
|
+
super(options.message);
|
|
376
|
+
__publicField(this, "errors");
|
|
377
|
+
this.errors = options.errors;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
function isValidationError(input) {
|
|
381
|
+
if (typeof input !== "object" || !input) {
|
|
382
|
+
return false;
|
|
383
|
+
}
|
|
384
|
+
return "message" in input && typeof input.message === "string" && "errors" in input && Array.isArray(input.errors);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function discriminator(propA, propB, propC) {
|
|
388
|
+
const isIdShorthand = typeof propB === "string";
|
|
389
|
+
const discriminator2 = isIdShorthand ? propB : propA;
|
|
390
|
+
const mapping = isIdShorthand ? propC : propB;
|
|
391
|
+
const opts = isIdShorthand ? { id: propA } : propC ?? {};
|
|
392
|
+
if (isIdShorthand) {
|
|
393
|
+
opts.id = propA;
|
|
394
|
+
}
|
|
395
|
+
return {
|
|
396
|
+
discriminator: discriminator2,
|
|
397
|
+
mapping,
|
|
398
|
+
metadata: {
|
|
399
|
+
id: opts.id,
|
|
400
|
+
description: opts.description,
|
|
401
|
+
isDeprecated: opts.isDeprecated,
|
|
402
|
+
[SCHEMA_METADATA]: {
|
|
403
|
+
output: {},
|
|
404
|
+
validate(input) {
|
|
405
|
+
return validate$2(discriminator2, mapping, input);
|
|
406
|
+
},
|
|
407
|
+
parse(input, data) {
|
|
408
|
+
return parse$3(discriminator2, mapping, input, data, false);
|
|
409
|
+
},
|
|
410
|
+
coerce: (input, data) => {
|
|
411
|
+
return parse$3(discriminator2, mapping, input, data, true);
|
|
412
|
+
},
|
|
413
|
+
serialize(input, data) {
|
|
414
|
+
const discriminatorVal = input[discriminator2] ?? "";
|
|
415
|
+
const targetSchema = mapping[discriminatorVal];
|
|
416
|
+
if (!targetSchema) {
|
|
417
|
+
throw discriminatorMappingError(discriminatorVal, data);
|
|
418
|
+
}
|
|
419
|
+
const result = targetSchema.metadata[SCHEMA_METADATA].serialize(input, {
|
|
420
|
+
instancePath: data.instancePath,
|
|
421
|
+
schemaPath: `${data.schemaPath}/mapping/${discriminatorVal}`,
|
|
422
|
+
errors: data.errors,
|
|
423
|
+
discriminatorKey: discriminator2,
|
|
424
|
+
discriminatorValue: discriminatorVal
|
|
425
|
+
});
|
|
426
|
+
return result;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
function validate$2(discriminator2, mapping, input) {
|
|
433
|
+
if (!isObject(input)) {
|
|
434
|
+
return false;
|
|
435
|
+
}
|
|
436
|
+
if (!(discriminator2 in input)) {
|
|
437
|
+
return false;
|
|
438
|
+
}
|
|
439
|
+
const discriminatorOptions = Object.keys(mapping);
|
|
440
|
+
if (!discriminatorOptions.includes(input[discriminator2])) {
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
443
|
+
const targetSchema = mapping[input[discriminator2]];
|
|
444
|
+
if (!targetSchema) {
|
|
445
|
+
return false;
|
|
446
|
+
}
|
|
447
|
+
return targetSchema.metadata[SCHEMA_METADATA].validate(input);
|
|
448
|
+
}
|
|
449
|
+
function parse$3(discriminator2, mapping, input, data, coerce = false) {
|
|
450
|
+
let parsedInput = input;
|
|
451
|
+
if (typeof input === "string" && input.length && data.instancePath.length === 0) {
|
|
452
|
+
parsedInput = JSON.parse(input);
|
|
453
|
+
}
|
|
454
|
+
if (!isObject(parsedInput)) {
|
|
455
|
+
data.errors.push({
|
|
456
|
+
instancePath: data.instancePath,
|
|
457
|
+
schemaPath: `${data.schemaPath}/discriminator`,
|
|
458
|
+
message: `Error at ${data.instancePath}. Expected object. Got ${typeof parsedInput}.`
|
|
459
|
+
});
|
|
460
|
+
return void 0;
|
|
461
|
+
}
|
|
462
|
+
if (!(discriminator2 in parsedInput)) {
|
|
463
|
+
data.errors.push({
|
|
464
|
+
instancePath: `${data.instancePath}/${discriminator2}`,
|
|
465
|
+
schemaPath: `${data.schemaPath}/discriminator`,
|
|
466
|
+
message: `Error at ${data.instancePath}/${discriminator2}. Discriminator field "${discriminator2}" cannot be undefined`
|
|
467
|
+
});
|
|
468
|
+
return void 0;
|
|
469
|
+
}
|
|
470
|
+
const acceptedDiscriminatorVals = Object.keys(mapping);
|
|
471
|
+
const discriminatorVal = parsedInput[discriminator2];
|
|
472
|
+
if (!acceptedDiscriminatorVals.includes(discriminatorVal)) {
|
|
473
|
+
data.errors.push({
|
|
474
|
+
instancePath: `${data.instancePath}/${discriminator2}`,
|
|
475
|
+
schemaPath: `${data.schemaPath}/discriminator`,
|
|
476
|
+
message: `Error at ${data.instancePath}/${discriminator2}. "${parsedInput[discriminator2]}" is not one of the accepted discriminator values: [${acceptedDiscriminatorVals.join(
|
|
477
|
+
", "
|
|
478
|
+
)}]`
|
|
479
|
+
});
|
|
480
|
+
return void 0;
|
|
481
|
+
}
|
|
482
|
+
const targetSchema = mapping[parsedInput[discriminator2]];
|
|
483
|
+
if (!targetSchema) {
|
|
484
|
+
throw discriminatorMappingError(discriminatorVal, data);
|
|
485
|
+
}
|
|
486
|
+
if (coerce) {
|
|
487
|
+
const result2 = targetSchema.metadata[SCHEMA_METADATA].coerce(
|
|
488
|
+
parsedInput,
|
|
489
|
+
{
|
|
490
|
+
instancePath: data.instancePath,
|
|
491
|
+
schemaPath: `${data.schemaPath}/mapping/${discriminatorVal}`,
|
|
492
|
+
errors: data.errors,
|
|
493
|
+
discriminatorKey: discriminator2,
|
|
494
|
+
discriminatorValue: discriminatorVal
|
|
495
|
+
}
|
|
496
|
+
);
|
|
497
|
+
return result2;
|
|
498
|
+
}
|
|
499
|
+
const result = targetSchema.metadata[SCHEMA_METADATA].parse(parsedInput, {
|
|
500
|
+
instancePath: data.instancePath,
|
|
501
|
+
schemaPath: `${data.schemaPath}/mapping/${discriminatorVal}`,
|
|
502
|
+
errors: data.errors,
|
|
503
|
+
discriminatorKey: discriminator2,
|
|
504
|
+
discriminatorValue: discriminatorVal
|
|
505
|
+
});
|
|
506
|
+
return result;
|
|
507
|
+
}
|
|
508
|
+
function discriminatorMappingError(discriminatorVal, data) {
|
|
509
|
+
return new ValidationError({
|
|
510
|
+
message: `Error fetching discriminator schema for "${discriminatorVal}"`,
|
|
511
|
+
errors: [
|
|
512
|
+
{
|
|
513
|
+
message: "Error fetching discriminator schema",
|
|
514
|
+
instancePath: data.instancePath,
|
|
515
|
+
schemaPath: data.schemaPath
|
|
516
|
+
}
|
|
517
|
+
]
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
const stringEnum = enumerator;
|
|
522
|
+
function enumerator(paramA, paramB) {
|
|
523
|
+
const isType = (input) => {
|
|
524
|
+
if (typeof input !== "string") {
|
|
525
|
+
return false;
|
|
526
|
+
}
|
|
527
|
+
for (const val of paramA) {
|
|
528
|
+
if (val === input) {
|
|
529
|
+
return true;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
return false;
|
|
533
|
+
};
|
|
534
|
+
const isIdShorthand = typeof paramA === "string";
|
|
535
|
+
const enumVal = isIdShorthand ? paramB : paramA;
|
|
536
|
+
const meta = isIdShorthand ? { id: paramA } : paramB;
|
|
537
|
+
return {
|
|
538
|
+
enum: enumVal,
|
|
539
|
+
metadata: {
|
|
540
|
+
id: meta?.id,
|
|
541
|
+
description: meta?.description,
|
|
542
|
+
isDeprecated: meta?.isDeprecated,
|
|
543
|
+
[SCHEMA_METADATA]: {
|
|
544
|
+
output: paramA[0] ?? "",
|
|
545
|
+
parse(input, data) {
|
|
546
|
+
if (isType(input)) {
|
|
547
|
+
return input;
|
|
548
|
+
}
|
|
549
|
+
data.errors.push({
|
|
550
|
+
instancePath: data.instancePath,
|
|
551
|
+
schemaPath: `${data.schemaPath}/enum`,
|
|
552
|
+
message: `Error at ${data.instancePath}. Invalid enum value. Expected one of the following values: [${enumVal.join(
|
|
553
|
+
", "
|
|
554
|
+
)}]`
|
|
555
|
+
});
|
|
556
|
+
return void 0;
|
|
557
|
+
},
|
|
558
|
+
coerce: (input, data) => {
|
|
559
|
+
if (isType(input)) {
|
|
560
|
+
return input;
|
|
561
|
+
}
|
|
562
|
+
data.errors.push({
|
|
563
|
+
instancePath: data.instancePath,
|
|
564
|
+
schemaPath: `${data.schemaPath}/enum`,
|
|
565
|
+
message: `Error at ${data.instancePath}. Invalid enum value. Expected one of the following values: [${enumVal.join(
|
|
566
|
+
", "
|
|
567
|
+
)}]`
|
|
568
|
+
});
|
|
569
|
+
return void 0;
|
|
570
|
+
},
|
|
571
|
+
validate: isType,
|
|
572
|
+
serialize(input, data) {
|
|
573
|
+
if (data.instancePath.length === 0) {
|
|
574
|
+
return input;
|
|
575
|
+
}
|
|
576
|
+
return `"${input}"`;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
function nullable(schema, opts = {}) {
|
|
584
|
+
const isType = (val) => {
|
|
585
|
+
if (val === null) {
|
|
586
|
+
return true;
|
|
587
|
+
}
|
|
588
|
+
return schema.metadata[SCHEMA_METADATA].validate(val);
|
|
589
|
+
};
|
|
590
|
+
return {
|
|
591
|
+
...schema,
|
|
592
|
+
nullable: true,
|
|
593
|
+
metadata: {
|
|
594
|
+
id: opts.id ?? schema.metadata.id,
|
|
595
|
+
description: opts.description ?? schema.metadata.description,
|
|
596
|
+
isDeprecated: opts.isDeprecated ?? schema.metadata.isDeprecated,
|
|
597
|
+
[SCHEMA_METADATA]: {
|
|
598
|
+
output: null,
|
|
599
|
+
optional: schema.metadata[SCHEMA_METADATA].optional,
|
|
600
|
+
validate: isType,
|
|
601
|
+
parse(val, data) {
|
|
602
|
+
if (data.instancePath.length === 0 && typeof val === "string" && val === "null") {
|
|
603
|
+
return null;
|
|
604
|
+
}
|
|
605
|
+
if (val === null) {
|
|
606
|
+
return null;
|
|
607
|
+
}
|
|
608
|
+
return schema.metadata[SCHEMA_METADATA].parse(val, data);
|
|
609
|
+
},
|
|
610
|
+
coerce(val, data) {
|
|
611
|
+
if (val === null) {
|
|
612
|
+
return null;
|
|
613
|
+
}
|
|
614
|
+
if (val === "null") {
|
|
615
|
+
return null;
|
|
616
|
+
}
|
|
617
|
+
return schema.metadata[SCHEMA_METADATA].coerce(val, data);
|
|
618
|
+
},
|
|
619
|
+
serialize(val, data) {
|
|
620
|
+
if (val === null) {
|
|
621
|
+
return "null";
|
|
622
|
+
}
|
|
623
|
+
return schema.metadata[SCHEMA_METADATA].serialize(
|
|
624
|
+
val,
|
|
625
|
+
data
|
|
626
|
+
);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
function optional(input, opts = {}) {
|
|
633
|
+
const isType = (val) => {
|
|
634
|
+
if (val === void 0) {
|
|
635
|
+
return true;
|
|
636
|
+
}
|
|
637
|
+
return input.metadata[SCHEMA_METADATA].validate(val);
|
|
638
|
+
};
|
|
639
|
+
return {
|
|
640
|
+
...input,
|
|
641
|
+
metadata: {
|
|
642
|
+
id: opts.id ?? input.metadata.id,
|
|
643
|
+
description: opts.description ?? input.metadata.description,
|
|
644
|
+
isDeprecated: opts.isDeprecated ?? input.metadata.isDeprecated,
|
|
645
|
+
[SCHEMA_METADATA]: {
|
|
646
|
+
output: void 0,
|
|
647
|
+
optional: true,
|
|
648
|
+
validate: isType,
|
|
649
|
+
parse: (val, data) => {
|
|
650
|
+
if (typeof val === "undefined") {
|
|
651
|
+
return void 0;
|
|
652
|
+
}
|
|
653
|
+
if (data.instancePath.length === 0 && val === "undefined") {
|
|
654
|
+
return void 0;
|
|
655
|
+
}
|
|
656
|
+
return input.metadata[SCHEMA_METADATA].parse(val, data);
|
|
657
|
+
},
|
|
658
|
+
coerce: (val, data) => {
|
|
659
|
+
if (typeof val === "undefined") {
|
|
660
|
+
return void 0;
|
|
661
|
+
}
|
|
662
|
+
if (val === "undefined") {
|
|
663
|
+
return void 0;
|
|
664
|
+
}
|
|
665
|
+
return input.metadata[SCHEMA_METADATA].coerce(val, data);
|
|
666
|
+
},
|
|
667
|
+
serialize: (val, data) => {
|
|
668
|
+
if (typeof val === "undefined") {
|
|
669
|
+
return "undefined";
|
|
670
|
+
}
|
|
671
|
+
return input.metadata[SCHEMA_METADATA].serialize(val, data);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
function clone(input, opts = {}) {
|
|
678
|
+
const schema = {
|
|
679
|
+
...input,
|
|
680
|
+
metadata: {
|
|
681
|
+
id: opts.id,
|
|
682
|
+
description: opts.description,
|
|
683
|
+
isDeprecated: opts.isDeprecated,
|
|
684
|
+
[SCHEMA_METADATA]: {
|
|
685
|
+
...input.metadata[SCHEMA_METADATA]
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
return schema;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
const int8Min = -128;
|
|
693
|
+
const int8Max = 127;
|
|
694
|
+
const uint8Min = 0;
|
|
695
|
+
const uint8Max = 255;
|
|
696
|
+
const int16Min = -32768;
|
|
697
|
+
const int16Max = 32767;
|
|
698
|
+
const uint16Min = 0;
|
|
699
|
+
const uint16Max = 65535;
|
|
700
|
+
const int32Min = -2147483648;
|
|
701
|
+
const int32Max = 2147483647;
|
|
702
|
+
const uint32Min = 0;
|
|
703
|
+
const uint32Max = 4294967295;
|
|
704
|
+
const int64Min = BigInt("-9223372036854775808");
|
|
705
|
+
const int64Max = BigInt("9223372036854775807");
|
|
706
|
+
const uint64Min = BigInt("0");
|
|
707
|
+
const uint64Max = BigInt("18446744073709551615");
|
|
708
|
+
|
|
709
|
+
function number(opts = {}) {
|
|
710
|
+
return float64(opts);
|
|
711
|
+
}
|
|
712
|
+
function coerceNumber(input, options) {
|
|
713
|
+
if (typeof input === "string") {
|
|
714
|
+
const parsedInput = Number(input);
|
|
715
|
+
if (Number.isNaN(parsedInput)) {
|
|
716
|
+
options.errors.push({
|
|
717
|
+
instancePath: `${options.instancePath}`,
|
|
718
|
+
schemaPath: `${options.schemaPath}/type`,
|
|
719
|
+
message: `Error at ${options.instancePath}. Unable to coerce ${typeof input} into a number`
|
|
720
|
+
});
|
|
721
|
+
return void 0;
|
|
722
|
+
}
|
|
723
|
+
return parseNumber(parsedInput, options);
|
|
724
|
+
}
|
|
725
|
+
return parseNumber(input, options);
|
|
726
|
+
}
|
|
727
|
+
function float32(opts = {}) {
|
|
728
|
+
return numberScalarType("float32", opts, (input) => {
|
|
729
|
+
return {
|
|
730
|
+
success: true
|
|
731
|
+
};
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
function float64(opts = {}) {
|
|
735
|
+
return numberScalarType("float64", opts, (input) => {
|
|
736
|
+
return {
|
|
737
|
+
success: true
|
|
738
|
+
};
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
function int8(opts = {}) {
|
|
742
|
+
return numberScalarType("int8", opts, (input) => {
|
|
743
|
+
const isValid = validateInt(input, int8Min, int8Max);
|
|
744
|
+
if (isValid) {
|
|
745
|
+
return {
|
|
746
|
+
success: true
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
return {
|
|
750
|
+
success: false,
|
|
751
|
+
message: `Must be an valid integer between ${int8Min} and ${int8Max}`
|
|
752
|
+
};
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
function uint8(opts = {}) {
|
|
756
|
+
return numberScalarType("uint8", opts, (input) => {
|
|
757
|
+
const isValid = validateInt(input, uint8Min, uint8Max);
|
|
758
|
+
if (isValid) {
|
|
759
|
+
return {
|
|
760
|
+
success: true
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
return {
|
|
764
|
+
success: false,
|
|
765
|
+
message: `Must be a valid integer between ${uint8Min} and ${uint8Max}`
|
|
766
|
+
};
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
function int16(opts = {}) {
|
|
770
|
+
return numberScalarType("int16", opts, (input) => {
|
|
771
|
+
const isValid = validateInt(input, int16Min, int16Max);
|
|
772
|
+
if (isValid) {
|
|
773
|
+
return {
|
|
774
|
+
success: true
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
return {
|
|
778
|
+
success: false,
|
|
779
|
+
message: `Must be a valid integer between ${int16Min} and ${int16Max}`
|
|
780
|
+
};
|
|
781
|
+
});
|
|
782
|
+
}
|
|
783
|
+
function uint16(opts = {}) {
|
|
784
|
+
return numberScalarType("uint16", opts, (input) => {
|
|
785
|
+
const isValid = validateInt(input, uint16Min, uint16Max);
|
|
786
|
+
if (isValid) {
|
|
787
|
+
return {
|
|
788
|
+
success: true
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
return {
|
|
792
|
+
success: false,
|
|
793
|
+
message: `Must be a valid integer between ${uint16Min} and ${uint16Max}`
|
|
794
|
+
};
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
function int32(opts = {}) {
|
|
798
|
+
return numberScalarType("int32", opts, (input) => {
|
|
799
|
+
const isValid = validateInt(input, int32Min, int32Max);
|
|
800
|
+
if (isValid) {
|
|
801
|
+
return {
|
|
802
|
+
success: true
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
return {
|
|
806
|
+
success: false,
|
|
807
|
+
message: `Must be a valid integer between ${int32Min} and ${int32Max}`
|
|
808
|
+
};
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
function uint32(opts = {}) {
|
|
812
|
+
return numberScalarType("uint32", opts, (input) => {
|
|
813
|
+
const isValid = validateInt(input, uint32Min, uint32Max);
|
|
814
|
+
if (isValid) {
|
|
815
|
+
return { success: true };
|
|
816
|
+
}
|
|
817
|
+
return {
|
|
818
|
+
success: false,
|
|
819
|
+
message: `Must be a valid integer between ${uint32Min} and ${uint32Max}`
|
|
820
|
+
};
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
function int64(opts = {}) {
|
|
824
|
+
function isType(input) {
|
|
825
|
+
return typeof input === "bigint" && input >= int64Min && input <= int64Max;
|
|
826
|
+
}
|
|
827
|
+
function parse(input, data) {
|
|
828
|
+
if (typeof input === "string" || typeof input === "number") {
|
|
829
|
+
try {
|
|
830
|
+
const val = BigInt(input);
|
|
831
|
+
if (isType(val)) {
|
|
832
|
+
return val;
|
|
833
|
+
}
|
|
834
|
+
data.errors.push({
|
|
835
|
+
message: `Error at ${data.instancePath}. Invalid int64.`,
|
|
836
|
+
schemaPath: `${data.schemaPath}/type`,
|
|
837
|
+
instancePath: data.instancePath
|
|
838
|
+
});
|
|
839
|
+
return void 0;
|
|
840
|
+
} catch (err) {
|
|
841
|
+
data.errors.push({
|
|
842
|
+
message: `Error at ${data.instancePath}. Unable to transform ${input} to BigInt`,
|
|
843
|
+
schemaPath: `${data.schemaPath}/type`,
|
|
844
|
+
instancePath: data.instancePath
|
|
845
|
+
});
|
|
846
|
+
return void 0;
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
if (isType(input)) {
|
|
850
|
+
return input;
|
|
851
|
+
}
|
|
852
|
+
data.errors.push({
|
|
853
|
+
message: `Error at ${data.instancePath}. Expected BigInt or integer string`,
|
|
854
|
+
schemaPath: `${data.schemaPath}/type`,
|
|
855
|
+
instancePath: data.instancePath
|
|
856
|
+
});
|
|
857
|
+
return void 0;
|
|
858
|
+
}
|
|
859
|
+
return {
|
|
860
|
+
type: "int64",
|
|
861
|
+
metadata: {
|
|
862
|
+
id: opts.id,
|
|
863
|
+
description: opts.description,
|
|
864
|
+
isDeprecated: opts.isDeprecated,
|
|
865
|
+
[SCHEMA_METADATA]: {
|
|
866
|
+
output: BigInt("0"),
|
|
867
|
+
validate: isType,
|
|
868
|
+
parse,
|
|
869
|
+
coerce: parse,
|
|
870
|
+
serialize(input, data) {
|
|
871
|
+
if (data.instancePath.length === 0) {
|
|
872
|
+
return input.toString();
|
|
873
|
+
}
|
|
874
|
+
return `"${input.toString()}"`;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
function uint64(opts = {}) {
|
|
881
|
+
function isType(input) {
|
|
882
|
+
return typeof input === "bigint" && input >= uint64Min && input <= uint64Max;
|
|
883
|
+
}
|
|
884
|
+
function parse(input, data) {
|
|
885
|
+
if (typeof input === "string" || typeof input === "number") {
|
|
886
|
+
try {
|
|
887
|
+
const val = BigInt(input);
|
|
888
|
+
if (isType(val)) {
|
|
889
|
+
return val;
|
|
890
|
+
}
|
|
891
|
+
data.errors.push({
|
|
892
|
+
message: `Error at ${data.instancePath}. Invalid uint64.`,
|
|
893
|
+
schemaPath: `${data.schemaPath}/type`,
|
|
894
|
+
instancePath: data.instancePath
|
|
895
|
+
});
|
|
896
|
+
return void 0;
|
|
897
|
+
} catch (err) {
|
|
898
|
+
data.errors.push({
|
|
899
|
+
message: `Error at ${data.instancePath}. Unable to transform ${input} to BigInt.`,
|
|
900
|
+
schemaPath: `${data.schemaPath}/type`,
|
|
901
|
+
instancePath: data.instancePath
|
|
902
|
+
});
|
|
903
|
+
return void 0;
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
if (isType(input)) {
|
|
907
|
+
return input;
|
|
908
|
+
}
|
|
909
|
+
data.errors.push({
|
|
910
|
+
message: `Error at ${data.instancePath}. Expected BigInt or integer string.`,
|
|
911
|
+
schemaPath: `${data.schemaPath}/type`,
|
|
912
|
+
instancePath: data.instancePath
|
|
913
|
+
});
|
|
914
|
+
return void 0;
|
|
915
|
+
}
|
|
916
|
+
return {
|
|
917
|
+
type: "uint64",
|
|
918
|
+
metadata: {
|
|
919
|
+
id: opts.id,
|
|
920
|
+
description: opts.description,
|
|
921
|
+
isDeprecated: opts.isDeprecated,
|
|
922
|
+
[SCHEMA_METADATA]: {
|
|
923
|
+
output: BigInt("0"),
|
|
924
|
+
validate: isType,
|
|
925
|
+
parse,
|
|
926
|
+
coerce: parse,
|
|
927
|
+
serialize(input, data) {
|
|
928
|
+
if (data.instancePath.length === 0) {
|
|
929
|
+
return input.toString();
|
|
930
|
+
}
|
|
931
|
+
return `"${input.toString()}"`;
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
function validateNumber(input) {
|
|
938
|
+
return typeof input === "number" || !Number.isNaN(input);
|
|
939
|
+
}
|
|
940
|
+
function validateInt(input, minVal, maxValue) {
|
|
941
|
+
return Number.isInteger(input) && input >= minVal && input <= maxValue;
|
|
942
|
+
}
|
|
943
|
+
function serializeNumber(input, data) {
|
|
944
|
+
return input.toString();
|
|
945
|
+
}
|
|
946
|
+
function parseNumber(input, options) {
|
|
947
|
+
if (options.instancePath.length === 0 && typeof input === "string") {
|
|
948
|
+
const result = Number(input);
|
|
949
|
+
if (Number.isNaN(result)) {
|
|
950
|
+
options?.errors.push({
|
|
951
|
+
instancePath: options.instancePath,
|
|
952
|
+
schemaPath: `${options.schemaPath}/type`,
|
|
953
|
+
message: `Error at ${options.instancePath}. Invalid number.`
|
|
954
|
+
});
|
|
955
|
+
return void 0;
|
|
956
|
+
}
|
|
957
|
+
return result;
|
|
958
|
+
}
|
|
959
|
+
if (typeof input === "number" && !Number.isNaN(input)) {
|
|
960
|
+
return input;
|
|
961
|
+
}
|
|
962
|
+
options?.errors.push({
|
|
963
|
+
instancePath: options.instancePath,
|
|
964
|
+
schemaPath: `${options.schemaPath}/type`,
|
|
965
|
+
message: `Error at ${options.instancePath}. Invalid number.`
|
|
966
|
+
});
|
|
967
|
+
return void 0;
|
|
968
|
+
}
|
|
969
|
+
function numberScalarType(type, opts, numTypeMatcher) {
|
|
970
|
+
return {
|
|
971
|
+
type,
|
|
972
|
+
metadata: {
|
|
973
|
+
id: opts.id,
|
|
974
|
+
description: opts.description,
|
|
975
|
+
isDeprecated: opts.isDeprecated,
|
|
976
|
+
[SCHEMA_METADATA]: {
|
|
977
|
+
output: 0,
|
|
978
|
+
validate(input) {
|
|
979
|
+
const isNum = validateNumber(input);
|
|
980
|
+
if (!isNum) {
|
|
981
|
+
return false;
|
|
982
|
+
}
|
|
983
|
+
return numTypeMatcher(input).success;
|
|
984
|
+
},
|
|
985
|
+
parse(input, options) {
|
|
986
|
+
const result = parseNumber(input, options);
|
|
987
|
+
if (options.errors.length) {
|
|
988
|
+
return void 0;
|
|
989
|
+
}
|
|
990
|
+
if (typeof result !== "number") {
|
|
991
|
+
options?.errors.push({
|
|
992
|
+
instancePath: options.instancePath,
|
|
993
|
+
schemaPath: `${options.schemaPath}/type`,
|
|
994
|
+
message: `Error at ${options.instancePath}. Invalid number.`
|
|
995
|
+
});
|
|
996
|
+
return void 0;
|
|
997
|
+
}
|
|
998
|
+
const matchResult = numTypeMatcher(result);
|
|
999
|
+
if (matchResult.success) {
|
|
1000
|
+
return result;
|
|
1001
|
+
}
|
|
1002
|
+
options?.errors.push({
|
|
1003
|
+
instancePath: options.instancePath,
|
|
1004
|
+
schemaPath: `${options.schemaPath}/type`,
|
|
1005
|
+
message: `Error at ${options.instancePath}. ${matchResult.message}`
|
|
1006
|
+
});
|
|
1007
|
+
return void 0;
|
|
1008
|
+
},
|
|
1009
|
+
serialize: serializeNumber,
|
|
1010
|
+
coerce(input, options) {
|
|
1011
|
+
const result = coerceNumber(input, options);
|
|
1012
|
+
if (typeof result !== "number") {
|
|
1013
|
+
options.errors.push({
|
|
1014
|
+
instancePath: options.instancePath,
|
|
1015
|
+
schemaPath: `${options.schemaPath}/type`,
|
|
1016
|
+
message: `Error at ${options.instancePath}. Unable to coerce ${typeof input} to ${type}.`
|
|
1017
|
+
});
|
|
1018
|
+
return void 0;
|
|
1019
|
+
}
|
|
1020
|
+
const matchResult = numTypeMatcher(result);
|
|
1021
|
+
if (matchResult.success) {
|
|
1022
|
+
return result;
|
|
1023
|
+
}
|
|
1024
|
+
options.errors.push({
|
|
1025
|
+
instancePath: options.instancePath,
|
|
1026
|
+
schemaPath: `${options.schemaPath}/type`,
|
|
1027
|
+
message: `Error at ${options.instancePath}. ${matchResult.message}`
|
|
1028
|
+
});
|
|
1029
|
+
return void 0;
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
function object(propA, propB) {
|
|
1037
|
+
const isIdShorthand = typeof propA === "string";
|
|
1038
|
+
const input = isIdShorthand ? propB : propA;
|
|
1039
|
+
const opts = isIdShorthand ? { id: propA } : propB ?? {};
|
|
1040
|
+
const schema = {
|
|
1041
|
+
properties: {},
|
|
1042
|
+
additionalProperties: typeof opts.additionalProperties === "boolean" ? opts.additionalProperties : true
|
|
1043
|
+
};
|
|
1044
|
+
for (const key of Object.keys(input)) {
|
|
1045
|
+
const prop = input[key];
|
|
1046
|
+
if (prop.metadata[SCHEMA_METADATA].optional) {
|
|
1047
|
+
if (!schema.optionalProperties) {
|
|
1048
|
+
schema.optionalProperties = {};
|
|
1049
|
+
}
|
|
1050
|
+
schema.optionalProperties[key] = prop;
|
|
1051
|
+
continue;
|
|
1052
|
+
}
|
|
1053
|
+
schema.properties[key] = prop;
|
|
1054
|
+
}
|
|
1055
|
+
const result = {
|
|
1056
|
+
...schema,
|
|
1057
|
+
metadata: {
|
|
1058
|
+
id: opts.id,
|
|
1059
|
+
description: opts.description,
|
|
1060
|
+
isDeprecated: opts.isDeprecated,
|
|
1061
|
+
[SCHEMA_METADATA]: {
|
|
1062
|
+
output: {},
|
|
1063
|
+
parse(input2, data) {
|
|
1064
|
+
return parseObjectSchema(
|
|
1065
|
+
schema,
|
|
1066
|
+
input2,
|
|
1067
|
+
data,
|
|
1068
|
+
false
|
|
1069
|
+
);
|
|
1070
|
+
},
|
|
1071
|
+
coerce(input2, data) {
|
|
1072
|
+
return parseObjectSchema(
|
|
1073
|
+
schema,
|
|
1074
|
+
input2,
|
|
1075
|
+
data,
|
|
1076
|
+
true
|
|
1077
|
+
);
|
|
1078
|
+
},
|
|
1079
|
+
validate(input2) {
|
|
1080
|
+
return validateObjectSchema(schema, input2);
|
|
1081
|
+
},
|
|
1082
|
+
serialize(input2, data) {
|
|
1083
|
+
return serializeObject(
|
|
1084
|
+
schema,
|
|
1085
|
+
input2,
|
|
1086
|
+
data
|
|
1087
|
+
);
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
};
|
|
1092
|
+
return result;
|
|
1093
|
+
}
|
|
1094
|
+
function parseObjectSchema(schema, input, data, coerce = false) {
|
|
1095
|
+
let parsedInput = input;
|
|
1096
|
+
if (data.instancePath.length === 0 && typeof input === "string") {
|
|
1097
|
+
try {
|
|
1098
|
+
const result2 = JSON.parse(input);
|
|
1099
|
+
parsedInput = result2;
|
|
1100
|
+
} catch (err) {
|
|
1101
|
+
data.errors.push({
|
|
1102
|
+
instancePath: data.instancePath,
|
|
1103
|
+
schemaPath: `${data.schemaPath}/properties`,
|
|
1104
|
+
message: `Error at ${data.instancePath}. Invalid JSON.`
|
|
1105
|
+
});
|
|
1106
|
+
return void 0;
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
if (!isObject(parsedInput)) {
|
|
1110
|
+
data.errors.push({
|
|
1111
|
+
instancePath: data.instancePath,
|
|
1112
|
+
schemaPath: `${data.schemaPath}/properties`,
|
|
1113
|
+
message: `Error at ${data.instancePath}. Expected object`
|
|
1114
|
+
});
|
|
1115
|
+
return void 0;
|
|
1116
|
+
}
|
|
1117
|
+
const result = {};
|
|
1118
|
+
const optionalProps = schema.optionalProperties ?? {};
|
|
1119
|
+
const inputKeys = Object.keys(parsedInput);
|
|
1120
|
+
const requiredKeys = Object.keys(schema.properties);
|
|
1121
|
+
const optionalKeys = Object.keys(optionalProps);
|
|
1122
|
+
if (!schema.additionalProperties) {
|
|
1123
|
+
for (const key of inputKeys) {
|
|
1124
|
+
if (!requiredKeys.includes(key) && !optionalKeys.includes(key) && key !== data.discriminatorKey) {
|
|
1125
|
+
data.errors.push({
|
|
1126
|
+
instancePath: `${data.instancePath}/${key}`,
|
|
1127
|
+
schemaPath: `${data.schemaPath}/additionalProperties`,
|
|
1128
|
+
message: `Error at ${data.instancePath}/${key}. Key '${key}' is not included in the schema. To allow additional input properties set additionalProperties to 'true'.`
|
|
1129
|
+
});
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
if (data.errors.length) {
|
|
1134
|
+
return void 0;
|
|
1135
|
+
}
|
|
1136
|
+
if (data.discriminatorKey) {
|
|
1137
|
+
result[data.discriminatorKey] = data.discriminatorValue;
|
|
1138
|
+
}
|
|
1139
|
+
for (const key of requiredKeys) {
|
|
1140
|
+
const val = parsedInput[key];
|
|
1141
|
+
const prop = schema.properties[key];
|
|
1142
|
+
if (coerce) {
|
|
1143
|
+
result[key] = prop.metadata[SCHEMA_METADATA].coerce(val, {
|
|
1144
|
+
instancePath: `${data.instancePath}/${key}`,
|
|
1145
|
+
schemaPath: `${data.schemaPath}/properties/${key}`,
|
|
1146
|
+
errors: data.errors
|
|
1147
|
+
});
|
|
1148
|
+
continue;
|
|
1149
|
+
}
|
|
1150
|
+
result[key] = prop.metadata[SCHEMA_METADATA].parse(val, {
|
|
1151
|
+
instancePath: `${data.instancePath}/${key}`,
|
|
1152
|
+
schemaPath: `${data.schemaPath}/properties/${key}`,
|
|
1153
|
+
errors: data.errors
|
|
1154
|
+
});
|
|
1155
|
+
}
|
|
1156
|
+
for (const key of optionalKeys) {
|
|
1157
|
+
const val = parsedInput[key];
|
|
1158
|
+
const prop = optionalProps[key];
|
|
1159
|
+
if (val === void 0) {
|
|
1160
|
+
continue;
|
|
1161
|
+
}
|
|
1162
|
+
if (coerce) {
|
|
1163
|
+
result[key] = prop.metadata[SCHEMA_METADATA].coerce(val, {
|
|
1164
|
+
instancePath: `${data.instancePath}/${key}`,
|
|
1165
|
+
schemaPath: `${data.schemaPath}/optionalProperties/${key}`,
|
|
1166
|
+
errors: data.errors
|
|
1167
|
+
});
|
|
1168
|
+
continue;
|
|
1169
|
+
}
|
|
1170
|
+
if (typeof val !== "undefined") {
|
|
1171
|
+
result[key] = prop.metadata[SCHEMA_METADATA].parse(val, {
|
|
1172
|
+
instancePath: `${data.instancePath}/${key}`,
|
|
1173
|
+
schemaPath: `${data.schemaPath}/optionalProperties/${key}`,
|
|
1174
|
+
errors: data.errors
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
if (data.errors.length) {
|
|
1179
|
+
return void 0;
|
|
1180
|
+
}
|
|
1181
|
+
return result;
|
|
1182
|
+
}
|
|
1183
|
+
function validateObjectSchema(schema, input) {
|
|
1184
|
+
if (!isObject(input)) {
|
|
1185
|
+
return false;
|
|
1186
|
+
}
|
|
1187
|
+
const optionalProps = schema.optionalProperties ?? {};
|
|
1188
|
+
for (const key of Object.keys(input)) {
|
|
1189
|
+
const prop = schema.properties[key] ?? optionalProps[key];
|
|
1190
|
+
if (!prop && !schema.additionalProperties) {
|
|
1191
|
+
return false;
|
|
1192
|
+
}
|
|
1193
|
+
if (prop) {
|
|
1194
|
+
const isValid = prop.metadata[SCHEMA_METADATA].validate(input[key]);
|
|
1195
|
+
if (!isValid) {
|
|
1196
|
+
return false;
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
return true;
|
|
1201
|
+
}
|
|
1202
|
+
function pick(inputSchema, keys, opts = {}) {
|
|
1203
|
+
const schema = {
|
|
1204
|
+
properties: {},
|
|
1205
|
+
nullable: inputSchema.nullable,
|
|
1206
|
+
additionalProperties: typeof opts.additionalProperties === "boolean" ? opts.additionalProperties : true
|
|
1207
|
+
};
|
|
1208
|
+
Object.keys(inputSchema.properties).forEach((key) => {
|
|
1209
|
+
if (!schema.properties) {
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
if (keys.includes(key)) {
|
|
1213
|
+
schema.properties[key] = inputSchema.properties[key];
|
|
1214
|
+
}
|
|
1215
|
+
});
|
|
1216
|
+
if (inputSchema.optionalProperties) {
|
|
1217
|
+
schema.optionalProperties = {};
|
|
1218
|
+
Object.keys(inputSchema.optionalProperties).forEach((key) => {
|
|
1219
|
+
if (!schema.optionalProperties || !inputSchema.optionalProperties) {
|
|
1220
|
+
return;
|
|
1221
|
+
}
|
|
1222
|
+
if (keys.includes(key)) {
|
|
1223
|
+
schema.optionalProperties[key] = inputSchema.optionalProperties[key];
|
|
1224
|
+
}
|
|
1225
|
+
});
|
|
1226
|
+
}
|
|
1227
|
+
return {
|
|
1228
|
+
...schema,
|
|
1229
|
+
metadata: {
|
|
1230
|
+
id: opts.id,
|
|
1231
|
+
description: opts.description,
|
|
1232
|
+
isDeprecated: opts.isDeprecated,
|
|
1233
|
+
[SCHEMA_METADATA]: {
|
|
1234
|
+
output: {},
|
|
1235
|
+
parse: (input, data) => {
|
|
1236
|
+
return parseObjectSchema(schema, input, data, true);
|
|
1237
|
+
},
|
|
1238
|
+
coerce(input, data) {
|
|
1239
|
+
return parseObjectSchema(schema, input, data, false);
|
|
1240
|
+
},
|
|
1241
|
+
validate(input) {
|
|
1242
|
+
return validateObjectSchema(schema, input);
|
|
1243
|
+
},
|
|
1244
|
+
serialize(input, data) {
|
|
1245
|
+
return serializeObject(schema, input, data);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
};
|
|
1250
|
+
}
|
|
1251
|
+
function omit(inputSchema, keys, opts = {}) {
|
|
1252
|
+
const schema = {
|
|
1253
|
+
properties: {
|
|
1254
|
+
...inputSchema.properties
|
|
1255
|
+
},
|
|
1256
|
+
nullable: inputSchema.nullable,
|
|
1257
|
+
additionalProperties: typeof opts.additionalProperties === "boolean" ? opts.additionalProperties : true
|
|
1258
|
+
};
|
|
1259
|
+
Object.keys(inputSchema.properties).forEach((key) => {
|
|
1260
|
+
if (keys.includes(key)) {
|
|
1261
|
+
delete schema.properties[key];
|
|
1262
|
+
}
|
|
1263
|
+
});
|
|
1264
|
+
if (inputSchema.optionalProperties) {
|
|
1265
|
+
schema.optionalProperties = {
|
|
1266
|
+
...inputSchema.optionalProperties
|
|
1267
|
+
};
|
|
1268
|
+
Object.keys(inputSchema.optionalProperties).forEach((key) => {
|
|
1269
|
+
if (!schema.optionalProperties) {
|
|
1270
|
+
return;
|
|
1271
|
+
}
|
|
1272
|
+
if (keys.includes(key)) {
|
|
1273
|
+
delete schema.optionalProperties[key];
|
|
1274
|
+
}
|
|
1275
|
+
});
|
|
1276
|
+
}
|
|
1277
|
+
return {
|
|
1278
|
+
...schema,
|
|
1279
|
+
metadata: {
|
|
1280
|
+
id: opts.id,
|
|
1281
|
+
description: opts.description,
|
|
1282
|
+
isDeprecated: opts.isDeprecated,
|
|
1283
|
+
[SCHEMA_METADATA]: {
|
|
1284
|
+
output: {},
|
|
1285
|
+
validate(input) {
|
|
1286
|
+
return validateObjectSchema(schema, input);
|
|
1287
|
+
},
|
|
1288
|
+
parse(input, data) {
|
|
1289
|
+
return parseObjectSchema(schema, input, data, false);
|
|
1290
|
+
},
|
|
1291
|
+
serialize(input, data) {
|
|
1292
|
+
return serializeObject(schema, input, data);
|
|
1293
|
+
},
|
|
1294
|
+
coerce(input, data) {
|
|
1295
|
+
return parseObjectSchema(schema, input, data, true);
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
};
|
|
1300
|
+
}
|
|
1301
|
+
function serializeObject(schema, input, data) {
|
|
1302
|
+
const strParts = [];
|
|
1303
|
+
if (data.discriminatorKey && data.discriminatorValue) {
|
|
1304
|
+
strParts.push(
|
|
1305
|
+
`"${data.discriminatorKey}":"${data.discriminatorValue}"`
|
|
1306
|
+
);
|
|
1307
|
+
}
|
|
1308
|
+
for (const key of Object.keys(schema.properties)) {
|
|
1309
|
+
const prop = schema.properties[key];
|
|
1310
|
+
const val = input[key];
|
|
1311
|
+
if (typeof val !== "undefined") {
|
|
1312
|
+
strParts.push(
|
|
1313
|
+
`"${key}":${prop.metadata[SCHEMA_METADATA].serialize(val, {
|
|
1314
|
+
instancePath: `${data.instancePath}/${key}`,
|
|
1315
|
+
schemaPath: `${data.schemaPath}/properties/${key}`,
|
|
1316
|
+
errors: data.errors
|
|
1317
|
+
})}`
|
|
1318
|
+
);
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
if (schema.optionalProperties) {
|
|
1322
|
+
for (const key of Object.keys(schema.optionalProperties)) {
|
|
1323
|
+
const prop = schema.optionalProperties[key];
|
|
1324
|
+
const val = input[key];
|
|
1325
|
+
if (typeof val !== "undefined") {
|
|
1326
|
+
strParts.push(
|
|
1327
|
+
`"${key}":${prop.metadata[SCHEMA_METADATA].serialize(val, {
|
|
1328
|
+
instancePath: `${data.instancePath}/${key}`,
|
|
1329
|
+
schemaPath: `${data.schemaPath}/optionalProperties/${key}`,
|
|
1330
|
+
errors: data.errors
|
|
1331
|
+
})}`
|
|
1332
|
+
);
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
return `{${strParts.join(",")}}`;
|
|
1337
|
+
}
|
|
1338
|
+
function extend(baseSchema, inputSchema, opts = {}) {
|
|
1339
|
+
const schema = {
|
|
1340
|
+
properties: {
|
|
1341
|
+
...baseSchema.properties,
|
|
1342
|
+
...inputSchema.properties
|
|
1343
|
+
},
|
|
1344
|
+
optionalProperties: {
|
|
1345
|
+
...baseSchema.optionalProperties,
|
|
1346
|
+
...inputSchema.optionalProperties
|
|
1347
|
+
},
|
|
1348
|
+
additionalProperties: typeof opts.additionalProperties === "boolean" ? opts.additionalProperties : true
|
|
1349
|
+
};
|
|
1350
|
+
const isType = (input) => validateObjectSchema(schema, input);
|
|
1351
|
+
const meta = {
|
|
1352
|
+
id: opts.id,
|
|
1353
|
+
description: opts.description,
|
|
1354
|
+
[SCHEMA_METADATA]: {
|
|
1355
|
+
output: {},
|
|
1356
|
+
parse(input, data) {
|
|
1357
|
+
return parseObjectSchema(schema, input, data, false);
|
|
1358
|
+
},
|
|
1359
|
+
coerce(input, data) {
|
|
1360
|
+
return parseObjectSchema(schema, input, data, true);
|
|
1361
|
+
},
|
|
1362
|
+
validate: isType,
|
|
1363
|
+
serialize(input, data) {
|
|
1364
|
+
return serializeObject(schema, input, data);
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
};
|
|
1368
|
+
schema.metadata = meta;
|
|
1369
|
+
return schema;
|
|
1370
|
+
}
|
|
1371
|
+
function partial(schema, options = {}) {
|
|
1372
|
+
const newSchema = {
|
|
1373
|
+
properties: {},
|
|
1374
|
+
optionalProperties: {},
|
|
1375
|
+
additionalProperties: typeof options.additionalProperties === "boolean" ? options.additionalProperties : true,
|
|
1376
|
+
nullable: schema.nullable
|
|
1377
|
+
};
|
|
1378
|
+
for (const key of Object.keys(schema.properties)) {
|
|
1379
|
+
const prop = schema.properties[key];
|
|
1380
|
+
newSchema.optionalProperties[key] = optional(prop);
|
|
1381
|
+
}
|
|
1382
|
+
if (schema.optionalProperties && newSchema.optionalProperties) {
|
|
1383
|
+
for (const key of Object.keys(schema.optionalProperties)) {
|
|
1384
|
+
const prop = schema.optionalProperties[key];
|
|
1385
|
+
if (prop.metadata[SCHEMA_METADATA].optional) {
|
|
1386
|
+
newSchema.optionalProperties[key] = prop;
|
|
1387
|
+
} else {
|
|
1388
|
+
newSchema.optionalProperties[key] = optional(prop);
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
const meta = {
|
|
1393
|
+
id: options.id,
|
|
1394
|
+
description: options.description,
|
|
1395
|
+
[SCHEMA_METADATA]: {
|
|
1396
|
+
output: {},
|
|
1397
|
+
optional: schema.metadata[SCHEMA_METADATA].optional,
|
|
1398
|
+
validate(input) {
|
|
1399
|
+
return validateObjectSchema(newSchema, input);
|
|
1400
|
+
},
|
|
1401
|
+
parse(input, data) {
|
|
1402
|
+
return parseObjectSchema(newSchema, input, data, false);
|
|
1403
|
+
},
|
|
1404
|
+
coerce(input, data) {
|
|
1405
|
+
return parseObjectSchema(newSchema, input, data, true);
|
|
1406
|
+
},
|
|
1407
|
+
serialize(input, data) {
|
|
1408
|
+
return serializeObject(schema, input, data);
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
};
|
|
1412
|
+
newSchema.metadata = meta;
|
|
1413
|
+
return newSchema;
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
function record(schema, opts = {}) {
|
|
1417
|
+
return {
|
|
1418
|
+
values: schema,
|
|
1419
|
+
metadata: {
|
|
1420
|
+
id: opts.id,
|
|
1421
|
+
description: opts.description,
|
|
1422
|
+
isDeprecated: opts.isDeprecated,
|
|
1423
|
+
[SCHEMA_METADATA]: {
|
|
1424
|
+
output: {},
|
|
1425
|
+
validate(input) {
|
|
1426
|
+
if (!isObject(input)) {
|
|
1427
|
+
return false;
|
|
1428
|
+
}
|
|
1429
|
+
for (const key of Object.keys(input)) {
|
|
1430
|
+
const val = input[key];
|
|
1431
|
+
const isValid = schema.metadata[SCHEMA_METADATA].validate(val);
|
|
1432
|
+
if (!isValid) {
|
|
1433
|
+
return false;
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
return true;
|
|
1437
|
+
},
|
|
1438
|
+
parse(input, data) {
|
|
1439
|
+
return parse$2(schema, input, data, false);
|
|
1440
|
+
},
|
|
1441
|
+
coerce(input, data) {
|
|
1442
|
+
return parse$2(schema, input, data, true);
|
|
1443
|
+
},
|
|
1444
|
+
serialize(input, data) {
|
|
1445
|
+
const strParts = [];
|
|
1446
|
+
for (const key of Object.keys(input)) {
|
|
1447
|
+
const val = input[key];
|
|
1448
|
+
strParts.push(
|
|
1449
|
+
`"${key}":${schema.metadata[SCHEMA_METADATA].serialize(val, {
|
|
1450
|
+
instancePath: `${data.instancePath}/${key}`,
|
|
1451
|
+
schemaPath: `${data.schemaPath}/values`,
|
|
1452
|
+
errors: data.errors
|
|
1453
|
+
})}`
|
|
1454
|
+
);
|
|
1455
|
+
}
|
|
1456
|
+
const result = `{${strParts.join(",")}}`;
|
|
1457
|
+
if (data.instancePath.length === 0) {
|
|
1458
|
+
return sanitizeJson(result);
|
|
1459
|
+
}
|
|
1460
|
+
return result;
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
};
|
|
1465
|
+
}
|
|
1466
|
+
function parse$2(schema, input, data, coerce = false) {
|
|
1467
|
+
let parsedInput = input;
|
|
1468
|
+
if (data.instancePath.length === 0 && typeof input === "string") {
|
|
1469
|
+
parsedInput = JSON.parse(input);
|
|
1470
|
+
}
|
|
1471
|
+
if (!isObject(parsedInput)) {
|
|
1472
|
+
data.errors.push({
|
|
1473
|
+
instancePath: data.instancePath,
|
|
1474
|
+
schemaPath: `${data.schemaPath}/values`,
|
|
1475
|
+
message: `Error at ${data.instancePath} Expected object`
|
|
1476
|
+
});
|
|
1477
|
+
return void 0;
|
|
1478
|
+
}
|
|
1479
|
+
const result = {};
|
|
1480
|
+
for (const key of Object.keys(parsedInput)) {
|
|
1481
|
+
const val = parsedInput[key];
|
|
1482
|
+
if (coerce) {
|
|
1483
|
+
result[key] = schema.metadata[SCHEMA_METADATA].coerce(val, {
|
|
1484
|
+
instancePath: `${data.instancePath}/${key}`,
|
|
1485
|
+
schemaPath: `${data.schemaPath}/values`,
|
|
1486
|
+
errors: data.errors
|
|
1487
|
+
});
|
|
1488
|
+
} else {
|
|
1489
|
+
result[key] = schema.metadata[SCHEMA_METADATA].parse(val, {
|
|
1490
|
+
instancePath: `${data.instancePath}/${key}`,
|
|
1491
|
+
schemaPath: `${data.schemaPath}/values`,
|
|
1492
|
+
errors: data.errors
|
|
1493
|
+
});
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
if (data.errors.length) {
|
|
1497
|
+
return void 0;
|
|
1498
|
+
}
|
|
1499
|
+
return result;
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
let recursiveTypeCount = 0;
|
|
1503
|
+
function recursive(propA, propB) {
|
|
1504
|
+
const isIdShorthand = typeof propA === "string";
|
|
1505
|
+
const callback = isIdShorthand ? propB : propA;
|
|
1506
|
+
const options = isIdShorthand ? { id: propA } : propB ?? {};
|
|
1507
|
+
const recursiveFns = {};
|
|
1508
|
+
if (!options.id) {
|
|
1509
|
+
recursiveTypeCount++;
|
|
1510
|
+
console.warn(
|
|
1511
|
+
`[@arrirpc/schema] WARNING: It is highly recommended to specify an ID for recursive types.`
|
|
1512
|
+
);
|
|
1513
|
+
}
|
|
1514
|
+
const id = options.id ?? `TypeRef${recursiveTypeCount}`;
|
|
1515
|
+
const mainSchema = callback({
|
|
1516
|
+
ref: id,
|
|
1517
|
+
metadata: {
|
|
1518
|
+
[SCHEMA_METADATA]: {
|
|
1519
|
+
output: "",
|
|
1520
|
+
parse(input, data) {
|
|
1521
|
+
if (recursiveFns[id]) {
|
|
1522
|
+
return recursiveFns[id].parse(input, data);
|
|
1523
|
+
}
|
|
1524
|
+
},
|
|
1525
|
+
serialize(input, data) {
|
|
1526
|
+
if (recursiveFns[id]) {
|
|
1527
|
+
return recursiveFns[id].serialize(input, data);
|
|
1528
|
+
}
|
|
1529
|
+
return "";
|
|
1530
|
+
},
|
|
1531
|
+
validate(input) {
|
|
1532
|
+
if (recursiveFns[id]) {
|
|
1533
|
+
return recursiveFns[id].validate(input);
|
|
1534
|
+
}
|
|
1535
|
+
return false;
|
|
1536
|
+
},
|
|
1537
|
+
coerce(input, data) {
|
|
1538
|
+
if (recursiveFns[id]) {
|
|
1539
|
+
return recursiveFns[id].coerce(input, data);
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
});
|
|
1545
|
+
mainSchema.metadata.id = id;
|
|
1546
|
+
mainSchema.metadata.description = options?.description ?? mainSchema.metadata.description;
|
|
1547
|
+
mainSchema.metadata.isDeprecated = options?.isDeprecated ?? mainSchema.metadata.isDeprecated;
|
|
1548
|
+
recursiveFns[id] = {
|
|
1549
|
+
validate: mainSchema.metadata[SCHEMA_METADATA].validate,
|
|
1550
|
+
parse: mainSchema.metadata[SCHEMA_METADATA].parse,
|
|
1551
|
+
serialize: mainSchema.metadata[SCHEMA_METADATA].serialize,
|
|
1552
|
+
coerce: mainSchema.metadata[SCHEMA_METADATA].coerce
|
|
1553
|
+
};
|
|
1554
|
+
return mainSchema;
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
function string(opts = {}) {
|
|
1558
|
+
return {
|
|
1559
|
+
type: "string",
|
|
1560
|
+
metadata: {
|
|
1561
|
+
id: opts.id,
|
|
1562
|
+
description: opts.description,
|
|
1563
|
+
isDeprecated: opts.isDeprecated,
|
|
1564
|
+
[SCHEMA_METADATA]: {
|
|
1565
|
+
output: "",
|
|
1566
|
+
parse: parse$1,
|
|
1567
|
+
coerce: coerce$1,
|
|
1568
|
+
validate: validate$1,
|
|
1569
|
+
serialize(input, data) {
|
|
1570
|
+
if (data.instancePath.length === 0) {
|
|
1571
|
+
return input;
|
|
1572
|
+
}
|
|
1573
|
+
if (input.length < 42) {
|
|
1574
|
+
return serializeSmallString(input);
|
|
1575
|
+
}
|
|
1576
|
+
if (input.length < 5e3 && !STR_ESCAPE.test(input)) {
|
|
1577
|
+
return `"${input}"`;
|
|
1578
|
+
}
|
|
1579
|
+
return JSON.stringify(input);
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
};
|
|
1584
|
+
}
|
|
1585
|
+
function validate$1(input) {
|
|
1586
|
+
return typeof input === "string";
|
|
1587
|
+
}
|
|
1588
|
+
function parse$1(input, context) {
|
|
1589
|
+
if (validate$1(input)) {
|
|
1590
|
+
return input;
|
|
1591
|
+
}
|
|
1592
|
+
context.errors.push({
|
|
1593
|
+
instancePath: context.instancePath,
|
|
1594
|
+
schemaPath: `${context.schemaPath}/type`,
|
|
1595
|
+
message: `Error at ${context.instancePath}. Expected 'string' got ${typeof input}.`
|
|
1596
|
+
});
|
|
1597
|
+
return void 0;
|
|
1598
|
+
}
|
|
1599
|
+
function coerce$1(input, context) {
|
|
1600
|
+
return parse$1(input, context);
|
|
1601
|
+
}
|
|
1602
|
+
const STR_ESCAPE = (
|
|
1603
|
+
// eslint-disable-next-line no-control-regex
|
|
1604
|
+
/[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/
|
|
1605
|
+
);
|
|
1606
|
+
function serializeSmallString(input) {
|
|
1607
|
+
const len = input.length;
|
|
1608
|
+
let result = "";
|
|
1609
|
+
let last = -1;
|
|
1610
|
+
let point = 255;
|
|
1611
|
+
for (let i = 0; i < len; i++) {
|
|
1612
|
+
point = input.charCodeAt(i);
|
|
1613
|
+
if (point < 32 || point >= 55296 && point <= 57343) {
|
|
1614
|
+
return JSON.stringify(input);
|
|
1615
|
+
}
|
|
1616
|
+
if (point === 34 || // '"'
|
|
1617
|
+
point === 92) {
|
|
1618
|
+
if (last === -1) {
|
|
1619
|
+
last = 0;
|
|
1620
|
+
}
|
|
1621
|
+
result += input.slice(last, i) + "\\";
|
|
1622
|
+
last = i;
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
if (last === -1) {
|
|
1626
|
+
return `"${input}"`;
|
|
1627
|
+
}
|
|
1628
|
+
return `"${result}${input.slice(last)}"`;
|
|
1629
|
+
}
|
|
1630
|
+
|
|
1631
|
+
function timestamp(opts = {}) {
|
|
1632
|
+
return {
|
|
1633
|
+
type: "timestamp",
|
|
1634
|
+
metadata: {
|
|
1635
|
+
id: opts.id,
|
|
1636
|
+
description: opts.description,
|
|
1637
|
+
isDeprecated: opts.isDeprecated,
|
|
1638
|
+
[SCHEMA_METADATA]: {
|
|
1639
|
+
output: /* @__PURE__ */ new Date(),
|
|
1640
|
+
validate,
|
|
1641
|
+
parse,
|
|
1642
|
+
coerce,
|
|
1643
|
+
serialize
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
};
|
|
1647
|
+
}
|
|
1648
|
+
function validate(input) {
|
|
1649
|
+
return typeof input === "object" && input instanceof Date;
|
|
1650
|
+
}
|
|
1651
|
+
function parse(input, data) {
|
|
1652
|
+
if (validate(input)) {
|
|
1653
|
+
return input;
|
|
1654
|
+
}
|
|
1655
|
+
if (typeof input === "string") {
|
|
1656
|
+
const result = Date.parse(input);
|
|
1657
|
+
if (Number.isNaN(result)) {
|
|
1658
|
+
data?.errors.push({
|
|
1659
|
+
message: `Error at ${data.instancePath}. Invalid date string.`,
|
|
1660
|
+
instancePath: data.instancePath,
|
|
1661
|
+
schemaPath: `${data.schemaPath}/type`
|
|
1662
|
+
});
|
|
1663
|
+
return void 0;
|
|
1664
|
+
}
|
|
1665
|
+
return new Date(result);
|
|
1666
|
+
}
|
|
1667
|
+
data.errors.push({
|
|
1668
|
+
message: `Error at ${data.instancePath}. Invalid date.`,
|
|
1669
|
+
instancePath: data.instancePath,
|
|
1670
|
+
schemaPath: `${data.schemaPath}/type`
|
|
1671
|
+
});
|
|
1672
|
+
return void 0;
|
|
1673
|
+
}
|
|
1674
|
+
function coerce(input, options) {
|
|
1675
|
+
if (typeof input === "number") {
|
|
1676
|
+
return new Date(input);
|
|
1677
|
+
}
|
|
1678
|
+
return parse(input, options);
|
|
1679
|
+
}
|
|
1680
|
+
function serialize(input, data) {
|
|
1681
|
+
if (data.instancePath.length === 0) {
|
|
1682
|
+
return input.toISOString();
|
|
1683
|
+
}
|
|
1684
|
+
return `"${input.toISOString()}"`;
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
export { uint64 as $, enumerator as A, extend as B, float32 as C, float64 as D, int16 as E, int32 as F, int64 as G, int8 as H, nullable as I, number as J, object as K, omit as L, optional as M, parse$4 as N, partial as O, pick as P, record as Q, recursive as R, safeCoerce as S, safeParse as T, serialize$1 as U, ValidationError as V, string as W, stringEnum as X, timestamp as Y, uint16 as Z, uint32 as _, uint8Min as a, uint8 as a0, validate$3 as a1, isASchema as a2, SCHEMA_METADATA as a3, int64Min as a4, int64Max as a5, uint64Min as a6, uint64Max as a7, parseObjectSchema as a8, validateObjectSchema as a9, serializeObject as aa, serializeSmallString as ab, sanitizeJson as ac, isValidationError as ad, NumberTypeValues as ae, isObject as af, uint16Max as b, uint16Min as c, uint32Max as d, uint32Min as e, int8Min as f, int16Max as g, int16Min as h, int8Max as i, int32Max as j, int32Min as k, isAScalarSchema as l, isAObjectSchema as m, isAStringEnumSchema as n, isAAraySchema as o, isARecordSchema as p, isADiscriminatorSchema as q, isARefSchema as r, errors as s, any as t, uint8Max as u, array as v, boolean as w, clone as x, coerce$2 as y, discriminator as z };
|