0.2.0 • Published 2 years ago
io-ts-to-json-schema v0.2.0
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"
// }
// ]
// }
// },
// }