justus 0.5.3 → 0.5.5

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.
Files changed (89) hide show
  1. package/dist/dts-generator.cjs +21 -3
  2. package/dist/dts-generator.cjs.map +1 -1
  3. package/dist/dts-generator.mjs +21 -3
  4. package/dist/dts-generator.mjs.map +1 -1
  5. package/dist/extra/arn.cjs +1 -1
  6. package/dist/extra/arn.cjs.map +1 -1
  7. package/dist/extra/arn.mjs +1 -1
  8. package/dist/extra/arn.mjs.map +1 -1
  9. package/dist/index.cjs +13 -2
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.ts +18 -6
  12. package/dist/index.mjs +9 -2
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/types.cjs +0 -7
  15. package/dist/types.cjs.map +1 -1
  16. package/dist/types.d.ts +7 -9
  17. package/dist/types.mjs +0 -6
  18. package/dist/types.mjs.map +1 -1
  19. package/dist/utilities.cjs +1 -0
  20. package/dist/utilities.cjs.map +1 -1
  21. package/dist/utilities.d.ts +2 -2
  22. package/dist/utilities.mjs +1 -0
  23. package/dist/utilities.mjs.map +1 -1
  24. package/dist/validators/array.cjs +6 -6
  25. package/dist/validators/array.cjs.map +1 -1
  26. package/dist/validators/array.d.ts +6 -6
  27. package/dist/validators/array.mjs +4 -4
  28. package/dist/validators/array.mjs.map +1 -1
  29. package/dist/validators/bigint.cjs +146 -0
  30. package/dist/validators/bigint.cjs.map +6 -0
  31. package/dist/validators/bigint.d.ts +46 -0
  32. package/dist/validators/bigint.mjs +118 -0
  33. package/dist/validators/bigint.mjs.map +6 -0
  34. package/dist/validators/boolean.cjs +5 -5
  35. package/dist/validators/boolean.cjs.map +1 -1
  36. package/dist/validators/boolean.d.ts +2 -2
  37. package/dist/validators/boolean.mjs +4 -4
  38. package/dist/validators/boolean.mjs.map +1 -1
  39. package/dist/validators/constant.cjs +2 -1
  40. package/dist/validators/constant.cjs.map +1 -1
  41. package/dist/validators/constant.d.ts +2 -2
  42. package/dist/validators/constant.mjs +2 -1
  43. package/dist/validators/constant.mjs.map +1 -1
  44. package/dist/validators/date.cjs +4 -4
  45. package/dist/validators/date.cjs.map +1 -1
  46. package/dist/validators/date.d.ts +2 -2
  47. package/dist/validators/date.mjs +3 -3
  48. package/dist/validators/date.mjs.map +1 -1
  49. package/dist/validators/never.cjs +1 -1
  50. package/dist/validators/never.cjs.map +1 -1
  51. package/dist/validators/never.mjs +2 -2
  52. package/dist/validators/never.mjs.map +1 -1
  53. package/dist/validators/number.cjs +9 -9
  54. package/dist/validators/number.cjs.map +1 -1
  55. package/dist/validators/number.d.ts +4 -4
  56. package/dist/validators/number.mjs +8 -8
  57. package/dist/validators/number.mjs.map +1 -1
  58. package/dist/validators/object.cjs +13 -11
  59. package/dist/validators/object.cjs.map +1 -1
  60. package/dist/validators/object.d.ts +2 -2
  61. package/dist/validators/object.mjs +12 -10
  62. package/dist/validators/object.mjs.map +1 -1
  63. package/dist/validators/optional.cjs +1 -1
  64. package/dist/validators/optional.cjs.map +1 -1
  65. package/dist/validators/optional.mjs +2 -2
  66. package/dist/validators/optional.mjs.map +1 -1
  67. package/dist/validators/string.cjs +6 -6
  68. package/dist/validators/string.cjs.map +1 -1
  69. package/dist/validators/string.d.ts +4 -4
  70. package/dist/validators/string.mjs +5 -5
  71. package/dist/validators/string.mjs.map +1 -1
  72. package/dist/validators/union.d.ts +2 -2
  73. package/package.json +3 -5
  74. package/src/dts-generator.ts +22 -3
  75. package/src/extra/arn.ts +1 -1
  76. package/src/index.ts +26 -8
  77. package/src/types.ts +7 -12
  78. package/src/utilities.ts +3 -1
  79. package/src/validators/array.ts +9 -7
  80. package/src/validators/bigint.ts +147 -0
  81. package/src/validators/boolean.ts +3 -3
  82. package/src/validators/constant.ts +4 -3
  83. package/src/validators/date.ts +2 -2
  84. package/src/validators/never.ts +2 -2
  85. package/src/validators/number.ts +10 -10
  86. package/src/validators/object.ts +11 -10
  87. package/src/validators/optional.ts +2 -2
  88. package/src/validators/string.ts +7 -7
  89. package/src/validators/union.ts +2 -2
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/validators/string.ts"],
4
- "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA+C;AAC/C,mBAAwD;AAqBjD,IAAM,qBAAN,cAAiC,+BAA0B;AAAA,EAChE,SAAS,OAAwB;AAC/B,wCAAiB,OAAO,SAAS,UAAU,yBAAyB;AACpE,WAAO;AAAA,EACT;AACF;AAGO,IAAM,kBAAN,cAAqE,+BAAwB;AAAA,EACzF;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,cAAiC,CAAC,GAAG;AAC/C,UAAM;AAEN,UAAM;AAAA,MACJ,YAAY;AAAA,MACZ,YAAY,OAAO;AAAA,MACnB;AAAA,IACF,IAAI;AAEJ,QAAI,WAAW;AAAa,WAAK,QAAe,YAAa;AAE7D,oCAAa,aAAa,GAAG,2BAA2B,SAAS,wBAAwB;AACzF,oCAAa,aAAa,GAAG,2BAA2B,SAAS,wBAAwB;AACzF,oCAAa,aAAa,WAAW,2BAA2B,SAAS,kCAAkC,SAAS,GAAG;AAEvH,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,SAAS,OAAmB;AAC1B,wCAAiB,OAAO,SAAS,UAAU,yBAAyB;AAEpE;AAAA,MAAiB,MAAM,UAAU,KAAK;AAAA,MAClC,wCAAwC,KAAK,SAAS;AAAA,IAAE;AAE5D;AAAA,MAAiB,MAAM,UAAU,KAAK;AAAA,MAClC,wCAAwC,KAAK,SAAS;AAAA,IAAE;AAE5D;AAAA,MAAiB,KAAK,UAAU,KAAK,QAAQ,KAAK,KAAK,IAAI;AAAA,MACvD,0CAA0C,KAAK,OAAO;AAAA,IAAE;AAE5D,WAAO;AAAA,EACT;AACF;AAKO,SAAS,cAAc,aAAmD;AAC/E,SAAO,IAAI,gBAAgB,WAAW;AACxC;AAGO,IAAM,aAAS,mCAAqB,IAAI,mBAAmB,GAAG,aAAa;",
4
+ "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA+C;AAC/C,mBAAwD;AAqBjD,IAAM,qBAAN,cAAiC,+BAA0B;AAAA,EAChE,SAAS,OAAwB;AAC/B,wCAAiB,OAAO,UAAU,UAAU,yBAAyB;AACrE,WAAO;AAAA,EACT;AACF;AAGO,IAAM,kBAAN,cAAqE,+BAAwB;AAAA,EACzF;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,cAAiC,CAAC,GAAG;AAC/C,UAAM;AAEN,UAAM;AAAA,MACJ,YAAY;AAAA,MACZ,YAAY,OAAO;AAAA,MACnB;AAAA,IACF,IAAI;AAEJ,QAAI,WAAW;AAAa,WAAK,QAAe,YAAa;AAE7D,oCAAa,aAAa,GAAG,2BAA2B,SAAS,wBAAwB;AACzF,oCAAa,aAAa,GAAG,2BAA2B,SAAS,wBAAwB;AACzF,oCAAa,aAAa,WAAW,2BAA2B,SAAS,kCAAkC,SAAS,GAAG;AAEvH,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,SAAS,OAAmB;AAC1B,wCAAiB,OAAO,UAAU,UAAU,yBAAyB;AAErE;AAAA,MAAiB,MAAM,UAAU,KAAK;AAAA,MAClC,wCAAwC,KAAK,SAAS;AAAA,IAAE;AAE5D;AAAA,MAAiB,MAAM,UAAU,KAAK;AAAA,MAClC,wCAAwC,KAAK,SAAS;AAAA,IAAE;AAE5D;AAAA,MAAiB,KAAK,UAAU,KAAK,QAAQ,KAAK,KAAK,IAAI;AAAA,MACvD,0CAA0C,KAAK,OAAO;AAAA,IAAE;AAE5D,WAAO;AAAA,EACT;AACF;AAKO,SAAS,uBAAuB,aAAmD;AACxF,SAAO,IAAI,gBAAgB,WAAW;AACxC;AAGO,IAAM,aAAS,mCAAqB,IAAI,mBAAmB,GAAG,sBAAsB;",
5
5
  "names": []
