stnl
Version:
A simple, opinionated type validator built for performance
1 lines • 2.9 kB
JavaScript
import{optimizeDirectCall}from"../utils.js";export let compileLimits=(arr,start,i)=>{let str=``;while(start<arr.length){let limit=arr[start++];let id=limit[0];str+=`&&`+(id===0?i+`>=`+limit[1]:id===1?i+`<=`+limit[1]:id===2?i+`.length>`+(limit[1]-1):id===3?i+`.length<`+(limit[1]+1):id===4?i+`.length===`+limit[1]:`true`)}return str};export let compileToFn=(t,deps)=>`o=>`+compile(t,`o`,deps,false);export let compile=(t,i,deps,optional)=>{let id=t[0];let str=``;let isNil=(id&1)===1;if(isNil){id-=1;str=`(`+i+(optional?`==null||`:`===null||`)}else if(optional)str+=`(`+i+`===void 0||`;let wrapped=isNil||optional;if(id===0)str+=`Number.isInteger(`+i+`)`+compileLimits(t,1,i);else if(id===2)str+=`typeof `+i+`==="number"`+compileLimits(t,1,i);else if(id===4)str+=`typeof `+i+`==="string"`+compileLimits(t,1,i);else if(id===6)str+=`typeof `+i+`==="boolean"`;else if(id===8)str+=i+`!==void 0`;else if(id===10){let list=t[1];wrapped||(str+=`(`);str+=i+`==="`+list[0]+`"`;for(let j=1;j<list.length;j++)str+=`||`+i+`==="`+list[j]+`"`;wrapped||(str+=`)`)}else if(id===12)str+=i+`===`+(typeof t[1]===`string`?JSON.stringify(t[1]):t[1]);else if(id===14)str+=`Array.isArray(`+i+`)`+compileLimits(t,2,i)+`&&`+i+`.every(d`+deps.push(optimizeDirectCall(compileToFn(t[1],deps)))+`)`;else if(id===16){str+=(isNil?``:i+`!==null&&`)+`typeof `+i+`==="object"`;i+=`.`;if(t[1]!=null){let o=t[1];for(const key in o)str+=`&&`+compile(o[key],i+key,deps,false)}if(t[2]!=null){let o=t[2];for(const key in o)str+=`&&`+compile(o[key],i+key,deps,true)}}else if(id===18){let list=t[1];str+=`Array.isArray(`+i+`)&&`+i+`.length===`+list.length;for(let j=0;j<list.length;j++)str+=`&&`+compile(list[j],i+`[`+j+`]`,deps,false)}else if(id===20){str+=(isNil?``:i+`!==null&&`)+`typeof `+i+`==="object"&&(`;i+=`.`;let tag=i+t[1];for(const key in t[2]){let schema=t[2][key];str+=tag+`===`+JSON.stringify(key)+`?`;let first=true;if(schema[1]!=null){let o=schema[1];for(const key in o){if(first){first=false;str+=`&&`}str+=compile(o[key],i+key,deps,false)}}if(schema[2]!=null){let o=schema[2];for(const key in o){if(first){first=false;str+=`&&`}str+=compile(o[key],i+key,deps,true)}}str+=`:`}str+=`false)`}else if(id===22)str+=`d`+t[1]+`(`+i+`)`;else if(id===24){let scope=`(()=>{var `;let scopeDeps=[];if(t[2]!=null){let depsObj=t[2];for(const key in depsObj)scope+=`d`+key+`=`+compileToFn(depsObj[key],scopeDeps)+`,`}let main=optimizeDirectCall(compileToFn(t[1],scopeDeps));for(let i=0;i<scopeDeps.length;i++)scope+=`d`+(i+1)+`=`+scopeDeps[i]+`,`;str+=`d`+deps.push(scope+`d=`+main+`;return d})()`)+`(`+i+`)`}return wrapped?str+`)`:str};export let dependencies=deps=>{let res=``;if(deps.length>0){for(let i=0;i<deps.length;i++)res+=(i===0?`var d`:`,d`)+(i+1)+`=`+deps[i]}return res};export let code=t=>{let deps=[];let str=optimizeDirectCall(compileToFn(t,deps));return dependencies(deps)+`;return `+str};export default t=>Function(code(t))();