@sjsf/ajv8-validator
Version:
The ajv-8 based validator for svelte-jsonschema-form
96 lines (95 loc) • 3.36 kB
JavaScript
import { createChildId, createPseudoId, getRootUiSchemaTitleByPath, pathToId, } from "@sjsf/form";
import { Ajv, } from "ajv";
function errorObjectToMessage({ params: { missingProperty }, parentSchema, message }, getPropertyTitle) {
if (!message) {
return "";
}
if (missingProperty === undefined) {
return message;
}
const propertyTitle = getPropertyTitle(missingProperty, parentSchema);
if (propertyTitle === undefined) {
return message;
}
return message.replace(missingProperty, propertyTitle);
}
export function createFormErrorsTransformer(options) {
const instancePathToId = ({ params: { missingProperty, propertyName: propertyNameParam }, propertyName = propertyNameParam, }, path) => {
let id = pathToId(path, options);
id =
missingProperty !== undefined
? createChildId(id, missingProperty, options)
: id;
id =
propertyName !== undefined
? createPseudoId(createChildId(id, propertyName, options), "key-input", options)
: id;
return id;
};
return (errors) => {
return errors.map((error) => {
let path = error.instancePath.split("/");
if (path[0] === "") {
path = path.slice(1);
}
return {
instanceId: instancePathToId(error, path),
propertyTitle: getRootUiSchemaTitleByPath(options.uiSchema ?? {}, path) ??
error.parentSchema?.title ??
path.join("."),
message: errorObjectToMessage(error, (missingProperty, parentSchema) => {
const uiSchemaTitle = getRootUiSchemaTitleByPath(options.uiSchema ?? {}, path.concat(missingProperty));
if (uiSchemaTitle !== undefined) {
return uiSchemaTitle;
}
const prop = parentSchema?.properties?.[missingProperty];
if (typeof prop === "object") {
return prop.title;
}
return undefined;
}),
error,
};
});
};
}
function isRootFieldError(error) {
return error.instancePath === "";
}
function isRootAndNonTypeError(error) {
return isRootFieldError(error) && error.keyword !== "type";
}
export function createFieldErrorsTransformer(config) {
return (errors) => errors
.filter(config.required ? isRootFieldError : isRootAndNonTypeError)
.map((error) => ({
instanceId: config.id,
propertyTitle: config.title,
message: errorObjectToMessage(error, () => config.title),
error,
}));
}
export function validateAndTransformErrors(validate, data, transformErrors) {
validate(data);
const errors = validate.errors;
validate.errors = null;
if (!errors) {
return [];
}
return transformErrors(errors);
}
export async function validateAndTransformErrorsAsync(validate, data, transformErrors) {
try {
await validate(data);
}
catch (e) {
if (!(e instanceof Ajv.ValidationError)) {
throw e;
}
return transformErrors(e.errors);
}
finally {
validate.errors = null;
}
return [];
}