UNPKG

runtypes-to-jsonschema

Version:
102 lines (101 loc) 3.92 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.tojsonschema = void 0; const nev = (x) => { throw new Error(`unhandled case: ${x}`); }; const tojsonschema = (rtschema, subjsonschema = {}, options) => { const { loose: isLooseMode } = options || {}; const js = subjsonschema; const { description, defaultValue } = rtschema.meta || {}; if (description) { js.description = description; } if (defaultValue != undefined) { // https://json-schema.org/understanding-json-schema/reference/generic.html?highlight=default js.default = defaultValue; } const reflect = rtschema.reflect; switch (reflect.tag) { case "array": // https://json-schema.org/understanding-json-schema/reference/array.html#id6 js.type = "array"; js.items = (0, exports.tojsonschema)(reflect.element, {}, options); return js; case "void": case "never": case "unknown": case "function": case "instanceof": case "symbol": case "template": if (isLooseMode) { return js; } throw new Error(`unsupported ${reflect.tag}. consider using { loose: true }`); case "bigint": js.type = "integer"; return js; case "number": js.type = "number"; return js; case "boolean": js.type = "boolean"; return js; case "brand": return (0, exports.tojsonschema)(reflect.entity, js, options); case "constraint": // https://github.com/pelotom/runtypes/issues/319 return (0, exports.tojsonschema)(rtschema.underlying, js, options); case "dictionary": // https://json-schema.org/understanding-json-schema/reference/object.html#id5 js.type = "object"; js.properties = { builtin: (0, exports.tojsonschema)(reflect.value, {}, options) }; return js; case "intersect": // @todo - this could be tricky. go easy mode for 1st pass // https://github.com/pelotom/runtypes#template-literals js.type = "string"; return js; case "literal": js.const = reflect.value; return js; case "optional": return (0, exports.tojsonschema)(reflect.underlying, {}, options); case "record": js.type = "object"; js.properties = Object.entries(reflect.fields).reduce((props, [k, v]) => { let isRequired = reflect.isPartial ? false : true; let underlying = v; do { if (underlying?.tag === "optional") { isRequired = false; break; } underlying = "underlying" in underlying ? underlying.underlying : null; } while (underlying); if (isRequired) { js.required = [...(js.required || []), k]; } props[k] = (0, exports.tojsonschema)(v, {}, options); return props; }, {}); return js; case "string": js.type = "string"; return js; case "tuple": // https://json-schema.org/understanding-json-schema/reference/combining.html#id5 // @todo allOf drops order. is there a better way? js.allOf = reflect.components.map((v) => (0, exports.tojsonschema)(v, {}, options)); return js; case "union": js.anyOf = reflect.alternatives.map((v) => (0, exports.tojsonschema)(v, {}, options)); return js; default: nev(reflect); return js; } }; exports.tojsonschema = tojsonschema;