@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,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 };