@lucania/schema 2.0.3 → 2.0.4

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.
@@ -1,5 +1,5 @@
1
1
  import { BaseSchemaAny } from "./typing/extended";
2
- import { DefaultValue, ModelValue, TypedMembers } from "./typing/toolbox";
2
+ import { DefaultValue, ModelValue } from "./typing/toolbox";
3
3
  import { AnySchema } from "./schema/AnySchema";
4
4
  import { ArraySchema, ArraySource } from "./schema/ArraySchema";
5
5
  import { BooleanSchema, BooleanSource } from "./schema/BooleanSchema";
@@ -33,17 +33,23 @@ export declare namespace Schema {
33
33
  function Array<Subschema extends BaseSchemaAny>(subschema: Subschema): ArraySchema<Subschema, true, undefined>;
34
34
  function Array<Subschema extends BaseSchemaAny, Required extends boolean>(subschema: Subschema, required: Required): ArraySchema<Subschema, Required, undefined>;
35
35
  function Array<Subschema extends BaseSchemaAny, Required extends boolean, Default extends DefaultValue<ArraySource<Subschema>>>(subschema: Subschema, required: Required, defaultValue: Default): ArraySchema<Subschema, Required, Default>;
36
- function Enumeration<Members extends string[]>(subschema: TypedMembers<Members>): EnumerationSchema<Members, true, undefined>;
37
- function Enumeration<Members extends string[], Required extends boolean>(subschema: TypedMembers<Members>, required: Required): EnumerationSchema<Members, Required, undefined>;
38
- function Enumeration<Members extends string[], Required extends boolean, Default extends DefaultValue<Members[number]>>(subschema: TypedMembers<Members>, required: Required, defaultValue: Default): EnumerationSchema<Members, Required, Default>;
36
+ function Enumeration<Member extends string>(subschema: TypedMembers<Member>): EnumerationSchema<Member, true, undefined>;
37
+ function Enumeration<Member extends string, Required extends boolean>(subschema: TypedMembers<Member>, required: Required): EnumerationSchema<Member, Required, undefined>;
38
+ function Enumeration<Member extends string, Required extends boolean, Default extends DefaultValue<Member>>(subschema: TypedMembers<Member>, required: Required, defaultValue: Default): EnumerationSchema<Member, Required, Default>;
39
39
  function DynamicObject<Subschema extends BaseSchemaAny>(subschema: Subschema): DynamicObjectSchema<Subschema, true, undefined>;
40
40
  function DynamicObject<Subschema extends BaseSchemaAny, Required extends boolean>(subschema: Subschema, required: Required): DynamicObjectSchema<Subschema, Required, undefined>;
41
41
  function DynamicObject<Subschema extends BaseSchemaAny, Required extends boolean, Default extends DefaultValue<DynamicObjectSource<Subschema>>>(subschema: Subschema, required: Required, defaultValue: Default): DynamicObjectSchema<Subschema, Required, Default>;
42
- function OrSet<MemberSchemas extends BaseSchemaAny[]>(subschema: TypedMembers<MemberSchemas>): OrSetSchema<MemberSchemas, true, undefined>;
43
- function OrSet<MemberSchemas extends BaseSchemaAny[], Required extends boolean>(subschema: TypedMembers<MemberSchemas>, required: Required): OrSetSchema<MemberSchemas, Required, undefined>;
44
- function OrSet<MemberSchemas extends BaseSchemaAny[], Required extends boolean, Default extends DefaultValue<OrSetSchemaSource<MemberSchemas>>>(subschema: TypedMembers<MemberSchemas>, required: Required, defaultValue: Default): OrSetSchema<MemberSchemas, Required, Default>;
45
- function Members<Members extends string[]>(...members: Members): TypedMembers<Members>;
46
- function Members<Members extends any[]>(...members: Members): TypedMembers<Members>;
42
+ function OrSet<MemberSchema extends BaseSchemaAny>(subschema: TypedMembers<MemberSchema>): OrSetSchema<MemberSchema, true, undefined>;
43
+ function OrSet<MemberSchema extends BaseSchemaAny, Required extends boolean>(subschema: TypedMembers<MemberSchema>, required: Required): OrSetSchema<MemberSchema, Required, undefined>;
44
+ function OrSet<MemberSchema extends BaseSchemaAny, Required extends boolean, Default extends DefaultValue<OrSetSchemaSource<MemberSchema>>>(subschema: TypedMembers<MemberSchema>, required: Required, defaultValue: Default): OrSetSchema<MemberSchema, Required, Default>;
45
+ type TypedMembers<Member extends any> = {
46
+ $members: Member[];
47
+ };
48
+ function Members<Member extends string[]>(...members: Member): TypedMembers<Member[number]>;
49
+ function Members<Member extends number[]>(...members: Member): TypedMembers<Member[number]>;
50
+ function Members<Member extends any[]>(...members: Member): TypedMembers<Member[number]>;
51
+ function Keys<Object extends object>(object: Object): (keyof Object)[];
52
+ function Values<Object extends object>(object: Object): (Object[keyof Object])[];
47
53
  type Model<Schema extends BaseSchemaAny> = Schema extends BaseSchema<infer Source, infer Model, infer Require, infer Default> ? (ModelValue<Source, Model, Require, Default>) : never;
48
54
  type Source<Schema extends BaseSchemaAny> = Schema extends BaseSchema<infer Source, any, infer Require, infer Default> ? (SourceValue<Source, Require, Default>) : never;
49
55
  }
package/build/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export * from "./builder";
2
- export { Schema as $ } from "./builder";
3
2
  export * from "./error/ValidationError";
