-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Implement precompiled validator support in @rjsf/validator-ajv8 (#…
…3652) * fix: Implement precompiled validator support in @rjsf/validator-ajv8 Fixes #3543 by implementing support for precompiled validators - In `@rjsf/validator-ajv8` added support for precompiled validators as follows: - Added a new `compileSchemaValidators()` API function used to generate the precompiled validators for a schema to an output file - Updated the documentation for the `customizeValidator()` API function - Added a new `AJV8PrecompiledValidator` implementation of the `ValidatorType` interface - Refactored a large piece of the raw validation error processing from the `AJV8Validator` into a new `processRawValidationErrors()` function also used by the `AJV8PrecompiledValidator` - Added a new `usePrecompiledValidator()` API function that is similar to `customizeValidator()` but returning a precompiled validator-based `ValidatorType` interface implementation - Added some new types to the `types.ts` file in support of precompiled validators - Updated the main `index.ts` file to export the new types and API functions - Added 100% unit test coverage of the new feature - This included implementing a node function to precompile the `superSchema.json` file found in the `test/harness` directory - Added `ignorePatterns` to the `.eslintrc` file to ignore the precompiled schema files - Updated the `validation.md` documentation for the new precompiled validator functionality - Added a new `validator-ajv8.md` documentation file to the `api-reference` directory and the `sidebar.js` - Updated the `CHANGELOG.md` file accordingly * - Responded to self-review feedback * - Replaced usage of `<` with `<` to match the similar line later in the file * - Fixed the peerDependencies in the `fluent-ui` package-lock.json and improved the `CHANGELOG.md` comments related to #3546 * - Responded to reviewer feedback
- Loading branch information
1 parent
c527317
commit 91bcc94
Showing
28 changed files
with
1,283 additions
and
175 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# @rjsf/validator-ajv8 APIs | ||
|
||
In RJSF version 5, the original, embedded AJV 6 validator implementation from earlier versions was extracted into its own package, `@rjsf/validator-ajv6`, which was immediately deprecated since AJV 6 is no longer getting maintenance updates. | ||
A new `@rjsf/validator-ajv8` package was added that uses the AJV 8 package, including adding support for using precompiled validators. | ||
Below are the exported API functions that are provided by this package. | ||
See the [Validation documentation](../usage/validation.md) for examples of using these APIs. | ||
|
||
## Types | ||
|
||
There are a few Typescript types that are exported by `@rjsf/validator-ajv8` in support of the APIs. | ||
|
||
These types can be found on GitHub [here](https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/validator-ajv8/src/types.ts). | ||
|
||
## APIs | ||
|
||
### customizeValidator<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>() | ||
|
||
Creates and returns a customized implementation of the `ValidatorType` with the given customization `options` if provided. | ||
If a `localizer` is provided, it is used to translate the messages generated by the underlying AJV validation. | ||
|
||
#### Parameters | ||
|
||
- [options={}]: CustomValidatorOptionsType - The optional map of `CustomValidatorOptionsType` options that are used to create the `ValidatorType` instance | ||
- [localizer]: Localizer | undefined - If provided, is used to localize a list of Ajv `ErrorObject`s after running the form validation using AJV | ||
|
||
#### Returns | ||
|
||
- ValidatorType<T, S, F>: The custom validator implementation resulting from the set of parameters provided | ||
|
||
### compileSchemaValidators<S extends StrictRJSFSchema = RJSFSchema>() | ||
|
||
The function used to compile a schema into an output file in the form that allows it to be used as a precompiled validator. | ||
The main reasons for using a precompiled validator is reducing code size, improving validation speed and, most importantly, avoiding dynamic code compilation when prohibited by a browser's Content Security Policy. | ||
For more information about AJV code compilation see: https://ajv.js.org/standalone.html | ||
|
||
#### Parameters | ||
|
||
- schema: S - The schema to be compiled into a set of precompiled validators functions | ||
- output: string - The name of the file into which the precompiled validator functions will be generated | ||
- [options={}]: CustomValidatorOptionsType - The set of `CustomValidatorOptionsType` information used to alter the AJV validator used for compiling the schema. They are the same options that are passed to the `customizeValidator()` function in order to modify the behavior of the regular AJV-based validator. | ||
|
||
### createPrecompiledValidator<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>() | ||
|
||
Creates and returns a `ValidatorType` interface that is implemented with a precompiled validator. | ||
If a `localizer` is provided, it is used to translate the messages generated by the underlying AJV validation. | ||
|
||
> NOTE: The `validateFns` parameter is an object obtained by importing from a precompiled validation file created via the `compileSchemaValidators()` function. | ||
#### Parameters | ||
|
||
- validateFns: ValidatorFunctions<T> - The map of the validation functions that are created by the `compileSchemaValidators()` function | ||
- rootSchema: S - The root schema that was used with the `compileSchemaValidators()` function | ||
- [localizer]: Localizer | undefined - If provided, is used to localize a list of Ajv `ErrorObject`s after running the form validation using AJV | ||
|
||
#### Returns | ||
|
||
- ValidatorType<T, S, F>: The precompiled validator implementation resulting from the set of parameters provided |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Ignore the generated test schema files | ||
test/harness/superSchema*.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import fs from 'fs'; | ||
import standaloneCode from 'ajv/dist/standalone'; | ||
import { RJSFSchema, StrictRJSFSchema, schemaParser } from '@rjsf/utils'; | ||
|
||
import createAjvInstance from './createAjvInstance'; | ||
import { CustomValidatorOptionsType } from './types'; | ||
|
||
/** The function used to compile a schema into an output file in the form that allows it to be used as a precompiled | ||
* validator. The main reasons for using a precompiled validator is reducing code size, improving validation speed and, | ||
* most importantly, avoiding dynamic code compilation when prohibited by a browser's Content Security Policy. For more | ||
* information about AJV code compilation see: https://ajv.js.org/standalone.html | ||
* | ||
* @param schema - The schema to be compiled into a set of precompiled validators functions | ||
* @param output - The name of the file into which the precompiled validator functions will be generated | ||
* @param [options={}] - The set of `CustomValidatorOptionsType` information used to alter the AJV validator used for | ||
* compiling the schema. They are the same options that are passed to the `customizeValidator()` function in | ||
* order to modify the behavior of the regular AJV-based validator. | ||
*/ | ||
export default function compileSchemaValidators<S extends StrictRJSFSchema = RJSFSchema>( | ||
schema: S, | ||
output: string, | ||
options: CustomValidatorOptionsType = {} | ||
) { | ||
console.log('parsing the schema'); | ||
const schemaMaps = schemaParser(schema); | ||
const schemas = Object.values(schemaMaps); | ||
|
||
const { additionalMetaSchemas, customFormats, ajvOptionsOverrides = {}, ajvFormatOptions, AjvClass } = options; | ||
// Allow users to turn off the `lines: true` feature in their own overrides, but NOT the `source: true` | ||
const compileOptions = { | ||
...ajvOptionsOverrides, | ||
code: { lines: true, ...ajvOptionsOverrides.code, source: true }, | ||
schemas, | ||
}; | ||
const ajv = createAjvInstance(additionalMetaSchemas, customFormats, compileOptions, ajvFormatOptions, AjvClass); | ||
|
||
const moduleCode = standaloneCode(ajv); | ||
console.log(`writing ${output}`); | ||
fs.writeFileSync(output, moduleCode); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { FormContextType, RJSFSchema, StrictRJSFSchema, ValidatorType } from '@rjsf/utils'; | ||
|
||
import { Localizer, ValidatorFunctions } from './types'; | ||
import AJV8PrecompiledValidator from './precompiledValidator'; | ||
|
||
/** Creates and returns a `ValidatorType` interface that is implemented with a precompiled validator. If a `localizer` | ||
* is provided, it is used to translate the messages generated by the underlying AJV validation. | ||
* | ||
* NOTE: The `validateFns` parameter is an object obtained by importing from a precompiled validation file created via | ||
* the `compileSchemaValidators()` function. | ||
* | ||
* @param validateFns - The map of the validation functions that are created by the `compileSchemaValidators()` function | ||
* @param rootSchema - The root schema that was used with the `compileSchemaValidators()` function | ||
* @param [localizer] - If provided, is used to localize a list of Ajv `ErrorObject`s | ||
* @returns - The precompiled validator implementation resulting from the set of parameters provided | ||
*/ | ||
export default function createPrecompiledValidator< | ||
T = any, | ||
S extends StrictRJSFSchema = RJSFSchema, | ||
F extends FormContextType = any | ||
>(validateFns: ValidatorFunctions<T>, rootSchema: S, localizer?: Localizer): ValidatorType<T, S, F> { | ||
return new AJV8PrecompiledValidator<T, S, F>(validateFns, rootSchema, localizer); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
import customizeValidator from './customizeValidator'; | ||
import compileSchemaValidators from './compileSchemaValidators'; | ||
import createPrecompiledValidator from './createPrecompiledValidator'; | ||
|
||
export { customizeValidator }; | ||
export { customizeValidator, compileSchemaValidators, createPrecompiledValidator }; | ||
export * from './types'; | ||
|
||
export default customizeValidator(); |
Oops, something went wrong.