@tsed/schema-formio
Version:
Transform Ts.ED Schema & JsonSchema to a valid Formio schema
89 lines (88 loc) • 3.06 kB
JavaScript
import { cleanObject, isFunction } from "@tsed/core";
import { sentenceCase } from "change-case";
import { execMapper, registerFormioMapper } from "../registries/FormioMappersContainer.js";
function bindResolvers(component, options) {
if (component.data) {
const data = { ...component.data };
Object.entries(data).forEach(([key, resolver]) => {
if (isFunction(resolver)) {
options.resolvers.push(async (form) => {
data[key] = await resolver({ ...options, component, form });
});
}
});
return {
...component,
data
};
}
return component;
}
function mapValidation(key, base, schema, propSchema) {
const required = (schema.required || []).includes(key);
const validate = {
...(base.validate || {}),
required,
pattern: propSchema.pattern,
minLength: !required || (required && propSchema.minLength > 1) ? propSchema.minLength : undefined,
maxLength: propSchema.maxLength,
min: propSchema.minimum || propSchema.minItems,
max: propSchema.maximum || propSchema.maxItems
};
switch (propSchema.type) {
case "string":
if (propSchema.minLength === 0 && validate.required) {
validate.minLength = undefined;
validate.required = false;
}
break;
case "boolean":
validate.required = false;
break;
}
return cleanObject(validate);
}
export function propertiesToComponents(schema, options) {
const tabs = {
label: "Tabs",
key: "tabs",
type: "tabs",
input: false,
tableView: false,
components: new Map(),
pushed: false
};
const components = [];
Object.entries(schema.properties).forEach(([key, propSchema]) => {
const tabsOptions = propSchema["x-formiotabs"];
const base = execMapper("any", propSchema, { ...options, parentKey: key });
let component = cleanObject({
key,
...base,
label: base.label == false ? undefined : base.label || propSchema.title || sentenceCase(key),
validate: mapValidation(key, base, schema, propSchema)
});
component = bindResolvers(component, options);
if (tabsOptions) {
if (!tabs.pushed) {
components.push(tabs);
tabs.pushed = true;
}
if (!tabs.components.has(tabsOptions.key)) {
tabs.components.set(tabsOptions.key, {
...tabsOptions,
components: []
});
}
tabs.components.get(tabsOptions.key).components.push(component);
}
else {
components.push(component);
}
});
if (tabs.components.size) {
tabs.components = [...tabs.components.values()];
}
return components;
}
registerFormioMapper("properties", propertiesToComponents);