validator-fns 1.7.4 → 1.7.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
21
+ SOFTWARE.
package/README.md CHANGED
@@ -36,26 +36,26 @@ This is a fairly exhaustive example of what's possible with `validator-fns`.
36
36
 
37
37
  ```js
38
38
  import {
39
- array,
40
- boolean,
41
- date,
42
- email,
43
- exact,
44
- integer,
45
- matches,
46
- max,
47
- maxDate,
48
- min,
49
- minDate,
50
- number,
51
- object,
52
- oneOf,
53
- required,
54
- string,
55
- url,
56
- valid,
57
- invalid,
58
- } from "validator-fns";
39
+ array,
40
+ boolean,
41
+ date,
42
+ email,
43
+ exact,
44
+ integer,
45
+ matches,
46
+ max,
47
+ maxDate,
48
+ min,
49
+ minDate,
50
+ number,
51
+ object,
52
+ oneOf,
53
+ required,
54
+ string,
55
+ url,
56
+ valid,
57
+ invalid,
58
+ } from 'validator-fns';
59
59
  // optionally, you can do
60
60
  // import * as validatorFns from 'validator-fns';
61
61
 
@@ -65,97 +65,97 @@ const now = new Date();
65
65
  const tenDaysFromNow = new Date(now.getTime() + TEN_DAYS);
66
66
 
67
67
  function customValidator(value, field) {
68
- if (value === "hello") {
69
- return valid({ value, field });
70
- }
71
- return invalid({
72
- message: 'Must be "hello".',
73
- value,
74
- field,
75
- });
68
+ if (value === 'hello') {
69
+ return valid({ value, field });
70
+ }
71
+ return invalid({
72
+ message: 'Must be "hello".',
73
+ value,
74
+ field,
75
+ });
76
76
  }
77
77
 
78
78
  const validate = object({
79
- firstName: string(
80
- { default: "", trim: true },
81
- required("First name is required.")
82
- ),
83
- emailAddress: string(
84
- required("Email address is required."),
85
- email("Must be a valid email address.")
86
- ),
87
- age: number(
88
- { round: "floor" },
89
- required("Age is required."),
90
- integer("Age must be a whole number."),
91
- min(18, "Must be at least {min} years old.")
92
- ),
93
- homepage: string(url("Must be a valid URL.", ["http:", "https:"])),
94
- fruit: string(
95
- { default: "apple" },
96
- oneOf(
97
- ["apple", "orange", "banana"],
98
- ({ values }) => `Must be ${values[0]}, ${values[1]} or ${values[2]}.`
99
- )
100
- ),
101
- favoriteCarMakers: array(
102
- { default: [] },
103
- string(
104
- required("Car brand is required."),
105
- oneOf(
106
- [
107
- "BMW",
108
- "Ferrari",
109
- "Fiat",
110
- "Ford",
111
- "Honda",
112
- "Kia",
113
- "Mercedes",
114
- "Subaru",
115
- "Tesla",
116
- "Toyota",
117
- "Volvo",
118
- ],
119
- "Must be a known car brand."
120
- )
121
- ),
122
- min(2, "Must pick at least two."),
123
- max(4, "Must pick at most four.")
124
- ),
125
- startDate: date(
126
- minDate(now, "Must be on or after today."),
127
- maxDate(tenDaysFromNow, "Must be at most ten days from now.")
128
- ),
129
- optIn: boolean(required("Must decide to opt in or out.")),
130
- notRobot: number(
131
- required("Must enter the correct answer."),
132
- exact(42, "This is the answer.")
133
- ),
134
- postalCode: string(matches(/^[0-9]{5}$/, "Must be a five-digit number.")),
135
- custom: customValidator,
79
+ firstName: string(
80
+ { default: '', trim: true },
81
+ required('First name is required.')
82
+ ),
83
+ emailAddress: string(
84
+ required('Email address is required.'),
85
+ email('Must be a valid email address.')
86
+ ),
87
+ age: number(
88
+ { round: 'floor' },
89
+ required('Age is required.'),
90
+ integer('Age must be a whole number.'),
91
+ min(18, 'Must be at least {min} years old.')
92
+ ),
93
+ homepage: string(url('Must be a valid URL.', ['http:', 'https:'])),
94
+ fruit: string(
95
+ { default: 'apple' },
96
+ oneOf(
97
+ ['apple', 'orange', 'banana'],
98
+ ({ values }) => `Must be ${values[0]}, ${values[1]} or ${values[2]}.`
99
+ )
100
+ ),
101
+ favoriteCarMakers: array(
102
+ { default: [] },
103
+ string(
104
+ required('Car brand is required.'),
105
+ oneOf(
106
+ [
107
+ 'BMW',
108
+ 'Ferrari',
109
+ 'Fiat',
110
+ 'Ford',
111
+ 'Honda',
112
+ 'Kia',
113
+ 'Mercedes',
114
+ 'Subaru',
115
+ 'Tesla',
116
+ 'Toyota',
117
+ 'Volvo',
118
+ ],
119
+ 'Must be a known car brand.'
120
+ )
121
+ ),
122
+ min(2, 'Must pick at least two.'),
123
+ max(4, 'Must pick at most four.')
124
+ ),
125
+ startDate: date(
126
+ minDate(now, 'Must be on or after today.'),
127
+ maxDate(tenDaysFromNow, 'Must be at most ten days from now.')
128
+ ),
129
+ optIn: boolean(required('Must decide to opt in or out.')),
130
+ notRobot: number(
131
+ required('Must enter the correct answer.'),
132
+ exact(42, 'This is the answer.')
133
+ ),
134
+ postalCode: string(matches(/^[0-9]{5}$/, 'Must be a five-digit number.')),
135
+ custom: customValidator,
136
136
  });
137
137
 
138
138
  // later...
139
139
  const result = await validate({
140
- age: 20,
141
- custom: "hello",
142
- emailAddress: "foo@example.com",
143
- favoriteCarMakers: ["Ferrari", "Tesla"],
144
- firstName: "Bob",
145
- fruit: "apple",
146
- homepage: "https://www.example.com",
147
- notRobot: 42,
148
- optIn: false,
149
- postalCode: "12345",
150
- startDate: new Date(),
140
+ age: 20,
141
+ custom: 'hello',
142
+ emailAddress: 'foo@example.com',
143
+ favoriteCarMakers: ['Ferrari', 'Tesla'],
144
+ firstName: 'Bob',
145
+ fruit: 'apple',
146
+ homepage: 'https://www.example.com',
147
+ notRobot: 42,
148
+ optIn: false,
149
+ postalCode: '12345',
150
+ startDate: new Date(),
151
151
  });
152
152
 
153
- if (result.state === "valid") {
154
- // do something with the parsed values
155
- console.log(result.value);
153
+ if (result.state === 'valid') {
154
+ // do something with the parsed values
155
+ console.log(result.value);
156
156
  } else {
157
- // handle and display errors
158
- console.error(result.errors);
157
+ // handle and display errors
158
+ console.error(result.errors);
159
159
  }
160
160
  ```
161
161
 
package/dist/cjs/index.js CHANGED
@@ -5,8 +5,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  function isObject(value) {
6
6
  return Object.prototype.toString.call(value) === "[object Object]";
7
7
  }
