wysiwyv 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/LICENSE +21 -0
- package/README.md +150 -0
- package/dist/core.d.ts +7 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +147 -0
- package/dist/hooks/and.d.ts +10 -0
- package/dist/hooks/and.d.ts.map +1 -0
- package/dist/hooks/and.js +29 -0
- package/dist/hooks/any.d.ts +8 -0
- package/dist/hooks/any.d.ts.map +1 -0
- package/dist/hooks/any.js +11 -0
- package/dist/hooks/array.d.ts +18 -0
- package/dist/hooks/array.d.ts.map +1 -0
- package/dist/hooks/array.js +56 -0
- package/dist/hooks/bool.d.ts +8 -0
- package/dist/hooks/bool.d.ts.map +1 -0
- package/dist/hooks/bool.js +16 -0
- package/dist/hooks/datetime.d.ts +11 -0
- package/dist/hooks/datetime.d.ts.map +1 -0
- package/dist/hooks/datetime.js +88 -0
- package/dist/hooks/email.d.ts +8 -0
- package/dist/hooks/email.d.ts.map +1 -0
- package/dist/hooks/email.js +26 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +28 -0
- package/dist/hooks/int.d.ts +13 -0
- package/dist/hooks/int.d.ts.map +1 -0
- package/dist/hooks/int.js +24 -0
- package/dist/hooks/number.d.ts +15 -0
- package/dist/hooks/number.d.ts.map +1 -0
- package/dist/hooks/number.js +30 -0
- package/dist/hooks/object.d.ts +14 -0
- package/dist/hooks/object.d.ts.map +1 -0
- package/dist/hooks/object.js +80 -0
- package/dist/hooks/or.d.ts +10 -0
- package/dist/hooks/or.d.ts.map +1 -0
- package/dist/hooks/or.js +26 -0
- package/dist/hooks/string.d.ts +8 -0
- package/dist/hooks/string.d.ts.map +1 -0
- package/dist/hooks/string.js +16 -0
- package/dist/hooks/uuid.d.ts +9 -0
- package/dist/hooks/uuid.d.ts.map +1 -0
- package/dist/hooks/uuid.js +78 -0
- package/dist/hooks/val.d.ts +10 -0
- package/dist/hooks/val.d.ts.map +1 -0
- package/dist/hooks/val.js +24 -0
- package/dist/type/engine.d.ts +14 -0
- package/dist/type/engine.d.ts.map +1 -0
- package/dist/type/engine.js +1 -0
- package/dist/type/plugin.d.ts +26 -0
- package/dist/type/plugin.d.ts.map +1 -0
- package/dist/type/plugin.js +1 -0
- package/dist/type/template.d.ts +6 -0
- package/dist/type/template.d.ts.map +1 -0
- package/dist/type/template.js +1 -0
- package/dist/util/HookAssessment.d.ts +13 -0
- package/dist/util/HookAssessment.d.ts.map +1 -0
- package/dist/util/HookAssessment.js +42 -0
- package/dist/util/HookError.d.ts +14 -0
- package/dist/util/HookError.d.ts.map +1 -0
- package/dist/util/HookError.js +13 -0
- package/dist/util/parseHook.d.ts +5 -0
- package/dist/util/parseHook.d.ts.map +1 -0
- package/dist/util/parseHook.js +21 -0
- package/dist/util/stringify.d.ts +2 -0
- package/dist/util/stringify.d.ts.map +1 -0
- package/dist/util/stringify.js +34 -0
- package/dist/util/types.d.ts +15 -0
- package/dist/util/types.d.ts.map +1 -0
- package/dist/util/types.js +24 -0
- package/dist/wysiwyv-core.d.ts +3 -0
- package/dist/wysiwyv-core.d.ts.map +1 -0
- package/dist/wysiwyv-core.js +11 -0
- package/dist/wysiwyv.d.ts +3 -0
- package/dist/wysiwyv.d.ts.map +1 -0
- package/dist/wysiwyv.js +7 -0
- package/dist/wysiwyv.min.js +1 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jeremy "Ibi-Wan" Kent "...obi"
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
| _README_ | [USAGE](README-USAGE.md) | [INCLUDED PLUGINS](README-INCLUDED-PLUGINS.md) | [PLUGIN AUTHORING](README-PLUGIN-AUTHORING.md) | [INTEGRATION](README-INTEGRATION.md) |
|
|
2
|
+
| :------- | :----------------------- | :--------------------------------------------- | :--------------------------------------------- | :----------------------------------- |
|
|
3
|
+
|
|
4
|
+
# WYSIWYV
|
|
5
|
+
|
|
6
|
+
- [Why You Wyv](#why-you-wyv)
|
|
7
|
+
- [Included Plugins](#included-plugins)
|
|
8
|
+
- [Make Your Own Plugins](#make-your-own-plugins)
|
|
9
|
+
|
|
10
|
+
## What You See is What You Validate
|
|
11
|
+
|
|
12
|
+
### candidate data:
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"name": "John Smythe-Do",
|
|
17
|
+
"id": "c522fc68-ca27-4391-ac43-494c023e24a7",
|
|
18
|
+
"age": 27
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### validation template:
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"name": "$string",
|
|
27
|
+
"id": "$uuid",
|
|
28
|
+
"age": "$number"
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### plugins nest and compose:
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
{
|
|
36
|
+
dept: ["sales", "acquisitions"],
|
|
37
|
+
team: [
|
|
38
|
+
{ name: "Joan Duet", team: "sales" },
|
|
39
|
+
{ name: "Jonn Tray", team: "sales" },
|
|
40
|
+
{ name: "Jane Quay", team: "sales" }
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
{
|
|
47
|
+
dept: { $array: { $minlength: 1 } },
|
|
48
|
+
team: {
|
|
49
|
+
$array: { $each: {
|
|
50
|
+
$object: { $partial: {
|
|
51
|
+
team: "sales",
|
|
52
|
+
}},
|
|
53
|
+
}},
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### success is simple:
|
|
59
|
+
|
|
60
|
+
```js
|
|
61
|
+
{ success: true, errors: [] }
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### rejection is clear:
|
|
65
|
+
|
|
66
|
+
```js
|
|
67
|
+
{
|
|
68
|
+
success: false,
|
|
69
|
+
errors:[
|
|
70
|
+
{
|
|
71
|
+
message: "Type: Expected 'number', got value 'old enough'",
|
|
72
|
+
path: ".age"
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Why You Wyv?
|
|
79
|
+
|
|
80
|
+
- Templates: JSON
|
|
81
|
+
- Or directly in JS
|
|
82
|
+
- $-prefix for plugins
|
|
83
|
+
- Templates are Language-Agnostic
|
|
84
|
+
- Other language libraries to follow
|
|
85
|
+
- Tiny: Core is ~ 1.5kB
|
|
86
|
+
- Batteries: Included
|
|
87
|
+
- Strict: By Default
|
|
88
|
+
- Flexible: Rich Plugin API
|
|
89
|
+
- Fast Enough: Faster than yup and joi.
|
|
90
|
+
_(Still pursuing zod and valibot)_
|
|
91
|
+
- Simple: Reuse in:
|
|
92
|
+
- jest assertions
|
|
93
|
+
- express middleware
|
|
94
|
+
- cli tools
|
|
95
|
+
- custom exceptions
|
|
96
|
+
|
|
97
|
+
### The real reason:
|
|
98
|
+
|
|
99
|
+
- You like that the plugins are called wyverns.
|
|
100
|
+
|
|
101
|
+
[↑ top](#wysiwyv)
|
|
102
|
+
|
|
103
|
+
## Included Plugins
|
|
104
|
+
|
|
105
|
+
Read the [Included Plugins Documentation](README-INCLUDED-PLUGINS.md)
|
|
106
|
+
|
|
107
|
+
- $and / $or
|
|
108
|
+
- $any
|
|
109
|
+
- $array / $object / $plainobject
|
|
110
|
+
- $bool
|
|
111
|
+
- $isodate / $basicisodate / $strictisodate
|
|
112
|
+
- $email
|
|
113
|
+
- $int / $number
|
|
114
|
+
- $string
|
|
115
|
+
- $uuid
|
|
116
|
+
- $val
|
|
117
|
+
- Match values known at call time
|
|
118
|
+
- Ensure values match within data (back-references)
|
|
119
|
+
|
|
120
|
+
[↑ top](#wysiwyv)
|
|
121
|
+
|
|
122
|
+
## Make Your Own Plugins
|
|
123
|
+
|
|
124
|
+
Read the [Plugin Authoring Documentation](README-PLUGIN-AUTHORING.md)
|
|
125
|
+
|
|
126
|
+
- Full Type System enables clean interfacing
|
|
127
|
+
- See `src/type/plugin.ts` for contract
|
|
128
|
+
- See `src/hooks/string.ts` for a simple example
|
|
129
|
+
- Rich data: inject at setup time or call time, or add during validation
|
|
130
|
+
- All scoped to your plugin for safety
|
|
131
|
+
- Alternately, use a shared context to communicate across plugins
|
|
132
|
+
- See `src/hooks/val.ts` for context use example
|
|
133
|
+
- `evaluate` function provided for custom recursive descent
|
|
134
|
+
- See `src/hooks/object.ts` for descent example
|
|
135
|
+
|
|
136
|
+
[↑ top](#wysiwyv)
|
|
137
|
+
|
|
138
|
+
# TODO
|
|
139
|
+
|
|
140
|
+
- [x] Base Plugin Set
|
|
141
|
+
- [x] Test Coverage
|
|
142
|
+
- [x] Documentation
|
|
143
|
+
- [x] Basic Usage
|
|
144
|
+
- [x] Plugin Authoring
|
|
145
|
+
- [x] Included Plugins
|
|
146
|
+
- [x] Integration Examples
|
|
147
|
+
- [x] Benchmarks
|
|
148
|
+
- [ ] Distro Builds
|
|
149
|
+
- [ ] To Npm!
|
|
150
|
+
- [ ] Reuse Instances
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type WysiwyvEvaluatorFunction } from "./type/engine";
|
|
2
|
+
import { type PluginList } from "./type/plugin";
|
|
3
|
+
import type { MultiContext } from "./type/engine";
|
|
4
|
+
export declare const makeCore: (hooks: PluginList, pluginSetups: MultiContext) => {
|
|
5
|
+
evaluate: WysiwyvEvaluatorFunction;
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAK9D,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAyBhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,eAAO,MAAM,QAAQ,GAAI,OAAO,UAAU,EAAE,cAAc,YAAY;;CA4MrE,CAAC"}
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import {} from "./type/engine";
|
|
2
|
+
import {} from "./type/plugin";
|
|
3
|
+
import {} from "./type/template";
|
|
4
|
+
import {} from "./type/template";
|
|
5
|
+
import {} from "./type/plugin";
|
|
6
|
+
import {} from "./type/plugin";
|
|
7
|
+
import { HookAssessor } from "./util/HookAssessment";
|
|
8
|
+
import { errAttr, errConfig, errMissing, errType, errUnexpected, errValue, } from "./util/HookError";
|
|
9
|
+
import { getHookKey, getHookParams } from "./util/parseHook";
|
|
10
|
+
import { repr } from "./util/stringify";
|
|
11
|
+
import { isArray, isBoolean, isNull, isNumber, isPlainObject, isString, isUndefined, } from "./util/types";
|
|
12
|
+
export const makeCore = (hooks, pluginSetups) => {
|
|
13
|
+
const perHookSetups = Object.freeze({ ...pluginSetups });
|
|
14
|
+
const perHookContexts = {};
|
|
15
|
+
const sharedContext = {};
|
|
16
|
+
const handlerKeyCache = new Map();
|
|
17
|
+
const evaluate = (expected, candidate, path) => {
|
|
18
|
+
const key = getHookKey(expected);
|
|
19
|
+
if (!key)
|
|
20
|
+
return expectNormal(expected, candidate, path);
|
|
21
|
+
const hookSetup = perHookSetups[key] ?? {};
|
|
22
|
+
if (perHookContexts[key] === undefined) {
|
|
23
|
+
perHookContexts[key] = {};
|
|
24
|
+
}
|
|
25
|
+
const hookContext = perHookContexts[key];
|
|
26
|
+
let handler;
|
|
27
|
+
if (handlerKeyCache.has(key)) {
|
|
28
|
+
handler = handlerKeyCache.get(key);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
const hookPlugin = hooks.find((h) => h.handles(key));
|
|
32
|
+
handler = hookPlugin?.handlers[key];
|
|
33
|
+
if (handler) {
|
|
34
|
+
handlerKeyCache.set(key, handler);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (!handler)
|
|
38
|
+
return expectNormal(expected, candidate, path);
|
|
39
|
+
const params = getHookParams(expected, key);
|
|
40
|
+
const result = handler(candidate, expected, {
|
|
41
|
+
path,
|
|
42
|
+
params,
|
|
43
|
+
setup: hookSetup,
|
|
44
|
+
context: hookContext,
|
|
45
|
+
shared: sharedContext,
|
|
46
|
+
evaluate: evaluate,
|
|
47
|
+
});
|
|
48
|
+
return result;
|
|
49
|
+
};
|
|
50
|
+
const expectNormal = (expected, candidate, path) => {
|
|
51
|
+
switch (true) {
|
|
52
|
+
case isString(expected):
|
|
53
|
+
return expectString(expected, candidate, path);
|
|
54
|
+
case isNumber(expected):
|
|
55
|
+
return expectNumber(expected, candidate, path);
|
|
56
|
+
case isBoolean(expected):
|
|
57
|
+
return expectBoolean(expected, candidate, path);
|
|
58
|
+
case isNull(expected):
|
|
59
|
+
return expectNull(candidate, path);
|
|
60
|
+
case isArray(expected):
|
|
61
|
+
return expectArray(expected, candidate, path);
|
|
62
|
+
case isPlainObject(expected):
|
|
63
|
+
return expectObject(expected, candidate, path);
|
|
64
|
+
default:
|
|
65
|
+
return HookAssessor.fault(errConfig(`Unsupported value type in expected object: '${repr(expected)}'`, path));
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const expectString = (expected, candidate, path) => {
|
|
69
|
+
if (typeof candidate !== "string") {
|
|
70
|
+
return HookAssessor.fault(errType("string", candidate, path));
|
|
71
|
+
}
|
|
72
|
+
if (candidate !== expected) {
|
|
73
|
+
return HookAssessor.fault(errValue(expected, candidate, path));
|
|
74
|
+
}
|
|
75
|
+
return HookAssessor.SUCCESS;
|
|
76
|
+
};
|
|
77
|
+
const expectNumber = (expected, candidate, path) => {
|
|
78
|
+
if (typeof candidate !== "number") {
|
|
79
|
+
return HookAssessor.fault(errType("number", candidate, path));
|
|
80
|
+
}
|
|
81
|
+
if (candidate !== expected) {
|
|
82
|
+
return HookAssessor.fault(errValue(expected, candidate, path));
|
|
83
|
+
}
|
|
84
|
+
return HookAssessor.SUCCESS;
|
|
85
|
+
};
|
|
86
|
+
const expectBoolean = (expected, candidate, path) => {
|
|
87
|
+
if (typeof candidate !== "boolean") {
|
|
88
|
+
return HookAssessor.fault(errType("boolean", candidate, path));
|
|
89
|
+
}
|
|
90
|
+
if (candidate !== expected) {
|
|
91
|
+
return HookAssessor.fault(errValue(expected, candidate, path));
|
|
92
|
+
}
|
|
93
|
+
return HookAssessor.SUCCESS;
|
|
94
|
+
};
|
|
95
|
+
const expectNull = (candidate, path) => {
|
|
96
|
+
if (candidate !== null) {
|
|
97
|
+
return HookAssessor.fault(errType("null", candidate, path));
|
|
98
|
+
}
|
|
99
|
+
return HookAssessor.SUCCESS;
|
|
100
|
+
};
|
|
101
|
+
const expectArray = (expected, candidate, path) => {
|
|
102
|
+
if (!isArray(candidate)) {
|
|
103
|
+
return HookAssessor.fault(errType("array", candidate, path));
|
|
104
|
+
}
|
|
105
|
+
const errors = HookAssessor.start();
|
|
106
|
+
if (candidate.length !== expected.length) {
|
|
107
|
+
errors.fault(errAttr("Array length", expected.length, candidate.length, path));
|
|
108
|
+
}
|
|
109
|
+
for (let i = 0; i < expected.length; i++) {
|
|
110
|
+
if (isUndefined(candidate[i])) {
|
|
111
|
+
errors.fault(errMissing(`index ${i}`, expected[i], `${path}[${i}]`));
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const itemErrors = evaluate(expected[i], // not undefined per earlier check
|
|
115
|
+
candidate[i], `${path}[${i}]`);
|
|
116
|
+
errors.include(itemErrors);
|
|
117
|
+
}
|
|
118
|
+
return errors;
|
|
119
|
+
};
|
|
120
|
+
const expectObject = (expected, candidate, path) => {
|
|
121
|
+
if (!isPlainObject(candidate)) {
|
|
122
|
+
return HookAssessor.fault(errType("object", candidate, path));
|
|
123
|
+
}
|
|
124
|
+
const errors = HookAssessor.start();
|
|
125
|
+
const expectedKeys = Object.keys(expected);
|
|
126
|
+
const candidateKeys = Object.keys(candidate);
|
|
127
|
+
const missingKeys = expectedKeys.filter((k) => !candidateKeys.includes(k));
|
|
128
|
+
const extraKeys = candidateKeys.filter((k) => !expectedKeys.includes(k));
|
|
129
|
+
missingKeys.forEach((k) => {
|
|
130
|
+
errors.fault(errMissing(`${k}`, expected[k], `${path}.${k}`));
|
|
131
|
+
});
|
|
132
|
+
extraKeys.forEach((k) => {
|
|
133
|
+
errors.fault(errUnexpected(k, candidate[k], `${path}.${k}`));
|
|
134
|
+
});
|
|
135
|
+
for (const key in expected) {
|
|
136
|
+
if (missingKeys.includes(key))
|
|
137
|
+
continue; // already reported
|
|
138
|
+
const keyErrors = evaluate(expected[key], // not undefined per earlier check
|
|
139
|
+
candidate[key], `${path}.${key}`);
|
|
140
|
+
errors.include(keyErrors);
|
|
141
|
+
}
|
|
142
|
+
return errors;
|
|
143
|
+
};
|
|
144
|
+
return {
|
|
145
|
+
evaluate,
|
|
146
|
+
};
|
|
147
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { HookValue } from "../type/template";
|
|
2
|
+
import type { ContextObject } from "../type/plugin";
|
|
3
|
+
import type { WyvPlugin } from "../type/plugin";
|
|
4
|
+
export declare const WYV_KEY_AND = "$and";
|
|
5
|
+
type WyvParams = HookValue[];
|
|
6
|
+
type WyvSetup = unknown;
|
|
7
|
+
type WyvContext = ContextObject;
|
|
8
|
+
declare const andWyvern: WyvPlugin<WyvParams, WyvSetup, WyvContext>;
|
|
9
|
+
export default andWyvern;
|
|
10
|
+
//# sourceMappingURL=and.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"and.d.ts","sourceRoot":"","sources":["../../src/hooks/and.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAIhD,eAAO,MAAM,WAAW,SAAS,CAAC;AAElC,KAAK,SAAS,GAAG,SAAS,EAAE,CAAC;AAC7B,KAAK,QAAQ,GAAG,OAAO,CAAC;AACxB,KAAK,UAAU,GAAG,aAAa,CAAC;AAEhC,QAAA,MAAM,SAAS,EAAE,SAAS,CAAC,SAAS,EAAE,QAAQ,EAAE,UAAU,CAqCzD,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { HookAssessor } from "../util/HookAssessment";
|
|
2
|
+
import { errColl, errConfig } from "../util/HookError";
|
|
3
|
+
export const WYV_KEY_AND = "$and";
|
|
4
|
+
const andWyvern = {
|
|
5
|
+
handles: (value) => [WYV_KEY_AND].includes(value),
|
|
6
|
+
handlers: {
|
|
7
|
+
[WYV_KEY_AND]: (value, _expected, { path, params, evaluate }) => {
|
|
8
|
+
if (!Array.isArray(params)) {
|
|
9
|
+
return HookAssessor.fault(errConfig("$and value should be an array of templates", path));
|
|
10
|
+
}
|
|
11
|
+
if (params.length === 0) {
|
|
12
|
+
// AND(<no arguments>) is defined as TRUE for boolean algebra
|
|
13
|
+
return HookAssessor.SUCCESS;
|
|
14
|
+
}
|
|
15
|
+
const errors = HookAssessor.start();
|
|
16
|
+
for (const template of params) {
|
|
17
|
+
const templateErrors = evaluate(template, value, path);
|
|
18
|
+
errors.include(templateErrors);
|
|
19
|
+
}
|
|
20
|
+
if (errors.success) {
|
|
21
|
+
return HookAssessor.SUCCESS;
|
|
22
|
+
}
|
|
23
|
+
const a = HookAssessor.fault(errColl("$and", path));
|
|
24
|
+
const final = a.include(errors);
|
|
25
|
+
return final;
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
export default andWyvern;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ContextObject, WyvPlugin } from "../type/plugin";
|
|
2
|
+
export declare const WYV_KEY_ANY = "$any";
|
|
3
|
+
type WyvParams = unknown;
|
|
4
|
+
type WyvSetup = unknown;
|
|
5
|
+
type WyvContext = ContextObject;
|
|
6
|
+
declare const anyWyvern: WyvPlugin<WyvParams, WyvSetup, WyvContext>;
|
|
7
|
+
export default anyWyvern;
|
|
8
|
+
//# sourceMappingURL=any.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"any.d.ts","sourceRoot":"","sources":["../../src/hooks/any.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG/D,eAAO,MAAM,WAAW,SAAS,CAAC;AAElC,KAAK,SAAS,GAAG,OAAO,CAAC;AACzB,KAAK,QAAQ,GAAG,OAAO,CAAC;AACxB,KAAK,UAAU,GAAG,aAAa,CAAC;AAEhC,QAAA,MAAM,SAAS,EAAE,SAAS,CAAC,SAAS,EAAE,QAAQ,EAAE,UAAU,CAOzD,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { HookAssessor } from "../util/HookAssessment";
|
|
2
|
+
export const WYV_KEY_ANY = "$any";
|
|
3
|
+
const anyWyvern = {
|
|
4
|
+
handles: (value) => [WYV_KEY_ANY].includes(value),
|
|
5
|
+
handlers: {
|
|
6
|
+
[WYV_KEY_ANY]: () => {
|
|
7
|
+
return HookAssessor.SUCCESS;
|
|
8
|
+
},
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
export default anyWyvern;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ContextObject } from "../type/plugin";
|
|
2
|
+
import type { WyvPlugin } from "../type/plugin";
|
|
3
|
+
export declare const WYV_KEY_ARRAY = "$array";
|
|
4
|
+
export declare const WYV_ARRAY_PARAM_LENGTH = "$length";
|
|
5
|
+
export declare const WYV_ARRAY_PARAM_MINLENGTH = "$minlength";
|
|
6
|
+
export declare const WYV_ARRAY_PARAM_MAXLENGTH = "$maxlength";
|
|
7
|
+
export declare const WYV_ARRAY_PARAM_EACH = "$each";
|
|
8
|
+
type WyvParams = {
|
|
9
|
+
[WYV_ARRAY_PARAM_LENGTH]?: number;
|
|
10
|
+
[WYV_ARRAY_PARAM_MINLENGTH]?: number;
|
|
11
|
+
[WYV_ARRAY_PARAM_MAXLENGTH]?: number;
|
|
12
|
+
[WYV_ARRAY_PARAM_EACH]?: unknown;
|
|
13
|
+
};
|
|
14
|
+
type WyvSetup = unknown;
|
|
15
|
+
type WyvContext = ContextObject;
|
|
16
|
+
declare const arrayWyvern: WyvPlugin<WyvParams, WyvSetup, WyvContext>;
|
|
17
|
+
export default arrayWyvern;
|
|
18
|
+
//# sourceMappingURL=array.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../../src/hooks/array.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAKhD,eAAO,MAAM,aAAa,WAAW,CAAC;AACtC,eAAO,MAAM,sBAAsB,YAAY,CAAC;AAChD,eAAO,MAAM,yBAAyB,eAAe,CAAC;AACtD,eAAO,MAAM,yBAAyB,eAAe,CAAC;AACtD,eAAO,MAAM,oBAAoB,UAAU,CAAC;AAE5C,KAAK,SAAS,GAAG;IACf,CAAC,sBAAsB,CAAC,CAAC,EAAE,MAAM,CAAC;IAClC,CAAC,yBAAyB,CAAC,CAAC,EAAE,MAAM,CAAC;IACrC,CAAC,yBAAyB,CAAC,CAAC,EAAE,MAAM,CAAC;IACrC,CAAC,oBAAoB,CAAC,CAAC,EAAE,OAAO,CAAC;CAClC,CAAC;AACF,KAAK,QAAQ,GAAG,OAAO,CAAC;AACxB,KAAK,UAAU,GAAG,aAAa,CAAC;AAEhC,QAAA,MAAM,WAAW,EAAE,SAAS,CAAC,SAAS,EAAE,QAAQ,EAAE,UAAU,CA8F3D,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { HookAssessor } from "../util/HookAssessment";
|
|
2
|
+
import { errAttr, errConfig, errType } from "../util/HookError";
|
|
3
|
+
import { isArray, isDefined, isNumber, isObject, notNull } from "../util/types";
|
|
4
|
+
export const WYV_KEY_ARRAY = "$array";
|
|
5
|
+
export const WYV_ARRAY_PARAM_LENGTH = "$length";
|
|
6
|
+
export const WYV_ARRAY_PARAM_MINLENGTH = "$minlength";
|
|
7
|
+
export const WYV_ARRAY_PARAM_MAXLENGTH = "$maxlength";
|
|
8
|
+
export const WYV_ARRAY_PARAM_EACH = "$each";
|
|
9
|
+
const arrayWyvern = {
|
|
10
|
+
handles: (value) => [WYV_KEY_ARRAY].includes(value),
|
|
11
|
+
handlers: {
|
|
12
|
+
[WYV_KEY_ARRAY]: (value, _expected, { path, params, evaluate }) => {
|
|
13
|
+
if (!isArray(value)) {
|
|
14
|
+
return HookAssessor.fault(errType("array", value, path));
|
|
15
|
+
}
|
|
16
|
+
const errors = HookAssessor.start();
|
|
17
|
+
const normalizedParams = isObject(params)
|
|
18
|
+
? params
|
|
19
|
+
: { [WYV_ARRAY_PARAM_EACH]: params };
|
|
20
|
+
const { [WYV_ARRAY_PARAM_LENGTH]: length, [WYV_ARRAY_PARAM_MINLENGTH]: minLength, [WYV_ARRAY_PARAM_MAXLENGTH]: maxLength, [WYV_ARRAY_PARAM_EACH]: each, ...rest } = normalizedParams;
|
|
21
|
+
const isParametric = isDefined(length) ||
|
|
22
|
+
isDefined(minLength) ||
|
|
23
|
+
isDefined(maxLength) ||
|
|
24
|
+
isDefined(each);
|
|
25
|
+
if (isParametric && Object.keys(rest).length > 0) {
|
|
26
|
+
errors.fault(errConfig(`Ignored unknown $array parameters: '${Object.keys(rest)}'`, path));
|
|
27
|
+
}
|
|
28
|
+
const useEach = isParametric
|
|
29
|
+
? each
|
|
30
|
+
: Object.keys(rest).length > 0
|
|
31
|
+
? rest
|
|
32
|
+
: null;
|
|
33
|
+
if (isDefined(length) && value.length !== length) {
|
|
34
|
+
errors.fault(errAttr(WYV_KEY_ARRAY + "." + WYV_ARRAY_PARAM_LENGTH, length, value.length, path));
|
|
35
|
+
}
|
|
36
|
+
if (isDefined(minLength) &&
|
|
37
|
+
isNumber(minLength) &&
|
|
38
|
+
value.length < minLength) {
|
|
39
|
+
errors.fault(errAttr(WYV_KEY_ARRAY + "." + WYV_ARRAY_PARAM_MINLENGTH, minLength, value.length, path));
|
|
40
|
+
}
|
|
41
|
+
if (isDefined(maxLength) &&
|
|
42
|
+
isNumber(maxLength) &&
|
|
43
|
+
value.length > maxLength) {
|
|
44
|
+
errors.fault(errAttr(WYV_KEY_ARRAY + "." + WYV_ARRAY_PARAM_MAXLENGTH, maxLength, value.length, path));
|
|
45
|
+
}
|
|
46
|
+
if (notNull(useEach)) {
|
|
47
|
+
for (const [index, element] of value.entries()) {
|
|
48
|
+
const elementErrors = evaluate(useEach, element, `${path}[${index}]`);
|
|
49
|
+
errors.include(elementErrors);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return errors;
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
export default arrayWyvern;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ContextObject, WyvPlugin } from "../type/plugin";
|
|
2
|
+
export declare const WYV_KEY_BOOL = "$bool";
|
|
3
|
+
type WyvParams = unknown;
|
|
4
|
+
type WyvSetup = unknown;
|
|
5
|
+
type WyvContext = ContextObject;
|
|
6
|
+
declare const boolWyvern: WyvPlugin<WyvParams, WyvSetup, WyvContext>;
|
|
7
|
+
export default boolWyvern;
|
|
8
|
+
//# sourceMappingURL=bool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bool.d.ts","sourceRoot":"","sources":["../../src/hooks/bool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAM/D,eAAO,MAAM,YAAY,UAAU,CAAC;AAEpC,KAAK,SAAS,GAAG,OAAO,CAAC;AACzB,KAAK,QAAQ,GAAG,OAAO,CAAC;AACxB,KAAK,UAAU,GAAG,aAAa,CAAC;AAEhC,QAAA,MAAM,UAAU,EAAE,SAAS,CAAC,SAAS,EAAE,QAAQ,EAAE,UAAU,CAU1D,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { HookAssessor } from "../util/HookAssessment";
|
|
2
|
+
import { isBoolean } from "../util/types";
|
|
3
|
+
import { errType } from "../util/HookError";
|
|
4
|
+
export const WYV_KEY_BOOL = "$bool";
|
|
5
|
+
const boolWyvern = {
|
|
6
|
+
handles: (value) => [WYV_KEY_BOOL].includes(value),
|
|
7
|
+
handlers: {
|
|
8
|
+
[WYV_KEY_BOOL]: (value, _expected, { path }) => {
|
|
9
|
+
if (!isBoolean(value)) {
|
|
10
|
+
return HookAssessor.fault(errType("boolean", value, path));
|
|
11
|
+
}
|
|
12
|
+
return HookAssessor.SUCCESS;
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
export default boolWyvern;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ContextObject, HookKey } from "../type/plugin";
|
|
2
|
+
import type { WyvPlugin } from "../type/plugin";
|
|
3
|
+
export declare const WYV_KEY_ISODATE: HookKey;
|
|
4
|
+
export declare const WYV_KEY_BASICISODATE: HookKey;
|
|
5
|
+
export declare const WYV_KEY_STRICTISODATE: HookKey;
|
|
6
|
+
type WyvParams = unknown;
|
|
7
|
+
type WyvSetup = unknown;
|
|
8
|
+
type WyvContext = ContextObject;
|
|
9
|
+
declare const datetimeWyvern: WyvPlugin<WyvParams, WyvSetup, WyvContext>;
|
|
10
|
+
export default datetimeWyvern;
|
|
11
|
+
//# sourceMappingURL=datetime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datetime.d.ts","sourceRoot":"","sources":["../../src/hooks/datetime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AA+ChD,eAAO,MAAM,eAAe,EAAE,OAAoB,CAAC;AACnD,eAAO,MAAM,oBAAoB,EAAE,OAAyB,CAAC;AAC7D,eAAO,MAAM,qBAAqB,EAAE,OAA0B,CAAC;AAgC/D,KAAK,SAAS,GAAG,OAAO,CAAC;AACzB,KAAK,QAAQ,GAAG,OAAO,CAAC;AACxB,KAAK,UAAU,GAAG,aAAa,CAAC;AAEhC,QAAA,MAAM,cAAc,EAAE,SAAS,CAAC,SAAS,EAAE,QAAQ,EAAE,UAAU,CAsB9D,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { HookAssessor } from "../util/HookAssessment";
|
|
2
|
+
import { errType } from "../util/HookError";
|
|
3
|
+
import { isString } from "../util/types";
|
|
4
|
+
const YEAR = "(?:\\d{4})"; // 0000-9999
|
|
5
|
+
const MONTH = "(?:0[1-9]|1[0-2])"; // 01-12;
|
|
6
|
+
const DAY = `(?:0[1-9]|[12]\\d|3[01])`; // 01-31
|
|
7
|
+
const HOUR = `(?:[01]\\d|2[0-3])`; // 00-23
|
|
8
|
+
const MINUTE = "(?:[0-5]\\d)"; // 00-59
|
|
9
|
+
const SECOND = "(?:[0-5]\\d)"; // 00-59
|
|
10
|
+
const MILLI_EXT = "(?:[,.]\\d+)"; // .123...
|
|
11
|
+
const MILLI_RFC = "(?:\\.\\d+)"; // .123...
|
|
12
|
+
// Validates numeric ranges: YYYY-MM-DD
|
|
13
|
+
const DATE_EXT = `(?:${YEAR}-${MONTH}-${DAY})`;
|
|
14
|
+
const DATE_BAS = `(?:${YEAR}${MONTH}${DAY})`;
|
|
15
|
+
// Validates numeric ranges: HH:mm:ss.SSS (seconds/ms optional)
|
|
16
|
+
const TIME_EXT = `(?:${HOUR}:${MINUTE}(?::${SECOND}(?:${MILLI_EXT})?)?)`;
|
|
17
|
+
const TIME_BAS = `(?:${HOUR}${MINUTE}(?:${SECOND}(?:${MILLI_EXT})?)?)`;
|
|
18
|
+
const TIME_RFC = `(?:${HOUR}:${MINUTE}(?::${SECOND}(?:${MILLI_RFC})?)?)`;
|
|
19
|
+
// Validates Z or ±HH:mm or ±HHmm
|
|
20
|
+
const ZONE_EXT = `(?:Z|[+-]${HOUR}:?${MINUTE})`;
|
|
21
|
+
const ZONE_BAS = `(?:Z|[+-]${HOUR}${MINUTE})`;
|
|
22
|
+
const ZONE_RFC = `(?:Z|[+-]${HOUR}:${MINUTE}|-00:00)`;
|
|
23
|
+
const make8601 = () => {
|
|
24
|
+
return new RegExp(`^${DATE_EXT}T${TIME_EXT}${ZONE_EXT}$`, "i");
|
|
25
|
+
};
|
|
26
|
+
const RE_ISO_8601 = make8601();
|
|
27
|
+
const make8601basic = () => {
|
|
28
|
+
return new RegExp(`^${DATE_BAS}T${TIME_BAS}${ZONE_BAS}$`, "i");
|
|
29
|
+
};
|
|
30
|
+
const RE_ISO_8601_BASIC = make8601basic();
|
|
31
|
+
const make3339 = () => {
|
|
32
|
+
// Full Pattern: YYYY-MM-DDTHH:mm:ss.sssZ
|
|
33
|
+
return new RegExp(`^${DATE_EXT}[T ]${TIME_RFC}${ZONE_RFC}$`, "i");
|
|
34
|
+
};
|
|
35
|
+
const RE_ISO_3339 = make3339();
|
|
36
|
+
export const WYV_KEY_ISODATE = "$isodate";
|
|
37
|
+
export const WYV_KEY_BASICISODATE = "$basicisodate";
|
|
38
|
+
export const WYV_KEY_STRICTISODATE = "$strictisodate";
|
|
39
|
+
const checkParsedDate = (value) => {
|
|
40
|
+
const date = new Date(value);
|
|
41
|
+
return !Number.isNaN(date.getTime());
|
|
42
|
+
};
|
|
43
|
+
const checkIsoDate = (value) => {
|
|
44
|
+
if (!isString(value)) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
if (!RE_ISO_8601.test(value))
|
|
48
|
+
return false;
|
|
49
|
+
return checkParsedDate(value);
|
|
50
|
+
};
|
|
51
|
+
const checkBasicIsoDate = (value) => {
|
|
52
|
+
if (!isString(value)) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
if (!RE_ISO_8601_BASIC.test(value))
|
|
56
|
+
return false;
|
|
57
|
+
// return checkParsedDate(value); // built-in can't parse basic.
|
|
58
|
+
return true;
|
|
59
|
+
};
|
|
60
|
+
const checkStrictIsoDate = (value) => {
|
|
61
|
+
if (!isString(value)) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
if (!RE_ISO_3339.test(value))
|
|
65
|
+
return false;
|
|
66
|
+
return checkParsedDate(value);
|
|
67
|
+
};
|
|
68
|
+
const datetimeWyvern = {
|
|
69
|
+
handles: (value) => [WYV_KEY_ISODATE, WYV_KEY_BASICISODATE, WYV_KEY_STRICTISODATE].includes(value),
|
|
70
|
+
handlers: {
|
|
71
|
+
[WYV_KEY_ISODATE]: (value, _expected, { path }) => {
|
|
72
|
+
if (!checkIsoDate(value))
|
|
73
|
+
return HookAssessor.fault(errType("ISO 8601 date", value, path));
|
|
74
|
+
return HookAssessor.SUCCESS;
|
|
75
|
+
},
|
|
76
|
+
[WYV_KEY_BASICISODATE]: (value, _expected, { path }) => {
|
|
77
|
+
if (!checkBasicIsoDate(value))
|
|
78
|
+
return HookAssessor.fault(errType("Basic ISO 8601 date", value, path));
|
|
79
|
+
return HookAssessor.SUCCESS;
|
|
80
|
+
},
|
|
81
|
+
[WYV_KEY_STRICTISODATE]: (value, _expected, { path }) => {
|
|
82
|
+
if (!checkStrictIsoDate(value))
|
|
83
|
+
return HookAssessor.fault(errType("RFC 3339 date", value, path));
|
|
84
|
+
return HookAssessor.SUCCESS;
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
export default datetimeWyvern;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ContextObject, WyvPlugin } from "../type/plugin";
|
|
2
|
+
export declare const WYV_KEY_EMAIL = "$email";
|
|
3
|
+
type WyvParams = unknown;
|
|
4
|
+
type WyvSetup = unknown;
|
|
5
|
+
type WyvContext = ContextObject;
|
|
6
|
+
declare const emailWyvern: WyvPlugin<WyvParams, WyvSetup, WyvContext>;
|
|
7
|
+
export default emailWyvern;
|
|
8
|
+
//# sourceMappingURL=email.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../../src/hooks/email.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAa/D,eAAO,MAAM,aAAa,WAAW,CAAC;AAEtC,KAAK,SAAS,GAAG,OAAO,CAAC;AACzB,KAAK,QAAQ,GAAG,OAAO,CAAC;AACxB,KAAK,UAAU,GAAG,aAAa,CAAC;AAEhC,QAAA,MAAM,WAAW,EAAE,SAAS,CAAC,SAAS,EAAE,QAAQ,EAAE,UAAU,CAc3D,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { HookAssessor } from "../util/HookAssessment";
|
|
2
|
+
import { isString } from "../util/types";
|
|
3
|
+
import { errType } from "../util/HookError";
|
|
4
|
+
const ncg = (s) => `(?:${s})`;
|
|
5
|
+
const CHARS = `[a-zA-Z0-9_%+\\-]+`;
|
|
6
|
+
const DOT_CHARS = ncg(`\\.${CHARS}`);
|
|
7
|
+
const DOTTED_CHARS_ANY = ncg(`${CHARS}${DOT_CHARS}*`);
|
|
8
|
+
const DOTTED_CHARS_SOME = ncg(`${CHARS}${DOT_CHARS}+`);
|
|
9
|
+
const EMAIL = `${DOTTED_CHARS_ANY}@${DOTTED_CHARS_SOME}`;
|
|
10
|
+
const RE_EMAIL_LOOSE = new RegExp(`^${EMAIL}$`);
|
|
11
|
+
export const WYV_KEY_EMAIL = "$email";
|
|
12
|
+
const emailWyvern = {
|
|
13
|
+
handles: (value) => [WYV_KEY_EMAIL].includes(value),
|
|
14
|
+
handlers: {
|
|
15
|
+
[WYV_KEY_EMAIL]: (value, _expected, { path }) => {
|
|
16
|
+
if (!isString(value)) {
|
|
17
|
+
return HookAssessor.fault(errType("string", value, path));
|
|
18
|
+
}
|
|
19
|
+
if (!RE_EMAIL_LOOSE.test(value)) {
|
|
20
|
+
return HookAssessor.fault(errType("valid email address", value, path));
|
|
21
|
+
}
|
|
22
|
+
return HookAssessor.SUCCESS;
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
export default emailWyvern;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAgBjD,eAAO,MAAM,YAAY,EAAE,UAc1B,CAAC"}
|