UNPKG

dotenvxjs

Version:

dotenvx is the official Node.js library for .envx files, offering advanced type validation, intelligent interpolation, and conditional logic. It makes environment management safer, more dynamic, and easier to maintain.

5 lines 8.53 kB
'use strict';var I=require('fs'),j=require('path');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var I__default=/*#__PURE__*/_interopDefault(I);var j__default=/*#__PURE__*/_interopDefault(j);var s=class extends Error{constructor(n){super(n),this.name="EnvError";}};var g={fileDoesNotExist:e=>`[envx:error] The specified file does not exist: ${e}`,unsupportedType:(e,n)=>`[envx:error] 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=>`[envx:error] Circular dependency detected while resolving "${e}". \u2192 Check for variables referencing each other in a loop.`,interpolationFailed:e=>`[envx:error] Failed to resolve variable "${e}". No value found for interpolation.`,requiredMissingInResolve:e=>`[envx:error] 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=>`[envx:error] Line ${e+1}: Schema block name cannot be empty.`,schemaKeyDuplicate:(e,n)=>`[envx:error] Line ${e+1}: Schema key "${n}" is already defined. Duplicate schema definitions are not allowed.`,typeAlreadyDefined:e=>`[envx:error] Line ${e+1}: "type" is already defined for this variable. You cannot redefine it.`,unknownSchemaProperty:(e,n)=>`[envx:error] Line ${e+1}: Unknown schema property "${n}".`,missingDelimiter:e=>`[envx:error] Line ${e+1}: Missing "=" delimiter in assignment.`,variableNameEmpty:e=>`[envx:error] Line ${e+1}: Variable name cannot be empty.`,typeRequiredBeforeDefault:e=>`[envx:error] Line ${e+1}: "type" must be defined before "default".`,defaultMustBeNumber:e=>`[envx:error] Line ${e+1}: Default value must be a valid number.`,defaultMustBeBoolean:e=>`[envx:error] Line ${e+1}: Default value must be "true" or "false".`,defaultNotInEnum:(e,n)=>`[envx:error] Line ${e+1}: Default "${n}" is not in enum values.`,invalidValuesJson:e=>`[envx:error] Line ${e+1}: "values" must be a valid JSON string array.`}};var l={lib:g};var S=["string","number","boolean","enum","email","url"],h={};function w(e){let n=e.split(/\r?\n/),r=[],o={},i=null,t=null,a=[];for(let u=0;u<n.length;u++){let f=n[u],c=f.trim();if(!c||c.startsWith("#"))continue;if(t){c.endsWith('"""')?(a.push(c.slice(0,-3)),r.push({key:t,value:a.join(` `)}),t=null,a=[]):a.push(f);continue}if(O(c)){i=A(c,u,o);continue}if(i){N(c,u,o[i]);continue}let{key:p,value:d,isMultilineStart:v}=P(c,u);v?(t=p,a.push(d)):r.push({key:p,value:d});}return {env:r,schema:o}}function A(e,n,r){let o=e.slice(1,-1).trim();if(!o)throw new s(l.lib.parser.schemaBlockEmpty(n));if(r[o])throw new s(l.lib.parser.schemaKeyDuplicate(n,o));return r[o]=r[o]??{},o}function N(e,n,r){let[o,i]=x(e,n),t=o.trim(),a=$(i.trim());switch(t){case "required":r.required=a==="true";break;case "type":if(r.type!==void 0)throw new s(l.lib.parser.typeAlreadyDefined(n));if(!S.includes(a))throw new s(l.lib.unsupportedType(n,a));r.type=a;break;case "default":q(a,n,r);break;case "values":try{let u=JSON.parse(a);if(!Array.isArray(u)||!u.every(f=>typeof f=="string"))throw new s(`[envx:error] Line ${n+1}: The parsed "values" field must be an array of strings. Please ensure the JSON array contains only string elements.`);r.values=u;}catch{throw new s(l.lib.parser.invalidValuesJson(n))}break;case "deprecated":r.deprecated=a;break;case "description":r.description=a;break;default:throw new s(l.lib.parser.unknownSchemaProperty(n,t))}}function O(e){return /^\[.*\]$/.test(e)}function q(e,n,r){let{type:o,values:i}=r;if(!o)throw new s(l.lib.parser.typeRequiredBeforeDefault(n));switch(o){case "number":let t=Number(e);if(isNaN(t))throw new s(l.lib.parser.defaultMustBeNumber(n));r.default=t;break;case "boolean":if(e!=="true"&&e!=="false")throw new s(l.lib.parser.defaultMustBeBoolean(n));r.default=e==="true";break;case "enum":if(!i||!i.includes(e))throw new s(l.lib.parser.defaultNotInEnum(n,e));r.default=e;break;default:r.default=e;}}function P(e,n){let[r,o]=x(e,n),i=r.trim();if(!i)throw new s(l.lib.parser.variableNameEmpty(n));let t=o.trim();return t.startsWith('"""')?{key:i,value:t.slice(3),isMultilineStart:true}:{key:i,value:$(t),isMultilineStart:false}}function x(e,n){let r=e.indexOf("=");if(r===-1)throw new s(l.lib.parser.missingDelimiter(n));return [e.slice(0,r),e.slice(r+1)]}function $(e){let n=e[0],r=e[e.length-1];return n==='"'&&r==='"'||n==="'"&&r==="'"?e.slice(1,-1):e}function R(e){if(typeof e=="boolean")return e;if(typeof e=="string"){if(e.toLowerCase()==="true")return true;if(e.toLowerCase()==="false")return false}return typeof e=="number"?e===1:false}var M=e=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);function _(e){return typeof e=="boolean"?"boolean":!isNaN(Number(e))&&e!==""&&e!==null?"number":"string"}function L(e,n){let r={...h,...n};return e.forEach(({key:o,value:i})=>{r[o]||(r[o]={type:_(i),required:false});}),r}function k(e){return {...h,...e||{}}}function T(e,n,r,o){switch(r){case "string":return n;case "number":{let i=Number(n);if(isNaN(i))throw new s(l.lib.validator.invalidNumber(e,n));return i}case "boolean":{let i=n.trim().toLowerCase();if(i==="true")return true;if(i==="false")return false;throw new s(l.lib.validator.invalidBoolean(e,n))}case "enum":{if(!o?.length)throw new s(l.lib.validator.missingEnumValues(e));if(!o.includes(n))throw new s(l.lib.validator.invalidEnum(e,n,o));return n}case "email":{if(!M(n))throw new s(l.lib.validator.invalidEmail(e,n));return n}case "url":try{return new URL(n),n}catch{throw new s(l.lib.validator.invalidUrl(e,n))}default:throw new s(l.lib.validator.unsupportedType(e,r))}}function V(e,n){let r={},o=new Map(e.map(({key:i,value:t})=>[i,t]));for(let i in n){let{type:t,required:a,default:u,values:f}=n[i],c=o.get(i);if(c!==void 0){r[i]=T(i,c,t,t==="enum"?f:void 0);continue}if(u!==void 0){r[i]=T(i,String(u),t,t==="enum"?f:void 0);continue}if(a)throw new s(l.lib.validator.requiredMissing(i))}for(let[i,t]of o.entries())i in r||(r[i]=t);return r}function B(e,n){let r={},o={};for(let t of e)r[t.key]=t.value;if(n)for(let t in n)r[t]===void 0&&n[t].default!==void 0&&(r[t]=n[t].default);let i=new Set;for(let t of Object.keys(r))o[t]=b(r[t],r,o,i,t);if(n){for(let t in n)if(n[t].required&&r[t]===void 0)throw new s(l.lib.resolver.requiredMissingInResolve(t))}return o}function b(e,n,r,o,i){if(typeof e!="string")return e;if(o.has(i))throw new s(l.lib.resolver.circularDependency(i));return o.add(i),C(e)&&(e=G(e,n,r,o)),U(e)&&(e=F(e,n,r,o)),o.delete(i),e}function U(e){return typeof e=="string"&&e.includes("${")}function F(e,n,r,o){return e.replace(/\${([^}]+)}/g,(i,t)=>{let a=t.trim();if(r[a]!==void 0)return String(r[a]);if(n[a]!==void 0)return String(b(n[a],n,r,o,a));throw new s(l.lib.resolver.interpolationFailed(a))})}function C(e){return /^\s*\${[^}]+}(?:\s*(==|!=)\s*"[^"]*")?\s*\?\s*"[^"]*"\s*:\s*"[^"]*"\s*$/.test(e.trim())}function G(e,n,r,o){let t=e.trim().match(/^\s*\${([^}]+)}(?:\s*(==|!=)\s*"([^"]*)")?\s*\?\s*"([^"]*)"\s*:\s*"([^"]*)"\s*$/);if(!t)return e;let[,a,u,f,c,p]=t,d=a.trim(),v=r[d]!==void 0?r[d]:b(n[d],n,r,o,d),E;if(u==="=="||u==="!="){let y=String(v)===f;E=u==="=="?y:!y;}else E=R(v);return E?c:p}function D(e,n){let{env:r,schema:o}=w(e),i=L(r,o),t=n?{...i,...n}:Object.keys(i).length>0?i:void 0,a=B(r,t);return t?{result:V(Object.entries(a).map(([f,c])=>({key:f,value:c})),t),schema:t}:{result:a,schema:t}}function J(e=".envx",n){let r=j__default.default.resolve(process.cwd(),e);if(!I__default.default.existsSync(r))throw new s(l.lib.fileDoesNotExist(r));let o=I__default.default.readFileSync(r,{encoding:"utf-8"}),i=k(n);return D(o,i).result}function _e(e=".envx",n){let r=J(e,n);return Object.entries(r).forEach(([o,i])=>{process.env[o]=String(i);}),r}exports.getEnvx=J;exports.loadEnvx=_e;//# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map