-
-
Notifications
You must be signed in to change notification settings - Fork 875
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Register custom validator without modifying the input schema #2462
Labels
Comments
I've created a utility to work around this via keywords so I'll close the issue. For anyone interested... const avj = new AVJ({ allErrors: true });
addSchemaValidator(avj, {
schemaDefs: jsonSchemaDefinitions,
schemaPath: '#/definitions/Account/properties/firstName,
keyword: 'x-accountNameVerifier',
validate: ({ data: firstName, keyword, errors }) => {
if (!isValidName(firstName)) {
errors.push({
keyword,
message: 'must pass a valid firstName',
});
return false;
}
return true;
},
errors: true,
});
avj.compile(jsonSchemaDefinitions);
const validateAccount = avj.getSchema('#/definitions/Account');
if (!validateAccount({ firstName: "james" })) {
console.log(validateAccount.errors)
} import AVJ, { AnySchemaObject, FuncKeywordDefinition, SchemaValidateFunction, ErrorObject } from 'ajv';
import { DataValidationCxt } from 'ajv/dist/types';
export type ValidateParams = {
schema: any;
data: any;
parentSchema?: AnySchemaObject;
dataCxt?: DataValidationCxt;
errors: Partial<ErrorObject>[];
};
export type SchemaValidator = (params: ValidateParams) => boolean;
export type SchemaValidatorDefinition = {
schemaDefs: any;
schemaPath: string;
keyword: string;
validate: SchemaValidator;
} & Omit<FuncKeywordDefinition, 'keyword' | 'validate'>;
export function addSchemaValidator(avj: AVJ, validatorDef: SchemaValidatorDefinition): AVJ {
const { schemaDefs, schemaPath, validate, ...keywordDef } = validatorDef;
let path = schemaPath;
if (path.startsWith('#')) path = path.slice(1);
if (path.startsWith('/')) path = path.slice(1);
let defs = schemaDefs;
for (const segment of path.split('/')) {
defs = defs[segment];
}
const keyword = keywordDef.keyword;
defs[keyword] = true;
const validateWrapperRef: SchemaValidateFunction = validateWrapper;
function validateWrapper(schema: any, data: any, parentSchema?: AnySchemaObject, dataCxt?: DataValidationCxt) {
const errors: Partial<ErrorObject>[] = [];
const isValid = validate({
schema,
data,
parentSchema,
dataCxt,
keyword,
errors,
});
if (!isValid && errors.length) {
validateWrapperRef.errors = errors;
}
return isValid;
}
avj.addKeyword({ ...keywordDef, validate: validateWrapper });
return avj;
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I've done a little searching but couldn't spot this raised or covered anywhere.
What version of Ajv you are you using?
What problem do you want to solve?
I'd like to add a custom validator to an existing schema without modifying the definition which I don't control. This would augment any validation already present on that schema.
What do you think is the correct solution to problem?
Something similar to
avj.addKeyword(...)
but instead add a validator targeting a specific schema path that's been registered with theavj
instance.Will you be able to implement it?
No bandwidth currently
The text was updated successfully, but these errors were encountered: