@naturalcycles/nodejs-lib 15.8.0 → 15.10.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.
@@ -1,4 +1,4 @@
1
1
  /**
2
2
  * CommonLogger that logs to process.stdout directly (bypassing console.log).
3
3
  */
4
- export declare const stdoutLogger: import("@naturalcycles/js-lib/log").CommonLogger;
4
+ export declare const stdoutLogger: any;
@@ -1,10 +1,19 @@
1
- import { type ValidationFunctionResult } from '@naturalcycles/js-lib';
1
+ import { type ValidationFunction, type ValidationFunctionResult } from '@naturalcycles/js-lib';
2
2
  import type { JsonSchema, JsonSchemaBuilder } from '@naturalcycles/js-lib/json-schema';
3
3
  import type { Ajv } from 'ajv';
4
4
  import { AjvValidationError } from './ajvValidationError.js';
5
5
  export interface AjvValidationOptions {
6
- objectName?: string;
7
- objectId?: string;
6
+ /**
7
+ * Defaults to false.
8
+ *
9
+ * If set to true - AJV will mutate the input in case it needs to apply transformations
10
+ * (strip unknown properties, convert types, etc).
11
+ *
12
+ * If false - it will deep-clone the input to prevent its mutation. Will return the cloned/mutated object.
13
+ */
14
+ mutateInput?: boolean;
15
+ inputName?: string;
16
+ inputId?: string;
8
17
  }
9
18
  export interface AjvSchemaCfg {
10
19
  /**
@@ -12,11 +21,7 @@ export interface AjvSchemaCfg {
12
21
  * AjvSchema default (not the same as Ajv defaults) parameters
13
22
  */
14
23
  ajv: Ajv;
15
- /**
16
- * Dependent schemas to pass to Ajv instance constructor.
17
- * Simpler than instantiating and passing ajv instance yourself.
18
- */
19
- objectName?: string;
24
+ inputName?: string;
20
25
  /**
21
26
  * Option of Ajv.
22
27
  * If set to true - will mutate your input objects!
@@ -54,7 +59,6 @@ export declare class AjvSchema<T = unknown> {
54
59
  */
55
60
  static create<T>(schema: JsonSchemaBuilder<T> | JsonSchema<T> | AjvSchema<T>, cfg?: Partial<AjvSchemaCfg>): AjvSchema<T>;
56
61
  readonly cfg: AjvSchemaCfg;
57
- private getValidateFunction;
58
62
  /**
59
63
  * It returns the original object just for convenience.
60
64
  * Reminder: Ajv will MUTATE your object under 2 circumstances:
@@ -64,6 +68,8 @@ export declare class AjvSchema<T = unknown> {
64
68
  * Returned object is always the same object (`===`) that was passed, so it is returned just for convenience.
65
69
  */
66
70
  validate(input: T, opt?: AjvValidationOptions): T;
67
- isValid(input: T): boolean;
71
+ isValid(input: T, opt?: AjvValidationOptions): boolean;
68
72
  getValidationResult(input: T, opt?: AjvValidationOptions): ValidationFunctionResult<T, AjvValidationError>;
73
+ getValidationFunction(): ValidationFunction<T, AjvValidationError>;
74
+ private getAJVValidateFunction;
69
75
  }
@@ -1,4 +1,4 @@
1
- import { _isObject, _lazyValue } from '@naturalcycles/js-lib';
1
+ import { _isObject, _lazyValue, } from '@naturalcycles/js-lib';
2
2
  import { JsonSchemaAnyBuilder } from '@naturalcycles/js-lib/json-schema';
3
3
  import { _filterNullishValues } from '@naturalcycles/js-lib/object';
4
4
  import { _substringBefore } from '@naturalcycles/js-lib/string';
