@rjsf/validator-ajv8 5.0.0-beta.8 → 5.0.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.
@@ -3,24 +3,57 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var toPath = require('lodash/toPath');
6
+ var isObject = require('lodash/isObject');
7
+ var clone = require('lodash/clone');
6
8
  var utils = require('@rjsf/utils');
9
+ var get = require('lodash/get');
7
10
  var Ajv = require('ajv');
8
11
  var addFormats = require('ajv-formats');
9
- var isObject = require('lodash/isObject');
10
12
 
11
13
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
14
 
13
15
  var toPath__default = /*#__PURE__*/_interopDefaultLegacy(toPath);
16
+ var isObject__default = /*#__PURE__*/_interopDefaultLegacy(isObject);
17
+ var clone__default = /*#__PURE__*/_interopDefaultLegacy(clone);
18
+ var get__default = /*#__PURE__*/_interopDefaultLegacy(get);
14
19
  var Ajv__default = /*#__PURE__*/_interopDefaultLegacy(Ajv);
15
20
  var addFormats__default = /*#__PURE__*/_interopDefaultLegacy(addFormats);
16
- var isObject__default = /*#__PURE__*/_interopDefaultLegacy(isObject);
17
21
 
18
- const AJV_CONFIG = {
22
+ function _extends() {
23
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
24
+ for (var i = 1; i < arguments.length; i++) {
25
+ var source = arguments[i];
26
+ for (var key in source) {
27
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
28
+ target[key] = source[key];
29
+ }
30
+ }
31
+ }
32
+ return target;
33
+ };
34
+ return _extends.apply(this, arguments);
35
+ }
36
+ function _objectWithoutPropertiesLoose(source, excluded) {
37
+ if (source == null) return {};
38
+ var target = {};
39
+ var sourceKeys = Object.keys(source);
40
+ var key, i;
41
+ for (i = 0; i < sourceKeys.length; i++) {
42
+ key = sourceKeys[i];
43
+ if (excluded.indexOf(key) >= 0) continue;
44
+ target[key] = source[key];
45
+ }
46
+ return target;
47
+ }
48
+
49
+ var AJV_CONFIG = {
19
50
  allErrors: true,
20
- multipleOfPrecision: 8
51
+ multipleOfPrecision: 8,
52
+ strict: false,
53
+ verbose: true
21
54
  };
