validator-fns 3.0.0-next.0 → 3.0.0-next.1

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/README.md CHANGED
@@ -167,14 +167,13 @@ if (result.state === 'valid') {
167
167
 
168
168
  All validation tests yield one of two results: `valid` and `invalid`. Both are objects. In TypeScript the result is `ValidatorResult<T, E>` and a validation test is `ValidatorTest<T, E>`, where `T` is the value type and `E` the `errors` type. Both default to `unknown`.
169
169
 
170
- | property | type | description |
171
- | :------------ | :------ | :------------------------------------------------------------------------- |
172
- | `state` | string | Either `valid` or `invalid`. |
173
- | `field` | string | Either the field name or `undefined`. |
174
- | `value` | `T` | The parsed value. |
175
- | `message` | string | The error message unless `state` is `valid`. |
176
- | `errors` | `E` | Only if `state` is `invalid` and using the `object` or `array` validators. |
177
- | ~~`isValid`~~ | boolean | Deprecated. Use `state` instead. |
170
+ | property | type | description |
171
+ | :-------- | :----- | :------------------------------------------------------------------------- |
172
+ | `state` | string | Either `valid` or `invalid`. |
173
+ | `field` | string | Either the field name or `undefined`. |
174
+ | `value` | `T` | The parsed value. |
175
+ | `message` | string | The error message unless `state` is `valid`. |
176
+ | `errors` | `E` | Only if `state` is `invalid` and using the `object` or `array` validators. |
178
177
 
179
178
  ### Validation error message
180
179
 
@@ -196,13 +195,15 @@ A **validation type** is expected to parse and prepare the value for the provide
196
195
  - [boolean(config?, ...tests)](#booleanconfig-tests)
197
196
  - [date(config?, ...tests)](#dateconfig-tests)
198
197
  - [number(config?, ...tests)](#numberconfig-tests)
199
- - [object(schema)](#objectschema)
198
+ - [object(schema, ...tests)](#objectschema-tests)
200
199
  - [string(config?, ...tests)](#stringconfig-tests)
201
200
 
202
201
  #### array(config?, itemTest, ...tests)
203
202
 
204
203
  Casts value to an array, `null` or `undefined` if using the default date parser. `config` is optional. `itemTest` is the validation type or test to be applied on each value within the array value. All remaining `tests` are applied to the array as a whole.
205
204
 
205
+ A valid result's `value` holds each item as `itemTest` returned it, so `array(number())` turns `['1', '2.5']` into `[1, 2.5]`, and `array(string({ trim: true }))` trims each item.
206
+
206
207
  Supported validation tests: `max`, `min`, and `required`.
207
208
 
208
209
  For invalid results, errors are in the `errors` property. It is an array of type:
@@ -258,6 +259,8 @@ The default parser only accepts dates, numbers, and a subset of [ISO 8601][iso86
258
259
 
259
260
  Casts value to a number, `null` or `undefined` if using the default number parser. `config` is optional.
260
261
 
262
+ The default parser accepts numbers, bigints, dates (as their timestamp), strings that start with a number (read with `parseFloat`, so `'12px'` is `12`), and `Number` or `String` objects holding one. A blank string (`''` or only whitespace) gives `NaN`, which `required` treats as empty and `default` replaces. Any other input gives an invalid result with the message `Failed to parse value to number.`: strings without a leading number, such as `'abc'`, booleans, symbols, and objects other than the ones above, arrays and functions included.
263
+
261
264
  Supported validation tests: `exact`, `integer`, `max`, `min`, `oneOf`, and `required`.
262
265
 
263
266
  <details><summary>config</summary>
@@ -270,13 +273,30 @@ Supported validation tests: `exact`, `integer`, `max`, `min`, `oneOf`, and `requ
270
273
 
271
274
  </details>
272
275
 
273
- #### object(schema)
276
+ #### object(schema, ...tests)
274
277
 
275
278
  The only validation type that does not cast the entered value, meaning it does not use a parser. There's also no default fallback value option here. Instead, the schema is an object where its properties are validation types such as `string`, `array`, `number`, etc. Nested `object` validators are allowed, but not recommended due to their complexity and potential performance hit.
276
279
 
277
280
  For invalid results, errors are in the `errors` property. It matches the provided object with the same keys and strings or string records as values that contain the error messages.
278
281
 
279
- Unlike yup, this API does not (yet at least) have a ref option.
282
+ In TypeScript, every field of the valid value is optional and can be `null`, as in `{ name?: string | null }`: a field's validator passes `null` and `undefined` through unless a test such as `required` rejects them.
283
+
284
+ The remaining `tests` are object-level tests. They run in order on the parsed object, only once every property is valid, and the first failure becomes the result. Use [`check`](#checkpath-test-message) to compare fields and put the error on one of them:
285
+
286
+ ```ts
287
+ const signup = object(
288
+ {
289
+ password: string(required('Required.')),
290
+ confirm: string(required('Required.')),
291
+ },
292
+ check('confirm', (value) => value.confirm === value.password, 'Must match.'),
293
+ );
294
+
295
+ await signup({ password: 'secret', confirm: 'other' });
296
+ // { state: 'invalid', message: '', errors: { confirm: 'Must match.' }, ... }
297
+ ```
298
+
299
+ A field's own error takes precedence: object-level tests don't run while any property is invalid, so they always compare valid, parsed values.
280
300
 
281
301
  To use this with a library such as [Formik][formik], you can use the resulting `errors` property. It is a key-value structure with the schema property keys and their validation errors if any. Besides that, the object validation results are the same as described above.
282
302
 
@@ -284,6 +304,8 @@ To use this with a library such as [Formik][formik], you can use the resulting `
284
304
 
285
305
  Casts value to a string, `null` or `undefined` if using the default string parser. `config` is optional.
286
306
 
307
+ The default parser accepts strings, numbers, bigints, booleans, dates (as an ISO string), and `String`, `Number`, or `Boolean` objects. Any other object, including arrays and functions, and symbols give an invalid result with the message `Failed to parse value to string.`
308
+
287
309
  Supported validation tests: `email`, `exact`, `matches`, `max`, `min`, `oneOf`, `required`, `url`, and `uuid`.
288
310
 
289
311
  <details><summary>config</summary>
@@ -300,6 +322,7 @@ Supported validation tests: `email`, `exact`, `matches`, `max`, `min`, `oneOf`,
300
322
 
301
323
  A **validation test** is a simplified version of a validation type. It accepts a value of a specific type including `null` and `undefined` and then returns a promise that resolves to a validation result. You can use a validation test directly without the validation type, but it's not recommended as you lose the parsing step and you can't apply multiple tests to the same field as easily.
302
324
 
325
+ - [check(path?, test, message)](#checkpath-test-message)
303
326
  - [email(message)](#emailmessage)
304
327
  - [exact(limit, message)](#exactlimit-message)
305
328
  - [integer(message)](#integermessage)
@@ -313,6 +336,20 @@ A **validation test** is a simplified version of a validation type. It accepts a
313
336
  - [url(message, protocols?)](#urlmessage-protocols)
314
337
  - [uuid(message)](#uuidmessage)
315
338
 
339
+ #### check(path?, test, message)
340
+
341
+ An object-level test for `object`. It fails when `test` returns `false` for the parsed object. With a `path`, the message is the error at that property in the object's `errors`; a list of names reaches into nested objects, such as `['shipping', 'zip']`. Without a `path`, the message is the object's own `message`. The parsed object is provided to the message as `value`.
342
+
343
+ <details><summary>arguments</summary>
344
+
345
+ | name | type | description |
346
+ | :-------- | :----------------- | :---------------------------------------------------------------- |
347
+ | `path` | string or string[] | Optional. The property, or the path into nested objects, to fail. |
348
+ | `test` | function | Gets the parsed object and returns `true` when it is valid. |
349
+ | `message` | string or function | The validation error message. |
350
+
351
+ </details>
352
+
316
353
  #### email(message)
317
354
 
318
355
  Ensures the value follows an email address format. Wraps the `matches` validation test. Works with strings.
@@ -447,16 +484,14 @@ Ensures value is **not** one of: `undefined`, `null`, `NaN`, an empty string, or
447
484
 
448
485
  #### url(message, protocols?)
449
486
 
450
- Ensures value is a valid URL. Works with strings. `protocols` is provided to the message.
451
-
452
- > **Warning:** without `protocols`, any URL that the `URL` constructor parses is valid, including `javascript:` and `data:` URLs, which can run script when used as a link. Pass `['http:', 'https:']` for values you render as links. The default is planned to change to `http:` and `https:` in v3 ([#521](https://github.com/smonn/validator-fns/issues/521)).
487
+ Ensures value is a valid URL with an allowed protocol. Works with strings. `protocols` defaults to `['http:', 'https:']`, so `javascript:` and `data:` URLs, which can run script when used as a link, are invalid. A list replaces the default, so `['mailto:']` allows only `mailto:`. `protocols` is provided to the message.
453
488
 
454
489
  <details><summary>arguments</summary>
455
490
 
456
- | name | type | description |
457
- | :---------- | :----------------- | :------------------------------------------------------- |
458
- | `message` | string or function | The validation error message. |
459
- | `protocols` | array | List of allowed URL protocols, e.g. `https:`, `mailto:`. |
491
+ | name | type | description |
492
+ | :---------- | :----------------- | :--------------------------------------------------------------------------------- |
493
+ | `message` | string or function | The validation error message. |
494
+ | `protocols` | array | Allowed URL protocols, e.g. `https:`, `mailto:`. Defaults to `http:` and `https:`. |
460
495
 
461
496
  </details>
462
497
 
@@ -480,6 +515,7 @@ Custom validation types and validators can be created and used as needed. There
480
515
  - [createTypeValidatorTest(defaultConfig, applyConfig)](#createtypevalidatortestdefaultconfig-applyconfig)
481
516
  - [valid({ value, field })](#valid-value-field-)
482
517
  - [invalid({ message, value, field, errors, extras })](#invalid-message-value-field-errors-extras-)
518
+ - [standard(validator)](#standardvalidator)
483
519
 
484
520
  #### formatMessage(template, params)
485
521
 
@@ -491,7 +527,7 @@ Useful helper for simple validation types such as strings, numbers, etc. `defaul
491
527
 
492
528
  The validation tests passed to the resulting validator report their errors as strings, as the built-in ones do; a test whose `errors` has another type is a type error.
493
529
 
494
- In TypeScript, pass the value type and the config type as type arguments. TypeScript 5.6 and later infer the config type from `defaultConfig` alone, so without them the validator rejects options that `defaultConfig` doesn't set.
530
+ In TypeScript, the value type and the config type are inferred from `applyConfig`, so the validator accepts options that `defaultConfig` doesn't set. Passing them as type arguments, as in `createTypeValidatorTest<number, MoneyConfig>(…)`, still works.
495
531
 
496
532
  ```ts
497
533
  import {
@@ -515,7 +551,7 @@ function applyMoneyConfig(
515
551
  : amount;
516
552
  }
517
553
 
518
- const money = createTypeValidatorTest<number, MoneyConfig>(
554
+ const money = createTypeValidatorTest(
519
555
  { parser: parseNumber },
520
556
  applyMoneyConfig,
521
557
  );
@@ -532,17 +568,33 @@ Formats a successful validation result. `value` is the parsed value and `field`
532
568
 
533
569
  Formats a failed validation result. `message` is the same as the `formatMessage`'s template. `value` and `field` is the same as above, `errors` is additional error details used by `array` and `object` validators, and `extras` are optional extra parameters that can be used in the message.
534
570
 
571
+ #### standard(validator)
572
+
573
+ Adds the [Standard Schema][standard-schema] interface to a validator, for libraries that accept any Standard Schema. It returns a new validator with a `~standard` property and leaves the one passed in unchanged.
574
+
575
+ ```ts
576
+ const schema = standard(object({ email: string(email('Must be an email.')) }));
577
+
578
+ await schema['~standard'].validate({ email: 'nope' });
579
+ // { issues: [{ message: 'Must be an email.', path: ['email'] }] }
580
+ ```
581
+
582
+ - `validate` always returns a promise, because every validator here is async. Libraries that only accept synchronous schemas can't use it.
583
+ - A valid result gives `{ value }`, the parsed value. Its type is the validator's value type or `null` or `undefined`, as in a valid result.
584
+ - An invalid result gives one issue per error message. Object keys and array indexes in `errors` form each issue's `path`, and a non-empty `message`, such as an array-level error, is an issue with no path. An error with no message gets `'Invalid value.'`.
585
+ - An `object` field that fails both an array-level test and item tests keeps only the array-level message, because `object` stores a field's message in place of its errors, so only that message becomes an issue.
586
+
535
587
  ## Supported environments
536
588
 
537
589
  Supports Node versions in active or maintenance LTS at release time. Dropping one waits for the next major release.
538
590
 
539
591
  - Node.js 22 and later.
592
+ - TypeScript 5.4 and later, for the type declarations.
540
593
  - Chrome and Edge 85+, Firefox 77+, and Safari 13.1+ (iOS 13.4+): the first versions with every feature below, per [MDN's browser compatibility data][bcd] 8.1.6.
541
594
 
542
595
  To support older environments, transpile or polyfill these:
543
596
 
544
597
  - `String.prototype.replaceAll` (ES2021)
545
- - Nullish coalescing (`??`, ES2020)
546
598
  - Optional catch binding (ES2019)
547
599
  - Object spread (`...`, ES2018)
548
600
  - `async`, `await` (ES2017)
@@ -552,6 +604,7 @@ To support older environments, transpile or polyfill these:
552
604
  [npm]: https://www.npmjs.com/package/validator-fns
553
605
  [docs]: #documentation
554
606
  [github]: https://github.com/smonn/validator-fns
607
+ [standard-schema]: https://standardschema.dev
555
608
  [yup]: https://github.com/jquense/yup
556
609
  [bcd]: https://github.com/mdn/browser-compat-data
557
610
  [date-fns]: https://date-fns.org
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e){return Object.prototype.toString.call(e)===`[object Object]`}function t(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function n(e){return!!Reflect.get(Object(e),Symbol.iterator)}const r=/{(\w+)}/g;function i(e,t){return typeof e==`string`?e.replaceAll(r,(e,n)=>String(Reflect.get(t,n))):e(t)}async function a({value:e,field:t}){return{isValid:!0,state:`valid`,value:e,field:t}}async function o({errors:e,field:t,message:n,value:r,extras:a}){return{isValid:!1,state:`invalid`,message:i(n,{...a,value:r,field:t}),value:r,field:t,errors:e}}function s(e){return Array.isArray(e)||e==null?e:n(e)?[...e]:[]}function c(e,t){let n=e.parser(t);return e.default!==void 0&&(n==null||n.length===0)&&(n=e.default),n}async function l(e,t,n){for(let r of e){let e=await r(t,n);if(e.state===`invalid`)return e}}async function u(e,t,n){let r=!0,i=[];if(!t||!e)return{isValid:r,errors:i};for(let[a,o]of t.entries()){let t=await e(o,n?`${n}[${a}]`:`[${a}]`);t.state===`invalid`?(r=!1,i.push(t.message||t.errors)):i.push(null)}return{isValid:r,errors:i}}function d(e,...t){let n=t,r={parser:s};return e!==void 0&&(typeof e==`function`?n=[e,...t]:r={...r,...e}),async(e,t)=>{let i=c(r,e),[s,...d]=n,f=await l(d,i,t),p=await u(s,i,t);return!f&&p.isValid?a({value:i,field:t}):o({message:f?f.message:``,value:e,field:t,errors:p.errors})}}function f(e,t){return(n,...r)=>{let i=e,s=r;return n!==void 0&&(typeof n==`function`?s=[n,...r]:i={...e,...n}),async(e,n)=>{try{let r=t(e,i);for(let e of s){let t=await e(r,n);if(t.state===`invalid`)return t}return await a({value:r,field:n})}catch(t){return o({message:t instanceof Error?t.message:String(t),value:e,field:n})}}}}function p(e,t,n){return async(r,i)=>e(r,i)?a({value:r,field:i}):o({message:t,value:r,field:i,extras:n?n(r):void 0})}function m(e){return e==null||typeof e==`boolean`?e:!!e}function h(e,t){let n=t.parser(e);return t.default!==void 0&&n==null&&(n=t.default),n}const g=f({parser:m},h),_=/* @__PURE__ */ new Date(``),v=/^(\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)?)?)?)?)?$/,y=/^([+-])([0-2]\d):?([0-5]\d)$/;function b(e){let t=y.exec(e);if(e===`Z`||!t)return 0;let[,n,r=`0`,i=`0`]=t;return(n===`-`?-1:1)*(Number.parseInt(r,10)*60+Number.parseInt(i,10))}const x=[()=>0,(e=`0`)=>Number.parseInt(e,10),(e=`1`)=>Number.parseInt(e,10)-1,(e=`1`)=>Number.parseInt(e,10),(e=`0`)=>Number.parseInt(e,10),(e=`0`)=>Number.parseInt(e,10),(e=`0`)=>Number.parseInt(e,10),(e=`0`)=>Number.parseFloat(e)*1e3];function S(e){return e==null||e instanceof Date?e:typeof e==`number`?new Date(e):typeof e==`string`?C(e):_}function C(e){let t=v.exec(e);if(t===null)return _;let[,n=0,r=0,i=0,a=0,o=0,s=0,c=0]=x.map((e,n)=>e(t[n])),l=t[8];return l?new Date(Date.UTC(n,r,i,a,o+b(l),s,c)):new Date(n,r,i,a,o,s,c)}function w(e,t){let n=t.parser(e);return t.default!==void 0&&(n==null||Number.isNaN(n.getTime()))&&(n=t.default),n}function T(e,t,n){let r=S(e);return p(e=>r!=null&&(e==null||e instanceof Date&&(n?e>r:e>=r)),t,()=>({min:r,limit:r,exclusive:n}))}function E(e,t,n){let r=S(e);return p(e=>r!=null&&(e==null||e instanceof Date&&(n?e<r:e<=r)),t,()=>({max:r,limit:r,exclusive:n}))}const D=f({parser:S},w);function O(e){return e==null||typeof e==`number`?e:e instanceof Date?e.getTime():typeof e==`string`?Number.parseFloat(e):Number.parseFloat(String(e))}function k(e,t){let n=t.parser(e);if(t.default!==void 0&&(n==null||Number.isNaN(n))&&(n=t.default),t.round&&typeof n==`number`)switch(t.round){case`nearest`:n=Math.round(n);break;case`ceil`:n=Math.ceil(n);break;case`floor`:n=Math.floor(n);break;default:throw Error(`Unknown round type: ${String(t.round)}`)}return n}function A(e){return async(t,n)=>t==null||typeof t==`number`&&Number.isFinite(t)&&Math.floor(t)===t?a({value:t,field:n}):o({message:e,value:t,field:n})}const j=f({parser:O},k);function M(e){if(typeof e!=`object`||!e)throw TypeError("`properties` must be a configuration object");return async(n,r)=>{let i={},s={},c=!0;for(let r in e)if(t(e,r)){let t=e[r],a=Reflect.get(Object(n),r),l=await(typeof t==`function`?t(a,r):o({field:r,message:`No validator set`,value:a}));s[r]=l.value,l.state===`invalid`&&(c=!1,i[r]=l.message||l.errors)}return c?a({value:s,field:r}):o({message:``,value:n,field:r,errors:i})}}function N(e,t){return p(e=>t&&e===null||e!=null&&(typeof e!=`string`||e!==``)&&!(typeof e==`number`&&Number.isNaN(e))&&!(e instanceof Date&&Number.isNaN(e.valueOf())),e)}function P(e,t){let n=e;return p(t=>t==null||n.includes(t)||t instanceof Date&&e.some(e=>e.valueOf()===t.valueOf()),t,()=>({values:e}))}function F(e){return typeof e==`string`||Array.isArray(e)?e.length:e}function I(e,t,n){return p(t=>{let r=F(t);return r==null||t===``||(n?r<e:r<=e)},t,t=>({max:e,limit:e,amount:F(t),exclusive:n}))}function L(e,t,n){return p(t=>{let r=F(t);return r==null||t===``||(n?r>e:r>=e)},t,t=>({min:e,limit:e,amount:F(t),exclusive:n}))}function R(e,t){return p(t=>{let n=F(t);return n==null||t===``||n===e},t,t=>({amount:F(t),limit:e,exact:e}))}const z=/^[\w!#$%&'*+./=?^`{|}~-]+@[\dA-Za-z](?:[\dA-Za-z-]{0,61}[\dA-Za-z])?(?:\.[\dA-Za-z](?:[\dA-Za-z-]{0,61}[\dA-Za-z])?)*$/,B=/^(?:[\da-f]{8}-[\da-f]{4}-[1-8][\da-f]{3}-[89ab][\da-f]{3}-[\da-f]{12}|0{8}-0{4}-0{4}-0{4}-0{12}|f{8}-f{4}-f{4}-f{4}-f{12})$/i;function V(t){if(t==null||typeof t==`string`)return t;if(t instanceof Date)return t.toISOString();if(e(t))throw TypeError(`Failed to parse value to string.`);return String(t)}function H(e,t){let n=t.parser(e);return t.default!==void 0&&(n==null||n===``)&&(n=t.default),t.trim&&typeof n==`string`&&(n=n.trim()),n}function U(e,t){let n=new RegExp(e);return p(e=>(n.lastIndex=0,e==null||e===``||typeof e==`string`&&n.test(e)),t,()=>({pattern:e}))}function W(e){return U(z,e)}function G(e){return U(B,e)}function K(e,t){return p(e=>{try{let n;if(e==null||e===``||typeof e==`string`&&(n=new URL(e)))return!(n&&t&&!t.includes(n.protocol))}catch{}return!1},e,()=>({protocols:t}))}const q=f({parser:V},H);exports.applyArrayConfig=c,exports.applyBooleanConfig=h,exports.applyDateConfig=w,exports.applyNumberConfig=k,exports.applyStringConfig=H,exports.array=d,exports.boolean=g,exports.createTypeValidatorTest=f,exports.createValidatorTest=p,exports.date=D,exports.email=W,exports.exact=R,exports.formatMessage=i,exports.hasOwnProperty=t,exports.integer=A,exports.invalid=o,exports.invalidDate=_,exports.isObject=e,exports.matches=U,exports.max=I,exports.maxDate=E,exports.min=L,exports.minDate=T,exports.number=j,exports.object=M,exports.oneOf=P,exports.parseArray=s,exports.parseBoolean=m,exports.parseDate=S,exports.parseNumber=O,exports.parseString=V,exports.required=N,exports.string=q,exports.url=K,exports.uuid=G,exports.valid=a;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e){return e.message||e.errors===void 0?e.message:e.errors}function t(e){return Object.prototype.toString.call(e)===`[object Object]`}function n(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function r(e){return!!Reflect.get(Object(e),Symbol.iterator)}const i=/{(\w+)}/g;function a(e,t){return typeof e==`string`?e.replaceAll(i,(e,n)=>String(Reflect.get(t,n))):e(t)}async function o(e){return s(e)}function s({value:e,field:t}){return{state:`valid`,value:e,field:t}}async function c(e){return l(e)}function l({errors:e,field:t,message:n,value:r,extras:i}){return{state:`invalid`,message:a(n,{...i,value:r,field:t}),value:r,field:t,errors:e}}function u(e){return Array.isArray(e)||e==null?e:r(e)?[...e]:[]}function d(e,t){let n=e.parser(t);return e.default!==void 0&&(n==null||n.length===0)&&(n=e.default),n}async function f(e,t,n){for(let r of e){let e=await r(t,n);if(e.state===`invalid`)return e}}async function p(t,n,r){let i=!0,a=[];if(!n||!t)return{isValid:i,errors:a,values:n};let o=[];for(let[s,c]of n.entries()){let n=await t(c,`${r||``}[${s}]`);o.push(n.value),n.state===`invalid`?(i=!1,a.push(e(n))):a.push(null)}return{isValid:i,errors:a,values:o}}function m(e,...t){let n=typeof e==`function`?[e,...t]:t,r={parser:u,...typeof e==`function`?void 0:e};return async(e,t)=>{let i=d(r,e),[a,...s]=n,l=await f(s,i,t),u=await p(a,i,t);return!l&&u.isValid?o({value:u.values,field:t}):c({message:l?l.message:``,value:e,field:t,errors:u.errors})}}const h=/* @__PURE__ */ new WeakMap;function g(e,t){return(n,...r)=>{let i=e,a=r;return n!==void 0&&(typeof n==`function`?a=[n,...r]:i={...e,...n}),async(e,n)=>{try{let r=t(e,i);for(let e of a){let t=h.get(e),i;if(i=t?t(r,n):await e(r,n),i.state===`invalid`)return i}return s({value:r,field:n})}catch(t){return c({message:t instanceof Error?t.message:String(t),value:e,field:n})}}}}function _(e,t,n){let r=(r,i)=>e(r,i)?s({value:r,field:i}):l({message:t,value:r,field:i,extras:n?n(r):void 0}),i=async(e,t)=>r(e,t);return h.set(i,r),i}function v(e){return e==null||typeof e==`boolean`?e:!!e}function y(e,t){let n=t.parser(e);return t.default!==void 0&&n==null&&(n=t.default),n}const b=g({parser:v},y),x=/* @__PURE__ */ new Date(``),S=/^(\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)?)?)?)?)?$/,C=/^([+-])([0-2]\d):?([0-5]\d)$/;function w(e){let t=C.exec(e);if(e===`Z`||!t)return 0;let[,n,r,i]=t;return(n===`-`?-1:1)*(Number(r)*60+Number(i))}const T=[()=>0,e=>Number(e),(e=`1`)=>Number.parseInt(e,10)-1,(e=`1`)=>Number.parseInt(e,10),(e=`0`)=>Number.parseInt(e,10),(e=`0`)=>Number.parseInt(e,10),(e=`0`)=>Number.parseInt(e,10),(e=`0`)=>Number.parseFloat(e)*1e3];function E(e){return e==null||e instanceof Date?e:typeof e==`number`?new Date(e):typeof e==`string`?D(e):x}function D(e){let t=S.exec(e);if(t===null)return x;let[,n=0,r=0,i=0,a=0,o=0,s=0,c=0]=T.map((e,n)=>e(t[n])),l=t[8];return l?new Date(Date.UTC(n,r,i,a,o+w(l),s,c)):new Date(n,r,i,a,o,s,c)}function O(e,t){let n=t.parser(e);return t.default!==void 0&&(n==null||Number.isNaN(n.getTime()))&&(n=t.default),n}function k(e,t,n){let r=E(e);return _(e=>r!=null&&(e==null||e instanceof Date&&(n?e>r:e>=r)),t,()=>({min:r,limit:r,exclusive:n}))}function ee(e,t,n){let r=E(e);return _(e=>r!=null&&(e==null||e instanceof Date&&(n?e<r:e<=r)),t,()=>({max:r,limit:r,exclusive:n}))}const te=g({parser:E},O),ne=[e=>String.prototype.valueOf.call(e),e=>Number.prototype.valueOf.call(e),e=>Boolean.prototype.valueOf.call(e)];function A(e){if(typeof e!=`object`||!e)return e;for(let t of ne)try{return t(e)}catch{}return e}function j(e){let t=A(e);switch(typeof t){case`string`:case`number`:case`bigint`:case`boolean`:return String(t);default:return}}function M(e){if(e==null||typeof e==`number`)return e;if(e instanceof Date)return e.getTime();let t=j(e),n=t===void 0?NaN:Number.parseFloat(t);if(Number.isNaN(n)&&(t===void 0||t.trim()!==``))throw TypeError(`Failed to parse value to number.`);return n}function N(e,t){let n=t.parser(e);if(t.default!==void 0&&(n==null||Number.isNaN(n))&&(n=t.default),t.round&&typeof n==`number`)switch(t.round){case`nearest`:n=Math.round(n);break;case`ceil`:n=Math.ceil(n);break;case`floor`:n=Math.floor(n);break;default:throw Error(`Unknown round type: ${String(t.round)}`)}return n}function P(e){return async(t,n)=>t==null||typeof t==`number`&&Number.isFinite(t)&&Math.floor(t)===t?o({value:t,field:n}):c({message:e,value:t,field:n})}const F=g({parser:M},N);function I(...e){let[t,n,r]=e.length===2?[[],...e]:e,i=typeof t==`string`?[t]:t;return async(e,t)=>{let s=e;return n(s)?o({value:s,field:t}):i.length===0?c({message:r,value:s,field:t}):c({message:``,value:s,field:t,errors:i.reduceRight((e,t)=>({[t]:e}),a(r,{value:s,field:t}))})}}function L(e,t,n){Object.defineProperty(e,t,{value:n,enumerable:!0,writable:!0,configurable:!0})}async function R(e,t,n){for(let r of e){let e=await r(t,n);if(e.state===`invalid`)return e}}function z(t,...r){if(typeof t!=`object`||!t)throw TypeError("`properties` must be a configuration object");return async(i,a)=>{let s=Object(i),l={},u={},d=!0;for(let r in t)if(n(t,r)){let i=t[r],a=n(s,r)?Reflect.get(s,r):void 0,o=await(typeof i==`function`?i(a,r):c({field:r,message:`No validator set`,value:a}));L(u,r,o.value),o.state===`invalid`&&(d=!1,L(l,r,e(o)))}if(!d)return c({message:``,value:i,field:a,errors:l});let f=await R(r,u,a);return f?c({message:f.message,value:i,field:a,errors:f.errors}):o({value:u,field:a})}}const B=`Invalid value.`;function V(e,t,n){if(typeof e==`string`)n.push({message:e||B,path:t});else if(Array.isArray(e))for(let[r,i]of e.entries())i!==null&&V(i,[...t,r],n);else if(typeof e==`object`&&e)for(let r of Object.keys(e))V(Reflect.get(e,r),[...t,r],n);else n.push({message:B,path:t})}function H(e){return Object.assign((t,n)=>e(t,n),{"~standard":{version:1,vendor:`validator-fns`,validate:async t=>{let n=await e(t);if(n.state===`valid`)return{value:n.value};let r=n.message?[{message:n.message}]:[];return n.errors!==void 0&&V(n.errors,[],r),{issues:r.length>0?r:[{message:B}]}}}})}function U(e,t){return _(e=>t&&e===null||e!=null&&(typeof e!=`string`||e!==``)&&!(typeof e==`number`&&Number.isNaN(e))&&!(e instanceof Date&&Number.isNaN(e.valueOf())),e)}function W(e,t){let n=e;return _(t=>t==null||n.includes(t)||t instanceof Date&&e.some(e=>e.valueOf()===t.valueOf()),t,()=>({values:e}))}function G(e){return typeof e==`string`||Array.isArray(e)?e.length:e}function K(e,t,n){return _(t=>{let r=G(t);return r==null||t===``||(n?r<e:r<=e)},t,t=>({max:e,limit:e,amount:G(t),exclusive:n}))}function q(e,t,n){return _(t=>{let r=G(t);return r==null||t===``||(n?r>e:r>=e)},t,t=>({min:e,limit:e,amount:G(t),exclusive:n}))}function J(e,t){return _(t=>{let n=G(t);return n==null||t===``||n===e},t,t=>({amount:G(t),limit:e,exact:e}))}const Y=/^[\w!#$%&'*+./=?^`{|}~-]+@[\dA-Za-z](?:[\dA-Za-z-]{0,61}[\dA-Za-z])?(?:\.[\dA-Za-z](?:[\dA-Za-z-]{0,61}[\dA-Za-z])?)*$/,X=/^(?:[\da-f]{8}-[\da-f]{4}-[1-8][\da-f]{3}-[89ab][\da-f]{3}-[\da-f]{12}|0{8}-0{4}-0{4}-0{4}-0{12}|f{8}-f{4}-f{4}-f{4}-f{12})$/i;function Z(e){if(e==null||typeof e==`string`)return e;if(e instanceof Date)return e.toISOString();let t=j(e);if(t===void 0)throw TypeError(`Failed to parse value to string.`);return t}function Q(e,t){let n=t.parser(e);return t.default!==void 0&&(n==null||n===``)&&(n=t.default),t.trim&&typeof n==`string`&&(n=n.trim()),n}function $(e,t){let n=new RegExp(e);return _(e=>(n.lastIndex=0,e==null||e===``||typeof e==`string`&&n.test(e)),t,()=>({pattern:e}))}function re(e){return $(Y,e)}function ie(e){return $(X,e)}function ae(e,t=[`http:`,`https:`]){return _(e=>{try{let n;if(e==null||e===``||typeof e==`string`&&(n=new URL(e)))return!n||t.includes(n.protocol)}catch{}return!1},e,()=>({protocols:t}))}const oe=g({parser:Z},Q);exports.applyArrayConfig=d,exports.applyBooleanConfig=y,exports.applyDateConfig=O,exports.applyNumberConfig=N,exports.applyStringConfig=Q,exports.array=m,exports.boolean=b,exports.check=I,exports.createTypeValidatorTest=g,exports.createValidatorTest=_,exports.date=te,exports.email=re,exports.exact=J,exports.formatMessage=a,exports.hasOwnProperty=n,exports.integer=P,exports.invalid=c,exports.invalidDate=x,exports.isObject=t,exports.matches=$,exports.max=K,exports.maxDate=ee,exports.min=q,exports.minDate=k,exports.number=F,exports.object=z,exports.oneOf=W,exports.parseArray=u,exports.parseBoolean=v,exports.parseDate=E,exports.parseNumber=M,exports.parseString=Z,exports.required=U,exports.standard=H,exports.string=oe,exports.url=ae,exports.uuid=ie,exports.valid=o;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["items","isObject","value","hasOwnProperty","object","property","isIterable","formatPattern","formatMessage","template","parameters","key","valid","invalid","message","extras","parseArray","applyArrayConfig","parsedValue","config","findArrayInvalidResult","validatorTest","tests","result","arrayValue","field","validateItems","isValid","errors","validateItem","index","item","array","allTests","finalConfig","arrayTests","arrayInvalidResult","items","createTypeValidatorTest","defaultConfig","applyConfig","error","createValidatorTest","test","getExtras","parseBoolean","applyBooleanConfig","boolean","invalidDate","isoDatePattern","timezonePattern","parseTimezone","parts","timezone","sign","hour","minute","dateParts","part","parseDate","parseIsoDate","year","month","day","second","millisecond","parse","applyDateConfig","minDate","parsedDate","limit","exclusive","maxDate","date","parseNumber","applyNumberConfig","integer","number","properties","resolvedValues","validator","values","required","nullable","oneOf","allowed","x","getAmount","max","amount","min","exact","emailPattern","uuidPattern","parseString","applyStringConfig","matches","ownPattern","pattern","email","uuid","url","parsed","protocols","string"],"sources":["../src/shared.ts","../src/arrays.ts","../src/factories.ts","../src/booleans.ts","../src/parse-date.ts","../src/dates.ts","../src/numbers.ts","../src/objects.ts","../src/common.ts","../src/limits.ts","../src/strings.ts"],"sourcesContent":["export 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 | undefined;\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 | undefined;\n /** Extra error details */\n errors?: E | undefined;\n};\n\n/**\n * The result of a validation.\n * @typeParam T The value type\n * @category Types\n */\nexport type ValidatorResult<T = unknown, E = unknown> =\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 = unknown, E = unknown> = (\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> =\n T extends ValidatorTest<unknown, infer E> ? E : 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> =\n T extends ValidatorTest<infer V> ? V : 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<unknown, E>,\n ...tests: ValidatorTest<unknown, E>[]\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 object Object to check\n * @param property 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/**\n * Checks for a truthy `Symbol.iterator` property, boxing primitives so strings\n * count as iterable.\n * @internal\n */\nexport function isIterable(value: unknown): value is Iterable<unknown> {\n return Boolean(Reflect.get(Object(value), Symbol.iterator));\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 parameters 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.replaceAll(formatPattern, (_, key: string) =>\n String(Reflect.get(parameters, key)),\n );\n }\n\n return template(parameters);\n}\n\n/**\n * Creates a valid result\n * @param result Result fields\n * @param result.value Parsed value\n * @param result.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 result Result fields\n * @param result.message Error message, formatted with `formatMessage`\n * @param result.value Parsed value\n * @param result.field Field name\n * @param result.errors Extra error details, such as per-field errors from `object` and `array`\n * @param result.extras Extra message params\n * @category Helpers\n */\nexport async function invalid<\n T,\n E = never,\n P extends ValidatorMessageParameters<T> = ValidatorMessageParameters<T>,\n>({\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 | undefined;\n extras?: Omit<P, 'field' | 'value'> | undefined;\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","import {\n invalid,\n isIterable,\n valid,\n type ConfigBase,\n type ValidatorTest,\n} from './shared.js';\n\n/**\n * Invalid validation result for an item in the array\n * @category Types\n */\nexport type ArrayItemValidatorResult<E = unknown> = null | string | E;\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 const items: unknown[] = value;\n return items;\n }\n\n if (value === null || value === undefined) {\n return value;\n }\n\n if (isIterable(value)) {\n return [...value];\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 */\n// oxlint-disable-next-line typescript/no-unnecessary-type-parameters -- removing T breaks callers that pass a type argument; #588 removes it in v3\nexport function applyArrayConfig<T>(\n config: ArrayConfig,\n value: unknown,\n): T[] | null | undefined {\n let parsedValue = config.parser(value);\n if (\n config.default !== undefined &&\n (parsedValue === undefined ||\n parsedValue === null ||\n parsedValue.length === 0)\n ) {\n parsedValue = config.default;\n }\n\n return parsedValue as T[];\n}\n\n/**\n * Runs the tests that target the array itself, stopping at the first failure.\n * @param tests Array-level tests\n * @param arrayValue Parsed array\n * @param field Field name\n * @internal\n */\nasync function findArrayInvalidResult(\n tests: ValidatorTest[],\n arrayValue: unknown[] | null | undefined,\n field: string | undefined,\n) {\n for (const validatorTest of tests) {\n const result = await validatorTest(arrayValue, field);\n if (result.state === 'invalid') {\n return result;\n }\n }\n\n return undefined;\n}\n\n/**\n * Runs the item test on every item, collecting `null` for valid items and the\n * message or errors for invalid ones. Without an array or an item test, there\n * is nothing to check.\n * @param validateItem Item test\n * @param arrayValue Parsed array\n * @param field Field name\n * @internal\n */\nasync function validateItems(\n validateItem: ValidatorTest | undefined,\n arrayValue: unknown[] | null | undefined,\n field: string | undefined,\n) {\n let isValid = true;\n const errors: ArrayItemValidatorResult[] = [];\n\n if (!arrayValue || !validateItem) {\n return { isValid, errors };\n }\n\n for (const [index, item] of arrayValue.entries()) {\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(result.message || result.errors);\n } else {\n errors.push(null);\n }\n }\n\n return { isValid, errors };\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, E>(\n config?: Partial<ArrayConfig> | ValidatorTest<T, E>,\n ...tests: ValidatorTest[]\n): ValidatorTest<T[], string | ArrayItemValidatorResult<E>[]> {\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 const [validateItem, ...arrayTests] = allTests;\n\n const arrayInvalidResult = await findArrayInvalidResult(\n arrayTests,\n arrayValue,\n field,\n );\n const items = await validateItems(validateItem, arrayValue, field);\n\n if (!arrayInvalidResult && items.isValid) {\n return valid({\n value: arrayValue,\n field,\n });\n }\n\n return invalid<T[], ArrayItemValidatorResult<E>[]>({\n message: arrayInvalidResult ? arrayInvalidResult.message : '',\n value,\n field,\n errors: items.errors as ArrayItemValidatorResult<E>[],\n });\n };\n}\n","import {\n type ConfigBase,\n invalid,\n valid,\n type ValidatorFactory,\n type ValidatorMessage,\n type ValidatorMessageParameters,\n type ValidatorTest,\n} from './shared.js';\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>>(\n defaultConfig: C,\n applyConfig: (value: unknown, config: C) => T | null | undefined,\n): ValidatorFactory<C, T, string> {\n return (config, ...tests) => {\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 for (const validatorTest of allTests) {\n const result = await validatorTest(parsedValue, field);\n if (result.state === 'invalid') {\n return result;\n }\n }\n\n return await valid({ value: parsedValue, field });\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 = unknown,\n E = never,\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) => Omit<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","import { createTypeValidatorTest } from './factories.js';\nimport type { ConfigBase } from './shared.js';\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 (\n config.default !== undefined &&\n (parsedValue === undefined || parsedValue === null)\n ) {\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<boolean, BooleanConfig>(\n { parser: parseBoolean },\n applyBooleanConfig,\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 = '0', minute = '0'] = 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 return typeof value === 'string' ? parseIsoDate(value) : invalidDate;\n}\n\n/**\n * Parses an ISO 8601 string into a date. Without a timezone, the date is local.\n * @param value String to parse\n * @internal\n */\nfunction parseIsoDate(value: string): Date {\n const parts = isoDatePattern.exec(value);\n\n if (parts === null) {\n return invalidDate;\n }\n\n const [\n ,\n year = 0,\n month = 0,\n day = 0,\n hour = 0,\n minute = 0,\n second = 0,\n millisecond = 0,\n ] = dateParts.map((parse, index) => parse(parts[index]));\n\n const timezone = parts[8];\n\n if (!timezone) {\n return new Date(year, month, day, hour, minute, second, millisecond);\n }\n\n return new Date(\n Date.UTC(\n year,\n month,\n day,\n hour,\n minute + parseTimezone(timezone),\n second,\n millisecond,\n ),\n );\n}\n","import { createTypeValidatorTest, createValidatorTest } from './factories.js';\nimport type {\n ConfigBase,\n ValidatorMessage,\n ValidatorMessageParameters,\n ValidatorTest,\n} from './shared.js';\nimport { parseDate } from './parse-date.js';\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 (\n config.default !== undefined &&\n (parsedValue === undefined ||\n parsedValue === null ||\n Number.isNaN(parsedValue.getTime()))\n ) {\n parsedValue = config.default;\n }\n\n return parsedValue;\n}\n\nexport type SharedDateValueType = Date | string | number;\n\nexport interface MinDateValidatorMessageParameters extends ValidatorMessageParameters<Date> {\n min: Date | null | undefined;\n limit: Date | null | undefined;\n exclusive?: boolean | undefined;\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, never> {\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 extends ValidatorMessageParameters<Date> {\n max: Date | null | undefined;\n limit: Date | null | undefined;\n exclusive?: boolean | undefined;\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, never> {\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<Date, DateConfig>(\n { parser: parseDate },\n applyDateConfig,\n);\n","import { createTypeValidatorTest } from './factories.js';\nimport {\n type ConfigBase,\n invalid,\n valid,\n type ValidatorMessage,\n type ValidatorTest,\n} from './shared.js';\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 // oxlint-disable-next-line typescript/no-base-to-string -- tests pin the coercion of non-primitives until #579 rejects them in v3\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 (\n config.default !== undefined &&\n (parsedValue === undefined ||\n parsedValue === null ||\n Number.isNaN(parsedValue))\n ) {\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 }\n case 'ceil': {\n parsedValue = Math.ceil(parsedValue);\n break;\n }\n case 'floor': {\n parsedValue = Math.floor(parsedValue);\n break;\n }\n default: {\n throw new Error(`Unknown round type: ${String(config.round)}`);\n }\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, never> {\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<number, NumberConfig>(\n {\n parser: parseNumber,\n },\n applyNumberConfig,\n);\n","import {\n type ExtractError,\n type ExtractValue,\n hasOwnProperty,\n invalid,\n valid,\n type ValidatorTest,\n} from './shared.js';\n\nexport type ObjectParameter = Record<string, ValidatorTest>;\n\n/**\n * Validates an object.\n * @category Type Validators\n */\nexport function object<\n P extends ObjectParameter,\n V extends { [K in keyof P]?: ExtractValue<P[K]> },\n E extends { [K in keyof P]?: ExtractError<P[K]> },\n>(properties: P): ValidatorTest<V, E> {\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 errors = {} as E;\n const resolvedValues = {} as V;\n let isValid = true;\n\n for (const key in properties) {\n if (hasOwnProperty(properties, key)) {\n const validator = properties[key];\n // Object() boxes primitives and turns null and undefined into {}.\n const value: unknown = Reflect.get(Object(values), key);\n const result = await (typeof validator === 'function'\n ? validator(value, key)\n : invalid({ field: key, message: 'No validator set', value }));\n\n resolvedValues[key] = result.value as V[Extract<keyof P, string>];\n\n if (result.state === 'invalid') {\n isValid = false;\n errors[key] = (result.message || result.errors) as E[Extract<\n keyof P,\n string\n >];\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 { createValidatorTest } from './factories.js';\nimport type {\n ValidatorMessage,\n ValidatorMessageParameters,\n ValidatorTest,\n} from './shared.js';\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, never> {\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 interface OneOfValidatorMessageParameters<\n 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, never> {\n const allowed: readonly unknown[] = values;\n return createValidatorTest(\n (value) =>\n value === undefined ||\n value === null ||\n allowed.includes(value) ||\n (value instanceof Date &&\n values.some((x) => x.valueOf() === value.valueOf())),\n message,\n () => ({ values }),\n );\n}\n","import { createValidatorTest } from './factories.js';\nimport type {\n ValidatorMessage,\n ValidatorMessageParameters,\n ValidatorTest,\n} from './shared.js';\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 extends ValidatorMessageParameters<SharedValueType> {\n max: number;\n amount: number | null | undefined;\n limit: number;\n exclusive?: boolean | undefined;\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, never> {\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 extends ValidatorMessageParameters<SharedValueType> {\n min: number;\n limit: number;\n amount: number | null | undefined;\n exclusive?: boolean | undefined;\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, never> {\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 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, never> {\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","import { createTypeValidatorTest, createValidatorTest } from './factories.js';\nimport {\n type ConfigBase,\n isObject,\n type ValidatorMessage,\n type ValidatorMessageParameters,\n type ValidatorTest,\n} from './shared.js';\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 * RFC 9562 UUIDs: versions 1 to 8 with the RFC's variant (10xx), plus the nil\n * and max UUIDs.\n * @internal\n */\nconst uuidPattern =\n /^(?:[\\da-f]{8}-[\\da-f]{4}-[1-8][\\da-f]{3}-[89ab][\\da-f]{3}-[\\da-f]{12}|0{8}-0{4}-0{4}-0{4}-0{12}|f{8}-f{4}-f{4}-f{4}-f{12})$/i;\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 // oxlint-disable-next-line typescript/no-base-to-string -- only plain objects throw above; tests pin the coercion of other non-primitives until #579 rejects them in v3\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 (\n config.default !== undefined &&\n (parsedValue === undefined || parsedValue === null || parsedValue === '')\n ) {\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 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, never> {\n // A g or y pattern advances lastIndex on each test(), so a shared one would\n // fail matching values after a match. Test a private copy from index 0.\n const ownPattern = new RegExp(pattern);\n return createValidatorTest(\n (value) => {\n ownPattern.lastIndex = 0;\n return (\n value === undefined ||\n value === null ||\n value === '' ||\n (typeof value === 'string' && ownPattern.test(value))\n );\n },\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, never> {\n return matches(emailPattern, message);\n}\n\n/**\n * Ensures a string value is an RFC 9562 UUID, any version from 1 to 8, or the\n * nil or max UUID. Case-insensitive, without braces or a `urn:uuid:` prefix.\n * @param message Error message\n * @category Validation Tests\n */\nexport function uuid(\n message: ValidatorMessage<string>,\n): ValidatorTest<string, never> {\n return matches(uuidPattern, 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. Without it, `javascript:`\n * and `data:` URLs are valid; use `['http:', 'https:']` for values rendered as links.\n * @category Validation Tests\n */\nexport function url(\n message: ValidatorMessage<string>,\n protocols?: string[],\n): ValidatorTest<string, never> {\n return createValidatorTest(\n (value) => {\n try {\n let parsed: URL | undefined;\n if (\n value === undefined ||\n value === null ||\n value === '' ||\n (typeof value === 'string' && (parsed = new URL(value)))\n ) {\n return !(parsed && protocols && !protocols.includes(parsed.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<string, StringConfig>(\n {\n parser: parseString,\n },\n applyStringConfig,\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["items","invalidDetail","result","isObject","value","hasOwnProperty","object","property","isIterable","formatPattern","formatMessage","template","parameters","key","valid","validResult","invalid","invalidResult","message","extras","parseArray","applyArrayConfig","parsedValue","config","findArrayInvalidResult","validatorTest","tests","arrayValue","field","validateItems","isValid","errors","validateItem","values","index","item","array","allTests","finalConfig","arrayTests","arrayInvalidResult","items","syncTests","createTypeValidatorTest","defaultConfig","applyConfig","syncTest","error","createValidatorTest","test","getExtras","parseBoolean","applyBooleanConfig","boolean","invalidDate","isoDatePattern","timezonePattern","parseTimezone","parts","timezone","sign","hour","minute","dateParts","part","parseDate","parseIsoDate","year","month","day","second","millisecond","parse","applyDateConfig","minDate","parsedDate","limit","exclusive","maxDate","date","primitiveValueOfs","unboxPrimitive","valueOf","primitiveToString","primitive","parseNumber","text","parsed","applyNumberConfig","integer","number","check","args","path","keys","inner","setOwn","target","findInvalidResult","objectTest","properties","source","resolvedValues","validator","objectInvalidResult","fallbackMessage","collectIssues","issues","standard","required","nullable","oneOf","allowed","x","getAmount","max","amount","min","exact","emailPattern","uuidPattern","parseString","applyStringConfig","matches","ownPattern","pattern","email","uuid","url","protocols","string"],"sources":["../src/invalid-detail.ts","../src/shared.ts","../src/arrays.ts","../src/factories.ts","../src/booleans.ts","../src/parse-date.ts","../src/dates.ts","../src/primitives.ts","../src/numbers.ts","../src/check.ts","../src/objects.ts","../src/standard.ts","../src/common.ts","../src/limits.ts","../src/strings.ts"],"sourcesContent":["import type { InvalidResult } from './shared.js';\n\n/**\n * The error that `array()` and `object()` record for a failed item or field:\n * its message, or its `errors` when the message is empty. With neither, the\n * empty message, so the failure never reads as `undefined`.\n * @param result Failed result\n * @internal\n */\nexport function invalidDetail<E>(result: InvalidResult<E>): string | E {\n return result.message || result.errors === undefined\n ? result.message\n : result.errors;\n}\n","export type ValidResult<T> = {\n /** `valid` if the value passed every validation test. */\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 | undefined;\n};\n\nexport type InvalidResult<E> = {\n /** `invalid` if the value failed a validation test. */\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 | undefined;\n /** Extra error details */\n errors?: E | undefined;\n};\n\n/**\n * The result of a validation.\n * @typeParam T The value type\n * @category Types\n */\nexport type ValidatorResult<T = unknown, E = unknown> =\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 = unknown, E = unknown> = (\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> =\n T extends ValidatorTest<unknown, infer E> ? E : 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> =\n T extends ValidatorTest<infer V> ? V : 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<unknown, E>,\n ...tests: ValidatorTest<unknown, E>[]\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 object Object to check\n * @param property 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/**\n * Checks for a truthy `Symbol.iterator` property, boxing primitives so strings\n * count as iterable.\n * @internal\n */\nexport function isIterable(value: unknown): value is Iterable<unknown> {\n return Boolean(Reflect.get(Object(value), Symbol.iterator));\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 parameters 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.replaceAll(formatPattern, (_, key: string) =>\n String(Reflect.get(parameters, key)),\n );\n }\n\n return template(parameters);\n}\n\n/**\n * Creates a valid result\n * @param result Result fields\n * @param result.value Parsed value\n * @param result.field Field name\n * @category Helpers\n */\nexport async function valid<T, E = never>(result: {\n value: T | null | undefined;\n field: string | undefined;\n}): Promise<ValidatorResult<T, E>> {\n return validResult(result);\n}\n\n/**\n * Creates a valid result synchronously, for `valid` and the built-in tests'\n * synchronous twins.\n * @internal\n */\nexport function validResult<T, E = never>({\n value,\n field,\n}: {\n value: T | null | undefined;\n field: string | undefined;\n}): ValidatorResult<T, E> {\n return {\n state: 'valid',\n value,\n field,\n };\n}\n\n/**\n * Creates an invalid result.\n * @param result Result fields\n * @param result.message Error message, formatted with `formatMessage`\n * @param result.value Parsed value\n * @param result.field Field name\n * @param result.errors Extra error details, such as per-field errors from `object` and `array`\n * @param result.extras Extra message params\n * @category Helpers\n */\nexport async function invalid<\n T,\n E = never,\n P extends ValidatorMessageParameters<T> = ValidatorMessageParameters<T>,\n>(result: {\n message: ValidatorMessage<T, P>;\n value: unknown;\n field: string | undefined;\n errors?: E | undefined;\n extras?: Omit<P, 'field' | 'value'> | undefined;\n}): Promise<ValidatorResult<T, E>> {\n return invalidResult(result);\n}\n\n/**\n * Creates an invalid result synchronously, for `invalid` and the built-in\n * tests' synchronous twins.\n * @internal\n */\nexport function invalidResult<\n T,\n E,\n P extends ValidatorMessageParameters<T> = ValidatorMessageParameters<T>,\n>({\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 | undefined;\n extras?: Omit<P, 'field' | 'value'> | undefined;\n}): ValidatorResult<T, E> {\n return {\n state: 'invalid',\n message: formatMessage(message, { ...extras, value, field } as P),\n value,\n field,\n errors,\n };\n}\n","import { invalidDetail } from './invalid-detail.js';\nimport {\n invalid,\n isIterable,\n valid,\n type ConfigBase,\n type ValidatorTest,\n} from './shared.js';\n\n/**\n * Invalid validation result for an item in the array\n * @category Types\n */\nexport type ArrayItemValidatorResult<E = unknown> = null | string | E;\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 const items: unknown[] = value;\n return items;\n }\n\n if (value === null || value === undefined) {\n return value;\n }\n\n if (isIterable(value)) {\n return [...value];\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(\n config: ArrayConfig,\n value: unknown,\n): unknown[] | null | undefined {\n let parsedValue = config.parser(value);\n if (\n config.default !== undefined &&\n (parsedValue === undefined ||\n parsedValue === null ||\n parsedValue.length === 0)\n ) {\n parsedValue = config.default;\n }\n\n return parsedValue;\n}\n\n/**\n * Runs the tests that target the array itself, stopping at the first failure.\n * @param tests Array-level tests\n * @param arrayValue Parsed array\n * @param field Field name\n * @internal\n */\nasync function findArrayInvalidResult(\n tests: ValidatorTest[],\n arrayValue: unknown[] | null | undefined,\n field: string | undefined,\n) {\n for (const validatorTest of tests) {\n const result = await validatorTest(arrayValue, field);\n if (result.state === 'invalid') {\n return result;\n }\n }\n\n return undefined;\n}\n\n/**\n * Runs the item test on every item, collecting each item's parsed value, and\n * `null` for valid items and the message or errors for invalid ones. Without\n * an array or an item test, there is nothing to check, and the values are the\n * array as given.\n * @param validateItem Item test\n * @param arrayValue Parsed array\n * @param field Field name\n * @internal\n */\nasync function validateItems(\n validateItem: ValidatorTest | undefined,\n arrayValue: unknown[] | null | undefined,\n field: string | undefined,\n) {\n let isValid = true;\n const errors: ArrayItemValidatorResult[] = [];\n\n if (!arrayValue || !validateItem) {\n return { isValid, errors, values: arrayValue };\n }\n\n const values: unknown[] = [];\n\n for (const [index, item] of arrayValue.entries()) {\n const result = await validateItem(item, `${field || ''}[${index}]`);\n values.push(result.value);\n\n if (result.state === 'invalid') {\n isValid = false;\n errors.push(invalidDetail(result));\n } else {\n errors.push(null);\n }\n }\n\n return { isValid, errors, values };\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, E>(\n config?: Partial<ArrayConfig> | ValidatorTest<T, E>,\n ...tests: ValidatorTest[]\n): ValidatorTest<T[], string | ArrayItemValidatorResult<E>[]> {\n const allTests = typeof config === 'function' ? [config, ...tests] : tests;\n const finalConfig: ArrayConfig = {\n parser: parseArray,\n ...(typeof config === 'function' ? undefined : config),\n };\n\n return async (value, field) => {\n const arrayValue = applyArrayConfig(finalConfig, value);\n const [validateItem, ...arrayTests] = allTests;\n\n const arrayInvalidResult = await findArrayInvalidResult(\n arrayTests,\n arrayValue,\n field,\n );\n const items = await validateItems(validateItem, arrayValue, field);\n\n if (!arrayInvalidResult && items.isValid) {\n return valid({\n value: items.values as T[] | null | undefined,\n field,\n });\n }\n\n return invalid<T[], ArrayItemValidatorResult<E>[]>({\n message: arrayInvalidResult ? arrayInvalidResult.message : '',\n value,\n field,\n errors: items.errors as ArrayItemValidatorResult<E>[],\n });\n };\n}\n","import {\n type ConfigBase,\n invalid,\n invalidResult,\n validResult,\n type ValidatorFactory,\n type ValidatorMessage,\n type ValidatorMessageParameters,\n type ValidatorResult,\n type ValidatorTest,\n} from './shared.js';\n\n/**\n * Synchronous twins of the tests `createValidatorTest` makes. A type validator\n * runs a test's twin when it has one, which skips the promise and await around\n * every built-in test (#523). The tests themselves stay async.\n * @internal\n */\nconst syncTests = new WeakMap<\n ValidatorTest,\n // The twins never set errors, so their error type is never.\n (value: unknown, field: string | undefined) => ValidatorResult<unknown, never>\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>>(\n // NoInfer makes TypeScript infer C from applyConfig's config parameter, so C\n // keeps the options that defaultConfig leaves out. Needs TypeScript 5.4.\n defaultConfig: NoInfer<C>,\n applyConfig: (value: unknown, config: C) => T | null | undefined,\n): ValidatorFactory<C, T, string> {\n return (config, ...tests) => {\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 for (const validatorTest of allTests) {\n const syncTest = syncTests.get(validatorTest);\n // Not a ternary: @vitest/coverage-v8 5 gives the branch after an\n // await in a ternary arm a negative count.\n let result: ValidatorResult<unknown, string>;\n if (syncTest) {\n result = syncTest(parsedValue, field);\n } else {\n result = await validatorTest(parsedValue, field);\n }\n if (result.state === 'invalid') {\n return result;\n }\n }\n\n return validResult({ value: parsedValue, field });\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 = unknown,\n E = never,\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) => Omit<P, 'value' | 'field'>,\n): ValidatorTest<T, E> {\n const syncTest = (\n value: unknown,\n field: string | undefined,\n ): ValidatorResult<T, never> => {\n if (test(value, field)) {\n return validResult({ value: value as T, field });\n }\n\n return invalidResult({\n message,\n value,\n field,\n extras: getExtras ? getExtras(value as T) : undefined,\n });\n };\n const validatorTest: ValidatorTest<T, E> = async (value, field) =>\n syncTest(value, field);\n syncTests.set(validatorTest, syncTest);\n\n return validatorTest;\n}\n","import { createTypeValidatorTest } from './factories.js';\nimport type { ConfigBase } from './shared.js';\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 (\n config.default !== undefined &&\n (parsedValue === undefined || parsedValue === null)\n ) {\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","/** 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 // The pattern's groups aren't optional, so a match always has the sign,\n // hour, and minute.\n const [, sign, hour, minute] = parts;\n const multiplier = sign === '-' ? -1 : 1;\n const offset = Number(hour) * 60 + Number(minute);\n\n return multiplier * offset;\n}\n\nconst BASE = 10;\n\nconst dateParts = [\n // Skip\n () => 0,\n // Year, which the date pattern always captures\n (part?: string) => Number(part),\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 return typeof value === 'string' ? parseIsoDate(value) : invalidDate;\n}\n\n/**\n * Parses an ISO 8601 string into a date. Without a timezone, the date is local.\n * @param value String to parse\n * @internal\n */\nfunction parseIsoDate(value: string): Date {\n const parts = isoDatePattern.exec(value);\n\n if (parts === null) {\n return invalidDate;\n }\n\n const [\n ,\n year = 0,\n month = 0,\n day = 0,\n hour = 0,\n minute = 0,\n second = 0,\n millisecond = 0,\n ] = dateParts.map((parse, index) => parse(parts[index]));\n\n const timezone = parts[8];\n\n if (!timezone) {\n return new Date(year, month, day, hour, minute, second, millisecond);\n }\n\n return new Date(\n Date.UTC(\n year,\n month,\n day,\n hour,\n minute + parseTimezone(timezone),\n second,\n millisecond,\n ),\n );\n}\n","import { createTypeValidatorTest, createValidatorTest } from './factories.js';\nimport type {\n ConfigBase,\n ValidatorMessage,\n ValidatorMessageParameters,\n ValidatorTest,\n} from './shared.js';\nimport { parseDate } from './parse-date.js';\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 (\n config.default !== undefined &&\n (parsedValue === undefined ||\n parsedValue === null ||\n Number.isNaN(parsedValue.getTime()))\n ) {\n parsedValue = config.default;\n }\n\n return parsedValue;\n}\n\nexport type SharedDateValueType = Date | string | number;\n\nexport interface MinDateValidatorMessageParameters extends ValidatorMessageParameters<Date> {\n min: Date | null | undefined;\n limit: Date | null | undefined;\n exclusive?: boolean | undefined;\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, never> {\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 extends ValidatorMessageParameters<Date> {\n max: Date | null | undefined;\n limit: Date | null | undefined;\n exclusive?: boolean | undefined;\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, never> {\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","/** @internal */\nconst primitiveValueOfs = [\n (value: object) => String.prototype.valueOf.call(value),\n (value: object) => Number.prototype.valueOf.call(value),\n (value: object) => Boolean.prototype.valueOf.call(value),\n];\n\n/**\n * Returns the primitive inside a `String`, `Number`, or `Boolean` object, and\n * any other value as it is.\n * @param value Value to unbox\n */\nfunction unboxPrimitive(value: unknown): unknown {\n if (typeof value !== 'object' || value === null) {\n return value;\n }\n\n // Each valueOf throws unless `this` is its own wrapper type, from any realm,\n // which `instanceof` can't tell.\n for (const valueOf of primitiveValueOfs) {\n try {\n return valueOf(value);\n } catch {\n // Not this wrapper type.\n }\n }\n\n return value;\n}\n\n/**\n * Converts a string, number, bigint, or boolean, or an object wrapping one, to\n * a string.\n * @param value Value to convert\n * @returns The string, or `undefined` for any other value\n */\nexport function primitiveToString(value: unknown): string | undefined {\n const primitive = unboxPrimitive(value);\n switch (typeof primitive) {\n case 'string':\n case 'number':\n case 'bigint':\n case 'boolean': {\n return String(primitive);\n }\n default: {\n return undefined;\n }\n }\n}\n","import { createTypeValidatorTest } from './factories.js';\nimport { primitiveToString } from './primitives.js';\nimport {\n type ConfigBase,\n invalid,\n valid,\n type ValidatorMessage,\n type ValidatorTest,\n} from './shared.js';\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 const text = primitiveToString(value);\n const parsed = text === undefined ? Number.NaN : Number.parseFloat(text);\n // Blank input stays empty, as NaN, for `required` and `default` to handle.\n if (Number.isNaN(parsed) && (text === undefined || text.trim() !== '')) {\n throw new TypeError('Failed to parse value to number.');\n }\n\n return parsed;\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 (\n config.default !== undefined &&\n (parsedValue === undefined ||\n parsedValue === null ||\n Number.isNaN(parsedValue))\n ) {\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 }\n case 'ceil': {\n parsedValue = Math.ceil(parsedValue);\n break;\n }\n case 'floor': {\n parsedValue = Math.floor(parsedValue);\n break;\n }\n default: {\n throw new Error(`Unknown round type: ${String(config.round)}`);\n }\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, never> {\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 formatMessage,\n invalid,\n valid,\n type ValidatorMessage,\n type ValidatorTest,\n} from './shared.js';\n\n/**\n * An object-level test for `object()`. It fails when `test` returns false for\n * the parsed object. The message goes to the error at `path`, a property name\n * or a list of names into nested objects, or to the object's own message\n * without a path. The message gets the parsed object as `value` and the\n * object's `field`.\n * @category Validation Tests\n */\nexport function check<T, E = never>(\n test: (value: T) => boolean,\n message: ValidatorMessage<T>,\n): ValidatorTest<T, E>;\nexport function check<T, E = never>(\n path: string | readonly string[],\n test: (value: T) => boolean,\n message: ValidatorMessage<T>,\n): ValidatorTest<T, E>;\nexport function check<T, E = never>(\n ...args:\n | [test: (value: T) => boolean, message: ValidatorMessage<T>]\n | [\n path: string | readonly string[],\n test: (value: T) => boolean,\n message: ValidatorMessage<T>,\n ]\n): ValidatorTest<T, E> {\n const [path, test, message] = args.length === 2 ? [[], ...args] : args;\n const keys = typeof path === 'string' ? [path] : path;\n\n return async (value, field) => {\n const parsed = value as T;\n if (test(parsed)) {\n return valid({ value: parsed, field });\n }\n\n if (keys.length === 0) {\n return invalid({ message, value: parsed, field });\n }\n\n // Computed keys define own properties, so a `__proto__` key stays one.\n const errors = keys.reduceRight<unknown>(\n (inner, key) => ({ [key]: inner }),\n formatMessage(message, { value: parsed, field }),\n );\n return invalid({ message: '', value: parsed, field, errors: errors as E });\n };\n}\n","import { invalidDetail } from './invalid-detail.js';\nimport {\n type ExtractError,\n type ExtractValue,\n hasOwnProperty,\n invalid,\n valid,\n type ValidatorTest,\n} from './shared.js';\n\nexport type ObjectParameter = Record<string, ValidatorTest>;\n\n/** @internal */\ntype ObjectValue<P extends ObjectParameter> = {\n // A field's validator passes null through unless a test rejects it.\n [K in keyof P]?: ExtractValue<P[K]> | null;\n};\n\n/** @internal */\ntype ObjectErrors<P extends ObjectParameter> = {\n [K in keyof P]?: ExtractError<P[K]>;\n};\n\n/**\n * Sets an own property. Plain assignment of `__proto__` calls the\n * `Object.prototype.__proto__` setter instead of creating the property.\n * @internal\n */\nfunction setOwn(target: object, key: string, value: unknown) {\n Object.defineProperty(target, key, {\n value,\n enumerable: true,\n writable: true,\n configurable: true,\n });\n}\n\n/**\n * Runs the object-level tests on the parsed object, stopping at the first\n * failure.\n * @param tests Object-level tests\n * @param value Parsed object\n * @param field Field name\n * @internal\n */\nasync function findInvalidResult<V, E>(\n tests: ValidatorTest<V, E>[],\n value: V,\n field: string | undefined,\n) {\n for (const objectTest of tests) {\n const result = await objectTest(value, field);\n if (result.state === 'invalid') {\n return result;\n }\n }\n\n return undefined;\n}\n\n/**\n * Validates an object. The remaining `tests` run on the parsed object, in\n * order, once every property is valid, and the first failure is the result.\n * @category Type Validators\n */\nexport function object<\n P extends ObjectParameter,\n V extends ObjectValue<P>,\n E extends ObjectErrors<P>,\n>(\n properties: P,\n // Typed from P rather than V and E, so the tests don't take part in\n // inferring V and E.\n ...tests: ValidatorTest<ObjectValue<P>, ObjectErrors<P>>[]\n): ValidatorTest<V, E> {\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 // Object() boxes primitives and turns null and undefined into {}.\n const source: object = Object(values);\n const errors = {} as E;\n const resolvedValues = {} as V;\n let isValid = true;\n\n for (const key in properties) {\n if (hasOwnProperty(properties, key)) {\n const validator = properties[key];\n // Only own properties, so a missing key named like an inherited one,\n // such as `constructor`, reads as missing.\n const value: unknown = hasOwnProperty(source, key)\n ? Reflect.get(source, key)\n : undefined;\n const result = await (typeof validator === 'function'\n ? validator(value, key)\n : invalid({ field: key, message: 'No validator set', value }));\n\n setOwn(resolvedValues, key, result.value);\n\n if (result.state === 'invalid') {\n isValid = false;\n setOwn(errors, key, invalidDetail(result));\n }\n }\n }\n\n if (!isValid) {\n return invalid({ message: '', value: values, field, errors });\n }\n\n const objectInvalidResult = await findInvalidResult(\n tests,\n resolvedValues,\n field,\n );\n if (objectInvalidResult) {\n return invalid({\n message: objectInvalidResult.message,\n value: values,\n field,\n errors: objectInvalidResult.errors as E,\n });\n }\n\n return valid({ value: resolvedValues, field });\n };\n}\n","import type { ValidatorTest } from './shared.js';\nimport type { StandardSchemaV1 } from './standard-schema.js';\n\n/** @internal */\nconst fallbackMessage = 'Invalid value.';\n\n/**\n * Turns the `errors` of an invalid result into issues: object keys and array\n * indexes become path segments, and each string becomes an issue. `null` marks\n * a valid array item. An empty string, which v3 records for a failure without\n * a message, and any other value get a fallback message.\n * @internal\n */\nfunction collectIssues(\n errors: unknown,\n path: PropertyKey[],\n issues: StandardSchemaV1.Issue[],\n) {\n if (typeof errors === 'string') {\n issues.push({ message: errors || fallbackMessage, path });\n } else if (Array.isArray(errors)) {\n for (const [index, item] of errors.entries()) {\n if (item !== null) {\n collectIssues(item, [...path, index], issues);\n }\n }\n } else if (typeof errors === 'object' && errors !== null) {\n // Object.keys rather than Object.entries, which would add an ES2017\n // built-in to the supported environments list.\n for (const key of Object.keys(errors)) {\n collectIssues(Reflect.get(errors, key), [...path, key], issues);\n }\n } else {\n issues.push({ message: fallbackMessage, path });\n }\n}\n\n/**\n * Adds the Standard Schema interface (https://standardschema.dev) to a\n * validator, so libraries that accept any Standard Schema can use it. Returns a\n * new validator; the one passed in is unchanged. `validate` always returns a\n * promise, since every validator here is async.\n * @category Helpers\n */\nexport function standard<T, E>(\n validator: ValidatorTest<T, E>,\n): ValidatorTest<T, E> & StandardSchemaV1<unknown, T | null | undefined> {\n const validate = async (\n value: unknown,\n ): Promise<StandardSchemaV1.Result<T | null | undefined>> => {\n const result = await validator(value);\n if (result.state === 'valid') {\n return { value: result.value };\n }\n\n const issues: StandardSchemaV1.Issue[] = result.message\n ? [{ message: result.message }]\n : [];\n if (result.errors !== undefined) {\n collectIssues(result.errors, [], issues);\n }\n\n return {\n issues: issues.length > 0 ? issues : [{ message: fallbackMessage }],\n };\n };\n\n return Object.assign(\n (value?: unknown, field?: string) => validator(value, field),\n {\n '~standard': { version: 1, vendor: 'validator-fns', validate } as const,\n },\n );\n}\n","import { createValidatorTest } from './factories.js';\nimport type {\n ValidatorMessage,\n ValidatorMessageParameters,\n ValidatorTest,\n} from './shared.js';\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, never> {\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 interface OneOfValidatorMessageParameters<\n 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, never> {\n const allowed: readonly unknown[] = values;\n return createValidatorTest(\n (value) =>\n value === undefined ||\n value === null ||\n allowed.includes(value) ||\n (value instanceof Date &&\n values.some((x) => x.valueOf() === value.valueOf())),\n message,\n () => ({ values }),\n );\n}\n","import { createValidatorTest } from './factories.js';\nimport type {\n ValidatorMessage,\n ValidatorMessageParameters,\n ValidatorTest,\n} from './shared.js';\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 extends ValidatorMessageParameters<SharedValueType> {\n max: number;\n amount: number | null | undefined;\n limit: number;\n exclusive?: boolean | undefined;\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, never> {\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 extends ValidatorMessageParameters<SharedValueType> {\n min: number;\n limit: number;\n amount: number | null | undefined;\n exclusive?: boolean | undefined;\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, never> {\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 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, never> {\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","import { createTypeValidatorTest, createValidatorTest } from './factories.js';\nimport { primitiveToString } from './primitives.js';\nimport {\n type ConfigBase,\n type ValidatorMessage,\n type ValidatorMessageParameters,\n type ValidatorTest,\n} from './shared.js';\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 * RFC 9562 UUIDs: versions 1 to 8 with the RFC's variant (10xx), plus the nil\n * and max UUIDs.\n * @internal\n */\nconst uuidPattern =\n /^(?:[\\da-f]{8}-[\\da-f]{4}-[1-8][\\da-f]{3}-[89ab][\\da-f]{3}-[\\da-f]{12}|0{8}-0{4}-0{4}-0{4}-0{12}|f{8}-f{4}-f{4}-f{4}-f{12})$/i;\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 const parsed = primitiveToString(value);\n if (parsed === undefined) {\n throw new TypeError('Failed to parse value to string.');\n }\n\n return parsed;\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 (\n config.default !== undefined &&\n (parsedValue === undefined || parsedValue === null || parsedValue === '')\n ) {\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 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, never> {\n // A g or y pattern advances lastIndex on each test(), so a shared one would\n // fail matching values after a match. Test a private copy from index 0.\n const ownPattern = new RegExp(pattern);\n return createValidatorTest(\n (value) => {\n ownPattern.lastIndex = 0;\n return (\n value === undefined ||\n value === null ||\n value === '' ||\n (typeof value === 'string' && ownPattern.test(value))\n );\n },\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, never> {\n return matches(emailPattern, message);\n}\n\n/**\n * Ensures a string value is an RFC 9562 UUID, any version from 1 to 8, or the\n * nil or max UUID. Case-insensitive, without braces or a `urn:uuid:` prefix.\n * @param message Error message\n * @category Validation Tests\n */\nexport function uuid(\n message: ValidatorMessage<string>,\n): ValidatorTest<string, never> {\n return matches(uuidPattern, message);\n}\n\n/**\n * Ensures a string value is a valid URL\n * @param message Error message\n * @param protocols Protocols to allow. Defaults to `['http:', 'https:']`; a list\n * replaces the default.\n * @category Validation Tests\n */\nexport function url(\n message: ValidatorMessage<string>,\n protocols: string[] = ['http:', 'https:'],\n): ValidatorTest<string, never> {\n return createValidatorTest(\n (value) => {\n try {\n let parsed: URL | undefined;\n if (\n value === undefined ||\n value === null ||\n value === '' ||\n (typeof value === 'string' && (parsed = new URL(value)))\n ) {\n return !parsed || protocols.includes(parsed.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"],"mappings":"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"}