4
3
  export * from "./error/ValidationPass";
5
4
  export * from "./schema/AnySchema";
@@ -15,3 +14,4 @@ export * from "./schema/OrSetSchema";
15
14
  export * from "./schema/StringSchema";
16
15
  export * from "./typing/extended";
17
16
  export * from "./typing/toolbox";
17
+ export { Schema as $ } from "./builder";
package/build/index.js CHANGED
@@ -8,6 +8,7 @@
8
8
  pass;
9
9
  constructor(pass, message) {
10
10
  super(message);
11
+ this.name = ValidationError.name;
11
12
  this.pass = pass;
12
13
  }
13
14
  }
@@ -182,6 +183,29 @@
182
183
  }
183
184
  return source;
184
185
  }
186
+ /**
187
+ * Converts this schema to a informational string representing this schema.
188
+ *
189
+ * @note Details about this schema will be displayed in [square brackets].
190
+ * * [R] Indicates this schema is required.
191
+ * * [D] Indicates this schema has a default value.
192
+ *
193
+ * @param level The nesting level. You needn't specify this externally.
194
+ * @returns A string representation of this schema.
195
+ */
196
+ toString(level = 0) {
197
+ const modifiers = [];
198
+ if (this._required)
199
+ modifiers.push("R");
200
+ if (this._default !== undefined)
201
+ modifiers.push("D");
202
+ if (modifiers.length > 0) {
203
+ return `${this.constructor.name}[${modifiers.join("")}]`;
204
+ }
205
+ else {
206
+ return this.constructor.name;
207
+ }
208
+ }
185
209
  /**
186
210
  * Checks to see if a value is present. (Not null or undefined)
187
211
  * @param value The value to check the presence of.
@@ -224,12 +248,15 @@
224
248
  getJsonSchema() {
225
249
  return { description: this._getJsonSchemaDescription() };
226
250
  }
251
+ clone() {
252
+ return new AnySchema(this._required, this._default, this._additionalValidationPasses);
253
+ }
227
254
  }
228
255
 
229
256
  class ArraySchema extends BaseSchema {
230
257
  subschema;
231
- constructor(subschema, required, defaultValue) {
232
- super(required, defaultValue);
258
+ constructor(subschema, required, defaultValue, additionalValidationPasses) {
259
+ super(required, defaultValue, additionalValidationPasses);
233
260
  this.subschema = subschema;
234
261
  }
235
262
  get type() { return "array"; }
@@ -273,6 +300,12 @@
273
300
  items: this.subschema.getJsonSchema()
274
301
  };
275
302
  }
303
+ clone() {
304
+ return new ArraySchema(this.subschema.clone(), this._required, this._default, this._additionalValidationPasses);
305
+ }
306
+ toString(level = 0) {
307
+ return `${super.toString(level)}(${this.subschema.toString(level)}[])`;
308
+ }
276
309
  }
277
310
 
278
311
  class BooleanSchema extends BaseSchema {
@@ -299,6 +332,9 @@
299
332
  throw pass.getError(`Unable to convert ${BaseSchema.getType(value)} to boolean.`);
300
333
  }
301
334
  }
335
+ clone() {
336
+ return new BooleanSchema(this._required, this._default, this._additionalValidationPasses);
337
+ }
302
338
  getJsonSchema() {
303
339
  return {
304
340
  type: "boolean",
@@ -358,6 +394,9 @@
358
394
  return model;
359
395
  }, "afterAll");
360
396
  }
397
+ clone() {
398
+ return new DateSchema(this._required, this._default, this._additionalValidationPasses);
399
+ }
361
400
  getJsonSchema() {
362
401
  return {
363
402
  type: "string",
@@ -368,8 +407,8 @@
368
407
 
369
408
  class DynamicObjectSchema extends BaseSchema {
370
409
  subschema;
371
- constructor(subschema, required, defaultValue) {
372
- super(required, defaultValue);
410
+ constructor(subschema, required, defaultValue, additionalValidationPasses) {
411
+ super(required, defaultValue, additionalValidationPasses);
373
412
  this.subschema = subschema;
374
413
  }
375
414
  get type() { return "object"; }
@@ -410,30 +449,36 @@
410
449
  additionalProperties: this.subschema.getJsonSchema()
411
450
  };
412
451
  }
452
+ clone() {
453
+ return new DynamicObjectSchema(this.subschema.clone(), this._required, this._default, this._additionalValidationPasses);
454
+ }
455
+ toString(level = 0) {
456
+ const indent = " ";
457
+ const prefix = indent.repeat(level);
458
+ return `${super.toString(level)}({\n${prefix}${indent}[string]: ${this.subschema.toString(level)}\n${prefix}})`;
459
+ }
413
460
  }
414
461
 
415
462
  class EnumerationSchema extends BaseSchema {
416
463
  members;
417
- constructor(members, required, defaultValue) {
418
- super(required, defaultValue);
464
+ constructor(members, required, defaultValue, additionalValidationPasses) {
465
+ super(required, defaultValue, additionalValidationPasses);
419
466
  this.members = members;
420
467
  }
421
468
  get type() { return "string"; }
422
- // public validate(source: SourceValue<Members[number], Required, Default>, pass?: ValidationPass):
423
- // ModelValue<Members[number], Members[number], Required, Default> {
424
- // pass = this._ensurePass(source, pass);
425
- // const result: any = super.validate(source, pass);
426
- // pass.assert(this.members.includes(result), `"${result}" is not a valid enumeration value (Expected: ${this.members.join(", ")}).`);
427
- // return result;
428
- // }
429
469
  _validate(source, pass) {
430
470
  const result = source;
431
- pass.assert(this.members.includes(result), `"${result}" is not a valid enumeration value (Expected: ${this.members.join(", ")}).`);
471
+ if (this._required) {
472
+ pass.assert(this.members.includes(result), `"${result}" is not a valid enumeration value (Expected: ${this.members.join(", ")}).`);
473
+ }
432
474
  return result;
433
475
  }
434
476
  convert(value, pass) {
435
477
  return value;
436
478
  }
479
+ clone() {
480
+ return new EnumerationSchema([...this.members], this._required, this._default, this._additionalValidationPasses);
481
+ }
437
482
  getJsonSchema() {
438
483
  return {
439
484
  type: "string",
@@ -489,6 +534,9 @@
489
534
  return model;
490
535
  }, "afterAll");
491
536
  }
537
+ clone() {
538
+ return new NumberSchema(this._required, this._default, this._additionalValidationPasses);
539
+ }
492
540
  getJsonSchema() {
493
541
  return {
494
542
  type: "number",
@@ -499,26 +547,11 @@
499
547
 
500
548
  class ObjectSchema extends BaseSchema {
501
549
  subschema;
502
- constructor(subschema, required, defaultValue) {
503
- super(required, defaultValue);
550
+ constructor(subschema, required, defaultValue, additionalValidationPasses) {
551
+ super(required, defaultValue, additionalValidationPasses);
504
552
  this.subschema = subschema;
505
553
  }
506
554
  get type() { return "object"; }
507
- // public validate(source: SourceValue<ObjectSource<Subschema>, Required, Default>, pass?: ValidationPass):
508
- // ModelValue<ObjectSource<Subschema>, ObjectModel<Subschema>, Required, Default> {
509
- // pass = this._ensurePass(source, pass);
510
- // const input: any = super.validate(source, pass);
511
- // let output: any = input;
512
- // if (typeof input === "object" && input !== null) {
513
- // output = {};
514
- // for (const key in this.subschema) {
515
- // const nestedSchema = this.subschema[key];
516
- // const nestedValue = input[key];
517
- // output[key] = this.subschema[key].validate(input[key], pass.next([...pass.path, key], nestedSchema, nestedValue));
518
- // }
519
- // }
520
- // return output;
521
- // }
522
555
  _validate(source, pass) {
523
556
  const input = source;
524
557
  let output = input;
@@ -568,39 +601,36 @@
568
601
  properties
569
602
  };
570
603
  }
604
+ clone() {
605
+ const subschema = {};
606
+ for (const key in this.subschema) {
607
+ subschema[key] = this.subschema[key].clone();
608
+ }
609
+ return new ObjectSchema(subschema, this._required, this._default, this._additionalValidationPasses);
610
+ }
611
+ toString(level = 0) {
612
+ const indent = " ";
613
+ const prefix = indent.repeat(level);
614
+ const pieces = [];
615
+ pieces.push(`${super.toString()}({\n`);
616
+ for (const schemaKey in this.subschema) {
617
+ const subschema = this.subschema[schemaKey];
618
+ pieces.push(`${prefix}${indent}${schemaKey}: ${subschema.toString(level + 1)}\n`);
619
+ }
620
+ pieces.push(`${prefix}})`);
621
+ return pieces.join("");
622
+ }
571
623
  }
572
624
 
573
625
  class OrSetSchema extends BaseSchema {
574
626
  schemas;
575
- constructor(schemas, required, defaultValue) {
576
- super(required, defaultValue);
627
+ constructor(schemas, required, defaultValue, additionalValidationPasses) {
628
+ super(required, defaultValue, additionalValidationPasses);
577
629
  this.schemas = schemas;
578
630
  }
579
- get type() { return "string"; }
580
- // public validate(source: SourceValue<OrSetSchemaSource<MemberSchemas>, Required, Default>, pass?: ValidationPass):
581
- // ModelValue<OrSetSchemaSource<MemberSchemas>, OrSetSchemaModel<MemberSchemas>, Required, Default> {
582
- // pass = this._ensurePass(source, pass);
583
- // let result: any = super.validate(source, pass);
584
- // if (result !== undefined) {
585
- // let done = false;
586
- // const failureMessages: string[] = [];
587
- // for (let i = 0; i < this.schemas.length && !done; i++) {
588
- // const schema = this.schemas[i];
589
- // try {
590
- // result = schema.validate(result, pass);
591
- // done = true;
592
- // } catch (error) {
593
- // if (error instanceof Error) {
594
- // failureMessages.push(`Schema #${i + 1}: ${error.message}`);
595
- // } else {
596
- // failureMessages.push(`Schema #${i + 1}: ${String(error)}`);
597
- // }
598
- // pass.assert(failureMessages.length !== this.schemas.length, `Supplied value didn't match any schemas in or-set.\n${failureMessages.join("\n")}`);
599
- // }
600
- // }
601
- // }
602
- // return result;
603
- // }
631
+ get type() {
632
+ return "string";
633
+ }
604
634
  _validate(source, pass) {
605
635
  let result = source;
606
636
  if (result !== undefined) {
@@ -609,8 +639,10 @@
609
639
  for (let i = 0; i < this.schemas.length && !done; i++) {
610
640
  const schema = this.schemas[i];
611
641
  try {
612
- result = schema.validate(result, pass);
613
- done = true;
642
+ if (BaseSchema.getType(result) === schema.type) {
643
+ result = schema.validate(result, pass);
644
+ done = true;
645
+ }
614
646
  }
615
647
  catch (error) {
616
648
  if (error instanceof Error) {
@@ -619,15 +651,22 @@
619
651
  else {
620
652
  failureMessages.push(`Schema #${i + 1}: ${String(error)}`);
621
653
  }
622
- pass.assert(failureMessages.length !== this.schemas.length, `Supplied value didn't match any schemas in or-set.\n${failureMessages.join("\n")}`);
623
654
  }
624
655
  }
656
+ if (!done) {
657
+ failureMessages.push(`Conversions for schemas in an OrSet are disabled.`);
658
+ }
659
+ pass.assert(failureMessages.length === 0, `Provided value (${BaseSchema.getType(result)}) matched no schemas ` +
660
+ `(${this.schemas.map((schema) => schema.type).join(", ")}).\n${failureMessages.join("\n")}`);
625
661
  }
626
662
  return result;
627
663
  }
628
664
  convert(value, pass) {
629
665
  return value;
630
666
  }
667
+ clone() {
668
+ return new OrSetSchema(this.schemas.map((schema) => schema.clone()), this._required, this._default, this._additionalValidationPasses);
669
+ }
631
670
  getJsonSchema() {
632
671
  return { oneOf: this.schemas.map((schema) => schema.getJsonSchema()) };
633
672
  }
@@ -654,6 +693,25 @@
654
693
  }
655
694
  return value.toString();
656
695
  }
696
+ /**
697
+ * Trims strings validated by this schema.
698
+ * @see {@link String.trim}
699
+ */
700
+ trim() {
701
+ return this.custom((model) => model.trim());
702
+ }
703
+ /**
704
+ * Makes strings validated by this schema lowercase.
705
+ */
706
+ lower() {
707
+ return this.custom((model) => model.toLowerCase());
708
+ }
709
+ /**
710
+ * Makes strings validated by this schema uppercase.
711
+ */
712
+ upper() {
713
+ return this.custom((model) => model.toUpperCase());
714
+ }
657
715
  length(minimum, maximum, messageA, messageB) {
658
716
  return this.custom((model, pass) => {
659
717
  messageB = messageB === undefined ? messageA : messageB;
@@ -662,12 +720,19 @@
662
720
  return model;
663
721
  }, "afterAll");
664
722
  }