6
6
  }
@@ -27,8 +27,8 @@ export declare class StringValidator<S extends string = string, I = string> exte
27
27
  constructor(constraints?: StringConstraints);
28
28
  validate(value: unknown): S;
29
29
  }
30
- export declare function stringFactory(constraints: StringConstraints): StringValidator<string>;
31
- export declare function stringFactory<S extends string>(constraints: StringConstraints): StringValidator<S>;
32
- export declare function stringFactory<B extends string>(constraints: BrandedStringConstraints<B>): StringValidator<string & Branding<B>>;
30
+ export declare function stringValidatorFactory(constraints: StringConstraints): StringValidator<string>;
31
+ export declare function stringValidatorFactory<S extends string>(constraints: StringConstraints): StringValidator<S>;
32
+ export declare function stringValidatorFactory<B extends string>(constraints: BrandedStringConstraints<B>): StringValidator<string & Branding<B>>;
33
33
  /** Validate `string`s. */
34
- export declare const string: typeof stringFactory & AnyStringValidator;
34
+ export declare const string: typeof stringValidatorFactory & AnyStringValidator;
@@ -3,7 +3,7 @@ import { assertSchema, assertValidation } from "../errors.mjs";
3
3
  import { AbstractValidator, makeValidatorFactory } from "../types.mjs";
4
4
  var AnyStringValidator = class extends AbstractValidator {
5
5
  validate(value) {
6
- assertValidation(typeof value == "string", 'Value is not a "string"');
6
+ assertValidation(typeof value === "string", 'Value is not a "string"');
7
7
  return value;
8
8
  }
9
9
  };
@@ -29,7 +29,7 @@ var StringValidator = class extends AbstractValidator {
29
29
  this.pattern = pattern;
30
30
  }
