@naturalcycles/nodejs-lib 15.12.0 → 15.14.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.
|
@@ -5,12 +5,19 @@ import type { Ajv } from 'ajv';
|
|
|
5
5
|
import { AjvValidationError } from './ajvValidationError.js';
|
|
6
6
|
export interface AjvValidationOptions {
|
|
7
7
|
/**
|
|
8
|
-
* Defaults to
|
|
8
|
+
* Defaults to true,
|
|
9
|
+
* because that's how AJV works by default,
|
|
10
|
+
* and what gives it performance advantage.
|
|
11
|
+
* (Because we have found that deep-clone is surprisingly slow,
|
|
12
|
+
* nearly as slow as Joi validation).
|
|
9
13
|
*
|
|
10
14
|
* If set to true - AJV will mutate the input in case it needs to apply transformations
|
|
11
15
|
* (strip unknown properties, convert types, etc).
|
|
12
16
|
*
|
|
13
|
-
* If false - it will deep-clone the input to prevent its mutation.
|
|
17
|
+
* If false - it will deep-clone (using JSON.stringify+parse) the input to prevent its mutation.
|
|
18
|
+
* Will return the cloned/mutated object.
|
|
19
|
+
* Please note that JSON.stringify+parse has side-effects,
|
|
20
|
+
* e.g it will transform Buffer into a weird object.
|
|
14
21
|
*/
|
|
15
22
|
mutateInput?: boolean;
|
|
16
23
|
inputName?: string;
|
|
@@ -57,6 +64,9 @@ export declare class AjvSchema<T = unknown> {
|
|
|
57
64
|
* correctly for some reason.
|
|
58
65
|
*/
|
|
59
66
|
static create<T>(schema: JsonSchemaBuilder<T> | JsonSchema<T> | AjvSchema<T>, cfg?: Partial<AjvSchemaCfg>): AjvSchema<T>;
|
|
67
|
+
/**
|
|
68
|
+
* @experimental
|
|
69
|
+
*/
|
|
60
70
|
static createFromZod<T>(zodSchema: ZodType<T>, cfg?: Partial<AjvSchemaCfg>): AjvSchema<T>;
|
|
61
71
|
readonly cfg: AjvSchemaCfg;
|
|
62
72
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _isObject, _lazyValue, } from '@naturalcycles/js-lib';
|
|
2
2
|
import { JsonSchemaAnyBuilder } from '@naturalcycles/js-lib/json-schema';
|
|
3
|
-
import { _filterNullishValues } from '@naturalcycles/js-lib/object';
|
|
3
|
+
import { _deepCopy, _filterNullishValues } from '@naturalcycles/js-lib/object';
|
|
4
4
|
import { _substringBefore } from '@naturalcycles/js-lib/string';
|
|
5
5
|
import { z } from '@naturalcycles/js-lib/zod';
|
|
6
6
|
import { _inspect } from '../../string/inspect.js';
|
|
@@ -51,6 +51,9 @@ export class AjvSchema {
|
|
|
51
51
|
}
|
|
52
52
|
return new AjvSchema(schema, cfg);
|
|
53
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* @experimental
|
|
56
|
+
*/
|
|
54
57
|
static createFromZod(zodSchema, cfg) {
|
|
55
58
|
const jsonSchema = z.toJSONSchema(zodSchema, { target: 'draft-7' });
|
|
56
59
|
return new AjvSchema(jsonSchema, cfg);
|
|
@@ -71,12 +74,16 @@ export class AjvSchema {
|
|
|
71
74
|
return output;
|
|
72
75
|
}
|
|
73
76
|
isValid(input, opt) {
|
|
77
|
+
// todo: we can make it both fast and non-mutating by using Ajv
|
|
78
|
+
// with "removeAdditional" and "useDefaults" disabled.
|
|
74
79
|
const [err] = this.getValidationResult(input, opt);
|
|
75
80
|
return !err;
|
|
76
81
|
}
|
|
77
82
|
getValidationResult(input, opt = {}) {
|
|
78
83
|
const fn = this.getAJVValidateFunction();
|
|
79
|
-
const item = opt.mutateInput || typeof input !== 'object'
|
|
84
|
+
const item = opt.mutateInput !== false || typeof input !== 'object'
|
|
85
|
+
? input // mutate
|
|
86
|
+
: _deepCopy(input); // not mutate
|
|
80
87
|
const valid = fn(item); // mutates item
|
|
81
88
|
if (valid)
|
|
82
89
|
return [null, item];
|
|
@@ -87,6 +94,8 @@ export class AjvSchema {
|
|
|
87
94
|
dataVar,
|
|
88
95
|
separator,
|
|
89
96
|
});
|
|
97
|
+
// Note: if we mutated the input already, e.g stripped unknown properties,
|
|
98
|
+
// the error message Input would contain already mutated object print, such as Input: {}
|
|
90
99
|
const inputStringified = _inspect(input, { maxLen: 4000 });
|
|
91
100
|
message = [message, 'Input: ' + inputStringified].join(separator);
|
|
92
101
|
const err = new AjvValidationError(message, _filterNullishValues({
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from '@naturalcycles/js-lib'
|
|
7
7
|
import type { JsonSchema, JsonSchemaBuilder } from '@naturalcycles/js-lib/json-schema'
|
|
8
8
|
import { JsonSchemaAnyBuilder } from '@naturalcycles/js-lib/json-schema'
|
|
9
|
-
import { _filterNullishValues } from '@naturalcycles/js-lib/object'
|
|
9
|
+
import { _deepCopy, _filterNullishValues } from '@naturalcycles/js-lib/object'
|
|
10
10
|
import { _substringBefore } from '@naturalcycles/js-lib/string'
|
|
11
11
|
import { z, type ZodType } from '@naturalcycles/js-lib/zod'
|
|
12
12
|
import type { Ajv } from 'ajv'
|
|
@@ -16,12 +16,19 @@ import { getAjv } from './getAjv.js'
|
|
|
16
16
|
|
|
17
17
|
export interface AjvValidationOptions {
|
|
18
18
|
/**
|
|
19
|
-
* Defaults to
|
|
19
|
+
* Defaults to true,
|
|
20
|
+
* because that's how AJV works by default,
|
|
21
|
+
* and what gives it performance advantage.
|
|
22
|
+
* (Because we have found that deep-clone is surprisingly slow,
|
|
23
|
+
* nearly as slow as Joi validation).
|
|
20
24
|
*
|
|
21
25
|
* If set to true - AJV will mutate the input in case it needs to apply transformations
|
|
22
26
|
* (strip unknown properties, convert types, etc).
|
|
23
27
|
*
|
|
24
|
-
* If false - it will deep-clone the input to prevent its mutation.
|
|
28
|
+
* If false - it will deep-clone (using JSON.stringify+parse) the input to prevent its mutation.
|
|
29
|
+
* Will return the cloned/mutated object.
|
|
30
|
+
* Please note that JSON.stringify+parse has side-effects,
|
|
31
|
+
* e.g it will transform Buffer into a weird object.
|
|
25
32
|
*/
|
|
26
33
|
mutateInput?: boolean
|
|
27
34
|
inputName?: string
|
|
@@ -108,6 +115,9 @@ export class AjvSchema<T = unknown> {
|
|
|
108
115
|
return new AjvSchema<T>(schema as JsonSchema<T>, cfg)
|
|
109
116
|
}
|
|
110
117
|
|
|
118
|
+
/**
|
|
119
|
+
* @experimental
|
|
120
|
+
*/
|
|
111
121
|
static createFromZod<T>(zodSchema: ZodType<T>, cfg?: Partial<AjvSchemaCfg>): AjvSchema<T> {
|
|
112
122
|
const jsonSchema = z.toJSONSchema(zodSchema, { target: 'draft-7' })
|
|
113
123
|
return new AjvSchema<T>(jsonSchema as JsonSchema<T>, cfg)
|
|
@@ -130,6 +140,8 @@ export class AjvSchema<T = unknown> {
|
|
|
130
140
|
}
|
|
131
141
|
|
|
132
142
|
isValid(input: T, opt?: AjvValidationOptions): boolean {
|
|
143
|
+
// todo: we can make it both fast and non-mutating by using Ajv
|
|
144
|
+
// with "removeAdditional" and "useDefaults" disabled.
|
|
133
145
|
const [err] = this.getValidationResult(input, opt)
|
|
134
146
|
return !err
|
|
135
147
|
}
|
|
@@ -140,7 +152,10 @@ export class AjvSchema<T = unknown> {
|
|
|
140
152
|
): ValidationFunctionResult<T, AjvValidationError> {
|
|
141
153
|
const fn = this.getAJVValidateFunction()
|
|
142
154
|
|
|
143
|
-
const item =
|
|
155
|
+
const item =
|
|
156
|
+
opt.mutateInput !== false || typeof input !== 'object'
|
|
157
|
+
? input // mutate
|
|
158
|
+
: _deepCopy(input) // not mutate
|
|
144
159
|
|
|
145
160
|
const valid = fn(item) // mutates item
|
|
146
161
|
if (valid) return [null, item]
|
|
@@ -158,6 +173,8 @@ export class AjvSchema<T = unknown> {
|
|
|
158
173
|
separator,
|
|
159
174
|
})
|
|
160
175
|
|
|
176
|
+
// Note: if we mutated the input already, e.g stripped unknown properties,
|
|
177
|
+
// the error message Input would contain already mutated object print, such as Input: {}
|
|
161
178
|
const inputStringified = _inspect(input, { maxLen: 4000 })
|
|
162
179
|
message = [message, 'Input: ' + inputStringified].join(separator)
|
|
163
180
|
|