723
+ /**
724
+ * Ensures a string validated by this schema matches a given regular expression.
725
+ * With an optional custom error message.
726
+ */
665
727
  regex(expression, message) {
666
728
  return this.custom((model, pass) => {
667
729
  pass.assert(expression.test(model), message === undefined ? `String "${model}" failed regular expression check. (${expression})` : message);
668
730
  return model;
669
731
  }, "afterAll");
670
732
  }
733
+ clone() {
734
+ return new StringSchema(this._required, this._default, this._additionalValidationPasses);
735
+ }
671
736
  getJsonSchema() {
672
737
  return {
673
738
  type: "string",
@@ -719,9 +784,26 @@
719
784
  }
720
785
  Schema.OrSet = OrSet;
721
786
  function Members(...members) {
787
+ /*
788
+ * HACK START: The hermes JS engine doesn't use globalThis.Array when interpreting `...members`
789
+ * It uses `Array`, which is already defined in this namespace.
790
+ */
791
+ if (!globalThis.Array.isArray(members)) {
792
+ const validArrayEntries = globalThis.Object.entries(members).filter(([key]) => !isNaN(key));
793
+ members = validArrayEntries.map(([_, value]) => value);
794
+ }
795
+ /* HACK END */
722
796
  return { $members: members };
723
797
  }
724
798
  Schema.Members = Members;
799
+ function Keys(object) {
800
+ return globalThis.Object.keys(object);
801
+ }
802
+ Schema.Keys = Keys;
803
+ function Values(object) {
804
+ return globalThis.Object.values(object);
805
+ }
806
+ Schema.Values = Values;
725
807
  })(exports.Schema || (exports.Schema = {}));
