@gcornut/valibot-json-schema
v0.42.0
Published
> [!CAUTION] > This project is now deprecated as Valibot now has an official JSON schema converter in the [@valibot/to-json-schema](https://github.com/fabian-hiller/valibot/tree/main/packages/to-json-schema). > The command line interface is moved to the p
Downloads
162,216
Readme
[!CAUTION] This project is now deprecated as Valibot now has an official JSON schema converter in the @valibot/to-json-schema. The command line interface is moved to the project @gcornut/cli-valibot-to-json-schema.
@gcornut/valibot-json-schema
CLI and JS utility to convert Valibot schemas to JSON schema (draft 07).
Some of the features of Valibot can't be converted to JSON schema. JS-specific types like blob
or nan
obviously
can't have an equivalent.
See supported features for more info.
Command Line Tool
This lib exports a CLI that can be used to quickly convert JS modules defining valibot schemas into a JSON schema.
# Convert valibot schemas to JSON schema
npx @gcornut/valibot-json-schema to-json-schema ./schemas.js
This outputs a conversion of the Valibot schemas into JSON schema. If the default export is a Valibot schemas, it is used as the root definition. Other exported Valibot schemas are converted in the JSON schema definitions section.
Input file ./schemas.js
:
import * as v from 'valibot';
export const AString = v.string();
const AnObject = v.object({ aString: AString });
export default AnObject;
Output conversion:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AString": {
"type": "string"
}
},
"properties": {
"aString": {
"$ref": "#/definitions/AString"
}
},
"required": [
"aString"
],
"type": "object"
}
AnObject
is the default export in the source module, so it is converted as the root definition. AString
is exported
separately, so it is exported to the definitions
section.
ESM and TypeScript input module
The valibot-json-schema
CLI loads the input JS module using standard NodeJS CommonJS require. This means you will
have issues with ESM or TypeScript modules.
To remedy that, you will either have to preinstall ebuild-runner
and esbuild
(so that the program can use them) or
use a Node-compatible runtime that support these modules (ex: bun, replacing npx
with bunx
).
Example:
# Convert from TS/ESM module using bunx
bunx @gcornut/valibot-json-schema to-json-schema ./schemas.ts
# Convert from TS/ESM module with esbuild-runner preinstalled
npm install esbuild esbuild-runner
npx @gcornut/valibot-json-schema to-json-schema ./schemas.ts
# Convert from TS/ESM module using `yarn dlx` multi-package feature
yarn dlx -p esbuild -p esbuild-runner -p @gcornut/valibot-json-schema valibot-json-schema to-json-schema ./schemas.ts
CLI parameters
Use -o <file>
option to output the JSON schema to a file instead of stdout
.
Use -t <type>
option to select the root definitions from the module exports (defaults to the "default" export).
Example: -t foo.bar
will get the property bar
on the foo
export of the input JS module.
Use -d <type>
option to select the definitions from the module exports (instead of using all non-default export).
Example: -d foo.bar
will get the property bar
on the foo
export of the input JS module.
See Advanced options for more options.
Programmatic usage
Use the toJSONSchema
function to convert a Valibot schema into JSON schema (v7):
import { toJSONSchema } from '@gcornut/valibot-json-schema';
import { string } from 'valibot';
toJSONSchema({ schema: string() })
// {
// $schema: 'http://json-schema.org/draft-07/schema#',
// type: 'string',
// }
If you have many named schemas to convert, you can use the definitions
option schema to list as a plain object so that
both the schema names (object keys) and schema definitions (object values) are exported to JSON schema.
import { toJSONSchema } from '@gcornut/valibot-json-schema';
import { number } from 'valibot';
const Number = number();
toJSONSchema({ definitions: { Number } });
// {
// $schema: 'http://json-schema.org/draft-07/schema#',
// definitions: { Number: { type: 'number' } },
// }
See Advanced options for more options.
Advanced options
Strict object types
Using the strictObjectTypes
option (--strictObjectTypes
in the CLI), you can force all object type block unknown
keys (additionalProperties: false
).
Ignore unknown validation
You might want to have advanced validation in your valibot schema that JSON schema can't support (
like custom()). By default, toJSONSchema()
will throw an error to let you know
these can't be converted to JSON schema.
Using the ignoreUnknownValidation
option (--ignoreUnknownValidation
in the CLI), you can ignore unsupported valibot
validations.
If you preferred to only ignore a specific type of validation, you can
use the customValidationConversion
option.
Common type strategies
Many JS types don't have a direct equivalent in JSON and toJSONSchema()
will throw an error when encountering any of
those. However, some of these types have common strategies to convert them.
Using the dateStrategy
option (--dateStrategy
in the CLI), you can choose to convert JS Date objects into a string (
with the date-time
format) or into an integer (with the unix-time
format).
Using the undefinedStrategy
option (--undefinedStrategy
in the CLI), you can choose to convert undefined
to the "
any" schema (no validation) or to the null
type.
Using the bigintStrategy
option (--bigintStrategy
in the CLI), you can choose to convert JS BigInt values to an
integer (with the int64
format) or into a string.
Custom schema conversion
In some cases, you might want to provide custom schema conversion to override standard schema conversion or to add conversion of unsupported schemas.
Using the customSchemaConversion
option, you can provide a custom schema converter for any valibot schema type.
Example: converting JS Set schema into an array schema
import { set, string } from 'valibot';
toJSONSchema({
schema: set(string()),
customSchemaConversion: {
// Treat set type like an array
set: (schema, converter) => converter(array(schema.value))
},
})
// => { type: 'array', items: { type: 'string' } }
Custom validation conversion
Using the customValidationConversion
option, you can provide a custom validation converter for any valibot
validation type.
Example: ignoring the valibot custom()
validation on all string schema
import { string, custom, pipe } from 'valibot';
toJSONSchema({
schema: pipe(string(), custom(myCustomStringValidation)),
customValidationConversion: {
string: { custom: () => ({}) }
},
})
// => { type: 'string' }
Supported features
Some converted schema might have slightly different behavior in a JSON schema validator, especially on string
formats (email
, ipv4
, date
, etc.) since their implementation is different from valibot implementation.
Here is the list of supported Valibot features (some have partial support):
| feature | status |
|---------------------------|--------------------------------------------------------------------------------------------------|
| any
schema | ✅ supported |
| null
schema | ✅ supported |
| number
schema | ✅ supported |
| bigint
schema | ⚠️ with bigintStrategy
option provided |
| string
schema | ✅ supported |
| boolean
schema | ✅ supported |
| literal
schema | ⚠️ partial: only JSON-compatible literal are supported |
| nullable
schema | ✅ supported |
| nullish
schema | ✅ supported |
| optional
schema | ✅ supported |
| never
schema | ⚠️ partial: only inside object
rest or tuple
rest params |
| picklist
schema | ⚠️ partial: only JSON-compatible literal are supported |
| enum_
schema | ✅ supported |
| union
schema | ✅ supported |
| variant
schema | ⚠️ partial: converted just like an union
|
| intersect
schema | ✅ supported |
| array
schema | ✅ supported |
| tuple
schema | ✅ supported |
| object
schema | ✅ supported |
| record
schema | ⚠️ partial: only string key are allowed, applicable to plain object only, not arrays |
| lazy
schema | ⚠️ partial: only if the schema inside is referenced in definitions
|
| date
schema | ⚠️ with dateStrategy
option provided |
| length
validation | ✅ supported |
| maxLength
validation | ✅ supported |
| minLength
validation | ✅ supported |
| regex
validation | ⚠️ partial: only on RegExp features supported by JSON schema |
| value
validation | ⚠️ partial: only on string
, number
and boolean
|
| minValue
validation | ⚠️ partial: only on number
|
| maxValue
validation | ⚠️ partial: only on number
|
| multipleOf
validation | ✅ supported |
| integer
validation | ✅ supported |
| email
validation | ✅ supported (JSON schema format) |
| isoDate
validation | ✅ supported (JSON schema format) |
| isoTimestamp
validation | ✅ supported (JSON schema format) |
| ipv4
validation | ✅ supported (JSON schema format) |
| ipv6
validation | ✅ supported (JSON schema format) |
| uuid
validation | ✅ supported (JSON schema format) |
| description
metadata | ✅ supported |