UNPKG

@rjsf/validator-ajv6

Version:
208 lines (201 loc) 9 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { customizeValidator: () => customizeValidator, default: () => src_default }); module.exports = __toCommonJS(src_exports); // src/validator.ts var import_utils = require("@rjsf/utils"); // src/createAjvInstance.ts var import_ajv = __toESM(require("ajv")); var import_isObject = __toESM(require("lodash/isObject")); var AJV_CONFIG = { errorDataPath: "property", allErrors: true, multipleOfPrecision: 8, schemaId: "auto", unknownFormats: "ignore" }; 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*\)))$/; var DATA_URL_FORMAT_REGEX = /^data:([a-z]+\/[a-z0-9-+.]+)?;(?:name=(.*);)?base64,(.*)$/; function createAjvInstance(additionalMetaSchemas, customFormats, ajvOptionsOverrides = {}) { const ajv = new import_ajv.default({ ...AJV_CONFIG, ...ajvOptionsOverrides }); ajv.addFormat("data-url", DATA_URL_FORMAT_REGEX); ajv.addFormat("color", COLOR_FORMAT_REGEX); if (Array.isArray(additionalMetaSchemas)) { ajv.addMetaSchema(additionalMetaSchemas); } if ((0, import_isObject.default)(customFormats)) { Object.keys(customFormats).forEach((formatName) => { ajv.addFormat(formatName, customFormats[formatName]); }); } return ajv; } // src/validator.ts var AJV6Validator = class { /** Constructs an `AJV6Validator` instance using the `options` * * @param options - The `CustomValidatorOptionsType` options that are used to create the AJV instance */ constructor(options) { const { additionalMetaSchemas, customFormats, ajvOptionsOverrides } = options; this.ajv = createAjvInstance(additionalMetaSchemas, customFormats, ajvOptionsOverrides); } /** Converts an `errorSchema` into a list of `RJSFValidationErrors` * * @param errorSchema - The `ErrorSchema` instance to convert * @param [fieldPath=[]] - The current field path, defaults to [] if not specified * @deprecated - Use the `toErrorList()` function provided by `@rjsf/utils` instead. This function will be removed in * the next major release. */ toErrorList(errorSchema, fieldPath = []) { return (0, import_utils.toErrorList)(errorSchema, fieldPath); } /** Transforming the error output from ajv to format used by @rjsf/utils. * At some point, components should be updated to support ajv. * * @param errors - The list of AJV errors to convert to `RJSFValidationErrors` * @private */ transformRJSFValidationErrors(errors = []) { return errors.map((e) => { const { dataPath, keyword, message, params, schemaPath } = e; const property = `${dataPath}`; return { name: keyword, property, message, params, // specific to ajv stack: `${property} ${message}`.trim(), schemaPath }; }); } /** Runs the pure validation of the `schema` and `formData` without any of the RJSF functionality. Provided for use * by the playground. Returns the `errors` from the validation * * @param schema - The schema against which to validate the form data * @param schema * @param formData - The form data to validate */ rawValidation(schema, formData) { let validationError = void 0; try { this.ajv.validate(schema, formData); } catch (err) { validationError = err; } const errors = this.ajv.errors || void 0; this.ajv.errors = null; return { errors, validationError }; } /** This function processes the `formData` with an optional user contributed `customValidate` function, which receives * the form data and a `errorHandler` function that will be used to add custom validation errors for each field. Also * supports a `transformErrors` function that will take the raw AJV validation errors, prior to custom validation and * transform them in what ever way it chooses. * * @param formData - The form data to validate * @param schema - The schema against which to validate the form data * @param [customValidate] - An optional function that is used to perform custom validation * @param [transformErrors] - An optional function that is used to transform errors after AJV validation * @param [uiSchema] - An optional uiSchema that is passed to `transformErrors` and `customValidate` */ validateFormData(formData, schema, customValidate, transformErrors, uiSchema) { const rootSchema = schema; const rawErrors = this.rawValidation(schema, formData); const { validationError } = rawErrors; let errors = this.transformRJSFValidationErrors(rawErrors.errors); const noProperMetaSchema = validationError && validationError.message && validationError.message.includes("no schema with key or ref "); if (noProperMetaSchema) { errors = [...errors, { stack: validationError.message }]; } if (typeof transformErrors === "function") { errors = transformErrors(errors, uiSchema); } let errorSchema = (0, import_utils.toErrorSchema)(errors); if (noProperMetaSchema) { errorSchema = { ...errorSchema, ...{ $schema: { __errors: [validationError.message] } } }; } if (typeof customValidate !== "function") { return { errors, errorSchema }; } const newFormData = (0, import_utils.getDefaultFormState)(this, schema, formData, rootSchema, true); const errorHandler = customValidate(newFormData, (0, import_utils.createErrorHandler)(newFormData), uiSchema); const userErrorSchema = (0, import_utils.unwrapErrorHandler)(errorHandler); return (0, import_utils.validationDataMerge)({ errors, errorSchema }, userErrorSchema); } /** * 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. * @param rootSchema - The root schema used to provide $ref resolutions */ handleSchemaUpdate(rootSchema) { const rootSchemaId = import_utils.ROOT_SCHEMA_PREFIX; if (this.ajv.getSchema(import_utils.ROOT_SCHEMA_PREFIX) === void 0) { this.ajv.addSchema(rootSchema, import_utils.ROOT_SCHEMA_PREFIX); } else if (!(0, import_utils.deepEquals)(rootSchema, this.ajv.getSchema(import_utils.ROOT_SCHEMA_PREFIX)?.schema)) { this.ajv.removeSchema(rootSchemaId); this.ajv.addSchema(rootSchema, rootSchemaId); } } /** Validates data against a schema, returning true if the data is valid, or * false otherwise. If the schema is invalid, then this function will return * false. * * @param schema - The schema against which to validate the form data * @param schema * @param formData- - The form data to validate * @param rootSchema - The root schema used to provide $ref resolutions */ isValid(schema, formData, rootSchema) { try { this.handleSchemaUpdate(rootSchema); const result = this.ajv.validate((0, import_utils.withIdRefPrefix)(schema), formData); return result; } catch (e) { return false; } } }; // src/customizeValidator.ts function customizeValidator(options = {}) { return new AJV6Validator(options); } // src/index.ts var src_default = customizeValidator(); //# sourceMappingURL=index.js.map