31
31
  validate(value) {
32
- assertValidation(typeof value == "string", 'Value is not a "string"');
32
+ assertValidation(typeof value === "string", 'Value is not a "string"');
33
33
  assertValidation(
34
34
  value.length >= this.minLength,
35
35
  `String must have a minimum length of ${this.minLength}`
@@ -45,14 +45,14 @@ var StringValidator = class extends AbstractValidator {
45
45
  return value;
46
46
  }
47
47
  };
48
- function stringFactory(constraints) {
48
+ function stringValidatorFactory(constraints) {
49
49
  return new StringValidator(constraints);
50
50
  }
51
- var string = makeValidatorFactory(new AnyStringValidator(), stringFactory);
51
+ var string = makeValidatorFactory(new AnyStringValidator(), stringValidatorFactory);
52
52
  export {
53
53
  AnyStringValidator,
54
54
  StringValidator,
55
55
  string,
56
- stringFactory
56
+ stringValidatorFactory
57
57
  };
58
58
  //# sourceMappingURL=string.mjs.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/validators/string.ts"],
4
- "mappings": ";AAAA,SAAS,cAAc,wBAAwB;AAC/C,SAAS,mBAAmB,4BAA4B;AAqBjD,IAAM,qBAAN,cAAiC,kBAA0B;AAAA,EAChE,SAAS,OAAwB;AAC/B,qBAAiB,OAAO,SAAS,UAAU,yBAAyB;AACpE,WAAO;AAAA,EACT;AACF;AAGO,IAAM,kBAAN,cAAqE,kBAAwB;AAAA,EACzF;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,cAAiC,CAAC,GAAG;AAC/C,UAAM;AAEN,UAAM;AAAA,MACJ,YAAY;AAAA,MACZ,YAAY,OAAO;AAAA,MACnB;AAAA,IACF,IAAI;AAEJ,QAAI,WAAW;AAAa,WAAK,QAAe,YAAa;AAE7D,iBAAa,aAAa,GAAG,2BAA2B,SAAS,wBAAwB;AACzF,iBAAa,aAAa,GAAG,2BAA2B,SAAS,wBAAwB;AACzF,iBAAa,aAAa,WAAW,2BAA2B,SAAS,kCAAkC,SAAS,GAAG;AAEvH,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,SAAS,OAAmB;AAC1B,qBAAiB,OAAO,SAAS,UAAU,yBAAyB;AAEpE;AAAA,MAAiB,MAAM,UAAU,KAAK;AAAA,MAClC,wCAAwC,KAAK,SAAS;AAAA,IAAE;AAE5D;AAAA,MAAiB,MAAM,UAAU,KAAK;AAAA,MAClC,wCAAwC,KAAK,SAAS;AAAA,IAAE;AAE5D;AAAA,MAAiB,KAAK,UAAU,KAAK,QAAQ,KAAK,KAAK,IAAI;AAAA,MACvD,0CAA0C,KAAK,OAAO;AAAA,IAAE;AAE5D,WAAO;AAAA,EACT;AACF;AAKO,SAAS,cAAc,aAAmD;AAC/E,SAAO,IAAI,gBAAgB,WAAW;AACxC;AAGO,IAAM,SAAS,qBAAqB,IAAI,mBAAmB,GAAG,aAAa;",
4
+ "mappings": ";AAAA,SAAS,cAAc,wBAAwB;AAC/C,SAAS,mBAAmB,4BAA4B;AAqBjD,IAAM,qBAAN,cAAiC,kBAA0B;AAAA,EAChE,SAAS,OAAwB;AAC/B,qBAAiB,OAAO,UAAU,UAAU,yBAAyB;AACrE,WAAO;AAAA,EACT;AACF;AAGO,IAAM,kBAAN,cAAqE,kBAAwB;AAAA,EACzF;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,cAAiC,CAAC,GAAG;AAC/C,UAAM;AAEN,UAAM;AAAA,MACJ,YAAY;AAAA,MACZ,YAAY,OAAO;AAAA,MACnB;AAAA,IACF,IAAI;AAEJ,QAAI,WAAW;AAAa,WAAK,QAAe,YAAa;AAE7D,iBAAa,aAAa,GAAG,2BAA2B,SAAS,wBAAwB;AACzF,iBAAa,aAAa,GAAG,2BAA2B,SAAS,wBAAwB;AACzF,iBAAa,aAAa,WAAW,2BAA2B,SAAS,kCAAkC,SAAS,GAAG;AAEvH,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,SAAS,OAAmB;AAC1B,qBAAiB,OAAO,UAAU,UAAU,yBAAyB;AAErE;AAAA,MAAiB,MAAM,UAAU,KAAK;AAAA,MAClC,wCAAwC,KAAK,SAAS;AAAA,IAAE;AAE5D;AAAA,MAAiB,MAAM,UAAU,KAAK;AAAA,MAClC,wCAAwC,KAAK,SAAS;AAAA,IAAE;AAE5D;AAAA,MAAiB,KAAK,UAAU,KAAK,QAAQ,KAAK,KAAK,IAAI;AAAA,MACvD,0CAA0C,KAAK,OAAO;AAAA,IAAE;AAE5D,WAAO;AAAA,EACT;AACF;AAKO,SAAS,uBAAuB,aAAmD;AACxF,SAAO,IAAI,gBAAgB,WAAW;AACxC;AAGO,IAAM,SAAS,qBAAqB,IAAI,mBAAmB,GAAG,sBAAsB;",
5
5
  "names": []
6
6
  }
@@ -2,7 +2,7 @@ import { AbstractValidator } from '../types';
2
2
  import type { InferInput, InferValidation, Validation, ValidationOptions, Validator } from '../types';
3
3
  export type OneOfArguments = readonly Validation[];
4
4
  export type InferOneOfValidation<A extends OneOfArguments> = A extends readonly [infer First, ...infer Rest] ? First extends Validation ? Rest extends OneOfArguments ? InferValidation<First> | InferOneOfValidation<Rest> : InferValidation<First> : never : A extends readonly (infer Type)[] ? Type extends Validation ? InferValidation<Type> : never : never;
5
- export type InferOneOfInput<A extends OneOfArguments> = A extends readonly [infer First, ...infer Rest] ? First extends Validation ? Rest extends OneOfArguments ? InferInput<First> | InferOneOfValidation<Rest> : InferInput<First> : never : A extends readonly (infer Type)[] ? Type extends Validation ? InferInput<Type> : never : never;
5
+ export type InferOneOfInput<A extends OneOfArguments> = A extends readonly [infer First, ...infer Rest] ? First extends Validation ? Rest extends OneOfArguments ? InferInput<First> | InferOneOfInput<Rest> : InferInput<First> : never : A extends readonly (infer Type)[] ? Type extends Validation ? InferInput<Type> : never : never;
6
6
  /** A `Validator` validating a value as _one of_ the specified arguments. */
7
7
  export declare class OneOfValidator<A extends OneOfArguments> extends AbstractValidator<InferOneOfValidation<A>, InferOneOfInput<A>> {
8
8
  readonly validators: readonly Validator[];
@@ -13,7 +13,7 @@ export declare class OneOfValidator<A extends OneOfArguments> extends AbstractVa
13
13
  export declare function oneOf<A extends OneOfArguments>(...args: A): OneOfValidator<A>;
14
14
  export type AllOfArguments = readonly [Validation, ...Validation[]];
15
15
  export type InferAllOfValidation<A extends AllOfArguments> = A extends readonly [infer First, ...infer Rest] ? First extends Validation ? Rest extends AllOfArguments ? InferValidation<First> & InferAllOfValidation<Rest> : InferValidation<First> : never : never;
16
- export type InferAllOfInput<A extends AllOfArguments> = A extends readonly [infer First, ...infer Rest] ? First extends Validation ? Rest extends AllOfArguments ? InferInput<First> & InferAllOfValidation<Rest> : InferInput<First> : never : never;
16
+ export type InferAllOfInput<A extends AllOfArguments> = A extends readonly [infer First, ...infer Rest] ? First extends Validation ? Rest extends AllOfArguments ? InferInput<First> & InferAllOfInput<Rest> : InferInput<First> : never : never;
17
17
  /** A `Validator` validating a value as _all of_ the specified arguments. */
18
18
  export declare class AllOfValidator<A extends AllOfArguments> extends AbstractValidator<InferAllOfValidation<A>, InferAllOfInput<A>> {
19
19
  readonly validators: readonly Validator[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "justus",
3
- "version": "0.5.3",
3
+ "version": "0.5.5",
4
4
  "description": "A JavaScript validation library, with types!",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -78,10 +78,8 @@
78
78
  "author": "Juit Developers <developers@juit.com>",
79
79
  "license": "Apache-2.0",
80
80
  "devDependencies": {
81
- "@plugjs/build": "^0.5.7",
82
- "@plugjs/tsd": "^0.5.7",
83
- "@types/chai": "^4.3.9",
84
- "chai": "^4.3.10",
81
+ "@plugjs/build": "^0.5.10",
82
+ "@plugjs/tsd": "^0.5.10",
85
83
  "typescript": "^5.2.2"
86
84
  },
87
85
  "directories": {
@@ -7,6 +7,7 @@ import { UUIDValidator } from './extra/uuid'
7
7
  import { getValidator } from './utilities'
8
8
  import { AnyValidator } from './validators/any'
9
9
  import { AnyArrayValidator, ArrayValidator } from './validators/array'
10
+ import { AnyBigIntValidator, BigIntValidator } from './validators/bigint'
10
11
  import { BooleanValidator } from './validators/boolean'
11
12
  import { ConstantValidator } from './validators/constant'
12
13
  import { DateValidator } from './validators/date'
@@ -29,8 +30,8 @@ import type { Validation, Validator } from './types'
29
30
  /** Check that two of our generated types are equal */
30
31
  function typeEqual(a: TypeNode, b: TypeNode): boolean {
31
32
  function eq(a: any, b: any): boolean {
32
- if ((typeof a == 'object' && a != null) &&
33
- (typeof b == 'object' && b != null) ) {
33
+ if ((typeof a === 'object' && a != null) &&
34
+ (typeof b === 'object' && b != null) ) {
34
35
  for (const key in a) {
35
36
  if (! eq(a[key], b[key])) return false
36
37
  }
@@ -426,6 +427,7 @@ function generateTypeNode(
426
427
 
427
428
  const anyType = ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)
428
429
  const anyArrayType = ts.factory.createArrayTypeNode(anyType)
430
+ const bigintType = ts.factory.createKeywordTypeNode(ts.SyntaxKind.BigIntKeyword)
429
431
  const booleanType = ts.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword)
430
432
  const dateType = ts.factory.createTypeReferenceNode('Date')
431
433
  const numberType = ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword)
@@ -453,6 +455,7 @@ const readonlyModifiers = [ ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyw
453
455
 
454
456
  registerTypeGenerator(AnyValidator, () => anyType)
455
457
  registerTypeGenerator(AnyArrayValidator, () => anyArrayType)
458
+ registerTypeGenerator(AnyBigIntValidator, () => bigintType)
456
459
  registerTypeGenerator(AnyNumberValidator, () => numberType)
457
460
  registerTypeGenerator(AnyObjectValidator, () => recordType)
458
461
  registerTypeGenerator(AnyStringValidator, () => stringType)
@@ -467,6 +470,21 @@ registerTypeGenerator(ArrayValidator, (validator, references, isInput) => {
467
470
  return ts.factory.createArrayTypeNode(itemType)
468
471
  })
469
472
 
473
+ registerTypeGenerator(BigIntValidator, (validator: BigIntValidator, _references, isInput) => {
474
+ if (isInput) {
475
+ const types: ts.TypeNode[] = [ bigintType ]
476
+ if (validator.fromNumber) types.push(numberType)
477
+ if (validator.fromString) types.push(stringType)
478
+ return types.length === 1 ? types[0] : ts.factory.createUnionTypeNode(types)
479
+ }
480
+
481
+ if (! validator.brand) return bigintType
482
+
483
+ const signature = ts.factory.createPropertySignature(undefined, `__brand_${validator.brand}`, undefined, neverType)
484
+ const literal = ts.factory.createTypeLiteralNode([ signature ])
485
+ return ts.factory.createIntersectionTypeNode([ bigintType, literal ])
486
+ })
487
+
470
488
  registerTypeGenerator(BooleanValidator, (validator, _references, isInput) => {
471
489
  return (isInput && validator.fromString) ?
472
490
  ts.factory.createUnionTypeNode([
@@ -481,6 +499,7 @@ registerTypeGenerator(ConstantValidator, (validator) => {
481
499
  const literal =
482
500
  typeof validator.constant === 'number' ? ts.factory.createNumericLiteral(validator.constant) :
483
501
  typeof validator.constant === 'string' ? ts.factory.createStringLiteral(validator.constant) :
502
+ typeof validator.constant === 'bigint' ? ts.factory.createBigIntLiteral(`${validator.constant}n`) :
484
503
  validator.constant === false ? ts.factory.createFalse() :
485
504
  validator.constant === true ? ts.factory.createTrue() :
486
505
  validator.constant === null ? ts.factory.createNull() :
@@ -611,7 +630,7 @@ registerTypeGenerator(ObjectValidator, (validator, references, isInput) => {
611
630
  propertyType, // type
612
631
  undefined) // members
613
632
 
614
- if (properties.length == 0) return extra
633
+ if (properties.length === 0) return extra
615
634
 
616
635
  const type = ts.factory.createTypeLiteralNode(properties)
617
636
  return ts.factory.createIntersectionTypeNode([ type, extra ])
package/src/extra/arn.ts CHANGED
@@ -42,7 +42,7 @@ function parse<Service extends string, ResourceType extends string>(
42
42
  service?: Service,
43
43
  type?: ResourceType,
44
44
  ): ParsedArn<Service, ResourceType> {
45
- assertValidation(typeof value == 'string', 'Value is not a "string"')
45
+ assertValidation(typeof value === 'string', 'Value is not a "string"')
46
46
 
47
47
  const segments = value.split(':')
48
48
 
package/src/index.ts CHANGED
@@ -11,6 +11,7 @@ export * from './utilities'
11
11
  // Validators
12
12
  export { AnyValidator, any } from './validators/any'
13
13
  export { AnyArrayValidator, ArrayValidator, array, arrayOf } from './validators/array'
14
+ export { AnyBigIntValidator, BigIntValidator, bigint } from './validators/bigint'
14
15
  export { BooleanValidator, boolean } from './validators/boolean'
15
16
  export { ConstantValidator, constant } from './validators/constant'
16
17
  export { DateValidator, date } from './validators/date'
@@ -23,19 +24,19 @@ export { TupleValidator, tuple } from './validators/tuple'
23
24
  export { AllOfValidator, OneOfValidator, allOf, oneOf } from './validators/union'
24
25
 
25
26
  // Validator Types
26
- export type { ArrayConstraints, arrayFactory } from './validators/array'
27
- export type { BooleanConstraints, booleanFactory } from './validators/boolean'
28
- export type { DateConstraints, dateFactory } from './validators/date'
29
- export type { BrandedNumberConstraints, numberFactory } from './validators/number'
30
- export type { objectFactory } from './validators/object'
31
- export type { BrandedStringConstraints, StringConstraints, stringFactory } from './validators/string'
27
+ export type { ArrayConstraints, arrayValidatorFactory } from './validators/array'
28
+ export type { BrandedBigIntConstraints, bigintValidatorFactory } from './validators/bigint'
29
+ export type { BooleanConstraints, booleanValidatorFactory } from './validators/boolean'
30
+ export type { DateConstraints, dateValidatorFactory } from './validators/date'
31
+ export type { BrandedNumberConstraints, numberValidatorFactory } from './validators/number'
32
+ export type { objectValidatorFactory } from './validators/object'
33
+ export type { BrandedStringConstraints, StringConstraints, stringValidatorFactory } from './validators/string'
32
34
  export type { TupleMember } from './validators/tuple'
33
35
 
34
36
  /* ========================================================================== *
35
37
  * VALIDATE FUNCTION (our main entry point) *
36
38
  * ========================================================================== */
37
39
 
38
- import { defaultValidationOptions } from './types'
39
40
  import { getValidator } from './utilities'
40
41
 
41
42
  import type { InferValidation, Validation, ValidationOptions } from './types'
@@ -51,7 +52,7 @@ export function validate<V extends Validation>(
51
52
  value: any,
52
53
  options?: ValidationOptions,
53
54
  ): InferValidation<V> {
54
- const opts: ValidationOptions = { ...defaultValidationOptions, ...options }
55
+ const opts: ValidationOptions = { ...options }
55
56
  return getValidator(validation).validate(value, opts)
56
57
  }
57
58
 
@@ -83,3 +84,20 @@ export function strip<V extends Validation>(
83
84
 
84
85
  return getValidator(validation).validate(value, opts)
85
86
  }
87
+
88
+ /**
89
+ * Validate a _value_ using the specified `Validation`, automatically stripping
90
+ * additional properties and optional `null`s (but not forbidden ones), and
91
+ * treating all properties as optional.
92
+ *
93
+ * This is equivalent to setting the `partialValidation` option to `true` in
94
+ * `validate(...)`, but this function correctly represents the returned type as
95
+ * a `Partial<...>` type.
96
+ */
97
+ export function partial<V extends Validation>(
98
+ validation: V,
99
+ value: any,
100
+ options?: ValidationOptions,
101
+ ): Partial<InferValidation<V>> {
102
+ return getValidator(validation).validate(value, { ...options, partialValidation: true })
103
+ }
package/src/types.ts CHANGED
@@ -34,15 +34,8 @@ export interface ValidationOptions {
34
34
  stripOptionalNulls?: boolean,
35
35
  /** Ignore and strip forbidden (`never`) properties from objects (default: `false`) */
36
36
  stripForbiddenProperties?: boolean,
37
- }
38
-
39
- /**
40
- * Default validation options.
41
- */
42
- export const defaultValidationOptions: Readonly<Required<ValidationOptions>> = {
43
- stripAdditionalProperties: false,
44
- stripForbiddenProperties: false,
45
- stripOptionalNulls: false,
37
+ /** Perform a _partial_ validation, treating all properties as optional (default: `false`) */
38
+ partialValidation?: boolean,
46
39
  }
47
40
 
48
41
  /**
@@ -117,13 +110,13 @@ implements Validator<T, I>, Iterable<TupleRestParameter<T, I>> {
117
110
  * Those are:
118
111
  *
119
112
  * * A `Validator` instance or a _zero-arguments_ function returning one
120
- * * A `Tuple` or a `Schema`, validated as arrays or object
121
- * * Either `null`, a `boolean`, a `number` or a `string` for constants
113
+ * * A `Tuple` or a `Schema`, validated as arrays or objects
114
+ * * Either `null`, a `boolean`, a `number`, a `bigint` or a `string` for constants
122
115
  */
123
116
  export type Validation =
124
117
  Validator | // Validator instances
125
118
  Tuple | Schema | // Tuples or schemas (arrays, objects)
126
- null | boolean | number | string // Primitives, mapped as constants
119
+ null | boolean | bigint | number | string // Primitives, mapped as constants
127
120
 
128
121
  /**
129
122
  * Infer the type returned by a `Validation` when validating.
@@ -135,6 +128,7 @@ export type InferValidation<V> =
135
128
  // Primitives are returned as constants
136
129
  V extends undefined ? V :
137
130
  V extends boolean ? V :
131
+ V extends bigint ? V :
138
132
  V extends number ? V :
139
133
  V extends string ? V :
140
134
  V extends null ? V :
@@ -155,6 +149,7 @@ export type InferInput<V> =
155
149
  // Primitives are returned as constants
156
150
  V extends undefined ? V :
157
151
  V extends boolean ? V :
152
+ V extends bigint ? V :
158
153
  V extends number ? V :
159
154
  V extends string ? V :
160
155
  V extends null ? V :
package/src/utilities.ts CHANGED
@@ -1,13 +1,14 @@
1
1
  import { assertSchema } from './errors'
2
2
  import { registry } from './registry'
3
3
 
4
- import type { Schema, Validation, Validator } from './types'
4
+ import type { InferInput, InferValidation, Schema, Validation, Validator } from './types'
5
5
 
6
6
  /* ========================================================================== *
7
7
  * UTILITY FUNCTIONS *
8
8
  * ========================================================================== */
9
9
 
10
10
  /** Return the `Validator` for the given `Validation` */
11
+ export function getValidator<V extends Validation>(validation: V): Validator<InferValidation<V>, InferInput<V>>
11
12
  export function getValidator(validation: Validation): Validator {
12
13
  assertSchema(validation !== undefined, 'No validator for undefined validation')
13
14
 
@@ -23,6 +24,7 @@ export function getValidator(validation: Validation): Validator {
23
24
  switch (typeof validation) {
24
25
  // constants
25
26
  case 'boolean':
27
+ case 'bigint':
26
28
  case 'string':
27
29
  case 'number':
28
30
  return new (registry.get('constant'))(validation)
@@ -3,7 +3,7 @@ import { AbstractValidator, makeValidatorFactory } from '../types'
3
3
  import { getValidator } from '../utilities'
4
4
  import { any } from './any'
5
5
 
6
- import type { InferValidation, Validation, ValidationOptions, Validator } from '../types'
6
+ import type { InferInput, InferValidation, Validation, ValidationOptions, Validator } from '../types'
7
7
 
8
8
  /* ========================================================================== *
9
9
  * ARRAYS VALIDATION *
@@ -22,7 +22,7 @@ export interface ArrayConstraints<V extends Validation> {
22
22
  }
23
23
 
24
24
  /** Basic validator for `Array` instances. */
25
- export class AnyArrayValidator<T = any> extends AbstractValidator<T[], T[]> {
25
+ export class AnyArrayValidator<T = any> extends AbstractValidator<T[]> {
26
26
  validate(value: unknown): T[] {
27
27
  assertValidation(Array.isArray(value), 'Value is not an "array"')
28
28
  return [ ...value ]
@@ -30,7 +30,7 @@ export class AnyArrayValidator<T = any> extends AbstractValidator<T[], T[]> {
30
30
  }
31
31
 
32
32
  /** A validator for `Array` instances with constraints. */
33
- export class ArrayValidator<T> extends AbstractValidator<T[]> {
33
+ export class ArrayValidator<T, I = T> extends AbstractValidator<T[], I[]> {
34
34
  readonly maxItems: number
35
35
  readonly minItems: number
36
36
  readonly uniqueItems: boolean
@@ -89,15 +89,17 @@ export class ArrayValidator<T> extends AbstractValidator<T[]> {
89
89
 
90
90
  /* -------------------------------------------------------------------------- */
91
91
 
92
- export function arrayFactory<V extends Validation>(constraints: ArrayConstraints<V>): ArrayValidator<InferValidation<V>> {
92
+ export function arrayValidatorFactory<V extends Validation>(
93
+ constraints: ArrayConstraints<V>,
94
+ ): ArrayValidator<InferValidation<V>, InferInput<V>> {
93
95
  const items = constraints.items ? getValidator(constraints.items) : any
94
- return new ArrayValidator({ ...constraints, items })
96
+ return new ArrayValidator<any>({ ...constraints, items })
95
97
  }
96
98
 
97
99
  /** Validate `Array`s. */
98
- export const array = makeValidatorFactory(new AnyArrayValidator(), arrayFactory)
100
+ export const array = makeValidatorFactory(new AnyArrayValidator(), arrayValidatorFactory)
99
101
 
100
102
  /** Validate `Array`s containing only the specified elements. */
101
- export function arrayOf<V extends Validation>(validation: V): Validator<InferValidation<V>[]> {
103
+ export function arrayOf<V extends Validation>(validation: V): Validator<InferValidation<V>[], InferInput<V>[]> {
102
104
  return new ArrayValidator({ items: getValidator(validation) })
103
105
  }
@@ -0,0 +1,147 @@
1
+ import { assertSchema, assertValidation, ValidationError } from '../errors'
2
+ import { AbstractValidator, makeValidatorFactory } from '../types'
3
+
4
+ import type { Branding, Validator } from '../types'
5
+
6
+ /* ========================================================================== */
7
+
8
+ /** Constraints to validate a `bigint` with. */
9
+ export interface BigIntConstraints {
10
+ /** The value for which a `bigint` must be multiple of for it to be valid */
11
+ multipleOf?: bigint | number,
12
+ /** The _inclusive_ maximum value for a valid `bigint`: `value <= maximum` */
13
+ maximum?: bigint | number,
14
+ /** The _inclusive_ minimum value for a valid `bigint`: `value >= minimum` */
15
+ minimum?: bigint | number,
16
+ /** The _exclusive_ maximum value for a valid `bigint`: `value < exclusiveMaximum` */
17
+ exclusiveMaximum?: bigint | number,
18
+ /** The _exclusive_ minimum value for a valid `bigint`: `value > exclusiveMaximum` */
19
+ exclusiveMinimum?: bigint | number,
20
+ /** Allow bigints to be parsed from strings (e.g. `123.456` or `0x0CAFE`, default: `false`) */
21
+ fromString?: boolean,
22
+ /** Allow bigints to be parsed from numbers (default: `true`) */
23
+ fromNumber?: boolean,
24
+ }
25
+
26
+ /** Constraints to validate a `bigint` with extra branding information. */
27
+ export interface BrandedBigIntConstraints<B extends string> extends BigIntConstraints {
28
+ /** The _brand_ of the string (will generate a `__brand_${B}` type property */
29
+ brand: B
30
+ }
31
+
32
+ /** A `Validator` validating any `bigint`. */
33
+ export class AnyBigIntValidator extends AbstractValidator<bigint> {
34
+ validate(value: unknown): bigint {
35
+ if (typeof value === 'number') {
36
+ try {
37
+ value = BigInt(value)
38
+ } catch (error) {
39
+ throw new ValidationError('BigInt can not be parsed from number')
40
+ }
41
+ }
42
+ assertValidation(typeof value === 'bigint', 'Value is not a "bigint"')
43
+ return value
44
+ }
45
+ }
46
+
47
+ /** A `Validator` validating `bigint`s with constaints. */
48
+ export class BigIntValidator<N extends bigint = bigint> extends AbstractValidator<N, bigint> {
49
+ readonly fromString: boolean
50
+ readonly fromNumber: boolean
51
+ readonly exclusiveMaximum?: bigint
52
+ readonly exclusiveMinimum?: bigint
53
+ readonly maximum?: bigint
54
+ readonly minimum?: bigint
55
+ readonly multipleOf?: bigint
56
+ readonly brand?: string
57
+
58
+ constructor(constraints: BigIntConstraints = {}) {
59
+ super()
60
+
61
+ const {
62
+ exclusiveMaximum,
63
+ exclusiveMinimum,
64
+ maximum,
65
+ minimum,
66
+ multipleOf,
67
+ fromString = false,
68
+ fromNumber = true,
69
+ } = constraints
70
+
71
+ if ('brand' in constraints) this.brand = (<any> constraints).brand
72
+ this.fromString = fromString
73
+ this.fromNumber = fromNumber
74
+
75
+ const _exclusiveMaximum = exclusiveMaximum === undefined ? undefined : BigInt(exclusiveMaximum)
76
+ const _exclusiveMinimum = exclusiveMinimum === undefined ? undefined : BigInt(exclusiveMinimum)
77
+ const _maximum = maximum === undefined ? undefined : BigInt(maximum)
78
+ const _minimum = minimum === undefined ? undefined : BigInt(minimum)
79
+ const _multipleOf = multipleOf === undefined ? undefined : BigInt(multipleOf)
80
+
81
+ if ((_maximum !== undefined) && (_minimum !== undefined)) {
82
+ assertSchema(_maximum >= _minimum, `Constraint "minimum" (${_minimum}) is greater than "maximum" (${_maximum})`)
83
+ }
84
+
85
+ if ((_exclusiveMaximum !== undefined) && (_minimum !== undefined)) {
86
+ assertSchema(_exclusiveMaximum > _minimum,
87
+ `Constraint "exclusiveMaximum" (${_exclusiveMaximum}) must be greater than "minimum" (${_minimum})`)
88
+ }
89
+
90
+ if ((_exclusiveMinimum !== undefined) && (_maximum != undefined)) {
91
+ assertSchema(_maximum > _exclusiveMinimum,
92
+ `Constraint "maximum" (${_maximum}) must be greater than "exclusiveMinimum" (${_exclusiveMinimum})`)
93
+ }
94
+
95
+ if ((_exclusiveMinimum != undefined) && (_exclusiveMaximum !== undefined)) {
96
+ assertSchema(_exclusiveMaximum > _exclusiveMinimum,
97
+ `Constraint "exclusiveMaximum" (${_exclusiveMaximum}) must be greater than "exclusiveMinimum" (${_exclusiveMinimum})`)
98
+ }
99
+
100
+ if (_multipleOf !== undefined) {
101
+ assertSchema(_multipleOf > 0, `Constraint "multipleOf" (${_multipleOf}) must be greater than zero`)
102
+ }
103
+
104
+ this.exclusiveMaximum = _exclusiveMaximum
105
+ this.exclusiveMinimum = _exclusiveMinimum
106
+ this.maximum = _maximum
107
+ this.minimum = _minimum
108
+ this.multipleOf = _multipleOf
109
+ }
110
+
111
+ validate(value: unknown): N {
112
+ // Allow parsing from strings or numbers
113
+ if (((typeof value === 'string') && (this.fromString)) ||
114
+ ((typeof value === 'number') && (this.fromNumber))) {
115
+ try {
116
+ value = BigInt(value)
117
+ } catch (error) {
118
+ throw new ValidationError('BigInt can not be parsed from ' + typeof value)
119
+ }
120
+ }
121
+
122
+ assertValidation(typeof value === 'bigint', 'Value is not a "bigint"')
123
+
124
+ assertValidation(((this.minimum === undefined) || (value >= this.minimum)),
125
+ `BigInt is less than ${this.minimum}`)
126
+ assertValidation(((this.maximum === undefined) || (value <= this.maximum)),
127
+ `BigInt is greater than ${this.maximum}`)
128
+ assertValidation((this.exclusiveMinimum === undefined) || (value > this.exclusiveMinimum),
129
+ `BigInt is less than or equal to ${this.exclusiveMinimum}`)
130
+ assertValidation((this.exclusiveMaximum === undefined) || (value < this.exclusiveMaximum),
131
+ `BigInt is greater than or equal to ${this.exclusiveMaximum}`)
132
+ assertValidation((this.multipleOf === undefined) || (!(value % this.multipleOf)),
133
+ `BigInt is not a multiple of ${this.multipleOf}`)
134
+
135
+ return value as N
136
+ }
137
+ }
138
+
139
+ export function bigintValidatorFactory(constraints: BigIntConstraints): BigIntValidator<bigint>
140
+ export function bigintValidatorFactory<N extends bigint>(constraints: BigIntConstraints): BigIntValidator<N>
141
+ export function bigintValidatorFactory<B extends string>(constraints: BrandedBigIntConstraints<B>): BigIntValidator<bigint & Branding<B>>
142
+ export function bigintValidatorFactory(constraints: BigIntConstraints): Validator<bigint> {
143
+ return new BigIntValidator(constraints)
144
+ }
145
+
146
+ /** Validate `bigint`s. */
147
+ export const bigint = makeValidatorFactory(new AnyBigIntValidator(), bigintValidatorFactory)
@@ -25,7 +25,7 @@ export class BooleanValidator extends AbstractValidator<boolean> {
25
25
 
26
26
  validate(value: unknown): boolean {
27
27
  // Allow parsing from strings
28
- if ((typeof value == 'string') && (this.fromString)) {
28
+ if ((typeof value === 'string') && (this.fromString)) {
29
29
  const string = value.toLowerCase()
30
30
  const parsed = string === 'true' ? true : string === 'false' ? false : undefined
31
31
  assertValidation(parsed !== undefined, 'Boolean can not be parsed from string')
@@ -37,9 +37,9 @@ export class BooleanValidator extends AbstractValidator<boolean> {
37
37
  }
38
38
  }
39
39
 
40
- export function booleanFactory(constraints: BooleanConstraints): BooleanValidator {
40
+ export function booleanValidatorFactory(constraints: BooleanConstraints): BooleanValidator {
41
41
  return new BooleanValidator(constraints)
42
42
  }
43
43
 
44
44
  /** The `Validator` for `boolean`s. */
45
- export const boolean = makeValidatorFactory(new BooleanValidator(), booleanFactory)
45
+ export const boolean = makeValidatorFactory(new BooleanValidator(), booleanValidatorFactory)
@@ -5,7 +5,7 @@ import { AbstractValidator } from '../types'
5
5
  import type { Validator } from '../types'
6
6
 
7
7
  /** A `Validator` for _constants_. */
8
- export class ConstantValidator<T extends string | number | boolean | null> extends AbstractValidator<T> {
8
+ export class ConstantValidator<T extends string | number | boolean | bigint | null> extends AbstractValidator<T> {
9
9
  readonly constant: T
10
10
 
11
11
  constructor(constant: T) {
@@ -14,13 +14,14 @@ export class ConstantValidator<T extends string | number | boolean | null> exten
14
14
  }
15
15
 
16
16
  validate(value: unknown): T {
17
- assertValidation(value === this.constant, `Value does not match constant "${this.constant}"`)
17
+ const extra = this.constant === null ? '' : ` (${typeof this.constant})`
18
+ assertValidation(value === this.constant, `Value does not match constant "${this.constant}"${extra}`)
18
19
  return value as T
19
20
  }
20
21
  }
21
22
 
22
23
  /** Validate _constants_. */
23
- export function constant<T extends string | number | boolean | null>(constant: T): Validator<T> {
24
+ export function constant<T extends string | number | boolean | bigint | null>(constant: T): Validator<T> {
24
25
  return new ConstantValidator(constant)
25
26
  }
26
27
 
@@ -64,9 +64,9 @@ export class DateValidator extends AbstractValidator<Date, Date | string | numbe
64
64
  }
65
65
  }
66
66
 
67
- export function dateFactory(constraints: DateConstraints): DateValidator {
67
+ export function dateValidatorFactory(constraints: DateConstraints): DateValidator {
68
68
  return new DateValidator(constraints)
69
69
  }
70
70
 
71
71
  /** Validate dates and convert them to `Date` instances. */
72
- export const date = makeValidatorFactory(new DateValidator(), dateFactory)
72
+ export const date = makeValidatorFactory(new DateValidator(), dateValidatorFactory)
@@ -1,5 +1,5 @@
1
1
  import { ValidationError } from '../errors'
2
- import { AbstractValidator, defaultValidationOptions } from '../types'
2
+ import { AbstractValidator } from '../types'
3
3
 
4
4
  import type { ValidationOptions } from '../types'
5
5
 
@@ -7,7 +7,7 @@ import type { ValidationOptions } from '../types'
7
7
  export class NeverValidator extends AbstractValidator<never> {
8
8
  optional: true = true
9
9
 
10
- validate(value: unknown, options: ValidationOptions = defaultValidationOptions): never {
10
+ validate(value: unknown, options: ValidationOptions = {}): never {
11
11
  const { stripForbiddenProperties } = options
12
12
 
13
13
  // @ts-expect-error