Skip to content
Playground Form Builder

ata-validator

Form validator implementation based on ata-validator JSON schema validator.

Terminal window
npm i @sjsf-lab/ata-validator ata-validator
<script lang="ts">
import {
ON_INPUT,
BasicForm,
createForm,
ON_CHANGE,
ON_ARRAY_CHANGE,
getValueSnapshot,
} from "@sjsf/form";
import { createFormValidator } from "@sjsf-lab/ata-validator";
import * as defaults from "@/lib/form/defaults";
import { initialValue, schema, uiSchema } from "../shared";
const form = createForm({
...defaults,
schema,
uiSchema,
validator: createFormValidator,
fieldsValidationMode: ON_INPUT | ON_CHANGE | ON_ARRAY_CHANGE,
initialValue,
});
</script>
<BasicForm {form} novalidate />
<pre>{JSON.stringify(getValueSnapshot(form), null, 2)}</pre>

It is possible to use precompiled validator to avoid issues with unsafe-eval warnings from the browser caused by strict Content Security Policy settings.

The first step in the process is to compile a schema into a set of validate functions.

import fs from "node:fs";
import path from "node:path";
import { ON_ARRAY_CHANGE, ON_CHANGE, ON_INPUT } from "@sjsf/form";
import {
insertSubSchemaIds,
fragmentSchema,
} from "@sjsf/form/validators/precompile";
import { Validator } from "ata-validator";
import {
DEFAULT_VALIDATOR_OPTIONS,
COLOR_FORMAT_REGEX,
DATA_URL_FORMAT_REGEX,
} from "@sjsf-lab/ata-validator";
import inputSchema from "../../shared/input-schema.json" with { type: "json" };
const fieldsValidationMode = ON_INPUT | ON_CHANGE | ON_ARRAY_CHANGE;
// NOTE: After calling this function, be sure to save the `schema` and
// use it to generate the form
const patch = insertSubSchemaIds(inputSchema as any, {
fieldsValidationMode,
});
// It is easier to save as a TS file
// https://github.com/microsoft/TypeScript/issues/32063
fs.writeFileSync(
path.join(import.meta.dirname, "patched-schema.ts"),
`import type { Schema } from "@sjsf/form";
export const fieldsValidationMode = ${fieldsValidationMode}
export const schema = ${JSON.stringify(patch.schema, null, 2)} as const satisfies Schema;`
);
const base = { $schema: "http://json-schema.org/draft-07/schema" };
const schemas = fragmentSchema(patch);
const bundle = Validator.bundleStandalone(
schemas.map((s) => Object.assign(s, base)),
{ ...DEFAULT_VALIDATOR_OPTIONS, format: "esm" }
)
.replace(
"const validators",
`export const [${schemas.map((s) => s.$id).join(", ")}]`
)
.slice(0, -50);
fs.writeFileSync(
path.join(import.meta.dirname, "validate-functions.js"),
`const COLOR_FORMAT_REGEX = ${COLOR_FORMAT_REGEX.toString()};
const DATA_URL_FORMAT_REGEX = ${DATA_URL_FORMAT_REGEX.toString()};
${bundle}`
);
Terminal window
node compile-schema-script.ts
<script lang="ts">
import { BasicForm, createForm, getValueSnapshot } from "@sjsf/form";
import { createFormValidatorFactory } from "@sjsf-lab/ata-validator/precompile";
import { resolver } from "@sjsf/form/resolvers/compat";
import * as defaults from "@/lib/form/defaults";
import { schema, fieldsValidationMode } from "./patched-schema";
import * as validateFunctions from "./validate-functions";
const form = createForm({
...defaults,
schema,
validator: createFormValidatorFactory({ validateFunctions }),
fieldsValidationMode,
resolver,
});
</script>
<BasicForm {form} novalidate />
<pre>{JSON.stringify(getValueSnapshot(form), null, 2)}</pre>