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.

6 lines 10.7 kB
'use strict';var y=require('fs'),g=require('path');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var y__default=/*#__PURE__*/_interopDefault(y);var g__default=/*#__PURE__*/_interopDefault(g);var M=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(n,r)=>(typeof require<"u"?require:n)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var s=class extends Error{constructor(n){super(n),this.name="EnvxError";}};var T={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=>`Failed to resolve variable "${e}". No value found for interpolation.`,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 a={lib:T};var F=["string","number","boolean","enum","email","url"],b={};function k(e){let n=e.split(/\r?\n/),r=[],t={},i=null,o=null,c=[];for(let l=0;l<n.length;l++){let u=n[l],f=u.indexOf("#");f!=-1&&(u=u.slice(0,f));let m=u.trim();if(!m||m.startsWith("#"))continue;if(o){m.endsWith('"""')?(c.push(m.slice(0,-3)),r.push({key:o,value:c.join(` `)}),o=null,c=[]):c.push(u);continue}if(K(m)){if(f>-1&&f>u.indexOf("]"))throw new s(`[envx:error] Line ${l+1}: Schema header line cannot contain inline comments.`);i=W(m,l,t);continue}if(i){H(m,l,t[i],()=>(l++,l>=n.length?null:n[l].trim()));continue}let{key:p,value:v,isMultilineStart:h}=X(m,l);h?(o=p,c.push(v)):r.push({key:p,value:v});}return {env:r,schema:t}}function W(e,n,r){let t=e.slice(1,-1).trim();if(!t)throw new s(a.lib.parser.schemaBlockEmpty(n));if(!/^[A-Za-z0-9_-]+$/.test(t))throw new s(`[envx:error] Line ${n+1}: Schema block name "${t}" contains invalid characters. Only letters, numbers, underscore and hyphen are allowed.`);if(r[t])throw new s(a.lib.parser.schemaKeyDuplicate(n,t));return r[t]=r[t]??{},t}function H(e,n,r,t){let[i,o]=_(e,n),c=i.trim(),l=N(o.trim());if(c==="description"&&o.trim().startsWith('"""')){let u=[],f=o.trim().slice(3);if(f.endsWith('"""')){f=f.slice(0,-3),r.description=f;return}for(u.push(f);t;){let m=t();if(m===null)throw new s(`Line ${n+1}: Unterminated multiline description.`);if(m.endsWith('"""')){u.push(m.slice(0,-3));break}else u.push(m);}r.description=u.join(` `);return}switch(c){case "required":r.required=l==="true";break;case "type":if(r.type!==void 0)throw new s(a.lib.parser.typeAlreadyDefined(n));if(!F.includes(l))throw new s(a.lib.unsupportedType(n,l));r.type=l;break;case "default":z(l,n,r);break;case "values":try{let u=JSON.parse(l);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(a.lib.parser.invalidValuesJson(n))}break;case "deprecated":r.deprecated=l;break;case "description":r.description=l;break;default:throw new s(a.lib.parser.unknownSchemaProperty(n,c))}}function K(e){return /^\[.*\]$/.test(e)}function z(e,n,r){let{type:t,values:i}=r;if(!t)throw new s(a.lib.parser.typeRequiredBeforeDefault(n));switch(t){case "number":let o=Number(e);if(isNaN(o))throw new s(a.lib.parser.defaultMustBeNumber(n));r.default=o;break;case "boolean":if(e!=="true"&&e!=="false")throw new s(a.lib.parser.defaultMustBeBoolean(n));r.default=e==="true";break;case "enum":if(!i||!i.includes(e))throw new s(a.lib.parser.defaultNotInEnum(n,e));r.default=e;break;default:r.default=e;}}function X(e,n){let[r,t]=_(e,n),i=r.trim();if(!i)throw new s(a.lib.parser.variableNameEmpty(n));let o=t.trim();return o.startsWith('"""')?{key:i,value:o.slice(3),isMultilineStart:true}:{key:i,value:N(o),isMultilineStart:false}}function _(e,n){let r=e.indexOf("=");if(r===-1)throw new s(a.lib.parser.missingDelimiter(n));return [e.slice(0,r),e.slice(r+1)]}function N(e){let n=e[0],r=e[e.length-1];return n==='"'&&r==='"'||n==="'"&&r==="'"?e.slice(1,-1):e}function V(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 I=e=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);function Q(e){return typeof e=="boolean"?"boolean":!isNaN(Number(e))&&e!==""&&e!==null?"number":"string"}function A(e,n){let r={...b,...n};return e.forEach(({key:t,value:i})=>{r[t]||(r[t]={type:Q(i),required:false});}),r}function O(e){return {...b,...e||{}}}function D(e,n,r,t){switch(r){case "string":return n;case "number":{let i=Number(n);if(isNaN(i))throw new s(a.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(a.lib.validator.invalidBoolean(e,n))}case "enum":{if(!t?.length)throw new s(a.lib.validator.missingEnumValues(e));if(!t.includes(n))throw new s(a.lib.validator.invalidEnum(e,n,t));return n}case "email":{if(!I(n))throw new s(a.lib.validator.invalidEmail(e,n));return n}case "url":try{return new URL(n),n}catch{throw new s(a.lib.validator.invalidUrl(e,n))}default:throw new s(a.lib.validator.unsupportedType(e,r))}}function P(e,n){let r={},t=new Map(e.map(({key:i,value:o})=>[i,o]));for(let i in n){let{type:o,required:c,default:l,values:u}=n[i],f=t.get(i);if(f!==void 0){r[i]=D(i,f,o,o==="enum"?u:void 0);continue}if(l!==void 0){r[i]=D(i,String(l),o,o==="enum"?u:void 0);continue}if(c)throw new s(a.lib.validator.requiredMissing(i))}for(let[i,o]of t.entries())i in r||(r[i]=o);return r}function B(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]=w(r[o],r,t,i,o);if(n){for(let o in n)if(n[o].required&&r[o]===void 0)throw new s(a.lib.resolver.requiredMissingInResolve(o))}return t}function w(e,n,r,t,i){if(typeof e!="string")return e;if(t.has(i))throw new s(a.lib.resolver.circularDependency(i));return t.add(i),ee(e)&&(e=ne(e,n,r,t)),Y(e)&&(e=Z(e,n,r,t)),t.delete(i),e}function Y(e){return typeof e=="string"&&e.includes("${")}function Z(e,n,r,t){return e.replace(/\${([^}]+)}/g,(i,o)=>{let c=o.trim();if(r[c]!==void 0)return String(r[c]);if(n[c]!==void 0)return String(w(n[c],n,r,t,c));throw new s(a.lib.resolver.interpolationFailed(c))})}function ee(e){return /^\s*\${[^}]+}(?:\s*(==|!=)\s*"[^"]*")?\s*\?\s*"[^"]*"\s*:\s*"[^"]*"\s*$/.test(e.trim())}function ne(e,n,r,t){let o=e.trim().match(/^\s*\${([^}]+)}(?:\s*(==|!=)\s*"([^"]*)")?\s*\?\s*"([^"]*)"\s*:\s*"([^"]*)"\s*$/);if(!o)return e;let[,c,l,u,f,m]=o,p=c.trim(),v=r[p]!==void 0?r[p]:w(n[p],n,r,t,p),h;if(l==="=="||l==="!="){let S=String(v)===u;h=l==="=="?S:!S;}else h=V(v);return h?f:m}function x(e,n){let{env:r,schema:t}=k(e),i=A(r,t),o=n?{...i,...n}:Object.keys(i).length>0?i:void 0,c=B(r,o);return o?{result:P(Object.entries(c).map(([u,f])=>({key:u,value:f})),o),schema:o}:{result:c,schema:o}}var E=".envx.meta.json",j=".env",$=".envx";function q(e){let n=e??g__default.default.join(process.cwd(),E);if(!y__default.default.existsSync(n))throw new Error(`Meta file not found at ${n}`);let r=y__default.default.readFileSync(n,"utf-8");try{return JSON.parse(r)}catch(t){throw new Error(`Invalid JSON in ${n}: ${t.message}`)}}var L={input:"./.envx",outputs:{env:"./.env",types:"./types/envx.ts",metaFilePath:"."},overwrite:false};function G(){let e="envx.config.js",r=g__default.default.resolve("envx.config.json"),t=g__default.default.resolve(process.cwd(),e);if(y.existsSync(r)){let i=y.readFileSync(r,"utf-8");try{return JSON.parse(i)}catch{return console.warn("[envx:info:config] Failed to parse envx.config.json, using default config."),L}}if(y.existsSync(t))try{return M(t)}catch{return console.warn("[envx:info:config] Failed to load envx.config.js. This file is only supported in CommonJS environments. Please try using 'envx.config.json' or check your project configuration."),L}return L}var R=G();function vn(e=j){let n=g__default.default.join(R?.outputs?.metaFilePath||".",E),r=g__default.default.resolve(process.cwd(),n),t=R?.outputs?.env||e,i=g__default.default.resolve(process.cwd(),t);if(!y__default.default.existsSync(i))throw new s(a.lib.fileDoesNotExist(i));let o=y__default.default.readFileSync(i,{encoding:"utf-8"}),c=q(r);return x(o,c).result}function ie(e=$,n){let r=R?.outputs?.env||e,t=g__default.default.resolve(process.cwd(),r);if(!y__default.default.existsSync(t))throw new s(a.lib.fileDoesNotExist(t));let i=y__default.default.readFileSync(t,{encoding:"utf-8"}),o=O(n);return x(i,o).result}function hn(e=$,n){let r=ie(e,n);return Object.entries(r).forEach(([t,i])=>{process.env[t]=String(i);}),r}exports.getEnv=vn;exports.getEnvx=ie;exports.loadEnvx=hn;//# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map