Skip to content

Commit

Permalink
Added ajvOptionsOverrides to support user-provided AJV options overri…
Browse files Browse the repository at this point in the history
…ding

- Updated `CustomValidatorOptionsType` to add `ajvOptionsOverrides`
- Updated the `createAjvInstance()` function to spread any `ajvOptionsOverrides` on top of the `AJV_CONFIG`
- Updated `AJV6Validator` constructor to pass `ajvOptionsOverrides` to `createAjvInstance()`
- Updated tests to add test-case for the `$data` flag mentioned in #1668
  • Loading branch information
heath-freenome committed Jul 15, 2022
1 parent b09d6d9 commit 6e2f0ed
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 6 deletions.
8 changes: 6 additions & 2 deletions packages/validator-ajv6/src/createAjvInstance.ts
Expand Up @@ -15,16 +15,20 @@ export const DATA_URL_FORMAT_REGEX = /^data:([a-z]+\/[a-z0-9-+.]+)?;(?:name=(.*)

/** Creates an Ajv version 6 implementation object with standard support for the 'color` and `data-url` custom formats.
* If `additionalMetaSchemas` are provided then the Ajv instance is modified to add each of the meta schemas in the
* list. If `customFormats` are provided then those additional formats are added to the list of supported formats.
* list. If `customFormats` are provided then those additional formats are added to the list of supported formats. If
* `ajvOptionsOverrides` are provided then they are spread on top of the default `AJV_CONFIG` options when constructing
* the `Ajv` instance.
*
* @param [additionalMetaSchemas] - The list of additional meta schemas that the validator can access
* @param [customFormats] - The set of additional custom formats that the validator will support
* @param [ajvOptionsOverrides={}] - The set of validator config override options
*/
export default function createAjvInstance(
additionalMetaSchemas?: CustomValidatorOptionsType['additionalMetaSchemas'],
customFormats?: CustomValidatorOptionsType['customFormats'],
ajvOptionsOverrides: CustomValidatorOptionsType['ajvOptionsOverrides'] = {},
) {
const ajv = new Ajv(AJV_CONFIG);
const ajv = new Ajv({ ...AJV_CONFIG, ...ajvOptionsOverrides });

// add custom formats
ajv.addFormat('data-url', DATA_URL_FORMAT_REGEX);
Expand Down
4 changes: 4 additions & 0 deletions packages/validator-ajv6/src/types.ts
@@ -1,8 +1,12 @@
import { Options } from 'ajv';

/** The type describing how to customize the AJV6 validator
*/
export interface CustomValidatorOptionsType {
/** The list of additional meta schemas that the validator can access */
additionalMetaSchemas?: ReadonlyArray<object>;
/** The set of additional custom formats that the validator will support */
customFormats?: { [k: string]: string | RegExp | ((data: string) => boolean) };
/** The set of config overrides that will be passed to the AJV validator constructor on top of the defaults */
ajvOptionsOverrides?: Options;
}
4 changes: 2 additions & 2 deletions packages/validator-ajv6/src/validator.ts
Expand Up @@ -37,8 +37,8 @@ export default class AJV6Validator<T = any> implements ValidatorType<T> {
* @param options - The `CustomValidatorOptionsType` options that are used to create the AJV instance
*/
constructor (options: CustomValidatorOptionsType) {
const { additionalMetaSchemas, customFormats } = options;
this.ajv = createAjvInstance(additionalMetaSchemas, customFormats);
const { additionalMetaSchemas, customFormats, ajvOptionsOverrides } = options;
this.ajv = createAjvInstance(additionalMetaSchemas, customFormats, ajvOptionsOverrides);
}

/** Transforms a ajv validation errors list:
Expand Down
12 changes: 10 additions & 2 deletions packages/validator-ajv6/test/createAjvInstance.test.ts
Expand Up @@ -12,6 +12,10 @@ export const CUSTOM_OPTIONS: CustomValidatorOptionsType = {
customFormats: {
'phone-us': /\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{4}$/,
'area-code': /\d{3}/,
},
ajvOptionsOverrides: {
$data: true,
verbose: true,
}
};

Expand Down Expand Up @@ -43,13 +47,17 @@ describe('createAjvInstance()', () => {
describe('no additional meta schemas or custom formats', () => {
let ajv: AjvType;
beforeAll(() => {
ajv = createAjvInstance(CUSTOM_OPTIONS.additionalMetaSchemas, CUSTOM_OPTIONS.customFormats);
ajv = createAjvInstance(
CUSTOM_OPTIONS.additionalMetaSchemas,
CUSTOM_OPTIONS.customFormats,
CUSTOM_OPTIONS.ajvOptionsOverrides
);
});
afterAll(() => {
(Ajv as unknown as jest.Mock).mockClear();
});
it('expect a new Ajv to be constructed with the AJV_CONFIG', () => {
expect(Ajv).toHaveBeenCalledWith(AJV_CONFIG);
expect(Ajv).toHaveBeenCalledWith({ ...AJV_CONFIG, ...CUSTOM_OPTIONS.ajvOptionsOverrides });
});
it('addFormat() was called twice', () => {
expect(ajv.addFormat).toHaveBeenCalledTimes(4);
Expand Down

0 comments on commit 6e2f0ed

Please sign in to comment.