@anotherdat/schema-validator
v0.2.0
Published
Validate a destination folder against a file-structure schema, with pluggable per-file validators (css, with more kinds to come)
Downloads
230
Readme
@anotherdat/schema-validator
Validate a whole destination folder against a file-structure schema, with pluggable per-file validators for the files inside it.
validate(folder, schema, options)— the main validator. Checks that a destination folder (e.g. a theme likegob) matches afile-structureschema: required/optional files, and per-file content validators.validators— the registry of per-file validators, keyed bykind, for validating a single file's content on its own.
| kind | validates |
| ---------------- | ---------------------------------------------------- |
| file-structure | a folder's tree (required/optional files + validators) |
| css | CSS custom-property declarations (flat or per-block) |
More per-file kinds (json, svg, ...) are planned.
Install
npm install @anotherdat/schema-validatorUsage
Validate a whole folder
const fs = require('fs');
const path = require('path');
const { validate } = require('@anotherdat/schema-validator');
// The schema can be an object, a JSON string, or a Buffer — pass whatever you
// have (a file you read, or a response you fetched).
const schema = fs.readFileSync('schema/schema.json');
// const schema = await fetch('https://host/schema.json').then((r) => r.text());
// Resolves on success; throws an Error listing every problem on failure.
await validate(path.join(__dirname, 'gob'), schema, { schemaDir: 'schema' });Validate a single file directly
const { validators } = require('@anotherdat/schema-validator');
// validators.<kind>.validate(content, schema, options)
validators.css.validate(cssSource, colorsSchema, { at: 'colors.css' });The file-structure schema
{
"kind": "file-structure",
"allowExtra": true,
"schema": {
"images/logo.svg": "required",
"images/hero.png": "optional",
"styles/colors.css": { "validator": "styles/colors.css.schema" },
"styles/custom.css": "required"
}
}Each entry maps a folder-relative path to a rule:
"required"— the file must exist."optional"— allowed, not mandatory.{ "required": false?, "validator": <ref> }— defaults to required; when the file is present,validatorruns against its contents. Set"required": falseto make it optional. (Folders aren't listed — they're implied by file paths.)
allowExtra (default true) — when false, any file in the folder not listed
in schema is also an error.
How validator references are resolved
A rule's validator is either an inline spec object or a string
reference. References are resolved, in order:
options.resolveValidator(ref)— an (async) function returning the spec (object or JSON string). Use this for fetched/remote schemas.options.schemaDir— readpath.join(schemaDir, ref)from disk.
// inline — no resolution needed
{ "styles/colors.css": { "validator": { "kind": "css", "blocks": [/* ... */] } } }
// reference resolved from disk
await validate(folder, schema, { schemaDir: 'schema' });
// reference resolved however you like (e.g. fetched)
await validate(folder, schema, {
resolveValidator: (ref) => fetch(`https://host/${ref}`).then((r) => r.text()),
});On failure validate throws a single Error listing every problem found
(missing files, per-file validator failures, unexpected files) — a whole-folder
report rather than fail-on-first.
options.at overrides the label that prefixes error messages (defaults to the
folder path).
CSS validator spec shapes
Block mode — the file must contain exactly these blocks, in order (same selectors), each declaring its required custom properties:
{
"kind": "css",
"blocks": [
{ "name": "palette", "selector": ":root", "requiredVariables": ["--c-primary"] },
{ "name": "theme", "selector": ".dark-mode", "requiredVariables": ["--c-bg"] }
],
"allowExtraVariables": false
}allowExtraVariables is optional; set it to false to reject variables not
listed in requiredVariables.
Flat mode — check required variables across the whole file, ignoring blocks:
{ "kind": "css", "requiredVariables": ["--c-primary", "--c-bg"] }Adding a per-file validator kind
- Create
validators/<kind>.jsexporting{ kind, validate(content, schema, options) }.validateparsesschema(object or JSON string) and throws anError(message prefixed withoptions.at) on the first problem. - Register it in the
validatorsmap inindex.js. - Reference it from a
file-structureschema via"validator", with a spec whose"kind"matches. - Add a
validators/<kind>.test.jsalongside it.
Development
npm install
npm test