@sjsf/ajv8-validator
Version:
The ajv-8 based validator for svelte-jsonschema-form
96 lines (95 loc) • 3.62 kB
JavaScript
import { encodePseudoElement, getRootUiSchemaTitleByPath, } from "@sjsf/form";
import { PROPERTIES_KEY, pathFromLocation } from "@sjsf/form/core";
import { getValueByPath } from "@sjsf/form/lib/object";
import { Ajv, } from "ajv";
function createInstancePath({ params: { missingProperty, propertyName: propertyNameParam }, propertyName = propertyNameParam, }, path) {
let id = path;
id = missingProperty !== undefined ? path.concat(missingProperty) : id;
id =
propertyName !== undefined
? path.concat(propertyName, encodePseudoElement("key-input"))
: id;
return id;
}
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({ uiSchema = {}, schema = {}, }) {
return (errors, data) => {
return {
value: data,
errors: errors.map((error) => {
const path = pathFromLocation(error.instancePath, data);
return {
path: createInstancePath(error, path),
message: errorObjectToMessage(error, (missingProperty, parentSchema) => {
const uiSchemaTitle = getRootUiSchemaTitleByPath(uiSchema, path.concat(missingProperty));
if (uiSchemaTitle !== undefined) {
return uiSchemaTitle;
}
const prop = parentSchema?.properties?.[missingProperty];
if (typeof prop === "object") {
return prop.title;
}
const schemaPath = [];
for (const part of path) {
schemaPath.push(PROPERTIES_KEY, part);
}
schemaPath.push(PROPERTIES_KEY, missingProperty, "title");
return getValueByPath(schema, schemaPath);
}),
};
}),
};
};
}
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) => errorObjectToMessage(error, () => config.title));
}
export function validateAndTransformErrors(validate, data, transformData, transformErrors) {
validate(data);
const errors = validate.errors;
validate.errors = null;
if (!errors) {
return transformData(data);
}
return transformErrors(errors, data);
}
export async function validateAndTransformErrorsAsync(validate, data, transformInput, transformErrors) {
try {
await validate(data);
}
catch (e) {
if (!(e instanceof Ajv.ValidationError)) {
throw e;
}
return transformErrors(e.errors, data);
}
finally {
validate.errors = null;
}
return transformInput(data);
}
export function withLocalize(transform, localize) {
return localize
? (errors, data) => transform(localize(errors, data), data)
: transform;
}