@lunora/cli
Version:
The Lunora CLI: init, dev, deploy, codegen, migrate, seed, doctor, insights, logs, registry, and the rest of the project commands
2 lines (1 loc) • 3.34 kB
JavaScript
import{LunoraError as r}from"@lunora/errors";const d=/[\r\n]/u,w=/^[A-Za-z_]\w*$/u,y=/^[A-Za-z0-9][\w-]*$/u,b=/^[\w.-]+(?:\/[\w.-]+)*$/u,I=(c,s)=>{if(typeof c!="object"||c===null)throw new r("INTERNAL",`registry.json for "${s}" is not an object`);const e=c,{name:n}=e;if(typeof n!="string"||n.length===0)throw new r("INTERNAL",`registry.json for "${s}" is missing a string "name"`);if(!y.test(n))throw new r("INTERNAL",`registry.json for "${s}": name "${n}" must match ${y.source} (letters, digits, "-", "_"; no path separators, "..", or code)`);const g=e.files;if(!Array.isArray(g))throw new TypeError(`registry.json for "${s}" is missing a "files" array`);const A=g.map((t,o)=>{if(typeof t!="object"||t===null)throw new r("INTERNAL",`registry.json "${s}": files[${String(o)}] is not an object`);const i=t,{from:a}=i,{to:f}=i,{merge:p}=i;if(typeof a!="string"||typeof f!="string")throw new TypeError(`registry.json "${s}": files[${String(o)}] needs string "from" and "to"`);if(p!=="create-or-skip"&&p!=="schema-extension")throw new r("INTERNAL",`registry.json "${s}": files[${String(o)}].merge must be "create-or-skip" or "schema-extension"`);for(const[v,l]of[["from",a],["to",f]])if(l.includes("..")||l.startsWith("/"))throw new r("INTERNAL",`registry.json "${s}": files[${String(o)}].${v} "${l}" must be a relative path without ".."`);return{from:a,merge:p,to:f}}),u=t=>typeof t=="object"&&t!==null?t:void 0,h=u(e.deps),m=u(e.devDependencies),$=Array.isArray(e.requires)?e.requires.filter(t=>typeof t=="string"):void 0,E=Array.isArray(e.bindings)?e.bindings.filter(t=>{if(typeof t!="object"||t===null)return!1;const o=t;return Array.isArray(o.path)&&o.path.every(i=>typeof i=="string")}):void 0,j=Array.isArray(e.entrypointReexports)?e.entrypointReexports.filter(t=>typeof t=="object"&&t!==null&&typeof t.module=="string").map(t=>{if(t.module.includes("..")||t.module.startsWith("/")||!b.test(t.module))throw new r("INTERNAL",`registry.json "${s}": entrypointReexports[].module "${t.module}" must be a safe relative module path without path traversal or unsafe characters`);const o={module:t.module};if(typeof t.comment=="string"){if(d.test(t.comment))throw new r("INTERNAL",`registry.json "${s}": entrypointReexports[].comment must not contain a newline`);o.comment=t.comment}return o}):void 0,R=Array.isArray(e.envVars)?e.envVars.filter(t=>typeof t=="object"&&t!==null&&typeof t.name=="string").map(t=>{const o=typeof t.value=="string";if(!w.test(t.name))throw new r("INTERNAL",`registry.json "${s}": envVars["${t.name}"].name must match ${w.source} (letters, digits, underscore; no "=" or newline)`);if(o&&d.test(t.value))throw new r("INTERNAL",`registry.json "${s}": envVars["${t.name}"].value must not contain a newline`);if(typeof t.description=="string"&&d.test(t.description))throw new r("INTERNAL",`registry.json "${s}": envVars["${t.name}"].description must not contain a newline`);return{...typeof t.description=="string"?{description:t.description}:{},name:t.name,secret:typeof t.secret=="boolean"?t.secret:!o,...o?{value:t.value}:{}}}):void 0;return{bindings:E,deps:h,description:typeof e.description=="string"?e.description:void 0,devDependencies:m,docs:typeof e.docs=="string"?e.docs:void 0,entrypointReexports:j,envVars:R,files:A,name:n,requires:$,title:typeof e.title=="string"?e.title:void 0}};export{I as default};