typia 3.7.0-dev.20230401-2 → 3.7.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/README.md +9 -1
- package/lib/CustomValidatorMap.d.ts +110 -0
- package/lib/CustomValidatorMap.js +3 -0
- package/lib/CustomValidatorMap.js.map +1 -0
- package/lib/functional/$dictionary.d.ts +2 -1
- package/lib/functional/$dictionary.js.map +1 -1
- package/lib/functional/$is_custom.js +2 -1
- package/lib/functional/$is_custom.js.map +1 -1
- package/lib/module.d.ts +9 -8
- package/lib/module.js +14 -12
- package/lib/module.js.map +1 -1
- package/package.json +1 -1
- package/src/CustomValidatorMap.ts +126 -0
- package/src/functional/$dictionary.ts +5 -2
- package/src/functional/$is_custom.ts +1 -1
- package/src/module.ts +22 -23
- package/src/programmers/internal/check_custom.ts +41 -41
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
export function is<T>(input: unknown | T): input is T; // returns boolean
|
|
11
11
|
export function assert<T>(input: unknown | T): T; // throws TypeGuardError
|
|
12
12
|
export function validate<T>(input: unknown | T): IValidation<T>; // detailed
|
|
13
|
+
export const customValidators: CustomValidatorMap; // can add custom validators
|
|
13
14
|
|
|
14
15
|
// STRICT VALIDATORS
|
|
15
16
|
export function equals<T>(input: unknown | T): input is T;
|
|
@@ -169,6 +170,7 @@ For more details, refer to the [Guide Documents (wiki)](https://github.com/samch
|
|
|
169
170
|
> - [strict validators](https://github.com/samchon/typia/wiki/Runtime-Validators#strict-validators)
|
|
170
171
|
> - [factory functions](https://github.com/samchon/typia/wiki/Runtime-Validators#factory-functions)
|
|
171
172
|
> - [comment tags](https://github.com/samchon/typia/wiki/Runtime-Validators#comment-tags)
|
|
173
|
+
> - [custom validators](https://github.com/samchon/typia/wiki/Runtime-Validators#custom-validators)
|
|
172
174
|
> - **Enhanced JSON**
|
|
173
175
|
> - [JSON schema](https://github.com/samchon/typia/wiki/Enhanced-JSON#json-schema)
|
|
174
176
|
> - [`parse()` functions](https://github.com/samchon/typia/wiki/Enhanced-JSON#parse-functions)
|
|
@@ -198,6 +200,9 @@ export function createValidate<T>(): (input: unknown) => IValidation<T>;
|
|
|
198
200
|
export function createEquals<T>(): (input: unknown) => input is T;
|
|
199
201
|
export function createAssertEquals<T>(): (input: unknown) => T;
|
|
200
202
|
export function createValidateEquals<T>(): (input: unknown) => IValidation<T>;
|
|
203
|
+
|
|
204
|
+
// YOU CAN ADD CUSTOM VALIDATORS
|
|
205
|
+
export const customValidators: CustomValidatorMap;
|
|
201
206
|
```
|
|
202
207
|
|
|
203
208
|
`typia` supports three type of validator functions:
|
|
@@ -210,7 +215,10 @@ export function createValidateEquals<T>(): (input: unknown) => IValidation<T>;
|
|
|
210
215
|
|
|
211
216
|
Also, if you want more strict validator functions that even do not allowing superfluous properties not written in the type `T`, you can use those functions instead; `equals()`, `assertEquals()`, `validateEquals()`. Otherwise you want to create resuable validator functions, you can utilize factory functions like `createIs()` instead.
|
|
212
217
|
|
|
213
|
-
When you want to add special validation logics, like limiting range of numeric values, you can do it through comment tags. If you want to know about
|
|
218
|
+
When you want to add special validation logics, like limiting range of numeric values, you can do it through comment tags. Furthermore, you can add your custom validator logics. If you want to know about them, visit the Guide Documents:
|
|
219
|
+
|
|
220
|
+
- [Features > Runtime Validators > Comment Tags](https://github.com/samchon/typia/wiki/Runtime-Validators#comment-tags)
|
|
221
|
+
- [Features > Runtime Validators > Custom Validators](https://github.com/samchon/typia/wiki/Runtime-Validators#comment-tags).
|
|
214
222
|
|
|
215
223
|
### Enhanced JSON
|
|
216
224
|
```typescript
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Customizable } from "./typings/Customizable";
|
|
2
|
+
/**
|
|
3
|
+
* Map of custom validators.
|
|
4
|
+
*
|
|
5
|
+
* Map of custom validator functions, storing tag name and type of target value
|
|
6
|
+
* as key, and custom validator function as value.
|
|
7
|
+
*
|
|
8
|
+
* When you want to add a custom validation logic utilizing comment tags, you
|
|
9
|
+
* can insert a custom validator function with specific tag name and type of
|
|
10
|
+
* the target value like below.
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* typia.customValidators.insert("powerOf")("number")(
|
|
14
|
+
* (text: string) => {
|
|
15
|
+
* const denominator: number = Math.log(Number(text));
|
|
16
|
+
* return (value: number) => {
|
|
17
|
+
* value = Math.log(value) / denominator;
|
|
18
|
+
* return value === Math.floor(value);
|
|
19
|
+
* };
|
|
20
|
+
* }
|
|
21
|
+
* );
|
|
22
|
+
* typia.customValidators.insert("dollar")("string")(
|
|
23
|
+
* () => (value: string) => value.startsWith("$"),
|
|
24
|
+
* );
|
|
25
|
+
*
|
|
26
|
+
* interface TagCustom {
|
|
27
|
+
* /**
|
|
28
|
+
* * @powerOf 10
|
|
29
|
+
* *\/
|
|
30
|
+
* powerOf: number;
|
|
31
|
+
*
|
|
32
|
+
* /**
|
|
33
|
+
* * @dollar
|
|
34
|
+
* *\/
|
|
35
|
+
* dollar: string;
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @author Jeongho Nam - https://github.com/samchon
|
|
40
|
+
*/
|
|
41
|
+
export interface CustomValidatorMap {
|
|
42
|
+
/**
|
|
43
|
+
* Get number of stored tags.
|
|
44
|
+
*
|
|
45
|
+
* @return Number of stored tags
|
|
46
|
+
*/
|
|
47
|
+
size(): number;
|
|
48
|
+
/**
|
|
49
|
+
* Get number of stored types of the specified tag name.
|
|
50
|
+
*
|
|
51
|
+
* In other words, number of stored custom validator functions of
|
|
52
|
+
* the specified tag name.
|
|
53
|
+
*
|
|
54
|
+
* @param name Tag name
|
|
55
|
+
* @return Number of stored types function
|
|
56
|
+
*/
|
|
57
|
+
size(name: string): number;
|
|
58
|
+
/**
|
|
59
|
+
* Test whether custom validator function exists or not.
|
|
60
|
+
*
|
|
61
|
+
* @param name Tag name
|
|
62
|
+
* @param type Type of the target value
|
|
63
|
+
* @returns Whether exists or not
|
|
64
|
+
*/
|
|
65
|
+
has: (name: string) => (type: keyof Customizable) => boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Get custom validator function.
|
|
68
|
+
*
|
|
69
|
+
* @param name Tag name
|
|
70
|
+
* @param type Type of the target value
|
|
71
|
+
* @returns Custom validator function or undefined value
|
|
72
|
+
*/
|
|
73
|
+
get(name: string): <Type extends keyof Customizable>(type: Type) => CustomValidatorMap.Closure<Type> | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* Insert a new custom validator function.
|
|
76
|
+
*
|
|
77
|
+
* You can add a custom validation logic utilizing comment tags,
|
|
78
|
+
* by inserting a function which returns a boolean value, with specific
|
|
79
|
+
* tag name and type of the target value.
|
|
80
|
+
*
|
|
81
|
+
* However, if you try to insert a duplicated tag name and type, the
|
|
82
|
+
* closure function would not be enrolled and `false` value would be
|
|
83
|
+
* returned.
|
|
84
|
+
*
|
|
85
|
+
* @param name Tag name
|
|
86
|
+
* @param type Type of the target value
|
|
87
|
+
* @param closure Custom validator function
|
|
88
|
+
* @returns Whether succeeded to insert or not
|
|
89
|
+
*/
|
|
90
|
+
insert(name: string): <Type extends keyof Customizable>(type: Type) => (closure: CustomValidatorMap.Closure<Type>) => boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Erase custom validator function.
|
|
93
|
+
*
|
|
94
|
+
* @param name Tag name
|
|
95
|
+
* @param type Type of the target value
|
|
96
|
+
* @returns Whether succeeded to erase or not
|
|
97
|
+
*/
|
|
98
|
+
erase(name: string): (type: keyof Customizable) => boolean;
|
|
99
|
+
}
|
|
100
|
+
export declare namespace CustomValidatorMap {
|
|
101
|
+
/**
|
|
102
|
+
* Type of closure function of custom validation.
|
|
103
|
+
*
|
|
104
|
+
* @template Type Type of the target value
|
|
105
|
+
* @param text Text of the tag. For example, if the tag is `@powerOf 10`, `text` is 10.
|
|
106
|
+
* @param value Value to validate
|
|
107
|
+
* @returns Whether the value is valid or not
|
|
108
|
+
*/
|
|
109
|
+
type Closure<Type extends keyof Customizable> = (text: string) => (value: Customizable[Type]) => boolean;
|
|
110
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CustomValidatorMap.js","sourceRoot":"","sources":["../src/CustomValidatorMap.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import { Customizable } from "../typings/Customizable";
|
|
2
|
+
export declare const $dictionary: Map<string, Map<keyof Customizable, (tagText: string) => (value: any) => boolean>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"$dictionary.js","sourceRoot":"","sources":["../../src/functional/$dictionary.ts"],"names":[],"mappings":";;;AAEa,QAAA,WAAW,GAAG,CAAC;;IACxB,IAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"$dictionary.js","sourceRoot":"","sources":["../../src/functional/$dictionary.ts"],"names":[],"mappings":";;;AAEa,QAAA,WAAW,GAAG,CAAC;;IACxB,IAAM,IAAI,GASN,OAAO,MAAM,KAAK,QAAQ;QAC1B,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ;QAClC,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAC3C,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,WAAW;QAC/C,CAAC,CAAE,MAAc;QACjB,CAAC,CAAE,MAAc,CAAC;IAC1B,OAAO,OAAC,IAAI,CAAC,wBAAwB,oCAA7B,IAAI,CAAC,wBAAwB,GAAK,IAAI,GAAG,EAAE,EAAC,CAAC;AACzD,CAAC,CAAC,EAAE,CAAC"}
|
|
@@ -3,7 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.$is_custom = void 0;
|
|
4
4
|
var _dictionary_1 = require("./$dictionary");
|
|
5
5
|
function $is_custom(name, type, text, value) {
|
|
6
|
-
var
|
|
6
|
+
var _a;
|
|
7
|
+
var validator = (_a = _dictionary_1.$dictionary.get(name)) === null || _a === void 0 ? void 0 : _a.get(type);
|
|
7
8
|
if (validator === undefined)
|
|
8
9
|
return true;
|
|
9
10
|
return validator(text)(value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"$is_custom.js","sourceRoot":"","sources":["../../src/functional/$is_custom.ts"],"names":[],"mappings":";;;AAEA,6CAA4C;AAE5C,SAAgB,UAAU,CACtB,IAAY,EACZ,IAAU,EACV,IAAY,EACZ,KAAyB
|
|
1
|
+
{"version":3,"file":"$is_custom.js","sourceRoot":"","sources":["../../src/functional/$is_custom.ts"],"names":[],"mappings":";;;AAEA,6CAA4C;AAE5C,SAAgB,UAAU,CACtB,IAAY,EACZ,IAAU,EACV,IAAY,EACZ,KAAyB;;IAEzB,IAAM,SAAS,GAAG,MAAA,yBAAW,CAAC,GAAG,CAAC,IAAI,CAAC,0CAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACzC,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AATD,gCASC"}
|
package/lib/module.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IJsonApplication } from "./schemas/IJsonApplication";
|
|
2
|
-
import {
|
|
2
|
+
import { CustomValidatorMap } from "./CustomValidatorMap";
|
|
3
3
|
import { IRandomGenerator } from "./IRandomGenerator";
|
|
4
4
|
import { IValidation } from "./IValidation";
|
|
5
5
|
import { Primitive } from "./Primitive";
|
|
@@ -323,12 +323,14 @@ export declare function validateEquals<T>(input: T): IValidation<T>;
|
|
|
323
323
|
*/
|
|
324
324
|
export declare function validateEquals<T>(input: unknown): IValidation<T>;
|
|
325
325
|
/**
|
|
326
|
-
*
|
|
326
|
+
* Custom validators.
|
|
327
327
|
*
|
|
328
|
-
* If you want to add a custom validation logic
|
|
328
|
+
* If you want to add a custom validation logic utilizing comment tags,
|
|
329
|
+
* add a closure function with its tag and type name. Below example code
|
|
330
|
+
* would helpful to understand how to use this instance.
|
|
329
331
|
*
|
|
330
332
|
* ```ts
|
|
331
|
-
* typia.
|
|
333
|
+
* typia.customValidators.insert("powerOf")("number")(
|
|
332
334
|
* (text: string) => {
|
|
333
335
|
* const denominator: number = Math.log(Number(text));
|
|
334
336
|
* return (value: number) => {
|
|
@@ -337,7 +339,7 @@ export declare function validateEquals<T>(input: unknown): IValidation<T>;
|
|
|
337
339
|
* };
|
|
338
340
|
* }
|
|
339
341
|
* );
|
|
340
|
-
* typia.
|
|
342
|
+
* typia.customValidators.insert("dollar")("string")(
|
|
341
343
|
* () => (value: string) => value.startsWith("$"),
|
|
342
344
|
* );
|
|
343
345
|
*
|
|
@@ -354,10 +356,9 @@ export declare function validateEquals<T>(input: unknown): IValidation<T>;
|
|
|
354
356
|
* }
|
|
355
357
|
* ```
|
|
356
358
|
*
|
|
357
|
-
* @
|
|
358
|
-
* @returns Currying function
|
|
359
|
+
* @author Jeongho Nam - https://github.com/samchon
|
|
359
360
|
*/
|
|
360
|
-
export declare const
|
|
361
|
+
export declare const customValidators: CustomValidatorMap;
|
|
361
362
|
/**
|
|
362
363
|
* > You must configure the generic argument `T`.
|
|
363
364
|
*
|
package/lib/module.js
CHANGED
|
@@ -14,9 +14,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.createValidatePrune = exports.createIsPrune = exports.createAssertPrune = exports.createPrune = exports.createValidateClone = exports.createIsClone = exports.createAssertClone = exports.createClone = exports.createRandom = exports.createValidateStringify = exports.createIsStringify = exports.createAssertStringify = exports.createStringify = exports.createValidateParse = exports.createAssertParse = exports.createIsParse = exports.createValidateEquals = exports.createEquals = exports.createAssertEquals = exports.createValidate = exports.createIs = exports.createAssertType = exports.createAssert = exports.validatePrune = exports.isPrune = exports.assertPrune = exports.prune = exports.validateClone = exports.isClone = exports.assertClone = exports.clone = exports.random = exports.metadata = exports.validateStringify = exports.isStringify = exports.assertStringify = exports.stringify = exports.validateParse = exports.isParse = exports.assertParse = exports.application = exports.
|
|
17
|
+
exports.createValidatePrune = exports.createIsPrune = exports.createAssertPrune = exports.createPrune = exports.createValidateClone = exports.createIsClone = exports.createAssertClone = exports.createClone = exports.createRandom = exports.createValidateStringify = exports.createIsStringify = exports.createAssertStringify = exports.createStringify = exports.createValidateParse = exports.createAssertParse = exports.createIsParse = exports.createValidateEquals = exports.createEquals = exports.createAssertEquals = exports.createValidate = exports.createIs = exports.createAssertType = exports.createAssert = exports.validatePrune = exports.isPrune = exports.assertPrune = exports.prune = exports.validateClone = exports.isClone = exports.assertClone = exports.clone = exports.random = exports.metadata = exports.validateStringify = exports.isStringify = exports.assertStringify = exports.stringify = exports.validateParse = exports.isParse = exports.assertParse = exports.application = exports.customValidators = exports.validateEquals = exports.equals = exports.assertEquals = exports.validate = exports.is = exports.assertType = exports.assert = void 0;
|
|
18
18
|
var _dictionary_1 = require("./functional/$dictionary");
|
|
19
19
|
var Namespace_1 = require("./functional/Namespace");
|
|
20
|
+
var MapUtil_1 = require("./utils/MapUtil");
|
|
20
21
|
__exportStar(require("./schemas/IJsonApplication"), exports);
|
|
21
22
|
__exportStar(require("./schemas/IJsonComponents"), exports);
|
|
22
23
|
__exportStar(require("./schemas/IJsonSchema"), exports);
|
|
@@ -59,18 +60,19 @@ function validateEquals() {
|
|
|
59
60
|
}
|
|
60
61
|
exports.validateEquals = validateEquals;
|
|
61
62
|
Object.assign(validateEquals, Namespace_1.Namespace.validate());
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
exports.customValidators = {
|
|
64
|
+
size: function (name) { var _a, _b; return name ? (_b = (_a = _dictionary_1.$dictionary.get(name)) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : 0 : _dictionary_1.$dictionary.size; },
|
|
65
|
+
has: function (name) { return function (type) { var _a, _b; return (_b = (_a = _dictionary_1.$dictionary.get(name)) === null || _a === void 0 ? void 0 : _a.has(type)) !== null && _b !== void 0 ? _b : false; }; },
|
|
66
|
+
get: function (name) { return function (type) { var _a; return (_a = _dictionary_1.$dictionary.get(name)) === null || _a === void 0 ? void 0 : _a.get(type); }; },
|
|
67
|
+
insert: function (name) { return function (type) { return function (closure) {
|
|
68
|
+
var internal = MapUtil_1.MapUtil.take(_dictionary_1.$dictionary, name, function () { return new Map(); });
|
|
69
|
+
if (internal.has(type))
|
|
70
|
+
return false;
|
|
71
|
+
internal.set(type, closure);
|
|
72
|
+
return true;
|
|
73
|
+
}; }; },
|
|
74
|
+
erase: function (name) { return function (type) { var _a, _b; return (_b = (_a = _dictionary_1.$dictionary.get(name)) === null || _a === void 0 ? void 0 : _a.delete(type)) !== null && _b !== void 0 ? _b : false; }; },
|
|
72
75
|
};
|
|
73
|
-
exports.addValidationTag = addValidationTag;
|
|
74
76
|
function application() {
|
|
75
77
|
halt("application");
|
|
76
78
|
}
|
package/lib/module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.js","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,wDAAuD;AACvD,oDAAmD;
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Customizable } from "./typings/Customizable";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Map of custom validators.
|
|
5
|
+
*
|
|
6
|
+
* Map of custom validator functions, storing tag name and type of target value
|
|
7
|
+
* as key, and custom validator function as value.
|
|
8
|
+
*
|
|
9
|
+
* When you want to add a custom validation logic utilizing comment tags, you
|
|
10
|
+
* can insert a custom validator function with specific tag name and type of
|
|
11
|
+
* the target value like below.
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* typia.customValidators.insert("powerOf")("number")(
|
|
15
|
+
* (text: string) => {
|
|
16
|
+
* const denominator: number = Math.log(Number(text));
|
|
17
|
+
* return (value: number) => {
|
|
18
|
+
* value = Math.log(value) / denominator;
|
|
19
|
+
* return value === Math.floor(value);
|
|
20
|
+
* };
|
|
21
|
+
* }
|
|
22
|
+
* );
|
|
23
|
+
* typia.customValidators.insert("dollar")("string")(
|
|
24
|
+
* () => (value: string) => value.startsWith("$"),
|
|
25
|
+
* );
|
|
26
|
+
*
|
|
27
|
+
* interface TagCustom {
|
|
28
|
+
* /**
|
|
29
|
+
* * @powerOf 10
|
|
30
|
+
* *\/
|
|
31
|
+
* powerOf: number;
|
|
32
|
+
*
|
|
33
|
+
* /**
|
|
34
|
+
* * @dollar
|
|
35
|
+
* *\/
|
|
36
|
+
* dollar: string;
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @author Jeongho Nam - https://github.com/samchon
|
|
41
|
+
*/
|
|
42
|
+
export interface CustomValidatorMap {
|
|
43
|
+
/**
|
|
44
|
+
* Get number of stored tags.
|
|
45
|
+
*
|
|
46
|
+
* @return Number of stored tags
|
|
47
|
+
*/
|
|
48
|
+
size(): number;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Get number of stored types of the specified tag name.
|
|
52
|
+
*
|
|
53
|
+
* In other words, number of stored custom validator functions of
|
|
54
|
+
* the specified tag name.
|
|
55
|
+
*
|
|
56
|
+
* @param name Tag name
|
|
57
|
+
* @return Number of stored types function
|
|
58
|
+
*/
|
|
59
|
+
size(name: string): number;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Test whether custom validator function exists or not.
|
|
63
|
+
*
|
|
64
|
+
* @param name Tag name
|
|
65
|
+
* @param type Type of the target value
|
|
66
|
+
* @returns Whether exists or not
|
|
67
|
+
*/
|
|
68
|
+
has: (name: string) => (type: keyof Customizable) => boolean;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Get custom validator function.
|
|
72
|
+
*
|
|
73
|
+
* @param name Tag name
|
|
74
|
+
* @param type Type of the target value
|
|
75
|
+
* @returns Custom validator function or undefined value
|
|
76
|
+
*/
|
|
77
|
+
get(
|
|
78
|
+
name: string,
|
|
79
|
+
): <Type extends keyof Customizable>(
|
|
80
|
+
type: Type,
|
|
81
|
+
) => CustomValidatorMap.Closure<Type> | undefined;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Insert a new custom validator function.
|
|
85
|
+
*
|
|
86
|
+
* You can add a custom validation logic utilizing comment tags,
|
|
87
|
+
* by inserting a function which returns a boolean value, with specific
|
|
88
|
+
* tag name and type of the target value.
|
|
89
|
+
*
|
|
90
|
+
* However, if you try to insert a duplicated tag name and type, the
|
|
91
|
+
* closure function would not be enrolled and `false` value would be
|
|
92
|
+
* returned.
|
|
93
|
+
*
|
|
94
|
+
* @param name Tag name
|
|
95
|
+
* @param type Type of the target value
|
|
96
|
+
* @param closure Custom validator function
|
|
97
|
+
* @returns Whether succeeded to insert or not
|
|
98
|
+
*/
|
|
99
|
+
insert(
|
|
100
|
+
name: string,
|
|
101
|
+
): <Type extends keyof Customizable>(
|
|
102
|
+
type: Type,
|
|
103
|
+
) => (closure: CustomValidatorMap.Closure<Type>) => boolean;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Erase custom validator function.
|
|
107
|
+
*
|
|
108
|
+
* @param name Tag name
|
|
109
|
+
* @param type Type of the target value
|
|
110
|
+
* @returns Whether succeeded to erase or not
|
|
111
|
+
*/
|
|
112
|
+
erase(name: string): (type: keyof Customizable) => boolean;
|
|
113
|
+
}
|
|
114
|
+
export namespace CustomValidatorMap {
|
|
115
|
+
/**
|
|
116
|
+
* Type of closure function of custom validation.
|
|
117
|
+
*
|
|
118
|
+
* @template Type Type of the target value
|
|
119
|
+
* @param text Text of the tag. For example, if the tag is `@powerOf 10`, `text` is 10.
|
|
120
|
+
* @param value Value to validate
|
|
121
|
+
* @returns Whether the value is valid or not
|
|
122
|
+
*/
|
|
123
|
+
export type Closure<Type extends keyof Customizable> = (
|
|
124
|
+
text: string,
|
|
125
|
+
) => (value: Customizable[Type]) => boolean;
|
|
126
|
+
}
|
|
@@ -3,8 +3,11 @@ import { Customizable } from "../typings/Customizable";
|
|
|
3
3
|
export const $dictionary = (() => {
|
|
4
4
|
const glob: {
|
|
5
5
|
__typia_custom_validator: Map<
|
|
6
|
-
`${string}
|
|
7
|
-
|
|
6
|
+
`${string}`,
|
|
7
|
+
Map<
|
|
8
|
+
keyof Customizable,
|
|
9
|
+
(tagText: string) => (value: any) => boolean
|
|
10
|
+
>
|
|
8
11
|
>;
|
|
9
12
|
} =
|
|
10
13
|
typeof global === "object" &&
|
|
@@ -8,7 +8,7 @@ export function $is_custom<Type extends keyof Customizable>(
|
|
|
8
8
|
text: string,
|
|
9
9
|
value: Customizable[Type],
|
|
10
10
|
): boolean {
|
|
11
|
-
const validator = $dictionary.get(
|
|
11
|
+
const validator = $dictionary.get(name)?.get(type);
|
|
12
12
|
if (validator === undefined) return true;
|
|
13
13
|
return validator(text)(value);
|
|
14
14
|
}
|
package/src/module.ts
CHANGED
|
@@ -4,8 +4,9 @@ import { Namespace } from "./functional/Namespace";
|
|
|
4
4
|
import { IMetadataApplication } from "./metadata/IMetadataApplication";
|
|
5
5
|
import { IJsonApplication } from "./schemas/IJsonApplication";
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { MapUtil } from "./utils/MapUtil";
|
|
8
8
|
|
|
9
|
+
import { CustomValidatorMap } from "./CustomValidatorMap";
|
|
9
10
|
import { IRandomGenerator } from "./IRandomGenerator";
|
|
10
11
|
import { IValidation } from "./IValidation";
|
|
11
12
|
import { Primitive } from "./Primitive";
|
|
@@ -414,12 +415,14 @@ export function validateEquals(): never {
|
|
|
414
415
|
Object.assign(validateEquals, Namespace.validate());
|
|
415
416
|
|
|
416
417
|
/**
|
|
417
|
-
*
|
|
418
|
+
* Custom validators.
|
|
418
419
|
*
|
|
419
|
-
* If you want to add a custom validation logic
|
|
420
|
+
* If you want to add a custom validation logic utilizing comment tags,
|
|
421
|
+
* add a closure function with its tag and type name. Below example code
|
|
422
|
+
* would helpful to understand how to use this instance.
|
|
420
423
|
*
|
|
421
424
|
* ```ts
|
|
422
|
-
* typia.
|
|
425
|
+
* typia.customValidators.insert("powerOf")("number")(
|
|
423
426
|
* (text: string) => {
|
|
424
427
|
* const denominator: number = Math.log(Number(text));
|
|
425
428
|
* return (value: number) => {
|
|
@@ -428,7 +431,7 @@ Object.assign(validateEquals, Namespace.validate());
|
|
|
428
431
|
* };
|
|
429
432
|
* }
|
|
430
433
|
* );
|
|
431
|
-
* typia.
|
|
434
|
+
* typia.customValidators.insert("dollar")("string")(
|
|
432
435
|
* () => (value: string) => value.startsWith("$"),
|
|
433
436
|
* );
|
|
434
437
|
*
|
|
@@ -445,25 +448,21 @@ Object.assign(validateEquals, Namespace.validate());
|
|
|
445
448
|
* }
|
|
446
449
|
* ```
|
|
447
450
|
*
|
|
448
|
-
* @
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
*/
|
|
460
|
-
(closure: (text: string) => (value: Customizable[Type]) => boolean) => {
|
|
461
|
-
const key = `${name}:${type}` as const;
|
|
462
|
-
if ($dictionary.has(key)) return false;
|
|
463
|
-
|
|
464
|
-
$dictionary.set(key, closure);
|
|
451
|
+
* @author Jeongho Nam - https://github.com/samchon
|
|
452
|
+
*/
|
|
453
|
+
export const customValidators: CustomValidatorMap = {
|
|
454
|
+
size: (name?: string) =>
|
|
455
|
+
name ? $dictionary.get(name)?.size ?? 0 : $dictionary.size,
|
|
456
|
+
has: (name) => (type) => $dictionary.get(name)?.has(type) ?? false,
|
|
457
|
+
get: (name) => (type) => $dictionary.get(name)?.get(type),
|
|
458
|
+
insert: (name) => (type) => (closure) => {
|
|
459
|
+
const internal = MapUtil.take($dictionary, name, () => new Map());
|
|
460
|
+
if (internal.has(type)) return false;
|
|
461
|
+
internal.set(type, closure);
|
|
465
462
|
return true;
|
|
466
|
-
}
|
|
463
|
+
},
|
|
464
|
+
erase: (name) => (type) => $dictionary.get(name)?.delete(type) ?? false,
|
|
465
|
+
};
|
|
467
466
|
|
|
468
467
|
/* -----------------------------------------------------------
|
|
469
468
|
JSON FUNCTIONS
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import ts from "typescript";
|
|
2
|
-
|
|
3
|
-
import { MetadataTagFactory } from "../../factories/MetadataTagFactory";
|
|
4
|
-
|
|
5
|
-
import { IJsDocTagInfo } from "../../metadata/IJsDocTagInfo";
|
|
6
|
-
|
|
7
|
-
import { FunctionImporter } from "../helpers/FunctionImporeter";
|
|
8
|
-
import { ICheckEntry } from "../helpers/ICheckEntry";
|
|
9
|
-
|
|
10
|
-
export const check_custom =
|
|
11
|
-
(type: string, alias?: string) =>
|
|
12
|
-
(importer: FunctionImporter) =>
|
|
13
|
-
(jsDocTags: IJsDocTagInfo[]) =>
|
|
14
|
-
(input: ts.Expression): ICheckEntry.ITag[] =>
|
|
15
|
-
jsDocTags
|
|
16
|
-
.filter(
|
|
17
|
-
(tag) =>
|
|
18
|
-
tag.name !== "random" &&
|
|
19
|
-
(!tag.text?.length ||
|
|
20
|
-
(tag.text?.length === 1 &&
|
|
21
|
-
tag.text?.[0]?.kind === "text")) &&
|
|
22
|
-
MetadataTagFactory._PARSER[tag.name] === undefined,
|
|
23
|
-
)
|
|
24
|
-
.map((tag) => {
|
|
25
|
-
const text: string | undefined = tag.text?.[0]?.text ?? "";
|
|
26
|
-
return {
|
|
27
|
-
expected: `${alias ?? type} (@${tag.name}${
|
|
28
|
-
text.length ? ` ${text}` : ""
|
|
29
|
-
})`,
|
|
30
|
-
expression: ts.factory.createCallExpression(
|
|
31
|
-
importer.use("is_custom"),
|
|
32
|
-
undefined,
|
|
33
|
-
[
|
|
34
|
-
ts.factory.createStringLiteral(tag.name),
|
|
35
|
-
ts.factory.createStringLiteral(type),
|
|
36
|
-
ts.factory.createStringLiteral(text),
|
|
37
|
-
input,
|
|
38
|
-
],
|
|
39
|
-
),
|
|
40
|
-
};
|
|
41
|
-
});
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
|
|
3
|
+
import { MetadataTagFactory } from "../../factories/MetadataTagFactory";
|
|
4
|
+
|
|
5
|
+
import { IJsDocTagInfo } from "../../metadata/IJsDocTagInfo";
|
|
6
|
+
|
|
7
|
+
import { FunctionImporter } from "../helpers/FunctionImporeter";
|
|
8
|
+
import { ICheckEntry } from "../helpers/ICheckEntry";
|
|
9
|
+
|
|
10
|
+
export const check_custom =
|
|
11
|
+
(type: string, alias?: string) =>
|
|
12
|
+
(importer: FunctionImporter) =>
|
|
13
|
+
(jsDocTags: IJsDocTagInfo[]) =>
|
|
14
|
+
(input: ts.Expression): ICheckEntry.ITag[] =>
|
|
15
|
+
jsDocTags
|
|
16
|
+
.filter(
|
|
17
|
+
(tag) =>
|
|
18
|
+
tag.name !== "random" &&
|
|
19
|
+
(!tag.text?.length ||
|
|
20
|
+
(tag.text?.length === 1 &&
|
|
21
|
+
tag.text?.[0]?.kind === "text")) &&
|
|
22
|
+
MetadataTagFactory._PARSER[tag.name] === undefined,
|
|
23
|
+
)
|
|
24
|
+
.map((tag) => {
|
|
25
|
+
const text: string | undefined = tag.text?.[0]?.text ?? "";
|
|
26
|
+
return {
|
|
27
|
+
expected: `${alias ?? type} (@${tag.name}${
|
|
28
|
+
text.length ? ` ${text}` : ""
|
|
29
|
+
})`,
|
|
30
|
+
expression: ts.factory.createCallExpression(
|
|
31
|
+
importer.use("is_custom"),
|
|
32
|
+
undefined,
|
|
33
|
+
[
|
|
34
|
+
ts.factory.createStringLiteral(tag.name),
|
|
35
|
+
ts.factory.createStringLiteral(type),
|
|
36
|
+
ts.factory.createStringLiteral(text),
|
|
37
|
+
input,
|
|
38
|
+
],
|
|
39
|
+
),
|
|
40
|
+
};
|
|
41
|
+
});
|