@valibot/to-json-schema
Version:
The official JSON schema converter for Valibot
2 lines (1 loc) • 5.4 kB
JavaScript
import*as v from"valibot";function i(e,n){switch(n?.errorMode){case"ignore":break;case"warn":{console.warn(e);break}default:throw new Error(e)}}function d(e,n,r){switch(n.type){case"base64":{e.contentEncoding="base64";break}case"bic":case"cuid2":case"decimal":case"digits":case"emoji":case"hexadecimal":case"hex_color":case"nanoid":case"octal":case"ulid":{e.pattern=n.requirement.source;break}case"description":{e.description=n.description;break}case"email":{e.format="email";break}case"empty":{e.type==="array"?e.maxItems=0:(e.type!=="string"&&i(`The "${n.type}" action is not supported on type "${e.type}".`,r),e.maxLength=0);break}case"integer":{e.type="integer";break}case"ipv4":{e.format="ipv4";break}case"ipv6":{e.format="ipv6";break}case"iso_date":{e.format="date";break}case"iso_date_time":case"iso_timestamp":{e.format="date-time";break}case"iso_time":{e.format="time";break}case"length":{e.type==="array"?(e.minItems=n.requirement,e.maxItems=n.requirement):(e.type!=="string"&&i(`The "${n.type}" action is not supported on type "${e.type}".`,r),e.minLength=n.requirement,e.maxLength=n.requirement);break}case"max_length":{e.type==="array"?e.maxItems=n.requirement:(e.type!=="string"&&i(`The "${n.type}" action is not supported on type "${e.type}".`,r),e.maxLength=n.requirement);break}case"max_value":{e.type!=="number"&&i(`The "max_value" action is not supported on type "${e.type}".`,r),e.maximum=n.requirement;break}case"min_length":{e.type==="array"?e.minItems=n.requirement:(e.type!=="string"&&i(`The "${n.type}" action is not supported on type "${e.type}".`,r),e.minLength=n.requirement);break}case"min_value":{e.type!=="number"&&i(`The "min_value" action is not supported on type "${e.type}".`,r),e.minimum=n.requirement;break}case"multiple_of":{e.multipleOf=n.requirement;break}case"non_empty":{e.type==="array"?e.minItems=1:(e.type!=="string"&&i(`The "${n.type}" action is not supported on type "${e.type}".`,r),e.minLength=1);break}case"regex":{n.requirement.flags&&i("RegExp flags are not supported by JSON Schema.",r),e.pattern=n.requirement.source;break}case"title":{e.title=n.title;break}case"url":{e.format="uri";break}case"uuid":{e.format="uuid";break}case"value":{e.const=n.requirement;break}default:i(`The "${n.type}" action cannot be converted to JSON Schema.`,r)}return e}var g=0;function u(e,n,r,t){let p=t.referenceMap.get(n);if(p&&p in t.definitions)return e.$ref=`#/$defs/${p}`,e;if("pipe"in n){for(let s=0;s<n.pipe.length;s++){let a=n.pipe[s];if(a.kind==="schema"){s>0&&i('A "pipe" with multiple schemas cannot be converted to JSON Schema.',r);let o=u({},a,r,t);if(o.$ref){let f=o.$ref.split("/")[2];Object.assign(e,t.definitions[f])}else Object.assign(e,o)}else e=d(e,a,r)}return e}switch(n.type){case"boolean":{e.type="boolean";break}case"null":{e.type="null";break}case"number":{e.type="number";break}case"string":{e.type="string";break}case"array":{e.type="array",e.items=u({},n.item,r,t);break}case"tuple":case"tuple_with_rest":case"loose_tuple":case"strict_tuple":{e.type="array",e.items=[];for(let s of n.items)e.items.push(u({},s,r,t));n.type==="tuple_with_rest"?e.additionalItems=u({},n.rest,r,t):e.additionalItems=n.type==="loose_tuple";break}case"object":case"object_with_rest":case"loose_object":case"strict_object":{e.type="object",e.properties={},e.required=[];for(let s in n.entries){let a=n.entries[s];e.properties[s]=u({},a,r,t),a.type!=="nullish"&&a.type!=="optional"&&e.required.push(s)}n.type==="object_with_rest"?e.additionalProperties=u({},n.rest,r,t):n.type==="strict_object"&&(e.additionalProperties=!1);break}case"record":{"pipe"in n.key&&i('The "record" schema with a schema for the key that contains a "pipe" cannot be converted to JSON Schema.',r),n.key.type!=="string"&&i(`The "record" schema with the "${n.key.type}" schema for the key cannot be converted to JSON Schema.`,r),e.type="object",e.additionalProperties=u({},n.value,r,t);break}case"any":case"unknown":break;case"nullable":case"nullish":{e.anyOf=[u({},n.wrapped,r,t),{type:"null"}],n.default!==void 0&&(e.default=v.getDefault(n));break}case"exact_optional":case"optional":case"undefinedable":{e=u(e,n.wrapped,r,t),n.default!==void 0&&(e.default=v.getDefault(n));break}case"literal":{typeof n.literal!="boolean"&&typeof n.literal!="number"&&typeof n.literal!="string"&&i('The value of the "literal" schema is not JSON compatible.',r),e.const=n.literal;break}case"enum":{e.enum=n.options;break}case"picklist":{n.options.some(s=>typeof s!="number"&&typeof s!="string")&&i('An option of the "picklist" schema is not JSON compatible.',r),e.enum=n.options;break}case"union":case"variant":{e.anyOf=n.options.map(s=>u({},s,r,t));break}case"intersect":{e.allOf=n.options.map(s=>u({},s,r,t));break}case"lazy":{let s=t.getterMap.get(n.getter);s||(s=n.getter(void 0),t.getterMap.set(n.getter,s));let a=t.referenceMap.get(s);a||(a=`${g++}`,t.referenceMap.set(s,a),t.definitions[a]=u({},s,r,t)),e.$ref=`#/$defs/${a}`;break}default:i(`The "${n.type}" schema cannot be converted to JSON Schema.`,r)}return e}function E(e,n){let r={definitions:{},referenceMap:new Map,getterMap:new Map};if(n?.definitions){for(let p in n.definitions)r.referenceMap.set(n.definitions[p],p);for(let p in n.definitions)r.definitions[p]=u({},n.definitions[p],n,r)}let t=u({$schema:"http://json-schema.org/draft-07/schema#"},e,n,r);return r.referenceMap.size&&(t.$defs=r.definitions),t}export{E as toJsonSchema};