22
- const COLOR_FORMAT_REGEX = /^(#?([0-9A-Fa-f]{3}){1,2}\b|aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow|(rgb\(\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*\))|(rgb\(\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*\)))$/;
23
- const DATA_URL_FORMAT_REGEX = /^data:([a-z]+\/[a-z0-9-+.]+)?;(?:name=(.*);)?base64,(.*)$/;
55
+ var COLOR_FORMAT_REGEX = /^(#?([0-9A-Fa-f]{3}){1,2}\b|aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow|(rgb\(\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*\))|(rgb\(\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*\)))$/;
56
+ var DATA_URL_FORMAT_REGEX = /^data:([a-z]+\/[a-z0-9-+.]+)?;(?:name=(.*);)?base64,(.*)$/;
24
57
  /** Creates an Ajv version 8 implementation object with standard support for the 'color` and `data-url` custom formats.
25
58
  * If `additionalMetaSchemas` are provided then the Ajv instance is modified to add each of the meta schemas in the
26
59
  * list. If `customFormats` are provided then those additional formats are added to the list of supported formats. If
@@ -34,44 +67,45 @@ const DATA_URL_FORMAT_REGEX = /^data:([a-z]+\/[a-z0-9-+.]+)?;(?:name=(.*);)?base
34
67
  * @param [customFormats] - The set of additional custom formats that the validator will support
35
68
  * @param [ajvOptionsOverrides={}] - The set of validator config override options
36
69
  * @param [ajvFormatOptions] - The `ajv-format` options to use when adding formats to `ajv`; pass `false` to disable it
70
+ * @param [AjvClass] - The `Ajv` class to use when creating the validator instance
37
71
  */
38
-
39
- function createAjvInstance(additionalMetaSchemas, customFormats, ajvOptionsOverrides, ajvFormatOptions) {
72
+ function createAjvInstance(additionalMetaSchemas, customFormats, ajvOptionsOverrides, ajvFormatOptions, AjvClass) {
40
73
  if (ajvOptionsOverrides === void 0) {
41
74
  ajvOptionsOverrides = {};
42
75
  }
43
-
44
- const ajv = new Ajv__default["default"]({ ...AJV_CONFIG,
45
- ...ajvOptionsOverrides
46
- });
47
-
48
- if (typeof ajvFormatOptions !== "boolean") {
76
+ if (AjvClass === void 0) {
77
+ AjvClass = Ajv__default["default"];
78
+ }
79
+ var ajv = new AjvClass(_extends({}, AJV_CONFIG, ajvOptionsOverrides));
80
+ if (ajvFormatOptions) {
49
81
  addFormats__default["default"](ajv, ajvFormatOptions);
50
- } // add custom formats
51
-
52
-
82
+ } else if (ajvFormatOptions !== false) {
83
+ addFormats__default["default"](ajv);
84
+ }
85
+ // add custom formats
53
86
  ajv.addFormat("data-url", DATA_URL_FORMAT_REGEX);
54
- ajv.addFormat("color", COLOR_FORMAT_REGEX); // add more schemas to validate against
55
-
87
+ ajv.addFormat("color", COLOR_FORMAT_REGEX);
88
+ // Add RJSF-specific additional properties keywords so Ajv doesn't report errors if strict is enabled.
89
+ ajv.addKeyword(utils.ADDITIONAL_PROPERTY_FLAG);
90
+ ajv.addKeyword(utils.RJSF_ADDITONAL_PROPERTIES_FLAG);
91
+ // add more schemas to validate against
56
92
  if (Array.isArray(additionalMetaSchemas)) {
57
93
  ajv.addMetaSchema(additionalMetaSchemas);
58
- } // add more custom formats to validate against
59
-
60
-
94
+ }
95
+ // add more custom formats to validate against
61
96
  if (isObject__default["default"](customFormats)) {
62
- Object.keys(customFormats).forEach(formatName => {
97
+ Object.keys(customFormats).forEach(function (formatName) {
63
98
  ajv.addFormat(formatName, customFormats[formatName]);
64
99
  });
65
100
  }
66
-
67
101
  return ajv;
68
102
  }
69
103
 
70
- const ROOT_SCHEMA_PREFIX = "__rjsf_rootSchema";
104
+ var _excluded = ["instancePath", "keyword", "params", "schemaPath", "parentSchema"];
105
+ var ROOT_SCHEMA_PREFIX = "__rjsf_rootSchema";
71
106
  /** `ValidatorType` implementation that uses the AJV 8 validation mechanism.
72
107
  */
73
-
74
- class AJV8Validator {
108
+ var AJV8Validator = /*#__PURE__*/function () {
75
109
  /** The AJV instance to use for all validations
76
110
  *
77
111
  * @private
@@ -87,16 +121,15 @@ class AJV8Validator {
87
121
  * @param options - The `CustomValidatorOptionsType` options that are used to create the AJV instance
88
122
  * @param [localizer] - If provided, is used to localize a list of Ajv `ErrorObject`s
89
123
  */
90
- constructor(options, localizer) {
124
+ function AJV8Validator(options, localizer) {
91
125
  this.ajv = void 0;
92
126
  this.localizer = void 0;
93
- const {
94
- additionalMetaSchemas,
95
- customFormats,
96
- ajvOptionsOverrides,
97
- ajvFormatOptions
98
- } = options;
99
- this.ajv = createAjvInstance(additionalMetaSchemas, customFormats, ajvOptionsOverrides, ajvFormatOptions);
127
+ var additionalMetaSchemas = options.additionalMetaSchemas,
128
+ customFormats = options.customFormats,
129
+ ajvOptionsOverrides = options.ajvOptionsOverrides,
130
+ ajvFormatOptions = options.ajvFormatOptions,
131
+ AjvClass = options.AjvClass;
132
+ this.ajv = createAjvInstance(additionalMetaSchemas, customFormats, ajvOptionsOverrides, ajvFormatOptions, AjvClass);
100
133
  this.localizer = localizer;
101
134
  }
102
135
  /** Transforms a ajv validation errors list:
@@ -118,82 +151,54 @@ class AJV8Validator {
118
151
  * @param errors - The list of RJSFValidationError objects
119
152
  * @private
120
153
  */
121
-
122
-
123
- toErrorSchema(errors) {
124
- if (!errors.length) {
125
- return {};
126
- }
127
-
128
- return errors.reduce((errorSchema, error) => {
129
- const {
130
- property,
131
- message
132
- } = error;
133
- const path = toPath__default["default"](property);
134
- let parent = errorSchema; // If the property is at the root (.level1) then toPath creates
135
- // an empty array element at the first index. Remove it.
136
-
137
- if (path.length > 0 && path[0] === "") {
138
- path.splice(0, 1);
139
- }
140
-
141
- for (const segment of path.slice(0)) {
142
- if (!(segment in parent)) {
143
- parent[segment] = {};
154
+ var _proto = AJV8Validator.prototype;
155
+ _proto.toErrorSchema = function toErrorSchema(errors) {
156
+ var builder = new utils.ErrorSchemaBuilder();
157
+ if (errors.length) {
158
+ errors.forEach(function (error) {
159
+ var property = error.property,
160
+ message = error.message;
161
+ var path = toPath__default["default"](property);
162
+ // If the property is at the root (.level1) then toPath creates
163
+ // an empty array element at the first index. Remove it.
164
+ if (path.length > 0 && path[0] === "") {
165
+ path.splice(0, 1);
144
166
  }
145
-
146
- parent = parent[segment];
147
- }
148
-
149
- if (Array.isArray(parent.__errors)) {
150
- // We store the list of errors for this node in a property named __errors
151
- // to avoid name collision with a possible sub schema field named
152
- // 'errors' (see `validate.createErrorHandler`).
153
- parent.__errors = parent.__errors.concat(message);
154
- } else {
155
167
  if (message) {
156
- parent.__errors = [message];
168
+ builder.addErrors(message, path);
157
169
  }
158
- }
159
-
160
- return errorSchema;
161
- }, {});
170
+ });
171
+ }
172
+ return builder.ErrorSchema;
162
173
  }
163
174
  /** Converts an `errorSchema` into a list of `RJSFValidationErrors`
164
175
  *
165
176
  * @param errorSchema - The `ErrorSchema` instance to convert
166
177
  * @param [fieldPath=[]] - The current field path, defaults to [] if not specified
167
- */
168
-
169
-
170
- toErrorList(errorSchema, fieldPath) {
178
+ */;
179
+ _proto.toErrorList = function toErrorList(errorSchema, fieldPath) {
180
+ var _this = this;
171
181
  if (fieldPath === void 0) {
172
182
  fieldPath = [];
173
183
  }
174
-
175
184
  if (!errorSchema) {
176
185
  return [];
177
186
  }
178
-
179
- let errorList = [];
180
-
187
+ var errorList = [];
181
188
  if (utils.ERRORS_KEY in errorSchema) {
182
- errorList = errorList.concat(errorSchema.__errors.map(message => {
183
- const property = "." + fieldPath.join(".");
189
+ errorList = errorList.concat(errorSchema[utils.ERRORS_KEY].map(function (message) {
190
+ var property = "." + fieldPath.join(".");
184
191
  return {
185
- property,
186
- message,
192
+ property: property,
193
+ message: message,
187
194
  stack: property + " " + message
188
195
  };
189
196
  }));
190
197
  }
191
-
192
- return Object.keys(errorSchema).reduce((acc, key) => {
198
+ return Object.keys(errorSchema).reduce(function (acc, key) {
193
199
  if (key !== utils.ERRORS_KEY) {
194
- acc = acc.concat(this.toErrorList(errorSchema[key], [...fieldPath, key]));
200
+ acc = acc.concat(_this.toErrorList(errorSchema[key], [].concat(fieldPath, [key])));
195
201
  }
196
-
197
202
  return acc;
198
203
  }, errorList);
199
204
  }
@@ -201,100 +206,141 @@ class AJV8Validator {
201
206
  *
202
207
  * @param formData - The form data around which the error handler is created
203
208
  * @private
204
- */
205
-
206
-
207
- createErrorHandler(formData) {
208
- const handler = {
209
+ */;
210
+ _proto.createErrorHandler = function createErrorHandler(formData) {
211
+ var _this2 = this;
212
+ var handler = {
209
213
  // We store the list of errors for this node in a property named __errors
210
214
  // to avoid name collision with a possible sub schema field named
211
215
  // 'errors' (see `utils.toErrorSchema`).
212
216
  __errors: [],
213
-
214
- addError(message) {
217
+ addError: function addError(message) {
215
218
  this.__errors.push(message);
216
219
  }
217
-
218
220
  };
219
-
220
- if (utils.isObject(formData)) {
221
- const formObject = formData;
222
- return Object.keys(formObject).reduce((acc, key) => {
223
- return { ...acc,
224
- [key]: this.createErrorHandler(formObject[key])
225
- };
221
+ if (Array.isArray(formData)) {
222
+ return formData.reduce(function (acc, value, key) {
223
+ var _extends2;
224
+ return _extends({}, acc, (_extends2 = {}, _extends2[key] = _this2.createErrorHandler(value), _extends2));
226
225
  }, handler);
227
226
  }
228
-
229
- if (Array.isArray(formData)) {
230
- return formData.reduce((acc, value, key) => {
231
- return { ...acc,
232
- [key]: this.createErrorHandler(value)
233
- };
227
+ if (isObject__default["default"](formData)) {
228
+ var formObject = formData;
229
+ return Object.keys(formObject).reduce(function (acc, key) {
230
+ var _extends3;
231
+ return _extends({}, acc, (_extends3 = {}, _extends3[key] = _this2.createErrorHandler(formObject[key]), _extends3));
234
232
  }, handler);
235
233
  }
236
-
237
234
  return handler;
238
235
  }
239
236
  /** Unwraps the `errorHandler` structure into the associated `ErrorSchema`, stripping the `addError` functions from it
240
237
  *
241
238
  * @param errorHandler - The `FormValidation` error handling structure
242
239
  * @private
243
- */
244
-
245
-
246
- unwrapErrorHandler(errorHandler) {
247
- return Object.keys(errorHandler).reduce((acc, key) => {
240
+ */;
241
+ _proto.unwrapErrorHandler = function unwrapErrorHandler(errorHandler) {
242
+ var _this3 = this;
243
+ return Object.keys(errorHandler).reduce(function (acc, key) {
244
+ var _extends5;
248
245
  if (key === "addError") {
249
246
  return acc;
250
247
  } else if (key === utils.ERRORS_KEY) {
251
- return { ...acc,
252
- [key]: errorHandler[key]
253
- };
248
+ var _extends4;
249
+ return _extends({}, acc, (_extends4 = {}, _extends4[key] = errorHandler[key], _extends4));
254
250
  }
255
-
256
- return { ...acc,
257
- [key]: this.unwrapErrorHandler(errorHandler[key])
258
- };
251
+ return _extends({}, acc, (_extends5 = {}, _extends5[key] = _this3.unwrapErrorHandler(errorHandler[key]), _extends5));
259
252
  }, {});
260
253
  }
261
254
  /** Transforming the error output from ajv to format used by @rjsf/utils.
262
255
  * At some point, components should be updated to support ajv.
263
256
  *
264
257
  * @param errors - The list of AJV errors to convert to `RJSFValidationErrors`
265
- * @private
266
- */
267
-
268
-
269
- transformRJSFValidationErrors(errors) {
258
+ * @protected
259
+ */;
260
+ _proto.transformRJSFValidationErrors = function transformRJSFValidationErrors(errors, uiSchema) {
270
261
  if (errors === void 0) {
271
262
  errors = [];
272
263
  }
273
-
274
- if (errors === null) {
275
- return [];
276
- }
277
-
278
- return errors.map(e => {
279
- const {
280
- instancePath,
281
- keyword,
282
- message,
283
- params,
284
- schemaPath
285
- } = e;
286
- const property = instancePath.replace(/\//g, "."); // put data in expected format
287
-
264
+ return errors.map(function (e) {
265
+ var instancePath = e.instancePath,
266
+ keyword = e.keyword,
267
+ params = e.params,
268
+ schemaPath = e.schemaPath,
269
+ parentSchema = e.parentSchema,
270
+ rest = _objectWithoutPropertiesLoose(e, _excluded);
271
+ var _rest$message = rest.message,
272
+ message = _rest$message === void 0 ? "" : _rest$message;
273
+ var property = instancePath.replace(/\//g, ".");
274
+ var stack = (property + " " + message).trim();
275
+ if ("missingProperty" in params) {
276
+ property = property ? property + "." + params.missingProperty : params.missingProperty;
277
+ var currentProperty = params.missingProperty;
278
+ var uiSchemaTitle = utils.getUiOptions(get__default["default"](uiSchema, "" + property.replace(/^\./, ""))).title;
279
+ if (uiSchemaTitle) {
280
+ message = message.replace(currentProperty, uiSchemaTitle);
281
+ } else {
282
+ var parentSchemaTitle = get__default["default"](parentSchema, [utils.PROPERTIES_KEY, currentProperty, "title"]);
283
+ if (parentSchemaTitle) {
284
+ message = message.replace(currentProperty, parentSchemaTitle);
285
+ }
286
+ }
287
+ stack = message;
288
+ } else {
289
+ var _uiSchemaTitle = utils.getUiOptions(get__default["default"](uiSchema, "" + property.replace(/^\./, ""))).title;
290
+ if (_uiSchemaTitle) {
291
+ stack = ("'" + _uiSchemaTitle + "' " + message).trim();
292
+ } else {
293
+ var _parentSchemaTitle = parentSchema === null || parentSchema === void 0 ? void 0 : parentSchema.title;
294
+ if (_parentSchemaTitle) {
295
+ stack = ("'" + _parentSchemaTitle + "' " + message).trim();
296
+ }
297
+ }
298
+ }
299
+ // put data in expected format
288
300
  return {
289
301
  name: keyword,
290
- property,
291
- message,
292
- params,
293
- stack: (property + " " + message).trim(),
294
- schemaPath
302
+ property: property,
303
+ message: message,
304
+ params: params,
305
+ stack: stack,
306
+ schemaPath: schemaPath
295
307
  };
296
308
  });
297
309
  }
310
+ /** Runs the pure validation of the `schema` and `formData` without any of the RJSF functionality. Provided for use
311
+ * by the playground. Returns the `errors` from the validation
312
+ *
313
+ * @param schema - The schema against which to validate the form data * @param schema
314
+ * @param formData - The form data to validate
315
+ */;
316
+ _proto.rawValidation = function rawValidation(schema, formData) {
317
+ var compilationError = undefined;
318
+ var compiledValidator;
319
+ if (schema["$id"]) {
320
+ compiledValidator = this.ajv.getSchema(schema["$id"]);
321
+ }
322
+ try {
323
+ if (compiledValidator === undefined) {
324
+ compiledValidator = this.ajv.compile(schema);
325
+ }
326
+ compiledValidator(formData);
327
+ } catch (err) {
328
+ compilationError = err;
329
+ }
330
+ var errors;
331
+ if (compiledValidator) {
332
+ if (typeof this.localizer === "function") {
333
+ this.localizer(compiledValidator.errors);
334
+ }
335
+ errors = compiledValidator.errors || undefined;
336
+ // Clear errors to prevent persistent errors, see #1104
337
+ compiledValidator.errors = null;
338
+ }
339
+ return {
340
+ errors: errors,
341
+ validationError: compilationError
342
+ };
343
+ }
298
344
  /** This function processes the `formData` with an optional user contributed `customValidate` function, which receives
299
345
  * the form data and a `errorHandler` function that will be used to add custom validation errors for each field. Also
300
346
  * supports a `transformErrors` function that will take the raw AJV validation errors, prior to custom validation and
@@ -304,64 +350,41 @@ class AJV8Validator {
304
350
  * @param schema - The schema against which to validate the form data
305
351
  * @param [customValidate] - An optional function that is used to perform custom validation
306
352
  * @param [transformErrors] - An optional function that is used to transform errors after AJV validation
307
- */
308
-
309
-
310
- validateFormData(formData, schema, customValidate, transformErrors) {
311
- // Include form data with undefined values, which is required for validation.
312
- const rootSchema = schema;
313
- const newFormData = utils.getDefaultFormState(this, schema, formData, rootSchema, true);
314
- let validationError = null;
315
-
316
- try {
317
- this.ajv.validate(schema, newFormData);
318
- } catch (err) {
319
- validationError = err;
353
+ * @param [uiSchema] - An optional uiSchema that is passed to `transformErrors` and `customValidate`
354
+ */;
355
+ _proto.validateFormData = function validateFormData(formData, schema, customValidate, transformErrors, uiSchema) {
356
+ var rawErrors = this.rawValidation(schema, formData);
357
+ var invalidSchemaError = rawErrors.validationError;
358
+ var errors = this.transformRJSFValidationErrors(rawErrors.errors, uiSchema);
359
+ if (invalidSchemaError) {
360
+ errors = [].concat(errors, [{
361
+ stack: invalidSchemaError.message
362
+ }]);
320
363
  }
321
-
322
- if (typeof this.localizer === "function") {
323
- this.localizer(this.ajv.errors);
324
- }
325
-
326
- let errors = this.transformRJSFValidationErrors(this.ajv.errors); // Clear errors to prevent persistent errors, see #1104
327
-
328
- this.ajv.errors = null;
329
- const noProperMetaSchema = validationError && validationError.message && typeof validationError.message === "string" && validationError.message.includes("no schema with key or ref ");
330
-
331
- if (noProperMetaSchema) {
332
- errors = [...errors, {
333
- stack: validationError.message
334
- }];
335
- }
336
-
337
364
  if (typeof transformErrors === "function") {
338
- errors = transformErrors(errors);
365
+ errors = transformErrors(errors, uiSchema);
339
366
  }
340
-
341
- let errorSchema = this.toErrorSchema(errors);
342
-
343
- if (noProperMetaSchema) {
344
- errorSchema = { ...errorSchema,
345
- ...{
346
- $schema: {
347
- __errors: [validationError.message]
348
- }
367
+ var errorSchema = this.toErrorSchema(errors);
368
+ if (invalidSchemaError) {
369
+ errorSchema = _extends({}, errorSchema, {
370
+ $schema: {
371
+ __errors: [invalidSchemaError.message]
349
372
  }
350
- };
373
+ });
351
374
  }
352
-
353
375
  if (typeof customValidate !== "function") {
354
376
  return {
355
- errors,
356
- errorSchema
377
+ errors: errors,
378
+ errorSchema: errorSchema
357
379
  };
358
380
  }
359
-
360
- const errorHandler = customValidate(newFormData, this.createErrorHandler(newFormData));
361
- const userErrorSchema = this.unwrapErrorHandler(errorHandler);
381
+ // Include form data with undefined values, which is required for custom validation.
382
+ var newFormData = utils.getDefaultFormState(this, schema, formData, schema, true);
383
+ var errorHandler = customValidate(newFormData, this.createErrorHandler(newFormData), uiSchema);
384
+ var userErrorSchema = this.unwrapErrorHandler(errorHandler);
362
385
  return utils.mergeValidationData(this, {
363
- errors,
364
- errorSchema
386
+ errors: errors,
387
+ errorSchema: errorSchema
365
388
  }, userErrorSchema);
366
389
  }
367
390
  /** Takes a `node` object and transforms any contained `$ref` node variables with a prefix, recursively calling
@@ -369,61 +392,67 @@ class AJV8Validator {
369
392
  *
370
393
  * @param node - The object node to which a ROOT_SCHEMA_PREFIX is added when a REF_KEY is part of it
371
394
  * @private
372
- */
373
-
374
-
375
- withIdRefPrefixObject(node) {
376
- for (const key in node) {
377
- const realObj = node;
378
- const value = realObj[key];
379
-
395
+ */;
396
+ _proto.withIdRefPrefixObject = function withIdRefPrefixObject(node) {
397
+ for (var key in node) {
398
+ var realObj = node;
399
+ var value = realObj[key];
380
400
  if (key === utils.REF_KEY && typeof value === "string" && value.startsWith("#")) {
381
401
  realObj[key] = ROOT_SCHEMA_PREFIX + value;
382
402
  } else {
383
403
  realObj[key] = this.withIdRefPrefix(value);
384
404
  }
385
405
  }
386
-
387
406
  return node;
388
407
  }
389
408
  /** Takes a `node` object list and transforms any contained `$ref` node variables with a prefix, recursively calling
390
409
  * `withIdRefPrefix` for any other elements.
391
410
  *
392
- * @param nodeThe - list of object nodes to which a ROOT_SCHEMA_PREFIX is added when a REF_KEY is part of it
411
+ * @param node - The list of object nodes to which a ROOT_SCHEMA_PREFIX is added when a REF_KEY is part of it
393
412
  * @private
394
- */
395
-
396
-
397
- withIdRefPrefixArray(node) {
398
- for (let i = 0; i < node.length; i++) {
413
+ */;
414
+ _proto.withIdRefPrefixArray = function withIdRefPrefixArray(node) {
415
+ for (var i = 0; i < node.length; i++) {
399
416
  node[i] = this.withIdRefPrefix(node[i]);
400
417
  }
401
-
402
418
  return node;
403
419
  }
404
420
  /** Validates data against a schema, returning true if the data is valid, or
405
421
  * false otherwise. If the schema is invalid, then this function will return
406
422
  * false.
407
423
  *
408
- * @param schema - The schema against which to validate the form data * @param schema
409
- * @param formData- - The form data to validate
424
+ * @param schema - The schema against which to validate the form data
425
+ * @param formData - The form data to validate
410
426
  * @param rootSchema - The root schema used to provide $ref resolutions
411
- */
412
-
413
-
414
- isValid(schema, formData, rootSchema) {
427
+ */;
428
+ _proto.isValid = function isValid(schema, formData, rootSchema) {
429
+ var _rootSchema$$id;
430
+ var rootSchemaId = (_rootSchema$$id = rootSchema["$id"]) != null ? _rootSchema$$id : ROOT_SCHEMA_PREFIX;
415
431
  try {
416
432
  // add the rootSchema ROOT_SCHEMA_PREFIX as id.
417
433
  // then rewrite the schema ref's to point to the rootSchema
418
434
  // this accounts for the case where schema have references to models
419
435
  // that lives in the rootSchema but not in the schema in question.
420
- const result = this.ajv.addSchema(rootSchema, ROOT_SCHEMA_PREFIX).validate(this.withIdRefPrefix(schema), formData);
436
+ if (this.ajv.getSchema(rootSchemaId) === undefined) {
437
+ this.ajv.addSchema(rootSchema, rootSchemaId);
438
+ }
439
+ var schemaWithIdRefPrefix = this.withIdRefPrefix(schema);
440
+ var compiledValidator;
441
+ if (schemaWithIdRefPrefix["$id"]) {
442
+ compiledValidator = this.ajv.getSchema(schemaWithIdRefPrefix["$id"]);
443
+ }
444
+ if (compiledValidator === undefined) {
445
+ compiledValidator = this.ajv.compile(schemaWithIdRefPrefix);
446
+ }
447
+ var result = compiledValidator(formData);
421
448
  return result;
422
449
  } catch (e) {
450
+ console.warn("Error encountered compiling schema:", e);
423
451
  return false;
424
452
  } finally {
453
+ // TODO: A function should be called if the root schema changes so we don't have to remove and recompile the schema every run.
425
454
  // make sure we remove the rootSchema from the global ajv instance
426
- this.ajv.removeSchema(ROOT_SCHEMA_PREFIX);
455
+ this.ajv.removeSchema(rootSchemaId);
427
456
  }
428
457
  }
429
458
  /** Recursively prefixes all $ref's in a schema with `ROOT_SCHEMA_PREFIX`
@@ -431,23 +460,18 @@ class AJV8Validator {
431
460
  *
432
461
  * @param schemaNode - The object node to which a ROOT_SCHEMA_PREFIX is added when a REF_KEY is part of it
433
462
  * @protected
434
- */
435
-
436
-
437
- withIdRefPrefix(schemaNode) {
438
- if (schemaNode.constructor === Object) {
439
- return this.withIdRefPrefixObject({ ...schemaNode
440
- });
441
- }
442
-
463
+ */;
464
+ _proto.withIdRefPrefix = function withIdRefPrefix(schemaNode) {
443
465
  if (Array.isArray(schemaNode)) {
444
- return this.withIdRefPrefixArray([...schemaNode]);
466
+ return this.withIdRefPrefixArray([].concat(schemaNode));
467
+ }
468
+ if (isObject__default["default"](schemaNode)) {
469
+ return this.withIdRefPrefixObject(clone__default["default"](schemaNode));
445
470
  }
446
-
447
471
  return schemaNode;
448
- }
449
-
450
- }
472
+ };
473
+ return AJV8Validator;
474
+ }();
451
475
 
452
476
  /** Creates and returns a customized implementation of the `ValidatorType` with the given customization `options` if
453
477
  * provided.
@@ -455,12 +479,10 @@ class AJV8Validator {
455
479
  * @param [options={}] - The `CustomValidatorOptionsType` options that are used to create the `ValidatorType` instance
456
480
  * @param [localizer] - If provided, is used to localize a list of Ajv `ErrorObject`s
457
481
  */
458
-
459
482
  function customizeValidator(options, localizer) {
460
483
  if (options === void 0) {
461
484
  options = {};
462
485
  }
463
-
464
486
  return new AJV8Validator(options, localizer);
465
487
  }
466
488