typenvx
Version:
Typenv is a modern, type-safe alternative to .env files, providing advanced validation, intelligent interpolation, and conditional logic for better environment management.
6 lines • 13 kB
JavaScript
;var ae=require('fs'),I=require('path');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var ae__default=/*#__PURE__*/_interopDefault(ae);var I__default=/*#__PURE__*/_interopDefault(I);var s=class extends Error{constructor(n){super(n),this.name="EnvxError";}};var D={fileDoesNotExist:e=>`The specified file does not exist: ${e}`,unsupportedType:(e,n)=>`Line ${e+1}: Unsupported type "${n}".`,validator:{invalidNumber:(e,n)=>`Invalid value for "${e}": expected a number but received "${n}".`,invalidBoolean:(e,n)=>`Invalid boolean for "${e}": expected "true" or "false" but received "${n}".`,missingEnumValues:e=>`Enum values are not defined for "${e}". Please specify allowed values.`,invalidEnum:(e,n,r)=>`Invalid enum value for "${e}": expected one of [${r.join(", ")}] but received "${n}".`,invalidEmail:(e,n)=>`Invalid email format for "${e}": received "${n}". Please provide a valid email address.`,invalidUrl:(e,n)=>`Invalid URL format for "${e}": received "${n}". Please provide a valid URL.`,unsupportedType:(e,n)=>`Unsupported type "${n}" specified for "${e}".`,requiredMissing:e=>`Required environment variable "${e}" is missing and has no default value.`},resolver:{circularDependency:e=>`Circular dependency detected while resolving "${e}".
\u2192 Check for variables referencing each other in a loop.`,interpolationFailed:(e,n="interpolation")=>`Failed to resolve variable "${e}". No value found for ${n}.`,requiredMissingInResolve:e=>`Environment variable "${e}" is not set and no default is defined.
\u2192 Define "${e}" in your .envx file or provide a default value in the schema.`},parser:{schemaBlockEmpty:e=>`Line ${e+1}: Schema block name cannot be empty.`,schemaKeyDuplicate:(e,n)=>`Line ${e+1}: Schema key "${n}" is already defined. Duplicate schema definitions are not allowed.`,typeAlreadyDefined:e=>`Line ${e+1}: "type" is already defined for this variable. You cannot redefine it.`,unknownSchemaProperty:(e,n)=>`Line ${e+1}: Unknown schema property "${n}".`,missingDelimiter:e=>`Line ${e+1}: Missing "=" delimiter in assignment.`,variableNameEmpty:e=>`Line ${e+1}: Variable name cannot be empty.`,typeRequiredBeforeDefault:e=>`Line ${e+1}: "type" must be defined before "default".`,defaultMustBeNumber:e=>`Line ${e+1}: Default value must be a valid number.`,defaultMustBeBoolean:e=>`Line ${e+1}: Default value must be "true" or "false".`,defaultNotInEnum:(e,n)=>`Line ${e+1}: Default "${n}" is not in enum values.`,invalidValuesJson:e=>`Line ${e+1}: "values" must be a valid JSON string array.`}};var c={lib:D,cli:{}};var y=/^\s*\$\{([^}]+)\}(?:\s*(==|!=)\s*(["'])?([^"']+)\3)?\s*\?\s*(["'])?([^"']+?)\5?\s*:\s*(["'])?([^"']+?)\7?\s*$/,O=/^[a-zA-Z0-9_\-\.]+$/,P=/^\[.*\]$/,U=/^[a-zA-Z0-9_\-\.]+$/;function B(e){return O.test(e)}function C(e){return P.test(e)}var G=(e,n)=>{let r=[",",";",":",".","-","?","!","|","\\","/","(",")","{","<",">","`","~","="],t=e.trimEnd().slice(-1);if(r.includes(t))throw new s(`[envx:error] Line ${n+1}: Value ends with a suspicious character (${t}). Please remove unnecessary character at the end.`)};function R(e,n,r){let{type:t,values:i}=r;if(!t)throw new s(c.lib.parser.typeRequiredBeforeDefault(n));switch(t){case "number":let o=Number(e);if(isNaN(o))throw new s(c.lib.parser.defaultMustBeNumber(n));r.default=o;break;case "boolean":if(e!=="true"&&e!=="false")throw new s(c.lib.parser.defaultMustBeBoolean(n));r.default=e==="true";break;case "enum":if(!i||!i.includes(e))throw new s(c.lib.parser.defaultNotInEnum(n,e));r.default=e;break;default:r.default=e;}}function _(e,n){let r=e.indexOf("=");if(r===-1)throw new s(c.lib.parser.missingDelimiter(n));return [e.slice(0,r),e.slice(r+1)]}function L(e){let n=e[0],r=e[e.length-1];return n==='"'&&r==='"'||n==="'"&&r==="'"?e.slice(1,-1):e}function q(e){let n=false,r=false;for(let t=0;t<e.length;t++){let i=e[t];if(i==='"'&&!n)r=!r;else if(i==="'"&&!r)n=!n;else if(i==="#"&&!n&&!r)return t}return -1}function H(e,n,r,t){let i=e.trim();if(i.includes('"""')){let o=i.indexOf('"""'),u=i.slice(0,o);return r.push(u.trimEnd()),t.push({key:n,value:r.join(`
`)}),{multilineKey:null,multilineBuffer:[]}}else return r.push(e),{multilineKey:n,multilineBuffer:r}}var J=["string","number","boolean","enum","email","url"],K={};function W(e,n,r,t){let[i,o]=_(e,n),u=i.trim(),a=L(o.trim());if(u==="description"&&o.trim().startsWith('"""')){let l=[],f=o.trim().slice(3);if(f.endsWith('"""')){r.description=f.slice(0,-3);return}for(l.push(f);t;){let p=t();if(p===null)throw new s(`Line ${n+1}: Unterminated multiline description.`);if(p.endsWith('"""')){l.push(p.slice(0,-3));break}else l.push(p);}r.description=l.join(`
`);return}switch(u){case "required":r.required=a==="true";break;case "type":if(r.type!==void 0)throw new s(c.lib.parser.typeAlreadyDefined(n));if(!J.includes(a))throw new s(c.lib.unsupportedType(n,a));r.type=a;break;case "default":r.type=="enum"&&!r.values?r.__pendingDefault=a:R(a,n,r);break;case "values":try{let l=JSON.parse(a);if(!(Array.isArray(l)&&l.length<=25&&l.every(p=>typeof p=="string"&&B(p))))throw new s(`[envx:error] Line ${n+1}: "values" must be a JSON array (max 25) of safe strings. Allowed characters: a-z, A-Z, 0-9, _, -, .`);r.values=l,r.__pendingDefault&&R(r.__pendingDefault,n,r);}catch{throw new s(c.lib.parser.invalidValuesJson(n))}break;case "deprecated":r.deprecated=a;break;case "description":r.description=a;break;default:throw new s(c.lib.parser.unknownSchemaProperty(n,u))}}function X(e,n,r){let t=e.slice(1,-1).trim();if(!t)throw new s(c.lib.parser.schemaBlockEmpty(n));if(!U.test(t))throw new s(`[envx:error] Line ${n+1}: Schema block name "${t}" contains invalid characters. Only letters, numbers, underscore (_), hyphen (-), and dot (.) are allowed.`);if(r[t])throw new s(c.lib.parser.schemaKeyDuplicate(n,t));return r[t]=r[t]??{},t}function j(e,n){let[r,t]=_(e,n),i=r.trim();if(!i)throw new s(c.lib.parser.variableNameEmpty(n));let o=t.trim();return o.startsWith('"""')?o.endsWith('"""')&&o.length>6?{key:i,value:o.slice(3,-3),isMultilineStart:false}:{key:i,value:o.slice(3),isMultilineStart:true}:(G(o,n),{key:i,value:L(o),isMultilineStart:false})}function $(e){let n=e.split(/\r?\n/),r=[],t={},i=null,o=null,u=[];for(let a=0;a<n.length;a++){let l=n[a],f=l.trim();if(!f||f.startsWith("#"))continue;if(o){let d=H(l,o,u,r);u=d.multilineBuffer,o=d.multilineKey;continue}let p=q(l);if(p!==-1&&(l=l.slice(0,p)),f=l.trim(),C(f)){if(p>-1&&p>l.indexOf("]"))throw new s(`[envx:error] Line ${a+1}: Schema header line cannot contain inline comments.`);i=X(f,a,t);continue}if(i){W(f,a,t[i],()=>(a++,a>=n.length?null:n[a].trim()));continue}let{key:E,value:x,isMultilineStart:g}=j(f,a);g?(o=E,u.push(x)):r.push({key:E,value:x});}if(o)throw new s(`[envx:error] End of file reached but multiline value for key "${o}" was not closed with triple quotes (""").`);return {env:r,schema:t}}function v(e,n,r=false,t=false){let i=typeof e=="string"?e.toLowerCase():e,o=i===true||i===false||i==="true"||i==="false"||i===1||i===0;if(t)return o;if(!o){if(r)throw new s(c.lib.validator.invalidBoolean(n||"",e));return false}return i===true||i==="true"||i===1}var Q=e=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);function xe(e){return v(e,"",false,true)?"boolean":!isNaN(Number(e))&&e!==""&&e!==null?"number":"string"}function z(e,n){let r={...K,...n};return e.forEach(({key:t,value:i})=>{r[t]||(r[t]={type:xe(i),required:false});}),r}function V(e){return I__default.default.isAbsolute(e)?e:I__default.default.resolve(process.cwd(),e)}function Z(e,n,r,t){switch(r){case "string":return n;case "number":{let i=Number(n);if(isNaN(i))throw new s(c.lib.validator.invalidNumber(e,n));return i}case "boolean":return v(n,e,true);case "enum":{if(!t?.length)throw new s(c.lib.validator.missingEnumValues(e));if(!t.includes(n))throw new s(c.lib.validator.invalidEnum(e,n,t));return n}case "email":{if(!Q(n))throw new s(c.lib.validator.invalidEmail(e,n));return n}case "url":try{return new URL(n),n}catch{throw new s(c.lib.validator.invalidUrl(e,n))}default:throw new s(c.lib.validator.unsupportedType(e,r))}}function M(e,n){let r={},t=new Map(e.map(({key:i,value:o})=>[i,o]));for(let i in n){let{type:o,required:u,default:a,values:l}=n[i],f=t.get(i);if(f!==void 0){r[i]=Z(i,f,o,o==="enum"?l:void 0);continue}if(a!==void 0){r[i]=Z(i,String(a),o,o==="enum"?l:void 0);continue}if(u)throw new s(c.lib.validator.requiredMissing(i))}for(let[i,o]of t.entries())i in r||(r[i]=o);return r}var ge=new Set(["NODE_ENV","CI","VERCEL_ENV"]);function ee(e){if(ge.has(e)&&typeof process<"u"&&process.env)return process.env[e]}function S(e,n,r){let{env:t,schema:i}=$(e),o=z(t,i),u=n?{...o,...n}:Object.keys(o).length>0?o:void 0,a=T(t,u),l=Object.fromEntries(Object.entries(a).filter(([f])=>u?.[f]!==void 0));return u&&true?{result:M(Object.entries(l).map(([p,E])=>({key:p,value:E})),u),schema:u,rawEnv:[]}:{result:l,schema:u,rawEnv:t}}function ne(e){let n=e.trim();return y.test(n)}function re(e){return typeof e=="string"&&e.includes("${")}function ie(e,n,r,t,i,o="interpolation"){if(r[e]!==void 0)return r[e];if(n[e]!==void 0)return oe(n[e],n,r,t,e,i+1);{let u=ee(e);if(u!==void 0)return r[e]=u,u;throw new s(c.lib.resolver.interpolationFailed(e,o))}}function T(e,n){let r={},t={};for(let o of e)r[o.key]=o.value;if(n)for(let o in n)r[o]===void 0&&n[o].default!==void 0&&(r[o]=n[o].default);let i=new Set;for(let o of Object.keys(r))t[o]=oe(r[o],r,t,i,o,0);if(n){for(let o in n)if(n[o].required&&r[o]===void 0)throw new s(c.lib.resolver.requiredMissingInResolve(o))}return t}function oe(e,n,r,t,i,o=0){if(typeof e!="string")return e;if(t.has(i))throw new s(c.lib.resolver.circularDependency(i));if(o>10)throw new s(`[envx:error] Max resolution depth exceeded while resolving "${i}".`);t.add(i);let a=e,l;for(;typeof a=="string";){if(l=a,ne(a)){a=Se(a,n,r,t,o+1);continue}if(re(a)){a=ye(a,n,r,t,o+1);continue}if(a===l)break}return t.delete(i),a}function ye(e,n,r,t,i){return e.replace(/\${([^}]+)}/g,(o,u)=>{let a=u.trim();return String(ie(a,n,r,t,i))})}function Se(e,n,r,t,i){let u=(e?.trim()).match(y);if(!u)return e;let[,a,l,,f,,p,,E]=u,x=a?.trim(),g=ie(x,n,r,t,i,"ternary"),d=f?.trim();(d?.startsWith('"')&&d?.endsWith('"')||d?.startsWith("'")&&d?.endsWith("'"))&&(d=d.slice(1,-1));let Ee=String(g),w;if(l==="=="||l==="!="){let k=Ee===d;w=l==="=="?k:!k;}else w=v(g);let ve=p.trim(),he=E.trim();return te(w?ve:he)}function te(e){return e==="true"?true:e==="false"?false:isNaN(Number(e))?e:Number(e)}var b="envx.meta.json",A="envx.config.json",se=".env",N=".envx";function le(e){let n=e??I__default.default.join(process.cwd(),b);if(!ae__default.default.existsSync(n))throw new Error(`Meta file not found at ${n}`);let r=ae__default.default.readFileSync(n,"utf-8");try{return JSON.parse(r)}catch(t){throw new Error(`Invalid JSON in ${n}: ${t.message}`)}}var h={input:"./.envx",outputs:{env:"./.env",types:"./types/envx.ts",metaFilePath:"."},overwrite:false};function Le(e){return e&&typeof e=="object"&&typeof e.input=="string"&&(e.outputs===void 0||typeof e.outputs=="object"&&(e.outputs.env===void 0||typeof e.outputs.env=="string")&&(e.outputs.types===void 0||typeof e.outputs.types=="string")&&(e.outputs.metaFilePath===void 0||typeof e.outputs.metaFilePath=="string"))&&(typeof e.overwrite=="boolean"||e.overwrite===void 0)}function ue(){let e=I__default.default.resolve(A);if(ae.existsSync(e)){let n=ae.readFileSync(e,"utf-8");try{let r=JSON.parse(n);return Le(r)?{...h,...r,outputs:{...h.outputs,...r.outputs}}:(console.warn("[envx:info:config] Invalid config structure, falling back to default."),h)}catch(r){let t=r instanceof Error?r.message:String(r);return console.warn(`[envx:warn:config] Could not parse ${A}: ${t}`),h}}return h}var $e=["envx"],Ve=e=>{let n=I__default.default.basename(e);if(n===".envx"||n.startsWith(".envx.")||n.endsWith(".envx"))return true;let r=I__default.default.extname(n).replace(/^\./,"");return !!$e.includes(r)};function ce(e){if(!Ve(e)){let n=I__default.default.extname(e).replace(/^\./,"");throw new Error(`[Typenv Error] Unsupported file extension '.${n}'. Please use a '.envx' file or a valid variant such as '.envx.local'.`)}}var F=ue();function pe(e){try{if(!ae__default.default.existsSync(e))throw new s(c.lib.fileDoesNotExist(e));return ae__default.default.readFileSync(e,"utf-8")}catch(n){let r=n instanceof Error?n.message:String(n);throw new s(`Failed to read file at ${e}: ${r}`)}}function Me(e=se){let n=I__default.default.join(F?.outputs?.metaFilePath||".",b),r=I__default.default.resolve(process.cwd(),n),t=F?.outputs?.env||e,i=V(t),o=pe(i),u;try{u=le(r);}catch(l){let f=l instanceof Error?l.message:String(l);throw new s(`Failed to parse meta schema file: ${f}`)}return S(o,u).result}function de(e=N,n){let r=F?.input||e,t=V(r);ce(t);let i=pe(t);return S(i,n).result}function Te(e=N,n){let r=de(e,n);return Object.entries(r).forEach(([t,i])=>{process.env[t]=String(i);}),r}exports.EnvxError=s;exports.getEnv=Me;exports.getEnvx=de;exports.loadEnvx=Te;//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map