@rjsf/validator-ajv8 6.4.2 → 6.5.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/lib/types.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import Ajv, { Options, ErrorObject } from 'ajv';
2
2
  import { FormatsPluginOptions } from 'ajv-formats';
3
+ /** The type describing the value for the `suppressDuplicateFiltering` option */
4
+ export type SuppressDuplicateFilteringType = 'anyOf' | 'oneOf' | 'all' | 'none';
3
5
  /** The type describing how to customize the AJV6 validator
4
6
  */
5
7
  export interface CustomValidatorOptionsType {
@@ -17,6 +19,13 @@ export interface CustomValidatorOptionsType {
17
19
  AjvClass?: typeof Ajv;
18
20
  /** A function to call to extend AJV, such as `ajvErrors()` */
19
21
  extenderFn?: (ajv: Ajv) => Ajv;
22
+ /** When set, suppresses duplicate error filtering for the specified keyword(s):
23
+ * - `'none'` (default): both `anyOf` and `oneOf` duplicate errors are filtered
24
+ * - `'all'`: disables all duplicate filtering
25
+ * - `'anyOf'`: disables filtering for `anyOf` errors only (oneOf duplicates are still filtered)
26
+ * - `'oneOf'`: disables filtering for `oneOf` errors only (anyOf duplicates are still filtered)
27
+ */
28
+ suppressDuplicateFiltering?: SuppressDuplicateFilteringType;
20
29
  }
21
30
  /** The type describing a function that takes a list of Ajv `ErrorObject`s and localizes them
22
31
  */
@@ -1,6 +1,6 @@
1
1
  import Ajv from 'ajv';
2
2
  import { CustomValidator, ErrorTransformer, FormContextType, RJSFSchema, StrictRJSFSchema, UiSchema, ValidationData, ValidatorType } from '@rjsf/utils';
3
- import { CustomValidatorOptionsType, Localizer } from './types.js';
3
+ import { CustomValidatorOptionsType, Localizer, SuppressDuplicateFilteringType } from './types.js';
4
4
  import { RawValidationErrorsType } from './processRawValidationErrors.js';
5
5
  /** `ValidatorType` implementation that uses the AJV 8 validation mechanism.
6
6
  */
@@ -15,6 +15,11 @@ export default class AJV8Validator<T = any, S extends StrictRJSFSchema = RJSFSch
15
15
  * @private
16
16
  */
17
17
  readonly localizer?: Localizer;
18
+ /** Controls which duplicate error filtering is suppressed; see `filterDuplicateErrors`
19
+ *
20
+ * @private
21
+ */
22
+ readonly suppressDuplicateFiltering?: SuppressDuplicateFilteringType;
18
23
  /** Constructs an `AJV8Validator` instance using the `options`
19
24
  *
20
25
  * @param options - The `CustomValidatorOptionsType` options that are used to create the AJV instance
package/lib/validator.js CHANGED
@@ -10,9 +10,10 @@ export default class AJV8Validator {
10
10
  * @param [localizer] - If provided, is used to localize a list of Ajv `ErrorObject`s
11
11
  */
12
12
  constructor(options, localizer) {
13
- const { additionalMetaSchemas, customFormats, ajvOptionsOverrides, ajvFormatOptions, AjvClass, extenderFn } = options;
13
+ const { additionalMetaSchemas, customFormats, ajvOptionsOverrides, ajvFormatOptions, AjvClass, extenderFn, suppressDuplicateFiltering, } = options;
14
14
  this.ajv = createAjvInstance(additionalMetaSchemas, customFormats, ajvOptionsOverrides, ajvFormatOptions, AjvClass, extenderFn);
15
15
  this.localizer = localizer;
16
+ this.suppressDuplicateFiltering = suppressDuplicateFiltering;
16
17
  }
17
18
  /** Resets the internal AJV validator to clear schemas from it. Can be helpful for resetting the validator for tests.
18
19
  */
@@ -105,7 +106,7 @@ export default class AJV8Validator {
105
106
  */
106
107
  validateFormData(formData, schema, customValidate, transformErrors, uiSchema) {
107
108
  const rawErrors = this.rawValidation(schema, formData);
108
- return processRawValidationErrors(this, rawErrors, formData, schema, customValidate, transformErrors, uiSchema);
109
+ return processRawValidationErrors(this, rawErrors, formData, schema, customValidate, transformErrors, uiSchema, this.suppressDuplicateFiltering);
109
110
  }
110
111
  /**
111
112
  * This function checks if a schema needs to be added and if the root schemas don't match it removes the old root schema from the ajv instance and adds the new one.
@@ -1 +1 @@
1
- {"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rjsf/validator-ajv8",
3
- "version": "6.4.2",
3
+ "version": "6.5.0",
4
4
  "main": "dist/index.js",
5
5
  "module": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -77,16 +77,16 @@
77
77
  ]
78
78
  },
79
79
  "dependencies": {
80
- "ajv": "^8.17.1",
80
+ "ajv": "^8.18.0",
81
81
  "ajv-formats": "^2.1.1",
82
- "lodash": "^4.17.23",
83
- "lodash-es": "^4.17.23"
82
+ "lodash": "^4.18.1",
83
+ "lodash-es": "^4.18.1"
84
84
  },
85
85
  "peerDependencies": {
86
86
  "@rjsf/utils": "^6.4.x"
87
87
  },
88
88
  "devDependencies": {
89
- "@rjsf/utils": "6.4.2",
89
+ "@rjsf/utils": "6.5.0",
90
90
  "@types/json-schema": "^7.0.15",
91
91
  "ajv-i18n": "^4.2.0",
92
92
  "eslint": "^8.57.1"
@@ -1,6 +1,6 @@
1
1
  import { FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '@rjsf/utils';
2
2
 
3
- import { Localizer, ValidatorFunctions } from './types';
3
+ import { Localizer, SuppressDuplicateFilteringType, ValidatorFunctions } from './types';
4
4
  import AJV8PrecompiledValidator from './precompiledValidator';
5
5
 
6
6
  /** Creates and returns a `ValidatorType` interface that is implemented with a precompiled validator. If a `localizer`
@@ -12,12 +12,18 @@ import AJV8PrecompiledValidator from './precompiledValidator';
12
12
  * @param validateFns - The map of the validation functions that are created by the `compileSchemaValidators()` function
13
13
  * @param rootSchema - The root schema that was used with the `compileSchemaValidators()` function
14
14
  * @param [localizer] - If provided, is used to localize a list of Ajv `ErrorObject`s
15
+ * @param [suppressDuplicateFiltering] - Controls which duplicate filtering is suppressed; see `filterDuplicateErrors`
15
16
  * @returns - The precompiled validator implementation resulting from the set of parameters provided
16
17
  */
17
18
  export default function createPrecompiledValidator<
18
19
  T = any,
19
20
  S extends StrictRJSFSchema = RJSFSchema,
20
21
  F extends FormContextType = any,
21
- >(validateFns: ValidatorFunctions, rootSchema: S, localizer?: Localizer): ValidatorType<T, S, F> {
22
- return new AJV8PrecompiledValidator<T, S, F>(validateFns, rootSchema, localizer);
22
+ >(
23
+ validateFns: ValidatorFunctions,
24
+ rootSchema: S,
25
+ localizer?: Localizer,
26
+ suppressDuplicateFiltering?: SuppressDuplicateFilteringType,
27
+ ): ValidatorType<T, S, F> {
28
+ return new AJV8PrecompiledValidator<T, S, F>(validateFns, rootSchema, localizer, suppressDuplicateFiltering);
23
29
  }
@@ -16,7 +16,7 @@ import {
16
16
  ValidatorType,
17
17
  } from '@rjsf/utils';
18
18
 
19
- import { CompiledValidateFunction, Localizer, ValidatorFunctions } from './types';
19
+ import { CompiledValidateFunction, Localizer, SuppressDuplicateFilteringType, ValidatorFunctions } from './types';
20
20
  import processRawValidationErrors, { RawValidationErrorsType } from './processRawValidationErrors';
21
21
 
22
22
  /** `ValidatorType` implementation that uses an AJV 8 precompiled validator as created by the
@@ -51,17 +51,30 @@ export default class AJV8PrecompiledValidator<
51
51
  */
52
52
  readonly localizer?: Localizer;
53
53
 
54
+ /** Controls which duplicate error filtering is suppressed; see `filterDuplicateErrors`
55
+ *
56
+ * @private
57
+ */
58
+ readonly suppressDuplicateFiltering?: SuppressDuplicateFilteringType;
59
+
54
60
  /** Constructs an `AJV8PrecompiledValidator` instance using the `validateFns` and `rootSchema`
55
61
  *
56
62
  * @param validateFns - The map of the validation functions that are generated by the `schemaCompile()` function
57
63
  * @param rootSchema - The root schema that was used with the `compileSchema()` function
58
64
  * @param [localizer] - If provided, is used to localize a list of Ajv `ErrorObject`s
65
+ * @param [suppressDuplicateFiltering] - Controls which duplicate filtering is suppressed; see `filterDuplicateErrors`
59
66
  * @throws - Error when the base schema of the precompiled validator does not have a matching validator function
60
67
  */
61
- constructor(validateFns: ValidatorFunctions, rootSchema: S, localizer?: Localizer) {
68
+ constructor(
69
+ validateFns: ValidatorFunctions,
70
+ rootSchema: S,
71
+ localizer?: Localizer,
72
+ suppressDuplicateFiltering?: SuppressDuplicateFilteringType,
73
+ ) {
62
74
  this.rootSchema = rootSchema;
63
75
  this.validateFns = validateFns;
64
76
  this.localizer = localizer;
77
+ this.suppressDuplicateFiltering = suppressDuplicateFiltering;
65
78
  this.mainValidator = this.getValidator(rootSchema);
66
79
  }
67
80
 
@@ -142,7 +155,16 @@ export default class AJV8PrecompiledValidator<
142
155
  uiSchema?: UiSchema<T, S, F>,
143
156
  ): ValidationData<T> {
144
157
  const rawErrors = this.rawValidation<ErrorObject>(schema, formData);
145
- return processRawValidationErrors(this, rawErrors, formData, schema, customValidate, transformErrors, uiSchema);
158
+ return processRawValidationErrors(
159
+ this,
160
+ rawErrors,
161
+ formData,
162
+ schema,
163
+ customValidate,
164
+ transformErrors,
165
+ uiSchema,
166
+ this.suppressDuplicateFiltering,
167
+ );
146
168
  }
147
169
 
148
170
  /** Validates data against a schema, returning true if the data is valid, or false otherwise. If the schema is
@@ -20,22 +20,68 @@ import {
20
20
  ValidatorType,
21
21
  } from '@rjsf/utils';
22
22
 
23
+ import { SuppressDuplicateFilteringType } from './types';
24
+
23
25
  export type RawValidationErrorsType<Result = any> = {
24
26
  errors?: Result[];
25
27
  validationError?: Error;
26
28
  };
27
29
 
30
+ /** Filters duplicate errors from `anyOf`/`oneOf` schema paths according to the `suppressDuplicateFiltering` flag.
31
+ *
32
+ * @param errorList - The list of `RJSFValidationError`s to filter
33
+ * @param [suppressDuplicateFiltering='none'] - Controls which duplicate filtering is suppressed:
34
+ * - `'none'` (default): filters duplicates for both `anyOf` and `oneOf`
35
+ * - `'all'`: returns `errorList` unmodified
36
+ * - `'anyOf'`: suppresses filtering for `anyOf` errors; `oneOf` duplicates are still filtered
37
+ * - `'oneOf'`: suppresses filtering for `oneOf` errors; `anyOf` duplicates are still filtered
38
+ */
39
+ export function filterDuplicateErrors(
40
+ errorList: RJSFValidationError[],
41
+ suppressDuplicateFiltering: SuppressDuplicateFilteringType = 'none',
42
+ ): RJSFValidationError[] {
43
+ if (suppressDuplicateFiltering === 'all') {
44
+ return errorList;
45
+ }
46
+ return errorList.reduce((acc: RJSFValidationError[], err: RJSFValidationError) => {
47
+ const { message, schemaPath } = err;
48
+ // Compute the index only when filtering for that keyword is not suppressed.
49
+ // 'all' is already handled above; within the reduce, only 'none', 'anyOf', and 'oneOf' are possible.
50
+ const anyOfIndex = suppressDuplicateFiltering !== 'anyOf' ? schemaPath?.indexOf(`/${ANY_OF_KEY}/`) : undefined;
51
+ const oneOfIndex = suppressDuplicateFiltering !== 'oneOf' ? schemaPath?.indexOf(`/${ONE_OF_KEY}/`) : undefined;
52
+ let schemaPrefix: string | undefined;
53
+ if (anyOfIndex && anyOfIndex >= 0) {
54
+ schemaPrefix = schemaPath?.substring(0, anyOfIndex);
55
+ } else if (oneOfIndex && oneOfIndex >= 0) {
56
+ schemaPrefix = schemaPath?.substring(0, oneOfIndex);
57
+ }
58
+ // If there is a schemaPrefix, then search for a duplicate message with the same prefix, otherwise undefined
59
+ const dup = schemaPrefix
60
+ ? acc.find((e: RJSFValidationError) => e.message === message && e.schemaPath?.startsWith(schemaPrefix))
61
+ : undefined;
62
+ if (!dup) {
63
+ acc.push(err);
64
+ }
65
+ return acc;
66
+ }, [] as RJSFValidationError[]);
67
+ }
68
+
28
69
  /** Transforming the error output from ajv to format used by @rjsf/utils.
29
70
  * At some point, components should be updated to support ajv.
30
71
  *
31
72
  * @param errors - The list of AJV errors to convert to `RJSFValidationErrors`
32
73
  * @param [uiSchema] - An optional uiSchema that is passed to `transformErrors` and `customValidate`
74
+ * @param [suppressDuplicateFiltering] - Controls which duplicate filtering is suppressed; see `filterDuplicateErrors`
33
75
  */
34
76
  export function transformRJSFValidationErrors<
35
77
  T = any,
36
78
  S extends StrictRJSFSchema = RJSFSchema,
37
79
  F extends FormContextType = any,
38
- >(errors: ErrorObject[] = [], uiSchema?: UiSchema<T, S, F>): RJSFValidationError[] {
80
+ >(
81
+ errors: ErrorObject[] = [],
82
+ uiSchema?: UiSchema<T, S, F>,
83
+ suppressDuplicateFiltering?: SuppressDuplicateFilteringType,
84
+ ): RJSFValidationError[] {
39
85
  const errorList = errors.map((e: ErrorObject) => {
40
86
  const { instancePath, keyword, params, schemaPath, parentSchema, ...rest } = e;
41
87
  let { message = '' } = rest;
@@ -107,28 +153,7 @@ export function transformRJSFValidationErrors<
107
153
  title: uiTitle,
108
154
  };
109
155
  });
110
- // Filter out duplicates around anyOf/oneOf messages
111
- return errorList.reduce((acc: RJSFValidationError[], err: RJSFValidationError) => {
112
- const { message, schemaPath } = err;
113
- const anyOfIndex = schemaPath?.indexOf(`/${ANY_OF_KEY}/`);
114
- const oneOfIndex = schemaPath?.indexOf(`/${ONE_OF_KEY}/`);
115
- let schemaPrefix: string | undefined;
116
- // Look specifically for `/anyOr/` or `/oneOf/` within the schemaPath information
117
- if (anyOfIndex && anyOfIndex >= 0) {
118
- schemaPrefix = schemaPath?.substring(0, anyOfIndex);
119
- } else if (oneOfIndex && oneOfIndex >= 0) {
120
- schemaPrefix = schemaPath?.substring(0, oneOfIndex);
121
- }
122
- // If there is a schemaPrefix, then search for a duplicate message with the same prefix, otherwise undefined
123
- const dup = schemaPrefix
124
- ? acc.find((e: RJSFValidationError) => e.message === message && e.schemaPath?.startsWith(schemaPrefix))
125
- : undefined;
126
- if (!dup) {
127
- // Only push an error that is not a duplicate
128
- acc.push(err);
129
- }
130
- return acc;
131
- }, [] as RJSFValidationError[]);
156
+ return filterDuplicateErrors(errorList, suppressDuplicateFiltering);
132
157
  }
133
158
 
134
159
  /** This function processes the `formData` with an optional user contributed `customValidate` function, which receives
@@ -143,6 +168,7 @@ export function transformRJSFValidationErrors<
143
168
  * @param [customValidate] - An optional function that is used to perform custom validation
144
169
  * @param [transformErrors] - An optional function that is used to transform errors after AJV validation
145
170
  * @param [uiSchema] - An optional uiSchema that is passed to `transformErrors` and `customValidate`
171
+ * @param [suppressDuplicateFiltering] - Controls which duplicate filtering is suppressed; see `filterDuplicateErrors`
146
172
  */
147
173
  export default function processRawValidationErrors<
148
174
  T = any,
@@ -156,9 +182,10 @@ export default function processRawValidationErrors<
156
182
  customValidate?: CustomValidator<T, S, F>,
157
183
  transformErrors?: ErrorTransformer<T, S, F>,
158
184
  uiSchema?: UiSchema<T, S, F>,
185
+ suppressDuplicateFiltering?: SuppressDuplicateFilteringType,
159
186
  ) {
160
187
  const { validationError: invalidSchemaError } = rawErrors;
161
- let errors = transformRJSFValidationErrors<T, S, F>(rawErrors.errors, uiSchema);
188
+ let errors = transformRJSFValidationErrors<T, S, F>(rawErrors.errors, uiSchema, suppressDuplicateFiltering);
162
189
 
163
190
  if (invalidSchemaError) {
164
191
  errors = [...errors, { stack: invalidSchemaError!.message }];
package/src/types.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  import Ajv, { Options, ErrorObject } from 'ajv';
2
2
  import { FormatsPluginOptions } from 'ajv-formats';
3
3
 
4
+ /** The type describing the value for the `suppressDuplicateFiltering` option */
5
+ export type SuppressDuplicateFilteringType = 'anyOf' | 'oneOf' | 'all' | 'none';
6
+
4
7
  /** The type describing how to customize the AJV6 validator
5
8
  */
6
9
  export interface CustomValidatorOptionsType {
@@ -18,6 +21,13 @@ export interface CustomValidatorOptionsType {
18
21
  AjvClass?: typeof Ajv;
19
22
  /** A function to call to extend AJV, such as `ajvErrors()` */
20
23
  extenderFn?: (ajv: Ajv) => Ajv;
24
+ /** When set, suppresses duplicate error filtering for the specified keyword(s):
25
+ * - `'none'` (default): both `anyOf` and `oneOf` duplicate errors are filtered
26
+ * - `'all'`: disables all duplicate filtering
27
+ * - `'anyOf'`: disables filtering for `anyOf` errors only (oneOf duplicates are still filtered)
28
+ * - `'oneOf'`: disables filtering for `oneOf` errors only (anyOf duplicates are still filtered)
29
+ */
30
+ suppressDuplicateFiltering?: SuppressDuplicateFilteringType;
21
31
  }
22
32
 
23
33
  /** The type describing a function that takes a list of Ajv `ErrorObject`s and localizes them
package/src/validator.ts CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  hashForSchema,
16
16
  } from '@rjsf/utils';
17
17
 
18
- import { CustomValidatorOptionsType, Localizer } from './types';
18
+ import { CustomValidatorOptionsType, Localizer, SuppressDuplicateFilteringType } from './types';
19
19
  import createAjvInstance from './createAjvInstance';
20
20
  import processRawValidationErrors, { RawValidationErrorsType } from './processRawValidationErrors';
21
21
 
@@ -38,14 +38,27 @@ export default class AJV8Validator<
38
38
  */
39
39
  readonly localizer?: Localizer;
40
40
 
41
+ /** Controls which duplicate error filtering is suppressed; see `filterDuplicateErrors`
42
+ *
43
+ * @private
44
+ */
45
+ readonly suppressDuplicateFiltering?: SuppressDuplicateFilteringType;
46
+
41
47
  /** Constructs an `AJV8Validator` instance using the `options`
42
48
  *
43
49
  * @param options - The `CustomValidatorOptionsType` options that are used to create the AJV instance
44
50
  * @param [localizer] - If provided, is used to localize a list of Ajv `ErrorObject`s
45
51
  */
46
52
  constructor(options: CustomValidatorOptionsType, localizer?: Localizer) {
47
- const { additionalMetaSchemas, customFormats, ajvOptionsOverrides, ajvFormatOptions, AjvClass, extenderFn } =
48
- options;
53
+ const {
54
+ additionalMetaSchemas,
55
+ customFormats,
56
+ ajvOptionsOverrides,
57
+ ajvFormatOptions,
58
+ AjvClass,
59
+ extenderFn,
60
+ suppressDuplicateFiltering,
61
+ } = options;
49
62
  this.ajv = createAjvInstance(
50
63
  additionalMetaSchemas,
51
64
  customFormats,
@@ -55,6 +68,7 @@ export default class AJV8Validator<
55
68
  extenderFn,
56
69
  );
57
70
  this.localizer = localizer;
71
+ this.suppressDuplicateFiltering = suppressDuplicateFiltering;
58
72
  }
59
73
 
60
74
  /** Resets the internal AJV validator to clear schemas from it. Can be helpful for resetting the validator for tests.
@@ -153,7 +167,16 @@ export default class AJV8Validator<
153
167
  uiSchema?: UiSchema<T, S, F>,
154
168
  ): ValidationData<T> {
155
169
  const rawErrors = this.rawValidation<ErrorObject>(schema, formData);
156
- return processRawValidationErrors(this, rawErrors, formData, schema, customValidate, transformErrors, uiSchema);
170
+ return processRawValidationErrors(
171
+ this,
172
+ rawErrors,
173
+ formData,
174
+ schema,
175
+ customValidate,
176
+ transformErrors,
177
+ uiSchema,
178
+ this.suppressDuplicateFiltering,
179
+ );
157
180
  }
158
181
 
159
182
  /**