ajv-build-tools
v1.0.0-next.8
Published
A tool to manage compiling json schemas with ajv to integrate with build tools like rollup and vite
Downloads
74
Maintainers
Readme
Ajv Build Tools
A universal build tools plugin to handle json schemas compilation with ajv. This will allow you to use highly optmized standalone validation code for your json schemas without any efforts:
- Define your json schemas in files(javascript or typescript)
- The builder will take care of loading and watching your source schemas
- Access your compiled schemas with the virtual import
$schemas
. See more
Features
- Server & client optmized builds.
- Warnings about insecure schemas.
- Different ajv options per schema*
- ajv-formats and ajv-errors added by default.
- Vite hmr support and auto ssr optmizations.
- Optmize the generated code by the bundlers.
- Extended with plugins.
Content
- Ajv Build Tools
Get Started
npm i ajv-build-tools
/ pnpm i ajv-build-tools
Prerequisite
This guide assumes you have familiarity with json schemas and ajv. See Resources
Vite
The plugin designed to work with vite and rollup first. This will inlcude features like hot reloading and ssr optmized builds.
import {unpluginAjvTools} from "ajv-build-tools";
export default defineConfig({
plugins: [
unpluginAjvTools.vite({
include: [
"./src/routes/*.{js,ts}",
"./src/**/schemas.{ts,js,\\.d.ts}"
]
})
]
})
Rollup and other bundlers
Other bundlers are supported as long it's supported by unplugin, but it's well tested and designed to work with vite and rollup.
Plugin Options
The plugin extends the schema builder interface
interface SchemaBuilderOptions {
root?: string;
baseDir?: string;
include: string | string[];
exclude?: string | string[];
ajvOptions?: {
all?: AjvOptions;
server?: AjvOptions;
client?: AjvOptions;
};
moduleLoader?: ModuleLoader;
useDirectImport?: boolean;
resolveModule?(module: Record<string, unknown>, file: string): Record<string, any>;
resolveSchema?(schema: any, file: string): any;
plugins?: Plugin[];
}
Basics
- root : The root directory where all files resolved from, it's either process.cwd() or vite's root.
- baseDir:
src
by default. - include/exlcude: list of glob patterns passed to
fast-glob
andmicromatch
Advanced
ajvOptions: Pass diferent ajv options based on the instance. use
all
to apply to all instances.resolveModule: module -> schema map. by default all exports are treated as individual schemas, but sometimes you want a custom resolution, for example:
async function resolveModule(module, file) { if (file.startsWith("routes/")) { /* Resolve from: export GET = {queries: {}} export POST = {body: {}} export actions = {default: {body}} to: export GET_queries = {} export POST_body = {} export actions_default_body = {} */ return resolveRoutesSchemas(module, file); } return module; },
resolveSchema: Similarly you could resolve each schema invidually, the result should be a valid json schema. This could be used to convert another schema formats to a json schema.
Module loader: Responsible for building and loading the source files for the schema. The default loader will bundle the files with esbuild and import them using a dynamic import. It's rare case to use a custom loader as the default loader will handle most cases including transpilling typescript. An example of custom loader that used by the vite plugin:
moduleLoader(context) { const { files, defaultModuleLoader } = context; // if vite dev server available use it to speed up dev speed if (vite_server) { return Object.fromEntries( files.map((file) => { return [file, vite_server.ssrLoadModule(file)]; }) ); } return defaultModuleLoader(context); },
useDirectImport: used by the default loader to decide if to use direct dynamic import or indirectly by using
new Function("p", "return import(p)")
. This to avoid transpiling dynamic imports to require by some tools.Plugins: The builder could be extended with plugins, refer to plugins.types for the available hooks. altho this feature is very WIP and the api subjects to change.
Importing the compiled schemas
By path relative to baseDir
import schemas from "$schemas/routes/api/login/schemas";
// schemas
{
GET_body: ...
}
- Queries:
- raw: import the resolved raw json schemas
- instance: server or client. This automatically set by vite depending on ssr property
- raw code: return compiled code as raw string
By reference or $id (similar to calling ajv.getSchema(id_or_key)
)
import validateUser from "$schemas:User"
// the default export is the compiled validate function
// it's the same function that return by ajv.compile
// use validateUser.errors to access the last validation errors
// note that's it's a global so refer to ajv docs for more information
- Queries:
- instance
- raw code
All schemas by file
import schemas from "$schemas?t=all";
- Queries:
- instance
- raw code
Types for the virtual imports
Use ajv-build-tools/types
to declare the virtaul modules.
Resources
(WIP) Using the core schema builder interface
You could refer to the unplugin source code or the tests to see how to use the core builder.