@naturalcycles/nodejs-lib 15.7.0 → 15.8.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/dist/validation/ajv/ajvSchema.d.ts +4 -3
- package/dist/validation/ajv/ajvSchema.js +14 -13
- package/dist/validation/joi/joi.validation.util.d.ts +2 -5
- package/dist/validation/joi/joi.validation.util.js +5 -11
- package/package.json +2 -2
- package/src/validation/ajv/ajvSchema.ts +16 -12
- package/src/validation/joi/joi.validation.util.ts +8 -25
- package/dist/stream/transform/worker/workerClassProxy.js +0 -89
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ValidationFunctionResult } from '@naturalcycles/js-lib';
|
|
1
2
|
import type { JsonSchema, JsonSchemaBuilder } from '@naturalcycles/js-lib/json-schema';
|
|
2
3
|
import type { Ajv } from 'ajv';
|
|
3
4
|
import { AjvValidationError } from './ajvValidationError.js';
|
|
@@ -62,7 +63,7 @@ export declare class AjvSchema<T = unknown> {
|
|
|
62
63
|
*
|
|
63
64
|
* Returned object is always the same object (`===`) that was passed, so it is returned just for convenience.
|
|
64
65
|
*/
|
|
65
|
-
validate(
|
|
66
|
-
isValid(
|
|
67
|
-
|
|
66
|
+
validate(input: T, opt?: AjvValidationOptions): T;
|
|
67
|
+
isValid(input: T): boolean;
|
|
68
|
+
getValidationResult(input: T, opt?: AjvValidationOptions): ValidationFunctionResult<T, AjvValidationError>;
|
|
68
69
|
}
|
|
@@ -73,32 +73,33 @@ export class AjvSchema {
|
|
|
73
73
|
*
|
|
74
74
|
* Returned object is always the same object (`===`) that was passed, so it is returned just for convenience.
|
|
75
75
|
*/
|
|
76
|
-
validate(
|
|
77
|
-
const
|
|
78
|
-
if (
|
|
79
|
-
throw
|
|
80
|
-
return
|
|
76
|
+
validate(input, opt = {}) {
|
|
77
|
+
const [error, output] = this.getValidationResult(input, opt);
|
|
78
|
+
if (error)
|
|
79
|
+
throw error;
|
|
80
|
+
return output;
|
|
81
81
|
}
|
|
82
|
-
isValid(
|
|
83
|
-
return this.getValidateFunction()(
|
|
82
|
+
isValid(input) {
|
|
83
|
+
return this.getValidateFunction()(input);
|
|
84
84
|
}
|
|
85
|
-
|
|
86
|
-
if (this.isValid(
|
|
87
|
-
return;
|
|
85
|
+
getValidationResult(input, opt = {}) {
|
|
86
|
+
if (this.isValid(input))
|
|
87
|
+
return [null, input];
|
|
88
88
|
const errors = this.getValidateFunction().errors;
|
|
89
|
-
const { objectId = _isObject(
|
|
89
|
+
const { objectId = _isObject(input) ? input['id'] : undefined, objectName = this.cfg.objectName, } = opt;
|
|
90
90
|
const name = [objectName || 'Object', objectId].filter(Boolean).join('.');
|
|
91
91
|
let message = this.cfg.ajv.errorsText(errors, {
|
|
92
92
|
dataVar: name,
|
|
93
93
|
separator,
|
|
94
94
|
});
|
|
95
|
-
const inputStringified = _inspect(
|
|
95
|
+
const inputStringified = _inspect(input, { maxLen: 4000 });
|
|
96
96
|
message = [message, 'Input: ' + inputStringified].join(separator);
|
|
97
|
-
|
|
97
|
+
const err = new AjvValidationError(message, _filterNullishValues({
|
|
98
98
|
errors,
|
|
99
99
|
objectName,
|
|
100
100
|
objectId,
|
|
101
101
|
}));
|
|
102
|
+
return [err, input];
|
|
102
103
|
}
|
|
103
104
|
}
|
|
104
105
|
const separator = '\n';
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
+
import { type ValidationFunctionResult } from '@naturalcycles/js-lib';
|
|
1
2
|
import type { AnySchema, ValidationOptions } from 'joi';
|
|
2
3
|
import { JoiValidationError } from './joi.validation.error.js';
|
|
3
|
-
export interface JoiValidationResult<T = any> {
|
|
4
|
-
value: T;
|
|
5
|
-
error?: JoiValidationError;
|
|
6
|
-
}
|
|
7
4
|
/**
|
|
8
5
|
* Validates with Joi.
|
|
9
6
|
* Throws JoiValidationError if invalid.
|
|
@@ -21,7 +18,7 @@ export declare function validate<T>(input: any, schema?: AnySchema<T>, objectNam
|
|
|
21
18
|
*
|
|
22
19
|
* If `schema` is undefined - returns value as is.
|
|
23
20
|
*/
|
|
24
|
-
export declare function getValidationResult<T>(input:
|
|
21
|
+
export declare function getValidationResult<T>(input: T, schema?: AnySchema<T>, objectName?: string, options?: ValidationOptions): ValidationFunctionResult<T, JoiValidationError>;
|
|
25
22
|
/**
|
|
26
23
|
* Convenience function that returns true if !error.
|
|
27
24
|
*/
|
|
@@ -39,10 +39,9 @@ const defaultOptions = {
|
|
|
39
39
|
* If `schema` is undefined - returns value as is.
|
|
40
40
|
*/
|
|
41
41
|
export function validate(input, schema, objectName, opt = {}) {
|
|
42
|
-
const
|
|
43
|
-
if (error)
|
|
42
|
+
const [error, returnValue] = getValidationResult(input, schema, objectName, opt);
|
|
43
|
+
if (error)
|
|
44
44
|
throw error;
|
|
45
|
-
}
|
|
46
45
|
return returnValue;
|
|
47
46
|
}
|
|
48
47
|
/**
|
|
@@ -56,18 +55,13 @@ export function validate(input, schema, objectName, opt = {}) {
|
|
|
56
55
|
*/
|
|
57
56
|
export function getValidationResult(input, schema, objectName, options = {}) {
|
|
58
57
|
if (!schema)
|
|
59
|
-
return
|
|
58
|
+
return [null, input];
|
|
60
59
|
const { value, error } = schema.validate(input, {
|
|
61
60
|
...defaultOptions,
|
|
62
61
|
...options,
|
|
63
62
|
});
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
};
|
|
67
|
-
if (error) {
|
|
68
|
-
vr.error = createError(input, error, objectName);
|
|
69
|
-
}
|
|
70
|
-
return vr;
|
|
63
|
+
const err = error ? createError(input, error, objectName) : null;
|
|
64
|
+
return [err, value];
|
|
71
65
|
}
|
|
72
66
|
/**
|
|
73
67
|
* Convenience function that returns true if !error.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naturalcycles/nodejs-lib",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "15.
|
|
4
|
+
"version": "15.8.0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@naturalcycles/js-lib": "^15",
|
|
7
7
|
"@types/js-yaml": "^4",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@types/through2-concurrent": "^2",
|
|
26
|
-
"@naturalcycles/dev-lib": "
|
|
26
|
+
"@naturalcycles/dev-lib": "19.14.0"
|
|
27
27
|
},
|
|
28
28
|
"exports": {
|
|
29
29
|
".": "./dist/index.js",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _isObject, _lazyValue } from '@naturalcycles/js-lib'
|
|
1
|
+
import { _isObject, _lazyValue, type ValidationFunctionResult } from '@naturalcycles/js-lib'
|
|
2
2
|
import type { JsonSchema, JsonSchemaBuilder } from '@naturalcycles/js-lib/json-schema'
|
|
3
3
|
import { JsonSchemaAnyBuilder } from '@naturalcycles/js-lib/json-schema'
|
|
4
4
|
import { _filterNullishValues } from '@naturalcycles/js-lib/object'
|
|
@@ -124,23 +124,26 @@ export class AjvSchema<T = unknown> {
|
|
|
124
124
|
*
|
|
125
125
|
* Returned object is always the same object (`===`) that was passed, so it is returned just for convenience.
|
|
126
126
|
*/
|
|
127
|
-
validate(
|
|
128
|
-
const
|
|
129
|
-
if (
|
|
130
|
-
return
|
|
127
|
+
validate(input: T, opt: AjvValidationOptions = {}): T {
|
|
128
|
+
const [error, output] = this.getValidationResult(input, opt)
|
|
129
|
+
if (error) throw error
|
|
130
|
+
return output
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
isValid(
|
|
134
|
-
return this.getValidateFunction()(
|
|
133
|
+
isValid(input: T): boolean {
|
|
134
|
+
return this.getValidateFunction()(input)
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
getValidationResult(
|
|
138
|
+
input: T,
|
|
139
|
+
opt: AjvValidationOptions = {},
|
|
140
|
+
): ValidationFunctionResult<T, AjvValidationError> {
|
|
141
|
+
if (this.isValid(input)) return [null, input]
|
|
139
142
|
|
|
140
143
|
const errors = this.getValidateFunction().errors!
|
|
141
144
|
|
|
142
145
|
const {
|
|
143
|
-
objectId = _isObject(
|
|
146
|
+
objectId = _isObject(input) ? (input['id' as keyof T] as any) : undefined,
|
|
144
147
|
objectName = this.cfg.objectName,
|
|
145
148
|
} = opt
|
|
146
149
|
const name = [objectName || 'Object', objectId].filter(Boolean).join('.')
|
|
@@ -150,10 +153,10 @@ export class AjvSchema<T = unknown> {
|
|
|
150
153
|
separator,
|
|
151
154
|
})
|
|
152
155
|
|
|
153
|
-
const inputStringified = _inspect(
|
|
156
|
+
const inputStringified = _inspect(input, { maxLen: 4000 })
|
|
154
157
|
message = [message, 'Input: ' + inputStringified].join(separator)
|
|
155
158
|
|
|
156
|
-
|
|
159
|
+
const err = new AjvValidationError(
|
|
157
160
|
message,
|
|
158
161
|
_filterNullishValues({
|
|
159
162
|
errors,
|
|
@@ -161,6 +164,7 @@ export class AjvSchema<T = unknown> {
|
|
|
161
164
|
objectId,
|
|
162
165
|
}),
|
|
163
166
|
)
|
|
167
|
+
return [err, input]
|
|
164
168
|
}
|
|
165
169
|
}
|
|
166
170
|
|
|
@@ -6,18 +6,12 @@
|
|
|
6
6
|
* "Converts" mean e.g trims all strings from leading/trailing spaces.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { _hb, _isObject } from '@naturalcycles/js-lib'
|
|
9
|
+
import { _hb, _isObject, type ValidationFunctionResult } from '@naturalcycles/js-lib'
|
|
10
10
|
import { _truncateMiddle } from '@naturalcycles/js-lib/string/string.util.js'
|
|
11
11
|
import type { AnySchema, ValidationError, ValidationOptions } from 'joi'
|
|
12
12
|
import type { JoiValidationErrorData } from './joi.validation.error.js'
|
|
13
13
|
import { JoiValidationError } from './joi.validation.error.js'
|
|
14
14
|
|
|
15
|
-
// todo: consider replacing with Tuple of [error, value]
|
|
16
|
-
export interface JoiValidationResult<T = any> {
|
|
17
|
-
value: T
|
|
18
|
-
error?: JoiValidationError
|
|
19
|
-
}
|
|
20
|
-
|
|
21
15
|
// Strip colors in production (for e.g Sentry reporting)
|
|
22
16
|
// const stripColors = process.env.NODE_ENV === 'production' || !!process.env.GAE_INSTANCE
|
|
23
17
|
// Currently colors do more bad than good, so let's strip them always for now
|
|
@@ -56,12 +50,8 @@ export function validate<T>(
|
|
|
56
50
|
objectName?: string,
|
|
57
51
|
opt: ValidationOptions = {},
|
|
58
52
|
): T {
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
if (error) {
|
|
62
|
-
throw error
|
|
63
|
-
}
|
|
64
|
-
|
|
53
|
+
const [error, returnValue] = getValidationResult(input, schema, objectName, opt)
|
|
54
|
+
if (error) throw error
|
|
65
55
|
return returnValue
|
|
66
56
|
}
|
|
67
57
|
|
|
@@ -75,27 +65,20 @@ export function validate<T>(
|
|
|
75
65
|
* If `schema` is undefined - returns value as is.
|
|
76
66
|
*/
|
|
77
67
|
export function getValidationResult<T>(
|
|
78
|
-
input:
|
|
68
|
+
input: T,
|
|
79
69
|
schema?: AnySchema<T>,
|
|
80
70
|
objectName?: string,
|
|
81
71
|
options: ValidationOptions = {},
|
|
82
|
-
):
|
|
83
|
-
if (!schema) return
|
|
72
|
+
): ValidationFunctionResult<T, JoiValidationError> {
|
|
73
|
+
if (!schema) return [null, input]
|
|
84
74
|
|
|
85
75
|
const { value, error } = schema.validate(input, {
|
|
86
76
|
...defaultOptions,
|
|
87
77
|
...options,
|
|
88
78
|
})
|
|
89
79
|
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (error) {
|
|
95
|
-
vr.error = createError(input, error, objectName)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return vr
|
|
80
|
+
const err = error ? createError(input, error, objectName) : null
|
|
81
|
+
return [err, value]
|
|
99
82
|
}
|
|
100
83
|
|
|
101
84
|
/**
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
const started = Date.now()
|
|
2
|
-
import { workerData, parentPort } from 'node:worker_threads'
|
|
3
|
-
import { inspect } from 'node:util'
|
|
4
|
-
const { workerFile, workerIndex, logEvery = 1000, metric = 'worker' } = workerData || {}
|
|
5
|
-
|
|
6
|
-
if (!workerFile) {
|
|
7
|
-
throw new Error('workerData.workerFile is required!')
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
// console.log(`worker#${workerIndex} created`)
|
|
11
|
-
|
|
12
|
-
try {
|
|
13
|
-
// require('esbuild-register') // alternative
|
|
14
|
-
// require('ts-node/register/transpile-only')
|
|
15
|
-
// require('tsx/cjs/api').register() // https://tsx.is/dev-api/register-cjs
|
|
16
|
-
const { register } = await import('tsx/esm/api')
|
|
17
|
-
register() // https://tsx.is/dev-api/register-esm
|
|
18
|
-
// require('tsconfig-paths/register')
|
|
19
|
-
} catch {} // require if exists
|
|
20
|
-
|
|
21
|
-
const { WorkerClass } = await import(workerFile)
|
|
22
|
-
const worker = new WorkerClass(workerData)
|
|
23
|
-
|
|
24
|
-
console.log(`${metric}#${workerIndex} loaded in ${Date.now() - started} ms`)
|
|
25
|
-
|
|
26
|
-
let errors = 0
|
|
27
|
-
let processed = 0
|
|
28
|
-
|
|
29
|
-
parentPort.on('message', async msg => {
|
|
30
|
-
if (msg === null) {
|
|
31
|
-
// console.log(`EXIT (null) received by ${index}, exiting`)
|
|
32
|
-
parentPort.close()
|
|
33
|
-
|
|
34
|
-
logStats(true)
|
|
35
|
-
|
|
36
|
-
return
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// console.log(`message received by worker ${index}: `, msg)
|
|
40
|
-
|
|
41
|
-
try {
|
|
42
|
-
const out = await worker.process(msg.payload, msg.index)
|
|
43
|
-
|
|
44
|
-
parentPort.postMessage({
|
|
45
|
-
index: msg.index,
|
|
46
|
-
payload: out,
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
processed++
|
|
50
|
-
|
|
51
|
-
if (processed % logEvery === 0) logStats()
|
|
52
|
-
} catch (err) {
|
|
53
|
-
parentPort.postMessage({
|
|
54
|
-
index: msg.index,
|
|
55
|
-
error: err,
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
errors++
|
|
59
|
-
console.log(`${metric}#${workerIndex} errors: ${errors}`)
|
|
60
|
-
}
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
const inspectOpt = {
|
|
64
|
-
colors: true,
|
|
65
|
-
breakLength: 120,
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function logStats(final) {
|
|
69
|
-
const { rss, heapUsed, heapTotal, external } = process.memoryUsage()
|
|
70
|
-
|
|
71
|
-
console.log(
|
|
72
|
-
inspect(
|
|
73
|
-
{
|
|
74
|
-
[`${metric}${workerIndex}`]: processed,
|
|
75
|
-
errors,
|
|
76
|
-
heapUsed: mb(heapUsed),
|
|
77
|
-
heapTotal: mb(heapTotal),
|
|
78
|
-
rss: mb(rss),
|
|
79
|
-
external: mb(external),
|
|
80
|
-
...(final ? { final: true } : {}),
|
|
81
|
-
},
|
|
82
|
-
inspectOpt,
|
|
83
|
-
),
|
|
84
|
-
)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function mb(b) {
|
|
88
|
-
return Math.round(b / (1024 * 1024))
|
|
89
|
-
}
|