valleyed 4.4.9 → 4.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +71 -0
- package/README.md +253 -179
- package/lib/api/arrays.d.ts +4 -8
- package/lib/api/arrays.js +55 -43
- package/lib/api/arrays.js.map +1 -1
- package/lib/api/base/errors.d.ts +19 -0
- package/lib/api/base/errors.js +38 -0
- package/lib/api/base/errors.js.map +1 -0
- package/lib/api/base/index.d.ts +3 -0
- package/lib/api/base/index.js +20 -0
- package/lib/api/base/index.js.map +1 -0
- package/lib/api/base/pipes.d.ts +9 -0
- package/lib/api/base/pipes.js +90 -0
- package/lib/api/base/pipes.js.map +1 -0
- package/lib/api/base/types.d.ts +48 -0
- package/lib/api/base/types.js +3 -0
- package/lib/api/base/types.js.map +1 -0
- package/lib/api/coerce.d.ts +4 -0
- package/lib/api/coerce.js +15 -0
- package/lib/api/coerce.js.map +1 -0
- package/lib/api/core.d.ts +17 -18
- package/lib/api/core.js +67 -46
- package/lib/api/core.js.map +1 -1
- package/lib/{rules/index.d.ts → api/externals.d.ts} +8 -6
- package/lib/{rules/index.js → api/externals.js} +11 -7
- package/lib/api/externals.js.map +1 -0
- package/lib/api/files.d.ts +7 -7
- package/lib/api/files.js +36 -18
- package/lib/api/files.js.map +1 -1
- package/lib/api/index.d.ts +1 -40
- package/lib/api/index.js +35 -43
- package/lib/api/index.js.map +1 -1
- package/lib/api/junctions.d.ts +6 -11
- package/lib/api/junctions.js +58 -50
- package/lib/api/junctions.js.map +1 -1
- package/lib/api/numbers.d.ts +7 -10
- package/lib/api/numbers.js +39 -28
- package/lib/api/numbers.js.map +1 -1
- package/lib/api/optionals.d.ts +11 -0
- package/lib/api/optionals.js +52 -0
- package/lib/api/optionals.js.map +1 -0
- package/lib/api/records.d.ts +13 -7
- package/lib/api/records.js +99 -45
- package/lib/api/records.js.map +1 -1
- package/lib/api/strings.d.ts +10 -15
- package/lib/api/strings.js +70 -44
- package/lib/api/strings.js.map +1 -1
- package/lib/api/times.d.ts +7 -11
- package/lib/api/times.js +31 -24
- package/lib/api/times.js.map +1 -1
- package/lib/api/types.d.ts +8 -0
- package/lib/api/types.js +45 -0
- package/lib/api/types.js.map +1 -0
- package/lib/index.d.ts +4 -6
- package/lib/index.js +27 -8
- package/lib/index.js.map +1 -1
- package/lib/utils/classes.d.ts +9 -10
- package/lib/utils/classes.js +21 -28
- package/lib/utils/classes.js.map +1 -1
- package/lib/utils/differ.d.ts +4 -6
- package/lib/utils/differ.js +109 -92
- package/lib/utils/differ.js.map +1 -1
- package/lib/utils/functions/index.d.ts +2 -0
- package/lib/utils/functions/index.js +6 -2
- package/lib/utils/functions/index.js.map +1 -1
- package/lib/utils/functions/urls/normalize.js.map +1 -1
- package/lib/utils/geohash.d.ts +12 -15
- package/lib/utils/geohash.js +80 -91
- package/lib/utils/geohash.js.map +1 -1
- package/lib/utils/types.d.ts +66 -9
- package/package.json +2 -1
- package/lib/api/base.d.ts +0 -33
- package/lib/api/base.js +0 -99
- package/lib/api/base.js.map +0 -1
- package/lib/api/booleans.d.ts +0 -4
- package/lib/api/booleans.js +0 -13
- package/lib/api/booleans.js.map +0 -1
- package/lib/api/objects.d.ts +0 -16
- package/lib/api/objects.js +0 -46
- package/lib/api/objects.js.map +0 -1
- package/lib/api/tuples.d.ts +0 -13
- package/lib/api/tuples.js +0 -26
- package/lib/api/tuples.js.map +0 -1
- package/lib/rules/arrays.d.ts +0 -5
- package/lib/rules/arrays.js +0 -55
- package/lib/rules/arrays.js.map +0 -1
- package/lib/rules/custom.d.ts +0 -1
- package/lib/rules/custom.js +0 -10
- package/lib/rules/custom.js.map +0 -1
- package/lib/rules/equality.d.ts +0 -4
- package/lib/rules/equality.js +0 -42
- package/lib/rules/equality.js.map +0 -1
- package/lib/rules/files.d.ts +0 -9
- package/lib/rules/files.js +0 -41
- package/lib/rules/files.js.map +0 -1
- package/lib/rules/index.js.map +0 -1
- package/lib/rules/mimes.json +0 -3158
- package/lib/rules/numbers.d.ts +0 -6
- package/lib/rules/numbers.js +0 -65
- package/lib/rules/numbers.js.map +0 -1
- package/lib/rules/records.d.ts +0 -2
- package/lib/rules/records.js +0 -26
- package/lib/rules/records.js.map +0 -1
- package/lib/rules/strings.d.ts +0 -6
- package/lib/rules/strings.js +0 -66
- package/lib/rules/strings.js.map +0 -1
- package/lib/rules/times.d.ts +0 -4
- package/lib/rules/times.js +0 -42
- package/lib/rules/times.js.map +0 -1
- package/lib/rules/tuples.d.ts +0 -7
- package/lib/rules/tuples.js +0 -19
- package/lib/rules/tuples.js.map +0 -1
- package/lib/rules/types.d.ts +0 -4
- package/lib/rules/types.js +0 -36
- package/lib/rules/types.js.map +0 -1
- package/lib/utils/rules.d.ts +0 -23
- package/lib/utils/rules.js +0 -40
- package/lib/utils/rules.js.map +0 -1
- package/lib/validators/index.d.ts +0 -5
- package/lib/validators/index.js +0 -40
- package/lib/validators/index.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,77 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [4.5.0](https://github.com/kevinand11/valleyed/compare/v4.4.10...v4.5.0) (2025-06-23)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* accept multiple pipes in .pipe ([7a6ebb2](https://github.com/kevinand11/valleyed/commit/7a6ebb2987449df7092eee26e5293cd3fe71e460))
|
|
11
|
+
* add __update function to allow update after init ([88a2f93](https://github.com/kevinand11/valleyed/commit/88a2f93c5d0403f443678db7ac3e4b17d7588013))
|
|
12
|
+
* add id for json schema ([7499fe5](https://github.com/kevinand11/valleyed/commit/7499fe5fa6305c1c6dcbd679863ae7ff1a6f30b2))
|
|
13
|
+
* allow value functions for all validators that expect a value input ([99276e7](https://github.com/kevinand11/valleyed/commit/99276e79bec45af2ea089474eafe85c01b78279c))
|
|
14
|
+
* better PipeError ([96817b6](https://github.com/kevinand11/valleyed/commit/96817b6c96454cbe8ea3b29ce63ad07b46b67cd3))
|
|
15
|
+
* bubble up config ([b24b8ee](https://github.com/kevinand11/valleyed/commit/b24b8eeb7161a3b9c26c41d2dc4be0ff0d284f6e))
|
|
16
|
+
* coerce and function ([dcd4dc7](https://github.com/kevinand11/valleyed/commit/dcd4dc7a4009ac6e41fdcd8da258d86644c50555))
|
|
17
|
+
* context ([d206e80](https://github.com/kevinand11/valleyed/commit/d206e80d43c5ddcc32504155c8e08cce32c12a92))
|
|
18
|
+
* defaultOnFail sanitizer ([70cbb85](https://github.com/kevinand11/valleyed/commit/70cbb85e26b3f5b39169a43e78586897c1d067f4))
|
|
19
|
+
* files and records pipe apis ([e9cca15](https://github.com/kevinand11/valleyed/commit/e9cca156067ec430b9a805a8b7bf5322247b1d91))
|
|
20
|
+
* forward PipeError cause ([8507e4e](https://github.com/kevinand11/valleyed/commit/8507e4ec1a02b5077c6bf9c71b22e76024cf27a4))
|
|
21
|
+
* fromJson pipe ([df1eafe](https://github.com/kevinand11/valleyed/commit/df1eafe90d739b63c900afdb24e85f293751944e))
|
|
22
|
+
* generate json schema ([848ed78](https://github.com/kevinand11/valleyed/commit/848ed787c795b92879bec7fe8be59be5af8a3110))
|
|
23
|
+
* isType supports any ([8584398](https://github.com/kevinand11/valleyed/commit/858439840f75bc4ebbbb009b0124fbbbeb480c02))
|
|
24
|
+
* merge pipe ([005acb0](https://github.com/kevinand11/valleyed/commit/005acb01501cd5dd630f9c5ccefe7033206102ca))
|
|
25
|
+
* meta on schema ([620143c](https://github.com/kevinand11/valleyed/commit/620143c80033205fe23206066d2a97a953a26c15))
|
|
26
|
+
* more primitives ([f15ce01](https://github.com/kevinand11/valleyed/commit/f15ce0143cb21d2161050a7060ab4dd4367d292f))
|
|
27
|
+
* new type ConditionalObjectKeys ([6829317](https://github.com/kevinand11/valleyed/commit/6829317c42bcf0dcec4f8614adf49171f369b573))
|
|
28
|
+
* numbers pipe api ([9d1a5ab](https://github.com/kevinand11/valleyed/commit/9d1a5ab1a7709fc025d74c58ef5142744f48228d))
|
|
29
|
+
* object extends ([129f32d](https://github.com/kevinand11/valleyed/commit/129f32de7dfe4f553251008ac4b2ffba95e75fd4))
|
|
30
|
+
* objectExtends, objectPick and objectOmit ([6a89dc3](https://github.com/kevinand11/valleyed/commit/6a89dc367a3cb89bd579d600b282b677d395a7d8))
|
|
31
|
+
* objectMerge ([2117fae](https://github.com/kevinand11/valleyed/commit/2117fae7dc2fde1e553657d7f5f47c72de58c038))
|
|
32
|
+
* optionals api ([29a6fdc](https://github.com/kevinand11/valleyed/commit/29a6fdc878fbc0075a6ac285a09706ac075f7b40))
|
|
33
|
+
* pipe api with primitives, junctions, core and arrays ([e9d2a69](https://github.com/kevinand11/valleyed/commit/e9d2a693b655016bd8c3caaaa15b1ae19a3e7954))
|
|
34
|
+
* pipe node and gather when needed ([dc364b2](https://github.com/kevinand11/valleyed/commit/dc364b21992534cc31a107c93afb59d61cba07df))
|
|
35
|
+
* refactor entire src for treeshaking ([254988d](https://github.com/kevinand11/valleyed/commit/254988d0c6fea4b3f15312fdddc9f73655f61b99))
|
|
36
|
+
* remove need for anyOf in nullable schemas ([2bb3d00](https://github.com/kevinand11/valleyed/commit/2bb3d0043ef6f3e9ebf0a4d63c51512cebb4a051))
|
|
37
|
+
* remove need for static list of files ([3d2d622](https://github.com/kevinand11/valleyed/commit/3d2d622067a9b29803e7c34bb3c2fc2cfe1baefb))
|
|
38
|
+
* strings pipe api ([04c6df8](https://github.com/kevinand11/valleyed/commit/04c6df8b4a5d693efcf41c8680a5e7dfcea79ea4))
|
|
39
|
+
* support custom context ([8530f8e](https://github.com/kevinand11/valleyed/commit/8530f8e8e7e423c425656af2c5bcfac61dae5684))
|
|
40
|
+
* support generics for file validations ([e5cb7b4](https://github.com/kevinand11/valleyed/commit/e5cb7b45d8f2097520cc2515b9da85430a47f327))
|
|
41
|
+
* support standard-schema ([e8b2c8f](https://github.com/kevinand11/valleyed/commit/e8b2c8fe115b1995d8a67cbbd20efec126df7345))
|
|
42
|
+
* switch to reverse linked list impl ([831ec48](https://github.com/kevinand11/valleyed/commit/831ec48efcfe19c50c5e459b92fb36572482d045))
|
|
43
|
+
* times pipe api ([1f18b5e](https://github.com/kevinand11/valleyed/commit/1f18b5e470da73de571d276c4a0dbb06e364a49e))
|
|
44
|
+
* withStrippedHtml ([50cfe72](https://github.com/kevinand11/valleyed/commit/50cfe72bc226290345893d33abdb33d697b474b3))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
### Bug Fixes
|
|
48
|
+
|
|
49
|
+
* before and after expects fn not plain values ([b40eb85](https://github.com/kevinand11/valleyed/commit/b40eb8549527d9fabd45fad27f00da244751b27a))
|
|
50
|
+
* context and schema must be objects ([4d26247](https://github.com/kevinand11/valleyed/commit/4d26247b4c668fc70b8f16df480bd35455a6d154))
|
|
51
|
+
* dataclass toJSON only returns original keys ([b1a5452](https://github.com/kevinand11/valleyed/commit/b1a54525c57bfc8fb9abef5959a8f0418d94b725))
|
|
52
|
+
* fix JSONValue of DataClass<any, any> ([6a168c1](https://github.com/kevinand11/valleyed/commit/6a168c1f0af94b878c0870758e96b2ad2e858d75))
|
|
53
|
+
* fix Prettify for class instances ([39d79fb](https://github.com/kevinand11/valleyed/commit/39d79fb70cff7d440f514f82d2b35278a58d7b82))
|
|
54
|
+
* fix typings for objectX rules ([885ea27](https://github.com/kevinand11/valleyed/commit/885ea27adbb0d1dc3726454bb250057aaca19279))
|
|
55
|
+
* fix up JSONValueOf ([de97762](https://github.com/kevinand11/valleyed/commit/de977629c8389986613dd3fd6379a68069d719ef))
|
|
56
|
+
* impl for objectPick, objectOmit and objectExtends and add tests ([76a2f6b](https://github.com/kevinand11/valleyed/commit/76a2f6bf674e7e279046e1fb5f24c3424edfaf39))
|
|
57
|
+
* no need to clone for objects ([f1f0f2d](https://github.com/kevinand11/valleyed/commit/f1f0f2d3493d29c359c1d1b1e2d6bffb10260611))
|
|
58
|
+
* objectPick and objectEmit as value ([0f94a9a](https://github.com/kevinand11/valleyed/commit/0f94a9aa7f90e5e2ae6aaba425987a0c01e9b5f1))
|
|
59
|
+
* optionals typing ([4ae6979](https://github.com/kevinand11/valleyed/commit/4ae6979836df939036870ffadd412c903dbc0979))
|
|
60
|
+
* remove need for __update ([11bf277](https://github.com/kevinand11/valleyed/commit/11bf27709645853bbe9dcc0ec8a15dfe3a505996))
|
|
61
|
+
* remove objectTrim ([630f1f0](https://github.com/kevinand11/valleyed/commit/630f1f05cab076344990e61ef5c266453d0f3388))
|
|
62
|
+
* remove Pipe requirement for PipeInput, Output and Context ([0671b1e](https://github.com/kevinand11/valleyed/commit/0671b1e814cdfe6d95911752c13eaa90f1316c27))
|
|
63
|
+
* remove unknown errors ([9d6fd72](https://github.com/kevinand11/valleyed/commit/9d6fd72fcc9067d6263f924f4db18d55c0912595))
|
|
64
|
+
* rename safeParse to validate ([6ce2a75](https://github.com/kevinand11/valleyed/commit/6ce2a756ef728d49b61d94b29b0f779dffb5d828))
|
|
65
|
+
* requiredIf doesnt add undefined to the type ([b8054fb](https://github.com/kevinand11/valleyed/commit/b8054fbe0d17cf1fb3904e766636f2a23be28f3c))
|
|
66
|
+
* return type of DataClass toJSON ([9cd66ac](https://github.com/kevinand11/valleyed/commit/9cd66ac94f514979c59ebf50b6f7ff2e15c20c34))
|
|
67
|
+
* stop Prettify from messing with classes ([2c6ca51](https://github.com/kevinand11/valleyed/commit/2c6ca51624e685e9a67720153711bf2abb200c2e))
|
|
68
|
+
|
|
69
|
+
### [4.4.10](https://github.com/kevinand11/valleyed/compare/v4.4.9...v4.4.10) (2025-06-04)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
### Bug Fixes
|
|
73
|
+
|
|
74
|
+
* type JSONValue of any with toJSON ([0d7d5a8](https://github.com/kevinand11/valleyed/commit/0d7d5a8aae7feed277ffb482e66ec583ed16a0a4))
|
|
75
|
+
|
|
5
76
|
### [4.4.9](https://github.com/kevinand11/valleyed/compare/v4.4.8...v4.4.9) (2025-06-04)
|
|
6
77
|
|
|
7
78
|
|
package/README.md
CHANGED
|
@@ -1,244 +1,318 @@
|
|
|
1
1
|
# Valleyed
|
|
2
2
|
|
|
3
|
+
Valleyed is a powerful, type-safe, and lightweight validation library for TypeScript and JavaScript. It provides a fluent, chainable API to build complex validation pipelines with ease, inspired by libraries like Zod, but with a focus on simplicity and extensibility.
|
|
3
4
|
|
|
4
|
-
##
|
|
5
|
+
## ✨ Features
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
- **Type-Safe**: Full TypeScript support, infer types directly from your schemas.
|
|
8
|
+
- **Lightweight**: Small bundle size with zero dependencies.
|
|
9
|
+
- **Chainable API**: Build complex validations by chaining methods.
|
|
10
|
+
- **Extensible**: Easily add your own custom validation logic.
|
|
11
|
+
- **Standard Schema Compatible**: Generate JSON Schemas from your validation pipes.
|
|
12
|
+
- **Isomorphic**: Works in both Node.js and browser environments.
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
npm install valleyed
|
|
14
|
+
## 📦 Installation
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
yarn add valleyed
|
|
16
|
+
You can install Valleyed using your favorite package manager:
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
import { isEmail, isMinOf } from 'valleyed'
|
|
25
|
-
|
|
26
|
-
// The isEmail function builds and returns a function that checks if the first argument is a valid email
|
|
27
|
-
let validity = isEmail()('johndoe@mail.co')
|
|
28
|
-
console.log(validity)
|
|
29
|
-
// Output should be : { valid: true, error: null, value: 'johndoe@mail.co' }
|
|
18
|
+
```bash
|
|
19
|
+
npm install valleyed
|
|
20
|
+
# or
|
|
21
|
+
yarn add valleyed
|
|
22
|
+
# or
|
|
23
|
+
pnpm add valleyed
|
|
24
|
+
```
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
## 🚀 Quick Start
|
|
27
|
+
|
|
28
|
+
Here's a quick example to get you started with Valleyed:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { v } from 'valleyed';
|
|
32
|
+
|
|
33
|
+
// 1. Define a schema for your data
|
|
34
|
+
const userSchema = v.object({
|
|
35
|
+
name: v.string().pipe(v.min(3)),
|
|
36
|
+
email: v.string().pipe(v.email()),
|
|
37
|
+
age: v.optional(v.number().pipe(v.gte(18))),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// 2. Some data to validate
|
|
41
|
+
const userData = {
|
|
42
|
+
name: 'John Doe',
|
|
43
|
+
email: 'john.doe@example.com',
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// 3. Validate the data
|
|
47
|
+
const validationResult = userSchema.validate(userData);
|
|
48
|
+
|
|
49
|
+
if (validationResult.valid) {
|
|
50
|
+
// Type-safe access to the validated data
|
|
51
|
+
console.log('Validation successful:', validationResult.value);
|
|
52
|
+
} else {
|
|
53
|
+
// Detailed error messages
|
|
54
|
+
console.error('Validation failed:', validationResult.error.toString());
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 4. You can also parse directly, which throws on error
|
|
58
|
+
try {
|
|
59
|
+
const user = userSchema.parse(userData);
|
|
60
|
+
console.log('Parsed user:', user);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.error(error);
|
|
63
|
+
}
|
|
35
64
|
```
|
|
36
65
|
|
|
66
|
+
## 📚 API Reference
|
|
37
67
|
|
|
38
|
-
|
|
68
|
+
Valleyed exports a single object `v` which contains all the validation functions.
|
|
39
69
|
|
|
40
|
-
###
|
|
70
|
+
### Primitive Types
|
|
41
71
|
|
|
42
|
-
|
|
72
|
+
These are the basic building blocks for any schema.
|
|
43
73
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
74
|
+
| Function | Description |
|
|
75
|
+
| ---------------- | ---------------------------------------------------- |
|
|
76
|
+
| `v.string()` | Checks if the input is a `string`. |
|
|
77
|
+
| `v.number()` | Checks if the input is a `number` (and not `NaN`). |
|
|
78
|
+
| `v.boolean()` | Checks if the input is a `boolean`. |
|
|
79
|
+
| `v.null()` | Checks if the input is `null`. |
|
|
80
|
+
| `v.undefined()` | Checks if the input is `undefined`. |
|
|
81
|
+
| `v.any()` | Allows any value, essentially a pass-through. |
|
|
82
|
+
| `v.instanceOf()` | Checks if the input is an instance of a given class. |
|
|
48
83
|
|
|
49
|
-
|
|
84
|
+
```typescript
|
|
85
|
+
// Example:
|
|
86
|
+
v.string().validate('hello').valid; // true
|
|
87
|
+
v.number().validate(123).valid; // true
|
|
88
|
+
v.instanceOf(Date).validate(new Date()).valid; // true
|
|
89
|
+
```
|
|
50
90
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
91
|
+
### Core Validators
|
|
92
|
+
|
|
93
|
+
These validators can be piped from any other validator to add more constraints.
|
|
94
|
+
|
|
95
|
+
| Function | Description |
|
|
96
|
+
| ------------------------- | ------------------------------------------------------------------------ |
|
|
97
|
+
| `v.custom(fn, msg?)` | Validates using a custom function that returns a boolean. |
|
|
98
|
+
| `v.eq(val, msg?)` | Checks for deep equality with a given value. Alias: `v.is()`. |
|
|
99
|
+
| `v.ne(val, msg?)` | Checks for deep inequality with a given value. |
|
|
100
|
+
| `v.in(arr, msg?)` | Checks if the value is present in the provided array. |
|
|
101
|
+
| `v.nin(arr, msg?)` | Checks if the value is **not** present in the provided array. |
|
|
102
|
+
| `v.has(len, msg?)` | For strings and arrays, checks for an exact length. |
|
|
103
|
+
| `v.min(len, msg?)` | For strings and arrays, checks for a minimum length. |
|
|
104
|
+
| `v.max(len, msg?)` | For strings and arrays, checks for a maximum length. |
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
// Example:
|
|
108
|
+
const schema = v.string().pipe(v.min(5), v.in(['hello', 'world']));
|
|
109
|
+
schema.validate('hello').valid; // true
|
|
110
|
+
schema.validate('hi').valid; // false (fails min(5))
|
|
111
|
+
schema.validate('testing').valid; // false (fails in([...]))
|
|
112
|
+
```
|
|
54
113
|
|
|
55
|
-
|
|
56
|
-
isDeepEqualTo(compare, compareFunction)
|
|
57
|
-
const res = isDeepEqualTo({ id: 1 }, (value, compare) => {
|
|
58
|
-
return value?.id === compare.id
|
|
59
|
-
})({ id: 1 }) // res.valid is true
|
|
114
|
+
### String Validators
|
|
60
115
|
|
|
61
|
-
|
|
62
|
-
arrayContains(array, compareFunction)
|
|
63
|
-
const res = arrayContains([{ id: 1 }, { id: 2 }], (value, compare) => {
|
|
64
|
-
return value?.id === compare.id
|
|
65
|
-
})({ id: 2 }) // res.valid is true
|
|
66
|
-
```
|
|
116
|
+
Specific validators and transformers for strings.
|
|
67
117
|
|
|
68
|
-
|
|
118
|
+
| Function | Description |
|
|
119
|
+
| -------------------- | ------------------------------------------------------------------------ |
|
|
120
|
+
| `v.email(msg?)` | Validates an email address format. |
|
|
121
|
+
| `v.url(msg?)` | Validates a URL format. |
|
|
122
|
+
| `v.asTrimmed()` | **Transformer**: Trims whitespace from the start and end of a string. |
|
|
123
|
+
| `v.asLowercased()` | **Transformer**: Converts the string to lowercase. |
|
|
124
|
+
| `v.asUppercased()` | **Transformer**: Converts the string to uppercase. |
|
|
125
|
+
| `v.asCapitalized()` | **Transformer**: Capitalizes each word in the string. |
|
|
126
|
+
| `v.asStrippedHtml()` | **Transformer**: Removes HTML tags from the string. |
|
|
127
|
+
| `v.asSliced(len)` | **Transformer**: Slices the string to a max length, adding `...`. |
|
|
128
|
+
| `v.withStrippedHtml(pipe)` | Applies a validation pipe to an HTML-stripped version of the string, but returns the original string if valid. |
|
|
69
129
|
|
|
70
|
-
```
|
|
71
|
-
//
|
|
72
|
-
|
|
130
|
+
```typescript
|
|
131
|
+
// Example:
|
|
132
|
+
v.string().pipe(v.email()).validate('test@example.com').valid; // true
|
|
73
133
|
|
|
74
|
-
|
|
75
|
-
|
|
134
|
+
const trimmedLower = v.string().pipe(v.asTrimmed(), v.asLowercased());
|
|
135
|
+
trimmedLower.parse(' HeLLo '); // 'hello'
|
|
136
|
+
```
|
|
76
137
|
|
|
77
|
-
|
|
78
|
-
isMinOf(length)
|
|
138
|
+
### Number Validators
|
|
79
139
|
|
|
80
|
-
|
|
81
|
-
isMaxOf(length)
|
|
140
|
+
Specific validators and transformers for numbers.
|
|
82
141
|
|
|
83
|
-
|
|
84
|
-
|
|
142
|
+
| Function | Description |
|
|
143
|
+
| ----------------- | -------------------------------------------------------- |
|
|
144
|
+
| `v.gt(num, msg?)` | Checks if the number is greater than the given value. |
|
|
145
|
+
| `v.gte(num, msg?)`| Checks if the number is greater than or equal to the given value. |
|
|
146
|
+
| `v.lt(num, msg?)` | Checks if the number is less than the given value. |
|
|
147
|
+
| `v.lte(num, msg?)`| Checks if the number is less than or equal to the given value. |
|
|
148
|
+
| `v.int(msg?)` | Checks if the number is an integer. |
|
|
149
|
+
| `v.asRounded(dp?)`| **Transformer**: Rounds the number to a number of decimal places. |
|
|
85
150
|
|
|
86
|
-
|
|
87
|
-
|
|
151
|
+
```typescript
|
|
152
|
+
// Example:
|
|
153
|
+
const ageSchema = v.number().pipe(v.int(), v.gte(18));
|
|
154
|
+
ageSchema.validate(25).valid; // true
|
|
155
|
+
ageSchema.validate(17.5).valid; // false
|
|
88
156
|
```
|
|
89
157
|
|
|
90
|
-
###
|
|
91
|
-
|
|
92
|
-
```ts
|
|
93
|
-
// Checks if the validation value is of type Number. This is used internally in all number methods, so no need to use it unless you are making a custom rule
|
|
94
|
-
isNumber()
|
|
158
|
+
### Array Validators
|
|
95
159
|
|
|
96
|
-
|
|
97
|
-
isMoreThan(compare)
|
|
160
|
+
Validators for handling arrays.
|
|
98
161
|
|
|
99
|
-
|
|
100
|
-
|
|
162
|
+
| Function | Description |
|
|
163
|
+
| ------------------------- | ------------------------------------------------------------------------ |
|
|
164
|
+
| `v.array(schema)` | Validates that every element in an array matches the provided schema. |
|
|
165
|
+
| `v.tuple([s1, s2])` | Validates a fixed-length array where each element has a specific type. |
|
|
166
|
+
| `v.asSet(keyFn?)` | **Transformer**: Removes duplicates from an array. By default, it uses the value itself for comparison. You can provide a `keyFn` for objects. |
|
|
101
167
|
|
|
102
|
-
|
|
103
|
-
|
|
168
|
+
```typescript
|
|
169
|
+
// Example:
|
|
170
|
+
const tagsSchema = v.array(v.string().pipe(v.min(2)));
|
|
171
|
+
tagsSchema.validate(['food', 'travel']).valid; // true
|
|
104
172
|
|
|
105
|
-
|
|
106
|
-
|
|
173
|
+
const pointSchema = v.tuple([v.number(), v.number()]);
|
|
174
|
+
pointSchema.validate([10, 20]).valid; // true
|
|
107
175
|
```
|
|
108
176
|
|
|
109
|
-
###
|
|
177
|
+
### Object Validators
|
|
110
178
|
|
|
111
|
-
|
|
112
|
-
// Checks if the validation value is of type Array. This is used internally in all array methods, so no need to use it unless you are making a custom rule
|
|
113
|
-
isArray()
|
|
179
|
+
Validators for handling objects.
|
|
114
180
|
|
|
115
|
-
|
|
116
|
-
|
|
181
|
+
| Function | Description |
|
|
182
|
+
| ------------------------------- | ------------------------------------------------------------------------ |
|
|
183
|
+
| `v.object({ k: schema })` | Validates an object's properties against a schema definition. |
|
|
184
|
+
| `v.record(keySchema, valSchema)`| Validates objects with dynamic keys (like dictionaries or records). |
|
|
185
|
+
| `v.objectPick(schema, keys)` | Creates a new object schema by picking specified keys from an existing one. |
|
|
186
|
+
| `v.objectOmit(schema, keys)` | Creates a new object schema by omitting specified keys from an existing one. |
|
|
187
|
+
| `v.objectExtends(schema, pipes)`| Extends an object schema with new properties. |
|
|
188
|
+
| `v.asMap()` | **Transformer**: Converts a record-like object into a `Map`. |
|
|
117
189
|
|
|
118
|
-
|
|
119
|
-
|
|
190
|
+
```typescript
|
|
191
|
+
// Example:
|
|
192
|
+
const userSchema = v.object({ name: v.string(), age: v.number() });
|
|
120
193
|
|
|
121
|
-
|
|
122
|
-
|
|
194
|
+
const publicUserSchema = v.objectOmit(userSchema, ['age']);
|
|
195
|
+
publicUserSchema.validate({ name: 'John' }).valid; // true
|
|
123
196
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
// Checks if all elements in the valition value passes a requirement. The compare function passes a element and its index as the arguments and expects a boolean in return.
|
|
128
|
-
isArrayOf(compareFunction)
|
|
129
|
-
const res = isArrayOf((element, index) => {
|
|
130
|
-
return isString(element).valid // This ensures all elements in the array are strings
|
|
131
|
-
})(['a', 'b', 'c']) // res.valid is true
|
|
197
|
+
const userWithIdSchema = v.objectExtends(userSchema, { id: v.string() });
|
|
198
|
+
userWithIdSchema.validate({ id: 'user-1', name: 'Jane', age: 30 }).valid; // true
|
|
199
|
+
```
|
|
132
200
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
201
|
+
### Optional & Default Values
|
|
202
|
+
|
|
203
|
+
Functions for handling optional values and providing defaults.
|
|
204
|
+
|
|
205
|
+
| Function | Description |
|
|
206
|
+
| ------------------------------ | ------------------------------------------------------------------------ |
|
|
207
|
+
| `v.optional(schema)` | Allows the value to be `undefined`. |
|
|
208
|
+
| `v.nullable(schema)` | Allows the value to be `null`. |
|
|
209
|
+
| `v.nullish(schema)` | Allows the value to be `null` or `undefined`. |
|
|
210
|
+
| `v.defaults(schema, val)` | Provides a default value if the input is `undefined`. |
|
|
211
|
+
| `v.defaultsOnFail(schema, val)`| Provides a default value if the initial validation fails. |
|
|
212
|
+
| `v.conditional(schema, fn)` | Makes a field optional based on a dynamic boolean condition. |
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
// Example:
|
|
216
|
+
const schema = v.object({
|
|
217
|
+
name: v.string(),
|
|
218
|
+
nickname: v.optional(v.string()),
|
|
219
|
+
role: v.defaults(v.string(), 'user'),
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
schema.parse({ name: 'John' });
|
|
223
|
+
// { name: 'John', role: 'user' }
|
|
139
224
|
```
|
|
140
225
|
|
|
141
|
-
###
|
|
226
|
+
### Junctions (Unions & Intersections)
|
|
142
227
|
|
|
143
|
-
|
|
144
|
-
// Checks if the validation value can be parsed into a valid javascript date. Validation value can be a Date object, a timestamp number or a datetime string. This is used internally in all datetime methods, so no need to use it unless you are making a custom rule
|
|
145
|
-
isTime()
|
|
228
|
+
Combine schemas to create complex types.
|
|
146
229
|
|
|
147
|
-
|
|
148
|
-
|
|
230
|
+
| Function | Description |
|
|
231
|
+
| -------------------------------------- | ------------------------------------------------------------------------ |
|
|
232
|
+
| `v.or([s1, s2])` | A union type. The value must match at least one of the provided schemas. |
|
|
233
|
+
| `v.and([s1, s2])` | An intersection. The value must match all of the provided schemas. |
|
|
234
|
+
| `v.merge(s1, s2)` | Merges two object or array schemas. |
|
|
235
|
+
| `v.discriminate(fn, schemas)` | Validates against one of several object schemas based on a discriminator field. |
|
|
236
|
+
| `v.fromJson(schema)` | **Transformer**: Parses a JSON string before validating against a schema. |
|
|
149
237
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
238
|
+
```typescript
|
|
239
|
+
// Example: Discriminated Union
|
|
240
|
+
const shapeSchema = v.discriminate(v => v.type, {
|
|
241
|
+
circle: v.object({ type: v.is('circle'), radius: v.number() }),
|
|
242
|
+
square: v.object({ type: v.is('square'), side: v.number() }),
|
|
243
|
+
});
|
|
153
244
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
```
|
|
157
|
-
// Checks if the validation value is a boolean
|
|
158
|
-
isBoolean()
|
|
245
|
+
shapeSchema.validate({ type: 'circle', radius: 10 }).valid; // true
|
|
246
|
+
shapeSchema.validate({ type: 'square', side: 5 }).valid; // true
|
|
247
|
+
```
|
|
159
248
|
|
|
160
|
-
|
|
161
|
-
isNull()
|
|
249
|
+
### Date & Time Validators
|
|
162
250
|
|
|
163
|
-
|
|
164
|
-
isUndefined()
|
|
251
|
+
Validators and transformers for dates and times.
|
|
165
252
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
253
|
+
| Function | Description |
|
|
254
|
+
| ------------------- | ------------------------------------------------------------------------ |
|
|
255
|
+
| `v.time(msg?)` | Validates a date, accepting `Date` objects, timestamps, or date strings. |
|
|
256
|
+
| `v.after(date, msg?)`| Checks if the date is after a specified date. |
|
|
257
|
+
| `v.before(date, msg?)`| Checks if the date is before a specified date. |
|
|
258
|
+
| `v.asStamp()` | **Transformer**: Converts a `Date` object into a numeric timestamp. |
|
|
259
|
+
| `v.asISOString()` | **Transformer**: Converts a `Date` object into an ISO 8601 string. |
|
|
170
260
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
return isNumber(currentValue).valid
|
|
178
|
-
})({ a: 1, b: 2, c: 3 }) // res.valid is true because all the values of the object are numbers
|
|
179
|
-
|
|
180
|
-
/// Checks if all keys and values in an map passes a comparer function
|
|
181
|
-
isMap(keysCompareFunction, valuesCompareFunction)
|
|
182
|
-
const map = new Map([
|
|
183
|
-
[1, true],
|
|
184
|
-
[2, false],
|
|
185
|
-
[3, true]
|
|
186
|
-
])
|
|
187
|
-
const res = isMap(
|
|
188
|
-
(key) => isNumber(key).valid,
|
|
189
|
-
(value) => isBoolean(value).valid
|
|
190
|
-
)(map) // res.valid is true because all the keys of the map are numbers and all the values are booleans
|
|
261
|
+
```typescript
|
|
262
|
+
// Example:
|
|
263
|
+
const eventSchema = v.object({
|
|
264
|
+
name: v.string(),
|
|
265
|
+
startsAt: v.time().pipe(v.after(new Date())),
|
|
266
|
+
});
|
|
191
267
|
```
|
|
192
268
|
|
|
193
|
-
###
|
|
194
|
-
|
|
195
|
-
```ts
|
|
196
|
-
// Checks if the validation value is an object with a key "type" that contains a supported file mimetypes. All supported file mimetypes can be imported under the name "fileMimeTypes". This is used internally in all file methods, so no need to use it unless you are making a custom rule
|
|
197
|
-
isFile()
|
|
269
|
+
### File Validators
|
|
198
270
|
|
|
199
|
-
|
|
200
|
-
isImage()
|
|
271
|
+
Validators for file-like objects (e.g., from a file upload). These validators expect an object with a `type` property containing the MIME type.
|
|
201
272
|
|
|
202
|
-
|
|
203
|
-
|
|
273
|
+
| Function | Description |
|
|
274
|
+
| ----------------------------- | ------------------------------------------------------------------------ |
|
|
275
|
+
| `v.file(msg?)` | Validates a generic file-like object. |
|
|
276
|
+
| `v.image(msg?)` | Validates if the file is an image (`image/*`). |
|
|
277
|
+
| `v.audio(msg?)` | Validates if the file is an audio file (`audio/*`). |
|
|
278
|
+
| `v.video(msg?)` | Validates if the file is a video file (`video/*`). |
|
|
279
|
+
| `v.fileType(types, msg?)` | Validates if the file's MIME type is in the provided list. |
|
|
204
280
|
|
|
205
|
-
|
|
206
|
-
|
|
281
|
+
```typescript
|
|
282
|
+
// Example:
|
|
283
|
+
const imageSchema = v.file().pipe(v.image(), v.fileType(['image/jpeg', 'image/png']));
|
|
284
|
+
imageSchema.validate({ type: 'image/png' }).valid; // true
|
|
285
|
+
imageSchema.validate({ type: 'image/gif' }).valid; // false
|
|
207
286
|
```
|
|
208
287
|
|
|
209
|
-
###
|
|
288
|
+
### Coercion
|
|
210
289
|
|
|
211
|
-
|
|
212
|
-
// If there is a rule for your usecase, you can create a custom one with this. The validityFunction passes the validation value as its argument and expects a boolean in return
|
|
213
|
-
isCustom(validityFunction)
|
|
214
|
-
const res = isCustom((value) => typeof value === 'function')(() => {}) // res.valid is true because the typeof value is function
|
|
215
|
-
```
|
|
290
|
+
These pipes attempt to convert the input to a specific type before validating it.
|
|
216
291
|
|
|
292
|
+
| Function | Description |
|
|
293
|
+
| ------------------- | ------------------------------------------------------------------------ |
|
|
294
|
+
| `v.coerceString()` | Coerces to `string` using `String()`. |
|
|
295
|
+
| `v.coerceNumber()` | Coerces to `number` using `Number()`. Fails if the result is `NaN`. |
|
|
296
|
+
| `v.coerceBoolean()` | Coerces to `boolean` using `Boolean()`. |
|
|
297
|
+
| `v.coerceTime()` | Coerces to `Date` using `new Date()`. |
|
|
217
298
|
|
|
218
|
-
|
|
299
|
+
```typescript
|
|
300
|
+
// Example:
|
|
301
|
+
const schema = v.coerceNumber().pipe(v.int());
|
|
302
|
+
schema.parse('123'); // 123
|
|
303
|
+
schema.validate('123.45').valid; // false (fails int())
|
|
304
|
+
```
|
|
219
305
|
|
|
220
|
-
|
|
221
|
-
import { Validator, isEmail, isMinOf, isString, isNumber } from 'valleyed'
|
|
306
|
+
## 🤝 Contributing
|
|
222
307
|
|
|
223
|
-
|
|
224
|
-
let res = Validator.and([[isEmail(), isMinOf(1)]])('johndoe@mail.com')
|
|
225
|
-
console.log(res) // { valid: true, errors: [], value: 'johndoe@mail.com' }
|
|
308
|
+
Contributions are welcome! Please open an issue or submit a pull request.
|
|
226
309
|
|
|
227
|
-
|
|
228
|
-
res = Validator.and([[isEmail(), isMinOf(1)]])('')
|
|
229
|
-
console.log(res) // { valid: false, value: '', errors: [ 'is not a valid email', 'must contain 1 or more characters' ] }
|
|
310
|
+
### Development Setup
|
|
230
311
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
312
|
+
1. Clone the repository.
|
|
313
|
+
2. Install dependencies with `pnpm install`.
|
|
314
|
+
3. Run tests with `pnpm test`.
|
|
234
315
|
|
|
235
|
-
|
|
236
|
-
res = Validator.or([[isString(), isMinOf(1)], [isNumber()]])(false)
|
|
237
|
-
console.log(res) // { valid: false, value: false, errors: [ 'doesn't match any of the schema' ] }
|
|
316
|
+
## 📜 License
|
|
238
317
|
|
|
239
|
-
|
|
240
|
-
Validator.and([[isEmail()]], {
|
|
241
|
-
nullable: true, // Boolean: if true, null passed as the first argument passes validation
|
|
242
|
-
required: () => false // Boolean or Function that returns a boolean: if false, undefined passed as the first argument passes validation
|
|
243
|
-
})('')
|
|
244
|
-
```
|
|
318
|
+
This project is licensed under the MIT License.
|
package/lib/api/arrays.d.ts
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
min(length: number, err?: string): this;
|
|
6
|
-
max(length: number, err?: string): this;
|
|
7
|
-
set(keyFn?: (v: I) => any): this;
|
|
8
|
-
}
|
|
1
|
+
import { PipeInput, type Pipe, type PipeOutput } from './base';
|
|
2
|
+
export declare const array: <T extends Pipe<any, any, any>>(pipeSchema: T) => Pipe<PipeInput<T>[], PipeOutput<T>[], any>;
|
|
3
|
+
export declare const tuple: <T extends ReadonlyArray<Pipe<any, any, any>>>(pipes: readonly [...T]) => Pipe<{ [K in keyof T]: PipeInput<T[K]>; }, { [K_1 in keyof T]: PipeOutput<T[K_1]>; }, any>;
|
|
4
|
+
export declare const asSet: <T>(keyFn?: (i: T) => PropertyKey) => Pipe<T[], T[], any>;
|