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