io-ts-to-json-schema
v0.2.0
Published
Understandable io-ts error reports.
Downloads
1,649
Maintainers
Readme
io-ts-to-json-schema
Transform io-ts
codecs to json schema.
Escape hatch for interfacing io-ts and json schema validations.
usage/examples
npm i io-ts-to-json-schema
# fp-ts and io-ts are package peerDependencies
# so make sure you have these also installed
import * as t from 'io-ts';
import { toJsonSchema } from 'io-ts-to-json-schema';
const codec = t.type({
a: t.string,
b: t.union([t.string, t.null]),
});
toJsonSchema(codec);
// {
// "type": "object",
// "description": "{ a: string, b: (string | null) }",
// "properties": {
// "a": {
// "type": "string",
// "description": "string"
// },
// "b": {
// "anyOf": [
// {
// "type": "string",
// "description": "string"
// },
// {
// "type": "null",
// "description": "null"
// }
// ],
// "description": "(string | null)"
// }
// },
// "required": [
// "a",
// "b"
// ]
// }
features
built-in codec support table
| codec | status | comment |
| ----------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| t.null
| ✅ | - |
| t.string
| ✅ | - |
| t.number
| ✅ | - |
| t.bigint
| ⚠️ | treated like number
|
| t.boolean
| ✅ | - |
| t.undefined
| ⚠️ | unrepresentable in JSON, falls back to {}
|
| t.void
| ⚠️ | unrepresentable in JSON, falls back to {}
|
| t.any
| ⚠️ | unrepresentable in JSON, falls back to {}
|
| t.unknown
| ⚠️ | unrepresentable in JSON, falls back to {}
|
| t.UnknownArray
| ⚠️ | unrepresentable in JSON, falls back to { type: 'array', items: {} }
|
| t.UnknownRecord
| ⚠️ | unrepresentable in JSON, falls back to { type: 'object' }
|
| t.Function
| ⚠️ | unrepresentable in JSON, falls back to {}
|
| t.Refinement
| ⚠️ | unrepresentable in JSON, falls back to {}
|
| t.literal
| ✅ | - |
| t.recursion
| ✅ | due to single top down codec traversal, additional definitions may be placed in other places than root level $deps
. see the tests |
| t.array
| ✅ | - |
| t.type
| ✅ | - |
| t.partial
| ✅ | - |
| t.record
| ✅ | assumes domain is string
|
| t.union
| ✅ | - |
| t.intersection
| ✅ | - |
| t.tuple
| ✅ | - |
| t.readonly
| ✅ | - |
| t.readonlyArray
| ✅ | - |
| t.strict
| ✅ | - |
| t.keyof
| ✅ | - |
| t.exact
| ✅ | - |
output customization
Each node in the schema can be customized or completely replaced. This allows you to add support for your custom t.Type
s.
const codec = t.type(
{
a: t.string,
b: t.union([t.string, t.null], 'StringOrNull'),
},
'FooBar',
);
const descriptions = {
FooBar: 'some description for foobar',
StringOrNull: 'some description for string | null',
};
// e.g. attaching custom descriptions
const schema = toJsonSchema(codec, {
customizer: (schema, codec, context) => ({
...schema,
description: descriptions[codec.name],
}),
});
// {
// "type": "object",
// "required": [
// "a",
// "b"
// ],
// "properties": {
// "a": {
// "type": "string"
// },
// "b": {
// "anyOf": [
// {
// "type": "string"
// },
// {
// "type": "null"
// }
// ],
// "description": "some description for string | null"
// }
// },
// "description": "some description for foobar"
// }
codec customization
Each entered codec can be manipulated beforehand.
const codec = t.type(
{
a: t.string,
b: t.union([t.string, t.null], 'StringOrNull'),
},
'FooBar',
);
const schema = toJsonSchema(codec, {
codecCustomizer: codec => {
if (codec.name !== 'FooBar' || !(codec instanceof t.InterfaceType)) return codec;
// omit single field
const { a: _, ...props } = codec.props;
return t.type(props, codec.name);
},
});
// {
// "type": "object",
// "required": [
// "b"
// ],
// "properties": {
// "b": {
// "anyOf": [
// {
// "type": "string"
// },
// {
// "type": "null"
// }
// ]
// }
// },
// }