726
808
 
727
809
  exports.$ = exports.Schema;
@@ -1,9 +1,10 @@
1
- import { DefaultValue, ModelValue, SourceValue } from "../typing/toolbox";
2
1
  import { ValidationPass } from "../error/ValidationPass";
2
+ import { DefaultValue, ModelValue } from "../typing/toolbox";
3
3
  import { BaseSchema } from "./BaseSchema";
4
4
  export declare class AnySchema<Required extends boolean, Default extends DefaultValue<any>> extends BaseSchema<any, any, Required, Default> {
5
5
  get type(): string;
6
- protected _validate(source: SourceValue<any, Required, Default>, pass: ValidationPass): ModelValue<any, any, Required, Default>;
6
+ protected _validate(source: ModelValue<any, any, Required, Default>, pass: ValidationPass): ModelValue<any, any, Required, Default>;
7
7
  convert(value: any, pass: ValidationPass): any;
8
8
  getJsonSchema(): object;
9
+ clone(): AnySchema<Required, Default>;
9
10
  }
@@ -1,14 +1,16 @@
1
1
  import { ValidationPass } from "../error/ValidationPass";
2
2
  import { BaseSchemaAny } from "../typing/extended";
3
- import type { DefaultValue, ModelValue, SourceValue } from "../typing/toolbox";
3
+ import type { AdditionalValidationPasses, DefaultValue, ModelValue, SourceValue } from "../typing/toolbox";
4
4
  import { BaseSchema } from "./BaseSchema";
5
5
  export type ArraySource<Subschema extends BaseSchemaAny> = (Subschema extends BaseSchema<infer Source, any, infer Required, infer Default> ? (SourceValue<Source, Required, Default>[]) : never);
