@stacksjs/env 0.74.32 → 0.74.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.d.ts CHANGED
@@ -54,6 +54,33 @@ export declare function envKeyNames(file?: string): { publicKeyName: string, pri
54
54
  * With no ciphertext there is nothing to stay consistent with, so a fresh
55
55
  * keypair is both safe and correct.
56
56
  */
57
+ /**
58
+ * Every public-key name a file may legitimately declare, in preference order.
59
+ *
60
+ * `dotenvx` accepts both the suffixed `DOTENV_PUBLIC_KEY_<ENV>` and the plain
61
+ * `DOTENV_PUBLIC_KEY`, and real projects use the plain form. Looking only for
62
+ * the suffixed name meant a file declaring the plain one appeared to have no
63
+ * key at all, so a fresh keypair was generated, a SECOND declaration was
64
+ * prepended, and every value already encrypted under the original key was
65
+ * stranded (stacksjs/stacks#2489).
66
+ */
67
+ export declare function envPublicKeyNames(file?: string): string[];
68
+ /** Likewise for the private half. */
69
+ export declare function envPrivateKeyNames(file?: string): string[];
70
+ /**
71
+ * Does this file already hold ciphertext, under any key name?
72
+ *
73
+ * The witness that makes rotation unsafe. If ANY value is encrypted, some key
74
+ * out there decrypts it, and generating a new one strands those values whether
75
+ * or not we recognise the name their public key was declared under. Deliberately
76
+ * name-agnostic: the name is exactly what the previous guards got wrong.
77
+ */
78
+ export declare function envHasCiphertext(envContent: string): boolean;
79
+ /**
80
+ * The public key an env file declares, whichever accepted name it uses, plus
81
+ * that name so callers write back to the same line instead of adding a second.
82
+ */
83
+ export declare function declaredEnvPublicKey(envContent: string, file?: string): { name: string, key: string } | undefined;
57
84
  export declare function reusableEnvPublicKey(envContent: string, publicKeyName: string): string | undefined;
58
85
  /**
59
86
  * Encrypt .env file
package/dist/cli.js CHANGED
@@ -1,28 +1,32 @@
1
1
  // @bun
2
- import{existsSync as w,readFileSync as K,renameSync as Q,rmSync as ee,writeFileSync as b}from"fs";import{basename as te,dirname as ne,resolve as k}from"path";import{createCipheriv as U,createDecipheriv as L,createHash as W,createPrivateKey as ae,createPublicKey as j,diffieHellman as X,generateKeyPairSync as H,hkdfSync as J,randomBytes as B}from"crypto";var I="x25519-public:",S="x25519-private:",D="encrypted:v2:",Y="encrypted:",M=Buffer.from("stacks-env:v2","utf8"),z="Environment decryption failed: authentication or format error";function G(t){if(t.length===32)return t;return W("sha256").update(t).digest()}function Fe(t,n){let e=B(16),s=U("aes-256-gcm",G(n),e);return{ciphertext:Buffer.concat([s.update(t,"utf8"),s.final()]).toString("hex"),iv:e.toString("hex"),authTag:s.getAuthTag().toString("hex")}}function ue(t,n,e,s){try{let r=L("aes-256-gcm",G(n),Buffer.from(e,"hex"));return r.setAuthTag(Buffer.from(s,"hex")),Buffer.concat([r.update(Buffer.from(t,"hex")),r.final()]).toString("utf8")}catch{throw Error("Decryption failed: authentication or format error")}}function _(t){return t.toString("base64url")}function x(t,n,e){if(typeof t!=="string"||t.length>0&&!/^[A-Za-z0-9_-]+$/.test(t))throw Error(`${n} is not canonical base64url`);let s=Buffer.from(t,"base64url");if(_(s)!==t)throw Error(`${n} is not canonical base64url`);if(e!==void 0&&s.length!==e)throw Error(`${n} has an invalid length`);return s}function fe(t){if(!t.startsWith(I))throw Error("Legacy or invalid public key. Run buddy env:rotate before creating new ciphertext.");let n=j({key:x(t.slice(I.length),"public key"),format:"der",type:"spki"});if(n.asymmetricKeyType!=="x25519")throw Error("Public key is not X25519");return n}function le(t){if(!t.startsWith(S))throw Error("Private key is not a version 2 X25519 key");let n=ae({key:x(t.slice(S.length),"private key"),format:"der",type:"pkcs8"});if(n.asymmetricKeyType!=="x25519")throw Error("Private key is not X25519");return n}function q(t){return Buffer.from(`stacks-env:v2;${t.epk};${t.salt};${t.nonce}`,"utf8")}function V(){let{publicKey:t,privateKey:n}=H("x25519"),e=t.export({format:"der",type:"spki"}),s=n.export({format:"der",type:"pkcs8"});return{publicKey:`${I}${_(e)}`,privateKey:`${S}${_(s)}`}}function F(t,n){let e=fe(n),s=H("x25519"),r=_(s.publicKey.export({format:"der",type:"spki"})),i=B(16),c=B(12),a=X({privateKey:s.privateKey,publicKey:e}),u=Buffer.from(J("sha256",a,i,M,32)),f={epk:r,salt:_(i),nonce:_(c)};try{let o=U("aes-256-gcm",u,c);o.setAAD(q(f));let l=Buffer.concat([o.update(t,"utf8"),o.final()]),d={v:2,...f,ciphertext:_(l),tag:_(o.getAuthTag())};return`${D}${_(Buffer.from(JSON.stringify(d),"utf8"))}`}finally{a.fill(0),u.fill(0)}}function pe(t){let n=x(t.slice(D.length),"envelope").toString("utf8"),e=JSON.parse(n);if(!e||typeof e!=="object"||Array.isArray(e))throw Error("envelope is not an object");let s=Object.keys(e).sort(),r=["ciphertext","epk","nonce","salt","tag","v"];if(s.length!==r.length||s.some((i,c)=>i!==r[c]))throw Error("envelope fields are invalid");if(e.v!==2)throw Error("envelope version is unsupported");for(let i of["epk","salt","nonce","ciphertext","tag"])if(typeof e[i]!=="string")throw Error(`${i} is invalid`);return e}function de(t,n){try{let e=pe(t),s=le(n),r=j({key:x(e.epk,"ephemeral public key"),format:"der",type:"spki"});if(r.asymmetricKeyType!=="x25519")throw Error("ephemeral key is not X25519");let i=x(e.salt,"salt",16),c=x(e.nonce,"nonce",12),a=x(e.ciphertext,"ciphertext"),u=x(e.tag,"tag",16),f=X({privateKey:s,publicKey:r}),o=Buffer.from(J("sha256",f,i,M,32));try{let l=L("aes-256-gcm",o,c);return l.setAAD(q(e)),l.setAuthTag(u),Buffer.concat([l.update(a),l.final()]).toString("utf8")}finally{f.fill(0),o.fill(0)}}catch{throw Error(z)}}function ye(t,n){try{if(!/^[0-9a-f]{64}$/.test(n))throw Error("invalid legacy private key");let e=Buffer.from(t.slice(Y.length),"base64");if(e.length<32)throw Error("invalid legacy payload");let s=W("sha256").update(Buffer.from(n,"hex")).digest(),r=W("sha256").update(s).digest();return ue(e.subarray(32).toString("hex"),r,e.subarray(0,16).toString("hex"),e.subarray(16,32).toString("hex"))}catch{throw Error(z)}}function Re(t){return t.startsWith(Y)&&!t.startsWith(D)}function O(t,n){if(!t.startsWith(Y))return t;return t.startsWith(D)?de(t,n):ye(t,n)}function Ce(t,n,e){return F(O(t,n),e)}function We(t){let n=t.match(/^DOTENV_PRIVATE_KEY_(.+)$/);return n&&n[1]?n[1].toLowerCase():""}function Be(t=""){return t?process.env[`DOTENV_PRIVATE_KEY_${t.toUpperCase()}`]:process.env.DOTENV_PRIVATE_KEY}import{spawnSync as ge}from"child_process";import{readFileSync as he}from"fs";import{arch as me,hostname as ve,platform as Z,release as Ee,userInfo as $e}from"os";import{basename as ke,dirname as Ke,resolve as we}from"path";function P(t,n={}){let e={},s=[],r=[],i=t.split(`
3
- `);for(let c of i){let a=c.trim();if(!a||a.startsWith("#"))continue;if(a.startsWith("DOTENV_PUBLIC_KEY=")){let l=a.match(/^DOTENV_PUBLIC_KEY=["']?([^"'\n]+)["']?/);if(l&&l[1]!==void 0)e.DOTENV_PUBLIC_KEY=l[1];continue}let u=a.match(/^([^=]+)=(.*)$/);if(!u||u[1]===void 0||u[2]===void 0)continue;let f=u[1].trim(),o=u[2].trim();if(o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'")){if(o=o.slice(1,-1),o.includes("\\n"))o=o.replace(/\\n/g,`
4
- `)}if(o.startsWith("encrypted:")||o.startsWith("enc:")){if(!n.privateKey){r.push(f);continue}try{let l=o.startsWith("enc:")?`encrypted:${o.slice(4)}`:o;o=O(l,n.privateKey)}catch(l){s.push(`Failed to decrypt ${f}: ${l instanceof Error?l.message:"Unknown error"}`)}}o=be(o,{...n.processEnv||process.env,...e}),o=Pe(o),e[f]=o}return{parsed:e,errors:s,skippedEncrypted:r}}function be(t,n){return t.replace(/\$\{([^}]+)\}/g,(e,s)=>{let r=s.match(/^([^:\-+]+)(:-|-)(.+)$/);if(r){let[,c,a,u]=r,f=n[c];if(a===":-")return f||u;else return f!==void 0?f:u}let i=s.match(/^([^:\-+]+)(:?\+)(.+)$/);if(i){let[,c,a,u]=i,f=n[c];if(a===":+")return f?u:"";else return f!==void 0?u:""}return n[s]||""})}var Ne=new Set(["date","hostname","whoami","uname","pwd","echo","printf","cat","basename","dirname"]);function _e(t){let n=[],e="",s=null,r=!1;for(let i of t.trim()){if(r){e+=i,r=!1;continue}if(i==="\\"&&s!=="'"){r=!0;continue}if(s){if(i===s)s=null;else e+=i;continue}if(i==='"'||i==="'"){s=i;continue}if(/\s/.test(i)){if(e)n.push(e),e="";continue}e+=i}if(r||s)throw Error("Command substitution contains an unterminated escape or quote");if(e)n.push(e);return n}function xe(t){let[n,...e]=t,s=e.some((r)=>r.startsWith("-"));if(n==="echo"&&!s)return e.join(" ");if(n==="printf"&&e.length===1&&!e[0]?.includes("%"))return e[0];if(n==="hostname"&&e.length===0)return ve();if(n==="whoami"&&e.length===0)return $e().username;if(n==="pwd"&&e.length===0)return process.cwd();if(n==="basename"&&e.length===1)return ke(e[0]??"");if(n==="dirname"&&e.length===1)return Ke(e[0]??"");if(n==="cat"&&e.length>0&&!s)return e.map((r)=>he(we(process.cwd(),r),"utf8")).join("");if(n==="uname"){let r=e[0]??"-s";if(e.length<=1&&r==="-m")return me();if(e.length<=1&&r==="-r")return Ee();if(e.length<=1&&r==="-s")return{aix:"AIX",android:"Android",cygwin:"CYGWIN",darwin:"Darwin",freebsd:"FreeBSD",haiku:"Haiku",linux:"Linux",netbsd:"NetBSD",openbsd:"OpenBSD",sunos:"SunOS",win32:"Windows_NT"}[Z()]??Z()}return}function Pe(t){return t.replace(/\$\(([^)]+)\)/g,(n,e)=>{try{let s=_e(e),r=s[0];if(!r||!Ne.has(r))return console.warn(`[env] Blocked command substitution for disallowed command: ${r}`),"";let i=xe(s);if(i!==void 0)return i.trim();let c=ge(r,s.slice(1),{encoding:"utf8",env:process.env});if(c.status===0)return c.stdout.trim();let a=c.stderr.trim();console.warn(`[env] Command substitution failed (exit code ${c.status??"unknown"}): ${r}${a?`: ${a}`:""}`)}catch(s){console.warn(`[env] Command substitution error: ${s instanceof Error?s.message:String(s)}`)}return""})}async function je(t,n={}){let e={},s=[],r=[];for(let i of t)try{let c=Bun.file(i);if(!c.size)continue;let a=await c.text(),{parsed:u,errors:f,skippedEncrypted:o}=P(a,n);s.push(...f),r.push(...o);for(let[l,d]of Object.entries(u)){if(!n.overload&&e[l]!==void 0)continue;e[l]=d}}catch(c){if(c?.code==="ENOENT")continue;s.push(`Failed to read ${i}: ${c instanceof Error?c.message:String(c)}`)}return{parsed:e,errors:s,skippedEncrypted:r}}function Ge(t,n){if(t)return t;let e=String(n??"").trim();if(!e||e==="development"||e==="dev"||e==="local")return"";if(!/^[\w.-]+$/.test(e))return"";return`.env.${e}`}function re(t,n){return(!n.key||t.includes(n.key))&&(!n.excludeKey||!t.includes(n.excludeKey))}function Ve(t,n){let e=[];for(let s of t.split(`
5
- `)){let r=s.trim();if(!r||r.startsWith("#"))continue;if(r.startsWith("DOTENV_PUBLIC_KEY"))continue;let i=r.match(/^([^=]+)=(.*)$/);if(!i||i[1]===void 0)continue;let c=i[1].trim();if(re(c,n))e.push(c)}return e}function se(t,n,e,s){let r=["#/-------------------[DOTENV_PUBLIC_KEY]--------------------/","#/ versioned X25519 encryption for .env files /","#/ [how it works](https://stacksjs.com/encryption) /","#/----------------------------------------------------------/",`${e}="${n}"`,""],i=!1;for(let c of t.split(`
6
- `)){let a=c.trim();if(a.startsWith("#/"))continue;if(a.startsWith("DOTENV_PUBLIC_KEY"))continue;if(!a&&!i)continue;if(!a||a.startsWith("#")){i=!0,r.push(c);continue}i=!0;let u=a.match(/^([^=]+)=(.*)$/);if(!u||u[1]===void 0||u[2]===void 0){r.push(c);continue}let f=u[1].trim(),o=u[2].trim();if(o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'"))o=o.slice(1,-1);if(re(f,s)&&!o.startsWith("encrypted:"))o=F(o,n);r.push(`${f}="${o}"`)}return r.join(`
7
- `)}function T(t){let e=((t||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase();return{publicKeyName:e?`DOTENV_PUBLIC_KEY_${e}`:"DOTENV_PUBLIC_KEY",privateKeyName:e?`DOTENV_PRIVATE_KEY_${e}`:"DOTENV_PRIVATE_KEY"}}function ie(t,n){let e,s=!1;for(let r of t.split(`
8
- `)){let i=r.trim();if(!i||i.startsWith("#"))continue;let c=i.match(/^([^=]+)=(.*)$/);if(!c?.[1]||c[2]===void 0)continue;let a=c[1].trim(),u=c[2].trim().replace(/^["']|["']$/g,"");if(a===n)e=u;else if(u.startsWith("encrypted:")||u.startsWith("enc:"))s=!0}return e&&s?e:void 0}function qe(t={}){let n=t.cwd||process.cwd(),e=k(n,t.file||".env"),s=k(n,t.keysFile||".env.keys");if(!w(e))return{success:!1,error:`File not found: ${e}`};try{let r,i,c=ie(K(e,"utf-8"),T(t.file).publicKeyName);if(c)r=c;else if(w(s)){let f=K(s,"utf-8"),{parsed:o}=P(f),{publicKeyName:l,privateKeyName:d}=T(t.file);if(r=o[l]||"",i=o[d]||"",!r||!i){let g=V();r=g.publicKey,i=g.privateKey;let y=`
2
+ import{existsSync as K,readFileSync as k,renameSync as ne,rmSync as re,writeFileSync as b}from"fs";import{basename as se,dirname as j,resolve as E}from"path";import{createCipheriv as X,createDecipheriv as H,createHash as I,createPrivateKey as fe,createPublicKey as G,diffieHellman as J,generateKeyPairSync as M,hkdfSync as z,randomBytes as S}from"crypto";var Y="x25519-public:",A="x25519-private:",C="encrypted:v2:",U="encrypted:",q=Buffer.from("stacks-env:v2","utf8"),Z="Environment decryption failed: authentication or format error";function Q(t){if(t.length===32)return t;return I("sha256").update(t).digest()}function Be(t,n){let e=S(16),s=X("aes-256-gcm",Q(n),e);return{ciphertext:Buffer.concat([s.update(t,"utf8"),s.final()]).toString("hex"),iv:e.toString("hex"),authTag:s.getAuthTag().toString("hex")}}function le(t,n,e,s){try{let r=H("aes-256-gcm",Q(n),Buffer.from(e,"hex"));return r.setAuthTag(Buffer.from(s,"hex")),Buffer.concat([r.update(Buffer.from(t,"hex")),r.final()]).toString("utf8")}catch{throw Error("Decryption failed: authentication or format error")}}function x(t){return t.toString("base64url")}function V(t,n,e){if(typeof t!=="string"||t.length>0&&!/^[A-Za-z0-9_-]+$/.test(t))throw Error(`${n} is not canonical base64url`);let s=Buffer.from(t,"base64url");if(x(s)!==t)throw Error(`${n} is not canonical base64url`);if(e!==void 0&&s.length!==e)throw Error(`${n} has an invalid length`);return s}function pe(t){if(!t.startsWith(Y))throw Error("Legacy or invalid public key. Run buddy env:rotate before creating new ciphertext.");let n=G({key:V(t.slice(Y.length),"public key"),format:"der",type:"spki"});if(n.asymmetricKeyType!=="x25519")throw Error("Public key is not X25519");return n}function de(t){if(!t.startsWith(A))throw Error("Private key is not a version 2 X25519 key");let n=fe({key:V(t.slice(A.length),"private key"),format:"der",type:"pkcs8"});if(n.asymmetricKeyType!=="x25519")throw Error("Private key is not X25519");return n}function ee(t){return Buffer.from(`stacks-env:v2;${t.epk};${t.salt};${t.nonce}`,"utf8")}function F(){let{publicKey:t,privateKey:n}=M("x25519"),e=t.export({format:"der",type:"spki"}),s=n.export({format:"der",type:"pkcs8"});return{publicKey:`${Y}${x(e)}`,privateKey:`${A}${x(s)}`}}function W(t,n){let e=pe(n),s=M("x25519"),r=x(s.publicKey.export({format:"der",type:"spki"})),i=S(16),o=S(12),a=J({privateKey:s.privateKey,publicKey:e}),u=Buffer.from(z("sha256",a,i,q,32)),f={epk:r,salt:x(i),nonce:x(o)};try{let c=X("aes-256-gcm",u,o);c.setAAD(ee(f));let l=Buffer.concat([c.update(t,"utf8"),c.final()]),p={v:2,...f,ciphertext:x(l),tag:x(c.getAuthTag())};return`${C}${x(Buffer.from(JSON.stringify(p),"utf8"))}`}finally{a.fill(0),u.fill(0)}}function ye(t){let n=V(t.slice(C.length),"envelope").toString("utf8"),e=JSON.parse(n);if(!e||typeof e!=="object"||Array.isArray(e))throw Error("envelope is not an object");let s=Object.keys(e).sort(),r=["ciphertext","epk","nonce","salt","tag","v"];if(s.length!==r.length||s.some((i,o)=>i!==r[o]))throw Error("envelope fields are invalid");if(e.v!==2)throw Error("envelope version is unsupported");for(let i of["epk","salt","nonce","ciphertext","tag"])if(typeof e[i]!=="string")throw Error(`${i} is invalid`);return e}function ge(t,n){try{let e=ye(t),s=de(n),r=G({key:V(e.epk,"ephemeral public key"),format:"der",type:"spki"});if(r.asymmetricKeyType!=="x25519")throw Error("ephemeral key is not X25519");let i=V(e.salt,"salt",16),o=V(e.nonce,"nonce",12),a=V(e.ciphertext,"ciphertext"),u=V(e.tag,"tag",16),f=J({privateKey:s,publicKey:r}),c=Buffer.from(z("sha256",f,i,q,32));try{let l=H("aes-256-gcm",c,o);return l.setAAD(ee(e)),l.setAuthTag(u),Buffer.concat([l.update(a),l.final()]).toString("utf8")}finally{f.fill(0),c.fill(0)}}catch{throw Error(Z)}}function he(t,n){try{if(!/^[0-9a-f]{64}$/.test(n))throw Error("invalid legacy private key");let e=Buffer.from(t.slice(U.length),"base64");if(e.length<32)throw Error("invalid legacy payload");let s=I("sha256").update(Buffer.from(n,"hex")).digest(),r=I("sha256").update(s).digest();return le(e.subarray(32).toString("hex"),r,e.subarray(0,16).toString("hex"),e.subarray(16,32).toString("hex"))}catch{throw Error(Z)}}function Ie(t){return t.startsWith(U)&&!t.startsWith(C)}function R(t,n){if(!t.startsWith(U))return t;return t.startsWith(C)?ge(t,n):he(t,n)}function Se(t,n,e){return W(R(t,n),e)}function Ye(t){let n=t.match(/^DOTENV_PRIVATE_KEY_(.+)$/);return n&&n[1]?n[1].toLowerCase():""}function Ae(t=""){return t?process.env[`DOTENV_PRIVATE_KEY_${t.toUpperCase()}`]:process.env.DOTENV_PRIVATE_KEY}import{spawnSync as me}from"child_process";import{readFileSync as ve}from"fs";import{arch as Ee,hostname as $e,platform as te,release as ke,userInfo as Ke}from"os";import{basename as we,dirname as be,resolve as Ne}from"path";function T(t,n={}){let e={},s=[],r=[],i=t.split(`
3
+ `);for(let o of i){let a=o.trim();if(!a||a.startsWith("#"))continue;if(a.startsWith("DOTENV_PUBLIC_KEY=")){let l=a.match(/^DOTENV_PUBLIC_KEY=["']?([^"'\n]+)["']?/);if(l&&l[1]!==void 0)e.DOTENV_PUBLIC_KEY=l[1];continue}let u=a.match(/^([^=]+)=(.*)$/);if(!u||u[1]===void 0||u[2]===void 0)continue;let f=u[1].trim(),c=u[2].trim();if(c.startsWith('"')&&c.endsWith('"')||c.startsWith("'")&&c.endsWith("'")){if(c=c.slice(1,-1),c.includes("\\n"))c=c.replace(/\\n/g,`
4
+ `)}if(c.startsWith("encrypted:")||c.startsWith("enc:")){if(!n.privateKey){r.push(f);continue}try{let l=c.startsWith("enc:")?`encrypted:${c.slice(4)}`:c;c=R(l,n.privateKey)}catch(l){s.push(`Failed to decrypt ${f}: ${l instanceof Error?l.message:"Unknown error"}`)}}c=_e(c,{...n.processEnv||process.env,...e}),c=Te(c),e[f]=c}return{parsed:e,errors:s,skippedEncrypted:r}}function _e(t,n){return t.replace(/\$\{([^}]+)\}/g,(e,s)=>{let r=s.match(/^([^:\-+]+)(:-|-)(.+)$/);if(r){let[,o,a,u]=r,f=n[o];if(a===":-")return f||u;else return f!==void 0?f:u}let i=s.match(/^([^:\-+]+)(:?\+)(.+)$/);if(i){let[,o,a,u]=i,f=n[o];if(a===":+")return f?u:"";else return f!==void 0?u:""}return n[s]||""})}var xe=new Set(["date","hostname","whoami","uname","pwd","echo","printf","cat","basename","dirname"]);function Pe(t){let n=[],e="",s=null,r=!1;for(let i of t.trim()){if(r){e+=i,r=!1;continue}if(i==="\\"&&s!=="'"){r=!0;continue}if(s){if(i===s)s=null;else e+=i;continue}if(i==='"'||i==="'"){s=i;continue}if(/\s/.test(i)){if(e)n.push(e),e="";continue}e+=i}if(r||s)throw Error("Command substitution contains an unterminated escape or quote");if(e)n.push(e);return n}function Ve(t){let[n,...e]=t,s=e.some((r)=>r.startsWith("-"));if(n==="echo"&&!s)return e.join(" ");if(n==="printf"&&e.length===1&&!e[0]?.includes("%"))return e[0];if(n==="hostname"&&e.length===0)return $e();if(n==="whoami"&&e.length===0)return Ke().username;if(n==="pwd"&&e.length===0)return process.cwd();if(n==="basename"&&e.length===1)return we(e[0]??"");if(n==="dirname"&&e.length===1)return be(e[0]??"");if(n==="cat"&&e.length>0&&!s)return e.map((r)=>ve(Ne(process.cwd(),r),"utf8")).join("");if(n==="uname"){let r=e[0]??"-s";if(e.length<=1&&r==="-m")return Ee();if(e.length<=1&&r==="-r")return ke();if(e.length<=1&&r==="-s")return{aix:"AIX",android:"Android",cygwin:"CYGWIN",darwin:"Darwin",freebsd:"FreeBSD",haiku:"Haiku",linux:"Linux",netbsd:"NetBSD",openbsd:"OpenBSD",sunos:"SunOS",win32:"Windows_NT"}[te()]??te()}return}function Te(t){return t.replace(/\$\(([^)]+)\)/g,(n,e)=>{try{let s=Pe(e),r=s[0];if(!r||!xe.has(r))return console.warn(`[env] Blocked command substitution for disallowed command: ${r}`),"";let i=Ve(s);if(i!==void 0)return i.trim();let o=me(r,s.slice(1),{encoding:"utf8",env:process.env});if(o.status===0)return o.stdout.trim();let a=o.stderr.trim();console.warn(`[env] Command substitution failed (exit code ${o.status??"unknown"}): ${r}${a?`: ${a}`:""}`)}catch(s){console.warn(`[env] Command substitution error: ${s instanceof Error?s.message:String(s)}`)}return""})}async function Je(t,n={}){let e={},s=[],r=[];for(let i of t)try{let o=Bun.file(i);if(!o.size)continue;let a=await o.text(),{parsed:u,errors:f,skippedEncrypted:c}=T(a,n);s.push(...f),r.push(...c);for(let[l,p]of Object.entries(u)){if(!n.overload&&e[l]!==void 0)continue;e[l]=p}}catch(o){if(o?.code==="ENOENT")continue;s.push(`Failed to read ${i}: ${o instanceof Error?o.message:String(o)}`)}return{parsed:e,errors:s,skippedEncrypted:r}}function et(t,n){if(t)return t;let e=String(n??"").trim();if(!e||e==="development"||e==="dev"||e==="local")return"";if(!/^[\w.-]+$/.test(e))return"";return`.env.${e}`}function oe(t,n){return(!n.key||t.includes(n.key))&&(!n.excludeKey||!t.includes(n.excludeKey))}function Oe(t,n){let e=[];for(let s of t.split(`
5
+ `)){let r=s.trim();if(!r||r.startsWith("#"))continue;if(r.startsWith("DOTENV_PUBLIC_KEY"))continue;let i=r.match(/^([^=]+)=(.*)$/);if(!i||i[1]===void 0)continue;let o=i[1].trim();if(oe(o,n))e.push(o)}return e}function ce(t,n,e,s){let r=["#/-------------------[DOTENV_PUBLIC_KEY]--------------------/","#/ versioned X25519 encryption for .env files /","#/ [how it works](https://stacksjs.com/encryption) /","#/----------------------------------------------------------/",`${e}="${n}"`,""],i=!1;for(let o of t.split(`
6
+ `)){let a=o.trim();if(a.startsWith("#/"))continue;if(a.startsWith("DOTENV_PUBLIC_KEY"))continue;if(!a&&!i)continue;if(!a||a.startsWith("#")){i=!0,r.push(o);continue}i=!0;let u=a.match(/^([^=]+)=(.*)$/);if(!u||u[1]===void 0||u[2]===void 0){r.push(o);continue}let f=u[1].trim(),c=u[2].trim();if(c.startsWith('"')&&c.endsWith('"')||c.startsWith("'")&&c.endsWith("'"))c=c.slice(1,-1);if(oe(f,s)&&!c.startsWith("encrypted:"))c=W(c,n);r.push(`${f}="${c}"`)}return r.join(`
7
+ `)}function D(t){let e=((t||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase();return{publicKeyName:e?`DOTENV_PUBLIC_KEY_${e}`:"DOTENV_PUBLIC_KEY",privateKeyName:e?`DOTENV_PRIVATE_KEY_${e}`:"DOTENV_PRIVATE_KEY"}}function ae(t){let{publicKeyName:n}=D(t);return n==="DOTENV_PUBLIC_KEY"?[n]:[n,"DOTENV_PUBLIC_KEY"]}function L(t){let{privateKeyName:n}=D(t);return n==="DOTENV_PRIVATE_KEY"?[n]:[n,"DOTENV_PRIVATE_KEY"]}function ie(t){for(let n of t.split(`
8
+ `)){let e=n.trim();if(!e||e.startsWith("#"))continue;let s=e.match(/^([^=]+)=(.*)$/);if(!s?.[1]||s[2]===void 0)continue;let r=s[2].trim().replace(/^["']|["']$/g,"");if(r.startsWith("encrypted:")||r.startsWith("enc:"))return!0}return!1}function De(t,n){let e=ae(n);for(let s of t.split(`
9
+ `)){let r=s.trim();if(!r||r.startsWith("#"))continue;let i=r.match(/^([^=]+)=["']?([^"'\n]+)["']?/);if(!i?.[1]||!i[2])continue;let o=i[1].trim();if(e.includes(o))return{name:o,key:i[2]}}return}function Fe(t,n){let e,s=!1;for(let r of t.split(`
10
+ `)){let i=r.trim();if(!i||i.startsWith("#"))continue;let o=i.match(/^([^=]+)=(.*)$/);if(!o?.[1]||o[2]===void 0)continue;let a=o[1].trim(),u=o[2].trim().replace(/^["']|["']$/g,"");if(a===n)e=u;else if(u.startsWith("encrypted:")||u.startsWith("enc:"))s=!0}return e&&s?e:void 0}function tt(t={}){let n=t.cwd||process.cwd(),e=E(n,t.file||".env"),s=E(n,t.keysFile||".env.keys");if(!K(e))return{success:!1,error:`File not found: ${e}`};try{let r,i,o=Fe(k(e,"utf-8"),D(t.file).publicKeyName);if(o)r=o;else if(K(s)){let f=k(s,"utf-8"),{parsed:c}=T(f),{publicKeyName:l,privateKeyName:p}=D(t.file);if(r=c[l]||"",i=c[p]||"",!r||!i){let g=F();r=g.publicKey,i=g.privateKey;let d=`
9
11
  ${l}="${r}"
10
- ${d}="${i}"
11
- `;b(s,f+y,"utf-8")}}else{let f=V();r=f.publicKey,i=f.privateKey;let{publicKeyName:o,privateKeyName:l}=T(t.file),d=`# .env.keys - Keep this file secure and never commit to source control
12
- ${o}="${r}"
12
+ ${p}="${i}"
13
+ `;b(s,f+d,"utf-8")}}else{let f=F();r=f.publicKey,i=f.privateKey;let{publicKeyName:c,privateKeyName:l}=D(t.file),p=`# .env.keys - Keep this file secure and never commit to source control
14
+ ${c}="${r}"
13
15
  ${l}="${i}"
14
- `;b(s,d,"utf-8")}let a=K(e,"utf-8"),u=se(a,r,T(t.file).publicKeyName,t);if(t.stdout)return{success:!0,output:u};return b(e,u,"utf-8"),{success:!0,output:`\u2714 encrypted (${t.file||".env"})
15
- \u2714 key added to ${t.keysFile||".env.keys"}`}}catch(r){return{success:!1,error:`Failed to encrypt: ${r instanceof Error?r.message:"Unknown error"}`}}}function Oe(t={}){let n=t.cwd||process.cwd(),e=k(n,t.file||".env"),s=k(n,t.keysFile||".env.keys");if(!w(e))return{success:!1,error:`File not found: ${e}`};if(!w(s))return{success:!1,error:`Keys file not found: ${s}`};try{let r=K(s,"utf-8"),{parsed:i}=P(r),u=((t.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),f=u?`DOTENV_PRIVATE_KEY_${u}`:"DOTENV_PRIVATE_KEY",o=i[f];if(!o)return{success:!1,error:`Private key not found: ${f}`};let l=[o];if(f!=="DOTENV_PRIVATE_KEY"&&i.DOTENV_PRIVATE_KEY&&i.DOTENV_PRIVATE_KEY!==o)l.push(i.DOTENV_PRIVATE_KEY);let g=K(e,"utf-8").split(`
16
- `),y=[];for(let N of g){let p=N.trim();if(!p||p.startsWith("#")){y.push(N);continue}if(p.startsWith("DOTENV_PUBLIC_KEY"))continue;let h=p.match(/^([^=]+)=(.*)$/);if(!h||h[1]===void 0||h[2]===void 0){y.push(N);continue}let v=h[1].trim(),E=h[2].trim();if(E.startsWith('"')&&E.endsWith('"')||E.startsWith("'")&&E.endsWith("'"))E=E.slice(1,-1);let A=E.startsWith("encrypted:");if(t.key&&!v.includes(t.key))A=!1;if(A){let R,C;for(let oe of l)try{R=O(E,oe);break}catch(ce){C=ce}if(R===void 0)throw C instanceof Error?C:Error(`Unable to decrypt ${v}`);E=R}y.push(`${v}="${E}"`)}let m=y.join(`
17
- `);if(t.stdout)return{success:!0,output:m};return b(e,m,"utf-8"),{success:!0,output:`\u2714 decrypted (${t.file||".env"})`}}catch(r){return{success:!1,error:`Failed to decrypt: ${r instanceof Error?r.message:"Unknown error"}`}}}function Ze(t,n,e={}){let s=e.cwd||process.cwd(),r=k(s,e.file||".env"),i=k(s,e.keysFile||".env.keys");try{let c="";if(w(r))c=K(r,"utf-8");let a=c.split(`
18
- `),u=!1,f,d=((e.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),g=d?`DOTENV_PUBLIC_KEY_${d}`:"DOTENV_PUBLIC_KEY",y=d?`DOTENV_PRIVATE_KEY_${d}`:"DOTENV_PRIVATE_KEY";for(let p of a){let h=p.trim();if(h.startsWith(`${g}=`)){let v=h.match(/^[^=]+=["']?([^"'\n]+)["']?/);if(v)f=v[1];break}}if(f){let p=!1;if(w(i)){let h=K(i,"utf-8"),{parsed:v}=P(h);p=Boolean(v[y])}if(!p&&!process.env[y]&&!ie(c,g))f=void 0}if(!e.plain&&!f){let p=V();f=p.publicKey;let h="";if(w(i))h=K(i,"utf-8");h+=`
19
- ${g}="${p.publicKey}"
20
- ${y}="${p.privateKey}"
21
- `,b(i,h,"utf-8");for(let v=a.length-1;v>=0;v--){let E=a[v];if(E!==void 0&&E.trim().startsWith(`${g}=`))a.splice(v,1)}a.unshift(`${g}="${f}"`)}let m=n;if(!e.plain&&f)m=F(n,f);for(let p=0;p<a.length;p++){let h=a[p];if(h===void 0)continue;if(h.trim().startsWith(`${t}=`)){a[p]=`${t}="${m}"`,u=!0;break}}if(!u)a.push(`${t}="${m}"`);let N=a.join(`
22
- `);return b(r,N,"utf-8"),{success:!0,output:`set ${t}${e.plain?"":" with encryption"} (${e.file||".env"})`}}catch(c){return{success:!1,error:`Failed to set: ${c instanceof Error?c.message:"Unknown error"}`}}}function Qe(t,n={}){let e=n.cwd||process.cwd(),s=k(e,n.file||".env");if(!w(s))return{success:!1,error:`File not found: ${s}`};try{let r,i=k(e,n.keysFile||".env.keys"),u=((n.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),f=u?`DOTENV_PRIVATE_KEY_${u}`:"DOTENV_PRIVATE_KEY";if(w(i)){let y=K(i,"utf-8"),{parsed:m}=P(y);r=m[f]}if(!r)r=process.env[f];let o=K(s,"utf-8"),{parsed:l}=P(o,{privateKey:r});if(t&&!n.all){let y=l[t];if(y===void 0)return{success:!1,error:`Key not found: ${t}`};return{success:!0,output:y}}let d=n.all?{...process.env,...l}:l,g;switch(n.format){case"shell":g=Object.entries(d).map(([y,m])=>`${y}=${m}`).join(" ");break;case"eval":g=Object.entries(d).map(([y,m])=>`${y}="${m}"`).join(`
23
- `);break;case"json":default:g=n.prettyPrint?JSON.stringify(d,null,2):JSON.stringify(d);break}return{success:!0,output:g}}catch(r){return{success:!1,error:`Failed to get: ${r instanceof Error?r.message:"Unknown error"}`}}}function et(t,n={}){let e=n.cwd||process.cwd(),s=k(e,n.keysFile||".env.keys");if(!w(s))return{success:!1,error:`Keys file not found: ${s}`};try{let r=K(s,"utf-8"),{parsed:i}=P(r),u=((n.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),f=u?`DOTENV_PUBLIC_KEY_${u}`:"DOTENV_PUBLIC_KEY",o=u?`DOTENV_PRIVATE_KEY_${u}`:"DOTENV_PRIVATE_KEY";if(t){let g=i[t];if(!g)return{success:!1,error:`Key not found: ${t}`};return{success:!0,output:g}}let l={[f]:i[f],[o]:i[o]};return{success:!0,output:n.format==="shell"?`${f}=${l[f]} ${o}=${l[o]}`:JSON.stringify(l)}}catch(r){return{success:!1,error:`Failed to get keypair: ${r instanceof Error?r.message:"Unknown error"}`}}}function Te(t,n,e,s){let r=t.split(`
24
- `),i=!1,c=!1;for(let a=0;a<r.length;a++){let u=r[a];if(u===void 0)continue;if(u.startsWith(`${e}=`))r[a]=`${e}="${n.publicKey}"`,i=!0;else if(u.startsWith(`${s}=`))r[a]=`${s}="${n.privateKey}"`,c=!0}if(!i)r.push(`${e}="${n.publicKey}"`);if(!c)r.push(`${s}="${n.privateKey}"`);return`${r.join(`
16
+ `;b(s,p,"utf-8")}let a=k(e,"utf-8"),u=ce(a,r,D(t.file).publicKeyName,t);if(t.stdout)return{success:!0,output:u};return b(e,u,"utf-8"),{success:!0,output:`\u2714 encrypted (${t.file||".env"})
17
+ \u2714 key added to ${t.keysFile||".env.keys"}`}}catch(r){return{success:!1,error:`Failed to encrypt: ${r instanceof Error?r.message:"Unknown error"}`}}}function Re(t={}){let n=t.cwd||process.cwd(),e=E(n,t.file||".env"),s=E(n,t.keysFile||".env.keys");if(!K(e))return{success:!1,error:`File not found: ${e}`};if(!K(s))return{success:!1,error:`Keys file not found: ${s}`};try{let r=k(s,"utf-8"),{parsed:i}=T(r),u=((t.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),f=u?`DOTENV_PRIVATE_KEY_${u}`:"DOTENV_PRIVATE_KEY",c=i[f];if(!c)return{success:!1,error:`Private key not found: ${f}`};let l=[c];if(f!=="DOTENV_PRIVATE_KEY"&&i.DOTENV_PRIVATE_KEY&&i.DOTENV_PRIVATE_KEY!==c)l.push(i.DOTENV_PRIVATE_KEY);let g=k(e,"utf-8").split(`
18
+ `),d=[];for(let N of g){let h=N.trim();if(!h||h.startsWith("#")){d.push(N);continue}if(h.startsWith("DOTENV_PUBLIC_KEY"))continue;let O=h.match(/^([^=]+)=(.*)$/);if(!O||O[1]===void 0||O[2]===void 0){d.push(N);continue}let v=O[1].trim(),y=O[2].trim();if(y.startsWith('"')&&y.endsWith('"')||y.startsWith("'")&&y.endsWith("'"))y=y.slice(1,-1);let _=y.startsWith("encrypted:");if(t.key&&!v.includes(t.key))_=!1;if(_){let w,P;for(let B of l)try{w=R(y,B);break}catch(ue){P=ue}if(w===void 0)throw P instanceof Error?P:Error(`Unable to decrypt ${v}`);y=w}d.push(`${v}="${y}"`)}let m=d.join(`
19
+ `);if(t.stdout)return{success:!0,output:m};return b(e,m,"utf-8"),{success:!0,output:`\u2714 decrypted (${t.file||".env"})`}}catch(r){return{success:!1,error:`Failed to decrypt: ${r instanceof Error?r.message:"Unknown error"}`}}}function nt(t,n,e={}){let s=e.cwd||process.cwd(),r=E(s,e.file||".env"),i=e.keysFile?E(s,e.keysFile):E(j(r),".env.keys");try{let o="";if(K(r))o=k(r,"utf-8");let a=o.split(`
20
+ `),u=!1,f,p=((e.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),g=p?`DOTENV_PUBLIC_KEY_${p}`:"DOTENV_PUBLIC_KEY",d=p?`DOTENV_PRIVATE_KEY_${p}`:"DOTENV_PRIVATE_KEY",m=De(o,e.file),N=m?.name??g;if(f=m?.key,f){let v=!1;if(K(i)){let _=k(i,"utf-8"),{parsed:w}=T(_);v=L(e.file).some((P)=>Boolean(w[P]))}let y=L(e.file).some((_)=>Boolean(process.env[_]));if(!v&&!y&&!ie(o))f=void 0}if(!e.plain&&!f&&ie(o))return{success:!1,error:`${e.file||".env"} already contains encrypted values, but no key that can be used to add another was found.
21
+ Generating one would leave every existing encrypted value unreadable.
22
+ Provide the private key as ${L(e.file)[0]} in the environment, restore ${i}, or use --plain to write this value unencrypted.`};if(!e.plain&&!f){let v=F();f=v.publicKey;let y="";if(K(i))y=k(i,"utf-8");y+=`
23
+ ${g}="${v.publicKey}"
24
+ ${d}="${v.privateKey}"
25
+ `,b(i,y,"utf-8");let _=ae(e.file);for(let w=a.length-1;w>=0;w--){let P=a[w];if(P!==void 0&&_.some((B)=>P.trim().startsWith(`${B}=`)))a.splice(w,1)}a.unshift(`${N}="${f}"`)}let h=n;if(!e.plain&&f)h=W(n,f);for(let v=0;v<a.length;v++){let y=a[v];if(y===void 0)continue;if(y.trim().startsWith(`${t}=`)){a[v]=`${t}="${h}"`,u=!0;break}}if(!u)a.push(`${t}="${h}"`);let O=a.join(`
26
+ `);return b(r,O,"utf-8"),{success:!0,output:`set ${t}${e.plain?"":" with encryption"} (${e.file||".env"})`}}catch(o){return{success:!1,error:`Failed to set: ${o instanceof Error?o.message:"Unknown error"}`}}}function rt(t,n={}){let e=n.cwd||process.cwd(),s=E(e,n.file||".env");if(!K(s))return{success:!1,error:`File not found: ${s}`};try{let r,i=E(e,n.keysFile||".env.keys"),u=((n.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),f=u?`DOTENV_PRIVATE_KEY_${u}`:"DOTENV_PRIVATE_KEY";if(K(i)){let d=k(i,"utf-8"),{parsed:m}=T(d);r=m[f]}if(!r)r=process.env[f];let c=k(s,"utf-8"),{parsed:l}=T(c,{privateKey:r});if(t&&!n.all){let d=l[t];if(d===void 0)return{success:!1,error:`Key not found: ${t}`};return{success:!0,output:d}}let p=n.all?{...process.env,...l}:l,g;switch(n.format){case"shell":g=Object.entries(p).map(([d,m])=>`${d}=${m}`).join(" ");break;case"eval":g=Object.entries(p).map(([d,m])=>`${d}="${m}"`).join(`
27
+ `);break;case"json":default:g=n.prettyPrint?JSON.stringify(p,null,2):JSON.stringify(p);break}return{success:!0,output:g}}catch(r){return{success:!1,error:`Failed to get: ${r instanceof Error?r.message:"Unknown error"}`}}}function st(t,n={}){let e=n.cwd||process.cwd(),s=E(e,n.keysFile||".env.keys");if(!K(s))return{success:!1,error:`Keys file not found: ${s}`};try{let r=k(s,"utf-8"),{parsed:i}=T(r),u=((n.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),f=u?`DOTENV_PUBLIC_KEY_${u}`:"DOTENV_PUBLIC_KEY",c=u?`DOTENV_PRIVATE_KEY_${u}`:"DOTENV_PRIVATE_KEY";if(t){let g=i[t];if(!g)return{success:!1,error:`Key not found: ${t}`};return{success:!0,output:g}}let l={[f]:i[f],[c]:i[c]};return{success:!0,output:n.format==="shell"?`${f}=${l[f]} ${c}=${l[c]}`:JSON.stringify(l)}}catch(r){return{success:!1,error:`Failed to get keypair: ${r instanceof Error?r.message:"Unknown error"}`}}}function Ce(t,n,e,s){let r=t.split(`
28
+ `),i=!1,o=!1;for(let a=0;a<r.length;a++){let u=r[a];if(u===void 0)continue;if(u.startsWith(`${e}=`))r[a]=`${e}="${n.publicKey}"`,i=!0;else if(u.startsWith(`${s}=`))r[a]=`${s}="${n.privateKey}"`,o=!0}if(!i)r.push(`${e}="${n.publicKey}"`);if(!o)r.push(`${s}="${n.privateKey}"`);return`${r.join(`
25
29
  `).replace(/\n+$/,"")}
26
- `}function tt(t={}){let n=Oe({file:t.file,keysFile:t.keysFile,stdout:!0,cwd:t.cwd});if(!n.success)return n;if(n.output===void 0)return{success:!1,error:"Rotation produced no decrypted content"};let e=t.cwd||process.cwd(),s=t.file||".env",r=t.keysFile||".env.keys",i=k(e,s),c=k(e,r),{publicKeyName:a,privateKeyName:u}=T(t.file);if(t.dryRun){let p=Ve(n.output,t);return{success:!0,output:["Dry run: nothing was written.",`${s}: ${p.length} value${p.length===1?"":"s"} would be re-encrypted under a new ${a}.`,`${r}: ${a} and ${u} would be replaced.`,`The current ${u} decrypts nothing once that happens, so keep a copy until the rotation is verified.`].join(`
27
- `)}}let f=V(),o=se(n.output,f.publicKey,a,t);if(t.stdout)return{success:!0,output:o,notice:[`Nothing was written. To adopt the output above, put this keypair in ${r}:`,"",`${a}="${f.publicKey}"`,`${u}="${f.privateKey}"`,"","Without it that output cannot be decrypted. Run without --stdout to have both applied together."].join(`
28
- `)};let l=K(i),d=K(c),g=Te(d.toString("utf8"),f,a,u),y=`${process.pid}-${Date.now()}`,m=k(ne(i),`.${te(i)}.${y}.rotate`),N=k(ne(c),`.${te(c)}.${y}.rotate`);try{b(m,o,{encoding:"utf8",mode:384}),b(N,g,{encoding:"utf8",mode:384}),Q(m,i);try{Q(N,c)}catch(p){throw b(i,l),p}return{success:!0,output:`\u2714 rotated (${s}) to encrypted:v2`}}catch(p){if(!w(c))b(c,d,{mode:384});return{success:!1,error:`Failed to rotate without exposing plaintext: ${p instanceof Error?p.message:"Unknown error"}`}}finally{ee(m,{force:!0}),ee(N,{force:!0})}}export{Oe as decryptEnv,qe as encryptEnv,T as envKeyNames,Qe as getEnv,et as getKeypair,Ge as resolveEnvFile,ie as reusableEnvPublicKey,tt as rotateKeypair,Ze as setEnv};
30
+ `}function it(t={}){let n=Re({file:t.file,keysFile:t.keysFile,stdout:!0,cwd:t.cwd});if(!n.success)return n;if(n.output===void 0)return{success:!1,error:"Rotation produced no decrypted content"};let e=t.cwd||process.cwd(),s=t.file||".env",r=t.keysFile||".env.keys",i=E(e,s),o=E(e,r),{publicKeyName:a,privateKeyName:u}=D(t.file);if(t.dryRun){let h=Oe(n.output,t);return{success:!0,output:["Dry run: nothing was written.",`${s}: ${h.length} value${h.length===1?"":"s"} would be re-encrypted under a new ${a}.`,`${r}: ${a} and ${u} would be replaced.`,`The current ${u} decrypts nothing once that happens, so keep a copy until the rotation is verified.`].join(`
31
+ `)}}let f=F(),c=ce(n.output,f.publicKey,a,t);if(t.stdout)return{success:!0,output:c,notice:[`Nothing was written. To adopt the output above, put this keypair in ${r}:`,"",`${a}="${f.publicKey}"`,`${u}="${f.privateKey}"`,"","Without it that output cannot be decrypted. Run without --stdout to have both applied together."].join(`
32
+ `)};let l=k(i),p=k(o),g=Ce(p.toString("utf8"),f,a,u),d=`${process.pid}-${Date.now()}`,m=E(j(i),`.${se(i)}.${d}.rotate`),N=E(j(o),`.${se(o)}.${d}.rotate`);try{b(m,c,{encoding:"utf8",mode:384}),b(N,g,{encoding:"utf8",mode:384}),ne(m,i);try{ne(N,o)}catch(h){throw b(i,l),h}return{success:!0,output:`\u2714 rotated (${s}) to encrypted:v2`}}catch(h){if(!K(o))b(o,p,{mode:384});return{success:!1,error:`Failed to rotate without exposing plaintext: ${h instanceof Error?h.message:"Unknown error"}`}}finally{re(m,{force:!0}),re(N,{force:!0})}}export{De as declaredEnvPublicKey,Re as decryptEnv,tt as encryptEnv,ie as envHasCiphertext,D as envKeyNames,L as envPrivateKeyNames,ae as envPublicKeyNames,rt as getEnv,st as getKeypair,et as resolveEnvFile,Fe as reusableEnvPublicKey,it as rotateKeypair,nt as setEnv};
package/dist/index.js CHANGED
@@ -1,31 +1,35 @@
1
1
  // @bun
2
- import gn from"process";import{projectPath as _n}from"@stacksjs/path";import Ne from"fs";import{existsSync as V}from"fs";import{readFileSync as z}from"fs";import{resolve as M}from"path";import{createCipheriv as ne,createDecipheriv as te,createHash as G,createPrivateKey as be,createPublicKey as re,diffieHellman as ie,generateKeyPairSync as se,hkdfSync as oe,randomBytes as H}from"crypto";var j="x25519-public:",X="x25519-private:",x="encrypted:v2:",Q="encrypted:",de=Buffer.from("stacks-env:v2","utf8"),ce="Environment decryption failed: authentication or format error";function ae(e){if(e.length===32)return e;return G("sha256").update(e).digest()}function vn(e,n){let t=H(16),r=ne("aes-256-gcm",ae(n),t);return{ciphertext:Buffer.concat([r.update(e,"utf8"),r.final()]).toString("hex"),iv:t.toString("hex"),authTag:r.getAuthTag().toString("hex")}}function Le(e,n,t,r){try{let i=te("aes-256-gcm",ae(n),Buffer.from(t,"hex"));return i.setAuthTag(Buffer.from(r,"hex")),Buffer.concat([i.update(Buffer.from(e,"hex")),i.final()]).toString("utf8")}catch{throw Error("Decryption failed: authentication or format error")}}function h(e){return e.toString("base64url")}function C(e,n,t){if(typeof e!=="string"||e.length>0&&!/^[A-Za-z0-9_-]+$/.test(e))throw Error(`${n} is not canonical base64url`);let r=Buffer.from(e,"base64url");if(h(r)!==e)throw Error(`${n} is not canonical base64url`);if(t!==void 0&&r.length!==t)throw Error(`${n} has an invalid length`);return r}function Ke(e){if(!e.startsWith(j))throw Error("Legacy or invalid public key. Run buddy env:rotate before creating new ciphertext.");let n=re({key:C(e.slice(j.length),"public key"),format:"der",type:"spki"});if(n.asymmetricKeyType!=="x25519")throw Error("Public key is not X25519");return n}function ke(e){if(!e.startsWith(X))throw Error("Private key is not a version 2 X25519 key");let n=be({key:C(e.slice(X.length),"private key"),format:"der",type:"pkcs8"});if(n.asymmetricKeyType!=="x25519")throw Error("Private key is not X25519");return n}function ue(e){return Buffer.from(`stacks-env:v2;${e.epk};${e.salt};${e.nonce}`,"utf8")}function k(){let{publicKey:e,privateKey:n}=se("x25519"),t=e.export({format:"der",type:"spki"}),r=n.export({format:"der",type:"pkcs8"});return{publicKey:`${j}${h(t)}`,privateKey:`${X}${h(r)}`}}function B(e,n){let t=Ke(n),r=se("x25519"),i=h(r.publicKey.export({format:"der",type:"spki"})),s=H(16),o=H(12),d=ie({privateKey:r.privateKey,publicKey:t}),c=Buffer.from(oe("sha256",d,s,de,32)),u={epk:i,salt:h(s),nonce:h(o)};try{let a=ne("aes-256-gcm",c,o);a.setAAD(ue(u));let f=Buffer.concat([a.update(e,"utf8"),a.final()]),p={v:2,...u,ciphertext:h(f),tag:h(a.getAuthTag())};return`${x}${h(Buffer.from(JSON.stringify(p),"utf8"))}`}finally{d.fill(0),c.fill(0)}}function Ue(e){let n=C(e.slice(x.length),"envelope").toString("utf8"),t=JSON.parse(n);if(!t||typeof t!=="object"||Array.isArray(t))throw Error("envelope is not an object");let r=Object.keys(t).sort(),i=["ciphertext","epk","nonce","salt","tag","v"];if(r.length!==i.length||r.some((s,o)=>s!==i[o]))throw Error("envelope fields are invalid");if(t.v!==2)throw Error("envelope version is unsupported");for(let s of["epk","salt","nonce","ciphertext","tag"])if(typeof t[s]!=="string")throw Error(`${s} is invalid`);return t}function $e(e,n){try{let t=Ue(e),r=ke(n),i=re({key:C(t.epk,"ephemeral public key"),format:"der",type:"spki"});if(i.asymmetricKeyType!=="x25519")throw Error("ephemeral key is not X25519");let s=C(t.salt,"salt",16),o=C(t.nonce,"nonce",12),d=C(t.ciphertext,"ciphertext"),c=C(t.tag,"tag",16),u=ie({privateKey:r,publicKey:i}),a=Buffer.from(oe("sha256",u,s,de,32));try{let f=te("aes-256-gcm",a,o);return f.setAAD(ue(t)),f.setAuthTag(c),Buffer.concat([f.update(d),f.final()]).toString("utf8")}finally{u.fill(0),a.fill(0)}}catch{throw Error(ce)}}function we(e,n){try{if(!/^[0-9a-f]{64}$/.test(n))throw Error("invalid legacy private key");let t=Buffer.from(e.slice(Q.length),"base64");if(t.length<32)throw Error("invalid legacy payload");let r=G("sha256").update(Buffer.from(n,"hex")).digest(),i=G("sha256").update(r).digest();return Le(t.subarray(32).toString("hex"),i,t.subarray(0,16).toString("hex"),t.subarray(16,32).toString("hex"))}catch{throw Error(ce)}}function On(e){return e.startsWith(Q)&&!e.startsWith(x)}function K(e,n){if(!e.startsWith(Q))return e;return e.startsWith(x)?$e(e,n):we(e,n)}function An(e,n,t){return B(K(e,n),t)}function Sn(e){let n=e.match(/^DOTENV_PRIVATE_KEY_(.+)$/);return n&&n[1]?n[1].toLowerCase():""}function q(e=""){return e?process.env[`DOTENV_PRIVATE_KEY_${e.toUpperCase()}`]:process.env.DOTENV_PRIVATE_KEY}import{spawnSync as xe}from"child_process";import{readFileSync as Be}from"fs";import{arch as Ve,hostname as Me,platform as fe,release as Fe,userInfo as Ye}from"os";import{basename as We,dirname as Ge,resolve as He}from"path";function S(e,n={}){let t={},r=[],i=[],s=e.split(`
3
- `);for(let o of s){let d=o.trim();if(!d||d.startsWith("#"))continue;if(d.startsWith("DOTENV_PUBLIC_KEY=")){let f=d.match(/^DOTENV_PUBLIC_KEY=["']?([^"'\n]+)["']?/);if(f&&f[1]!==void 0)t.DOTENV_PUBLIC_KEY=f[1];continue}let c=d.match(/^([^=]+)=(.*)$/);if(!c||c[1]===void 0||c[2]===void 0)continue;let u=c[1].trim(),a=c[2].trim();if(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'")){if(a=a.slice(1,-1),a.includes("\\n"))a=a.replace(/\\n/g,`
4
- `)}if(a.startsWith("encrypted:")||a.startsWith("enc:")){if(!n.privateKey){i.push(u);continue}try{let f=a.startsWith("enc:")?`encrypted:${a.slice(4)}`:a;a=K(f,n.privateKey)}catch(f){r.push(`Failed to decrypt ${u}: ${f instanceof Error?f.message:"Unknown error"}`)}}a=je(a,{...n.processEnv||process.env,...t}),a=ze(a),t[u]=a}return{parsed:t,errors:r,skippedEncrypted:i}}function je(e,n){return e.replace(/\$\{([^}]+)\}/g,(t,r)=>{let i=r.match(/^([^:\-+]+)(:-|-)(.+)$/);if(i){let[,o,d,c]=i,u=n[o];if(d===":-")return u||c;else return u!==void 0?u:c}let s=r.match(/^([^:\-+]+)(:?\+)(.+)$/);if(s){let[,o,d,c]=s,u=n[o];if(d===":+")return u?c:"";else return u!==void 0?c:""}return n[r]||""})}var Xe=new Set(["date","hostname","whoami","uname","pwd","echo","printf","cat","basename","dirname"]);function Qe(e){let n=[],t="",r=null,i=!1;for(let s of e.trim()){if(i){t+=s,i=!1;continue}if(s==="\\"&&r!=="'"){i=!0;continue}if(r){if(s===r)r=null;else t+=s;continue}if(s==='"'||s==="'"){r=s;continue}if(/\s/.test(s)){if(t)n.push(t),t="";continue}t+=s}if(i||r)throw Error("Command substitution contains an unterminated escape or quote");if(t)n.push(t);return n}function qe(e){let[n,...t]=e,r=t.some((i)=>i.startsWith("-"));if(n==="echo"&&!r)return t.join(" ");if(n==="printf"&&t.length===1&&!t[0]?.includes("%"))return t[0];if(n==="hostname"&&t.length===0)return Me();if(n==="whoami"&&t.length===0)return Ye().username;if(n==="pwd"&&t.length===0)return process.cwd();if(n==="basename"&&t.length===1)return We(t[0]??"");if(n==="dirname"&&t.length===1)return Ge(t[0]??"");if(n==="cat"&&t.length>0&&!r)return t.map((i)=>Be(He(process.cwd(),i),"utf8")).join("");if(n==="uname"){let i=t[0]??"-s";if(t.length<=1&&i==="-m")return Ve();if(t.length<=1&&i==="-r")return Fe();if(t.length<=1&&i==="-s")return{aix:"AIX",android:"Android",cygwin:"CYGWIN",darwin:"Darwin",freebsd:"FreeBSD",haiku:"Haiku",linux:"Linux",netbsd:"NetBSD",openbsd:"OpenBSD",sunos:"SunOS",win32:"Windows_NT"}[fe()]??fe()}return}function ze(e){return e.replace(/\$\(([^)]+)\)/g,(n,t)=>{try{let r=Qe(t),i=r[0];if(!i||!Xe.has(i))return console.warn(`[env] Blocked command substitution for disallowed command: ${i}`),"";let s=qe(r);if(s!==void 0)return s.trim();let o=xe(i,r.slice(1),{encoding:"utf8",env:process.env});if(o.status===0)return o.stdout.trim();let d=o.stderr.trim();console.warn(`[env] Command substitution failed (exit code ${o.status??"unknown"}): ${i}${d?`: ${d}`:""}`)}catch(r){console.warn(`[env] Command substitution error: ${r instanceof Error?r.message:String(r)}`)}return""})}async function bn(e,n={}){let t={},r=[],i=[];for(let s of e)try{let o=Bun.file(s);if(!o.size)continue;let d=await o.text(),{parsed:c,errors:u,skippedEncrypted:a}=S(d,n);r.push(...u),i.push(...a);for(let[f,p]of Object.entries(c)){if(!n.overload&&t[f]!==void 0)continue;t[f]=p}}catch(o){if(o?.code==="ENOENT")continue;r.push(`Failed to read ${s}: ${o instanceof Error?o.message:String(o)}`)}return{parsed:t,errors:r,skippedEncrypted:i}}function U(e){return typeof e==="string"&&(e.startsWith("encrypted:")||e.startsWith("enc:"))}function b(e){if(!e||U(e))return;let n=e.trim().toLowerCase();if(!/^[a-z0-9_-]+$/.test(n))return;if(n==="prod")return"production";if(n==="stage")return"staging";if(n==="dev")return"development";return n}var F=null,Y,W;function Je(e,n,t=".env.keys"){let r=M(n,t);if(!V(r))return;try{let{parsed:i}=S(z(r,"utf-8"));if(e){let s=i[`DOTENV_PRIVATE_KEY_${e.toUpperCase()}`];if(s)return s}return i.DOTENV_PRIVATE_KEY}catch{return}}function J(e={}){return b(e.env)||W||b("development")||b(process.env.DOTENV_ENV)||b(process.env.APP_ENV)||"development"}function Ze(e={}){let n=J(e),t=e.cwd||process.cwd();if(F===n)return Y;let r=q(n);if(!r)r=process.env.DOTENV_PRIVATE_KEY;if(!r)r=Je(n,t);return F=n,Y=r,r}function xn(){F=null,Y=void 0,W=void 0}function Ee(e,n={}){if(!U(e))return e;let t=Ze(n);if(!t)return;try{let r=e.startsWith("enc:")?`encrypted:${e.slice(4)}`:e;return K(r,t)}catch{return}}function le(e={}){let{path:n=[".env"],overload:t=!1,env:r,privateKey:i,keysFile:s=".env.keys",quiet:o=!1,cwd:d=process.cwd()}=e,c=Array.isArray(n)?n:[n],u=[],a=0,f=new Set(Object.entries(process.env).filter(([,E])=>E!==void 0&&!U(E)).map(([E])=>E)),p=i;if(!p&&s){let E=M(d,s);if(V(E))try{let l=z(E,"utf-8"),{parsed:T}=S(l);if(r){let v=`DOTENV_PRIVATE_KEY_${r.toUpperCase()}`;p=T[v]}else p=T.DOTENV_PRIVATE_KEY}catch(l){u.push(`Failed to load keys file: ${l instanceof Error?l.message:"Unknown error"}`)}}if(!p)p=q(r||"");for(let E of c){let l=M(d,E);if(!V(l)){if(!o)u.push(`File not found: ${l}`);continue}try{let T=z(l,"utf-8"),{parsed:v,errors:_,skippedEncrypted:y}=S(T,{privateKey:p,processEnv:process.env});if(u.push(..._),y.length>0){for(let D of y)if(U(process.env[D]))delete process.env[D];let R=r?`DOTENV_PRIVATE_KEY_${r.toUpperCase()}`:"DOTENV_PRIVATE_KEY",L=y.slice(0,5).join(", "),P=y.length>5?`, \u2026 +${y.length-5} more`:"";console.warn(`[env] warning: skipped ${y.length} encrypted value(s) in ${E} (${R} not set; defaults apply): ${L}${P}`)}let m=0;for(let[R,L]of Object.entries(v)){if(R==="DOTENV_PUBLIC_KEY")continue;let P=process.env[R],D=U(P)&&L!==P;if(t||!f.has(R)||D)process.env[R]=L,a++,m++}if(!o&&!process.env.__ENV_LOADED__)console.error(`[env] loaded ${m}/${Object.keys(v).length} variables from ${E}`),process.env.__ENV_LOADED__="1"}catch(T){u.push(`Failed to load ${l}: ${T instanceof Error?T.message:"Unknown error"}`)}}return{loaded:a,errors:u}}function en(e={}){return{name:"env-plugin",setup(n){le(e)}}}function Bn(e={}){let n=b(e.env)||b("development")||b(process.env.DOTENV_ENV)||b(process.env.APP_ENV)||"development",t=e.cwd||process.cwd();if(W!==n)W=n,F=null,Y=void 0;let r=[],i=(d)=>{if(!r.includes(d)&&V(M(t,d)))r.push(d)};i(".env"),i(".env.local");let s=`.env.${n}`,o=`.env.${n}.local`;return i(s),i(o),le({...e,path:r,env:n})}var Mn=en;var pe={APP_ENV:["local","dev","development","staging","prod","production"],DB_CONNECTION:["mysql","sqlite","postgres","singlestore","vitess","dynamodb"],DB_MIGRATE_FRESH:["allow","confirm","disabled"],MAIL_MAILER:["smtp","mailgun","ses","log","sendgrid","mailtrap","capture"],SEARCH_ENGINE_DRIVER:["opensearch","meilisearch","algolia","typesense"],FRONTEND_APP_ENV:["development","staging","production"]};function Fn(e){return e}import{existsSync as I,readFileSync as A,renameSync as ge,rmSync as _e,writeFileSync as N}from"fs";import{basename as Te,dirname as ye,resolve as O}from"path";function Xn(e,n){if(e)return e;let t=String(n??"").trim();if(!t||t==="development"||t==="dev"||t==="local")return"";if(!/^[\w.-]+$/.test(t))return"";return`.env.${t}`}function Re(e,n){return(!n.key||e.includes(n.key))&&(!n.excludeKey||!e.includes(n.excludeKey))}function nn(e,n){let t=[];for(let r of e.split(`
5
- `)){let i=r.trim();if(!i||i.startsWith("#"))continue;if(i.startsWith("DOTENV_PUBLIC_KEY"))continue;let s=i.match(/^([^=]+)=(.*)$/);if(!s||s[1]===void 0)continue;let o=s[1].trim();if(Re(o,n))t.push(o)}return t}function me(e,n,t,r){let i=["#/-------------------[DOTENV_PUBLIC_KEY]--------------------/","#/ versioned X25519 encryption for .env files /","#/ [how it works](https://stacksjs.com/encryption) /","#/----------------------------------------------------------/",`${t}="${n}"`,""],s=!1;for(let o of e.split(`
6
- `)){let d=o.trim();if(d.startsWith("#/"))continue;if(d.startsWith("DOTENV_PUBLIC_KEY"))continue;if(!d&&!s)continue;if(!d||d.startsWith("#")){s=!0,i.push(o);continue}s=!0;let c=d.match(/^([^=]+)=(.*)$/);if(!c||c[1]===void 0||c[2]===void 0){i.push(o);continue}let u=c[1].trim(),a=c[2].trim();if(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))a=a.slice(1,-1);if(Re(u,r)&&!a.startsWith("encrypted:"))a=B(a,n);i.push(`${u}="${a}"`)}return i.join(`
7
- `)}function w(e){let t=((e||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase();return{publicKeyName:t?`DOTENV_PUBLIC_KEY_${t}`:"DOTENV_PUBLIC_KEY",privateKeyName:t?`DOTENV_PRIVATE_KEY_${t}`:"DOTENV_PRIVATE_KEY"}}function ve(e,n){let t,r=!1;for(let i of e.split(`
8
- `)){let s=i.trim();if(!s||s.startsWith("#"))continue;let o=s.match(/^([^=]+)=(.*)$/);if(!o?.[1]||o[2]===void 0)continue;let d=o[1].trim(),c=o[2].trim().replace(/^["']|["']$/g,"");if(d===n)t=c;else if(c.startsWith("encrypted:")||c.startsWith("enc:"))r=!0}return t&&r?t:void 0}function Qn(e={}){let n=e.cwd||process.cwd(),t=O(n,e.file||".env"),r=O(n,e.keysFile||".env.keys");if(!I(t))return{success:!1,error:`File not found: ${t}`};try{let i,s,o=ve(A(t,"utf-8"),w(e.file).publicKeyName);if(o)i=o;else if(I(r)){let u=A(r,"utf-8"),{parsed:a}=S(u),{publicKeyName:f,privateKeyName:p}=w(e.file);if(i=a[f]||"",s=a[p]||"",!i||!s){let E=k();i=E.publicKey,s=E.privateKey;let l=`
2
+ import mn from"process";import{projectPath as Rn}from"@stacksjs/path";import De from"fs";import{existsSync as V}from"fs";import{readFileSync as J}from"fs";import{resolve as M}from"path";import{createCipheriv as ie,createDecipheriv as se,createHash as H,createPrivateKey as Le,createPublicKey as oe,diffieHellman as de,generateKeyPairSync as ce,hkdfSync as ae,randomBytes as j}from"crypto";var X="x25519-public:",Q="x25519-private:",w="encrypted:v2:",q="encrypted:",ue=Buffer.from("stacks-env:v2","utf8"),fe="Environment decryption failed: authentication or format error";function Ee(e){if(e.length===32)return e;return H("sha256").update(e).digest()}function In(e,n){let t=j(16),r=ie("aes-256-gcm",Ee(n),t);return{ciphertext:Buffer.concat([r.update(e,"utf8"),r.final()]).toString("hex"),iv:t.toString("hex"),authTag:r.getAuthTag().toString("hex")}}function ke(e,n,t,r){try{let i=se("aes-256-gcm",Ee(n),Buffer.from(t,"hex"));return i.setAuthTag(Buffer.from(r,"hex")),Buffer.concat([i.update(Buffer.from(e,"hex")),i.final()]).toString("utf8")}catch{throw Error("Decryption failed: authentication or format error")}}function C(e){return e.toString("base64url")}function b(e,n,t){if(typeof e!=="string"||e.length>0&&!/^[A-Za-z0-9_-]+$/.test(e))throw Error(`${n} is not canonical base64url`);let r=Buffer.from(e,"base64url");if(C(r)!==e)throw Error(`${n} is not canonical base64url`);if(t!==void 0&&r.length!==t)throw Error(`${n} has an invalid length`);return r}function Ue(e){if(!e.startsWith(X))throw Error("Legacy or invalid public key. Run buddy env:rotate before creating new ciphertext.");let n=oe({key:b(e.slice(X.length),"public key"),format:"der",type:"spki"});if(n.asymmetricKeyType!=="x25519")throw Error("Public key is not X25519");return n}function $e(e){if(!e.startsWith(Q))throw Error("Private key is not a version 2 X25519 key");let n=Le({key:b(e.slice(Q.length),"private key"),format:"der",type:"pkcs8"});if(n.asymmetricKeyType!=="x25519")throw Error("Private key is not X25519");return n}function le(e){return Buffer.from(`stacks-env:v2;${e.epk};${e.salt};${e.nonce}`,"utf8")}function U(){let{publicKey:e,privateKey:n}=ce("x25519"),t=e.export({format:"der",type:"spki"}),r=n.export({format:"der",type:"pkcs8"});return{publicKey:`${X}${C(t)}`,privateKey:`${Q}${C(r)}`}}function B(e,n){let t=Ue(n),r=ce("x25519"),i=C(r.publicKey.export({format:"der",type:"spki"})),s=j(16),o=j(12),d=de({privateKey:r.privateKey,publicKey:t}),c=Buffer.from(ae("sha256",d,s,ue,32)),a={epk:i,salt:C(s),nonce:C(o)};try{let u=ie("aes-256-gcm",c,o);u.setAAD(le(a));let f=Buffer.concat([u.update(e,"utf8"),u.final()]),E={v:2,...a,ciphertext:C(f),tag:C(u.getAuthTag())};return`${w}${C(Buffer.from(JSON.stringify(E),"utf8"))}`}finally{d.fill(0),c.fill(0)}}function xe(e){let n=b(e.slice(w.length),"envelope").toString("utf8"),t=JSON.parse(n);if(!t||typeof t!=="object"||Array.isArray(t))throw Error("envelope is not an object");let r=Object.keys(t).sort(),i=["ciphertext","epk","nonce","salt","tag","v"];if(r.length!==i.length||r.some((s,o)=>s!==i[o]))throw Error("envelope fields are invalid");if(t.v!==2)throw Error("envelope version is unsupported");for(let s of["epk","salt","nonce","ciphertext","tag"])if(typeof t[s]!=="string")throw Error(`${s} is invalid`);return t}function we(e,n){try{let t=xe(e),r=$e(n),i=oe({key:b(t.epk,"ephemeral public key"),format:"der",type:"spki"});if(i.asymmetricKeyType!=="x25519")throw Error("ephemeral key is not X25519");let s=b(t.salt,"salt",16),o=b(t.nonce,"nonce",12),d=b(t.ciphertext,"ciphertext"),c=b(t.tag,"tag",16),a=de({privateKey:r,publicKey:i}),u=Buffer.from(ae("sha256",a,s,ue,32));try{let f=se("aes-256-gcm",u,o);return f.setAAD(le(t)),f.setAuthTag(c),Buffer.concat([f.update(d),f.final()]).toString("utf8")}finally{a.fill(0),u.fill(0)}}catch{throw Error(fe)}}function Be(e,n){try{if(!/^[0-9a-f]{64}$/.test(n))throw Error("invalid legacy private key");let t=Buffer.from(e.slice(q.length),"base64");if(t.length<32)throw Error("invalid legacy payload");let r=H("sha256").update(Buffer.from(n,"hex")).digest(),i=H("sha256").update(r).digest();return ke(t.subarray(32).toString("hex"),i,t.subarray(0,16).toString("hex"),t.subarray(16,32).toString("hex"))}catch{throw Error(fe)}}function Nn(e){return e.startsWith(q)&&!e.startsWith(w)}function L(e,n){if(!e.startsWith(q))return e;return e.startsWith(w)?we(e,n):Be(e,n)}function hn(e,n,t){return B(L(e,n),t)}function Pn(e){let n=e.match(/^DOTENV_PRIVATE_KEY_(.+)$/);return n&&n[1]?n[1].toLowerCase():""}function z(e=""){return e?process.env[`DOTENV_PRIVATE_KEY_${e.toUpperCase()}`]:process.env.DOTENV_PRIVATE_KEY}import{spawnSync as Ve}from"child_process";import{readFileSync as Me}from"fs";import{arch as Fe,hostname as Ye,platform as pe,release as We,userInfo as Ge}from"os";import{basename as He,dirname as je,resolve as Xe}from"path";function h(e,n={}){let t={},r=[],i=[],s=e.split(`
3
+ `);for(let o of s){let d=o.trim();if(!d||d.startsWith("#"))continue;if(d.startsWith("DOTENV_PUBLIC_KEY=")){let f=d.match(/^DOTENV_PUBLIC_KEY=["']?([^"'\n]+)["']?/);if(f&&f[1]!==void 0)t.DOTENV_PUBLIC_KEY=f[1];continue}let c=d.match(/^([^=]+)=(.*)$/);if(!c||c[1]===void 0||c[2]===void 0)continue;let a=c[1].trim(),u=c[2].trim();if(u.startsWith('"')&&u.endsWith('"')||u.startsWith("'")&&u.endsWith("'")){if(u=u.slice(1,-1),u.includes("\\n"))u=u.replace(/\\n/g,`
4
+ `)}if(u.startsWith("encrypted:")||u.startsWith("enc:")){if(!n.privateKey){i.push(a);continue}try{let f=u.startsWith("enc:")?`encrypted:${u.slice(4)}`:u;u=L(f,n.privateKey)}catch(f){r.push(`Failed to decrypt ${a}: ${f instanceof Error?f.message:"Unknown error"}`)}}u=Qe(u,{...n.processEnv||process.env,...t}),u=Ze(u),t[a]=u}return{parsed:t,errors:r,skippedEncrypted:i}}function Qe(e,n){return e.replace(/\$\{([^}]+)\}/g,(t,r)=>{let i=r.match(/^([^:\-+]+)(:-|-)(.+)$/);if(i){let[,o,d,c]=i,a=n[o];if(d===":-")return a||c;else return a!==void 0?a:c}let s=r.match(/^([^:\-+]+)(:?\+)(.+)$/);if(s){let[,o,d,c]=s,a=n[o];if(d===":+")return a?c:"";else return a!==void 0?c:""}return n[r]||""})}var qe=new Set(["date","hostname","whoami","uname","pwd","echo","printf","cat","basename","dirname"]);function ze(e){let n=[],t="",r=null,i=!1;for(let s of e.trim()){if(i){t+=s,i=!1;continue}if(s==="\\"&&r!=="'"){i=!0;continue}if(r){if(s===r)r=null;else t+=s;continue}if(s==='"'||s==="'"){r=s;continue}if(/\s/.test(s)){if(t)n.push(t),t="";continue}t+=s}if(i||r)throw Error("Command substitution contains an unterminated escape or quote");if(t)n.push(t);return n}function Je(e){let[n,...t]=e,r=t.some((i)=>i.startsWith("-"));if(n==="echo"&&!r)return t.join(" ");if(n==="printf"&&t.length===1&&!t[0]?.includes("%"))return t[0];if(n==="hostname"&&t.length===0)return Ye();if(n==="whoami"&&t.length===0)return Ge().username;if(n==="pwd"&&t.length===0)return process.cwd();if(n==="basename"&&t.length===1)return He(t[0]??"");if(n==="dirname"&&t.length===1)return je(t[0]??"");if(n==="cat"&&t.length>0&&!r)return t.map((i)=>Me(Xe(process.cwd(),i),"utf8")).join("");if(n==="uname"){let i=t[0]??"-s";if(t.length<=1&&i==="-m")return Fe();if(t.length<=1&&i==="-r")return We();if(t.length<=1&&i==="-s")return{aix:"AIX",android:"Android",cygwin:"CYGWIN",darwin:"Darwin",freebsd:"FreeBSD",haiku:"Haiku",linux:"Linux",netbsd:"NetBSD",openbsd:"OpenBSD",sunos:"SunOS",win32:"Windows_NT"}[pe()]??pe()}return}function Ze(e){return e.replace(/\$\(([^)]+)\)/g,(n,t)=>{try{let r=ze(t),i=r[0];if(!i||!qe.has(i))return console.warn(`[env] Blocked command substitution for disallowed command: ${i}`),"";let s=Je(r);if(s!==void 0)return s.trim();let o=Ve(i,r.slice(1),{encoding:"utf8",env:process.env});if(o.status===0)return o.stdout.trim();let d=o.stderr.trim();console.warn(`[env] Command substitution failed (exit code ${o.status??"unknown"}): ${i}${d?`: ${d}`:""}`)}catch(r){console.warn(`[env] Command substitution error: ${r instanceof Error?r.message:String(r)}`)}return""})}async function Un(e,n={}){let t={},r=[],i=[];for(let s of e)try{let o=Bun.file(s);if(!o.size)continue;let d=await o.text(),{parsed:c,errors:a,skippedEncrypted:u}=h(d,n);r.push(...a),i.push(...u);for(let[f,E]of Object.entries(c)){if(!n.overload&&t[f]!==void 0)continue;t[f]=E}}catch(o){if(o?.code==="ENOENT")continue;r.push(`Failed to read ${s}: ${o instanceof Error?o.message:String(o)}`)}return{parsed:t,errors:r,skippedEncrypted:i}}function x(e){return typeof e==="string"&&(e.startsWith("encrypted:")||e.startsWith("enc:"))}function K(e){if(!e||x(e))return;let n=e.trim().toLowerCase();if(!/^[a-z0-9_-]+$/.test(n))return;if(n==="prod")return"production";if(n==="stage")return"staging";if(n==="dev")return"development";return n}var F=null,Y,W;function en(e,n,t=".env.keys"){let r=M(n,t);if(!V(r))return;try{let{parsed:i}=h(J(r,"utf-8"));if(e){let s=i[`DOTENV_PRIVATE_KEY_${e.toUpperCase()}`];if(s)return s}return i.DOTENV_PRIVATE_KEY}catch{return}}function Z(e={}){return K(e.env)||W||K("development")||K(process.env.DOTENV_ENV)||K(process.env.APP_ENV)||"development"}function nn(e={}){let n=Z(e),t=e.cwd||process.cwd();if(F===n)return Y;let r=z(n);if(!r)r=process.env.DOTENV_PRIVATE_KEY;if(!r)r=en(n,t);return F=n,Y=r,r}function Fn(){F=null,Y=void 0,W=void 0}function ge(e,n={}){if(!x(e))return e;let t=nn(n);if(!t)return;try{let r=e.startsWith("enc:")?`encrypted:${e.slice(4)}`:e;return L(r,t)}catch{return}}function _e(e={}){let{path:n=[".env"],overload:t=!1,env:r,privateKey:i,keysFile:s=".env.keys",quiet:o=!1,cwd:d=process.cwd()}=e,c=Array.isArray(n)?n:[n],a=[],u=0,f=new Set(Object.entries(process.env).filter(([,g])=>g!==void 0&&!x(g)).map(([g])=>g)),E=i;if(!E&&s){let g=M(d,s);if(V(g))try{let l=J(g,"utf-8"),{parsed:y}=h(l);if(r){let v=`DOTENV_PRIVATE_KEY_${r.toUpperCase()}`;E=y[v]}else E=y.DOTENV_PRIVATE_KEY}catch(l){a.push(`Failed to load keys file: ${l instanceof Error?l.message:"Unknown error"}`)}}if(!E)E=z(r||"");for(let g of c){let l=M(d,g);if(!V(l)){if(!o)a.push(`File not found: ${l}`);continue}try{let y=J(l,"utf-8"),{parsed:v,errors:T,skippedEncrypted:O}=h(y,{privateKey:E,processEnv:process.env});if(a.push(...T),O.length>0){for(let I of O)if(x(process.env[I]))delete process.env[I];let _=r?`DOTENV_PRIVATE_KEY_${r.toUpperCase()}`:"DOTENV_PRIVATE_KEY",A=O.slice(0,5).join(", "),R=O.length>5?`, \u2026 +${O.length-5} more`:"";console.warn(`[env] warning: skipped ${O.length} encrypted value(s) in ${g} (${_} not set; defaults apply): ${A}${R}`)}let m=0;for(let[_,A]of Object.entries(v)){if(_==="DOTENV_PUBLIC_KEY")continue;let R=process.env[_],I=x(R)&&A!==R;if(t||!f.has(_)||I)process.env[_]=A,u++,m++}if(!o&&!process.env.__ENV_LOADED__)console.error(`[env] loaded ${m}/${Object.keys(v).length} variables from ${g}`),process.env.__ENV_LOADED__="1"}catch(y){a.push(`Failed to load ${l}: ${y instanceof Error?y.message:"Unknown error"}`)}}return{loaded:u,errors:a}}function tn(e={}){return{name:"env-plugin",setup(n){_e(e)}}}function Yn(e={}){let n=K(e.env)||K("development")||K(process.env.DOTENV_ENV)||K(process.env.APP_ENV)||"development",t=e.cwd||process.cwd();if(W!==n)W=n,F=null,Y=void 0;let r=[],i=(d)=>{if(!r.includes(d)&&V(M(t,d)))r.push(d)};i(".env"),i(".env.local");let s=`.env.${n}`,o=`.env.${n}.local`;return i(s),i(o),_e({...e,path:r,env:n})}var Gn=tn;var ye={APP_ENV:["local","dev","development","staging","prod","production"],DB_CONNECTION:["mysql","sqlite","postgres","singlestore","vitess","dynamodb"],DB_MIGRATE_FRESH:["allow","confirm","disabled"],MAIL_MAILER:["smtp","mailgun","ses","log","sendgrid","mailtrap","capture"],SEARCH_ENGINE_DRIVER:["opensearch","meilisearch","algolia","typesense"],FRONTEND_APP_ENV:["development","staging","production"]};function Hn(e){return e}import{existsSync as P,readFileSync as N,renameSync as Te,rmSync as me,writeFileSync as D}from"fs";import{basename as Re,dirname as ne,resolve as S}from"path";function Jn(e,n){if(e)return e;let t=String(n??"").trim();if(!t||t==="development"||t==="dev"||t==="local")return"";if(!/^[\w.-]+$/.test(t))return"";return`.env.${t}`}function Oe(e,n){return(!n.key||e.includes(n.key))&&(!n.excludeKey||!e.includes(n.excludeKey))}function rn(e,n){let t=[];for(let r of e.split(`
5
+ `)){let i=r.trim();if(!i||i.startsWith("#"))continue;if(i.startsWith("DOTENV_PUBLIC_KEY"))continue;let s=i.match(/^([^=]+)=(.*)$/);if(!s||s[1]===void 0)continue;let o=s[1].trim();if(Oe(o,n))t.push(o)}return t}function Ae(e,n,t,r){let i=["#/-------------------[DOTENV_PUBLIC_KEY]--------------------/","#/ versioned X25519 encryption for .env files /","#/ [how it works](https://stacksjs.com/encryption) /","#/----------------------------------------------------------/",`${t}="${n}"`,""],s=!1;for(let o of e.split(`
6
+ `)){let d=o.trim();if(d.startsWith("#/"))continue;if(d.startsWith("DOTENV_PUBLIC_KEY"))continue;if(!d&&!s)continue;if(!d||d.startsWith("#")){s=!0,i.push(o);continue}s=!0;let c=d.match(/^([^=]+)=(.*)$/);if(!c||c[1]===void 0||c[2]===void 0){i.push(o);continue}let a=c[1].trim(),u=c[2].trim();if(u.startsWith('"')&&u.endsWith('"')||u.startsWith("'")&&u.endsWith("'"))u=u.slice(1,-1);if(Oe(a,r)&&!u.startsWith("encrypted:"))u=B(u,n);i.push(`${a}="${u}"`)}return i.join(`
7
+ `)}function k(e){let t=((e||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase();return{publicKeyName:t?`DOTENV_PUBLIC_KEY_${t}`:"DOTENV_PUBLIC_KEY",privateKeyName:t?`DOTENV_PRIVATE_KEY_${t}`:"DOTENV_PRIVATE_KEY"}}function Se(e){let{publicKeyName:n}=k(e);return n==="DOTENV_PUBLIC_KEY"?[n]:[n,"DOTENV_PUBLIC_KEY"]}function ee(e){let{privateKeyName:n}=k(e);return n==="DOTENV_PRIVATE_KEY"?[n]:[n,"DOTENV_PRIVATE_KEY"]}function ve(e){for(let n of e.split(`
8
+ `)){let t=n.trim();if(!t||t.startsWith("#"))continue;let r=t.match(/^([^=]+)=(.*)$/);if(!r?.[1]||r[2]===void 0)continue;let i=r[2].trim().replace(/^["']|["']$/g,"");if(i.startsWith("encrypted:")||i.startsWith("enc:"))return!0}return!1}function sn(e,n){let t=Se(n);for(let r of e.split(`
9
+ `)){let i=r.trim();if(!i||i.startsWith("#"))continue;let s=i.match(/^([^=]+)=["']?([^"'\n]+)["']?/);if(!s?.[1]||!s[2])continue;let o=s[1].trim();if(t.includes(o))return{name:o,key:s[2]}}return}function on(e,n){let t,r=!1;for(let i of e.split(`
10
+ `)){let s=i.trim();if(!s||s.startsWith("#"))continue;let o=s.match(/^([^=]+)=(.*)$/);if(!o?.[1]||o[2]===void 0)continue;let d=o[1].trim(),c=o[2].trim().replace(/^["']|["']$/g,"");if(d===n)t=c;else if(c.startsWith("encrypted:")||c.startsWith("enc:"))r=!0}return t&&r?t:void 0}function Zn(e={}){let n=e.cwd||process.cwd(),t=S(n,e.file||".env"),r=S(n,e.keysFile||".env.keys");if(!P(t))return{success:!1,error:`File not found: ${t}`};try{let i,s,o=on(N(t,"utf-8"),k(e.file).publicKeyName);if(o)i=o;else if(P(r)){let a=N(r,"utf-8"),{parsed:u}=h(a),{publicKeyName:f,privateKeyName:E}=k(e.file);if(i=u[f]||"",s=u[E]||"",!i||!s){let g=U();i=g.publicKey,s=g.privateKey;let l=`
9
11
  ${f}="${i}"
10
- ${p}="${s}"
11
- `;N(r,u+l,"utf-8")}}else{let u=k();i=u.publicKey,s=u.privateKey;let{publicKeyName:a,privateKeyName:f}=w(e.file),p=`# .env.keys - Keep this file secure and never commit to source control
12
- ${a}="${i}"
12
+ ${E}="${s}"
13
+ `;D(r,a+l,"utf-8")}}else{let a=U();i=a.publicKey,s=a.privateKey;let{publicKeyName:u,privateKeyName:f}=k(e.file),E=`# .env.keys - Keep this file secure and never commit to source control
14
+ ${u}="${i}"
13
15
  ${f}="${s}"
14
- `;N(r,p,"utf-8")}let d=A(t,"utf-8"),c=me(d,i,w(e.file).publicKeyName,e);if(e.stdout)return{success:!0,output:c};return N(t,c,"utf-8"),{success:!0,output:`\u2714 encrypted (${e.file||".env"})
15
- \u2714 key added to ${e.keysFile||".env.keys"}`}}catch(i){return{success:!1,error:`Failed to encrypt: ${i instanceof Error?i.message:"Unknown error"}`}}}function tn(e={}){let n=e.cwd||process.cwd(),t=O(n,e.file||".env"),r=O(n,e.keysFile||".env.keys");if(!I(t))return{success:!1,error:`File not found: ${t}`};if(!I(r))return{success:!1,error:`Keys file not found: ${r}`};try{let i=A(r,"utf-8"),{parsed:s}=S(i),c=((e.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),u=c?`DOTENV_PRIVATE_KEY_${c}`:"DOTENV_PRIVATE_KEY",a=s[u];if(!a)return{success:!1,error:`Private key not found: ${u}`};let f=[a];if(u!=="DOTENV_PRIVATE_KEY"&&s.DOTENV_PRIVATE_KEY&&s.DOTENV_PRIVATE_KEY!==a)f.push(s.DOTENV_PRIVATE_KEY);let E=A(t,"utf-8").split(`
16
- `),l=[];for(let v of E){let _=v.trim();if(!_||_.startsWith("#")){l.push(v);continue}if(_.startsWith("DOTENV_PUBLIC_KEY"))continue;let y=_.match(/^([^=]+)=(.*)$/);if(!y||y[1]===void 0||y[2]===void 0){l.push(v);continue}let m=y[1].trim(),R=y[2].trim();if(R.startsWith('"')&&R.endsWith('"')||R.startsWith("'")&&R.endsWith("'"))R=R.slice(1,-1);let L=R.startsWith("encrypted:");if(e.key&&!m.includes(e.key))L=!1;if(L){let P,D;for(let De of f)try{P=K(R,De);break}catch(Ce){D=Ce}if(P===void 0)throw D instanceof Error?D:Error(`Unable to decrypt ${m}`);R=P}l.push(`${m}="${R}"`)}let T=l.join(`
17
- `);if(e.stdout)return{success:!0,output:T};return N(t,T,"utf-8"),{success:!0,output:`\u2714 decrypted (${e.file||".env"})`}}catch(i){return{success:!1,error:`Failed to decrypt: ${i instanceof Error?i.message:"Unknown error"}`}}}function qn(e,n,t={}){let r=t.cwd||process.cwd(),i=O(r,t.file||".env"),s=O(r,t.keysFile||".env.keys");try{let o="";if(I(i))o=A(i,"utf-8");let d=o.split(`
18
- `),c=!1,u,p=((t.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),E=p?`DOTENV_PUBLIC_KEY_${p}`:"DOTENV_PUBLIC_KEY",l=p?`DOTENV_PRIVATE_KEY_${p}`:"DOTENV_PRIVATE_KEY";for(let _ of d){let y=_.trim();if(y.startsWith(`${E}=`)){let m=y.match(/^[^=]+=["']?([^"'\n]+)["']?/);if(m)u=m[1];break}}if(u){let _=!1;if(I(s)){let y=A(s,"utf-8"),{parsed:m}=S(y);_=Boolean(m[l])}if(!_&&!process.env[l]&&!ve(o,E))u=void 0}if(!t.plain&&!u){let _=k();u=_.publicKey;let y="";if(I(s))y=A(s,"utf-8");y+=`
19
- ${E}="${_.publicKey}"
20
- ${l}="${_.privateKey}"
21
- `,N(s,y,"utf-8");for(let m=d.length-1;m>=0;m--){let R=d[m];if(R!==void 0&&R.trim().startsWith(`${E}=`))d.splice(m,1)}d.unshift(`${E}="${u}"`)}let T=n;if(!t.plain&&u)T=B(n,u);for(let _=0;_<d.length;_++){let y=d[_];if(y===void 0)continue;if(y.trim().startsWith(`${e}=`)){d[_]=`${e}="${T}"`,c=!0;break}}if(!c)d.push(`${e}="${T}"`);let v=d.join(`
22
- `);return N(i,v,"utf-8"),{success:!0,output:`set ${e}${t.plain?"":" with encryption"} (${t.file||".env"})`}}catch(o){return{success:!1,error:`Failed to set: ${o instanceof Error?o.message:"Unknown error"}`}}}function zn(e,n={}){let t=n.cwd||process.cwd(),r=O(t,n.file||".env");if(!I(r))return{success:!1,error:`File not found: ${r}`};try{let i,s=O(t,n.keysFile||".env.keys"),c=((n.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),u=c?`DOTENV_PRIVATE_KEY_${c}`:"DOTENV_PRIVATE_KEY";if(I(s)){let l=A(s,"utf-8"),{parsed:T}=S(l);i=T[u]}if(!i)i=process.env[u];let a=A(r,"utf-8"),{parsed:f}=S(a,{privateKey:i});if(e&&!n.all){let l=f[e];if(l===void 0)return{success:!1,error:`Key not found: ${e}`};return{success:!0,output:l}}let p=n.all?{...process.env,...f}:f,E;switch(n.format){case"shell":E=Object.entries(p).map(([l,T])=>`${l}=${T}`).join(" ");break;case"eval":E=Object.entries(p).map(([l,T])=>`${l}="${T}"`).join(`
23
- `);break;case"json":default:E=n.prettyPrint?JSON.stringify(p,null,2):JSON.stringify(p);break}return{success:!0,output:E}}catch(i){return{success:!1,error:`Failed to get: ${i instanceof Error?i.message:"Unknown error"}`}}}function Jn(e,n={}){let t=n.cwd||process.cwd(),r=O(t,n.keysFile||".env.keys");if(!I(r))return{success:!1,error:`Keys file not found: ${r}`};try{let i=A(r,"utf-8"),{parsed:s}=S(i),c=((n.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),u=c?`DOTENV_PUBLIC_KEY_${c}`:"DOTENV_PUBLIC_KEY",a=c?`DOTENV_PRIVATE_KEY_${c}`:"DOTENV_PRIVATE_KEY";if(e){let E=s[e];if(!E)return{success:!1,error:`Key not found: ${e}`};return{success:!0,output:E}}let f={[u]:s[u],[a]:s[a]};return{success:!0,output:n.format==="shell"?`${u}=${f[u]} ${a}=${f[a]}`:JSON.stringify(f)}}catch(i){return{success:!1,error:`Failed to get keypair: ${i instanceof Error?i.message:"Unknown error"}`}}}function rn(e,n,t,r){let i=e.split(`
16
+ `;D(r,E,"utf-8")}let d=N(t,"utf-8"),c=Ae(d,i,k(e.file).publicKeyName,e);if(e.stdout)return{success:!0,output:c};return D(t,c,"utf-8"),{success:!0,output:`\u2714 encrypted (${e.file||".env"})
17
+ \u2714 key added to ${e.keysFile||".env.keys"}`}}catch(i){return{success:!1,error:`Failed to encrypt: ${i instanceof Error?i.message:"Unknown error"}`}}}function dn(e={}){let n=e.cwd||process.cwd(),t=S(n,e.file||".env"),r=S(n,e.keysFile||".env.keys");if(!P(t))return{success:!1,error:`File not found: ${t}`};if(!P(r))return{success:!1,error:`Keys file not found: ${r}`};try{let i=N(r,"utf-8"),{parsed:s}=h(i),c=((e.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),a=c?`DOTENV_PRIVATE_KEY_${c}`:"DOTENV_PRIVATE_KEY",u=s[a];if(!u)return{success:!1,error:`Private key not found: ${a}`};let f=[u];if(a!=="DOTENV_PRIVATE_KEY"&&s.DOTENV_PRIVATE_KEY&&s.DOTENV_PRIVATE_KEY!==u)f.push(s.DOTENV_PRIVATE_KEY);let g=N(t,"utf-8").split(`
18
+ `),l=[];for(let v of g){let T=v.trim();if(!T||T.startsWith("#")){l.push(v);continue}if(T.startsWith("DOTENV_PUBLIC_KEY"))continue;let O=T.match(/^([^=]+)=(.*)$/);if(!O||O[1]===void 0||O[2]===void 0){l.push(v);continue}let m=O[1].trim(),_=O[2].trim();if(_.startsWith('"')&&_.endsWith('"')||_.startsWith("'")&&_.endsWith("'"))_=_.slice(1,-1);let A=_.startsWith("encrypted:");if(e.key&&!m.includes(e.key))A=!1;if(A){let R,I;for(let G of f)try{R=L(_,G);break}catch(Ke){I=Ke}if(R===void 0)throw I instanceof Error?I:Error(`Unable to decrypt ${m}`);_=R}l.push(`${m}="${_}"`)}let y=l.join(`
19
+ `);if(e.stdout)return{success:!0,output:y};return D(t,y,"utf-8"),{success:!0,output:`\u2714 decrypted (${e.file||".env"})`}}catch(i){return{success:!1,error:`Failed to decrypt: ${i instanceof Error?i.message:"Unknown error"}`}}}function et(e,n,t={}){let r=t.cwd||process.cwd(),i=S(r,t.file||".env"),s=t.keysFile?S(r,t.keysFile):S(ne(i),".env.keys");try{let o="";if(P(i))o=N(i,"utf-8");let d=o.split(`
20
+ `),c=!1,a,E=((t.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),g=E?`DOTENV_PUBLIC_KEY_${E}`:"DOTENV_PUBLIC_KEY",l=E?`DOTENV_PRIVATE_KEY_${E}`:"DOTENV_PRIVATE_KEY",y=sn(o,t.file),v=y?.name??g;if(a=y?.key,a){let m=!1;if(P(s)){let A=N(s,"utf-8"),{parsed:R}=h(A);m=ee(t.file).some((I)=>Boolean(R[I]))}let _=ee(t.file).some((A)=>Boolean(process.env[A]));if(!m&&!_&&!ve(o))a=void 0}if(!t.plain&&!a&&ve(o))return{success:!1,error:`${t.file||".env"} already contains encrypted values, but no key that can be used to add another was found.
21
+ Generating one would leave every existing encrypted value unreadable.
22
+ Provide the private key as ${ee(t.file)[0]} in the environment, restore ${s}, or use --plain to write this value unencrypted.`};if(!t.plain&&!a){let m=U();a=m.publicKey;let _="";if(P(s))_=N(s,"utf-8");_+=`
23
+ ${g}="${m.publicKey}"
24
+ ${l}="${m.privateKey}"
25
+ `,D(s,_,"utf-8");let A=Se(t.file);for(let R=d.length-1;R>=0;R--){let I=d[R];if(I!==void 0&&A.some((G)=>I.trim().startsWith(`${G}=`)))d.splice(R,1)}d.unshift(`${v}="${a}"`)}let T=n;if(!t.plain&&a)T=B(n,a);for(let m=0;m<d.length;m++){let _=d[m];if(_===void 0)continue;if(_.trim().startsWith(`${e}=`)){d[m]=`${e}="${T}"`,c=!0;break}}if(!c)d.push(`${e}="${T}"`);let O=d.join(`
26
+ `);return D(i,O,"utf-8"),{success:!0,output:`set ${e}${t.plain?"":" with encryption"} (${t.file||".env"})`}}catch(o){return{success:!1,error:`Failed to set: ${o instanceof Error?o.message:"Unknown error"}`}}}function nt(e,n={}){let t=n.cwd||process.cwd(),r=S(t,n.file||".env");if(!P(r))return{success:!1,error:`File not found: ${r}`};try{let i,s=S(t,n.keysFile||".env.keys"),c=((n.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),a=c?`DOTENV_PRIVATE_KEY_${c}`:"DOTENV_PRIVATE_KEY";if(P(s)){let l=N(s,"utf-8"),{parsed:y}=h(l);i=y[a]}if(!i)i=process.env[a];let u=N(r,"utf-8"),{parsed:f}=h(u,{privateKey:i});if(e&&!n.all){let l=f[e];if(l===void 0)return{success:!1,error:`Key not found: ${e}`};return{success:!0,output:l}}let E=n.all?{...process.env,...f}:f,g;switch(n.format){case"shell":g=Object.entries(E).map(([l,y])=>`${l}=${y}`).join(" ");break;case"eval":g=Object.entries(E).map(([l,y])=>`${l}="${y}"`).join(`
27
+ `);break;case"json":default:g=n.prettyPrint?JSON.stringify(E,null,2):JSON.stringify(E);break}return{success:!0,output:g}}catch(i){return{success:!1,error:`Failed to get: ${i instanceof Error?i.message:"Unknown error"}`}}}function tt(e,n={}){let t=n.cwd||process.cwd(),r=S(t,n.keysFile||".env.keys");if(!P(r))return{success:!1,error:`Keys file not found: ${r}`};try{let i=N(r,"utf-8"),{parsed:s}=h(i),c=((n.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),a=c?`DOTENV_PUBLIC_KEY_${c}`:"DOTENV_PUBLIC_KEY",u=c?`DOTENV_PRIVATE_KEY_${c}`:"DOTENV_PRIVATE_KEY";if(e){let g=s[e];if(!g)return{success:!1,error:`Key not found: ${e}`};return{success:!0,output:g}}let f={[a]:s[a],[u]:s[u]};return{success:!0,output:n.format==="shell"?`${a}=${f[a]} ${u}=${f[u]}`:JSON.stringify(f)}}catch(i){return{success:!1,error:`Failed to get keypair: ${i instanceof Error?i.message:"Unknown error"}`}}}function cn(e,n,t,r){let i=e.split(`
24
28
  `),s=!1,o=!1;for(let d=0;d<i.length;d++){let c=i[d];if(c===void 0)continue;if(c.startsWith(`${t}=`))i[d]=`${t}="${n.publicKey}"`,s=!0;else if(c.startsWith(`${r}=`))i[d]=`${r}="${n.privateKey}"`,o=!0}if(!s)i.push(`${t}="${n.publicKey}"`);if(!o)i.push(`${r}="${n.privateKey}"`);return`${i.join(`
25
29
  `).replace(/\n+$/,"")}
26
- `}function Zn(e={}){let n=tn({file:e.file,keysFile:e.keysFile,stdout:!0,cwd:e.cwd});if(!n.success)return n;if(n.output===void 0)return{success:!1,error:"Rotation produced no decrypted content"};let t=e.cwd||process.cwd(),r=e.file||".env",i=e.keysFile||".env.keys",s=O(t,r),o=O(t,i),{publicKeyName:d,privateKeyName:c}=w(e.file);if(e.dryRun){let _=nn(n.output,e);return{success:!0,output:["Dry run: nothing was written.",`${r}: ${_.length} value${_.length===1?"":"s"} would be re-encrypted under a new ${d}.`,`${i}: ${d} and ${c} would be replaced.`,`The current ${c} decrypts nothing once that happens, so keep a copy until the rotation is verified.`].join(`
27
- `)}}let u=k(),a=me(n.output,u.publicKey,d,e);if(e.stdout)return{success:!0,output:a,notice:[`Nothing was written. To adopt the output above, put this keypair in ${i}:`,"",`${d}="${u.publicKey}"`,`${c}="${u.privateKey}"`,"","Without it that output cannot be decrypted. Run without --stdout to have both applied together."].join(`
28
- `)};let f=A(s),p=A(o),E=rn(p.toString("utf8"),u,d,c),l=`${process.pid}-${Date.now()}`,T=O(ye(s),`.${Te(s)}.${l}.rotate`),v=O(ye(o),`.${Te(o)}.${l}.rotate`);try{N(T,a,{encoding:"utf8",mode:384}),N(v,E,{encoding:"utf8",mode:384}),ge(T,s);try{ge(v,o)}catch(_){throw N(s,f),_}return{success:!0,output:`\u2714 rotated (${r}) to encrypted:v2`}}catch(_){if(!I(o))N(o,p,{mode:384});return{success:!1,error:`Failed to rotate without exposing plaintext: ${_ instanceof Error?_.message:"Unknown error"}`}}finally{_e(T,{force:!0}),_e(v,{force:!0})}}function sn(e){return typeof e==="string"&&(e.startsWith("encrypted:")||e.startsWith("enc:"))}var on=/(?:^|_)(?:PASSWORD|PASSWD|SECRET|TOKEN|APIKEY|API_KEY|CREDENTIAL|CREDENTIALS|PRIVATE|SALT|DSN|CERT|CIPHER|SIGNATURE|WEBHOOK)(?:_|$)|(?:^|_)(?:ACCESS|SECRET)_KEY(?:_|$)|_KEY$/,dn=/^DOTENV_(?:PUBLIC|PRIVATE)_KEY/,cn=/^\$\{[^}]+\}$/;function nt(e,n={}){let{placeholders:t={},strict:r=!1}=n,i=[];for(let[s,o]of Object.entries(e)){if(!o||o.trim()==="")continue;if(sn(o))continue;if(dn.test(s))continue;if(cn.test(o.trim()))continue;let d=on.test(s),c=Object.prototype.hasOwnProperty.call(t,s)&&t[s]===o;if(d&&!c){i.push({key:s,reason:"plaintext-secret"});continue}if(r)i.push({key:s,reason:"plaintext-value"})}return i}function tt(e){return e.split(`
29
- `).map((n)=>n.trim()).filter(Boolean).filter((n)=>n!==".env.example").filter((n)=>/(?:^|\/)\.env(?:\.|$)/.test(n)).filter((n)=>!n.endsWith(".env.keys"))}function Oe(e){return`${e.replace(/[^a-z0-9]/gi,"").toUpperCase()}_`}function an(e,n={}){let t=n.self?Oe(n.self):void 0,r=(n.tenants??[]).filter((o)=>typeof o==="string"&&o.trim().length>0).map((o)=>({slug:o,prefix:Oe(o)})).filter(({prefix:o})=>o!==t).sort((o,d)=>d.prefix.length-o.prefix.length),i={},s={};for(let[o,d]of Object.entries(e)){let c=r.find(({prefix:u})=>o.startsWith(u));if(c){(s[c.slug]??={})[o]=d;continue}i[o]=d}return{own:i,foreign:s}}function it(e,n={}){return an(e,n).own}function st(e){return Object.entries(e.foreign).map(([n,t])=>({tenant:n,keys:Object.keys(t).sort()})).sort((n,t)=>n.tenant.localeCompare(t.tenant))}import g from"process";import{platform as un}from"os";var Ae=typeof Bun<"u",Se=typeof g<"u"&&g.versions?.node!==void 0,fn=Ae?"bun":Se?"node":"unknown",at={name:fn,version:Ae?Bun.version:Se?g.version:void 0},ee=un(),ut=ee==="win32",ft=ee==="darwin",Et=ee==="linux",Ie=Boolean(g.stdout?.isTTY),lt=typeof globalThis.window<"u",En=Boolean(g.env.CI||g.env.CONTINUOUS_INTEGRATION||g.env.BUILD_NUMBER||g.env.RUN_ID),pt=Boolean(g.env.DEBUG||g.env.VERBOSE||g.argv.includes("--debug")||g.argv.includes("--verbose")),ln=En||!Ie,gt=Boolean(!ln&&(Ie||g.env.COLORTERM||g.env.FORCE_COLOR||g.env.TERM&&g.env.TERM!=="dumb")),Z={github:{name:"GitHub Actions",detected:Boolean(g.env.GITHUB_ACTIONS)},gitlab:{name:"GitLab CI",detected:Boolean(g.env.GITLAB_CI)},circle:{name:"CircleCI",detected:Boolean(g.env.CIRCLECI)},travis:{name:"Travis CI",detected:Boolean(g.env.TRAVIS)},jenkins:{name:"Jenkins",detected:Boolean(g.env.JENKINS_URL)},vercel:{name:"Vercel",detected:Boolean(g.env.VERCEL)},netlify:{name:"Netlify",detected:Boolean(g.env.NETLIFY)},heroku:{name:"Heroku",detected:Boolean(g.env.DYNO)},aws:{name:"AWS",detected:Boolean(g.env.AWS_REGION||g.env.AWS_LAMBDA_FUNCTION_NAME)},azure:{name:"Azure",detected:Boolean(g.env.AZURE_HTTP_USER_AGENT)},cloudflare:{name:"Cloudflare",detected:Boolean(g.env.CF_PAGES)},railway:{name:"Railway",detected:Boolean(g.env.RAILWAY_ENVIRONMENT)},render:{name:"Render",detected:Boolean(g.env.RENDER)}},pn=Object.keys(Z).find((e)=>{let n=Z[e];return n!==void 0&&n.detected})||"unknown",_t=Z[pn]||{name:"Unknown",detected:!1};var he=new Set;function Tn(e){if(he.has(e))return;he.add(e);let n=J();console.warn(`[env] warning: "${e}" is encrypted but no usable private key was found for the "${n}" environment; falling back to its default. Set DOTENV_PRIVATE_KEY_${n.toUpperCase()} or ship .env.keys.`)}var yn={get:(e,n)=>{let t=e,r=t[n];if(typeof r==="string"&&(r.startsWith("encrypted:")||r.startsWith("enc:"))){let s=Ee(r);if(s===void 0){Tn(n),delete t[n];return}t[n]=s,r=s}let i=["_PORT","_TIMEOUT","_TTL","_SIZE","_LIMIT","_MAX","_MIN","_INTERVAL","_RETRIES","_CONCURRENCY","_WORKERS","_CONNECTIONS"];if(typeof r==="string"&&/^\d+$/.test(r)&&!r.startsWith("0")&&i.some((s)=>n.endsWith(s)))return Number(r);if(typeof r==="string"){let s=r.toLowerCase();if(s==="true")return!0;if(s==="false")return!1}return r},set:(e,n,t)=>Reflect.set(e,n,t,e),deleteProperty:(e,n)=>Reflect.deleteProperty(e,n)};function Rn(){return typeof Bun<"u"?Bun.env:gn.env}var Pe=new Proxy(Rn(),yn);function At(e,n,t){let r=t?.path||_n(".env"),s=Ne.readFileSync(r,"utf-8").split(`
30
- `),o=s.findIndex((u)=>u.startsWith(`${e}=`)),c=/[\s"'#$\\]/.test(n)?`"${n.replace(/"/g,"\\\"")}"`:n;if(o!==-1)s[o]=`${e}=${c}`;else s.push(`${e}=${c}`);Ne.writeFileSync(r,s.join(`
31
- `))}function St(e=Pe){let n=[],t=e;for(let[r,i]of Object.entries(pe)){let s=t[r];if(s!==void 0&&s!==""&&!i.includes(String(s)))n.push(`${r}="${s}" is not valid. Allowed values: ${i.join(", ")}`)}return n}function It(e,n=Pe){let t=[],r=n;for(let i of e){let s=r[i];if(s===void 0||s===""||s===null)t.push(i)}if(t.length>0)throw Error(`[env] Missing required environment variable(s): ${t.join(", ")}. Set them in .env or your process environment before booting.`);return n}export{on as SECRET_NAME_PATTERN,J as activeEnvName,Le as aesDecrypt,vn as aesEncrypt,Bn as autoLoadEnv,tn as decryptEnv,Ee as decryptEnvValue,K as decryptValue,Fn as defineEnv,Qn as encryptEnv,B as encryptValue,Pe as env,pe as envEnum,w as envKeyNames,en as envPlugin,st as foreignTenantKeys,k as generateKeypair,zn as getEnv,Jn as getKeypair,q as getPrivateKey,Ie as hasTTY,lt as hasWindow,Ae as isBun,En as isCI,gt as isColorSupported,pt as isDebug,sn as isEncryptedValue,On as isLegacyEncryptedValue,Et as isLinux,ft as isMacOS,ln as isMinimal,Se as isNode,ut as isWindows,le as loadEnv,bn as loadEnvFiles,An as migrateEncryptedValue,S as parse,Sn as parseEnvFromKey,an as partitionTenantEnv,nt as plaintextSecrets,ee as platform,Rn as process,pn as provider,_t as providerInfo,It as requireEnv,xn as resetPrivateKeyCache,Xn as resolveEnvFile,Ze as resolvePrivateKey,ve as reusableEnvPublicKey,Zn as rotateKeypair,fn as runtime,at as runtimeInfo,qn as setEnv,it as stripForeignTenantEnv,Oe as tenantEnvPrefix,tt as trackedEnvFiles,St as validateEnv,At as writeEnv};
30
+ `}function rt(e={}){let n=dn({file:e.file,keysFile:e.keysFile,stdout:!0,cwd:e.cwd});if(!n.success)return n;if(n.output===void 0)return{success:!1,error:"Rotation produced no decrypted content"};let t=e.cwd||process.cwd(),r=e.file||".env",i=e.keysFile||".env.keys",s=S(t,r),o=S(t,i),{publicKeyName:d,privateKeyName:c}=k(e.file);if(e.dryRun){let T=rn(n.output,e);return{success:!0,output:["Dry run: nothing was written.",`${r}: ${T.length} value${T.length===1?"":"s"} would be re-encrypted under a new ${d}.`,`${i}: ${d} and ${c} would be replaced.`,`The current ${c} decrypts nothing once that happens, so keep a copy until the rotation is verified.`].join(`
31
+ `)}}let a=U(),u=Ae(n.output,a.publicKey,d,e);if(e.stdout)return{success:!0,output:u,notice:[`Nothing was written. To adopt the output above, put this keypair in ${i}:`,"",`${d}="${a.publicKey}"`,`${c}="${a.privateKey}"`,"","Without it that output cannot be decrypted. Run without --stdout to have both applied together."].join(`
32
+ `)};let f=N(s),E=N(o),g=cn(E.toString("utf8"),a,d,c),l=`${process.pid}-${Date.now()}`,y=S(ne(s),`.${Re(s)}.${l}.rotate`),v=S(ne(o),`.${Re(o)}.${l}.rotate`);try{D(y,u,{encoding:"utf8",mode:384}),D(v,g,{encoding:"utf8",mode:384}),Te(y,s);try{Te(v,o)}catch(T){throw D(s,f),T}return{success:!0,output:`\u2714 rotated (${r}) to encrypted:v2`}}catch(T){if(!P(o))D(o,E,{mode:384});return{success:!1,error:`Failed to rotate without exposing plaintext: ${T instanceof Error?T.message:"Unknown error"}`}}finally{me(y,{force:!0}),me(v,{force:!0})}}function an(e){return typeof e==="string"&&(e.startsWith("encrypted:")||e.startsWith("enc:"))}var un=/(?:^|_)(?:PASSWORD|PASSWD|SECRET|TOKEN|APIKEY|API_KEY|CREDENTIAL|CREDENTIALS|PRIVATE|SALT|DSN|CERT|CIPHER|SIGNATURE|WEBHOOK)(?:_|$)|(?:^|_)(?:ACCESS|SECRET)_KEY(?:_|$)|_KEY$/,fn=/^DOTENV_(?:PUBLIC|PRIVATE)_KEY/,En=/^\$\{[^}]+\}$/;function st(e,n={}){let{placeholders:t={},strict:r=!1}=n,i=[];for(let[s,o]of Object.entries(e)){if(!o||o.trim()==="")continue;if(an(o))continue;if(fn.test(s))continue;if(En.test(o.trim()))continue;let d=un.test(s),c=Object.prototype.hasOwnProperty.call(t,s)&&t[s]===o;if(d&&!c){i.push({key:s,reason:"plaintext-secret"});continue}if(r)i.push({key:s,reason:"plaintext-value"})}return i}function ot(e){return e.split(`
33
+ `).map((n)=>n.trim()).filter(Boolean).filter((n)=>n!==".env.example").filter((n)=>/(?:^|\/)\.env(?:\.|$)/.test(n)).filter((n)=>!n.endsWith(".env.keys"))}function Ie(e){return`${e.replace(/[^a-z0-9]/gi,"").toUpperCase()}_`}function ln(e,n={}){let t=n.self?Ie(n.self):void 0,r=(n.tenants??[]).filter((o)=>typeof o==="string"&&o.trim().length>0).map((o)=>({slug:o,prefix:Ie(o)})).filter(({prefix:o})=>o!==t).sort((o,d)=>d.prefix.length-o.prefix.length),i={},s={};for(let[o,d]of Object.entries(e)){let c=r.find(({prefix:a})=>o.startsWith(a));if(c){(s[c.slug]??={})[o]=d;continue}i[o]=d}return{own:i,foreign:s}}function ct(e,n={}){return ln(e,n).own}function at(e){return Object.entries(e.foreign).map(([n,t])=>({tenant:n,keys:Object.keys(t).sort()})).sort((n,t)=>n.tenant.localeCompare(t.tenant))}import p from"process";import{platform as pn}from"os";var Ne=typeof Bun<"u",he=typeof p<"u"&&p.versions?.node!==void 0,gn=Ne?"bun":he?"node":"unknown",lt={name:gn,version:Ne?Bun.version:he?p.version:void 0},re=pn(),pt=re==="win32",gt=re==="darwin",_t=re==="linux",Pe=Boolean(p.stdout?.isTTY),yt=typeof globalThis.window<"u",_n=Boolean(p.env.CI||p.env.CONTINUOUS_INTEGRATION||p.env.BUILD_NUMBER||p.env.RUN_ID),Tt=Boolean(p.env.DEBUG||p.env.VERBOSE||p.argv.includes("--debug")||p.argv.includes("--verbose")),yn=_n||!Pe,mt=Boolean(!yn&&(Pe||p.env.COLORTERM||p.env.FORCE_COLOR||p.env.TERM&&p.env.TERM!=="dumb")),te={github:{name:"GitHub Actions",detected:Boolean(p.env.GITHUB_ACTIONS)},gitlab:{name:"GitLab CI",detected:Boolean(p.env.GITLAB_CI)},circle:{name:"CircleCI",detected:Boolean(p.env.CIRCLECI)},travis:{name:"Travis CI",detected:Boolean(p.env.TRAVIS)},jenkins:{name:"Jenkins",detected:Boolean(p.env.JENKINS_URL)},vercel:{name:"Vercel",detected:Boolean(p.env.VERCEL)},netlify:{name:"Netlify",detected:Boolean(p.env.NETLIFY)},heroku:{name:"Heroku",detected:Boolean(p.env.DYNO)},aws:{name:"AWS",detected:Boolean(p.env.AWS_REGION||p.env.AWS_LAMBDA_FUNCTION_NAME)},azure:{name:"Azure",detected:Boolean(p.env.AZURE_HTTP_USER_AGENT)},cloudflare:{name:"Cloudflare",detected:Boolean(p.env.CF_PAGES)},railway:{name:"Railway",detected:Boolean(p.env.RAILWAY_ENVIRONMENT)},render:{name:"Render",detected:Boolean(p.env.RENDER)}},Tn=Object.keys(te).find((e)=>{let n=te[e];return n!==void 0&&n.detected})||"unknown",Rt=te[Tn]||{name:"Unknown",detected:!1};var Ce=new Set;function vn(e){if(Ce.has(e))return;Ce.add(e);let n=Z();console.warn(`[env] warning: "${e}" is encrypted but no usable private key was found for the "${n}" environment; falling back to its default. Set DOTENV_PRIVATE_KEY_${n.toUpperCase()} or ship .env.keys.`)}var On={get:(e,n)=>{let t=e,r=t[n];if(typeof r==="string"&&(r.startsWith("encrypted:")||r.startsWith("enc:"))){let s=ge(r);if(s===void 0){vn(n),delete t[n];return}t[n]=s,r=s}let i=["_PORT","_TIMEOUT","_TTL","_SIZE","_LIMIT","_MAX","_MIN","_INTERVAL","_RETRIES","_CONCURRENCY","_WORKERS","_CONNECTIONS"];if(typeof r==="string"&&/^\d+$/.test(r)&&!r.startsWith("0")&&i.some((s)=>n.endsWith(s)))return Number(r);if(typeof r==="string"){let s=r.toLowerCase();if(s==="true")return!0;if(s==="false")return!1}return r},set:(e,n,t)=>Reflect.set(e,n,t,e),deleteProperty:(e,n)=>Reflect.deleteProperty(e,n)};function An(){return typeof Bun<"u"?Bun.env:mn.env}var be=new Proxy(An(),On);function ht(e,n,t){let r=t?.path||Rn(".env"),s=De.readFileSync(r,"utf-8").split(`
34
+ `),o=s.findIndex((a)=>a.startsWith(`${e}=`)),c=/[\s"'#$\\]/.test(n)?`"${n.replace(/"/g,"\\\"")}"`:n;if(o!==-1)s[o]=`${e}=${c}`;else s.push(`${e}=${c}`);De.writeFileSync(r,s.join(`
35
+ `))}function Pt(e=be){let n=[],t=e;for(let[r,i]of Object.entries(ye)){let s=t[r];if(s!==void 0&&s!==""&&!i.includes(String(s)))n.push(`${r}="${s}" is not valid. Allowed values: ${i.join(", ")}`)}return n}function Dt(e,n=be){let t=[],r=n;for(let i of e){let s=r[i];if(s===void 0||s===""||s===null)t.push(i)}if(t.length>0)throw Error(`[env] Missing required environment variable(s): ${t.join(", ")}. Set them in .env or your process environment before booting.`);return n}export{un as SECRET_NAME_PATTERN,Z as activeEnvName,ke as aesDecrypt,In as aesEncrypt,Yn as autoLoadEnv,sn as declaredEnvPublicKey,dn as decryptEnv,ge as decryptEnvValue,L as decryptValue,Hn as defineEnv,Zn as encryptEnv,B as encryptValue,be as env,ye as envEnum,ve as envHasCiphertext,k as envKeyNames,tn as envPlugin,ee as envPrivateKeyNames,Se as envPublicKeyNames,at as foreignTenantKeys,U as generateKeypair,nt as getEnv,tt as getKeypair,z as getPrivateKey,Pe as hasTTY,yt as hasWindow,Ne as isBun,_n as isCI,mt as isColorSupported,Tt as isDebug,an as isEncryptedValue,Nn as isLegacyEncryptedValue,_t as isLinux,gt as isMacOS,yn as isMinimal,he as isNode,pt as isWindows,_e as loadEnv,Un as loadEnvFiles,hn as migrateEncryptedValue,h as parse,Pn as parseEnvFromKey,ln as partitionTenantEnv,st as plaintextSecrets,re as platform,An as process,Tn as provider,Rt as providerInfo,Dt as requireEnv,Fn as resetPrivateKeyCache,Jn as resolveEnvFile,nn as resolvePrivateKey,on as reusableEnvPublicKey,rt as rotateKeypair,gn as runtime,lt as runtimeInfo,et as setEnv,ct as stripForeignTenantEnv,Ie as tenantEnvPrefix,ot as trackedEnvFiles,Pt as validateEnv,ht as writeEnv};
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/env",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.74.32",
5
+ "version": "0.74.34",
6
6
  "description": "Stacks env helper methods.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -56,10 +56,10 @@
56
56
  "prepublishOnly": "bun run build"
57
57
  },
58
58
  "dependencies": {
59
- "@stacksjs/path": "0.74.32"
59
+ "@stacksjs/path": "0.74.34"
60
60
  },
61
61
  "devDependencies": {
62
62
  "better-dx": "^0.2.24",
63
- "@stacksjs/validation": "0.74.32"
63
+ "@stacksjs/validation": "0.74.34"
64
64
  }
65
65
  }