Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/gcornut/valibot-json-schema
Converter from Valibot schemas to JSON schema
https://github.com/gcornut/valibot-json-schema
json-schema valibot
Last synced: 3 months ago
JSON representation
Converter from Valibot schemas to JSON schema
- Host: GitHub
- URL: https://github.com/gcornut/valibot-json-schema
- Owner: gcornut
- License: mit
- Created: 2023-10-13T08:11:17.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-08-05T16:27:39.000Z (3 months ago)
- Last Synced: 2024-08-06T13:56:08.288Z (3 months ago)
- Topics: json-schema, valibot
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/@gcornut/valibot-json-schema
- Size: 1.37 MB
- Stars: 43
- Watchers: 0
- Forks: 4
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# @gcornut/valibot-json-schema
CLI and JS utility to convert [Valibot](https://valibot.dev) 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](#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.
```shell
# 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 schemadefinitions
section.See detailed input and output:
_Input file `./schemas.js`_:
```js
import * as v from 'valibot';export const AString = v.string();
const AnObject = v.object({ aString: AString });
export default AnObject;
```_Output conversion_:
```json
{
"$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:
```shell
# 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 ` option to output the JSON schema to a file instead of `stdout`.
Use `-t ` 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 ` 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](#advanded-options) for more options.
## Programmatic usage
Use the `toJSONSchema` function to convert a Valibot schema into JSON schema (v7):
```js
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.```js
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](#advanded-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()](https://valibot.dev/api/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](#custom-validation-conversion).### 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
```js
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
```ts
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`](#json-schema-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 |