6
6
  export type ArrayModel<Subschema extends BaseSchemaAny> = (Subschema extends BaseSchema<infer Source, infer Model, infer Required, infer Default> ? (ModelValue<Source, Model, Required, Default>[]) : never);
7
7
  export declare class ArraySchema<Subschema extends BaseSchemaAny, Required extends boolean, Default extends DefaultValue<ArraySource<Subschema>>> extends BaseSchema<ArraySource<Subschema>, ArrayModel<Subschema>, Required, Default> {
8
8
  readonly subschema: Subschema;
9
- constructor(subschema: Subschema, required: Required, defaultValue: Default);
9
+ constructor(subschema: Subschema, required: Required, defaultValue: Default, additionalValidationPasses?: AdditionalValidationPasses<ArraySource<Subschema>, ArrayModel<Subschema>>);
10
10
  get type(): string;
11
- protected _validate(source: SourceValue<ArraySource<Subschema>, Required, Default>, pass: ValidationPass): ModelValue<ArraySource<Subschema>, ArrayModel<Subschema>, Required, Default>;
11
+ protected _validate(source: ModelValue<ArraySource<Subschema>, ArrayModel<Subschema>, Required, Default>, pass: ValidationPass): ModelValue<ArraySource<Subschema>, ArrayModel<Subschema>, Required, Default>;
12
12
  convert(value: ArraySource<Subschema>, pass: ValidationPass): ArrayModel<Subschema>;
13
13
  getJsonSchema(): object;
14
+ clone(): ArraySchema<Subschema, Required, Default>;
15
+ toString(level?: number): string;
14
16
  }
@@ -1,4 +1,5 @@
1
1
  import { ValidationPass } from "../error/ValidationPass";
2
+ import { BaseSchemaAny } from "../typing/extended";
2
3
  import type { AdditionalValidationPasses, AdditionalValidator, AdditionalValidatorAfterType, AdditionalValidatorBeforeType, DefaultValue, EnsureValidator, ModelValue, SourceValue } from "../typing/toolbox";
3
4
  export declare abstract class BaseSchema<Source, Model, Required extends boolean, Default extends DefaultValue<Source>> {
4
5
  protected readonly _required: Required;
@@ -7,7 +8,7 @@ export declare abstract class BaseSchema<Source, Model, Required extends boolean
7
8
  constructor(required: Required, defaultValue: Default, additionalValidationPasses?: AdditionalValidationPasses<Source, Model>);
8
9
  abstract get type(): string;
9
10
  validate(source: SourceValue<Source, Required, Default>, pass?: ValidationPass): ModelValue<Source, Model, Required, Default>;
10
- protected abstract _validate(source: SourceValue<Source, Required, Default>, pass: ValidationPass): ModelValue<Source, Model, Required, Default>;
11
+ protected abstract _validate(source: ModelValue<Source, Model, Required, Default>, pass: ValidationPass): ModelValue<Source, Model, Required, Default>;
11
12
  abstract convert(value: Source, pass: ValidationPass): Model;
12
13
  custom(additionalValidator: AdditionalValidator<SourceValue<Source, Required, Default>>, type: AdditionalValidatorBeforeType): this;
13
14
  custom(additionalValidator: AdditionalValidator<Model>, type: AdditionalValidatorAfterType): this;
@@ -33,6 +34,18 @@ export declare abstract class BaseSchema<Source, Model, Required extends boolean
33
34
  protected _getJsonSchemaDescription(): string;
34
35
  protected _ensurePass(source: SourceValue<Source, Required, Default>, pass?: ValidationPass): ValidationPass;
35
36
  private _executeAdditionalValidator;
37
+ abstract clone(): BaseSchemaAny;
38
+ /**
39
+ * Converts this schema to a informational string representing this schema.
40
+ *
41
+ * @note Details about this schema will be displayed in [square brackets].
42
+ * * [R] Indicates this schema is required.
43
+ * * [D] Indicates this schema has a default value.
44
+ *
45
+ * @param level The nesting level. You needn't specify this externally.
46
+ * @returns A string representation of this schema.
47
+ */
48
+ toString(level?: number): string;
36
49
  /**
37
50
  * Checks to see if a value is present. (Not null or undefined)
38
51
  * @param value The value to check the presence of.
@@ -1,10 +1,11 @@
1
- import { DefaultValue, ModelValue, SourceValue } from "../typing/toolbox";
2
1
  import { ValidationPass } from "../error/ValidationPass";
2
+ import { DefaultValue, ModelValue } from "../typing/toolbox";
3
3
  import { BaseSchema } from "./BaseSchema";
4
4
  export type BooleanSource = boolean | number | string | null | undefined;
5
5
  export declare class BooleanSchema<Required extends boolean, Default extends DefaultValue<BooleanSource>> extends BaseSchema<BooleanSource, boolean, Required, Default> {
6
6
  get type(): string;
7
- protected _validate(source: SourceValue<BooleanSource, Required, Default>, pass: ValidationPass): ModelValue<BooleanSource, boolean, Required, Default>;
7
+ protected _validate(source: ModelValue<BooleanSource, boolean, Required, Default>, pass: ValidationPass): ModelValue<BooleanSource, boolean, Required, Default>;
8
8
  convert(value: BooleanSource, pass: ValidationPass): boolean;
9
+ clone(): BooleanSchema<Required, Default>;
9
10
  getJsonSchema(): object;
10
11
  }
@@ -1,12 +1,12 @@
1
- import { DefaultValue, ModelValue, SourceValue } from "../typing/toolbox";
2
1
  import { ValidationPass } from "../error/ValidationPass";
2
+ import { DefaultValue, ModelValue } from "../typing/toolbox";
3
3
  import { BaseSchema } from "./BaseSchema";
4
4
  type StandardDate = globalThis.Date;
5
5
  declare const StandardDate: DateConstructor;
6
6
  export type DateSource = string | number | StandardDate;
7
7
  export declare class DateSchema<Required extends boolean, Default extends DefaultValue<DateSource>> extends BaseSchema<DateSource, StandardDate, Required, Default> {
8
8
  get type(): string;
9
- protected _validate(source: SourceValue<DateSource, Required, Default>, pass: ValidationPass): ModelValue<DateSource, Date, Required, Default>;
9
+ protected _validate(source: ModelValue<DateSource, Date, Required, Default>, pass: ValidationPass): ModelValue<DateSource, Date, Required, Default>;
10
10
  convert(value: DateSource, pass: ValidationPass): StandardDate;
11
11
  before(date: Date, message?: string): this;
12
12
  after(date: Date, message?: string): this;
@@ -18,6 +18,7 @@ export declare class DateSchema<Required extends boolean, Default extends Defaul
18
18
  * @param duration milliseconds
19
19
  */
20
20
  lessThanAgo(duration: number, message?: string): this;
21
+ clone(): DateSchema<Required, Default>;
21
22
  getJsonSchema(): object;
22
23
  }