8
- function hasOwnProperty(object, prop) {
9
- return Object.prototype.hasOwnProperty.call(object, prop);
8
+ function hasOwnProperty(object, property) {
9
+ return Object.prototype.hasOwnProperty.call(object, property);
10
10
  }
11
11
  const formatPattern = /{(\w+)}/g;
12
12
  function formatMessage(template, parameters) {
@@ -36,7 +36,7 @@ async function invalid({
36
36
  return {
37
37
  isValid: false,
38
38
  state: "invalid",
39
- message: formatMessage(message, { ...extras != null ? extras : {}, value, field }),
39
+ message: formatMessage(message, { ...extras, value, field }),
40
40
  value,
41
41
  field,
42
42
  errors
@@ -75,7 +75,7 @@ function createTypeValidatorTest(defaultConfig, applyConfig) {
75
75
  return cache[parsedValueString];
76
76
  } catch (error) {
77
77
  return invalid({
78
- message: error == null ? void 0 : error.message,
78
+ message: error instanceof Error ? error.message : String(error),
79
79
  value,
80
80
  field
81
81
  });
@@ -234,8 +234,8 @@ function applyBooleanConfig(value, config) {
234
234
  const boolean = createTypeValidatorTest({ parser: parseBoolean }, applyBooleanConfig);
235
235
 
236
236
  const invalidDate = new Date("");
237
- const isoDatePattern = /^(\d{4})(?:-([012]\d)(?:-([0123]\d)(?:[T ]([012]\d):([0-5]\d)(?::([0-5]\d)(\.\d+)?(Z|[+-][012]\d:?[0-5]\d)?)?)?)?)?$/;
238
- const timezonePattern = /^([+-])([012]\d):?([0-5]\d)$/;
237
+ const isoDatePattern = /^(\d{4})(?:-([0-2]\d)(?:-([0-3]\d)(?:[ T]([0-2]\d):([0-5]\d)(?::([0-5]\d)(\.\d+)?(Z|[+-][0-2]\d:?[0-5]\d)?)?)?)?)?$/;
238
+ const timezonePattern = /^([+-])([0-2]\d):?([0-5]\d)$/;
239
239
  function parseTimezone(timezone) {
240
240
  const parts = timezonePattern.exec(timezone);
241
241
  if (timezone === "Z" || !parts) {
@@ -243,8 +243,8 @@ function parseTimezone(timezone) {
243
243
  }
244
244
  const [, sign, hour, minute] = parts;
245
245
  const multiplier = sign === "-" ? -1 : 1;
246
- const hoursInMinutes = Number.parseInt(hour != null ? hour : "0", 10) * 60;
247
- const offset = hoursInMinutes + Number.parseInt(minute != null ? minute : "0", 10);
246
+ const hoursInMinutes = Number.parseInt(hour, 10) * 60;
247
+ const offset = hoursInMinutes + Number.parseInt(minute, 10);
248
248
  return multiplier * offset;
249
249
  }
250
250
  const BASE = 10;
@@ -275,7 +275,7 @@ function parseDate(value) {
275
275
  if (parts === null) {
276
276
  return invalidDate;
277
277
  }
278
- const [, year, month, day, hour, minute, second, millisecond] = dateParts.map((parse, i) => parse(parts[i]));
278
+ const [, year, month, day, hour, minute, second, millisecond] = dateParts.map((parse, index) => parse(parts[index]));
279
279
  const timezone = parts[8];
280
280
  if (!timezone) {
281
281
  return new Date(year, month, day, hour, minute, second, millisecond);
@@ -394,7 +394,7 @@ function object(properties) {
394
394
  };
395
395
  }
396
396
 
397
- const emailPattern = /^[\w.!#$%&'*+/=?^`{|}~-]+@[a-zA-Z\d](?:[a-zA-Z\d-]{0,61}[a-zA-Z\d])?(?:\.[a-zA-Z\d](?:[a-zA-Z\d-]{0,61}[a-zA-Z\d])?)*$/;
397
+ const emailPattern = /^[\w!#$%&'*+./=?^`{|}~-]+@[\dA-Za-z](?:[\dA-Za-z-]{0,61}[\dA-Za-z])?(?:\.[\dA-Za-z](?:[\dA-Za-z-]{0,61}[\dA-Za-z])?)*$/;
398
398
  function parseString(value) {
399
399
  if (value === null || value === void 0) {
400
400
  return value;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/shared.ts","../../src/arrays.ts","../../src/booleans.ts","../../src/dates.ts","../../src/numbers.ts","../../src/objects.ts","../../src/strings.ts"],"sourcesContent":["/**\n * From type-fest: https://github.com/sindresorhus/type-fest/blob/HEAD/source/except.d.ts\n * @internal\n */\ntype Except<ObjectType, KeysType extends keyof ObjectType> = Pick<ObjectType, Exclude<keyof ObjectType, KeysType>>;\n\nexport type ValidResult<T> = {\n\t/**\n\t * True if the original value is valid according to all validation tests\n\t * @deprecated Use `state` instead.\n\t */\n\tisValid: true;\n\t/** This is preferred to use over `isValid` as it works better for type guards. */\n\tstate: 'valid';\n\t/** The parsed value. Note that may be different than the original value. */\n\tvalue: T | null | undefined;\n\t/** Field name if provided. Automatically provided if using object validation. */\n\tfield?: string;\n};\n\nexport type InvalidResult<E> = {\n\t/**\n\t * True if the original value is valid according to all validation tests.\n\t * @deprecated Use `state` instead.\n\t */\n\tisValid: false;\n\t/** This is preferred to use over `isValid` as it works better for type guards. */\n\tstate: 'invalid';\n\t/** The parsed value. Note that may be different than the original value. */\n\tvalue: unknown;\n\t/** Error message if `state` is invalid. */\n\tmessage: string;\n\t/** Field name if provided. Automatically provided if using object validation. */\n\tfield?: string;\n\t/** Extra error details */\n\terrors?: E;\n};\n\n/**\n * The result of a validation.\n * @typeParam T The value type\n * @category Types\n */\nexport type ValidatorResult<T = any, E = any> =\n\t| ValidResult<T>\n\t| InvalidResult<E>;\n\n/**\n * Validation test function.\n * @typeParam T The value type\n * @category Types\n */\nexport type ValidatorTest<T = any, E = any> = (\n\tvalue: unknown,\n\tfield?: string\n) => Promise<ValidatorResult<T, E>>;\n\n/**\n * Extracts the generic error type from a ValidatorTest.\n * @typeParam T a ValidatorTest\n * @category Types\n */\nexport type ExtractError<T extends ValidatorTest> = T extends ValidatorTest<\nany,\ninfer E\n>\n\t? E\n\t: unknown;\n\n/**\n * Extracts the generic value type from a ValidatorTest.\n * @typeParam T a ValidatorTest\n * @category Types\n */\nexport type ExtractValue<T extends ValidatorTest> = T extends ValidatorTest<\ninfer V\n>\n\t? V\n\t: unknown;\n\n/**\n * Make a deep partial type.\n * @typeParam T any object type\n * @category Types\n */\nexport type DeepPartial<T> = {\n\t[P in keyof T]?: DeepPartial<T[P]>;\n};\n\n/**\n * Validation factory function.\n * @typeParam C The configuration type\n * @category Types\n */\nexport type ValidatorFactory<C, T, E> = (\n\tconfig?: Partial<C> | ValidatorTest,\n\t...tests: ValidatorTest[]\n) => ValidatorTest<T, E>;\n\n/**\n * Base configuration type.\n * @typeParam T The target type.\n * @category Types\n */\nexport interface ConfigBase<T> {\n\t/** Parser to convert value into the designated type. */\n\tparser: (value: unknown) => T | null | undefined;\n\t/** Provide a fallback value in case the original value is undefined. */\n\tdefault?: T;\n}\n\nexport interface ValidatorMessageParameters<T> {\n\tvalue: T | null | undefined;\n\tfield: string | undefined;\n}\n\n/**\n * Validation message. May be a plain string or a function that accepts arguments.\n * While using a string, values in squiggly brackets `{}` are replaced.\n * @category Types\n */\nexport type ValidatorMessage<\n\tT,\n\tP extends ValidatorMessageParameters<T> = ValidatorMessageParameters<T>,\n> = string | ((parameters: P) => string);\n\n/**\n * Simple check for objects.\n * @param value Value to test\n */\nexport function isObject(value: unknown): boolean {\n\treturn Object.prototype.toString.call(value) === '[object Object]';\n}\n\n/**\n * Safe hasOwnProperty check\n * @param obj Object to check\n * @param prop Property to look for\n */\nexport function hasOwnProperty(\n\tobject: unknown,\n\tprop: string | number | symbol,\n): boolean {\n\treturn Object.prototype.hasOwnProperty.call(object, prop);\n}\n\n/** @internal */\nconst formatPattern = /{(\\w+)}/g;\n\n/**\n * Formats a message using a squiggly bracket `{}` template.\n * @param template Message template as string or function\n * @param params Params to inject into template\n * @category Helpers\n */\nexport function formatMessage<T, P extends ValidatorMessageParameters<T>>(\n\ttemplate: ValidatorMessage<T, P>,\n\tparameters: P,\n): string {\n\tif (typeof template === 'string') {\n\t\treturn template.replace(formatPattern, (_, key: string) =>\n\t\t\tString((parameters as Record<string, unknown>)[key]),\n\t\t);\n\t}\n\n\treturn template(parameters);\n}\n\n/**\n * Creates a valid result\n * @param value Parsed value\n * @param field Field name\n * @category Helpers\n */\nexport async function valid<T, E = never>({\n\tvalue,\n\tfield,\n}: {\n\tvalue: T | null | undefined;\n\tfield: string | undefined;\n}): Promise<ValidatorResult<T, E>> {\n\treturn {\n\t\tisValid: true,\n\t\tstate: 'valid',\n\t\tvalue,\n\t\tfield,\n\t};\n}\n\n/**\n * Creates an invalid result.\n * @param message Error message\n * @param value Parsed value\n * @param field Field name\n * @param extras Extra message params\n * @category Helpers\n */\nexport async function invalid<T, E, P extends ValidatorMessageParameters<T>>({\n\terrors,\n\tfield,\n\tmessage,\n\tvalue,\n\textras,\n}: {\n\tmessage: ValidatorMessage<T, P>;\n\tvalue: unknown;\n\tfield: string | undefined;\n\terrors?: E;\n\textras?: Except<P, 'field' | 'value'>;\n}): Promise<ValidatorResult<T, E>> {\n\treturn {\n\t\tisValid: false,\n\t\tstate: 'invalid',\n\t\tmessage: formatMessage(message, {...(extras ?? {}), value, field} as P),\n\t\tvalue,\n\t\tfield,\n\t\terrors,\n\t};\n}\n\n/**\n * Creates a type validator.\n * @typeParam T The basic type for the final value to be validated.\n * @typeParam C The configuration type.\n * @param defaultParser Parser to convert value into type.\n * @param applyConfig Function that applies configuration to value.\n * @category Helpers\n */\nexport function createTypeValidatorTest<T, C extends ConfigBase<T>, E>(\n\tdefaultConfig: C,\n\tapplyConfig: (value: unknown, config: C) => T | null | undefined,\n): ValidatorFactory<C, T, E> {\n\treturn (config, ...tests) => {\n\t\tconst cache: Record<string, ValidatorResult<T>> = {};\n\t\tlet finalConfig = defaultConfig;\n\t\tlet allTests = tests;\n\n\t\tif (config !== undefined) {\n\t\t\tif (typeof config === 'function') {\n\t\t\t\tallTests = [config, ...tests];\n\t\t\t} else {\n\t\t\t\tfinalConfig = {\n\t\t\t\t\t...defaultConfig,\n\t\t\t\t\t...config,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn async (value, field) => {\n\t\t\ttry {\n\t\t\t\tconst parsedValue = applyConfig(value, finalConfig);\n\t\t\t\tconst parsedValueString = String(parsedValue);\n\t\t\t\tif (hasOwnProperty(cache, parsedValueString)) {\n\t\t\t\t\treturn cache[parsedValueString];\n\t\t\t\t}\n\n\t\t\t\tfor (const validatorTest of allTests) {\n\t\t\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\t\t\tconst result = await validatorTest(parsedValue, field);\n\t\t\t\t\tif (result.state === 'invalid') {\n\t\t\t\t\t\tcache[parsedValueString] = result;\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcache[parsedValueString] = await valid({value: parsedValue, field});\n\t\t\t\treturn cache[parsedValueString];\n\t\t\t} catch (error: unknown) {\n\t\t\t\treturn invalid({\n\t\t\t\t\tmessage: (error as Error)?.message,\n\t\t\t\t\tvalue,\n\t\t\t\t\tfield,\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\t};\n}\n\n/**\n * Captures basic validator test pattern\n * @param test Test function\n * @param message Error message\n * @param getExtras Optional extra fields for error message\n */\nexport function createValidatorTest<\n\tT = any,\n\tE = any,\n\tP extends ValidatorMessageParameters<T> = ValidatorMessageParameters<T>,\n>(\n\ttest: (value: unknown, field?: string) => boolean,\n\tmessage: ValidatorMessage<T, P>,\n\tgetExtras?: (value: T | null | undefined) => Except<P, 'value' | 'field'>,\n): ValidatorTest<T, E> {\n\treturn async (value, field) => {\n\t\tif (test(value, field)) {\n\t\t\treturn valid({value: value as T, field});\n\t\t}\n\n\t\treturn invalid({\n\t\t\tmessage,\n\t\t\tvalue,\n\t\t\tfield,\n\t\t\textras: getExtras ? getExtras(value as T) : undefined,\n\t\t});\n\t};\n}\n\n/**\n * Ensures a value is not undefined, null, empty string, NaN, nor invalid date.\n * @param message Error message\n * @param nullable Allow null values\n * @category Validation Tests\n */\nexport function required<T, P extends ValidatorMessageParameters<T>>(\n\tmessage: ValidatorMessage<T, P>,\n\tnullable?: boolean,\n): ValidatorTest<T> {\n\treturn createValidatorTest(\n\t\tvalue =>\n\t\t\t(nullable && value === null)\n\t\t\t|| (value !== null\n\t\t\t\t&& value !== undefined\n\t\t\t\t&& !(typeof value === 'string' && value === '')\n\t\t\t\t&& !(typeof value === 'number' && Number.isNaN(value))\n\t\t\t\t&& !(value instanceof Date && Number.isNaN(value.valueOf()))),\n\t\tmessage,\n\t);\n}\n\nexport type SharedValueType = string | number | unknown[];\n\n/**\n * Extracts a numeric amount from value, i.e. string length, array length, or number.\n * @internal\n */\nfunction getAmount(value: SharedValueType | null | undefined) {\n\treturn typeof value === 'string' || Array.isArray(value)\n\t\t? value.length\n\t\t: value;\n}\n\nexport interface MaxValidatorMessageParameters\n\textends ValidatorMessageParameters<SharedValueType> {\n\tmax: number;\n\tamount: number | null | undefined;\n\tlimit: number;\n\texclusive?: boolean;\n}\n\n/**\n * Ensures a string, number, or array value is at most a certain amount.\n * @param limit Size or value limit\n * @param message Error message\n * @param exclusive Use exclusive comparison instead of inclusive\n * @category Validation Tests\n */\nexport function max(\n\tlimit: number,\n\tmessage: ValidatorMessage<SharedValueType, MaxValidatorMessageParameters>,\n\texclusive?: boolean,\n): ValidatorTest<SharedValueType> {\n\treturn createValidatorTest(\n\t\tvalue => {\n\t\t\tconst amount = getAmount(value as SharedValueType);\n\t\t\treturn (\n\t\t\t\tamount === undefined\n\t\t\t\t|| amount === null\n\t\t\t\t|| value === ''\n\t\t\t\t|| (exclusive ? amount < limit : amount <= limit)\n\t\t\t);\n\t\t},\n\t\tmessage,\n\t\tvalue => ({\n\t\t\tmax: limit,\n\t\t\tlimit,\n\t\t\tamount: getAmount(value),\n\t\t\texclusive,\n\t\t}),\n\t);\n}\n\nexport interface MinValidatorMessageParameters\n\textends ValidatorMessageParameters<SharedValueType> {\n\tmin: number;\n\tlimit: number;\n\tamount: number | null | undefined;\n\texclusive?: boolean;\n}\n\n/**\n * Ensures a string, number, or array value is at most a certain amount.\n * @param limit Size or value limit\n * @param message Error message\n * @param exclusive Use exclusive comparison instead of inclusive\n * @category Validation Tests\n */\nexport function min(\n\tlimit: number,\n\tmessage: ValidatorMessage<SharedValueType, MinValidatorMessageParameters>,\n\texclusive?: boolean,\n): ValidatorTest<SharedValueType> {\n\treturn createValidatorTest(\n\t\tvalue => {\n\t\t\tconst amount = getAmount(value as SharedValueType);\n\t\t\treturn (\n\t\t\t\tamount === undefined\n\t\t\t\t|| amount === null\n\t\t\t\t|| value === ''\n\t\t\t\t|| (exclusive ? amount > limit : amount >= limit)\n\t\t\t);\n\t\t},\n\t\tmessage,\n\t\tvalue => ({\n\t\t\tmin: limit,\n\t\t\tlimit,\n\t\t\tamount: getAmount(value),\n\t\t\texclusive,\n\t\t}),\n\t);\n}\n\nexport interface ExactValidatorMessageParameters\n\textends ValidatorMessageParameters<SharedValueType> {\n\tlimit: number;\n\tamount: number | null | undefined;\n\texact: number;\n}\n\n/**\n * Ensures a string, number, or array value is exactly a certain amount.\n * @param limit Size or value limit\n * @param message Error message\n * @category Validation Tests\n */\nexport function exact(\n\tlimit: number,\n\tmessage: ValidatorMessage<SharedValueType, ExactValidatorMessageParameters>,\n): ValidatorTest<SharedValueType> {\n\treturn createValidatorTest(\n\t\tvalue => {\n\t\t\tconst amount = getAmount(value as SharedValueType);\n\t\t\treturn (\n\t\t\t\tamount === undefined\n\t\t\t\t|| amount === null\n\t\t\t\t|| value === ''\n\t\t\t\t|| amount === limit\n\t\t\t);\n\t\t},\n\t\tmessage,\n\t\tvalue => ({\n\t\t\tamount: getAmount(value),\n\t\t\tlimit,\n\t\t\texact: limit,\n\t\t}),\n\t);\n}\n\nexport interface OneOfValidatorMessageParameters<T>\n\textends ValidatorMessageParameters<T> {\n\tvalues: readonly T[];\n}\n\n/**\n * Ensures a value is one in a predefined list.\n * @param values List of allowed values.\n * @param message Error message\n * @category Validation Tests\n */\nexport function oneOf<T extends string | number | boolean | Date>(\n\tvalues: readonly T[],\n\tmessage: ValidatorMessage<T, OneOfValidatorMessageParameters<T>>,\n): ValidatorTest<T> {\n\treturn createValidatorTest(\n\t\tvalue =>\n\t\t\tvalue === undefined\n\t\t\t|| value === null\n\t\t\t|| values.includes(value as T)\n\t\t\t|| (value instanceof Date\n\t\t\t\t&& values.some(x => x.valueOf() === value.valueOf())),\n\t\tmessage,\n\t\t() => ({values}),\n\t);\n}\n","import {\n\tConfigBase,\n\tinvalid,\n\tvalid,\n\tValidatorResult,\n\tValidatorTest,\n} from './shared';\n\n/**\n * Invalid validation result for an item in the array\n * @category Types\n */\nexport interface ArrayItemValidatorResult {\n\t/** The index of the item in the original array */\n\tindex: number;\n\t/** The error message if a simple type */\n\tmessage: string;\n\t/** The errors if an object or array */\n\terrors: unknown;\n}\n\n/**\n * Configuration for array validation.\n * @category Types\n */\nexport type ArrayConfig = ConfigBase<unknown[]>;\n\n/**\n * Parses a value into an array.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseArray(value: unknown): unknown[] | null | undefined {\n\tif (Array.isArray(value)) {\n\t\treturn value as unknown[];\n\t}\n\n\tif (value === null || value === undefined) {\n\t\treturn value;\n\t}\n\n\tconst iterable = value as Iterable<unknown>;\n\n\tif (iterable[Symbol.iterator]) {\n\t\treturn [...iterable];\n\t}\n\n\treturn [];\n}\n\n/**\n * Applies a configuration to the array value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyArrayConfig<T>(\n\tconfig: ArrayConfig,\n\tvalue: unknown,\n): T[] | null | undefined {\n\tlet parsedValue = config.parser(value);\n\tif (parsedValue === undefined && config.default !== undefined) {\n\t\tparsedValue = config.default;\n\t}\n\n\treturn parsedValue as T[];\n}\n\n/**\n * Validates an array. The first passed validator is used to validate individual\n * items. The remaining validators target the array itself.\n * @category Type Validators\n */\nexport function array<T>(\n\tconfig?: Partial<ArrayConfig> | ValidatorTest<T>,\n\t...tests: ValidatorTest[]\n): ValidatorTest<T[], ArrayItemValidatorResult[]> {\n\tlet allTests = tests;\n\tlet finalConfig: ArrayConfig = {\n\t\tparser: parseArray,\n\t};\n\n\tif (config !== undefined) {\n\t\tif (typeof config === 'function') {\n\t\t\tallTests = [config, ...tests];\n\t\t} else {\n\t\t\tfinalConfig = {\n\t\t\t\t...finalConfig,\n\t\t\t\t...config,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn async (value, field) => {\n\t\tconst arrayValue = applyArrayConfig<T>(finalConfig, value);\n\t\tlet arrayInvalidResult: ValidatorResult | undefined;\n\t\tlet isValid = true;\n\t\tconst errors: ArrayItemValidatorResult[] = [];\n\t\tconst [validateItem, ...arrayTests] = allTests;\n\n\t\tfor (const validatorTest of arrayTests) {\n\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\tconst result = await validatorTest(arrayValue, field);\n\t\t\tif (result.state === 'invalid') {\n\t\t\t\tisValid = false;\n\t\t\t\tarrayInvalidResult = result;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (arrayValue && validateItem) {\n\t\t\tfor (const [index, item] of arrayValue.entries()) {\n\t\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\t\tconst result = await validateItem(\n\t\t\t\t\titem,\n\t\t\t\t\tfield ? `${field}[${index}]` : `[${index}]`,\n\t\t\t\t);\n\n\t\t\t\tif (result.state === 'invalid') {\n\t\t\t\t\tisValid = false;\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\terrors: result.errors,\n\t\t\t\t\t\tindex,\n\t\t\t\t\t\tmessage: result.message,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (isValid) {\n\t\t\treturn valid({\n\t\t\t\tvalue: arrayValue,\n\t\t\t\tfield,\n\t\t\t});\n\t\t}\n\n\t\treturn invalid({\n\t\t\tmessage:\n\t\t\t\tarrayInvalidResult?.state === 'invalid'\n\t\t\t\t\t? arrayInvalidResult.message\n\t\t\t\t\t: '',\n\t\t\tvalue,\n\t\t\tfield,\n\t\t\terrors,\n\t\t});\n\t};\n}\n","import {ConfigBase, createTypeValidatorTest} from './shared';\n\n/**\n * Parses a value into a boolean.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseBoolean(value: unknown): boolean | null | undefined {\n\tif (value === undefined || value === null) {\n\t\treturn value;\n\t}\n\n\tif (typeof value === 'boolean') {\n\t\treturn value;\n\t}\n\n\treturn Boolean(value);\n}\n\n/**\n * Applies a configuration to the boolean value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyBooleanConfig(\n\tvalue: unknown,\n\tconfig: BooleanConfig,\n): boolean | null | undefined {\n\tlet parsedValue = config.parser(value);\n\tif (parsedValue === undefined && config.default !== undefined) {\n\t\tparsedValue = config.default;\n\t}\n\n\treturn parsedValue;\n}\n\n/**\n * Configuration for boolean validation.\n * @category Types\n */\nexport type BooleanConfig = ConfigBase<boolean>;\n\n/**\n * Validates a boolean value.\n * @category Type Validators\n */\nexport const boolean = createTypeValidatorTest(\n\t{parser: parseBoolean},\n\tapplyBooleanConfig,\n);\n","import {\n\tConfigBase,\n\tcreateTypeValidatorTest,\n\tcreateValidatorTest,\n\tValidatorMessage,\n\tValidatorMessageParameters,\n\tValidatorTest,\n} from './shared';\n\n/** Badly formatted date for internal use. */\nexport const invalidDate = new Date('');\n\n/** @internal */\nconst isoDatePattern\n\t= /^(\\d{4})(?:-([012]\\d)(?:-([0123]\\d)(?:[T ]([012]\\d):([0-5]\\d)(?::([0-5]\\d)(\\.\\d+)?(Z|[+-][012]\\d:?[0-5]\\d)?)?)?)?)?$/;\n\n/** @internal */\nconst timezonePattern = /^([+-])([012]\\d):?([0-5]\\d)$/;\n\n/**\n * Parses a timezone string.\n * @param timezone Timezone to parse\n * @internal\n */\nfunction parseTimezone(timezone: string): number {\n\tconst parts = timezonePattern.exec(timezone);\n\n\tif (timezone === 'Z' || !parts) {\n\t\treturn 0;\n\t}\n\n\tconst [, sign, hour, minute] = parts;\n\tconst multiplier = sign === '-' ? -1 : 1;\n\tconst hoursInMinutes = Number.parseInt(hour ?? '0', 10) * 60;\n\tconst offset = hoursInMinutes + Number.parseInt(minute ?? '0', 10);\n\n\treturn multiplier * offset;\n}\n\nconst BASE = 10;\n\nconst dateParts = [\n\t// Skip\n\t() => 0,\n\t// Year\n\t(part = '0') => Number.parseInt(part, BASE),\n\t// Month\n\t(part = '1') => Number.parseInt(part, BASE) - 1,\n\t// Day\n\t(part = '1') => Number.parseInt(part, BASE),\n\t// Hour\n\t(part = '0') => Number.parseInt(part, BASE),\n\t// Minute\n\t(part = '0') => Number.parseInt(part, BASE),\n\t// Second\n\t(part = '0') => Number.parseInt(part, BASE),\n\t// Millisecond\n\t(part = '0') => Number.parseFloat(part) * 1e3,\n];\n\n/**\n * Parses a value into a date.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseDate(value: unknown): Date | null | undefined {\n\tif (value === null || value === undefined) {\n\t\treturn value;\n\t}\n\n\tif (value instanceof Date) {\n\t\treturn value;\n\t}\n\n\tif (typeof value === 'number') {\n\t\treturn new Date(value);\n\t}\n\n\tif (typeof value !== 'string') {\n\t\treturn invalidDate;\n\t}\n\n\tconst parts = isoDatePattern.exec(value);\n\n\tif (parts === null) {\n\t\treturn invalidDate;\n\t}\n\n\tconst [, year, month, day, hour, minute, second, millisecond] = dateParts.map(\n\t\t(parse, i) => parse(parts[i]),\n\t);\n\n\tconst timezone = parts[8];\n\n\tif (!timezone) {\n\t\treturn new Date(year, month, day, hour, minute, second, millisecond);\n\t}\n\n\tconst minuteOffset = parseTimezone(timezone);\n\n\treturn new Date(\n\t\tDate.UTC(year, month, day, hour, minute + minuteOffset, second, millisecond),\n\t);\n}\n\n/**\n * Applies a configuration to the date value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyDateConfig(\n\tvalue: unknown,\n\tconfig: DateConfig,\n): Date | null | undefined {\n\tlet parsedValue = config.parser(value);\n\tif (parsedValue === undefined && config.default !== undefined) {\n\t\tparsedValue = config.default;\n\t}\n\n\treturn parsedValue;\n}\n\nexport type SharedDateValueType = Date | string | number;\n\nexport interface MinDateValidatorMessageParameters\n\textends ValidatorMessageParameters<Date> {\n\tmin: Date | null | undefined;\n\tlimit: Date | null | undefined;\n\texclusive?: boolean;\n}\n\n/**\n * Ensures a date value is on or after a date.\n * @param limit Minimum date\n * @param message Error message\n * @param exclusive Makes comparison exclusive instead of inclusive\n * @category Validation Tests\n */\nexport function minDate(\n\tlimit: SharedDateValueType,\n\tmessage: ValidatorMessage<Date, MinDateValidatorMessageParameters>,\n\texclusive?: boolean,\n): ValidatorTest<Date, null> {\n\tconst parsedDate = parseDate(limit);\n\treturn createValidatorTest(\n\t\tvalue =>\n\t\t\tparsedDate !== null\n\t\t\t&& parsedDate !== undefined\n\t\t\t&& (value === null\n\t\t\t\t|| value === undefined\n\t\t\t\t|| (value instanceof Date\n\t\t\t\t\t&& (exclusive ? value > parsedDate : value >= parsedDate))),\n\t\tmessage,\n\t\t() => ({\n\t\t\tmin: parsedDate,\n\t\t\tlimit: parsedDate,\n\t\t\texclusive,\n\t\t}),\n\t);\n}\n\nexport interface MaxDateValidatorMessageParameters\n\textends ValidatorMessageParameters<Date> {\n\tmax: Date | null | undefined;\n\tlimit: Date | null | undefined;\n\texclusive?: boolean;\n}\n\n/**\n * Ensures a date value is on or before a date.\n * @param limit Maximum date\n * @param message Error message\n * @param exclusive Makes comparison exclusive instead of inclusive\n * @category Validation Tests\n */\nexport function maxDate(\n\tlimit: SharedDateValueType,\n\tmessage: ValidatorMessage<Date, MaxDateValidatorMessageParameters>,\n\texclusive?: boolean,\n): ValidatorTest<Date> {\n\tconst parsedDate = parseDate(limit);\n\treturn createValidatorTest(\n\t\tvalue =>\n\t\t\tparsedDate !== null\n\t\t\t&& parsedDate !== undefined\n\t\t\t&& (value === null\n\t\t\t\t|| value === undefined\n\t\t\t\t|| (value instanceof Date\n\t\t\t\t\t&& (exclusive ? value < parsedDate : value <= parsedDate))),\n\t\tmessage,\n\t\t() => ({\n\t\t\tmax: parsedDate,\n\t\t\tlimit: parsedDate,\n\t\t\texclusive,\n\t\t}),\n\t);\n}\n\n/**\n * Configuration for date validation.\n * @category Types\n */\nexport type DateConfig = ConfigBase<Date>;\n\n/**\n * Validates a date value.\n * @category Type Validators\n */\nexport const date = createTypeValidatorTest(\n\t{parser: parseDate},\n\tapplyDateConfig,\n);\n","import {\n\tConfigBase,\n\tcreateTypeValidatorTest,\n\tinvalid,\n\tvalid,\n\tValidatorMessage,\n\tValidatorTest,\n} from './shared';\n\n/**\n * Parses a value into a number.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseNumber(value: unknown): number | null | undefined {\n\tif (value === null || value === undefined) {\n\t\treturn value;\n\t}\n\n\tif (typeof value === 'number') {\n\t\treturn value;\n\t}\n\n\tif (value instanceof Date) {\n\t\treturn value.getTime();\n\t}\n\n\tif (typeof value === 'string') {\n\t\treturn Number.parseFloat(value);\n\t}\n\n\treturn Number.parseFloat(String(value));\n}\n\n/**\n * Applies a configuration to the number value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyNumberConfig(\n\tvalue: unknown,\n\tconfig: NumberConfig,\n): number | null | undefined {\n\tlet parsedValue = config.parser(value);\n\tif (config.default !== undefined && parsedValue === undefined) {\n\t\tparsedValue = config.default;\n\t}\n\n\tif (config.round && typeof parsedValue === 'number') {\n\t\tswitch (config.round) {\n\t\t\tcase 'nearest':\n\t\t\t\tparsedValue = Math.round(parsedValue);\n\t\t\t\tbreak;\n\t\t\tcase 'ceil':\n\t\t\t\tparsedValue = Math.ceil(parsedValue);\n\t\t\t\tbreak;\n\t\t\tcase 'floor':\n\t\t\t\tparsedValue = Math.floor(parsedValue);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unknown round type: ${String(config.round)}`);\n\t\t}\n\t}\n\n\treturn parsedValue;\n}\n\n/**\n * Ensures a number value is an integer.\n * @param message Error message\n * @category Validation Tests\n */\nexport function integer(\n\tmessage: ValidatorMessage<number>,\n): ValidatorTest<number> {\n\treturn async (value, field) => {\n\t\tif (\n\t\t\tvalue === undefined\n\t\t\t|| value === null\n\t\t\t|| (typeof value === 'number'\n\t\t\t\t&& Number.isFinite(value)\n\t\t\t\t&& Math.floor(value) === value)\n\t\t) {\n\t\t\treturn valid({value, field});\n\t\t}\n\n\t\treturn invalid({\n\t\t\tmessage,\n\t\t\tvalue,\n\t\t\tfield,\n\t\t});\n\t};\n}\n\n/**\n * Configuration for number validation.\n * @category Types\n */\nexport interface NumberConfig extends ConfigBase<number> {\n\t/** Apply rounding mechanism before validation. */\n\tround?: 'nearest' | 'floor' | 'ceil';\n}\n\n/**\n * Validates a number value.\n * @category Type Validators\n */\nexport const number = createTypeValidatorTest(\n\t{\n\t\tparser: parseNumber,\n\t},\n\tapplyNumberConfig,\n);\n","import {\n\tDeepPartial,\n\tExtractError,\n\tExtractValue,\n\thasOwnProperty,\n\tinvalid,\n\tvalid,\n\tValidatorTest,\n} from './shared';\n\nexport type ObjectParameter = Record<string, ValidatorTest<unknown, unknown>>;\n\n/**\n * Validates an object.\n * @category Type Validators\n */\nexport function object<P extends ObjectParameter, K extends keyof P>(\n\tproperties: P,\n): ValidatorTest<\n\tDeepPartial<{[K in keyof P]?: ExtractValue<P[K]>}>,\n\tDeepPartial<{[K in keyof P]?: ExtractError<P[K]>}>\n\t> {\n\tif (typeof properties !== 'object' || properties === null) {\n\t\tthrow new TypeError('`properties` must be a configuration object');\n\t}\n\n\treturn async (values, field) => {\n\t\tconst definedValues: {[K in keyof P]?: ExtractValue<P[K]>}\n\t\t\t= (values as {[K in keyof P]?: ExtractValue<P[K]>}) ?? {};\n\t\tconst errors: {[K in keyof P]?: ExtractError<P[K]>} = {};\n\t\tconst resolvedValues: {[K in keyof P]?: ExtractValue<P[K]>} = {};\n\t\tlet isValid = true;\n\n\t\tfor (const key in properties) {\n\t\t\tif (hasOwnProperty(properties, key)) {\n\t\t\t\tconst validator = properties[key];\n\t\t\t\tconst value = definedValues[key];\n\t\t\t\t/* eslint-disable no-await-in-loop */\n\t\t\t\tconst result\n\t\t\t\t\t= typeof validator === 'function'\n\t\t\t\t\t\t? await validator(value, key)\n\t\t\t\t\t\t: await invalid({field: key, message: 'No validator set', value});\n\t\t\t\t/* eslint-enable no-await-in-loop */\n\n\t\t\t\tresolvedValues[key] = result.value as ExtractValue<P[K]>;\n\n\t\t\t\tif (result.state === 'invalid') {\n\t\t\t\t\tisValid = false;\n\t\t\t\t\terrors[key] = (\n\t\t\t\t\t\tresult.message ? result.message : result.errors\n\t\t\t\t\t) as ExtractError<P[K]>;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (isValid) {\n\t\t\treturn valid({value: resolvedValues, field});\n\t\t}\n\n\t\treturn invalid({\n\t\t\tmessage: '',\n\t\t\tvalue: values,\n\t\t\tfield,\n\t\t\terrors,\n\t\t});\n\t};\n}\n","import {\n\tConfigBase,\n\tcreateTypeValidatorTest,\n\tcreateValidatorTest,\n\tisObject,\n\tValidatorMessage,\n\tValidatorMessageParameters,\n\tValidatorTest,\n} from './shared';\n\n/** @internal */\nconst emailPattern\n\t= /^[\\w.!#$%&'*+/=?^`{|}~-]+@[a-zA-Z\\d](?:[a-zA-Z\\d-]{0,61}[a-zA-Z\\d])?(?:\\.[a-zA-Z\\d](?:[a-zA-Z\\d-]{0,61}[a-zA-Z\\d])?)*$/;\n\n/**\n * Configuration for string validation.\n * @category Types\n */\nexport interface StringConfig extends ConfigBase<string> {\n\t/** Apply trim to string before validation. */\n\ttrim?: boolean;\n}\n\n/**\n * Parses a value into a string.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseString(value: unknown): string | null | undefined {\n\tif (value === null || value === undefined) {\n\t\treturn value;\n\t}\n\n\tif (typeof value === 'string') {\n\t\treturn value;\n\t}\n\n\tif (value instanceof Date) {\n\t\treturn value.toISOString();\n\t}\n\n\tif (isObject(value)) {\n\t\tthrow new TypeError('Failed to parse value to string.');\n\t}\n\n\treturn String(value);\n}\n\n/**\n * Applies a configuration to the string value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyStringConfig(\n\tvalue: unknown,\n\tconfig: StringConfig,\n): string | null | undefined {\n\tlet parsedValue = config.parser(value);\n\tif (config.default !== undefined && parsedValue === undefined) {\n\t\tparsedValue = config.default;\n\t}\n\n\tif (config.trim && typeof parsedValue === 'string') {\n\t\tparsedValue = parsedValue.trim();\n\t}\n\n\treturn parsedValue;\n}\n\nexport interface MatchesValidatorMessageParameters\n\textends ValidatorMessageParameters<string> {\n\tpattern: RegExp;\n}\n\n/**\n * Ensures a string value matches a pattern\n * @param pattern Pattern to match\n * @param message Error message\n * @category Validation Tests\n */\nexport function matches(\n\tpattern: RegExp,\n\tmessage: ValidatorMessage<string, MatchesValidatorMessageParameters>,\n): ValidatorTest<string> {\n\treturn createValidatorTest(\n\t\tvalue =>\n\t\t\tvalue === undefined\n\t\t\t|| value === null\n\t\t\t|| value === ''\n\t\t\t|| (typeof value === 'string' && pattern.test(value)),\n\t\tmessage,\n\t\t() => ({pattern}),\n\t);\n}\n\n/**\n * Ensures a string value matches an email pattern\n * @param message Error message\n * @category Validation Tests\n */\nexport function email(\n\tmessage: ValidatorMessage<string>,\n): ValidatorTest<string> {\n\treturn matches(emailPattern, message);\n}\n\n/**\n * Ensures a string value is a valid URL\n * @param message Error message\n * @param protocols Optional list of protocols to allow\n * @category Validation Tests\n */\nexport function url(\n\tmessage: ValidatorMessage<string>,\n\tprotocols?: string[],\n): ValidatorTest<string> {\n\treturn createValidatorTest(\n\t\tvalue => {\n\t\t\ttry {\n\t\t\t\tlet url: URL | undefined;\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined\n\t\t\t\t\t|| value === null\n\t\t\t\t\t|| value === ''\n\t\t\t\t\t|| (typeof value === 'string' && (url = new URL(value)))\n\t\t\t\t) {\n\t\t\t\t\treturn !(url && protocols && !protocols.includes(url.protocol));\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Do nothing\n\t\t\t}\n\n\t\t\treturn false;\n\t\t},\n\t\tmessage,\n\t\t() => ({protocols}),\n\t);\n}\n\n/**\n * Validates a string value.\n * @category Type Validators\n */\nexport const string = createTypeValidatorTest(\n\t{\n\t\tparser: parseString,\n\t},\n\tapplyStringConfig,\n);\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/shared.ts","../../src/arrays.ts","../../src/booleans.ts","../../src/dates.ts","../../src/numbers.ts","../../src/objects.ts","../../src/strings.ts"],"sourcesContent":["/**\n * From type-fest: https://github.com/sindresorhus/type-fest/blob/HEAD/source/except.d.ts\n * @internal\n */\ntype Except<ObjectType, KeysType extends keyof ObjectType> = Pick<\n ObjectType,\n Exclude<keyof ObjectType, KeysType>\n>;\n\nexport type ValidResult<T> = {\n /**\n * True if the original value is valid according to all validation tests\n * @deprecated Use `state` instead.\n */\n isValid: true;\n /** This is preferred to use over `isValid` as it works better for type guards. */\n state: 'valid';\n /** The parsed value. Note that may be different than the original value. */\n value: T | null | undefined;\n /** Field name if provided. Automatically provided if using object validation. */\n field?: string;\n};\n\nexport type InvalidResult<E> = {\n /**\n * True if the original value is valid according to all validation tests.\n * @deprecated Use `state` instead.\n */\n isValid: false;\n /** This is preferred to use over `isValid` as it works better for type guards. */\n state: 'invalid';\n /** The parsed value. Note that may be different than the original value. */\n value: unknown;\n /** Error message if `state` is invalid. */\n message: string;\n /** Field name if provided. Automatically provided if using object validation. */\n field?: string;\n /** Extra error details */\n errors?: E;\n};\n\n/**\n * The result of a validation.\n * @typeParam T The value type\n * @category Types\n */\nexport type ValidatorResult<T = any, E = any> =\n | ValidResult<T>\n | InvalidResult<E>;\n\n/**\n * Validation test function.\n * @typeParam T The value type\n * @category Types\n */\nexport type ValidatorTest<T = any, E = any> = (\n value?: unknown,\n field?: string\n) => Promise<ValidatorResult<T, E>>;\n\n/**\n * Extracts the generic error type from a ValidatorTest.\n * @typeParam T a ValidatorTest\n * @category Types\n */\nexport type ExtractError<T extends ValidatorTest> = T extends ValidatorTest<\n any,\n infer E\n>\n ? E\n : unknown;\n\n/**\n * Extracts the generic value type from a ValidatorTest.\n * @typeParam T a ValidatorTest\n * @category Types\n */\nexport type ExtractValue<T extends ValidatorTest> = T extends ValidatorTest<\n infer V\n>\n ? V\n : unknown;\n\n/**\n * Make a deep partial type.\n * @typeParam T any object type\n * @category Types\n */\nexport type DeepPartial<T> = {\n [P in keyof T]?: DeepPartial<T[P]>;\n};\n\n/**\n * Validation factory function.\n * @typeParam C The configuration type\n * @category Types\n */\nexport type ValidatorFactory<C, T, E> = (\n config?: Partial<C> | ValidatorTest,\n ...tests: ValidatorTest[]\n) => ValidatorTest<T, E>;\n\n/**\n * Base configuration type.\n * @typeParam T The target type.\n * @category Types\n */\nexport interface ConfigBase<T> {\n /** Parser to convert value into the designated type. */\n parser: (value: unknown) => T | null | undefined;\n /** Provide a fallback value in case the original value is undefined. */\n default?: T;\n}\n\nexport interface ValidatorMessageParameters<T> {\n value: T | null | undefined;\n field: string | undefined;\n}\n\n/**\n * Validation message. May be a plain string or a function that accepts arguments.\n * While using a string, values in squiggly brackets `{}` are replaced.\n * @category Types\n */\nexport type ValidatorMessage<\n T,\n P extends ValidatorMessageParameters<T> = ValidatorMessageParameters<T>\n> = string | ((parameters: P) => string);\n\n/**\n * Simple check for objects.\n * @param value Value to test\n */\nexport function isObject(value: unknown): boolean {\n return Object.prototype.toString.call(value) === '[object Object]';\n}\n\n/**\n * Safe hasOwnProperty check\n * @param obj Object to check\n * @param prop Property to look for\n */\nexport function hasOwnProperty(\n object: unknown,\n property: string | number | symbol\n): boolean {\n return Object.prototype.hasOwnProperty.call(object, property);\n}\n\n/** @internal */\nconst formatPattern = /{(\\w+)}/g;\n\n/**\n * Formats a message using a squiggly bracket `{}` template.\n * @param template Message template as string or function\n * @param params Params to inject into template\n * @category Helpers\n */\nexport function formatMessage<T, P extends ValidatorMessageParameters<T>>(\n template: ValidatorMessage<T, P>,\n parameters: P\n): string {\n if (typeof template === 'string') {\n return template.replace(formatPattern, (_, key: string) =>\n String((parameters as Record<string, unknown>)[key])\n );\n }\n\n return template(parameters);\n}\n\n/**\n * Creates a valid result\n * @param value Parsed value\n * @param field Field name\n * @category Helpers\n */\nexport async function valid<T, E = never>({\n value,\n field,\n}: {\n value: T | null | undefined;\n field: string | undefined;\n}): Promise<ValidatorResult<T, E>> {\n return {\n isValid: true,\n state: 'valid',\n value,\n field,\n };\n}\n\n/**\n * Creates an invalid result.\n * @param message Error message\n * @param value Parsed value\n * @param field Field name\n * @param extras Extra message params\n * @category Helpers\n */\nexport async function invalid<T, E, P extends ValidatorMessageParameters<T>>({\n errors,\n field,\n message,\n value,\n extras,\n}: {\n message: ValidatorMessage<T, P>;\n value: unknown;\n field: string | undefined;\n errors?: E;\n extras?: Except<P, 'field' | 'value'>;\n}): Promise<ValidatorResult<T, E>> {\n return {\n isValid: false,\n state: 'invalid',\n message: formatMessage(message, { ...extras, value, field } as P),\n value,\n field,\n errors,\n };\n}\n\n/**\n * Creates a type validator.\n * @typeParam T The basic type for the final value to be validated.\n * @typeParam C The configuration type.\n * @param defaultParser Parser to convert value into type.\n * @param applyConfig Function that applies configuration to value.\n * @category Helpers\n */\nexport function createTypeValidatorTest<T, C extends ConfigBase<T>, E>(\n defaultConfig: C,\n applyConfig: (value: unknown, config: C) => T | null | undefined\n): ValidatorFactory<C, T, E> {\n return (config, ...tests) => {\n const cache: Record<string, ValidatorResult<T>> = {};\n let finalConfig = defaultConfig;\n let allTests = tests;\n\n if (config !== undefined) {\n if (typeof config === 'function') {\n allTests = [config, ...tests];\n } else {\n finalConfig = {\n ...defaultConfig,\n ...config,\n };\n }\n }\n\n return async (value, field) => {\n try {\n const parsedValue = applyConfig(value, finalConfig);\n const parsedValueString = String(parsedValue);\n if (hasOwnProperty(cache, parsedValueString)) {\n return cache[parsedValueString];\n }\n\n for (const validatorTest of allTests) {\n // eslint-disable-next-line no-await-in-loop\n const result = await validatorTest(parsedValue, field);\n if (result.state === 'invalid') {\n cache[parsedValueString] = result;\n return result;\n }\n }\n\n cache[parsedValueString] = await valid({ value: parsedValue, field });\n return cache[parsedValueString];\n } catch (error) {\n return invalid({\n message: error instanceof Error ? error.message : String(error),\n value,\n field,\n });\n }\n };\n };\n}\n\n/**\n * Captures basic validator test pattern\n * @param test Test function\n * @param message Error message\n * @param getExtras Optional extra fields for error message\n */\nexport function createValidatorTest<\n T = any,\n E = any,\n P extends ValidatorMessageParameters<T> = ValidatorMessageParameters<T>\n>(\n test: (value: unknown, field?: string) => boolean,\n message: ValidatorMessage<T, P>,\n getExtras?: (value: T | null | undefined) => Except<P, 'value' | 'field'>\n): ValidatorTest<T, E> {\n return async (value, field) => {\n if (test(value, field)) {\n return valid({ value: value as T, field });\n }\n\n return invalid({\n message,\n value,\n field,\n extras: getExtras ? getExtras(value as T) : undefined,\n });\n };\n}\n\n/**\n * Ensures a value is not undefined, null, empty string, NaN, nor invalid date.\n * @param message Error message\n * @param nullable Allow null values\n * @category Validation Tests\n */\nexport function required<T, P extends ValidatorMessageParameters<T>>(\n message: ValidatorMessage<T, P>,\n nullable?: boolean\n): ValidatorTest<T> {\n return createValidatorTest(\n (value) =>\n (nullable && value === null) ||\n (value !== null &&\n value !== undefined &&\n !(typeof value === 'string' && value === '') &&\n !(typeof value === 'number' && Number.isNaN(value)) &&\n !(value instanceof Date && Number.isNaN(value.valueOf()))),\n message\n );\n}\n\nexport type SharedValueType = string | number | unknown[];\n\n/**\n * Extracts a numeric amount from value, i.e. string length, array length, or number.\n * @internal\n */\nfunction getAmount(value: SharedValueType | null | undefined) {\n return typeof value === 'string' || Array.isArray(value)\n ? value.length\n : value;\n}\n\nexport interface MaxValidatorMessageParameters\n extends ValidatorMessageParameters<SharedValueType> {\n max: number;\n amount: number | null | undefined;\n limit: number;\n exclusive?: boolean;\n}\n\n/**\n * Ensures a string, number, or array value is at most a certain amount.\n * @param limit Size or value limit\n * @param message Error message\n * @param exclusive Use exclusive comparison instead of inclusive\n * @category Validation Tests\n */\nexport function max(\n limit: number,\n message: ValidatorMessage<SharedValueType, MaxValidatorMessageParameters>,\n exclusive?: boolean\n): ValidatorTest<SharedValueType> {\n return createValidatorTest(\n (value) => {\n const amount = getAmount(value as SharedValueType);\n return (\n amount === undefined ||\n amount === null ||\n value === '' ||\n (exclusive ? amount < limit : amount <= limit)\n );\n },\n message,\n (value) => ({\n max: limit,\n limit,\n amount: getAmount(value),\n exclusive,\n })\n );\n}\n\nexport interface MinValidatorMessageParameters\n extends ValidatorMessageParameters<SharedValueType> {\n min: number;\n limit: number;\n amount: number | null | undefined;\n exclusive?: boolean;\n}\n\n/**\n * Ensures a string, number, or array value is at most a certain amount.\n * @param limit Size or value limit\n * @param message Error message\n * @param exclusive Use exclusive comparison instead of inclusive\n * @category Validation Tests\n */\nexport function min(\n limit: number,\n message: ValidatorMessage<SharedValueType, MinValidatorMessageParameters>,\n exclusive?: boolean\n): ValidatorTest<SharedValueType> {\n return createValidatorTest(\n (value) => {\n const amount = getAmount(value as SharedValueType);\n return (\n amount === undefined ||\n amount === null ||\n value === '' ||\n (exclusive ? amount > limit : amount >= limit)\n );\n },\n message,\n (value) => ({\n min: limit,\n limit,\n amount: getAmount(value),\n exclusive,\n })\n );\n}\n\nexport interface ExactValidatorMessageParameters\n extends ValidatorMessageParameters<SharedValueType> {\n limit: number;\n amount: number | null | undefined;\n exact: number;\n}\n\n/**\n * Ensures a string, number, or array value is exactly a certain amount.\n * @param limit Size or value limit\n * @param message Error message\n * @category Validation Tests\n */\nexport function exact(\n limit: number,\n message: ValidatorMessage<SharedValueType, ExactValidatorMessageParameters>\n): ValidatorTest<SharedValueType> {\n return createValidatorTest(\n (value) => {\n const amount = getAmount(value as SharedValueType);\n return (\n amount === undefined ||\n amount === null ||\n value === '' ||\n amount === limit\n );\n },\n message,\n (value) => ({\n amount: getAmount(value),\n limit,\n exact: limit,\n })\n );\n}\n\nexport interface OneOfValidatorMessageParameters<T>\n extends ValidatorMessageParameters<T> {\n values: readonly T[];\n}\n\n/**\n * Ensures a value is one in a predefined list.\n * @param values List of allowed values.\n * @param message Error message\n * @category Validation Tests\n */\nexport function oneOf<T extends string | number | boolean | Date>(\n values: readonly T[],\n message: ValidatorMessage<T, OneOfValidatorMessageParameters<T>>\n): ValidatorTest<T> {\n return createValidatorTest(\n (value) =>\n value === undefined ||\n value === null ||\n values.includes(value as T) ||\n (value instanceof Date &&\n values.some((x) => x.valueOf() === value.valueOf())),\n message,\n () => ({ values })\n );\n}\n","import {\n ConfigBase,\n invalid,\n valid,\n ValidatorResult,\n ValidatorTest,\n} from './shared';\n\n/**\n * Invalid validation result for an item in the array\n * @category Types\n */\nexport interface ArrayItemValidatorResult {\n /** The index of the item in the original array */\n index: number;\n /** The error message if a simple type */\n message: string;\n /** The errors if an object or array */\n errors: unknown;\n}\n\n/**\n * Configuration for array validation.\n * @category Types\n */\nexport type ArrayConfig = ConfigBase<unknown[]>;\n\n/**\n * Parses a value into an array.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseArray(value: unknown): unknown[] | null | undefined {\n if (Array.isArray(value)) {\n return value as unknown[];\n }\n\n if (value === null || value === undefined) {\n return value;\n }\n\n const iterable = value as Iterable<unknown>;\n\n if (iterable[Symbol.iterator]) {\n return [...iterable];\n }\n\n return [];\n}\n\n/**\n * Applies a configuration to the array value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyArrayConfig<T>(\n config: ArrayConfig,\n value: unknown\n): T[] | null | undefined {\n let parsedValue = config.parser(value);\n if (parsedValue === undefined && config.default !== undefined) {\n parsedValue = config.default;\n }\n\n return parsedValue as T[];\n}\n\n/**\n * Validates an array. The first passed validator is used to validate individual\n * items. The remaining validators target the array itself.\n * @category Type Validators\n */\nexport function array<T>(\n config?: Partial<ArrayConfig> | ValidatorTest<T>,\n ...tests: ValidatorTest[]\n): ValidatorTest<T[], ArrayItemValidatorResult[]> {\n let allTests = tests;\n let finalConfig: ArrayConfig = {\n parser: parseArray,\n };\n\n if (config !== undefined) {\n if (typeof config === 'function') {\n allTests = [config, ...tests];\n } else {\n finalConfig = {\n ...finalConfig,\n ...config,\n };\n }\n }\n\n return async (value, field) => {\n const arrayValue = applyArrayConfig<T>(finalConfig, value);\n let arrayInvalidResult: ValidatorResult | undefined;\n let isValid = true;\n const errors: ArrayItemValidatorResult[] = [];\n const [validateItem, ...arrayTests] = allTests;\n\n for (const validatorTest of arrayTests) {\n // eslint-disable-next-line no-await-in-loop\n const result = await validatorTest(arrayValue, field);\n if (result.state === 'invalid') {\n isValid = false;\n arrayInvalidResult = result;\n break;\n }\n }\n\n if (arrayValue && validateItem) {\n for (const [index, item] of arrayValue.entries()) {\n // eslint-disable-next-line no-await-in-loop\n const result = await validateItem(\n item,\n field ? `${field}[${index}]` : `[${index}]`\n );\n\n if (result.state === 'invalid') {\n isValid = false;\n errors.push({\n errors: result.errors,\n index,\n message: result.message,\n });\n }\n }\n }\n\n if (isValid) {\n return valid({\n value: arrayValue,\n field,\n });\n }\n\n return invalid({\n message:\n arrayInvalidResult?.state === 'invalid'\n ? arrayInvalidResult.message\n : '',\n value,\n field,\n errors,\n });\n };\n}\n","import { ConfigBase, createTypeValidatorTest } from './shared';\n\n/**\n * Parses a value into a boolean.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseBoolean(value: unknown): boolean | null | undefined {\n if (value === undefined || value === null) {\n return value;\n }\n\n if (typeof value === 'boolean') {\n return value;\n }\n\n return Boolean(value);\n}\n\n/**\n * Applies a configuration to the boolean value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyBooleanConfig(\n value: unknown,\n config: BooleanConfig\n): boolean | null | undefined {\n let parsedValue = config.parser(value);\n if (parsedValue === undefined && config.default !== undefined) {\n parsedValue = config.default;\n }\n\n return parsedValue;\n}\n\n/**\n * Configuration for boolean validation.\n * @category Types\n */\nexport type BooleanConfig = ConfigBase<boolean>;\n\n/**\n * Validates a boolean value.\n * @category Type Validators\n */\nexport const boolean = createTypeValidatorTest(\n { parser: parseBoolean },\n applyBooleanConfig\n);\n","import {\n ConfigBase,\n createTypeValidatorTest,\n createValidatorTest,\n ValidatorMessage,\n ValidatorMessageParameters,\n ValidatorTest,\n} from './shared';\n\n/** Badly formatted date for internal use. */\nexport const invalidDate = new Date('');\n\n/** @internal */\nconst isoDatePattern =\n /^(\\d{4})(?:-([0-2]\\d)(?:-([0-3]\\d)(?:[ T]([0-2]\\d):([0-5]\\d)(?::([0-5]\\d)(\\.\\d+)?(Z|[+-][0-2]\\d:?[0-5]\\d)?)?)?)?)?$/;\n\n/** @internal */\nconst timezonePattern = /^([+-])([0-2]\\d):?([0-5]\\d)$/;\n\n/**\n * Parses a timezone string.\n * @param timezone Timezone to parse\n * @internal\n */\nfunction parseTimezone(timezone: string): number {\n const parts = timezonePattern.exec(timezone);\n\n if (timezone === 'Z' || !parts) {\n return 0;\n }\n\n const [, sign, hour, minute] = parts;\n const multiplier = sign === '-' ? -1 : 1;\n const hoursInMinutes = Number.parseInt(hour, 10) * 60;\n const offset = hoursInMinutes + Number.parseInt(minute, 10);\n\n return multiplier * offset;\n}\n\nconst BASE = 10;\n\nconst dateParts = [\n // Skip\n () => 0,\n // Year\n (part = '0') => Number.parseInt(part, BASE),\n // Month\n (part = '1') => Number.parseInt(part, BASE) - 1,\n // Day\n (part = '1') => Number.parseInt(part, BASE),\n // Hour\n (part = '0') => Number.parseInt(part, BASE),\n // Minute\n (part = '0') => Number.parseInt(part, BASE),\n // Second\n (part = '0') => Number.parseInt(part, BASE),\n // Millisecond\n (part = '0') => Number.parseFloat(part) * 1e3,\n];\n\n/**\n * Parses a value into a date.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseDate(value: unknown): Date | null | undefined {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (value instanceof Date) {\n return value;\n }\n\n if (typeof value === 'number') {\n return new Date(value);\n }\n\n if (typeof value !== 'string') {\n return invalidDate;\n }\n\n const parts = isoDatePattern.exec(value);\n\n if (parts === null) {\n return invalidDate;\n }\n\n const [, year, month, day, hour, minute, second, millisecond] = dateParts.map(\n (parse, index) => parse(parts[index])\n );\n\n const timezone = parts[8];\n\n if (!timezone) {\n return new Date(year, month, day, hour, minute, second, millisecond);\n }\n\n const minuteOffset = parseTimezone(timezone);\n\n return new Date(\n Date.UTC(year, month, day, hour, minute + minuteOffset, second, millisecond)\n );\n}\n\n/**\n * Applies a configuration to the date value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyDateConfig(\n value: unknown,\n config: DateConfig\n): Date | null | undefined {\n let parsedValue = config.parser(value);\n if (parsedValue === undefined && config.default !== undefined) {\n parsedValue = config.default;\n }\n\n return parsedValue;\n}\n\nexport type SharedDateValueType = Date | string | number;\n\nexport interface MinDateValidatorMessageParameters\n extends ValidatorMessageParameters<Date> {\n min: Date | null | undefined;\n limit: Date | null | undefined;\n exclusive?: boolean;\n}\n\n/**\n * Ensures a date value is on or after a date.\n * @param limit Minimum date\n * @param message Error message\n * @param exclusive Makes comparison exclusive instead of inclusive\n * @category Validation Tests\n */\nexport function minDate(\n limit: SharedDateValueType,\n message: ValidatorMessage<Date, MinDateValidatorMessageParameters>,\n exclusive?: boolean\n): ValidatorTest<Date, null> {\n const parsedDate = parseDate(limit);\n return createValidatorTest(\n (value) =>\n parsedDate !== null &&\n parsedDate !== undefined &&\n (value === null ||\n value === undefined ||\n (value instanceof Date &&\n (exclusive ? value > parsedDate : value >= parsedDate))),\n message,\n () => ({\n min: parsedDate,\n limit: parsedDate,\n exclusive,\n })\n );\n}\n\nexport interface MaxDateValidatorMessageParameters\n extends ValidatorMessageParameters<Date> {\n max: Date | null | undefined;\n limit: Date | null | undefined;\n exclusive?: boolean;\n}\n\n/**\n * Ensures a date value is on or before a date.\n * @param limit Maximum date\n * @param message Error message\n * @param exclusive Makes comparison exclusive instead of inclusive\n * @category Validation Tests\n */\nexport function maxDate(\n limit: SharedDateValueType,\n message: ValidatorMessage<Date, MaxDateValidatorMessageParameters>,\n exclusive?: boolean\n): ValidatorTest<Date> {\n const parsedDate = parseDate(limit);\n return createValidatorTest(\n (value) =>\n parsedDate !== null &&\n parsedDate !== undefined &&\n (value === null ||\n value === undefined ||\n (value instanceof Date &&\n (exclusive ? value < parsedDate : value <= parsedDate))),\n message,\n () => ({\n max: parsedDate,\n limit: parsedDate,\n exclusive,\n })\n );\n}\n\n/**\n * Configuration for date validation.\n * @category Types\n */\nexport type DateConfig = ConfigBase<Date>;\n\n/**\n * Validates a date value.\n * @category Type Validators\n */\nexport const date = createTypeValidatorTest(\n { parser: parseDate },\n applyDateConfig\n);\n","import {\n ConfigBase,\n createTypeValidatorTest,\n invalid,\n valid,\n ValidatorMessage,\n ValidatorTest,\n} from './shared';\n\n/**\n * Parses a value into a number.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseNumber(value: unknown): number | null | undefined {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (typeof value === 'number') {\n return value;\n }\n\n if (value instanceof Date) {\n return value.getTime();\n }\n\n if (typeof value === 'string') {\n return Number.parseFloat(value);\n }\n\n return Number.parseFloat(String(value));\n}\n\n/**\n * Applies a configuration to the number value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyNumberConfig(\n value: unknown,\n config: NumberConfig\n): number | null | undefined {\n let parsedValue = config.parser(value);\n if (config.default !== undefined && parsedValue === undefined) {\n parsedValue = config.default;\n }\n\n if (config.round && typeof parsedValue === 'number') {\n switch (config.round) {\n case 'nearest':\n parsedValue = Math.round(parsedValue);\n break;\n case 'ceil':\n parsedValue = Math.ceil(parsedValue);\n break;\n case 'floor':\n parsedValue = Math.floor(parsedValue);\n break;\n default:\n throw new Error(`Unknown round type: ${String(config.round)}`);\n }\n }\n\n return parsedValue;\n}\n\n/**\n * Ensures a number value is an integer.\n * @param message Error message\n * @category Validation Tests\n */\nexport function integer(\n message: ValidatorMessage<number>\n): ValidatorTest<number> {\n return async (value, field) => {\n if (\n value === undefined ||\n value === null ||\n (typeof value === 'number' &&\n Number.isFinite(value) &&\n Math.floor(value) === value)\n ) {\n return valid({ value, field });\n }\n\n return invalid({\n message,\n value,\n field,\n });\n };\n}\n\n/**\n * Configuration for number validation.\n * @category Types\n */\nexport interface NumberConfig extends ConfigBase<number> {\n /** Apply rounding mechanism before validation. */\n round?: 'nearest' | 'floor' | 'ceil';\n}\n\n/**\n * Validates a number value.\n * @category Type Validators\n */\nexport const number = createTypeValidatorTest(\n {\n parser: parseNumber,\n },\n applyNumberConfig\n);\n","import {\n DeepPartial,\n ExtractError,\n ExtractValue,\n hasOwnProperty,\n invalid,\n valid,\n ValidatorTest,\n} from './shared';\n\nexport type ObjectParameter = Record<string, ValidatorTest<unknown, unknown>>;\n\n/**\n * Validates an object.\n * @category Type Validators\n */\nexport function object<P extends ObjectParameter, K extends keyof P>(\n properties: P\n): ValidatorTest<\n DeepPartial<{ [K in keyof P]?: ExtractValue<P[K]> }>,\n DeepPartial<{ [K in keyof P]?: ExtractError<P[K]> }>\n> {\n if (typeof properties !== 'object' || properties === null) {\n throw new TypeError('`properties` must be a configuration object');\n }\n\n return async (values, field) => {\n const definedValues: { [K in keyof P]?: ExtractValue<P[K]> } =\n (values as { [K in keyof P]?: ExtractValue<P[K]> }) ?? {};\n const errors: { [K in keyof P]?: ExtractError<P[K]> } = {};\n const resolvedValues: { [K in keyof P]?: ExtractValue<P[K]> } = {};\n let isValid = true;\n\n for (const key in properties) {\n if (hasOwnProperty(properties, key)) {\n const validator = properties[key];\n const value = definedValues[key];\n /* eslint-disable no-await-in-loop */\n const result =\n typeof validator === 'function'\n ? await validator(value, key)\n : await invalid({ field: key, message: 'No validator set', value });\n /* eslint-enable no-await-in-loop */\n\n resolvedValues[key] = result.value as ExtractValue<P[K]>;\n\n if (result.state === 'invalid') {\n isValid = false;\n errors[key] = (\n result.message ? result.message : result.errors\n ) as ExtractError<P[K]>;\n }\n }\n }\n\n if (isValid) {\n return valid({ value: resolvedValues, field });\n }\n\n return invalid({\n message: '',\n value: values,\n field,\n errors,\n });\n };\n}\n","import {\n ConfigBase,\n createTypeValidatorTest,\n createValidatorTest,\n isObject,\n ValidatorMessage,\n ValidatorMessageParameters,\n ValidatorTest,\n} from './shared';\n\n/** @internal */\nconst emailPattern =\n /^[\\w!#$%&'*+./=?^`{|}~-]+@[\\dA-Za-z](?:[\\dA-Za-z-]{0,61}[\\dA-Za-z])?(?:\\.[\\dA-Za-z](?:[\\dA-Za-z-]{0,61}[\\dA-Za-z])?)*$/;\n\n/**\n * Configuration for string validation.\n * @category Types\n */\nexport interface StringConfig extends ConfigBase<string> {\n /** Apply trim to string before validation. */\n trim?: boolean;\n}\n\n/**\n * Parses a value into a string.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseString(value: unknown): string | null | undefined {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n if (isObject(value)) {\n throw new TypeError('Failed to parse value to string.');\n }\n\n return String(value);\n}\n\n/**\n * Applies a configuration to the string value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyStringConfig(\n value: unknown,\n config: StringConfig\n): string | null | undefined {\n let parsedValue = config.parser(value);\n if (config.default !== undefined && parsedValue === undefined) {\n parsedValue = config.default;\n }\n\n if (config.trim && typeof parsedValue === 'string') {\n parsedValue = parsedValue.trim();\n }\n\n return parsedValue;\n}\n\nexport interface MatchesValidatorMessageParameters\n extends ValidatorMessageParameters<string> {\n pattern: RegExp;\n}\n\n/**\n * Ensures a string value matches a pattern\n * @param pattern Pattern to match\n * @param message Error message\n * @category Validation Tests\n */\nexport function matches(\n pattern: RegExp,\n message: ValidatorMessage<string, MatchesValidatorMessageParameters>\n): ValidatorTest<string> {\n return createValidatorTest(\n (value) =>\n value === undefined ||\n value === null ||\n value === '' ||\n (typeof value === 'string' && pattern.test(value)),\n message,\n () => ({ pattern })\n );\n}\n\n/**\n * Ensures a string value matches an email pattern\n * @param message Error message\n * @category Validation Tests\n */\nexport function email(\n message: ValidatorMessage<string>\n): ValidatorTest<string> {\n return matches(emailPattern, message);\n}\n\n/**\n * Ensures a string value is a valid URL\n * @param message Error message\n * @param protocols Optional list of protocols to allow\n * @category Validation Tests\n */\nexport function url(\n message: ValidatorMessage<string>,\n protocols?: string[]\n): ValidatorTest<string> {\n return createValidatorTest(\n (value) => {\n try {\n let url: URL | undefined;\n if (\n value === undefined ||\n value === null ||\n value === '' ||\n (typeof value === 'string' && (url = new URL(value)))\n ) {\n return !(url && protocols && !protocols.includes(url.protocol));\n }\n } catch {\n // Do nothing\n }\n\n return false;\n },\n message,\n () => ({ protocols })\n );\n}\n\n/**\n * Validates a string value.\n * @category Type Validators\n */\nexport const string = createTypeValidatorTest(\n {\n parser: parseString,\n },\n applyStringConfig\n);\n"],"names":[],"mappings":"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"}
package/dist/esm/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  function isObject(value) {
2
2
  return Object.prototype.toString.call(value) === "[object Object]";
3
3
  }
4
- function hasOwnProperty(object, prop) {
5
- return Object.prototype.hasOwnProperty.call(object, prop);
4
+ function hasOwnProperty(object, property) {
5
+ return Object.prototype.hasOwnProperty.call(object, property);
6
6
  }
7
7
  const formatPattern = /{(\w+)}/g;
8
8
  function formatMessage(template, parameters) {
@@ -32,7 +32,7 @@ async function invalid({
32
32
  return {
33
33
  isValid: false,
34
34
  state: "invalid",
35
- message: formatMessage(message, { ...extras != null ? extras : {}, value, field }),
35
+ message: formatMessage(message, { ...extras, value, field }),
36
36
  value,
37
37
  field,
38
38
  errors
@@ -71,7 +71,7 @@ function createTypeValidatorTest(defaultConfig, applyConfig) {
71
71
  return cache[parsedValueString];
72
72
  } catch (error) {
73
73
  return invalid({
74
- message: error == null ? void 0 : error.message,
74
+ message: error instanceof Error ? error.message : String(error),
75
75
  value,
76
76
  field
77
77
  });
@@ -230,8 +230,8 @@ function applyBooleanConfig(value, config) {
230
230
  const boolean = createTypeValidatorTest({ parser: parseBoolean }, applyBooleanConfig);
231
231
 
232
232
  const invalidDate = new Date("");
233
- const isoDatePattern = /^(\d{4})(?:-([012]\d)(?:-([0123]\d)(?:[T ]([012]\d):([0-5]\d)(?::([0-5]\d)(\.\d+)?(Z|[+-][012]\d:?[0-5]\d)?)?)?)?)?$/;
234
- const timezonePattern = /^([+-])([012]\d):?([0-5]\d)$/;
233
+ const isoDatePattern = /^(\d{4})(?:-([0-2]\d)(?:-([0-3]\d)(?:[ T]([0-2]\d):([0-5]\d)(?::([0-5]\d)(\.\d+)?(Z|[+-][0-2]\d:?[0-5]\d)?)?)?)?)?$/;
234
+ const timezonePattern = /^([+-])([0-2]\d):?([0-5]\d)$/;
235
235
  function parseTimezone(timezone) {
236
236
  const parts = timezonePattern.exec(timezone);
237
237
  if (timezone === "Z" || !parts) {
@@ -239,8 +239,8 @@ function parseTimezone(timezone) {
239
239
  }
240
240
  const [, sign, hour, minute] = parts;
241
241
  const multiplier = sign === "-" ? -1 : 1;
242
- const hoursInMinutes = Number.parseInt(hour != null ? hour : "0", 10) * 60;
243
- const offset = hoursInMinutes + Number.parseInt(minute != null ? minute : "0", 10);
242
+ const hoursInMinutes = Number.parseInt(hour, 10) * 60;
243
+ const offset = hoursInMinutes + Number.parseInt(minute, 10);
244
244
  return multiplier * offset;
245
245
  }
246
246
  const BASE = 10;
@@ -271,7 +271,7 @@ function parseDate(value) {
271
271
  if (parts === null) {
272
272
  return invalidDate;
273
273
  }
274
- const [, year, month, day, hour, minute, second, millisecond] = dateParts.map((parse, i) => parse(parts[i]));
274
+ const [, year, month, day, hour, minute, second, millisecond] = dateParts.map((parse, index) => parse(parts[index]));
275
275
  const timezone = parts[8];
276
276
  if (!timezone) {
277
277
  return new Date(year, month, day, hour, minute, second, millisecond);
@@ -390,7 +390,7 @@ function object(properties) {
390
390
  };
391
391
  }
392
392
 
393
- const emailPattern = /^[\w.!#$%&'*+/=?^`{|}~-]+@[a-zA-Z\d](?:[a-zA-Z\d-]{0,61}[a-zA-Z\d])?(?:\.[a-zA-Z\d](?:[a-zA-Z\d-]{0,61}[a-zA-Z\d])?)*$/;
393
+ const emailPattern = /^[\w!#$%&'*+./=?^`{|}~-]+@[\dA-Za-z](?:[\dA-Za-z-]{0,61}[\dA-Za-z])?(?:\.[\dA-Za-z](?:[\dA-Za-z-]{0,61}[\dA-Za-z])?)*$/;
394
394
  function parseString(value) {
395
395
  if (value === null || value === void 0) {
396
396
  return value;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/shared.ts","../../src/arrays.ts","../../src/booleans.ts","../../src/dates.ts","../../src/numbers.ts","../../src/objects.ts","../../src/strings.ts"],"sourcesContent":["/**\n * From type-fest: https://github.com/sindresorhus/type-fest/blob/HEAD/source/except.d.ts\n * @internal\n */\ntype Except<ObjectType, KeysType extends keyof ObjectType> = Pick<ObjectType, Exclude<keyof ObjectType, KeysType>>;\n\nexport type ValidResult<T> = {\n\t/**\n\t * True if the original value is valid according to all validation tests\n\t * @deprecated Use `state` instead.\n\t */\n\tisValid: true;\n\t/** This is preferred to use over `isValid` as it works better for type guards. */\n\tstate: 'valid';\n\t/** The parsed value. Note that may be different than the original value. */\n\tvalue: T | null | undefined;\n\t/** Field name if provided. Automatically provided if using object validation. */\n\tfield?: string;\n};\n\nexport type InvalidResult<E> = {\n\t/**\n\t * True if the original value is valid according to all validation tests.\n\t * @deprecated Use `state` instead.\n\t */\n\tisValid: false;\n\t/** This is preferred to use over `isValid` as it works better for type guards. */\n\tstate: 'invalid';\n\t/** The parsed value. Note that may be different than the original value. */\n\tvalue: unknown;\n\t/** Error message if `state` is invalid. */\n\tmessage: string;\n\t/** Field name if provided. Automatically provided if using object validation. */\n\tfield?: string;\n\t/** Extra error details */\n\terrors?: E;\n};\n\n/**\n * The result of a validation.\n * @typeParam T The value type\n * @category Types\n */\nexport type ValidatorResult<T = any, E = any> =\n\t| ValidResult<T>\n\t| InvalidResult<E>;\n\n/**\n * Validation test function.\n * @typeParam T The value type\n * @category Types\n */\nexport type ValidatorTest<T = any, E = any> = (\n\tvalue: unknown,\n\tfield?: string\n) => Promise<ValidatorResult<T, E>>;\n\n/**\n * Extracts the generic error type from a ValidatorTest.\n * @typeParam T a ValidatorTest\n * @category Types\n */\nexport type ExtractError<T extends ValidatorTest> = T extends ValidatorTest<\nany,\ninfer E\n>\n\t? E\n\t: unknown;\n\n/**\n * Extracts the generic value type from a ValidatorTest.\n * @typeParam T a ValidatorTest\n * @category Types\n */\nexport type ExtractValue<T extends ValidatorTest> = T extends ValidatorTest<\ninfer V\n>\n\t? V\n\t: unknown;\n\n/**\n * Make a deep partial type.\n * @typeParam T any object type\n * @category Types\n */\nexport type DeepPartial<T> = {\n\t[P in keyof T]?: DeepPartial<T[P]>;\n};\n\n/**\n * Validation factory function.\n * @typeParam C The configuration type\n * @category Types\n */\nexport type ValidatorFactory<C, T, E> = (\n\tconfig?: Partial<C> | ValidatorTest,\n\t...tests: ValidatorTest[]\n) => ValidatorTest<T, E>;\n\n/**\n * Base configuration type.\n * @typeParam T The target type.\n * @category Types\n */\nexport interface ConfigBase<T> {\n\t/** Parser to convert value into the designated type. */\n\tparser: (value: unknown) => T | null | undefined;\n\t/** Provide a fallback value in case the original value is undefined. */\n\tdefault?: T;\n}\n\nexport interface ValidatorMessageParameters<T> {\n\tvalue: T | null | undefined;\n\tfield: string | undefined;\n}\n\n/**\n * Validation message. May be a plain string or a function that accepts arguments.\n * While using a string, values in squiggly brackets `{}` are replaced.\n * @category Types\n */\nexport type ValidatorMessage<\n\tT,\n\tP extends ValidatorMessageParameters<T> = ValidatorMessageParameters<T>,\n> = string | ((parameters: P) => string);\n\n/**\n * Simple check for objects.\n * @param value Value to test\n */\nexport function isObject(value: unknown): boolean {\n\treturn Object.prototype.toString.call(value) === '[object Object]';\n}\n\n/**\n * Safe hasOwnProperty check\n * @param obj Object to check\n * @param prop Property to look for\n */\nexport function hasOwnProperty(\n\tobject: unknown,\n\tprop: string | number | symbol,\n): boolean {\n\treturn Object.prototype.hasOwnProperty.call(object, prop);\n}\n\n/** @internal */\nconst formatPattern = /{(\\w+)}/g;\n\n/**\n * Formats a message using a squiggly bracket `{}` template.\n * @param template Message template as string or function\n * @param params Params to inject into template\n * @category Helpers\n */\nexport function formatMessage<T, P extends ValidatorMessageParameters<T>>(\n\ttemplate: ValidatorMessage<T, P>,\n\tparameters: P,\n): string {\n\tif (typeof template === 'string') {\n\t\treturn template.replace(formatPattern, (_, key: string) =>\n\t\t\tString((parameters as Record<string, unknown>)[key]),\n\t\t);\n\t}\n\n\treturn template(parameters);\n}\n\n/**\n * Creates a valid result\n * @param value Parsed value\n * @param field Field name\n * @category Helpers\n */\nexport async function valid<T, E = never>({\n\tvalue,\n\tfield,\n}: {\n\tvalue: T | null | undefined;\n\tfield: string | undefined;\n}): Promise<ValidatorResult<T, E>> {\n\treturn {\n\t\tisValid: true,\n\t\tstate: 'valid',\n\t\tvalue,\n\t\tfield,\n\t};\n}\n\n/**\n * Creates an invalid result.\n * @param message Error message\n * @param value Parsed value\n * @param field Field name\n * @param extras Extra message params\n * @category Helpers\n */\nexport async function invalid<T, E, P extends ValidatorMessageParameters<T>>({\n\terrors,\n\tfield,\n\tmessage,\n\tvalue,\n\textras,\n}: {\n\tmessage: ValidatorMessage<T, P>;\n\tvalue: unknown;\n\tfield: string | undefined;\n\terrors?: E;\n\textras?: Except<P, 'field' | 'value'>;\n}): Promise<ValidatorResult<T, E>> {\n\treturn {\n\t\tisValid: false,\n\t\tstate: 'invalid',\n\t\tmessage: formatMessage(message, {...(extras ?? {}), value, field} as P),\n\t\tvalue,\n\t\tfield,\n\t\terrors,\n\t};\n}\n\n/**\n * Creates a type validator.\n * @typeParam T The basic type for the final value to be validated.\n * @typeParam C The configuration type.\n * @param defaultParser Parser to convert value into type.\n * @param applyConfig Function that applies configuration to value.\n * @category Helpers\n */\nexport function createTypeValidatorTest<T, C extends ConfigBase<T>, E>(\n\tdefaultConfig: C,\n\tapplyConfig: (value: unknown, config: C) => T | null | undefined,\n): ValidatorFactory<C, T, E> {\n\treturn (config, ...tests) => {\n\t\tconst cache: Record<string, ValidatorResult<T>> = {};\n\t\tlet finalConfig = defaultConfig;\n\t\tlet allTests = tests;\n\n\t\tif (config !== undefined) {\n\t\t\tif (typeof config === 'function') {\n\t\t\t\tallTests = [config, ...tests];\n\t\t\t} else {\n\t\t\t\tfinalConfig = {\n\t\t\t\t\t...defaultConfig,\n\t\t\t\t\t...config,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn async (value, field) => {\n\t\t\ttry {\n\t\t\t\tconst parsedValue = applyConfig(value, finalConfig);\n\t\t\t\tconst parsedValueString = String(parsedValue);\n\t\t\t\tif (hasOwnProperty(cache, parsedValueString)) {\n\t\t\t\t\treturn cache[parsedValueString];\n\t\t\t\t}\n\n\t\t\t\tfor (const validatorTest of allTests) {\n\t\t\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\t\t\tconst result = await validatorTest(parsedValue, field);\n\t\t\t\t\tif (result.state === 'invalid') {\n\t\t\t\t\t\tcache[parsedValueString] = result;\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcache[parsedValueString] = await valid({value: parsedValue, field});\n\t\t\t\treturn cache[parsedValueString];\n\t\t\t} catch (error: unknown) {\n\t\t\t\treturn invalid({\n\t\t\t\t\tmessage: (error as Error)?.message,\n\t\t\t\t\tvalue,\n\t\t\t\t\tfield,\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\t};\n}\n\n/**\n * Captures basic validator test pattern\n * @param test Test function\n * @param message Error message\n * @param getExtras Optional extra fields for error message\n */\nexport function createValidatorTest<\n\tT = any,\n\tE = any,\n\tP extends ValidatorMessageParameters<T> = ValidatorMessageParameters<T>,\n>(\n\ttest: (value: unknown, field?: string) => boolean,\n\tmessage: ValidatorMessage<T, P>,\n\tgetExtras?: (value: T | null | undefined) => Except<P, 'value' | 'field'>,\n): ValidatorTest<T, E> {\n\treturn async (value, field) => {\n\t\tif (test(value, field)) {\n\t\t\treturn valid({value: value as T, field});\n\t\t}\n\n\t\treturn invalid({\n\t\t\tmessage,\n\t\t\tvalue,\n\t\t\tfield,\n\t\t\textras: getExtras ? getExtras(value as T) : undefined,\n\t\t});\n\t};\n}\n\n/**\n * Ensures a value is not undefined, null, empty string, NaN, nor invalid date.\n * @param message Error message\n * @param nullable Allow null values\n * @category Validation Tests\n */\nexport function required<T, P extends ValidatorMessageParameters<T>>(\n\tmessage: ValidatorMessage<T, P>,\n\tnullable?: boolean,\n): ValidatorTest<T> {\n\treturn createValidatorTest(\n\t\tvalue =>\n\t\t\t(nullable && value === null)\n\t\t\t|| (value !== null\n\t\t\t\t&& value !== undefined\n\t\t\t\t&& !(typeof value === 'string' && value === '')\n\t\t\t\t&& !(typeof value === 'number' && Number.isNaN(value))\n\t\t\t\t&& !(value instanceof Date && Number.isNaN(value.valueOf()))),\n\t\tmessage,\n\t);\n}\n\nexport type SharedValueType = string | number | unknown[];\n\n/**\n * Extracts a numeric amount from value, i.e. string length, array length, or number.\n * @internal\n */\nfunction getAmount(value: SharedValueType | null | undefined) {\n\treturn typeof value === 'string' || Array.isArray(value)\n\t\t? value.length\n\t\t: value;\n}\n\nexport interface MaxValidatorMessageParameters\n\textends ValidatorMessageParameters<SharedValueType> {\n\tmax: number;\n\tamount: number | null | undefined;\n\tlimit: number;\n\texclusive?: boolean;\n}\n\n/**\n * Ensures a string, number, or array value is at most a certain amount.\n * @param limit Size or value limit\n * @param message Error message\n * @param exclusive Use exclusive comparison instead of inclusive\n * @category Validation Tests\n */\nexport function max(\n\tlimit: number,\n\tmessage: ValidatorMessage<SharedValueType, MaxValidatorMessageParameters>,\n\texclusive?: boolean,\n): ValidatorTest<SharedValueType> {\n\treturn createValidatorTest(\n\t\tvalue => {\n\t\t\tconst amount = getAmount(value as SharedValueType);\n\t\t\treturn (\n\t\t\t\tamount === undefined\n\t\t\t\t|| amount === null\n\t\t\t\t|| value === ''\n\t\t\t\t|| (exclusive ? amount < limit : amount <= limit)\n\t\t\t);\n\t\t},\n\t\tmessage,\n\t\tvalue => ({\n\t\t\tmax: limit,\n\t\t\tlimit,\n\t\t\tamount: getAmount(value),\n\t\t\texclusive,\n\t\t}),\n\t);\n}\n\nexport interface MinValidatorMessageParameters\n\textends ValidatorMessageParameters<SharedValueType> {\n\tmin: number;\n\tlimit: number;\n\tamount: number | null | undefined;\n\texclusive?: boolean;\n}\n\n/**\n * Ensures a string, number, or array value is at most a certain amount.\n * @param limit Size or value limit\n * @param message Error message\n * @param exclusive Use exclusive comparison instead of inclusive\n * @category Validation Tests\n */\nexport function min(\n\tlimit: number,\n\tmessage: ValidatorMessage<SharedValueType, MinValidatorMessageParameters>,\n\texclusive?: boolean,\n): ValidatorTest<SharedValueType> {\n\treturn createValidatorTest(\n\t\tvalue => {\n\t\t\tconst amount = getAmount(value as SharedValueType);\n\t\t\treturn (\n\t\t\t\tamount === undefined\n\t\t\t\t|| amount === null\n\t\t\t\t|| value === ''\n\t\t\t\t|| (exclusive ? amount > limit : amount >= limit)\n\t\t\t);\n\t\t},\n\t\tmessage,\n\t\tvalue => ({\n\t\t\tmin: limit,\n\t\t\tlimit,\n\t\t\tamount: getAmount(value),\n\t\t\texclusive,\n\t\t}),\n\t);\n}\n\nexport interface ExactValidatorMessageParameters\n\textends ValidatorMessageParameters<SharedValueType> {\n\tlimit: number;\n\tamount: number | null | undefined;\n\texact: number;\n}\n\n/**\n * Ensures a string, number, or array value is exactly a certain amount.\n * @param limit Size or value limit\n * @param message Error message\n * @category Validation Tests\n */\nexport function exact(\n\tlimit: number,\n\tmessage: ValidatorMessage<SharedValueType, ExactValidatorMessageParameters>,\n): ValidatorTest<SharedValueType> {\n\treturn createValidatorTest(\n\t\tvalue => {\n\t\t\tconst amount = getAmount(value as SharedValueType);\n\t\t\treturn (\n\t\t\t\tamount === undefined\n\t\t\t\t|| amount === null\n\t\t\t\t|| value === ''\n\t\t\t\t|| amount === limit\n\t\t\t);\n\t\t},\n\t\tmessage,\n\t\tvalue => ({\n\t\t\tamount: getAmount(value),\n\t\t\tlimit,\n\t\t\texact: limit,\n\t\t}),\n\t);\n}\n\nexport interface OneOfValidatorMessageParameters<T>\n\textends ValidatorMessageParameters<T> {\n\tvalues: readonly T[];\n}\n\n/**\n * Ensures a value is one in a predefined list.\n * @param values List of allowed values.\n * @param message Error message\n * @category Validation Tests\n */\nexport function oneOf<T extends string | number | boolean | Date>(\n\tvalues: readonly T[],\n\tmessage: ValidatorMessage<T, OneOfValidatorMessageParameters<T>>,\n): ValidatorTest<T> {\n\treturn createValidatorTest(\n\t\tvalue =>\n\t\t\tvalue === undefined\n\t\t\t|| value === null\n\t\t\t|| values.includes(value as T)\n\t\t\t|| (value instanceof Date\n\t\t\t\t&& values.some(x => x.valueOf() === value.valueOf())),\n\t\tmessage,\n\t\t() => ({values}),\n\t);\n}\n","import {\n\tConfigBase,\n\tinvalid,\n\tvalid,\n\tValidatorResult,\n\tValidatorTest,\n} from './shared';\n\n/**\n * Invalid validation result for an item in the array\n * @category Types\n */\nexport interface ArrayItemValidatorResult {\n\t/** The index of the item in the original array */\n\tindex: number;\n\t/** The error message if a simple type */\n\tmessage: string;\n\t/** The errors if an object or array */\n\terrors: unknown;\n}\n\n/**\n * Configuration for array validation.\n * @category Types\n */\nexport type ArrayConfig = ConfigBase<unknown[]>;\n\n/**\n * Parses a value into an array.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseArray(value: unknown): unknown[] | null | undefined {\n\tif (Array.isArray(value)) {\n\t\treturn value as unknown[];\n\t}\n\n\tif (value === null || value === undefined) {\n\t\treturn value;\n\t}\n\n\tconst iterable = value as Iterable<unknown>;\n\n\tif (iterable[Symbol.iterator]) {\n\t\treturn [...iterable];\n\t}\n\n\treturn [];\n}\n\n/**\n * Applies a configuration to the array value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyArrayConfig<T>(\n\tconfig: ArrayConfig,\n\tvalue: unknown,\n): T[] | null | undefined {\n\tlet parsedValue = config.parser(value);\n\tif (parsedValue === undefined && config.default !== undefined) {\n\t\tparsedValue = config.default;\n\t}\n\n\treturn parsedValue as T[];\n}\n\n/**\n * Validates an array. The first passed validator is used to validate individual\n * items. The remaining validators target the array itself.\n * @category Type Validators\n */\nexport function array<T>(\n\tconfig?: Partial<ArrayConfig> | ValidatorTest<T>,\n\t...tests: ValidatorTest[]\n): ValidatorTest<T[], ArrayItemValidatorResult[]> {\n\tlet allTests = tests;\n\tlet finalConfig: ArrayConfig = {\n\t\tparser: parseArray,\n\t};\n\n\tif (config !== undefined) {\n\t\tif (typeof config === 'function') {\n\t\t\tallTests = [config, ...tests];\n\t\t} else {\n\t\t\tfinalConfig = {\n\t\t\t\t...finalConfig,\n\t\t\t\t...config,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn async (value, field) => {\n\t\tconst arrayValue = applyArrayConfig<T>(finalConfig, value);\n\t\tlet arrayInvalidResult: ValidatorResult | undefined;\n\t\tlet isValid = true;\n\t\tconst errors: ArrayItemValidatorResult[] = [];\n\t\tconst [validateItem, ...arrayTests] = allTests;\n\n\t\tfor (const validatorTest of arrayTests) {\n\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\tconst result = await validatorTest(arrayValue, field);\n\t\t\tif (result.state === 'invalid') {\n\t\t\t\tisValid = false;\n\t\t\t\tarrayInvalidResult = result;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (arrayValue && validateItem) {\n\t\t\tfor (const [index, item] of arrayValue.entries()) {\n\t\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\t\tconst result = await validateItem(\n\t\t\t\t\titem,\n\t\t\t\t\tfield ? `${field}[${index}]` : `[${index}]`,\n\t\t\t\t);\n\n\t\t\t\tif (result.state === 'invalid') {\n\t\t\t\t\tisValid = false;\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\terrors: result.errors,\n\t\t\t\t\t\tindex,\n\t\t\t\t\t\tmessage: result.message,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (isValid) {\n\t\t\treturn valid({\n\t\t\t\tvalue: arrayValue,\n\t\t\t\tfield,\n\t\t\t});\n\t\t}\n\n\t\treturn invalid({\n\t\t\tmessage:\n\t\t\t\tarrayInvalidResult?.state === 'invalid'\n\t\t\t\t\t? arrayInvalidResult.message\n\t\t\t\t\t: '',\n\t\t\tvalue,\n\t\t\tfield,\n\t\t\terrors,\n\t\t});\n\t};\n}\n","import {ConfigBase, createTypeValidatorTest} from './shared';\n\n/**\n * Parses a value into a boolean.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseBoolean(value: unknown): boolean | null | undefined {\n\tif (value === undefined || value === null) {\n\t\treturn value;\n\t}\n\n\tif (typeof value === 'boolean') {\n\t\treturn value;\n\t}\n\n\treturn Boolean(value);\n}\n\n/**\n * Applies a configuration to the boolean value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyBooleanConfig(\n\tvalue: unknown,\n\tconfig: BooleanConfig,\n): boolean | null | undefined {\n\tlet parsedValue = config.parser(value);\n\tif (parsedValue === undefined && config.default !== undefined) {\n\t\tparsedValue = config.default;\n\t}\n\n\treturn parsedValue;\n}\n\n/**\n * Configuration for boolean validation.\n * @category Types\n */\nexport type BooleanConfig = ConfigBase<boolean>;\n\n/**\n * Validates a boolean value.\n * @category Type Validators\n */\nexport const boolean = createTypeValidatorTest(\n\t{parser: parseBoolean},\n\tapplyBooleanConfig,\n);\n","import {\n\tConfigBase,\n\tcreateTypeValidatorTest,\n\tcreateValidatorTest,\n\tValidatorMessage,\n\tValidatorMessageParameters,\n\tValidatorTest,\n} from './shared';\n\n/** Badly formatted date for internal use. */\nexport const invalidDate = new Date('');\n\n/** @internal */\nconst isoDatePattern\n\t= /^(\\d{4})(?:-([012]\\d)(?:-([0123]\\d)(?:[T ]([012]\\d):([0-5]\\d)(?::([0-5]\\d)(\\.\\d+)?(Z|[+-][012]\\d:?[0-5]\\d)?)?)?)?)?$/;\n\n/** @internal */\nconst timezonePattern = /^([+-])([012]\\d):?([0-5]\\d)$/;\n\n/**\n * Parses a timezone string.\n * @param timezone Timezone to parse\n * @internal\n */\nfunction parseTimezone(timezone: string): number {\n\tconst parts = timezonePattern.exec(timezone);\n\n\tif (timezone === 'Z' || !parts) {\n\t\treturn 0;\n\t}\n\n\tconst [, sign, hour, minute] = parts;\n\tconst multiplier = sign === '-' ? -1 : 1;\n\tconst hoursInMinutes = Number.parseInt(hour ?? '0', 10) * 60;\n\tconst offset = hoursInMinutes + Number.parseInt(minute ?? '0', 10);\n\n\treturn multiplier * offset;\n}\n\nconst BASE = 10;\n\nconst dateParts = [\n\t// Skip\n\t() => 0,\n\t// Year\n\t(part = '0') => Number.parseInt(part, BASE),\n\t// Month\n\t(part = '1') => Number.parseInt(part, BASE) - 1,\n\t// Day\n\t(part = '1') => Number.parseInt(part, BASE),\n\t// Hour\n\t(part = '0') => Number.parseInt(part, BASE),\n\t// Minute\n\t(part = '0') => Number.parseInt(part, BASE),\n\t// Second\n\t(part = '0') => Number.parseInt(part, BASE),\n\t// Millisecond\n\t(part = '0') => Number.parseFloat(part) * 1e3,\n];\n\n/**\n * Parses a value into a date.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseDate(value: unknown): Date | null | undefined {\n\tif (value === null || value === undefined) {\n\t\treturn value;\n\t}\n\n\tif (value instanceof Date) {\n\t\treturn value;\n\t}\n\n\tif (typeof value === 'number') {\n\t\treturn new Date(value);\n\t}\n\n\tif (typeof value !== 'string') {\n\t\treturn invalidDate;\n\t}\n\n\tconst parts = isoDatePattern.exec(value);\n\n\tif (parts === null) {\n\t\treturn invalidDate;\n\t}\n\n\tconst [, year, month, day, hour, minute, second, millisecond] = dateParts.map(\n\t\t(parse, i) => parse(parts[i]),\n\t);\n\n\tconst timezone = parts[8];\n\n\tif (!timezone) {\n\t\treturn new Date(year, month, day, hour, minute, second, millisecond);\n\t}\n\n\tconst minuteOffset = parseTimezone(timezone);\n\n\treturn new Date(\n\t\tDate.UTC(year, month, day, hour, minute + minuteOffset, second, millisecond),\n\t);\n}\n\n/**\n * Applies a configuration to the date value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyDateConfig(\n\tvalue: unknown,\n\tconfig: DateConfig,\n): Date | null | undefined {\n\tlet parsedValue = config.parser(value);\n\tif (parsedValue === undefined && config.default !== undefined) {\n\t\tparsedValue = config.default;\n\t}\n\n\treturn parsedValue;\n}\n\nexport type SharedDateValueType = Date | string | number;\n\nexport interface MinDateValidatorMessageParameters\n\textends ValidatorMessageParameters<Date> {\n\tmin: Date | null | undefined;\n\tlimit: Date | null | undefined;\n\texclusive?: boolean;\n}\n\n/**\n * Ensures a date value is on or after a date.\n * @param limit Minimum date\n * @param message Error message\n * @param exclusive Makes comparison exclusive instead of inclusive\n * @category Validation Tests\n */\nexport function minDate(\n\tlimit: SharedDateValueType,\n\tmessage: ValidatorMessage<Date, MinDateValidatorMessageParameters>,\n\texclusive?: boolean,\n): ValidatorTest<Date, null> {\n\tconst parsedDate = parseDate(limit);\n\treturn createValidatorTest(\n\t\tvalue =>\n\t\t\tparsedDate !== null\n\t\t\t&& parsedDate !== undefined\n\t\t\t&& (value === null\n\t\t\t\t|| value === undefined\n\t\t\t\t|| (value instanceof Date\n\t\t\t\t\t&& (exclusive ? value > parsedDate : value >= parsedDate))),\n\t\tmessage,\n\t\t() => ({\n\t\t\tmin: parsedDate,\n\t\t\tlimit: parsedDate,\n\t\t\texclusive,\n\t\t}),\n\t);\n}\n\nexport interface MaxDateValidatorMessageParameters\n\textends ValidatorMessageParameters<Date> {\n\tmax: Date | null | undefined;\n\tlimit: Date | null | undefined;\n\texclusive?: boolean;\n}\n\n/**\n * Ensures a date value is on or before a date.\n * @param limit Maximum date\n * @param message Error message\n * @param exclusive Makes comparison exclusive instead of inclusive\n * @category Validation Tests\n */\nexport function maxDate(\n\tlimit: SharedDateValueType,\n\tmessage: ValidatorMessage<Date, MaxDateValidatorMessageParameters>,\n\texclusive?: boolean,\n): ValidatorTest<Date> {\n\tconst parsedDate = parseDate(limit);\n\treturn createValidatorTest(\n\t\tvalue =>\n\t\t\tparsedDate !== null\n\t\t\t&& parsedDate !== undefined\n\t\t\t&& (value === null\n\t\t\t\t|| value === undefined\n\t\t\t\t|| (value instanceof Date\n\t\t\t\t\t&& (exclusive ? value < parsedDate : value <= parsedDate))),\n\t\tmessage,\n\t\t() => ({\n\t\t\tmax: parsedDate,\n\t\t\tlimit: parsedDate,\n\t\t\texclusive,\n\t\t}),\n\t);\n}\n\n/**\n * Configuration for date validation.\n * @category Types\n */\nexport type DateConfig = ConfigBase<Date>;\n\n/**\n * Validates a date value.\n * @category Type Validators\n */\nexport const date = createTypeValidatorTest(\n\t{parser: parseDate},\n\tapplyDateConfig,\n);\n","import {\n\tConfigBase,\n\tcreateTypeValidatorTest,\n\tinvalid,\n\tvalid,\n\tValidatorMessage,\n\tValidatorTest,\n} from './shared';\n\n/**\n * Parses a value into a number.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseNumber(value: unknown): number | null | undefined {\n\tif (value === null || value === undefined) {\n\t\treturn value;\n\t}\n\n\tif (typeof value === 'number') {\n\t\treturn value;\n\t}\n\n\tif (value instanceof Date) {\n\t\treturn value.getTime();\n\t}\n\n\tif (typeof value === 'string') {\n\t\treturn Number.parseFloat(value);\n\t}\n\n\treturn Number.parseFloat(String(value));\n}\n\n/**\n * Applies a configuration to the number value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyNumberConfig(\n\tvalue: unknown,\n\tconfig: NumberConfig,\n): number | null | undefined {\n\tlet parsedValue = config.parser(value);\n\tif (config.default !== undefined && parsedValue === undefined) {\n\t\tparsedValue = config.default;\n\t}\n\n\tif (config.round && typeof parsedValue === 'number') {\n\t\tswitch (config.round) {\n\t\t\tcase 'nearest':\n\t\t\t\tparsedValue = Math.round(parsedValue);\n\t\t\t\tbreak;\n\t\t\tcase 'ceil':\n\t\t\t\tparsedValue = Math.ceil(parsedValue);\n\t\t\t\tbreak;\n\t\t\tcase 'floor':\n\t\t\t\tparsedValue = Math.floor(parsedValue);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unknown round type: ${String(config.round)}`);\n\t\t}\n\t}\n\n\treturn parsedValue;\n}\n\n/**\n * Ensures a number value is an integer.\n * @param message Error message\n * @category Validation Tests\n */\nexport function integer(\n\tmessage: ValidatorMessage<number>,\n): ValidatorTest<number> {\n\treturn async (value, field) => {\n\t\tif (\n\t\t\tvalue === undefined\n\t\t\t|| value === null\n\t\t\t|| (typeof value === 'number'\n\t\t\t\t&& Number.isFinite(value)\n\t\t\t\t&& Math.floor(value) === value)\n\t\t) {\n\t\t\treturn valid({value, field});\n\t\t}\n\n\t\treturn invalid({\n\t\t\tmessage,\n\t\t\tvalue,\n\t\t\tfield,\n\t\t});\n\t};\n}\n\n/**\n * Configuration for number validation.\n * @category Types\n */\nexport interface NumberConfig extends ConfigBase<number> {\n\t/** Apply rounding mechanism before validation. */\n\tround?: 'nearest' | 'floor' | 'ceil';\n}\n\n/**\n * Validates a number value.\n * @category Type Validators\n */\nexport const number = createTypeValidatorTest(\n\t{\n\t\tparser: parseNumber,\n\t},\n\tapplyNumberConfig,\n);\n","import {\n\tDeepPartial,\n\tExtractError,\n\tExtractValue,\n\thasOwnProperty,\n\tinvalid,\n\tvalid,\n\tValidatorTest,\n} from './shared';\n\nexport type ObjectParameter = Record<string, ValidatorTest<unknown, unknown>>;\n\n/**\n * Validates an object.\n * @category Type Validators\n */\nexport function object<P extends ObjectParameter, K extends keyof P>(\n\tproperties: P,\n): ValidatorTest<\n\tDeepPartial<{[K in keyof P]?: ExtractValue<P[K]>}>,\n\tDeepPartial<{[K in keyof P]?: ExtractError<P[K]>}>\n\t> {\n\tif (typeof properties !== 'object' || properties === null) {\n\t\tthrow new TypeError('`properties` must be a configuration object');\n\t}\n\n\treturn async (values, field) => {\n\t\tconst definedValues: {[K in keyof P]?: ExtractValue<P[K]>}\n\t\t\t= (values as {[K in keyof P]?: ExtractValue<P[K]>}) ?? {};\n\t\tconst errors: {[K in keyof P]?: ExtractError<P[K]>} = {};\n\t\tconst resolvedValues: {[K in keyof P]?: ExtractValue<P[K]>} = {};\n\t\tlet isValid = true;\n\n\t\tfor (const key in properties) {\n\t\t\tif (hasOwnProperty(properties, key)) {\n\t\t\t\tconst validator = properties[key];\n\t\t\t\tconst value = definedValues[key];\n\t\t\t\t/* eslint-disable no-await-in-loop */\n\t\t\t\tconst result\n\t\t\t\t\t= typeof validator === 'function'\n\t\t\t\t\t\t? await validator(value, key)\n\t\t\t\t\t\t: await invalid({field: key, message: 'No validator set', value});\n\t\t\t\t/* eslint-enable no-await-in-loop */\n\n\t\t\t\tresolvedValues[key] = result.value as ExtractValue<P[K]>;\n\n\t\t\t\tif (result.state === 'invalid') {\n\t\t\t\t\tisValid = false;\n\t\t\t\t\terrors[key] = (\n\t\t\t\t\t\tresult.message ? result.message : result.errors\n\t\t\t\t\t) as ExtractError<P[K]>;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (isValid) {\n\t\t\treturn valid({value: resolvedValues, field});\n\t\t}\n\n\t\treturn invalid({\n\t\t\tmessage: '',\n\t\t\tvalue: values,\n\t\t\tfield,\n\t\t\terrors,\n\t\t});\n\t};\n}\n","import {\n\tConfigBase,\n\tcreateTypeValidatorTest,\n\tcreateValidatorTest,\n\tisObject,\n\tValidatorMessage,\n\tValidatorMessageParameters,\n\tValidatorTest,\n} from './shared';\n\n/** @internal */\nconst emailPattern\n\t= /^[\\w.!#$%&'*+/=?^`{|}~-]+@[a-zA-Z\\d](?:[a-zA-Z\\d-]{0,61}[a-zA-Z\\d])?(?:\\.[a-zA-Z\\d](?:[a-zA-Z\\d-]{0,61}[a-zA-Z\\d])?)*$/;\n\n/**\n * Configuration for string validation.\n * @category Types\n */\nexport interface StringConfig extends ConfigBase<string> {\n\t/** Apply trim to string before validation. */\n\ttrim?: boolean;\n}\n\n/**\n * Parses a value into a string.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseString(value: unknown): string | null | undefined {\n\tif (value === null || value === undefined) {\n\t\treturn value;\n\t}\n\n\tif (typeof value === 'string') {\n\t\treturn value;\n\t}\n\n\tif (value instanceof Date) {\n\t\treturn value.toISOString();\n\t}\n\n\tif (isObject(value)) {\n\t\tthrow new TypeError('Failed to parse value to string.');\n\t}\n\n\treturn String(value);\n}\n\n/**\n * Applies a configuration to the string value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyStringConfig(\n\tvalue: unknown,\n\tconfig: StringConfig,\n): string | null | undefined {\n\tlet parsedValue = config.parser(value);\n\tif (config.default !== undefined && parsedValue === undefined) {\n\t\tparsedValue = config.default;\n\t}\n\n\tif (config.trim && typeof parsedValue === 'string') {\n\t\tparsedValue = parsedValue.trim();\n\t}\n\n\treturn parsedValue;\n}\n\nexport interface MatchesValidatorMessageParameters\n\textends ValidatorMessageParameters<string> {\n\tpattern: RegExp;\n}\n\n/**\n * Ensures a string value matches a pattern\n * @param pattern Pattern to match\n * @param message Error message\n * @category Validation Tests\n */\nexport function matches(\n\tpattern: RegExp,\n\tmessage: ValidatorMessage<string, MatchesValidatorMessageParameters>,\n): ValidatorTest<string> {\n\treturn createValidatorTest(\n\t\tvalue =>\n\t\t\tvalue === undefined\n\t\t\t|| value === null\n\t\t\t|| value === ''\n\t\t\t|| (typeof value === 'string' && pattern.test(value)),\n\t\tmessage,\n\t\t() => ({pattern}),\n\t);\n}\n\n/**\n * Ensures a string value matches an email pattern\n * @param message Error message\n * @category Validation Tests\n */\nexport function email(\n\tmessage: ValidatorMessage<string>,\n): ValidatorTest<string> {\n\treturn matches(emailPattern, message);\n}\n\n/**\n * Ensures a string value is a valid URL\n * @param message Error message\n * @param protocols Optional list of protocols to allow\n * @category Validation Tests\n */\nexport function url(\n\tmessage: ValidatorMessage<string>,\n\tprotocols?: string[],\n): ValidatorTest<string> {\n\treturn createValidatorTest(\n\t\tvalue => {\n\t\t\ttry {\n\t\t\t\tlet url: URL | undefined;\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined\n\t\t\t\t\t|| value === null\n\t\t\t\t\t|| value === ''\n\t\t\t\t\t|| (typeof value === 'string' && (url = new URL(value)))\n\t\t\t\t) {\n\t\t\t\t\treturn !(url && protocols && !protocols.includes(url.protocol));\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Do nothing\n\t\t\t}\n\n\t\t\treturn false;\n\t\t},\n\t\tmessage,\n\t\t() => ({protocols}),\n\t);\n}\n\n/**\n * Validates a string value.\n * @category Type Validators\n */\nexport const string = createTypeValidatorTest(\n\t{\n\t\tparser: parseString,\n\t},\n\tapplyStringConfig,\n);\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/shared.ts","../../src/arrays.ts","../../src/booleans.ts","../../src/dates.ts","../../src/numbers.ts","../../src/objects.ts","../../src/strings.ts"],"sourcesContent":["/**\n * From type-fest: https://github.com/sindresorhus/type-fest/blob/HEAD/source/except.d.ts\n * @internal\n */\ntype Except<ObjectType, KeysType extends keyof ObjectType> = Pick<\n ObjectType,\n Exclude<keyof ObjectType, KeysType>\n>;\n\nexport type ValidResult<T> = {\n /**\n * True if the original value is valid according to all validation tests\n * @deprecated Use `state` instead.\n */\n isValid: true;\n /** This is preferred to use over `isValid` as it works better for type guards. */\n state: 'valid';\n /** The parsed value. Note that may be different than the original value. */\n value: T | null | undefined;\n /** Field name if provided. Automatically provided if using object validation. */\n field?: string;\n};\n\nexport type InvalidResult<E> = {\n /**\n * True if the original value is valid according to all validation tests.\n * @deprecated Use `state` instead.\n */\n isValid: false;\n /** This is preferred to use over `isValid` as it works better for type guards. */\n state: 'invalid';\n /** The parsed value. Note that may be different than the original value. */\n value: unknown;\n /** Error message if `state` is invalid. */\n message: string;\n /** Field name if provided. Automatically provided if using object validation. */\n field?: string;\n /** Extra error details */\n errors?: E;\n};\n\n/**\n * The result of a validation.\n * @typeParam T The value type\n * @category Types\n */\nexport type ValidatorResult<T = any, E = any> =\n | ValidResult<T>\n | InvalidResult<E>;\n\n/**\n * Validation test function.\n * @typeParam T The value type\n * @category Types\n */\nexport type ValidatorTest<T = any, E = any> = (\n value?: unknown,\n field?: string\n) => Promise<ValidatorResult<T, E>>;\n\n/**\n * Extracts the generic error type from a ValidatorTest.\n * @typeParam T a ValidatorTest\n * @category Types\n */\nexport type ExtractError<T extends ValidatorTest> = T extends ValidatorTest<\n any,\n infer E\n>\n ? E\n : unknown;\n\n/**\n * Extracts the generic value type from a ValidatorTest.\n * @typeParam T a ValidatorTest\n * @category Types\n */\nexport type ExtractValue<T extends ValidatorTest> = T extends ValidatorTest<\n infer V\n>\n ? V\n : unknown;\n\n/**\n * Make a deep partial type.\n * @typeParam T any object type\n * @category Types\n */\nexport type DeepPartial<T> = {\n [P in keyof T]?: DeepPartial<T[P]>;\n};\n\n/**\n * Validation factory function.\n * @typeParam C The configuration type\n * @category Types\n */\nexport type ValidatorFactory<C, T, E> = (\n config?: Partial<C> | ValidatorTest,\n ...tests: ValidatorTest[]\n) => ValidatorTest<T, E>;\n\n/**\n * Base configuration type.\n * @typeParam T The target type.\n * @category Types\n */\nexport interface ConfigBase<T> {\n /** Parser to convert value into the designated type. */\n parser: (value: unknown) => T | null | undefined;\n /** Provide a fallback value in case the original value is undefined. */\n default?: T;\n}\n\nexport interface ValidatorMessageParameters<T> {\n value: T | null | undefined;\n field: string | undefined;\n}\n\n/**\n * Validation message. May be a plain string or a function that accepts arguments.\n * While using a string, values in squiggly brackets `{}` are replaced.\n * @category Types\n */\nexport type ValidatorMessage<\n T,\n P extends ValidatorMessageParameters<T> = ValidatorMessageParameters<T>\n> = string | ((parameters: P) => string);\n\n/**\n * Simple check for objects.\n * @param value Value to test\n */\nexport function isObject(value: unknown): boolean {\n return Object.prototype.toString.call(value) === '[object Object]';\n}\n\n/**\n * Safe hasOwnProperty check\n * @param obj Object to check\n * @param prop Property to look for\n */\nexport function hasOwnProperty(\n object: unknown,\n property: string | number | symbol\n): boolean {\n return Object.prototype.hasOwnProperty.call(object, property);\n}\n\n/** @internal */\nconst formatPattern = /{(\\w+)}/g;\n\n/**\n * Formats a message using a squiggly bracket `{}` template.\n * @param template Message template as string or function\n * @param params Params to inject into template\n * @category Helpers\n */\nexport function formatMessage<T, P extends ValidatorMessageParameters<T>>(\n template: ValidatorMessage<T, P>,\n parameters: P\n): string {\n if (typeof template === 'string') {\n return template.replace(formatPattern, (_, key: string) =>\n String((parameters as Record<string, unknown>)[key])\n );\n }\n\n return template(parameters);\n}\n\n/**\n * Creates a valid result\n * @param value Parsed value\n * @param field Field name\n * @category Helpers\n */\nexport async function valid<T, E = never>({\n value,\n field,\n}: {\n value: T | null | undefined;\n field: string | undefined;\n}): Promise<ValidatorResult<T, E>> {\n return {\n isValid: true,\n state: 'valid',\n value,\n field,\n };\n}\n\n/**\n * Creates an invalid result.\n * @param message Error message\n * @param value Parsed value\n * @param field Field name\n * @param extras Extra message params\n * @category Helpers\n */\nexport async function invalid<T, E, P extends ValidatorMessageParameters<T>>({\n errors,\n field,\n message,\n value,\n extras,\n}: {\n message: ValidatorMessage<T, P>;\n value: unknown;\n field: string | undefined;\n errors?: E;\n extras?: Except<P, 'field' | 'value'>;\n}): Promise<ValidatorResult<T, E>> {\n return {\n isValid: false,\n state: 'invalid',\n message: formatMessage(message, { ...extras, value, field } as P),\n value,\n field,\n errors,\n };\n}\n\n/**\n * Creates a type validator.\n * @typeParam T The basic type for the final value to be validated.\n * @typeParam C The configuration type.\n * @param defaultParser Parser to convert value into type.\n * @param applyConfig Function that applies configuration to value.\n * @category Helpers\n */\nexport function createTypeValidatorTest<T, C extends ConfigBase<T>, E>(\n defaultConfig: C,\n applyConfig: (value: unknown, config: C) => T | null | undefined\n): ValidatorFactory<C, T, E> {\n return (config, ...tests) => {\n const cache: Record<string, ValidatorResult<T>> = {};\n let finalConfig = defaultConfig;\n let allTests = tests;\n\n if (config !== undefined) {\n if (typeof config === 'function') {\n allTests = [config, ...tests];\n } else {\n finalConfig = {\n ...defaultConfig,\n ...config,\n };\n }\n }\n\n return async (value, field) => {\n try {\n const parsedValue = applyConfig(value, finalConfig);\n const parsedValueString = String(parsedValue);\n if (hasOwnProperty(cache, parsedValueString)) {\n return cache[parsedValueString];\n }\n\n for (const validatorTest of allTests) {\n // eslint-disable-next-line no-await-in-loop\n const result = await validatorTest(parsedValue, field);\n if (result.state === 'invalid') {\n cache[parsedValueString] = result;\n return result;\n }\n }\n\n cache[parsedValueString] = await valid({ value: parsedValue, field });\n return cache[parsedValueString];\n } catch (error) {\n return invalid({\n message: error instanceof Error ? error.message : String(error),\n value,\n field,\n });\n }\n };\n };\n}\n\n/**\n * Captures basic validator test pattern\n * @param test Test function\n * @param message Error message\n * @param getExtras Optional extra fields for error message\n */\nexport function createValidatorTest<\n T = any,\n E = any,\n P extends ValidatorMessageParameters<T> = ValidatorMessageParameters<T>\n>(\n test: (value: unknown, field?: string) => boolean,\n message: ValidatorMessage<T, P>,\n getExtras?: (value: T | null | undefined) => Except<P, 'value' | 'field'>\n): ValidatorTest<T, E> {\n return async (value, field) => {\n if (test(value, field)) {\n return valid({ value: value as T, field });\n }\n\n return invalid({\n message,\n value,\n field,\n extras: getExtras ? getExtras(value as T) : undefined,\n });\n };\n}\n\n/**\n * Ensures a value is not undefined, null, empty string, NaN, nor invalid date.\n * @param message Error message\n * @param nullable Allow null values\n * @category Validation Tests\n */\nexport function required<T, P extends ValidatorMessageParameters<T>>(\n message: ValidatorMessage<T, P>,\n nullable?: boolean\n): ValidatorTest<T> {\n return createValidatorTest(\n (value) =>\n (nullable && value === null) ||\n (value !== null &&\n value !== undefined &&\n !(typeof value === 'string' && value === '') &&\n !(typeof value === 'number' && Number.isNaN(value)) &&\n !(value instanceof Date && Number.isNaN(value.valueOf()))),\n message\n );\n}\n\nexport type SharedValueType = string | number | unknown[];\n\n/**\n * Extracts a numeric amount from value, i.e. string length, array length, or number.\n * @internal\n */\nfunction getAmount(value: SharedValueType | null | undefined) {\n return typeof value === 'string' || Array.isArray(value)\n ? value.length\n : value;\n}\n\nexport interface MaxValidatorMessageParameters\n extends ValidatorMessageParameters<SharedValueType> {\n max: number;\n amount: number | null | undefined;\n limit: number;\n exclusive?: boolean;\n}\n\n/**\n * Ensures a string, number, or array value is at most a certain amount.\n * @param limit Size or value limit\n * @param message Error message\n * @param exclusive Use exclusive comparison instead of inclusive\n * @category Validation Tests\n */\nexport function max(\n limit: number,\n message: ValidatorMessage<SharedValueType, MaxValidatorMessageParameters>,\n exclusive?: boolean\n): ValidatorTest<SharedValueType> {\n return createValidatorTest(\n (value) => {\n const amount = getAmount(value as SharedValueType);\n return (\n amount === undefined ||\n amount === null ||\n value === '' ||\n (exclusive ? amount < limit : amount <= limit)\n );\n },\n message,\n (value) => ({\n max: limit,\n limit,\n amount: getAmount(value),\n exclusive,\n })\n );\n}\n\nexport interface MinValidatorMessageParameters\n extends ValidatorMessageParameters<SharedValueType> {\n min: number;\n limit: number;\n amount: number | null | undefined;\n exclusive?: boolean;\n}\n\n/**\n * Ensures a string, number, or array value is at most a certain amount.\n * @param limit Size or value limit\n * @param message Error message\n * @param exclusive Use exclusive comparison instead of inclusive\n * @category Validation Tests\n */\nexport function min(\n limit: number,\n message: ValidatorMessage<SharedValueType, MinValidatorMessageParameters>,\n exclusive?: boolean\n): ValidatorTest<SharedValueType> {\n return createValidatorTest(\n (value) => {\n const amount = getAmount(value as SharedValueType);\n return (\n amount === undefined ||\n amount === null ||\n value === '' ||\n (exclusive ? amount > limit : amount >= limit)\n );\n },\n message,\n (value) => ({\n min: limit,\n limit,\n amount: getAmount(value),\n exclusive,\n })\n );\n}\n\nexport interface ExactValidatorMessageParameters\n extends ValidatorMessageParameters<SharedValueType> {\n limit: number;\n amount: number | null | undefined;\n exact: number;\n}\n\n/**\n * Ensures a string, number, or array value is exactly a certain amount.\n * @param limit Size or value limit\n * @param message Error message\n * @category Validation Tests\n */\nexport function exact(\n limit: number,\n message: ValidatorMessage<SharedValueType, ExactValidatorMessageParameters>\n): ValidatorTest<SharedValueType> {\n return createValidatorTest(\n (value) => {\n const amount = getAmount(value as SharedValueType);\n return (\n amount === undefined ||\n amount === null ||\n value === '' ||\n amount === limit\n );\n },\n message,\n (value) => ({\n amount: getAmount(value),\n limit,\n exact: limit,\n })\n );\n}\n\nexport interface OneOfValidatorMessageParameters<T>\n extends ValidatorMessageParameters<T> {\n values: readonly T[];\n}\n\n/**\n * Ensures a value is one in a predefined list.\n * @param values List of allowed values.\n * @param message Error message\n * @category Validation Tests\n */\nexport function oneOf<T extends string | number | boolean | Date>(\n values: readonly T[],\n message: ValidatorMessage<T, OneOfValidatorMessageParameters<T>>\n): ValidatorTest<T> {\n return createValidatorTest(\n (value) =>\n value === undefined ||\n value === null ||\n values.includes(value as T) ||\n (value instanceof Date &&\n values.some((x) => x.valueOf() === value.valueOf())),\n message,\n () => ({ values })\n );\n}\n","import {\n ConfigBase,\n invalid,\n valid,\n ValidatorResult,\n ValidatorTest,\n} from './shared';\n\n/**\n * Invalid validation result for an item in the array\n * @category Types\n */\nexport interface ArrayItemValidatorResult {\n /** The index of the item in the original array */\n index: number;\n /** The error message if a simple type */\n message: string;\n /** The errors if an object or array */\n errors: unknown;\n}\n\n/**\n * Configuration for array validation.\n * @category Types\n */\nexport type ArrayConfig = ConfigBase<unknown[]>;\n\n/**\n * Parses a value into an array.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseArray(value: unknown): unknown[] | null | undefined {\n if (Array.isArray(value)) {\n return value as unknown[];\n }\n\n if (value === null || value === undefined) {\n return value;\n }\n\n const iterable = value as Iterable<unknown>;\n\n if (iterable[Symbol.iterator]) {\n return [...iterable];\n }\n\n return [];\n}\n\n/**\n * Applies a configuration to the array value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyArrayConfig<T>(\n config: ArrayConfig,\n value: unknown\n): T[] | null | undefined {\n let parsedValue = config.parser(value);\n if (parsedValue === undefined && config.default !== undefined) {\n parsedValue = config.default;\n }\n\n return parsedValue as T[];\n}\n\n/**\n * Validates an array. The first passed validator is used to validate individual\n * items. The remaining validators target the array itself.\n * @category Type Validators\n */\nexport function array<T>(\n config?: Partial<ArrayConfig> | ValidatorTest<T>,\n ...tests: ValidatorTest[]\n): ValidatorTest<T[], ArrayItemValidatorResult[]> {\n let allTests = tests;\n let finalConfig: ArrayConfig = {\n parser: parseArray,\n };\n\n if (config !== undefined) {\n if (typeof config === 'function') {\n allTests = [config, ...tests];\n } else {\n finalConfig = {\n ...finalConfig,\n ...config,\n };\n }\n }\n\n return async (value, field) => {\n const arrayValue = applyArrayConfig<T>(finalConfig, value);\n let arrayInvalidResult: ValidatorResult | undefined;\n let isValid = true;\n const errors: ArrayItemValidatorResult[] = [];\n const [validateItem, ...arrayTests] = allTests;\n\n for (const validatorTest of arrayTests) {\n // eslint-disable-next-line no-await-in-loop\n const result = await validatorTest(arrayValue, field);\n if (result.state === 'invalid') {\n isValid = false;\n arrayInvalidResult = result;\n break;\n }\n }\n\n if (arrayValue && validateItem) {\n for (const [index, item] of arrayValue.entries()) {\n // eslint-disable-next-line no-await-in-loop\n const result = await validateItem(\n item,\n field ? `${field}[${index}]` : `[${index}]`\n );\n\n if (result.state === 'invalid') {\n isValid = false;\n errors.push({\n errors: result.errors,\n index,\n message: result.message,\n });\n }\n }\n }\n\n if (isValid) {\n return valid({\n value: arrayValue,\n field,\n });\n }\n\n return invalid({\n message:\n arrayInvalidResult?.state === 'invalid'\n ? arrayInvalidResult.message\n : '',\n value,\n field,\n errors,\n });\n };\n}\n","import { ConfigBase, createTypeValidatorTest } from './shared';\n\n/**\n * Parses a value into a boolean.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseBoolean(value: unknown): boolean | null | undefined {\n if (value === undefined || value === null) {\n return value;\n }\n\n if (typeof value === 'boolean') {\n return value;\n }\n\n return Boolean(value);\n}\n\n/**\n * Applies a configuration to the boolean value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyBooleanConfig(\n value: unknown,\n config: BooleanConfig\n): boolean | null | undefined {\n let parsedValue = config.parser(value);\n if (parsedValue === undefined && config.default !== undefined) {\n parsedValue = config.default;\n }\n\n return parsedValue;\n}\n\n/**\n * Configuration for boolean validation.\n * @category Types\n */\nexport type BooleanConfig = ConfigBase<boolean>;\n\n/**\n * Validates a boolean value.\n * @category Type Validators\n */\nexport const boolean = createTypeValidatorTest(\n { parser: parseBoolean },\n applyBooleanConfig\n);\n","import {\n ConfigBase,\n createTypeValidatorTest,\n createValidatorTest,\n ValidatorMessage,\n ValidatorMessageParameters,\n ValidatorTest,\n} from './shared';\n\n/** Badly formatted date for internal use. */\nexport const invalidDate = new Date('');\n\n/** @internal */\nconst isoDatePattern =\n /^(\\d{4})(?:-([0-2]\\d)(?:-([0-3]\\d)(?:[ T]([0-2]\\d):([0-5]\\d)(?::([0-5]\\d)(\\.\\d+)?(Z|[+-][0-2]\\d:?[0-5]\\d)?)?)?)?)?$/;\n\n/** @internal */\nconst timezonePattern = /^([+-])([0-2]\\d):?([0-5]\\d)$/;\n\n/**\n * Parses a timezone string.\n * @param timezone Timezone to parse\n * @internal\n */\nfunction parseTimezone(timezone: string): number {\n const parts = timezonePattern.exec(timezone);\n\n if (timezone === 'Z' || !parts) {\n return 0;\n }\n\n const [, sign, hour, minute] = parts;\n const multiplier = sign === '-' ? -1 : 1;\n const hoursInMinutes = Number.parseInt(hour, 10) * 60;\n const offset = hoursInMinutes + Number.parseInt(minute, 10);\n\n return multiplier * offset;\n}\n\nconst BASE = 10;\n\nconst dateParts = [\n // Skip\n () => 0,\n // Year\n (part = '0') => Number.parseInt(part, BASE),\n // Month\n (part = '1') => Number.parseInt(part, BASE) - 1,\n // Day\n (part = '1') => Number.parseInt(part, BASE),\n // Hour\n (part = '0') => Number.parseInt(part, BASE),\n // Minute\n (part = '0') => Number.parseInt(part, BASE),\n // Second\n (part = '0') => Number.parseInt(part, BASE),\n // Millisecond\n (part = '0') => Number.parseFloat(part) * 1e3,\n];\n\n/**\n * Parses a value into a date.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseDate(value: unknown): Date | null | undefined {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (value instanceof Date) {\n return value;\n }\n\n if (typeof value === 'number') {\n return new Date(value);\n }\n\n if (typeof value !== 'string') {\n return invalidDate;\n }\n\n const parts = isoDatePattern.exec(value);\n\n if (parts === null) {\n return invalidDate;\n }\n\n const [, year, month, day, hour, minute, second, millisecond] = dateParts.map(\n (parse, index) => parse(parts[index])\n );\n\n const timezone = parts[8];\n\n if (!timezone) {\n return new Date(year, month, day, hour, minute, second, millisecond);\n }\n\n const minuteOffset = parseTimezone(timezone);\n\n return new Date(\n Date.UTC(year, month, day, hour, minute + minuteOffset, second, millisecond)\n );\n}\n\n/**\n * Applies a configuration to the date value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyDateConfig(\n value: unknown,\n config: DateConfig\n): Date | null | undefined {\n let parsedValue = config.parser(value);\n if (parsedValue === undefined && config.default !== undefined) {\n parsedValue = config.default;\n }\n\n return parsedValue;\n}\n\nexport type SharedDateValueType = Date | string | number;\n\nexport interface MinDateValidatorMessageParameters\n extends ValidatorMessageParameters<Date> {\n min: Date | null | undefined;\n limit: Date | null | undefined;\n exclusive?: boolean;\n}\n\n/**\n * Ensures a date value is on or after a date.\n * @param limit Minimum date\n * @param message Error message\n * @param exclusive Makes comparison exclusive instead of inclusive\n * @category Validation Tests\n */\nexport function minDate(\n limit: SharedDateValueType,\n message: ValidatorMessage<Date, MinDateValidatorMessageParameters>,\n exclusive?: boolean\n): ValidatorTest<Date, null> {\n const parsedDate = parseDate(limit);\n return createValidatorTest(\n (value) =>\n parsedDate !== null &&\n parsedDate !== undefined &&\n (value === null ||\n value === undefined ||\n (value instanceof Date &&\n (exclusive ? value > parsedDate : value >= parsedDate))),\n message,\n () => ({\n min: parsedDate,\n limit: parsedDate,\n exclusive,\n })\n );\n}\n\nexport interface MaxDateValidatorMessageParameters\n extends ValidatorMessageParameters<Date> {\n max: Date | null | undefined;\n limit: Date | null | undefined;\n exclusive?: boolean;\n}\n\n/**\n * Ensures a date value is on or before a date.\n * @param limit Maximum date\n * @param message Error message\n * @param exclusive Makes comparison exclusive instead of inclusive\n * @category Validation Tests\n */\nexport function maxDate(\n limit: SharedDateValueType,\n message: ValidatorMessage<Date, MaxDateValidatorMessageParameters>,\n exclusive?: boolean\n): ValidatorTest<Date> {\n const parsedDate = parseDate(limit);\n return createValidatorTest(\n (value) =>\n parsedDate !== null &&\n parsedDate !== undefined &&\n (value === null ||\n value === undefined ||\n (value instanceof Date &&\n (exclusive ? value < parsedDate : value <= parsedDate))),\n message,\n () => ({\n max: parsedDate,\n limit: parsedDate,\n exclusive,\n })\n );\n}\n\n/**\n * Configuration for date validation.\n * @category Types\n */\nexport type DateConfig = ConfigBase<Date>;\n\n/**\n * Validates a date value.\n * @category Type Validators\n */\nexport const date = createTypeValidatorTest(\n { parser: parseDate },\n applyDateConfig\n);\n","import {\n ConfigBase,\n createTypeValidatorTest,\n invalid,\n valid,\n ValidatorMessage,\n ValidatorTest,\n} from './shared';\n\n/**\n * Parses a value into a number.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseNumber(value: unknown): number | null | undefined {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (typeof value === 'number') {\n return value;\n }\n\n if (value instanceof Date) {\n return value.getTime();\n }\n\n if (typeof value === 'string') {\n return Number.parseFloat(value);\n }\n\n return Number.parseFloat(String(value));\n}\n\n/**\n * Applies a configuration to the number value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyNumberConfig(\n value: unknown,\n config: NumberConfig\n): number | null | undefined {\n let parsedValue = config.parser(value);\n if (config.default !== undefined && parsedValue === undefined) {\n parsedValue = config.default;\n }\n\n if (config.round && typeof parsedValue === 'number') {\n switch (config.round) {\n case 'nearest':\n parsedValue = Math.round(parsedValue);\n break;\n case 'ceil':\n parsedValue = Math.ceil(parsedValue);\n break;\n case 'floor':\n parsedValue = Math.floor(parsedValue);\n break;\n default:\n throw new Error(`Unknown round type: ${String(config.round)}`);\n }\n }\n\n return parsedValue;\n}\n\n/**\n * Ensures a number value is an integer.\n * @param message Error message\n * @category Validation Tests\n */\nexport function integer(\n message: ValidatorMessage<number>\n): ValidatorTest<number> {\n return async (value, field) => {\n if (\n value === undefined ||\n value === null ||\n (typeof value === 'number' &&\n Number.isFinite(value) &&\n Math.floor(value) === value)\n ) {\n return valid({ value, field });\n }\n\n return invalid({\n message,\n value,\n field,\n });\n };\n}\n\n/**\n * Configuration for number validation.\n * @category Types\n */\nexport interface NumberConfig extends ConfigBase<number> {\n /** Apply rounding mechanism before validation. */\n round?: 'nearest' | 'floor' | 'ceil';\n}\n\n/**\n * Validates a number value.\n * @category Type Validators\n */\nexport const number = createTypeValidatorTest(\n {\n parser: parseNumber,\n },\n applyNumberConfig\n);\n","import {\n DeepPartial,\n ExtractError,\n ExtractValue,\n hasOwnProperty,\n invalid,\n valid,\n ValidatorTest,\n} from './shared';\n\nexport type ObjectParameter = Record<string, ValidatorTest<unknown, unknown>>;\n\n/**\n * Validates an object.\n * @category Type Validators\n */\nexport function object<P extends ObjectParameter, K extends keyof P>(\n properties: P\n): ValidatorTest<\n DeepPartial<{ [K in keyof P]?: ExtractValue<P[K]> }>,\n DeepPartial<{ [K in keyof P]?: ExtractError<P[K]> }>\n> {\n if (typeof properties !== 'object' || properties === null) {\n throw new TypeError('`properties` must be a configuration object');\n }\n\n return async (values, field) => {\n const definedValues: { [K in keyof P]?: ExtractValue<P[K]> } =\n (values as { [K in keyof P]?: ExtractValue<P[K]> }) ?? {};\n const errors: { [K in keyof P]?: ExtractError<P[K]> } = {};\n const resolvedValues: { [K in keyof P]?: ExtractValue<P[K]> } = {};\n let isValid = true;\n\n for (const key in properties) {\n if (hasOwnProperty(properties, key)) {\n const validator = properties[key];\n const value = definedValues[key];\n /* eslint-disable no-await-in-loop */\n const result =\n typeof validator === 'function'\n ? await validator(value, key)\n : await invalid({ field: key, message: 'No validator set', value });\n /* eslint-enable no-await-in-loop */\n\n resolvedValues[key] = result.value as ExtractValue<P[K]>;\n\n if (result.state === 'invalid') {\n isValid = false;\n errors[key] = (\n result.message ? result.message : result.errors\n ) as ExtractError<P[K]>;\n }\n }\n }\n\n if (isValid) {\n return valid({ value: resolvedValues, field });\n }\n\n return invalid({\n message: '',\n value: values,\n field,\n errors,\n });\n };\n}\n","import {\n ConfigBase,\n createTypeValidatorTest,\n createValidatorTest,\n isObject,\n ValidatorMessage,\n ValidatorMessageParameters,\n ValidatorTest,\n} from './shared';\n\n/** @internal */\nconst emailPattern =\n /^[\\w!#$%&'*+./=?^`{|}~-]+@[\\dA-Za-z](?:[\\dA-Za-z-]{0,61}[\\dA-Za-z])?(?:\\.[\\dA-Za-z](?:[\\dA-Za-z-]{0,61}[\\dA-Za-z])?)*$/;\n\n/**\n * Configuration for string validation.\n * @category Types\n */\nexport interface StringConfig extends ConfigBase<string> {\n /** Apply trim to string before validation. */\n trim?: boolean;\n}\n\n/**\n * Parses a value into a string.\n * @param value Value to parse\n * @category Parsers\n */\nexport function parseString(value: unknown): string | null | undefined {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n if (isObject(value)) {\n throw new TypeError('Failed to parse value to string.');\n }\n\n return String(value);\n}\n\n/**\n * Applies a configuration to the string value.\n * @param value Value to modify\n * @param config Configuration to apply\n * @category Helpers\n */\nexport function applyStringConfig(\n value: unknown,\n config: StringConfig\n): string | null | undefined {\n let parsedValue = config.parser(value);\n if (config.default !== undefined && parsedValue === undefined) {\n parsedValue = config.default;\n }\n\n if (config.trim && typeof parsedValue === 'string') {\n parsedValue = parsedValue.trim();\n }\n\n return parsedValue;\n}\n\nexport interface MatchesValidatorMessageParameters\n extends ValidatorMessageParameters<string> {\n pattern: RegExp;\n}\n\n/**\n * Ensures a string value matches a pattern\n * @param pattern Pattern to match\n * @param message Error message\n * @category Validation Tests\n */\nexport function matches(\n pattern: RegExp,\n message: ValidatorMessage<string, MatchesValidatorMessageParameters>\n): ValidatorTest<string> {\n return createValidatorTest(\n (value) =>\n value === undefined ||\n value === null ||\n value === '' ||\n (typeof value === 'string' && pattern.test(value)),\n message,\n () => ({ pattern })\n );\n}\n\n/**\n * Ensures a string value matches an email pattern\n * @param message Error message\n * @category Validation Tests\n */\nexport function email(\n message: ValidatorMessage<string>\n): ValidatorTest<string> {\n return matches(emailPattern, message);\n}\n\n/**\n * Ensures a string value is a valid URL\n * @param message Error message\n * @param protocols Optional list of protocols to allow\n * @category Validation Tests\n */\nexport function url(\n message: ValidatorMessage<string>,\n protocols?: string[]\n): ValidatorTest<string> {\n return createValidatorTest(\n (value) => {\n try {\n let url: URL | undefined;\n if (\n value === undefined ||\n value === null ||\n value === '' ||\n (typeof value === 'string' && (url = new URL(value)))\n ) {\n return !(url && protocols && !protocols.includes(url.protocol));\n }\n } catch {\n // Do nothing\n }\n\n return false;\n },\n message,\n () => ({ protocols })\n );\n}\n\n/**\n * Validates a string value.\n * @category Type Validators\n */\nexport const string = createTypeValidatorTest(\n {\n parser: parseString,\n },\n applyStringConfig\n);\n"],"names":[],"mappings":"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"}
@@ -39,7 +39,7 @@ declare type ValidatorResult<T = any, E = any> = ValidResult<T> | InvalidResult<
39
39
  * @typeParam T The value type
40
40
  * @category Types
41
41
  */
42
- declare type ValidatorTest<T = any, E = any> = (value: unknown, field?: string) => Promise<ValidatorResult<T, E>>;
42
+ declare type ValidatorTest<T = any, E = any> = (value?: unknown, field?: string) => Promise<ValidatorResult<T, E>>;
43
43
  /**
44
44
  * Extracts the generic error type from a ValidatorTest.
45
45
  * @typeParam T a ValidatorTest
@@ -97,7 +97,7 @@ declare function isObject(value: unknown): boolean;
97
97
  * @param obj Object to check
98
98
  * @param prop Property to look for
99
99
  */
100
- declare function hasOwnProperty(object: unknown, prop: string | number | symbol): boolean;
100
+ declare function hasOwnProperty(object: unknown, property: string | number | symbol): boolean;
101
101
  /**
102
102
  * Formats a message using a squiggly bracket `{}` template.
103
103
  * @param template Message template as string or function
package/package.json CHANGED
@@ -1,90 +1,83 @@
1
1
  {
2
- "name": "validator-fns",
3
- "version": "1.7.4",
4
- "description": "Small asynchronous validation library",
5
- "license": "MIT",
6
- "files": [
7
- "dist",
8
- "runkit.js"
9
- ],
10
- "author": {
11
- "name": "Simon Ingeson",
12
- "url": "https://smonn.se"
13
- },
14
- "keywords": [
15
- "async",
16
- "browser",
17
- "browsers",
18
- "function",
19
- "functional",
20
- "functions",
21
- "isomorphic",
22
- "node",
23
- "promise",
24
- "ssr",
25
- "typescript",
26
- "universal",
27
- "validate",
28
- "validation",
29
- "validator"
30
- ],
31
- "main": "dist/cjs/index.js",
32
- "module": "./dist/esm/index.js",
33
- "exports": {
34
- "require": "./dist/cjs/index.js",
35
- "import": "./dist/esm/index.js"
36
- },
37
- "typings": "dist/types/index.d.ts",
38
- "sideEffects": false,
39
- "engines": {
40
- "node": ">=12",
41
- "npm": ">=6"
42
- },
43
- "scripts": {
44
- "clean": "rimraf dist",
45
- "check": "tsc --noEmit",
46
- "build": "rollup -c",
47
- "lint": "xo",
48
- "test": "uvu -r ts-node/register test",
49
- "coverage": "c8 --include=src --exclude=src/index.ts npm test",
50
- "report": "c8 report --reporter=text-lcov > coverage/lcov.info",
51
- "prepublishOnly": "run-s clean lint check test build"
52
- },
53
- "devDependencies": {
54
- "c8": "7.9.0",
55
- "esbuild": "0.12.26",
56
- "husky": "7.0.2",
57
- "lint-staged": "11.1.2",
58
- "npm-run-all": "4.1.5",
59
- "rimraf": "3.0.2",
60
- "rollup": "2.56.3",
61
- "rollup-plugin-dts": "4.0.0",
62
- "rollup-plugin-esbuild": "4.5.0",
63
- "rollup-plugin-filesize": "9.1.1",
64
- "ts-node": "10.2.1",
65
- "typescript": "4.4.3",
66
- "uvu": "0.5.1",
67
- "xo": "0.44.0"
68
- },
69
- "repository": "github:smonn/validator-fns",
70
- "homepage": "https://validator-fns.smonn.se/",
71
- "runkitExampleFilename": "runkit.js",
72
- "husky": {
73
- "hooks": {
74
- "pre-commit": "lint-staged"
75
- }
76
- },
77
- "lint-staged": {
78
- "*.ts": "xo --fix"
79
- },
80
- "xo": {
81
- "envs": [
82
- "browser",
83
- "node"
84
- ],
85
- "ignores": [
86
- "runkit.js",
87
- "benchmark/"
88
- ]
89
- }
2
+ "name": "validator-fns",
3
+ "version": "1.7.8",
4
+ "description": "Small asynchronous validation library",
5
+ "license": "MIT",
6
+ "files": [
7
+ "dist",
8
+ "runkit.js"
9
+ ],
10
+ "author": {
11
+ "name": "Simon Ingeson",
12
+ "url": "https://smonn.se"
13
+ },
14
+ "keywords": [
15
+ "async",
16
+ "browser",
17
+ "browsers",
18
+ "function",
19
+ "functional",
20
+ "functions",
21
+ "isomorphic",
22
+ "node",
23
+ "promise",
24
+ "ssr",
25
+ "typescript",
26
+ "universal",
27
+ "validate",
28
+ "validation",
29
+ "validator"
30
+ ],
31
+ "main": "dist/cjs/index.js",
32
+ "module": "./dist/esm/index.js",
33
+ "exports": {
34
+ "require": "./dist/cjs/index.js",
35
+ "import": "./dist/esm/index.js"
36
+ },
37
+ "typings": "dist/types/index.d.ts",
38
+ "sideEffects": false,
39
+ "engines": {
40
+ "node": ">=12",
41
+ "npm": ">=6"
42
+ },
43
+ "scripts": {
44
+ "clean": "rimraf dist",
45
+ "check": "tsc --noEmit",
46
+ "build": "rollup -c",
47
+ "lint": "eslint --ext ts .",
48
+ "format": "prettier --write .",
49
+ "test": "uvu -r ts-node/register test",
50
+ "coverage": "c8 --include=src --exclude=src/index.ts npm test",
51
+ "report": "c8 report --reporter=text-lcov > coverage/lcov.info",
52
+ "prepublishOnly": "run-s clean lint check test build",
53
+ "prepare": "husky install"
54
+ },
55
+ "devDependencies": {
56
+ "@typescript-eslint/eslint-plugin": "5.8.1",
57
+ "@typescript-eslint/parser": "5.8.1",
58
+ "c8": "7.11.0",
59
+ "esbuild": "0.14.9",
60
+ "eslint": "8.5.0",
61
+ "eslint-config-prettier": "8.3.0",
62
+ "eslint-plugin-unicorn": "39.0.0",
63
+ "husky": "7.0.4",
64
+ "lint-staged": "12.1.4",
65
+ "npm-run-all": "4.1.5",
66
+ "prettier": "2.5.1",
67
+ "rimraf": "3.0.2",
68
+ "rollup": "2.62.0",
69
+ "rollup-plugin-dts": "4.1.0",
70
+ "rollup-plugin-esbuild": "4.8.2",
71
+ "rollup-plugin-filesize": "9.1.1",
72
+ "ts-node": "10.4.0",
73
+ "typescript": "4.5.4",
74
+ "uvu": "0.5.2"
75
+ },
76
+ "repository": "github:smonn/validator-fns",
77
+ "homepage": "https://validator-fns.smonn.se/",
78
+ "runkitExampleFilename": "runkit.js",
79
+ "lint-staged": {
80
+ "*.ts": "eslint --cache --fix",
81
+ "*.{js,css,md}": "prettier --write"
82
+ }
90
83
  }
package/runkit.js CHANGED
@@ -1,23 +1,23 @@
1
1
  const {
2
- array,
3
- boolean,
4
- date,
5
- email,
6
- exact,
7
- integer,
8
- matches,
9
- max,
10
- maxDate,
11
- min,
12
- minDate,
13
- number,
14
- object,
15
- oneOf,
16
- required,
17
- string,
18
- url,
19
- valid,
20
- invalid
2
+ array,
3
+ boolean,
4
+ date,
5
+ email,
6
+ exact,
7
+ integer,
8
+ matches,
9
+ max,
10
+ maxDate,
11
+ min,
12
+ minDate,
13
+ number,
14
+ object,
15
+ oneOf,
16
+ required,
17
+ string,
18
+ url,
19
+ valid,
20
+ invalid,
21
21
  } = require('validator-fns');
22
22
 
23
23
  const ONE_DAY = 1000 * 60 * 60 * 24;
@@ -26,98 +26,98 @@ const now = new Date();
26
26
  const tenDaysFromNow = new Date(now.getTime() + TEN_DAYS);
27
27
 
28
28
  const customValidator = (value, field) => {
29
- if (value === 'hello') {
30
- return valid({value, field});
31
- }
29
+ if (value === 'hello') {
30
+ return valid({ value, field });
31
+ }
32
32
 
33
- return invalid({
34
- message: 'Must be "hello".',
35
- value,
36
- field
37
- });
33
+ return invalid({
34
+ message: 'Must be "hello".',
35
+ value,
36
+ field,
37
+ });
38
38
  };
39
39
 
40
40
  const validate = object({
41
- firstName: string(
42
- {default: '', trim: true},
43
- required('First name is required.')
44
- ),
45
- emailAddress: string(
46
- required('Email address is required.'),
47
- email('Must be a valid email address.')
48
- ),
49
- age: number(
50
- {round: 'floor'},
51
- required('Age is required.'),
52
- integer('Age must be a whole number.'),
53
- min(18, 'Must be at least {min} years old.')
54
- ),
55
- homepage: string(url('Must be a valid URL.', ['http:', 'https:'])),
56
- fruit: string(
57
- {default: 'apple'},
58
- oneOf(
59
- ['apple', 'orange', 'banana'],
60
- ({values}) => `Must be ${values[0]}, ${values[1]} or ${values[2]}.`
61
- )
62
- ),
63
- favoriteCarMakers: array(
64
- {default: []},
65
- string(
66
- required('Car brand is required.'),
67
- oneOf(
68
- [
69
- 'BMW',
70
- 'Ferrari',
71
- 'Fiat',
72
- 'Ford',
73
- 'Honda',
74
- 'Kia',
75
- 'Mercedes',
76
- 'Subaru',
77
- 'Tesla',
78
- 'Toyota',
79
- 'Volvo'
80
- ],
81
- 'Must be a known car brand.'
82
- )
83
- ),
84
- min(2, 'Must pick at least two.'),
85
- max(4, 'Must pick at most four.')
86
- ),
87
- startDate: date(
88
- minDate(now, 'Must be on or after today.'),
89
- maxDate(tenDaysFromNow, 'Must be at most ten days from now.')
90
- ),
91
- optIn: boolean(required('Must decide to opt in or out.')),
92
- notRobot: number(
93
- required('Must enter the correct answer.'),
94
- exact(42, 'This is the answer.')
95
- ),
96
- postalCode: string(matches(/^\d{5}$/, 'Must be a five-digit number.')),
97
- custom: customValidator
41
+ firstName: string(
42
+ { default: '', trim: true },
43
+ required('First name is required.')
44
+ ),
45
+ emailAddress: string(
46
+ required('Email address is required.'),
47
+ email('Must be a valid email address.')
48
+ ),
49
+ age: number(
50
+ { round: 'floor' },
51
+ required('Age is required.'),
52
+ integer('Age must be a whole number.'),
53
+ min(18, 'Must be at least {min} years old.')
54
+ ),
55
+ homepage: string(url('Must be a valid URL.', ['http:', 'https:'])),
56
+ fruit: string(
57
+ { default: 'apple' },
58
+ oneOf(
59
+ ['apple', 'orange', 'banana'],
60
+ ({ values }) => `Must be ${values[0]}, ${values[1]} or ${values[2]}.`
61
+ )
62
+ ),
63
+ favoriteCarMakers: array(
64
+ { default: [] },
65
+ string(
66
+ required('Car brand is required.'),
67
+ oneOf(
68
+ [
69
+ 'BMW',
70
+ 'Ferrari',
71
+ 'Fiat',
72
+ 'Ford',
73
+ 'Honda',
74
+ 'Kia',
75
+ 'Mercedes',
76
+ 'Subaru',
77
+ 'Tesla',
78
+ 'Toyota',
79
+ 'Volvo',
80
+ ],
81
+ 'Must be a known car brand.'
82
+ )
83
+ ),
84
+ min(2, 'Must pick at least two.'),
85
+ max(4, 'Must pick at most four.')
86
+ ),
87
+ startDate: date(
88
+ minDate(now, 'Must be on or after today.'),
89
+ maxDate(tenDaysFromNow, 'Must be at most ten days from now.')
90
+ ),
91
+ optIn: boolean(required('Must decide to opt in or out.')),
92
+ notRobot: number(
93
+ required('Must enter the correct answer.'),
94
+ exact(42, 'This is the answer.')
95
+ ),
96
+ postalCode: string(matches(/^\d{5}$/, 'Must be a five-digit number.')),
97
+ custom: customValidator,
98
98
  });
99
99
 
100
100
  // Later...
101
101
  (async () => {
102
- const result = await validate({
103
- age: 20,
104
- custom: 'hello',
105
- emailAddress: 'foo@example.com',
106
- favoriteCarMakers: ['Ferrari', 'Tesla'],
107
- firstName: 'Bob',
108
- fruit: 'apple',
109
- homepage: 'https://www.example.com',
110
- notRobot: 42,
111
- optIn: false,
112
- postalCode: '12345',
113
- startDate: new Date()
114
- });
102
+ const result = await validate({
103
+ age: 20,
104
+ custom: 'hello',
105
+ emailAddress: 'foo@example.com',
106
+ favoriteCarMakers: ['Ferrari', 'Tesla'],
107
+ firstName: 'Bob',
108
+ fruit: 'apple',
109
+ homepage: 'https://www.example.com',
110
+ notRobot: 42,
111
+ optIn: false,
112
+ postalCode: '12345',
113
+ startDate: new Date(),
114
+ });
115
115
 
116
- if (result.state === 'valid') {
117
- // Do something with the parsed values
118
- console.log(result.value);
119
- } else {
120
- // Handle and display errors
121
- console.error(result.errors);
122
- }
116
+ if (result.state === 'valid') {
117
+ // Do something with the parsed values
118
+ console.log(result.value);
119
+ } else {
120
+ // Handle and display errors
121
+ console.error(result.errors);
122
+ }
123
123
  })();