@modulify/validator 0.0.1 → 0.1.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 +28 -0
- package/README.md +111 -137
- package/dist/assertions/Assert.d.ts +2 -0
- package/dist/assertions/HasLength.d.ts +7 -0
- package/dist/assertions/check.d.ts +3 -0
- package/dist/assertions/index.d.ts +16 -0
- package/dist/assertions.cjs +109 -0
- package/dist/assertions.d.ts +2 -0
- package/dist/assertions.mjs +109 -0
- package/dist/index.cjs +110 -317
- package/dist/index.d.ts +6 -0
- package/dist/index.mjs +110 -308
- package/dist/predicates.cjs +81 -0
- package/dist/predicates.d.ts +34 -0
- package/dist/predicates.mjs +81 -0
- package/dist/runners/Each.d.ts +3 -0
- package/dist/runners/HasProperties.d.ts +6 -0
- package/dist/runners/index.d.ts +2 -0
- package/dist/runners.cjs +32 -0
- package/dist/runners.d.ts +2 -0
- package/dist/runners.mjs +32 -0
- package/logo.png +0 -0
- package/package.json +62 -22
- package/types/index.d.ts +53 -118
- package/dist/index.cjs.map +0 -1
- package/dist/index.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,34 @@
|
|
|
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
|
+
## [0.1.0](https://github.com/modulify/validator/compare/v0.0.2...v0.1.0) (2024-12-22)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### ⚠ BREAKING CHANGES
|
|
9
|
+
|
|
10
|
+
* validator object replaced with validate function, containing sub method sync for synchronous validation
|
|
11
|
+
* Length constraint replaced with HasLength functional assertion
|
|
12
|
+
* Exists constraint replaced with IsDefined functional assertion
|
|
13
|
+
* Each object replaced with Each runner
|
|
14
|
+
* Collection object replaced with HasProperties runner
|
|
15
|
+
* Type "Key" replaced with in-box "PropertyKey"
|
|
16
|
+
* ConstraintCollection type was removed
|
|
17
|
+
* ConstraintValidator was renamed to Validator
|
|
18
|
+
* ConstraintViolation was renamed to Violation
|
|
19
|
+
* d.ts files for exported logic units are now generated and available in dist catalogue
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
|
|
23
|
+
* Logic redesign and simplification ([b829a1e](https://github.com/modulify/validator/commit/b829a1eb0373cc6069451eb1cdf4767accbe2ee3))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### Fixes
|
|
27
|
+
|
|
28
|
+
* Removed sourcemap ([7e469d0](https://github.com/modulify/validator/commit/7e469d0ca60d854c62a79c54e9b3dba1d3b72657))
|
|
29
|
+
* test coverage ([84912c4](https://github.com/modulify/validator/commit/84912c4a33d58b385a1e0c764c57b3806d658613))
|
|
30
|
+
|
|
31
|
+
### [0.0.2](https://github.com/modulify/validator/compare/v0.0.1...v0.0.2) (2024-02-05)
|
|
32
|
+
|
|
5
33
|
### 0.0.1 (2024-02-05)
|
|
6
34
|
|
|
7
35
|
|
package/README.md
CHANGED
|
@@ -1,52 +1,60 @@
|
|
|
1
|
-
# `@modulify/validator`
|
|
1
|
+
# <img src="./logo.png" alt="Logo" width="36" /> `@modulify/validator`
|
|
2
2
|
|
|
3
3
|
[](https://codecov.io/gh/modulify/validator)
|
|
4
4
|
[](https://github.com/modulify/validator/actions)
|
|
5
5
|
[](https://www.npmjs.com/package/@modulify/validator)
|
|
6
6
|
|
|
7
|
+
This library provides a declarative validation utility.
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
The util does not provide any text messages in the constraints produced and gives only metadata that can
|
|
9
|
+
The utility does not include text messages in the generated violations but instead provides metadata that can
|
|
11
10
|
be used to create a custom view for them.
|
|
12
11
|
|
|
13
12
|
## Installation
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
Using `yarn`:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
yarn add @modulify/validator
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
or, using `npm`:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
npm install @modulify/validator --save
|
|
24
|
+
```
|
|
16
25
|
|
|
17
26
|
## Usage
|
|
18
27
|
|
|
19
28
|
```typescript
|
|
20
29
|
import {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
30
|
+
HasLength,
|
|
31
|
+
HasProperties,
|
|
32
|
+
IsDefined,
|
|
33
|
+
IsString,
|
|
34
|
+
validate,
|
|
25
35
|
} from '@modulify/validator'
|
|
26
36
|
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
const violations = validator.validate({
|
|
37
|
+
const violations = await validate({
|
|
30
38
|
form: {
|
|
31
39
|
nickname: '',
|
|
32
40
|
password: '',
|
|
33
41
|
},
|
|
34
|
-
},
|
|
42
|
+
}, HasProperties({
|
|
35
43
|
form: [
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
nickname:
|
|
39
|
-
password:
|
|
44
|
+
IsDefined(),
|
|
45
|
+
HasProperties({
|
|
46
|
+
nickname: IsString.That(HasLength({ min: 4 })),
|
|
47
|
+
password: IsString.That(HasLength({ min: 6 })),
|
|
40
48
|
}),
|
|
41
49
|
],
|
|
42
|
-
})
|
|
43
|
-
by: '@modulify/validator/
|
|
50
|
+
})) /* [{
|
|
51
|
+
by: '@modulify/validator/IsString',
|
|
44
52
|
value: '',
|
|
45
53
|
path: ['form', 'nickname'],
|
|
46
54
|
reason: 'min',
|
|
47
55
|
meta: 4,
|
|
48
56
|
}, {
|
|
49
|
-
by: '@modulify/validator/
|
|
57
|
+
by: '@modulify/validator/IsString',
|
|
50
58
|
value: '',
|
|
51
59
|
path: ['form', 'password'],
|
|
52
60
|
reason: 'min',
|
|
@@ -54,124 +62,90 @@ const violations = validator.validate({
|
|
|
54
62
|
}] */
|
|
55
63
|
```
|
|
56
64
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
Constraints provide information of how the value should be validated.
|
|
60
|
-
|
|
61
|
-
Available from the box:
|
|
62
|
-
|
|
63
|
-
* `Collection` – used for validating objects' structure;
|
|
64
|
-
* `Each` – used for validating arrays' elements; applies specified constraints to each element of an array;
|
|
65
|
-
* `Exists` – used for checking if a value is defined; useful for finding missing keys;
|
|
66
|
-
* `Length` – used for checking arrays' and string's length, available settings (all optional) are:
|
|
67
|
-
* `exact` – `number`, array or string should have exactly specified count of elements or characters;
|
|
68
|
-
* `max` – `number`, maximum elements in array or maximum characters in string;
|
|
69
|
-
* `min` – `number`, minimum elements in array or minimum characters in string;
|
|
70
|
-
* `OneOf` – used for restricting which values can be used.
|
|
71
|
-
|
|
72
|
-
There is no any basic constraint class to extend, but they should follow signature
|
|
73
|
-
described in `types/index.d.ts` – `Constraint`.
|
|
74
|
-
|
|
75
|
-
### Validators
|
|
76
|
-
|
|
77
|
-
Validators provide validation logic that relies on information provided by constraints.
|
|
78
|
-
|
|
79
|
-
There is no any basic validator class to extend, but they should follow signature
|
|
80
|
-
described in `types/index.d.ts` – `ConstraintValidator`.
|
|
81
|
-
|
|
82
|
-
### Provider
|
|
83
|
-
|
|
84
|
-
Provider is used to bind constraints with their validators, provides a validator for a constraint.
|
|
85
|
-
|
|
86
|
-
All providers should follow signature described in `types/index.d.ts` – `Provider`.
|
|
87
|
-
|
|
88
|
-
This feature is responsible for extending validation capabilities. Custom provider can be passed into
|
|
89
|
-
`createValidator` function or `override` method of `Validator` instance.
|
|
90
|
-
|
|
91
|
-
There is a built-in provider – `ProviderChain`. It allows to "chain" providers – if
|
|
92
|
-
suitable validator was not found in currently used provider, it will try to find it in previous provider that was
|
|
93
|
-
overridden by `override` method.
|
|
65
|
+
or (for synchronous validation):
|
|
94
66
|
|
|
95
67
|
```typescript
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
public readonly name = '@app/validator/Email'
|
|
111
|
-
|
|
112
|
-
toViolation (value: unknown, path: Key[]): ConstraintViolation {
|
|
113
|
-
return {
|
|
114
|
-
by: this.name,
|
|
115
|
-
value,
|
|
116
|
-
path,
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
class EmailValidator implements ConstraintValidator {
|
|
122
|
-
private readonly _constraint: Email
|
|
123
|
-
|
|
124
|
-
constructor (constraint: Email) {
|
|
125
|
-
this._constraint = constraint
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
validate (value: unknown, path?: Key[]): ConstraintViolation | null {
|
|
129
|
-
if (!(typeof value === 'string') || !/\S+@\S+\.\S+/.test(value)) {
|
|
130
|
-
return this._constraint.toViolation(value, path)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return null
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
then
|
|
139
|
-
|
|
140
|
-
```typescript
|
|
141
|
-
const provider = new ProviderChain(new class implements Provider {
|
|
142
|
-
get (constraint: Constraint) {
|
|
143
|
-
return constraint instanceof Email ? new EmailValidator(constraint) : null
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
override (provider: Provider): Provider {
|
|
147
|
-
return new ProviderChain(provider, this)
|
|
148
|
-
}
|
|
149
|
-
})
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
or
|
|
153
|
-
|
|
154
|
-
```typescript
|
|
155
|
-
const provider = new class implements Provider {
|
|
156
|
-
get (constraint: Constraint) {
|
|
157
|
-
return constraint instanceof Email ? new EmailValidator(constraint) : null
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
override (provider: Provider): Provider {
|
|
161
|
-
return new ProviderChain(provider, this)
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
and then
|
|
167
|
-
|
|
168
|
-
```typescript
|
|
169
|
-
const validator = createValidator(provider)
|
|
68
|
+
const violations = validate.sync({
|
|
69
|
+
form: {
|
|
70
|
+
nickname: '',
|
|
71
|
+
password: '',
|
|
72
|
+
},
|
|
73
|
+
}, HasProperties({
|
|
74
|
+
form: [
|
|
75
|
+
IsDefined(),
|
|
76
|
+
HasProperties({
|
|
77
|
+
nickname: IsString.That(HasLength({ min: 4 })),
|
|
78
|
+
password: IsString.That(HasLength({ min: 6 })),
|
|
79
|
+
}),
|
|
80
|
+
],
|
|
81
|
+
}))
|
|
170
82
|
```
|
|
171
83
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
84
|
+
## Exported types
|
|
85
|
+
|
|
86
|
+
* `Violation` – an object that contains information about a value – why it violates one or more constraints;
|
|
87
|
+
includes following fields:
|
|
88
|
+
* `value` – value that violates something;
|
|
89
|
+
* `path` – path to the value, an empty array for scalar values and represents full path to the value in a complex
|
|
90
|
+
object;
|
|
91
|
+
* `violates` – indicator of the violated constraint;
|
|
92
|
+
* `reason` – indicator of the reason why the constraint is violated;
|
|
93
|
+
* `meta` – some data to describe the reason – what exactly the boundaries were not met;
|
|
94
|
+
```typescript
|
|
95
|
+
import type { Violation } from '@modulify/validator/types'
|
|
96
|
+
```
|
|
97
|
+
* `Predicate` – function that accepts a value and returns `true` or `false`; logical unit that is used for checking
|
|
98
|
+
multiple things: type or if the value satisfies certain criteria; accepts generic argument `T` to specify
|
|
99
|
+
the type of the value, if predicate returns `true`;
|
|
100
|
+
```typescript
|
|
101
|
+
import type { Predicate } from '@modulify/validator/types'
|
|
102
|
+
```
|
|
103
|
+
* `Assertion` – extension of the `Predicate` type that includes:
|
|
104
|
+
* `fqn` – field – some predefined name that will be used as a value for the `violates` field of `Violation`;
|
|
105
|
+
* `bail` – field – flag that interrupts further validation if the assertion fails;
|
|
106
|
+
* `reason` – field, optional – string or symbol that is used to indicate, why assertion has failed;
|
|
107
|
+
always added to a violation object, if present;
|
|
108
|
+
* `meta` – field, optional – some metadata to use in further analysis; always added to a violation object, if present;
|
|
109
|
+
* `That` – method – used to extend assertion with other assertions;
|
|
110
|
+
* `also` – field – readonly array of other assertions that was attached by `That` method;
|
|
111
|
+
```typescript
|
|
112
|
+
import type { Assertion } from '@modulify/validator/types'
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Exported members
|
|
116
|
+
|
|
117
|
+
* `validate` – function that accepts a value for validation as the first argument, constraints as the second,
|
|
118
|
+
and path to a value as the third (that is optional and used mostly for internal purposes, as validation is recursive);
|
|
119
|
+
includes method `sync` that has the same arguments set but performs validation synchronously and throws error when
|
|
120
|
+
finds an asynchronous constraint;
|
|
121
|
+
|
|
122
|
+
* `Assert` – creates assertion from logical predicate:
|
|
123
|
+
```typescript
|
|
124
|
+
const IsSomething = Assert(isSomething, {
|
|
125
|
+
fqn: 'Some fqn',
|
|
126
|
+
bail: true,
|
|
127
|
+
})
|
|
128
|
+
```
|
|
129
|
+
Arguments:
|
|
130
|
+
* Logical predicate
|
|
131
|
+
* Options, that includes `fqn`, `bail`, `reason` (optional), and `meta` (optional);
|
|
132
|
+
* `HasLength` – checks length property of the specified string or array; can be configured with options:
|
|
133
|
+
* `exact` – if the length should be exactly equal the specified value;
|
|
134
|
+
* `max` – if the length should be equal or less than the specified value;
|
|
135
|
+
* `min` – if the length should be equal or greater than the specified value;
|
|
136
|
+
* `bail` – set this to true if you need to interrupt further validation if the assertion fails;
|
|
137
|
+
* `IsBoolean` – checks if the value is **boolean**; interrupts further validation if fails;
|
|
138
|
+
* `IsDate` – checks if the value is Date **object**; interrupts further validation if fails;
|
|
139
|
+
* `IsDefined` – checks if the value is **not undefined**; interrupts further validation if fails;
|
|
140
|
+
* `IsEmail` – checks if the value is a **valid email**; interrupts further validation if fails;
|
|
141
|
+
* `IsNull` – checks if the value is **null**; interrupts further validation if fails;
|
|
142
|
+
* `IsNumber` – checks if the value is **number**; interrupts further validation if fails;
|
|
143
|
+
* `IsString` – checks if the value is **string**; interrupts further validation if fails;
|
|
144
|
+
* `IsSymbol` – checks if the value is a **symbol**; interrupts further validation if fails;
|
|
145
|
+
* `OneOf` – checks if the value equal to one of the specified values; can be configured with:
|
|
146
|
+
* `equalTo` – predicate f(a, b) that checks if two values are equal or not;
|
|
147
|
+
by default the strict `===` comparison is used
|
|
148
|
+
* `bail` – set this to true if you need to interrupt further validation if the assertion fails;
|
|
149
|
+
|
|
150
|
+
* `Each` – a runner that runs validation for each element in array;
|
|
151
|
+
* `HasProperties` – a runner that runs object's structure check.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Assert } from './Assert';
|
|
2
|
+
import { Assertion } from '../../types';
|
|
3
|
+
export { Assert };
|
|
4
|
+
export { HasLength } from './HasLength';
|
|
5
|
+
export declare const IsBoolean: Assertion<boolean, unknown>;
|
|
6
|
+
export declare const IsDate: Assertion<Date, unknown>;
|
|
7
|
+
export declare const IsDefined: Assertion<unknown, unknown>;
|
|
8
|
+
export declare const IsEmail: Assertion<string, unknown>;
|
|
9
|
+
export declare const IsNull: Assertion<null, unknown>;
|
|
10
|
+
export declare const IsNumber: Assertion<number, unknown>;
|
|
11
|
+
export declare const IsString: Assertion<string, unknown>;
|
|
12
|
+
export declare const IsSymbol: Assertion<symbol, unknown>;
|
|
13
|
+
export declare const OneOf: <Actual = unknown>(values: Actual[] | Record<string, Actual>, { equalTo, bail, }?: {
|
|
14
|
+
equalTo?: (a: Actual, b: unknown) => boolean;
|
|
15
|
+
bail?: boolean;
|
|
16
|
+
}) => Assertion<Actual, Actual[]>;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const predicates = require("./predicates.cjs");
|
|
4
|
+
const delegate = (p) => {
|
|
5
|
+
return (value) => p(value);
|
|
6
|
+
};
|
|
7
|
+
const Assert = (predicate, options) => {
|
|
8
|
+
const extender = (asserts = []) => {
|
|
9
|
+
return {
|
|
10
|
+
That(...asserts2) {
|
|
11
|
+
return Object.assign(delegate(predicate), options, extender(asserts2));
|
|
12
|
+
},
|
|
13
|
+
get also() {
|
|
14
|
+
return asserts;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
return Object.assign(delegate(predicate), options, extender());
|
|
19
|
+
};
|
|
20
|
+
const isGTE = (min) => (x) => predicates.isNumber(x) && x >= min;
|
|
21
|
+
const isLTE = (max) => (x) => predicates.isNumber(x) && x <= max;
|
|
22
|
+
const IsEqual = (exact) => Assert((x) => predicates.isExact(exact)(x.length), {
|
|
23
|
+
fqn: "@modulify/validator/HasLength[exact]",
|
|
24
|
+
bail: false,
|
|
25
|
+
reason: "exact",
|
|
26
|
+
meta: exact
|
|
27
|
+
});
|
|
28
|
+
const IsGTE = (min) => Assert((x) => isGTE(min)(x.length), {
|
|
29
|
+
fqn: "@modulify/validator/HasLength[min]",
|
|
30
|
+
bail: false,
|
|
31
|
+
reason: "min",
|
|
32
|
+
meta: min
|
|
33
|
+
});
|
|
34
|
+
const IsLTE = (max) => Assert((x) => isLTE(max)(x.length), {
|
|
35
|
+
fqn: "@modulify/validator/HasLength[max]",
|
|
36
|
+
bail: false,
|
|
37
|
+
reason: "max",
|
|
38
|
+
meta: max
|
|
39
|
+
});
|
|
40
|
+
const HasLength = ({
|
|
41
|
+
exact = null,
|
|
42
|
+
max = null,
|
|
43
|
+
min = null,
|
|
44
|
+
bail = false
|
|
45
|
+
}) => Assert(predicates.Or(predicates.isString, predicates.isArray), {
|
|
46
|
+
fqn: "@modulify/validator/HasLength",
|
|
47
|
+
bail,
|
|
48
|
+
reason: "unsupported"
|
|
49
|
+
}).That(
|
|
50
|
+
...exact !== null ? [IsEqual(exact)] : [],
|
|
51
|
+
...max !== null ? [IsLTE(max)] : [],
|
|
52
|
+
...min !== null ? [IsGTE(min)] : []
|
|
53
|
+
);
|
|
54
|
+
const IsBoolean = Assert(predicates.isBoolean, {
|
|
55
|
+
fqn: "@modulify/validator/IsBoolean",
|
|
56
|
+
bail: true
|
|
57
|
+
});
|
|
58
|
+
const IsDate = Assert(predicates.isDate, {
|
|
59
|
+
fqn: "@modulify/validator/IsDate",
|
|
60
|
+
bail: true
|
|
61
|
+
});
|
|
62
|
+
const IsDefined = Assert(predicates.Not(predicates.isUndefined), {
|
|
63
|
+
fqn: "@modulify/validator/IsDefined",
|
|
64
|
+
bail: true,
|
|
65
|
+
reason: "undefined"
|
|
66
|
+
});
|
|
67
|
+
const IsEmail = Assert(predicates.isEmail, {
|
|
68
|
+
fqn: "@modulify/validator/IsEmail",
|
|
69
|
+
bail: true
|
|
70
|
+
});
|
|
71
|
+
const IsNull = Assert(predicates.isNull, {
|
|
72
|
+
fqn: "@modulify/validator/IsNull",
|
|
73
|
+
bail: true
|
|
74
|
+
});
|
|
75
|
+
const IsNumber = Assert(predicates.isNumber, {
|
|
76
|
+
fqn: "@modulify/validator/IsNumber",
|
|
77
|
+
bail: true
|
|
78
|
+
});
|
|
79
|
+
const IsString = Assert(predicates.isString, {
|
|
80
|
+
fqn: "@modulify/validator/IsString",
|
|
81
|
+
bail: true
|
|
82
|
+
});
|
|
83
|
+
const IsSymbol = Assert(predicates.isSymbol, {
|
|
84
|
+
fqn: "@modulify/validator/IsSymbol",
|
|
85
|
+
bail: true
|
|
86
|
+
});
|
|
87
|
+
const OneOf = (values, {
|
|
88
|
+
equalTo = (a, b) => a === b,
|
|
89
|
+
bail = false
|
|
90
|
+
} = {}) => {
|
|
91
|
+
const haystack = predicates.isArray(values) ? values : Object.values(values);
|
|
92
|
+
const oneOf = (value) => haystack.some((allowed) => equalTo(allowed, value));
|
|
93
|
+
return Assert(oneOf, {
|
|
94
|
+
fqn: "@modulify/validator/OneOf",
|
|
95
|
+
bail,
|
|
96
|
+
meta: haystack
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
exports.Assert = Assert;
|
|
100
|
+
exports.HasLength = HasLength;
|
|
101
|
+
exports.IsBoolean = IsBoolean;
|
|
102
|
+
exports.IsDate = IsDate;
|
|
103
|
+
exports.IsDefined = IsDefined;
|
|
104
|
+
exports.IsEmail = IsEmail;
|
|
105
|
+
exports.IsNull = IsNull;
|
|
106
|
+
exports.IsNumber = IsNumber;
|
|
107
|
+
exports.IsString = IsString;
|
|
108
|
+
exports.IsSymbol = IsSymbol;
|
|
109
|
+
exports.OneOf = OneOf;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { Or, isArray, isString, isExact, isNumber, isBoolean, isDate, Not, isUndefined, isEmail, isNull, isSymbol } from "./predicates.mjs";
|
|
2
|
+
const delegate = (p) => {
|
|
3
|
+
return (value) => p(value);
|
|
4
|
+
};
|
|
5
|
+
const Assert = (predicate, options) => {
|
|
6
|
+
const extender = (asserts = []) => {
|
|
7
|
+
return {
|
|
8
|
+
That(...asserts2) {
|
|
9
|
+
return Object.assign(delegate(predicate), options, extender(asserts2));
|
|
10
|
+
},
|
|
11
|
+
get also() {
|
|
12
|
+
return asserts;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
return Object.assign(delegate(predicate), options, extender());
|
|
17
|
+
};
|
|
18
|
+
const isGTE = (min) => (x) => isNumber(x) && x >= min;
|
|
19
|
+
const isLTE = (max) => (x) => isNumber(x) && x <= max;
|
|
20
|
+
const IsEqual = (exact) => Assert((x) => isExact(exact)(x.length), {
|
|
21
|
+
fqn: "@modulify/validator/HasLength[exact]",
|
|
22
|
+
bail: false,
|
|
23
|
+
reason: "exact",
|
|
24
|
+
meta: exact
|
|
25
|
+
});
|
|
26
|
+
const IsGTE = (min) => Assert((x) => isGTE(min)(x.length), {
|
|
27
|
+
fqn: "@modulify/validator/HasLength[min]",
|
|
28
|
+
bail: false,
|
|
29
|
+
reason: "min",
|
|
30
|
+
meta: min
|
|
31
|
+
});
|
|
32
|
+
const IsLTE = (max) => Assert((x) => isLTE(max)(x.length), {
|
|
33
|
+
fqn: "@modulify/validator/HasLength[max]",
|
|
34
|
+
bail: false,
|
|
35
|
+
reason: "max",
|
|
36
|
+
meta: max
|
|
37
|
+
});
|
|
38
|
+
const HasLength = ({
|
|
39
|
+
exact = null,
|
|
40
|
+
max = null,
|
|
41
|
+
min = null,
|
|
42
|
+
bail = false
|
|
43
|
+
}) => Assert(Or(isString, isArray), {
|
|
44
|
+
fqn: "@modulify/validator/HasLength",
|
|
45
|
+
bail,
|
|
46
|
+
reason: "unsupported"
|
|
47
|
+
}).That(
|
|
48
|
+
...exact !== null ? [IsEqual(exact)] : [],
|
|
49
|
+
...max !== null ? [IsLTE(max)] : [],
|
|
50
|
+
...min !== null ? [IsGTE(min)] : []
|
|
51
|
+
);
|
|
52
|
+
const IsBoolean = Assert(isBoolean, {
|
|
53
|
+
fqn: "@modulify/validator/IsBoolean",
|
|
54
|
+
bail: true
|
|
55
|
+
});
|
|
56
|
+
const IsDate = Assert(isDate, {
|
|
57
|
+
fqn: "@modulify/validator/IsDate",
|
|
58
|
+
bail: true
|
|
59
|
+
});
|
|
60
|
+
const IsDefined = Assert(Not(isUndefined), {
|
|
61
|
+
fqn: "@modulify/validator/IsDefined",
|
|
62
|
+
bail: true,
|
|
63
|
+
reason: "undefined"
|
|
64
|
+
});
|
|
65
|
+
const IsEmail = Assert(isEmail, {
|
|
66
|
+
fqn: "@modulify/validator/IsEmail",
|
|
67
|
+
bail: true
|
|
68
|
+
});
|
|
69
|
+
const IsNull = Assert(isNull, {
|
|
70
|
+
fqn: "@modulify/validator/IsNull",
|
|
71
|
+
bail: true
|
|
72
|
+
});
|
|
73
|
+
const IsNumber = Assert(isNumber, {
|
|
74
|
+
fqn: "@modulify/validator/IsNumber",
|
|
75
|
+
bail: true
|
|
76
|
+
});
|
|
77
|
+
const IsString = Assert(isString, {
|
|
78
|
+
fqn: "@modulify/validator/IsString",
|
|
79
|
+
bail: true
|
|
80
|
+
});
|
|
81
|
+
const IsSymbol = Assert(isSymbol, {
|
|
82
|
+
fqn: "@modulify/validator/IsSymbol",
|
|
83
|
+
bail: true
|
|
84
|
+
});
|
|
85
|
+
const OneOf = (values, {
|
|
86
|
+
equalTo = (a, b) => a === b,
|
|
87
|
+
bail = false
|
|
88
|
+
} = {}) => {
|
|
89
|
+
const haystack = isArray(values) ? values : Object.values(values);
|
|
90
|
+
const oneOf = (value) => haystack.some((allowed) => equalTo(allowed, value));
|
|
91
|
+
return Assert(oneOf, {
|
|
92
|
+
fqn: "@modulify/validator/OneOf",
|
|
93
|
+
bail,
|
|
94
|
+
meta: haystack
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
export {
|
|
98
|
+
Assert,
|
|
99
|
+
HasLength,
|
|
100
|
+
IsBoolean,
|
|
101
|
+
IsDate,
|
|
102
|
+
IsDefined,
|
|
103
|
+
IsEmail,
|
|
104
|
+
IsNull,
|
|
105
|
+
IsNumber,
|
|
106
|
+
IsString,
|
|
107
|
+
IsSymbol,
|
|
108
|
+
OneOf
|
|
109
|
+
};
|