@@ -19,22 +19,11 @@ export class AjvSchema {
19
19
  lazy: false,
20
20
  ...cfg,
21
21
  ajv: cfg.ajv || getAjv(),
22
- // ajv:
23
- // cfg.ajv ||
24
- // getAjv({
25
- // schemas: cfg.schemas?.map(s => {
26
- // if (s instanceof AjvSchema) return s.schema
27
- // if (s instanceof JsonSchemaAnyBuilder) return s.build()
28
- // return s as JsonSchema
29
- // }),
30
- // coerceTypes: cfg.coerceTypes || false,
31
- // // verbose: true,
32
- // }),
33
- // Auto-detecting "ObjectName" from $id of the schema (e.g "Address.schema.json")
34
- objectName: cfg.objectName || (schema.$id ? _substringBefore(schema.$id, '.') : undefined),
22
+ // Auto-detecting "InputName" from $id of the schema (e.g "Address.schema.json")
23
+ inputName: cfg.inputName || (schema.$id ? _substringBefore(schema.$id, '.') : undefined),
35
24
  };
36
25
  if (!cfg.lazy) {
37
- this.getValidateFunction(); // compile eagerly
26
+ this.getAJVValidateFunction(); // compile eagerly
38
27
  }
39
28
  }
40
29
  /**
@@ -64,7 +53,6 @@ export class AjvSchema {
64
53
  return new AjvSchema(schema, cfg);
65
54
  }
66
55
  cfg;
67
- getValidateFunction = _lazyValue(() => this.cfg.ajv.compile(this.schema));
68
56
  /**
69
57
  * It returns the original object just for convenience.
70
58
  * Reminder: Ajv will MUTATE your object under 2 circumstances:
@@ -74,32 +62,46 @@ export class AjvSchema {
74
62
  * Returned object is always the same object (`===`) that was passed, so it is returned just for convenience.
75
63
  */
76
64
  validate(input, opt = {}) {
77
- const [error, output] = this.getValidationResult(input, opt);
78
- if (error)
79
- throw error;
65
+ const [err, output] = this.getValidationResult(input, opt);
66
+ if (err)
67
+ throw err;
80
68
  return output;
81
69
  }
82
- isValid(input) {
83
- return this.getValidateFunction()(input);
70
+ isValid(input, opt) {
71
+ const [err] = this.getValidationResult(input, opt);
72
+ return !err;
84
73
  }
85
74
  getValidationResult(input, opt = {}) {
86
- if (this.isValid(input))
87
- return [null, input];
88
- const errors = this.getValidateFunction().errors;
89
- const { objectId = _isObject(input) ? input['id'] : undefined, objectName = this.cfg.objectName, } = opt;
90
- const name = [objectName || 'Object', objectId].filter(Boolean).join('.');
75
+ const fn = this.getAJVValidateFunction();
76
+ const item = opt.mutateInput || typeof input !== 'object' ? input : structuredClone(input);
77
+ const valid = fn(item); // mutates item
78
+ if (valid)
79
+ return [null, item];
80
+ const errors = fn.errors;
81
+ const { inputId = _isObject(input) ? input['id'] : undefined, inputName = this.cfg.inputName || 'Object', } = opt;
82
+ const dataVar = [inputName, inputId].filter(Boolean).join('.');
91
83
  let message = this.cfg.ajv.errorsText(errors, {
92
- dataVar: name,
84
+ dataVar,
93
85
  separator,
94
86
  });
95
87
  const inputStringified = _inspect(input, { maxLen: 4000 });
96
88
  message = [message, 'Input: ' + inputStringified].join(separator);
97
89
  const err = new AjvValidationError(message, _filterNullishValues({
98
90
  errors,
99
- objectName,
100
- objectId,
91
+ inputName,
92
+ inputId,
101
93
  }));
102
- return [err, input];
94
+ return [err, item];
103
95
  }
96
+ getValidationFunction() {
97
+ return (input, opt) => {
98
+ return this.getValidationResult(input, {
99
+ mutateInput: opt?.mutateInput,
100
+ inputName: opt?.inputName,
101
+ inputId: opt?.inputId,
102
+ });
103
+ };
104
+ }
105
+ getAJVValidateFunction = _lazyValue(() => this.cfg.ajv.compile(this.schema));
104
106
  }
105
107
  const separator = '\n';
@@ -3,8 +3,8 @@ import { AppError } from '@naturalcycles/js-lib/error/error.util.js';
3
3
  import type { ErrorObject } from 'ajv';
