@cmtlyt/json-schema
Version:
json schema 处理相关方法
2 lines (1 loc) • 4.29 kB
JavaScript
import{getType as m,cacheByReturn as k,isFalse as O}from"@cmtlyt/base";const A=["string","number","boolean"];let d=0;function f(e,t=new Map){const n=m(e),r={type:n,id:d,value:"unknown"};t.has(e)?r.id=t.get(e):(++d,t.set(e,r.id));let a=r;return A.includes(n)&&(a={...r,value:e}),n==="array"?a={...r,value:e.map(u=>f(u,t))}:n==="object"?a={...r,value:Object.keys(e).sort().reduce((u,o)=>(u[o]=f(e[o],t),u),{})}:n==="map"?a={...r,value:[...e.entries()].map(([u,o])=>{const s=f(u,t),p=f(o,t);return{key:s,value:p}})}:n==="set"?a={...r,value:[...e.values()].map(u=>f(u,t))}:n==="function"||n==="asyncfunction"?a={...r,value:(()=>{const u=e.toString();return/^.*?=>/.test(u)?`return ${u}`:u.indexOf("async")===0?u.replace("async","return async function"):u.indexOf("function")===0?`return ${u}`:`return function ${u}`})()}:n==="date"?a={...r,value:e.toISOString()}:n==="regexp"&&(a={...r,value:{source:e.source,flags:e.flags}}),a}function B(e){d=0;let t=new Map;const n=f(e,t);return t.clear(),t=null,JSON.stringify(n)}function y(e,t={}){const n=e.type;if(A.includes(n))return e.value;if(t[e.id])return t[e.id];let r="unknown";return n==="array"?r=e.value.map(a=>y(a),t):n==="object"?r=Object.keys(e.value).reduce((a,u)=>(a[u]=y(e.value[u],t),a),{}):n==="map"?r=new Map(e.value.map(({key:a,value:u})=>[y(a,t),y(u,t)])):n==="set"?r=new Set(e.value.map(a=>y(a,t))):n==="function"||n==="asyncfunction"?r=new Function(e.value)():n==="date"?r=new Date(e.value):n==="regexp"&&(r=new RegExp(e.value.source,e.value.flags)),t[e.id]=r,r}function F(e){let t={};const n=y(JSON.parse(e),t);for(const r in t)delete t[r];return t=null,n}const b={string:()=>"",number:()=>0,boolean:()=>!1,array:()=>[],object:()=>({}),map:()=>new Map,set:()=>new Set,function:()=>()=>{},asyncfunction:()=>async()=>{},date:()=>new Date,regexp:()=>/(?:.)/,bigint:()=>BigInt(0),symbol:()=>Symbol(""),weakmap:()=>new WeakMap,weakset:()=>new WeakSet,promise:()=>Promise.resolve(),error:()=>new Error(" "),int8array:()=>new Int8Array,uint8array:()=>new Uint8Array,uint8clampedarray:()=>new Uint8ClampedArray,int16array:()=>new Int16Array,uint16array:()=>new Uint16Array,int32array:()=>new Int32Array,uint32array:()=>new Uint32Array,float32array:()=>new Float32Array,float64array:()=>new Float64Array,file:()=>new File([],"file"),blob:()=>new Blob};function v(e){const t=m(e),n={type:t,description:""};if(Array.isArray(e)){const r=e[0],a=v(r);n.type="array",typeof r<"u"&&(n.items=a)}else if(t==="object"){const r=[];n.properties={};for(const a in e){const u=e[a],o=v(u);n.properties[a]=o,!r.includes(a)&&r.push(a)}n.required=r}return n}function $(e){const t=v(e);return JSON.stringify(t)}function g(e,t){const n=t.type,r=(e[n]||(()=>{}))();if(n!=="object"&&n!=="array")return r;if(n==="object"){const a=t.properties,u=r;for(const o in a){const s=a[o];u[o]=g(e,s)}return u}else if(n==="array"){const a=t.items;if(!a)return r;const u=r,{maxItems:o=0,minItems:s=0}=a,p=Math.floor(Math.random()*(o-s+1))+s||1;for(let c=0;c<p;c++)u.push(g(e,a));return u}}function I(e,t={}){const n={...b,...t};return g(n,JSON.parse(e))}function w(e,t,n="",r=[]){const a=m(t);if(e.type!==a&&r.push({path:n,message:`\u7C7B\u578B\u5E94\u8BE5\u4E3A ${e.type}`}),a==="array"){const u=t.length,{minItems:o=0,maxItems:s=1/0,uniqueItems:p,items:c}=e;(u>s||u<o)&&r.push({path:n,message:`\u6700\u591A\u5141\u8BB8 ${s} \u5143\u7D20, \u81F3\u5C11\u8981\u6709 ${o} \u5143\u7D20, \u5F53\u524D ${u} \u4E2A`});const S=new Set,j=k(()=>p?(i,l)=>{if(S.has(i))return r.push({path:n,message:`\u5143\u7D20\u5FC5\u987B\u552F\u4E00 ${l}`}),!1;S.add(i),c&&w(c,i,`${n}/${l}`,r)}:(i,l)=>{c&&w(c,i,`${n}/${l}`,r)});for(const i in t){const l=t[i];if(O(j(l,+i)))break}}if(a==="object"){const{properties:u,required:o}=e;o?.every(s=>s in t);for(const s in u)w(u[s],t[s],`${n}/${s}`,r)}}function x(e,t){const n=[];return w(JSON.parse(e),t,"",n),[n.length===0,n]}function h(e){if(typeof e=="string")return b[e]?.();if(Array.isArray(e))return[h(e[0])];if(m(e)!=="object")return{};const t={};return Object.keys(e).forEach(n=>{const r=e[n];m(r)==="string"?t[n]=b[r]?.():typeof r=="object"?t[n]=h(r):t[n]=r}),t}function D(e){const t=h(e);return $(t)}export{F as decodeDataSchema,B as encodeDataSchema,$ as jsonSchemaGenerator,I as mockFromSchema,D as typeObjectToSchema,x as verifyBySchema};