Skip to content

Commit 69a7af7

Browse files
Merge pull request #1372 from open-circle/feat-json-schema-v1.5
Valibot `toJsonSchema` v1.5
2 parents 0a235e2 + df48dd9 commit 69a7af7

File tree

22 files changed

+881
-152
lines changed

22 files changed

+881
-152
lines changed

packages/to-json-schema/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
All notable changes to the library will be documented in this file.
44

5+
## v1.5.0 (December 11, 2025)
6+
7+
- Add support for JSON Schema draft-2020-12 and OpenAPI 3.0 Schema Object format
8+
- Add `propertyNames` support to record schemas for key validation constraints
9+
- Add support for `toBigint`, `toBoolean`, `toDate`, `toNumber` and `toString` actions for `typeMode: 'input'`
10+
- Add new `toStandardJsonSchema` function to convert Valibot schemas to Standard JSON Schema format
11+
- Change return type from `JSONSchema7` to a custom `JsonSchema` type
12+
513
## v1.4.0 (December 02, 2025)
614

715
- Add support for `examples` action

packages/to-json-schema/README.md

Lines changed: 84 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Valibot to JSON Schema
22

3-
Utility to convert [Valibot](https://valibot.dev) schemas to JSON schema (draft 07).
3+
Utility to convert [Valibot](https://valibot.dev) schemas to JSON Schema. Supports JSON Schema draft-07, draft-2020-12, and OpenAPI 3.0 Schema Object formats.
44

55
```js
66
import { toJsonSchema } from '@valibot/to-json-schema';
77
import * as v from 'valibot';
88

9-
toJsonSchema(v.string()); // { type: "string" }
9+
toJsonSchema(v.string()); // { $schema: "http://json-schema.org/draft-07/schema#", type: "string" }
1010
```
1111

1212
This package is particularly popular for:
@@ -22,36 +22,36 @@ This package is particularly popular for:
2222

2323
**Note**: Converted schemas may behave slightly differently in JSON schema validators (especially for string format) because their implementation is different from Valibot's.
2424

25-
| Schema | Status | Note |
26-
| ---------------- | ------ | ------------------------------------------------------------------- |
27-
| `any` || |
28-
| `array` || |
29-
| `boolean` || |
30-
| `enum` || |
31-
| `exactOptional` || |
32-
| `intersect` || |
33-
| `lazy` | ⚠️ | The `.getter` function is always executed with `undefined` as input |
34-
| `literal` | ⚠️ | Only JSON compatible values are supported |
35-
| `looseObject` || |
36-
| `looseTuple` || |
37-
| `null` || |
38-
| `nullable` || |
39-
| `nullish` || |
40-
| `number` || |
41-
| `objectWithRest` || |
42-
| `object` || |
43-
| `optional` || |
44-
| `picklist` | ⚠️ | Only JSON compatible values are supported |
45-
| `record` | ⚠️ | Only plain `string` schemas for the key of the record are supported |
46-
| `strictObject` || |
47-
| `strictTuple` || |
48-
| `string` || |
49-
| `tupleWithRest` || |
50-
| `tuple` || |
51-
| `union` || |
52-
| `undefinedable` || |
53-
| `unknown` || |
54-
| `variant` | ⚠️ | The discriminator key will be ignored |
25+
| Schema | Status | Note |
26+
| ---------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------- |
27+
| `any` || |
28+
| `array` || |
29+
| `boolean` || |
30+
| `enum` || |
31+
| `exactOptional` || |
32+
| `intersect` || |
33+
| `lazy` | ⚠️ | The `.getter` function is always executed with `undefined` as input |
34+
| `literal` | ⚠️ | Only JSON compatible values are supported |
35+
| `looseObject` || |
36+
| `looseTuple` || |
37+
| `null` || |
38+
| `nullable` || |
39+
| `nullish` || |
40+
| `number` || |
41+
| `objectWithRest` || |
42+
| `object` || |
43+
| `optional` || |
44+
| `picklist` | ⚠️ | Only JSON compatible values are supported |
45+
| `record` | ⚠️ | Only `string` schemas for the key of the record are supported. Adds `propertyNames` for key validation (not available in OpenAPI 3.0) |
46+
| `strictObject` || |
47+
| `strictTuple` || |
48+
| `string` || |
49+
| `tupleWithRest` || |
50+
| `tuple` || |
51+
| `union` || |
52+
| `undefinedable` || |
53+
| `unknown` || |
54+
| `variant` | ⚠️ | The discriminator key will be ignored |
5555

5656
| Actions | Status | Note |
5757
| -------------- | ------ | ----------------------------------------------------------- |
@@ -95,15 +95,41 @@ This package is particularly popular for:
9595

9696
## Configurations
9797

98-
| Option | Type | Note |
99-
| -------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
100-
| typeMode | `'ignore' \| 'input' \| 'output'` | Whether to convert the input or output type of the Valibot schema to JSON Schema. |
101-
| errorMode | `'throw' \| 'warn' \| 'ignore'` | The policy for handling incompatible schemas and actions. |
102-
| definitions | `Record<string, GenericSchema>` | The schema definitions for constructing recursive schemas. If not specified, the definitions are generated automatically. |
103-
| overrideSchema | `(context: OverrideSchemaContext) => JSONSchema7 \| null \| undefined` | Overrides the JSON Schema conversion for a specific Valibot schema. |
104-
| ignoreActions | `string[]` | The actions that should be ignored during the conversion. |
105-
| overrideAction | `(context: OverrideActionContext) => JSONSchema7 \| null \| undefined` | Overrides the JSON Schema reference for a specific Valibot action. |
106-
| overrideRef | `(context: OverrideRefContext) => string \| null \| undefined` | Overrides the JSON Schema reference for a specific reference ID. |
98+
| Option | Type | Note |
99+
| -------------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
100+
| target | `'draft-07' \| 'draft-2020-12' \| 'openapi-3.0'` | The target JSON Schema format. Defaults to `'draft-07'`. |
101+
| typeMode | `'ignore' \| 'input' \| 'output'` | Whether to convert the input or output type of the Valibot schema to JSON Schema. |
102+
| errorMode | `'throw' \| 'warn' \| 'ignore'` | The policy for handling incompatible schemas and actions. |
103+
| definitions | `Record<string, GenericSchema>` | The schema definitions for constructing recursive schemas. If not specified, the definitions are generated automatically. |
104+
| overrideSchema | `(context: OverrideSchemaContext) => JsonSchema \| null \| undefined` | Overrides the JSON Schema conversion for a specific Valibot schema. |
105+
| ignoreActions | `string[]` | The actions that should be ignored during the conversion. |
106+
| overrideAction | `(context: OverrideActionContext) => JsonSchema \| null \| undefined` | Overrides the JSON Schema reference for a specific Valibot action. |
107+
| overrideRef | `(context: OverrideRefContext) => string \| null \| undefined` | Overrides the JSON Schema reference for a specific reference ID. |
108+
109+
### Target format
110+
111+
The `target` configuration allows you to specify which JSON Schema format to generate. Different targets have different capabilities and syntax:
112+
113+
```js
114+
import { toJsonSchema } from '@valibot/to-json-schema';
115+
import * as v from 'valibot';
116+
117+
const schema = v.nullable(v.string());
118+
119+
// JSON Schema draft-07 (default)
120+
toJsonSchema(schema);
121+
// { $schema: "http://json-schema.org/draft-07/schema#", anyOf: [{ type: "string" }, { type: "null" }] }
122+
123+
// JSON Schema draft-2020-12
124+
toJsonSchema(schema, { target: 'draft-2020-12' });
125+
// { $schema: "https://json-schema.org/draft/2020-12/schema", anyOf: [{ type: "string" }, { type: "null" }] }
126+
127+
// OpenAPI 3.0 Schema Object
128+
toJsonSchema(schema, { target: 'openapi-3.0' });
129+
// { type: "string", nullable: true }
130+
```
131+
132+
**Note**: Some features like `propertyNames` for record schemas are not available in OpenAPI 3.0.
107133

108134
### Type mode
109135

@@ -296,6 +322,23 @@ toJsonSchema(v.object({ key: v.lazy(() => StringSchema) }));
296322

297323
## Additional functions
298324

325+
### `toStandardJsonSchema`
326+
327+
Converts a Valibot schema to the [Standard JSON Schema](https://standardschema.dev/) format. This format is useful when working with tools and libraries that support the Standard JSON Schema specification.
328+
329+
```js
330+
import { toStandardJsonSchema } from '@valibot/to-json-schema';
331+
import * as v from 'valibot';
332+
333+
const schema = toStandardJsonSchema(
334+
v.object({
335+
id: v.pipe(v.string(), v.uuid()),
336+
name: v.pipe(v.string(), v.nonEmpty()),
337+
age: v.optional(v.number()),
338+
})
339+
);
340+
```
341+
299342
### `toJsonSchemaDefs`
300343

301344
Converts only the provided Valibot schema definitions to JSON Schema definitions, without wrapping them in a root schema. This is particularly useful for OpenAPI specifications where you need only the schema definitions.

packages/to-json-schema/jsr.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@valibot/to-json-schema",
3-
"version": "1.4.0",
3+
"version": "1.5.0",
44
"exports": "./src/index.ts",
55
"publish": {
66
"include": ["src/**/*.ts", "README.md"],

packages/to-json-schema/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@valibot/to-json-schema",
33
"description": "The official JSON schema converter for Valibot",
4-
"version": "1.4.0",
4+
"version": "1.5.0",
55
"license": "MIT",
66
"author": "Fabian Hiller",
77
"homepage": "https://valibot.dev",
@@ -53,7 +53,6 @@
5353
},
5454
"devDependencies": {
5555
"@eslint/js": "^9.39.1",
56-
"@types/json-schema": "^7.0.15",
5756
"@types/node": "^24.10.1",
5857
"@vitest/coverage-v8": "^4.0.13",
5958
"eslint": "^9.39.1",

packages/to-json-schema/src/converters/convertAction/convertAction.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import type { JSONSchema7 } from 'json-schema';
21
import type * as v from 'valibot';
3-
import type { ConversionConfig } from '../../type.ts';
2+
import type { ConversionConfig, JsonSchema } from '../../types/index.ts';
43
import { addError, handleError } from '../../utils/index.ts';
54

65
/**
@@ -114,10 +113,10 @@ type Action =
114113
* @returns The converted JSON Schema.
115114
*/
116115
export function convertAction(
117-
jsonSchema: JSONSchema7,
116+
jsonSchema: JsonSchema,
118117
valibotAction: Action,
119118
config: ConversionConfig | undefined
120-
): JSONSchema7 {
119+
): JsonSchema {
121120
// Ignore action if specified in configuration
122121
if (config?.ignoreActions?.includes(valibotAction.type)) {
123122
return jsonSchema;

0 commit comments

Comments
 (0)