4
4
  export interface AjvValidationErrorData extends ErrorData {
5
5
  errors: ErrorObject[];
6
- objectName?: string;
7
- objectId?: string;
6
+ inputName?: string;
7
+ inputId?: string;
8
8
  }
9
9
  export declare class AjvValidationError extends AppError<AjvValidationErrorData> {
10
10
  constructor(message: string, data: AjvValidationErrorData);
@@ -6,7 +6,7 @@ import { Ajv } from 'ajv';
6
6
  * This function should be used as much as possible,
7
7
  * to benefit from cached Ajv instance.
8
8
  */
9
- export declare const getAjv: import("@naturalcycles/js-lib/types").Lazy<Ajv>;
9
+ export declare const getAjv: any;
10
10
  /**
11
11
  * Create Ajv with modified defaults.
12
12
  *
@@ -10,7 +10,7 @@ export declare const numberSchema: NumberSchema<number>;
10
10
  export declare const numberSchemaTyped: <T>() => NumberSchema<T>;
11
11
  export declare const integerSchema: NumberSchema<number>;
12
12
  export declare const percentageSchema: NumberSchema<number>;
13
- export declare const dateStringSchema: StringSchema<import("@naturalcycles/js-lib/types").IsoDate>;
13
+ export declare const dateStringSchema: StringSchema<IsoDate>;
14
14
  export declare const binarySchema: import("joi").BinarySchema<Buffer<ArrayBufferLike>>;
15
15
  export declare const dateObjectSchema: ObjectSchema<any>;
16
16
  export declare const dateIntervalStringSchema: StringSchema<string>;
@@ -13,8 +13,8 @@ import type { ValidationErrorItem } from 'joi';
13
13
  */
14
14
  export interface JoiValidationErrorData extends ErrorData {
15
15
  joiValidationErrorItems: ValidationErrorItem[];
16
- joiValidationObjectName?: string;
17
- joiValidationObjectId?: string;
16
+ joiValidationInputName?: string;
17
+ joiValidationInputId?: string;
18
18
  /**
19
19
  * Error "annotation" is stripped in Error.message.
20
20
  * This field contains the "full" annotation.
@@ -1,6 +1,7 @@
1
- import { type ValidationFunctionResult } from '@naturalcycles/js-lib';
1
+ import { type ValidationFunction, type ValidationFunctionResult } from '@naturalcycles/js-lib';
2
2
  import type { AnySchema, ValidationOptions } from 'joi';
3
3
  import { JoiValidationError } from './joi.validation.error.js';
4
+ export declare function getJoiValidationFunction<T>(schema: AnySchema<T>): ValidationFunction<T, JoiValidationError>;
4
5
  /**
5
6
  * Validates with Joi.
6
7
  * Throws JoiValidationError if invalid.
@@ -8,7 +9,7 @@ import { JoiValidationError } from './joi.validation.error.js';
8
9
  *
9
10
  * If `schema` is undefined - returns value as is.
10
11
  */
11
- export declare function validate<T>(input: any, schema?: AnySchema<T>, objectName?: string, opt?: ValidationOptions): T;
12
+ export declare function validate<T>(input: any, schema?: AnySchema<T>, inputName?: string, opt?: ValidationOptions): T;
12
13
  /**
13
14
  * Validates with Joi.
14
15
  * Returns JoiValidationResult with converted value and error (if any).
@@ -18,7 +19,7 @@ export declare function validate<T>(input: any, schema?: AnySchema<T>, objectNam
18
19
  *
19
20
  * If `schema` is undefined - returns value as is.
20
21
  */
21
- export declare function getValidationResult<T>(input: T, schema?: AnySchema<T>, objectName?: string, options?: ValidationOptions): ValidationFunctionResult<T, JoiValidationError>;
22
+ export declare function getValidationResult<T>(input: T, schema?: AnySchema<T>, inputName?: string, options?: ValidationOptions): ValidationFunctionResult<T, JoiValidationError>;
22
23
  /**
23
24
  * Convenience function that returns true if !error.
24
25
  */
@@ -5,7 +5,8 @@
5
5
  *
6
6
  * "Converts" mean e.g trims all strings from leading/trailing spaces.
7
7
  */
8
- import { _hb, _isObject } from '@naturalcycles/js-lib';
8
+ import { _hb, _isObject, } from '@naturalcycles/js-lib';
9
+ import { _assert } from '@naturalcycles/js-lib/error/assert.js';
9
10
  import { _truncateMiddle } from '@naturalcycles/js-lib/string/string.util.js';
10
11
  import { JoiValidationError } from './joi.validation.error.js';
11
12
  // Strip colors in production (for e.g Sentry reporting)
@@ -31,6 +32,12 @@ const defaultOptions = {
31
32
  // stack: true,
32
33
  // }
33
34
  };
35
+ export function getJoiValidationFunction(schema) {
36
+ return (input, opt) => {
37
+ _assert(!opt?.mutateInput, 'mutateInput=true is not yet supported with Joi');
38
+ return getValidationResult(input, schema, opt?.inputName);
39
+ };
40
+ }
34
41
  /**
35
42
  * Validates with Joi.
36
43
  * Throws JoiValidationError if invalid.
@@ -38,8 +45,8 @@ const defaultOptions = {
38
45
  *
39
46
  * If `schema` is undefined - returns value as is.
40
47
  */
41
- export function validate(input, schema, objectName, opt = {}) {
42
- const [error, returnValue] = getValidationResult(input, schema, objectName, opt);
48
+ export function validate(input, schema, inputName, opt = {}) {
49
+ const [error, returnValue] = getValidationResult(input, schema, inputName, opt);
43
50
  if (error)
44
51
  throw error;
45
52
  return returnValue;
@@ -53,14 +60,14 @@ export function validate(input, schema, objectName, opt = {}) {
53
60
  *
54
61
  * If `schema` is undefined - returns value as is.
55
62
  */
56
- export function getValidationResult(input, schema, objectName, options = {}) {
63
+ export function getValidationResult(input, schema, inputName, options = {}) {
57
64
  if (!schema)
58
65
  return [null, input];
59
66
  const { value, error } = schema.validate(input, {
60
67
  ...defaultOptions,
61
68
  ...options,
62
69
  });
63
- const err = error ? createError(input, error, objectName) : null;
70
+ const err = error ? createError(input, error, inputName) : null;
64
71
  return [err, value];
65
72
  }
66
73
  /**
@@ -89,12 +96,12 @@ export function convert(input, schema) {
89
96
  const { value } = schema.validate(input, defaultOptions);
90
97
  return value;
91
98
  }
92
- function createError(value, err, objectName) {
99
+ function createError(value, err, inputName) {
93
100
  const tokens = [];
94
- const objectId = _isObject(value) ? value['id'] : undefined;
95
- if (objectId || objectName) {
96
- objectName ||= value?.constructor?.name;
97
- tokens.push('Invalid ' + [objectName, objectId].filter(Boolean).join('.'));
101
+ const inputId = _isObject(value) ? value['id'] : undefined;
102
+ if (inputId || inputName) {
103
+ inputName ||= value?.constructor?.name;
104
+ tokens.push('Invalid ' + [inputName, inputId].filter(Boolean).join('.'));
98
105
  }
99
106
  const annotation = err.annotate(stripColors);
100
107
  if (annotation.length > 100) {
@@ -117,8 +124,8 @@ function createError(value, err, objectName) {
117
124
  const msg = tokens.join('\n');
118
125
  const data = {
119
126
  joiValidationErrorItems: err.details,
120
- ...(objectName && { joiValidationObjectName: objectName }),
121
- ...(objectId && { joiValidationObjectId: objectId }),
127
+ ...(inputName && { joiValidationInputName: inputName }),
128
+ ...(inputId && { joiValidationInputId: inputId }),
122
129
  };
123
130
  // Make annotation non-enumerable, to not get it automatically printed,
124
131
  // but still accessible
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/nodejs-lib",
3
3
  "type": "module",
4
- "version": "15.8.0",
4
+ "version": "15.10.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": "19.14.0"
26
+ "@naturalcycles/dev-lib": "18.4.2"
27
27
  },
28
28
  "exports": {
29
29
  ".": "./dist/index.js",
@@ -1,4 +1,9 @@
1
- import { _isObject, _lazyValue, type ValidationFunctionResult } from '@naturalcycles/js-lib'
1
+ import {
2
+ _isObject,
3
+ _lazyValue,
4
+ type ValidationFunction,
5
+ type ValidationFunctionResult,
6
+ } from '@naturalcycles/js-lib'
2
7
  import type { JsonSchema, JsonSchemaBuilder } from '@naturalcycles/js-lib/json-schema'
3
8
  import { JsonSchemaAnyBuilder } from '@naturalcycles/js-lib/json-schema'
4
9
  import { _filterNullishValues } from '@naturalcycles/js-lib/object'
@@ -9,8 +14,17 @@ import { AjvValidationError } from './ajvValidationError.js'
9
14
  import { getAjv } from './getAjv.js'
10
15
 
11
16
  export interface AjvValidationOptions {
12
- objectName?: string
13
- objectId?: string
17
+ /**
18
+ * Defaults to false.
19
+ *
20
+ * If set to true - AJV will mutate the input in case it needs to apply transformations
21
+ * (strip unknown properties, convert types, etc).
22
+ *
23
+ * If false - it will deep-clone the input to prevent its mutation. Will return the cloned/mutated object.
24
+ */
25
+ mutateInput?: boolean
26
+ inputName?: string
27
+ inputId?: string
14
28
  }
15
29
 
16
30
  export interface AjvSchemaCfg {
@@ -20,13 +34,7 @@ export interface AjvSchemaCfg {
20
34
  */
21
35
  ajv: Ajv
22
36
 
23
- /**
24
- * Dependent schemas to pass to Ajv instance constructor.
25
- * Simpler than instantiating and passing ajv instance yourself.
26
- */
27
- // schemas?: (JsonSchema | JsonSchemaBuilder | AjvSchema)[]
28
-
29
- objectName?: string
37
+ inputName?: string
30
38
 
31
39
  /**
32
40
  * Option of Ajv.
@@ -59,23 +67,12 @@ export class AjvSchema<T = unknown> {
59
67
  lazy: false,
60
68
  ...cfg,
61
69
  ajv: cfg.ajv || getAjv(),
62
- // ajv:
63
- // cfg.ajv ||
64
- // getAjv({
65
- // schemas: cfg.schemas?.map(s => {
66
- // if (s instanceof AjvSchema) return s.schema
67
- // if (s instanceof JsonSchemaAnyBuilder) return s.build()
68
- // return s as JsonSchema
69
- // }),
70
- // coerceTypes: cfg.coerceTypes || false,
71
- // // verbose: true,
72
- // }),
73
- // Auto-detecting "ObjectName" from $id of the schema (e.g "Address.schema.json")
74
- objectName: cfg.objectName || (schema.$id ? _substringBefore(schema.$id, '.') : undefined),
70
+ // Auto-detecting "InputName" from $id of the schema (e.g "Address.schema.json")
71
+ inputName: cfg.inputName || (schema.$id ? _substringBefore(schema.$id, '.') : undefined),
75
72
  }
76
73
 
77
74
  if (!cfg.lazy) {
78
- this.getValidateFunction() // compile eagerly
75
+ this.getAJVValidateFunction() // compile eagerly
79
76
  }
80
77
  }
81
78
 
@@ -114,8 +111,6 @@ export class AjvSchema<T = unknown> {
114
111
 
115
112
  readonly cfg: AjvSchemaCfg
116
113
 
117
- private getValidateFunction = _lazyValue(() => this.cfg.ajv.compile<T>(this.schema))
118
-
119
114
  /**
120
115
  * It returns the original object just for convenience.
121
116
  * Reminder: Ajv will MUTATE your object under 2 circumstances:
@@ -125,31 +120,37 @@ export class AjvSchema<T = unknown> {
125
120
  * Returned object is always the same object (`===`) that was passed, so it is returned just for convenience.
126
121
  */
127
122
  validate(input: T, opt: AjvValidationOptions = {}): T {
128
- const [error, output] = this.getValidationResult(input, opt)
129
- if (error) throw error
123
+ const [err, output] = this.getValidationResult(input, opt)
124
+ if (err) throw err
130
125
  return output
131
126
  }
132
127
 
133
- isValid(input: T): boolean {
134
- return this.getValidateFunction()(input)
128
+ isValid(input: T, opt?: AjvValidationOptions): boolean {
129
+ const [err] = this.getValidationResult(input, opt)
130
+ return !err
135
131
  }
136
132
 
137
133
  getValidationResult(
138
134
  input: T,
139
135
  opt: AjvValidationOptions = {},
140
136
  ): ValidationFunctionResult<T, AjvValidationError> {
141
- if (this.isValid(input)) return [null, input]
137
+ const fn = this.getAJVValidateFunction()
138
+
139
+ const item = opt.mutateInput || typeof input !== 'object' ? input : structuredClone(input)
142
140
 
143
- const errors = this.getValidateFunction().errors!
141
+ const valid = fn(item) // mutates item
142
+ if (valid) return [null, item]
143
+
144
+ const errors = fn.errors!
144
145
 
145
146
  const {
146
- objectId = _isObject(input) ? (input['id' as keyof T] as any) : undefined,
147
- objectName = this.cfg.objectName,
147
+ inputId = _isObject(input) ? (input['id' as keyof T] as any) : undefined,
148
+ inputName = this.cfg.inputName || 'Object',
148
149
  } = opt
149
- const name = [objectName || 'Object', objectId].filter(Boolean).join('.')
150
+ const dataVar = [inputName, inputId].filter(Boolean).join('.')
150
151
 
151
152
  let message = this.cfg.ajv.errorsText(errors, {
152
- dataVar: name,
153
+ dataVar,
153
154
  separator,
154
155
  })
155
156
 
@@ -160,12 +161,24 @@ export class AjvSchema<T = unknown> {
160
161
  message,
161
162
  _filterNullishValues({
162
163
  errors,
163
- objectName,
164
- objectId,
164
+ inputName,
165
+ inputId,
165
166
  }),
166
167
  )
167
- return [err, input]
168
+ return [err, item]
168
169
  }
170
+
171
+ getValidationFunction(): ValidationFunction<T, AjvValidationError> {
172
+ return (input, opt) => {
173
+ return this.getValidationResult(input, {
174
+ mutateInput: opt?.mutateInput,
175
+ inputName: opt?.inputName,
176
+ inputId: opt?.inputId,
177
+ })
178
+ }
179
+ }
180
+
181
+ private getAJVValidateFunction = _lazyValue(() => this.cfg.ajv.compile<T>(this.schema))
169
182
  }
170
183
 
171
184
  const separator = '\n'
@@ -4,8 +4,8 @@ import type { ErrorObject } from 'ajv'
4
4
 
5
5
  export interface AjvValidationErrorData extends ErrorData {
6
6
  errors: ErrorObject[]
7
- objectName?: string
8
- objectId?: string
7
+ inputName?: string
8
+ inputId?: string
9
9
  }
10
10
 
11
11
  export class AjvValidationError extends AppError<AjvValidationErrorData> {
@@ -14,8 +14,8 @@ import type { ValidationErrorItem } from 'joi'
14
14
  */
15
15
  export interface JoiValidationErrorData extends ErrorData {
16
16
  joiValidationErrorItems: ValidationErrorItem[]
17
- joiValidationObjectName?: string
18
- joiValidationObjectId?: string
17
+ joiValidationInputName?: string
18
+ joiValidationInputId?: string
19
19
  /**
20
20
  * Error "annotation" is stripped in Error.message.
21
21
  * This field contains the "full" annotation.
@@ -6,7 +6,13 @@
6
6
  * "Converts" mean e.g trims all strings from leading/trailing spaces.
7
7
  */
8
8
 
9
- import { _hb, _isObject, type ValidationFunctionResult } from '@naturalcycles/js-lib'
9
+ import {
10
+ _hb,
11
+ _isObject,
12
+ type ValidationFunction,
13
+ type ValidationFunctionResult,
14
+ } from '@naturalcycles/js-lib'
15
+ import { _assert } from '@naturalcycles/js-lib/error/assert.js'
10
16
  import { _truncateMiddle } from '@naturalcycles/js-lib/string/string.util.js'
11
17
  import type { AnySchema, ValidationError, ValidationOptions } from 'joi'
12
18
  import type { JoiValidationErrorData } from './joi.validation.error.js'
@@ -37,6 +43,15 @@ const defaultOptions: ValidationOptions = {
37
43
  // }
38
44
  }
39
45
 
46
+ export function getJoiValidationFunction<T>(
47
+ schema: AnySchema<T>,
48
+ ): ValidationFunction<T, JoiValidationError> {
49
+ return (input, opt) => {
50
+ _assert(!opt?.mutateInput, 'mutateInput=true is not yet supported with Joi')
51
+ return getValidationResult(input, schema, opt?.inputName)
52
+ }
53
+ }
54
+
40
55
  /**
41
56
  * Validates with Joi.
42
57
  * Throws JoiValidationError if invalid.
@@ -47,10 +62,10 @@ const defaultOptions: ValidationOptions = {
47
62
  export function validate<T>(
48
63
  input: any,
49
64
  schema?: AnySchema<T>,
50
- objectName?: string,
65
+ inputName?: string,
51
66
  opt: ValidationOptions = {},
52
67
  ): T {
53
- const [error, returnValue] = getValidationResult(input, schema, objectName, opt)
68
+ const [error, returnValue] = getValidationResult(input, schema, inputName, opt)
54
69
  if (error) throw error
55
70
  return returnValue
56
71
  }
@@ -67,7 +82,7 @@ export function validate<T>(
67
82
  export function getValidationResult<T>(
68
83
  input: T,
69
84
  schema?: AnySchema<T>,
70
- objectName?: string,
85
+ inputName?: string,
71
86
  options: ValidationOptions = {},
72
87
  ): ValidationFunctionResult<T, JoiValidationError> {
73
88
  if (!schema) return [null, input]
@@ -77,7 +92,7 @@ export function getValidationResult<T>(
77
92
  ...options,
78
93
  })
79
94
 
80
- const err = error ? createError(input, error, objectName) : null
95
+ const err = error ? createError(input, error, inputName) : null
81
96
  return [err, value]
82
97
  }
83
98
 
@@ -110,15 +125,15 @@ export function convert<T>(input: any, schema?: AnySchema<T>): T {
110
125
  return value
111
126
  }
112
127
 
113
- function createError(value: any, err: ValidationError, objectName?: string): JoiValidationError {
128
+ function createError(value: any, err: ValidationError, inputName?: string): JoiValidationError {
114
129
  const tokens: string[] = []
115
130
 
116
- const objectId = _isObject(value) ? (value['id'] as string) : undefined
131
+ const inputId = _isObject(value) ? (value['id'] as string) : undefined
117
132
 
118
- if (objectId || objectName) {
119
- objectName ||= value?.constructor?.name
133
+ if (inputId || inputName) {
134
+ inputName ||= value?.constructor?.name
120
135
 
121
- tokens.push('Invalid ' + [objectName, objectId].filter(Boolean).join('.'))
136
+ tokens.push('Invalid ' + [inputName, inputId].filter(Boolean).join('.'))
122
137
  }
123
138
 
124
139
  const annotation = err.annotate(stripColors)
@@ -151,8 +166,8 @@ function createError(value: any, err: ValidationError, objectName?: string): Joi
151
166
 
152
167
  const data: JoiValidationErrorData = {
153
168
  joiValidationErrorItems: err.details,
154
- ...(objectName && { joiValidationObjectName: objectName }),
155
- ...(objectId && { joiValidationObjectId: objectId }),
169
+ ...(inputName && { joiValidationInputName: inputName }),
170
+ ...(inputId && { joiValidationInputId: inputId }),
156
171
  }
157
172
 
158
173
  // Make annotation non-enumerable, to not get it automatically printed,