23
24
  export {};
@@ -1,6 +1,6 @@
1
- import type { DefaultValue, ModelValue, SourceValue } from "../typing/toolbox";
2
1
  import { ValidationPass } from "../error/ValidationPass";
3
2
  import { BaseSchemaAny } from "../typing/extended";
3
+ import type { AdditionalValidationPasses, DefaultValue, ModelValue, SourceValue } from "../typing/toolbox";
4
4
  import { BaseSchema } from "./BaseSchema";
5
5
  export type DynamicObjectSource<Subschema extends BaseSchemaAny> = ({
6
6
  [Key: string]: (Subschema extends BaseSchema<infer Source, any, infer Required, infer Default> ? (SourceValue<Source, Required, Default>) : never);
@@ -10,9 +10,11 @@ export type DynamicObjectModel<Subschema extends BaseSchemaAny> = ({
10
10
  });
11
11
  export declare class DynamicObjectSchema<Subschema extends BaseSchemaAny, Required extends boolean, Default extends DefaultValue<DynamicObjectSource<Subschema>>> extends BaseSchema<DynamicObjectSource<Subschema>, DynamicObjectModel<Subschema>, Required, Default> {
12
12
  readonly subschema: Subschema;
13
- constructor(subschema: Subschema, required: Required, defaultValue: Default);
13
+ constructor(subschema: Subschema, required: Required, defaultValue: Default, additionalValidationPasses?: AdditionalValidationPasses<DynamicObjectSource<Subschema>, DynamicObjectModel<Subschema>>);
14
14
  get type(): string;
15
- _validate(source: SourceValue<DynamicObjectSource<Subschema>, Required, Default>, pass: ValidationPass): ModelValue<DynamicObjectSource<Subschema>, DynamicObjectModel<Subschema>, Required, Default>;
15
+ protected _validate(source: ModelValue<DynamicObjectSource<Subschema>, DynamicObjectModel<Subschema>, Required, Default>, pass: ValidationPass): ModelValue<DynamicObjectSource<Subschema>, DynamicObjectModel<Subschema>, Required, Default>;
16
16
  convert(source: DynamicObjectSource<Subschema>, pass: ValidationPass): DynamicObjectModel<Subschema>;
17
17
  getJsonSchema(): object;
18
+ clone(): DynamicObjectSchema<Subschema, Required, Default>;
19
+ toString(level?: number): string;
18
20
  }
@@ -1,11 +1,12 @@
1
- import { DefaultValue, ModelValue, SourceValue } from "../typing/toolbox";
2
1
  import { ValidationPass } from "../error/ValidationPass";
2
+ import { AdditionalValidationPasses, DefaultValue, ModelValue } from "../typing/toolbox";
3
3
  import { BaseSchema } from "./BaseSchema";
4
- export declare class EnumerationSchema<Members extends string[], Required extends boolean, Default extends DefaultValue<Members[number]>> extends BaseSchema<Members[number], Members[number], Required, Default> {
5
- readonly members: Members;
6
- constructor(members: Members, required: Required, defaultValue: Default);
4
+ export declare class EnumerationSchema<Members extends string, Required extends boolean, Default extends DefaultValue<Members>> extends BaseSchema<Members, Members, Required, Default> {
5
+ readonly members: Members[];
6
+ constructor(members: Members[], required: Required, defaultValue: Default, additionalValidationPasses?: AdditionalValidationPasses<Members, Members>);
7
7
  get type(): string;
8
- _validate(source: SourceValue<Members[number], Required, Default>, pass: ValidationPass): ModelValue<Members[number], Members[number], Required, Default>;
9
- convert(value: Members[number], pass: ValidationPass): Members[number];
8
+ protected _validate(source: ModelValue<Members, Members, Required, Default>, pass: ValidationPass): ModelValue<Members, Members, Required, Default>;
9
+ convert(value: Members, pass: ValidationPass): Members;
10
+ clone(): EnumerationSchema<Members, Required, Default>;
10
11
  getJsonSchema(): object;
11
12
  }
@@ -1,10 +1,10 @@
1
- import { DefaultValue, ModelValue, SourceValue } from "../typing/toolbox";
2
1
  import { ValidationPass } from "../error/ValidationPass";
2
+ import { DefaultValue, ModelValue } from "../typing/toolbox";
3
3
  import { BaseSchema } from "./BaseSchema";
4
4
  export type NumberSource = number | bigint | string | boolean | null | undefined | Date;
5
5
  export declare class NumberSchema<Required extends boolean, Default extends DefaultValue<NumberSource>> extends BaseSchema<NumberSource, number, Required, Default> {
6
6
  get type(): string;
7
- protected _validate(source: SourceValue<NumberSource, Required, Default>, pass: ValidationPass): ModelValue<NumberSource, number, Required, Default>;
7
+ protected _validate(source: ModelValue<NumberSource, number, Required, Default>, pass: ValidationPass): ModelValue<NumberSource, number, Required, Default>;
8
8
  convert(value: NumberSource, pass: ValidationPass): number;
9
9
  min(minimum: number, message?: string): this;
10
10
  max(maximum: number, message?: string): this;
@@ -12,5 +12,6 @@ export declare class NumberSchema<Required extends boolean, Default extends Defa
12
12
  clamp(minimum: number, maximum: number, message: string): this;
13
13
  clamp(minimum: number, maximum: number, tooShortMessage: string, tooLongMessage: string): this;
14
14
  validNumber(notANumber?: boolean, message?: string): this;
15
+ clone(): NumberSchema<Required, Default>;
15
16
  getJsonSchema(): object;
16
17
  }
@@ -1,6 +1,6 @@
1
- import type { DefaultValue, Merge, ModelRequirement, ModelValue, SourceRequirement, SourceValue } from "../typing/toolbox";
2
1
  import { ValidationPass } from "../error/ValidationPass";
3
2
  import { BaseSchemaAny } from "../typing/extended";
3
+ import type { AdditionalValidationPasses, DefaultValue, Merge, ModelRequirement, ModelValue, SourceRequirement, SourceValue } from "../typing/toolbox";
4
4
  import { BaseSchema } from "./BaseSchema";
5
5
  export type ObjectSubschema = {
6
6
  [Key: string]: BaseSchemaAny;
@@ -17,10 +17,12 @@ export type ObjectModel<Subschema extends ObjectSubschema> = (Merge<{
17
17
  }>);
18
18
  export declare class ObjectSchema<Subschema extends ObjectSubschema, Required extends boolean, Default extends DefaultValue<ObjectSource<Subschema>>> extends BaseSchema<ObjectSource<Subschema>, ObjectModel<Subschema>, Required, Default> {
19
19
  readonly subschema: Subschema;
20
- constructor(subschema: Subschema, required: Required, defaultValue: Default);
20
+ constructor(subschema: Subschema, required: Required, defaultValue: Default, additionalValidationPasses?: AdditionalValidationPasses<ObjectSource<Subschema>, ObjectModel<Subschema>>);
21
21
  get type(): string;
22
- protected _validate(source: SourceValue<ObjectSource<Subschema>, Required, Default>, pass: ValidationPass): ModelValue<ObjectSource<Subschema>, ObjectModel<Subschema>, Required, Default>;
22
+ protected _validate(source: ModelValue<ObjectSource<Subschema>, ObjectModel<Subschema>, Required, Default>, pass: ValidationPass): ModelValue<ObjectSource<Subschema>, ObjectModel<Subschema>, Required, Default>;
23
23
  convert(value: ObjectSource<Subschema>, pass: ValidationPass): ObjectModel<Subschema>;
24
24
  extend<ExtensionSubschema extends ObjectSubschema, ExtensionDefault extends DefaultValue<ObjectSource<ExtensionSubschema>>>(schema: ObjectSchema<ExtensionSubschema, Required, ExtensionDefault>): ObjectSchema<Subschema & ExtensionSubschema, Required, any>;
25
25
  getJsonSchema(): object;
26
+ clone(): ObjectSchema<Subschema, Required, Default>;
27
+ toString(level?: number): string;
26
28
  }
@@ -1,18 +1,15 @@
1
1
  import { ValidationPass } from "../error/ValidationPass";
2
2
  import { BaseSchemaAny } from "../typing/extended";
3
- import { DefaultValue, ModelValue, SourceValue } from "../typing/toolbox";
3
+ import { AdditionalValidationPasses, DefaultValue, ModelValue, SourceValue } from "../typing/toolbox";
4
4
  import { BaseSchema } from "./BaseSchema";
5
- export type OrSetSchemaSource<MemberSchemas extends BaseSchemaAny[]> = {
6
- [Key in keyof MemberSchemas]: (MemberSchemas[Key] extends BaseSchema<infer Source, any, infer Required, infer Default> ? (SourceValue<Source, Required, Default>) : never);
7
- }[number];
8
- export type OrSetSchemaModel<MemberSchemas extends BaseSchemaAny[]> = ({
9
- [Key in keyof MemberSchemas]: (MemberSchemas[Key] extends BaseSchema<infer Source, infer Model, infer Required, infer Default> ? (ModelValue<Source, Model, Required, Default>) : never);
10
- })[number];
11
- export declare class OrSetSchema<MemberSchemas extends BaseSchemaAny[], Required extends boolean, Default extends DefaultValue<OrSetSchemaSource<MemberSchemas>>> extends BaseSchema<OrSetSchemaSource<MemberSchemas>, OrSetSchemaModel<MemberSchemas>, Required, Default> {
12
- readonly schemas: MemberSchemas;
13
- constructor(schemas: MemberSchemas, required: Required, defaultValue: Default);
5
+ export type OrSetSchemaSource<MemberSchema extends BaseSchemaAny> = (MemberSchema extends BaseSchema<infer Source, any, infer Required, infer Default> ? SourceValue<Source, Required, Default> : never);
6
+ export type OrSetSchemaModel<MemberSchema extends BaseSchemaAny> = (MemberSchema extends BaseSchema<infer Source, infer Model, infer Required, infer Default> ? ModelValue<Source, Model, Required, Default> : never);
7
+ export declare class OrSetSchema<MemberSchema extends BaseSchemaAny, Required extends boolean, Default extends DefaultValue<OrSetSchemaSource<MemberSchema>>> extends BaseSchema<OrSetSchemaSource<MemberSchema>, OrSetSchemaModel<MemberSchema>, Required, Default> {
8
+ readonly schemas: MemberSchema[];
9
+ constructor(schemas: MemberSchema[], required: Required, defaultValue: Default, additionalValidationPasses?: AdditionalValidationPasses<OrSetSchemaSource<MemberSchema>, OrSetSchemaModel<MemberSchema>>);
14
10
  get type(): string;
15
- _validate(source: SourceValue<OrSetSchemaSource<MemberSchemas>, Required, Default>, pass: ValidationPass): ModelValue<OrSetSchemaSource<MemberSchemas>, OrSetSchemaModel<MemberSchemas>, Required, Default>;
16
- convert(value: OrSetSchemaSource<MemberSchemas>, pass: ValidationPass): OrSetSchemaModel<MemberSchemas>;
11
+ protected _validate(source: ModelValue<OrSetSchemaSource<MemberSchema>, OrSetSchemaModel<MemberSchema>, Required, Default>, pass: ValidationPass): ModelValue<OrSetSchemaSource<MemberSchema>, OrSetSchemaModel<MemberSchema>, Required, Default>;
12
+ convert(value: OrSetSchemaSource<MemberSchema>, pass: ValidationPass): OrSetSchemaModel<MemberSchema>;
13
+ clone(): OrSetSchema<MemberSchema, Required, Default>;
17
14
  getJsonSchema(): object;
18
15
  }
@@ -1,14 +1,43 @@
1
1
  import { ValidationPass } from "../error/ValidationPass";
2
- import { DefaultValue, ModelValue, SourceValue } from "../typing/toolbox";
2
+ import { DefaultValue, ModelValue } from "../typing/toolbox";
3
3
  import { BaseSchema } from "./BaseSchema";
4
4
  export type StringSource = string | number | boolean | null | undefined | Date;
5
5
  export declare class StringSchema<Required extends boolean, Default extends DefaultValue<StringSource>> extends BaseSchema<StringSource, string, Required, Default> {
6
6
  get type(): string;
7
- protected _validate(source: SourceValue<StringSource, Required, Default>, pass: ValidationPass): ModelValue<StringSource, string, Required, Default>;
7
+ protected _validate(source: ModelValue<StringSource, string, Required, Default>, pass: ValidationPass): ModelValue<StringSource, string, Required, Default>;
8
8
  convert(value: StringSource, pass: ValidationPass): string;
9
+ /**
10
+ * Trims strings validated by this schema.
11
+ * @see {@link String.trim}
12
+ */
13
+ trim(): this;
14
+ /**
15
+ * Makes strings validated by this schema lowercase.
16
+ */
17
+ lower(): this;
18
+ /**
19
+ * Makes strings validated by this schema uppercase.
20
+ */
21
+ upper(): this;
22
+ /**
23
+ * Ensures that a string validated by this schema has a minimum (inclusive) and maximum (inclusive) length.
24
+ */
9
25
  length(minimum: number, maximum: number): this;
26
+ /**
27
+ * Ensures that a string validated by this schema has a minimum (inclusive) and maximum (inclusive) length.
28
+ * With a custom error message.
29
+ */
10
30
  length(minimum: number, maximum: number, message: string): this;
31
+ /**
32
+ * Ensures that a string validated by this schema has a minimum (inclusive) and maximum (inclusive) length.
33
+ * With custom error messages for too long, and too short.
34
+ */
11
35
  length(minimum: number, maximum: number, tooShortMessage: string, tooLongMessage: string): this;
36
+ /**
37
+ * Ensures a string validated by this schema matches a given regular expression.
38
+ * With an optional custom error message.
39
+ */
12
40
  regex(expression: RegExp, message?: string): this;
41
+ clone(): StringSchema<Required, Default>;
13
42
  getJsonSchema(): object;
14
43
  }
@@ -6,9 +6,6 @@ export type SourceValue<Source, Required extends boolean, Default extends Defaul
6
6
  export type ModelRequirement<Layout extends BaseSchemaAny> = (Layout extends BaseSchema<any, any, infer Required, infer Default> ? (Required extends true ? (true) : (Default extends undefined ? false : true)) : never);
7
7
  export type ModelValue<Source, Model, Required extends boolean, Default extends DefaultValue<Source>> = (Required extends true ? Model : Default extends undefined ? Model | undefined : Model);
8
8
  export type DefaultValue<Type> = undefined | Type | ((pass: ValidationPass) => Type);
9
- export type TypedMembers<Members> = {
10
- $members: Members;
11
- };
12
9
  export type AdditionalValidatorBeforeType = ("beforeAll" | "beforeDefault" | "afterDefault");
13
10
  export type AdditionalValidatorAfterType = ("beforeConversion" | "afterConversion" | "afterAll");
14
11
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lucania/schema",
3
- "version": "2.0.3",
3
+ "version": "2.0.4",
4
4
  "description": "A schema module for compile-time and runtime type checking.",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",