@stacksjs/env 0.70.45 → 0.70.54

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/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ # MIT License
2
+
3
+ Copyright (c) 2023 Open Web Foundation
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/cli.js ADDED
@@ -0,0 +1,23 @@
1
+ // @bun
2
+ import{createCipheriv as S,createDecipheriv as b,createHash as f,randomBytes as x}from"crypto";function P(j,I){let Y=x(16),X=I.length===32?I:Buffer.from(I.toString("hex").slice(0,64),"hex"),q=S("aes-256-gcm",X,Y),Q=Buffer.concat([q.update(j,"utf8"),q.final()]),U=q.getAuthTag();return{ciphertext:Q.toString("hex"),iv:Y.toString("hex"),authTag:U.toString("hex")}}function N(j,I,Y,X){let q=I.length===32?I:Buffer.from(I.toString("hex").slice(0,64),"hex");try{let Q=b("aes-256-gcm",q,Buffer.from(Y,"hex"));return Q.setAuthTag(Buffer.from(X,"hex")),Buffer.concat([Q.update(Buffer.from(j,"hex")),Q.final()]).toString("utf8")}catch(Q){throw Error(`Decryption failed (data may be corrupted or key is incorrect): ${Q instanceof Error?Q.message:String(Q)}`)}}function F(){let j=x(32);return{publicKey:f("sha256").update(j).digest().toString("hex"),privateKey:j.toString("hex")}}function V(j,I){let Y=f("sha256").update(Buffer.from(I,"hex")).digest(),{ciphertext:X,iv:q,authTag:Q}=P(j,Y);return`encrypted:${Buffer.concat([Buffer.from(q,"hex"),Buffer.from(Q,"hex"),Buffer.from(X,"hex")]).toString("base64")}`}function w(j,I){if(!j.startsWith("encrypted:"))return j;let Y=j.slice(10),X=Buffer.from(Y,"base64");if(X.length<32)throw Error("Invalid encrypted data: payload too short (need at least iv + authTag = 32 bytes)");let q=X.subarray(0,16).toString("hex"),Q=X.subarray(16,32).toString("hex"),U=X.subarray(32).toString("hex"),$=f("sha256").update(Buffer.from(I,"hex")).digest(),Z=f("sha256").update($).digest();return N(U,Z,q,Q)}function v(j){let I=j.match(/^DOTENV_PRIVATE_KEY_(.+)$/);return I&&I[1]?I[1].toLowerCase():""}function c(j=""){if(!j)return process.env.DOTENV_PRIVATE_KEY;let I=`DOTENV_PRIVATE_KEY_${j.toUpperCase()}`;return process.env[I]}function C(j,I={}){let Y={},X=[],q=j.split(`
3
+ `);for(let Q of q){let U=Q.trim();if(!U||U.startsWith("#"))continue;if(U.startsWith("DOTENV_PUBLIC_KEY=")){let A=U.match(/^DOTENV_PUBLIC_KEY=["']?([^"'\n]+)["']?/);if(A&&A[1]!==void 0)Y.DOTENV_PUBLIC_KEY=A[1];continue}let $=U.match(/^([^=]+)=(.*)$/);if(!$||$[1]===void 0||$[2]===void 0)continue;let Z=$[1].trim(),J=$[2].trim();if(J.startsWith('"')&&J.endsWith('"')||J.startsWith("'")&&J.endsWith("'")){if(J=J.slice(1,-1),J.includes("\\n"))J=J.replace(/\\n/g,`
4
+ `)}if(I.privateKey&&(J.startsWith("encrypted:")||J.startsWith("enc:")))try{let A=J.startsWith("enc:")?`encrypted:${J.slice(4)}`:J;J=w(A,I.privateKey)}catch(A){X.push(`Failed to decrypt ${Z}: ${A instanceof Error?A.message:"Unknown error"}`)}J=K(J,{...I.processEnv||process.env,...Y}),J=h(J),Y[Z]=J}return{parsed:Y,errors:X}}function K(j,I){return j.replace(/\$\{([^}]+)\}/g,(Y,X)=>{let q=X.match(/^([^:\-+]+)(:-|-)(.+)$/);if(q){let[,U,$,Z]=q,J=I[U];if($===":-")return J||Z;else return J!==void 0?J:Z}let Q=X.match(/^([^:\-+]+)(:?\+)(.+)$/);if(Q){let[,U,$,Z]=Q,J=I[U];if($===":+")return J?Z:"";else return J!==void 0?Z:""}return I[X]||""})}var m=new Set(["date","hostname","whoami","uname","pwd","echo","printf","cat","basename","dirname"]);function h(j){return j.replace(/\$\(([^)]+)\)/g,(I,Y)=>{try{let X=Y.trim().split(/\s+/),q=X[0];if(!q||!m.has(q))return console.warn(`[env] Blocked command substitution for disallowed command: ${q}`),"";let Q=Bun.spawnSync(X,{stdout:"pipe",stderr:"pipe"});if(Q.exitCode===0)return new TextDecoder().decode(Q.stdout).trim();console.warn(`[env] Command substitution failed (exit code ${Q.exitCode}): ${q}`)}catch(X){console.warn(`[env] Command substitution error: ${X instanceof Error?X.message:String(X)}`)}return""})}async function s(j,I={}){let Y={},X=[];for(let q of j)try{let Q=Bun.file(q);if(!Q.size)continue;let U=await Q.text(),{parsed:$,errors:Z}=C(U,I);X.push(...Z);for(let[J,A]of Object.entries($)){if(!I.overload&&Y[J]!==void 0)continue;Y[J]=A}}catch(Q){if(Q?.code==="ENOENT")continue;X.push(`Failed to read ${q}: ${Q instanceof Error?Q.message:String(Q)}`)}return{parsed:Y,errors:X}}import{existsSync as g,readFileSync as D,writeFileSync as E}from"fs";import{resolve as M}from"path";function k(j={}){let I=j.cwd||process.cwd(),Y=M(I,j.file||".env"),X=M(I,j.keysFile||".env.keys");if(!g(Y))return{success:!1,error:`File not found: ${Y}`};try{let q,Q;if(g(X)){let G=D(X,"utf-8"),{parsed:O}=C(G),W=((j.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),z=W?`DOTENV_PUBLIC_KEY_${W}`:"DOTENV_PUBLIC_KEY",R=W?`DOTENV_PRIVATE_KEY_${W}`:"DOTENV_PRIVATE_KEY";if(q=O[z]||"",Q=O[R]||"",!q||!Q){let _=F();q=_.publicKey,Q=_.privateKey;let L=`
5
+ ${z}="${q}"
6
+ ${R}="${Q}"
7
+ `;E(X,G+L,"utf-8")}}else{let G=F();q=G.publicKey,Q=G.privateKey;let B=((j.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),W=B?`DOTENV_PUBLIC_KEY_${B}`:"DOTENV_PUBLIC_KEY",z=B?`DOTENV_PRIVATE_KEY_${B}`:"DOTENV_PRIVATE_KEY",R=`# .env.keys - Keep this file secure and never commit to source control
8
+ ${W}="${q}"
9
+ ${z}="${Q}"
10
+ `;E(X,R,"utf-8")}let $=D(Y,"utf-8").split(`
11
+ `),Z=[],J=j.file?j.file.replace(/^\.env\./,"").toUpperCase():"",A=J?`DOTENV_PUBLIC_KEY_${J}`:"DOTENV_PUBLIC_KEY";Z.push("#/-------------------[DOTENV_PUBLIC_KEY]--------------------/"),Z.push("#/ public-key encryption for .env files /"),Z.push("#/ [how it works](https://stacksjs.com/encryption) /"),Z.push("#/----------------------------------------------------------/"),Z.push(`${A}="${q}"`),Z.push("");for(let G of $){let O=G.trim();if(!O||O.startsWith("#")){Z.push(G);continue}if(O.startsWith("DOTENV_PUBLIC_KEY"))continue;let H=O.match(/^([^=]+)=(.*)$/);if(!H||H[1]===void 0||H[2]===void 0){Z.push(G);continue}let B=H[1].trim(),W=H[2].trim();if(W.startsWith('"')&&W.endsWith('"')||W.startsWith("'")&&W.endsWith("'"))W=W.slice(1,-1);let z=!0;if(j.key&&!B.includes(j.key))z=!1;if(j.excludeKey&&B.includes(j.excludeKey))z=!1;if(W.startsWith("encrypted:"))z=!1;if(z)W=V(W,q);Z.push(`${B}="${W}"`)}let T=Z.join(`
12
+ `);if(j.stdout)return{success:!0,output:T};return E(Y,T,"utf-8"),{success:!0,output:`\u2714 encrypted (${j.file||".env"})
13
+ \u2714 key added to ${j.keysFile||".env.keys"}`}}catch(q){return{success:!1,error:`Failed to encrypt: ${q instanceof Error?q.message:"Unknown error"}`}}}function d(j={}){let I=j.cwd||process.cwd(),Y=M(I,j.file||".env"),X=M(I,j.keysFile||".env.keys");if(!g(Y))return{success:!1,error:`File not found: ${Y}`};if(!g(X))return{success:!1,error:`Keys file not found: ${X}`};try{let q=D(X,"utf-8"),{parsed:Q}=C(q),Z=((j.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),J=Z?`DOTENV_PRIVATE_KEY_${Z}`:"DOTENV_PRIVATE_KEY",A=Q[J];if(!A)return{success:!1,error:`Private key not found: ${J}`};let G=D(Y,"utf-8").split(`
14
+ `),O=[];for(let B of G){let W=B.trim();if(!W||W.startsWith("#")){O.push(B);continue}if(W.startsWith("DOTENV_PUBLIC_KEY"))continue;let z=W.match(/^([^=]+)=(.*)$/);if(!z||z[1]===void 0||z[2]===void 0){O.push(B);continue}let R=z[1].trim(),_=z[2].trim();if(_.startsWith('"')&&_.endsWith('"')||_.startsWith("'")&&_.endsWith("'"))_=_.slice(1,-1);let L=_.startsWith("encrypted:");if(j.key&&!R.includes(j.key))L=!1;if(L)_=w(_,A);O.push(`${R}="${_}"`)}let H=O.join(`
15
+ `);if(j.stdout)return{success:!0,output:H};return E(Y,H,"utf-8"),{success:!0,output:`\u2714 decrypted (${j.file||".env"})`}}catch(q){return{success:!1,error:`Failed to decrypt: ${q instanceof Error?q.message:"Unknown error"}`}}}function i(j,I,Y={}){let X=Y.cwd||process.cwd(),q=M(X,Y.file||".env"),Q=M(X,Y.keysFile||".env.keys");try{let U="";if(g(q))U=D(q,"utf-8");let $=U.split(`
16
+ `),Z=!1,J,G=((Y.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),O=G?`DOTENV_PUBLIC_KEY_${G}`:"DOTENV_PUBLIC_KEY",H=G?`DOTENV_PRIVATE_KEY_${G}`:"DOTENV_PRIVATE_KEY";for(let z of $){let R=z.trim();if(R.startsWith(`${O}=`)){let _=R.match(/^[^=]+=["']?([^"'\n]+)["']?/);if(_)J=_[1];break}}if(J){let z=!1;if(g(Q)){let R=D(Q,"utf-8"),{parsed:_}=C(R);z=Boolean(_[H])}if(!z)J=void 0}if(!Y.plain&&!J){let z=F();J=z.publicKey;let R="";if(g(Q))R=D(Q,"utf-8");R+=`
17
+ ${O}="${z.publicKey}"
18
+ ${H}="${z.privateKey}"
19
+ `,E(Q,R,"utf-8");for(let _=$.length-1;_>=0;_--){let L=$[_];if(L!==void 0&&L.trim().startsWith(`${O}=`))$.splice(_,1)}$.unshift(`${O}="${J}"`)}let B=I;if(!Y.plain&&J)B=V(I,J);for(let z=0;z<$.length;z++){let R=$[z];if(R===void 0)continue;if(R.trim().startsWith(`${j}=`)){$[z]=`${j}="${B}"`,Z=!0;break}}if(!Z)$.push(`${j}="${B}"`);let W=$.join(`
20
+ `);return E(q,W,"utf-8"),{success:!0,output:`set ${j}${Y.plain?"":" with encryption"} (${Y.file||".env"})`}}catch(U){return{success:!1,error:`Failed to set: ${U instanceof Error?U.message:"Unknown error"}`}}}function t(j,I={}){let Y=I.cwd||process.cwd(),X=M(Y,I.file||".env");if(!g(X))return{success:!1,error:`File not found: ${X}`};try{let q,Q=M(Y,I.keysFile||".env.keys"),Z=((I.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),J=Z?`DOTENV_PRIVATE_KEY_${Z}`:"DOTENV_PRIVATE_KEY";if(g(Q)){let H=D(Q,"utf-8"),{parsed:B}=C(H);q=B[J]}if(!q)q=process.env[J];let A=D(X,"utf-8"),{parsed:T}=C(A,{privateKey:q});if(j&&!I.all){let H=T[j];if(H===void 0)return{success:!1,error:`Key not found: ${j}`};return{success:!0,output:H}}let G=I.all?{...process.env,...T}:T,O;switch(I.format){case"shell":O=Object.entries(G).map(([H,B])=>`${H}=${B}`).join(" ");break;case"eval":O=Object.entries(G).map(([H,B])=>`${H}="${B}"`).join(`
21
+ `);break;case"json":default:O=I.prettyPrint?JSON.stringify(G,null,2):JSON.stringify(G);break}return{success:!0,output:O}}catch(q){return{success:!1,error:`Failed to get: ${q instanceof Error?q.message:"Unknown error"}`}}}function e(j,I={}){let Y=I.cwd||process.cwd(),X=M(Y,I.keysFile||".env.keys");if(!g(X))return{success:!1,error:`Keys file not found: ${X}`};try{let q=D(X,"utf-8"),{parsed:Q}=C(q),Z=((I.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),J=Z?`DOTENV_PUBLIC_KEY_${Z}`:"DOTENV_PUBLIC_KEY",A=Z?`DOTENV_PRIVATE_KEY_${Z}`:"DOTENV_PRIVATE_KEY";if(j){let O=Q[j];if(!O)return{success:!1,error:`Key not found: ${j}`};return{success:!0,output:O}}let T={[J]:Q[J],[A]:Q[A]};return{success:!0,output:I.format==="shell"?`${J}=${T[J]} ${A}=${T[A]}`:JSON.stringify(T)}}catch(q){return{success:!1,error:`Failed to get keypair: ${q instanceof Error?q.message:"Unknown error"}`}}}function jj(j={}){let I=d({file:j.file,keysFile:j.keysFile,stdout:!0,cwd:j.cwd});if(!I.success)return I;let Y=j.cwd||process.cwd(),X=M(Y,j.file||".env"),q=M(Y,j.keysFile||".env.keys");if(I.output)E(X,I.output,"utf-8");let Q=F(),$=D(q,"utf-8").split(`
22
+ `),Z=j.file?j.file.replace(/^\.env\./,"").toUpperCase():"",J=Z?`DOTENV_PUBLIC_KEY_${Z}`:"DOTENV_PUBLIC_KEY",A=Z?`DOTENV_PRIVATE_KEY_${Z}`:"DOTENV_PRIVATE_KEY";for(let T=0;T<$.length;T++){let G=$[T];if(G===void 0)continue;if(G.startsWith(`${J}=`))$[T]=`${J}="${Q.publicKey}"`;else if(G.startsWith(`${A}=`))$[T]=`${A}="${Q.privateKey}"`}return E(q,$.join(`
23
+ `),"utf-8"),k({file:j.file,keysFile:j.keysFile,key:j.key,excludeKey:j.excludeKey,stdout:j.stdout,cwd:j.cwd})}export{i as setEnv,jj as rotateKeypair,e as getKeypair,t as getEnv,k as encryptEnv,d as decryptEnv};
package/dist/crypto.js ADDED
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{createCipheriv as P,createDecipheriv as Q,createHash as J,randomBytes as L}from"crypto";function R(q,j){let F=L(16),z=j.length===32?j:Buffer.from(j.toString("hex").slice(0,64),"hex"),A=P("aes-256-gcm",z,F),w=Buffer.concat([A.update(q,"utf8"),A.final()]),I=A.getAuthTag();return{ciphertext:w.toString("hex"),iv:F.toString("hex"),authTag:I.toString("hex")}}function S(q,j,F,z){let A=j.length===32?j:Buffer.from(j.toString("hex").slice(0,64),"hex");try{let w=Q("aes-256-gcm",A,Buffer.from(F,"hex"));return w.setAuthTag(Buffer.from(z,"hex")),Buffer.concat([w.update(Buffer.from(q,"hex")),w.final()]).toString("utf8")}catch(w){throw Error(`Decryption failed (data may be corrupted or key is incorrect): ${w instanceof Error?w.message:String(w)}`)}}function W(){let q=L(32);return{publicKey:J("sha256").update(q).digest().toString("hex"),privateKey:q.toString("hex")}}function X(q,j){let F=J("sha256").update(Buffer.from(j,"hex")).digest(),{ciphertext:z,iv:A,authTag:w}=R(q,F);return`encrypted:${Buffer.concat([Buffer.from(A,"hex"),Buffer.from(w,"hex"),Buffer.from(z,"hex")]).toString("base64")}`}function Y(q,j){if(!q.startsWith("encrypted:"))return q;let F=q.slice(10),z=Buffer.from(F,"base64");if(z.length<32)throw Error("Invalid encrypted data: payload too short (need at least iv + authTag = 32 bytes)");let A=z.subarray(0,16).toString("hex"),w=z.subarray(16,32).toString("hex"),I=z.subarray(32).toString("hex"),M=J("sha256").update(Buffer.from(j,"hex")).digest(),O=J("sha256").update(M).digest();return S(I,O,A,w)}function Z(q){let j=q.match(/^DOTENV_PRIVATE_KEY_(.+)$/);return j&&j[1]?j[1].toLowerCase():""}function _(q=""){if(!q)return process.env.DOTENV_PRIVATE_KEY;let j=`DOTENV_PRIVATE_KEY_${q.toUpperCase()}`;return process.env[j]}export{Z as parseEnvFromKey,_ as getPrivateKey,W as generateKeypair,X as encryptValue,Y as decryptValue,R as aesEncrypt,S as aesDecrypt};
package/dist/index.js CHANGED
@@ -1,25 +1,25 @@
1
1
  // @bun
2
- import XJ from"process";import{projectPath as jJ}from"@stacksjs/path";import y from"fs";var K={APP_ENV:["local","dev","development","staging","prod","production"],DB_CONNECTION:["mysql","sqlite","postgres","dynamodb"],MAIL_MAILER:["smtp","mailgun","ses","postmark","sendmail","log","sendgrid","mailtrap"],SEARCH_ENGINE_DRIVER:["opensearch","meilisearch","algolia","typesense"],FRONTEND_APP_ENV:["development","staging","production"]};import{createCipheriv as p,createDecipheriv as i,createHash as f,randomBytes as m}from"crypto";function a(J,Q){let $=m(16),z=Q.length===32?Q:Buffer.from(Q.toString("hex").slice(0,64),"hex"),Z=p("aes-256-gcm",z,$),X=Buffer.concat([Z.update(J,"utf8"),Z.final()]),W=Z.getAuthTag();return{ciphertext:X.toString("hex"),iv:$.toString("hex"),authTag:W.toString("hex")}}function n(J,Q,$,z){let Z=Q.length===32?Q:Buffer.from(Q.toString("hex").slice(0,64),"hex");try{let X=i("aes-256-gcm",Z,Buffer.from($,"hex"));return X.setAuthTag(Buffer.from(z,"hex")),Buffer.concat([X.update(Buffer.from(J,"hex")),X.final()]).toString("utf8")}catch(X){throw Error(`Decryption failed (data may be corrupted or key is incorrect): ${X instanceof Error?X.message:String(X)}`)}}function b(){let J=m(32);return{publicKey:f("sha256").update(J).digest().toString("hex"),privateKey:J.toString("hex")}}function S(J,Q){let $=f("sha256").update(Buffer.from(Q,"hex")).digest(),{ciphertext:z,iv:Z,authTag:X}=a(J,$);return`encrypted:${Buffer.concat([Buffer.from(Z,"hex"),Buffer.from(X,"hex"),Buffer.from(z,"hex")]).toString("base64")}`}function x(J,Q){if(!J.startsWith("encrypted:"))return J;let $=J.slice(10),z=Buffer.from($,"base64");if(z.length<32)throw Error("Invalid encrypted data: payload too short (need at least iv + authTag = 32 bytes)");let Z=z.subarray(0,16).toString("hex"),X=z.subarray(16,32).toString("hex"),W=z.subarray(32).toString("hex"),H=f("sha256").update(Buffer.from(Q,"hex")).digest(),G=f("sha256").update(H).digest();return n(W,G,Z,X)}function AJ(J){let Q=J.match(/^DOTENV_PRIVATE_KEY_(.+)$/);return Q&&Q[1]?Q[1].toLowerCase():""}function h(J=""){if(!J)return process.env.DOTENV_PRIVATE_KEY;let Q=`DOTENV_PRIVATE_KEY_${J.toUpperCase()}`;return process.env[Q]}function C(J,Q={}){let $={},z=[],Z=J.split(`
3
- `);for(let X of Z){let W=X.trim();if(!W||W.startsWith("#"))continue;if(W.startsWith("DOTENV_PUBLIC_KEY=")){let O=W.match(/^DOTENV_PUBLIC_KEY=["']?([^"'\n]+)["']?/);if(O&&O[1]!==void 0)$.DOTENV_PUBLIC_KEY=O[1];continue}let H=W.match(/^([^=]+)=(.*)$/);if(!H||H[1]===void 0||H[2]===void 0)continue;let G=H[1].trim(),j=H[2].trim();if(j.startsWith('"')&&j.endsWith('"')||j.startsWith("'")&&j.endsWith("'")){if(j=j.slice(1,-1),j.includes("\\n"))j=j.replace(/\\n/g,`
4
- `)}if(Q.privateKey&&(j.startsWith("encrypted:")||j.startsWith("enc:")))try{let O=j.startsWith("enc:")?`encrypted:${j.slice(4)}`:j;j=x(O,Q.privateKey)}catch(O){z.push(`Failed to decrypt ${G}: ${O instanceof Error?O.message:"Unknown error"}`)}j=r(j,{...Q.processEnv||process.env,...$}),j=s(j),$[G]=j}return{parsed:$,errors:z}}function r(J,Q){return J.replace(/\$\{([^}]+)\}/g,($,z)=>{let Z=z.match(/^([^:\-+]+)(:-|-)(.+)$/);if(Z){let[,W,H,G]=Z,j=Q[W];if(H===":-")return j||G;else return j!==void 0?j:G}let X=z.match(/^([^:\-+]+)(:?\+)(.+)$/);if(X){let[,W,H,G]=X,j=Q[W];if(H===":+")return j?G:"";else return j!==void 0?G:""}return Q[z]||""})}var o=new Set(["date","hostname","whoami","uname","pwd","echo","printf","cat","basename","dirname"]);function s(J){return J.replace(/\$\(([^)]+)\)/g,(Q,$)=>{try{let z=$.trim().split(/\s+/),Z=z[0];if(!Z||!o.has(Z))return console.warn(`[env] Blocked command substitution for disallowed command: ${Z}`),"";let X=Bun.spawnSync(z,{stdout:"pipe",stderr:"pipe"});if(X.exitCode===0)return new TextDecoder().decode(X.stdout).trim();console.warn(`[env] Command substitution failed (exit code ${X.exitCode}): ${Z}`)}catch(z){console.warn(`[env] Command substitution error: ${z instanceof Error?z.message:String(z)}`)}return""})}async function _J(J,Q={}){let $={},z=[];for(let Z of J)try{let X=Bun.file(Z);if(!X.size)continue;let W=await X.text(),{parsed:H,errors:G}=C(W,Q);z.push(...G);for(let[j,O]of Object.entries(H)){if(!Q.overload&&$[j]!==void 0)continue;$[j]=O}}catch(X){if(X?.code==="ENOENT")continue;z.push(`Failed to read ${Z}: ${X instanceof Error?X.message:String(X)}`)}return{parsed:$,errors:z}}import{existsSync as F}from"fs";import{readFileSync as k}from"fs";import{resolve as V}from"path";function d(J={}){let{path:Q=[".env"],overload:$=!1,env:z,privateKey:Z,keysFile:X,quiet:W=!1,cwd:H=process.cwd()}=J,G=Array.isArray(Q)?Q:[Q],j=[],O=0,Y=Z;if(!Y&&X){let U=V(H,X);if(F(U))try{let A=k(U,"utf-8"),{parsed:B}=C(A);if(z){let M=`DOTENV_PRIVATE_KEY_${z.toUpperCase()}`;Y=B[M]}else Y=B.DOTENV_PRIVATE_KEY}catch(A){j.push(`Failed to load keys file: ${A instanceof Error?A.message:"Unknown error"}`)}}if(!Y)Y=h(z||"");for(let U of G){let A=V(H,U);if(!F(A)){if(!W)j.push(`File not found: ${A}`);continue}try{let B=k(A,"utf-8"),{parsed:M,errors:q}=C(B,{privateKey:Y,processEnv:process.env});j.push(...q);for(let[I,R]of Object.entries(M)){if(I==="DOTENV_PUBLIC_KEY")continue;if($||process.env[I]===void 0)process.env[I]=R,O++}if(!W&&!process.env.__ENV_LOADED__)console.log(`[env] loaded ${Object.keys(M).length} variables from ${U}`),process.env.__ENV_LOADED__="1"}catch(B){j.push(`Failed to load ${A}: ${B instanceof Error?B.message:"Unknown error"}`)}}return{loaded:O,errors:j}}function CJ(J={}){return{name:"env-plugin",setup(Q){d(J)}}}function LJ(J={}){let Q=J.env||"development",$=J.cwd||process.cwd(),z=[],Z=`.env.${Q}`,X=`.env.${Q}.local`;if(F(V($,X)))z.push(X);if(F(V($,Z)))z.push(Z);if(F(V($,".env.local")))z.push(".env.local");if(F(V($,".env")))z.push(".env");return d({...J,path:z,env:Q})}import{existsSync as g,readFileSync as L,writeFileSync as E}from"fs";import{resolve as T}from"path";function t(J={}){let Q=J.cwd||process.cwd(),$=T(Q,J.file||".env"),z=T(Q,J.keysFile||".env.keys");if(!g($))return{success:!1,error:`File not found: ${$}`};try{let Z,X;if(g(z)){let U=L(z,"utf-8"),{parsed:A}=C(U),q=((J.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),I=q?`DOTENV_PUBLIC_KEY_${q}`:"DOTENV_PUBLIC_KEY",R=q?`DOTENV_PRIVATE_KEY_${q}`:"DOTENV_PRIVATE_KEY";if(Z=A[I]||"",X=A[R]||"",!Z||!X){let D=b();Z=D.publicKey,X=D.privateKey;let w=`
2
+ import{createCipheriv as p,createDecipheriv as i,createHash as f,randomBytes as K}from"crypto";function a(J,Q){let $=K(16),z=Q.length===32?Q:Buffer.from(Q.toString("hex").slice(0,64),"hex"),Z=p("aes-256-gcm",z,$),X=Buffer.concat([Z.update(J,"utf8"),Z.final()]),Y=Z.getAuthTag();return{ciphertext:X.toString("hex"),iv:$.toString("hex"),authTag:Y.toString("hex")}}function n(J,Q,$,z){let Z=Q.length===32?Q:Buffer.from(Q.toString("hex").slice(0,64),"hex");try{let X=i("aes-256-gcm",Z,Buffer.from($,"hex"));return X.setAuthTag(Buffer.from(z,"hex")),Buffer.concat([X.update(Buffer.from(J,"hex")),X.final()]).toString("utf8")}catch(X){throw Error(`Decryption failed (data may be corrupted or key is incorrect): ${X instanceof Error?X.message:String(X)}`)}}function b(){let J=K(32);return{publicKey:f("sha256").update(J).digest().toString("hex"),privateKey:J.toString("hex")}}function S(J,Q){let $=f("sha256").update(Buffer.from(Q,"hex")).digest(),{ciphertext:z,iv:Z,authTag:X}=a(J,$);return`encrypted:${Buffer.concat([Buffer.from(Z,"hex"),Buffer.from(X,"hex"),Buffer.from(z,"hex")]).toString("base64")}`}function x(J,Q){if(!J.startsWith("encrypted:"))return J;let $=J.slice(10),z=Buffer.from($,"base64");if(z.length<32)throw Error("Invalid encrypted data: payload too short (need at least iv + authTag = 32 bytes)");let Z=z.subarray(0,16).toString("hex"),X=z.subarray(16,32).toString("hex"),Y=z.subarray(32).toString("hex"),W=f("sha256").update(Buffer.from(Q,"hex")).digest(),G=f("sha256").update(W).digest();return n(Y,G,Z,X)}function AJ(J){let Q=J.match(/^DOTENV_PRIVATE_KEY_(.+)$/);return Q&&Q[1]?Q[1].toLowerCase():""}function m(J=""){if(!J)return process.env.DOTENV_PRIVATE_KEY;let Q=`DOTENV_PRIVATE_KEY_${J.toUpperCase()}`;return process.env[Q]}function T(J,Q={}){let $={},z=[],Z=J.split(`
3
+ `);for(let X of Z){let Y=X.trim();if(!Y||Y.startsWith("#"))continue;if(Y.startsWith("DOTENV_PUBLIC_KEY=")){let q=Y.match(/^DOTENV_PUBLIC_KEY=["']?([^"'\n]+)["']?/);if(q&&q[1]!==void 0)$.DOTENV_PUBLIC_KEY=q[1];continue}let W=Y.match(/^([^=]+)=(.*)$/);if(!W||W[1]===void 0||W[2]===void 0)continue;let G=W[1].trim(),j=W[2].trim();if(j.startsWith('"')&&j.endsWith('"')||j.startsWith("'")&&j.endsWith("'")){if(j=j.slice(1,-1),j.includes("\\n"))j=j.replace(/\\n/g,`
4
+ `)}if(Q.privateKey&&(j.startsWith("encrypted:")||j.startsWith("enc:")))try{let q=j.startsWith("enc:")?`encrypted:${j.slice(4)}`:j;j=x(q,Q.privateKey)}catch(q){z.push(`Failed to decrypt ${G}: ${q instanceof Error?q.message:"Unknown error"}`)}j=r(j,{...Q.processEnv||process.env,...$}),j=s(j),$[G]=j}return{parsed:$,errors:z}}function r(J,Q){return J.replace(/\$\{([^}]+)\}/g,($,z)=>{let Z=z.match(/^([^:\-+]+)(:-|-)(.+)$/);if(Z){let[,Y,W,G]=Z,j=Q[Y];if(W===":-")return j||G;else return j!==void 0?j:G}let X=z.match(/^([^:\-+]+)(:?\+)(.+)$/);if(X){let[,Y,W,G]=X,j=Q[Y];if(W===":+")return j?G:"";else return j!==void 0?G:""}return Q[z]||""})}var o=new Set(["date","hostname","whoami","uname","pwd","echo","printf","cat","basename","dirname"]);function s(J){return J.replace(/\$\(([^)]+)\)/g,(Q,$)=>{try{let z=$.trim().split(/\s+/),Z=z[0];if(!Z||!o.has(Z))return console.warn(`[env] Blocked command substitution for disallowed command: ${Z}`),"";let X=Bun.spawnSync(z,{stdout:"pipe",stderr:"pipe"});if(X.exitCode===0)return new TextDecoder().decode(X.stdout).trim();console.warn(`[env] Command substitution failed (exit code ${X.exitCode}): ${Z}`)}catch(z){console.warn(`[env] Command substitution error: ${z instanceof Error?z.message:String(z)}`)}return""})}async function _J(J,Q={}){let $={},z=[];for(let Z of J)try{let X=Bun.file(Z);if(!X.size)continue;let Y=await X.text(),{parsed:W,errors:G}=T(Y,Q);z.push(...G);for(let[j,q]of Object.entries(W)){if(!Q.overload&&$[j]!==void 0)continue;$[j]=q}}catch(X){if(X?.code==="ENOENT")continue;z.push(`Failed to read ${Z}: ${X instanceof Error?X.message:String(X)}`)}return{parsed:$,errors:z}}import{existsSync as F}from"fs";import{readFileSync as h}from"fs";import{resolve as w}from"path";function k(J={}){let{path:Q=[".env"],overload:$=!1,env:z,privateKey:Z,keysFile:X,quiet:Y=!1,cwd:W=process.cwd()}=J,G=Array.isArray(Q)?Q:[Q],j=[],q=0,D=Z;if(!D&&X){let H=w(W,X);if(F(H))try{let O=h(H,"utf-8"),{parsed:U}=T(O);if(z){let B=`DOTENV_PRIVATE_KEY_${z.toUpperCase()}`;D=U[B]}else D=U.DOTENV_PRIVATE_KEY}catch(O){j.push(`Failed to load keys file: ${O instanceof Error?O.message:"Unknown error"}`)}}if(!D)D=m(z||"");for(let H of G){let O=w(W,H);if(!F(O)){if(!Y)j.push(`File not found: ${O}`);continue}try{let U=h(O,"utf-8"),{parsed:B,errors:I}=T(U,{privateKey:D,processEnv:process.env});j.push(...I);for(let[A,M]of Object.entries(B)){if(A==="DOTENV_PUBLIC_KEY")continue;if($||process.env[A]===void 0)process.env[A]=M,q++}if(!Y&&!process.env.__ENV_LOADED__)console.log(`[env] loaded ${Object.keys(B).length} variables from ${H}`),process.env.__ENV_LOADED__="1"}catch(U){j.push(`Failed to load ${O}: ${U instanceof Error?U.message:"Unknown error"}`)}}return{loaded:q,errors:j}}function t(J={}){return{name:"env-plugin",setup(Q){k(J)}}}function LJ(J={}){let Q=J.env||"development",$=J.cwd||process.cwd(),z=[],Z=`.env.${Q}`,X=`.env.${Q}.local`;if(F(w($,X)))z.push(X);if(F(w($,Z)))z.push(Z);if(F(w($,".env.local")))z.push(".env.local");if(F(w($,".env")))z.push(".env");return k({...J,path:z,env:Q})}var gJ=t;import{existsSync as g,readFileSync as L,writeFileSync as V}from"fs";import{resolve as C}from"path";function e(J={}){let Q=J.cwd||process.cwd(),$=C(Q,J.file||".env"),z=C(Q,J.keysFile||".env.keys");if(!g($))return{success:!1,error:`File not found: ${$}`};try{let Z,X;if(g(z)){let H=L(z,"utf-8"),{parsed:O}=T(H),I=((J.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),A=I?`DOTENV_PUBLIC_KEY_${I}`:"DOTENV_PUBLIC_KEY",M=I?`DOTENV_PRIVATE_KEY_${I}`:"DOTENV_PRIVATE_KEY";if(Z=O[A]||"",X=O[M]||"",!Z||!X){let R=b();Z=R.publicKey,X=R.privateKey;let E=`
5
+ ${A}="${Z}"
6
+ ${M}="${X}"
7
+ `;V(z,H+E,"utf-8")}}else{let H=b();Z=H.publicKey,X=H.privateKey;let B=((J.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),I=B?`DOTENV_PUBLIC_KEY_${B}`:"DOTENV_PUBLIC_KEY",A=B?`DOTENV_PRIVATE_KEY_${B}`:"DOTENV_PRIVATE_KEY",M=`# .env.keys - Keep this file secure and never commit to source control
5
8
  ${I}="${Z}"
6
- ${R}="${X}"
7
- `;E(z,U+w,"utf-8")}}else{let U=b();Z=U.publicKey,X=U.privateKey;let M=((J.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),q=M?`DOTENV_PUBLIC_KEY_${M}`:"DOTENV_PUBLIC_KEY",I=M?`DOTENV_PRIVATE_KEY_${M}`:"DOTENV_PRIVATE_KEY",R=`# .env.keys - Keep this file secure and never commit to source control
8
- ${q}="${Z}"
9
- ${I}="${X}"
10
- `;E(z,R,"utf-8")}let H=L($,"utf-8").split(`
11
- `),G=[],j=J.file?J.file.replace(/^\.env\./,"").toUpperCase():"",O=j?`DOTENV_PUBLIC_KEY_${j}`:"DOTENV_PUBLIC_KEY";G.push("#/-------------------[DOTENV_PUBLIC_KEY]--------------------/"),G.push("#/ public-key encryption for .env files /"),G.push("#/ [how it works](https://stacksjs.com/encryption) /"),G.push("#/----------------------------------------------------------/"),G.push(`${O}="${Z}"`),G.push("");for(let U of H){let A=U.trim();if(!A||A.startsWith("#")){G.push(U);continue}if(A.startsWith("DOTENV_PUBLIC_KEY"))continue;let B=A.match(/^([^=]+)=(.*)$/);if(!B||B[1]===void 0||B[2]===void 0){G.push(U);continue}let M=B[1].trim(),q=B[2].trim();if(q.startsWith('"')&&q.endsWith('"')||q.startsWith("'")&&q.endsWith("'"))q=q.slice(1,-1);let I=!0;if(J.key&&!M.includes(J.key))I=!1;if(J.excludeKey&&M.includes(J.excludeKey))I=!1;if(q.startsWith("encrypted:"))I=!1;if(I)q=S(q,Z);G.push(`${M}="${q}"`)}let Y=G.join(`
12
- `);if(J.stdout)return{success:!0,output:Y};return E($,Y,"utf-8"),{success:!0,output:`\u2714 encrypted (${J.file||".env"})
13
- \u2714 key added to ${J.keysFile||".env.keys"}`}}catch(Z){return{success:!1,error:`Failed to encrypt: ${Z instanceof Error?Z.message:"Unknown error"}`}}}function e(J={}){let Q=J.cwd||process.cwd(),$=T(Q,J.file||".env"),z=T(Q,J.keysFile||".env.keys");if(!g($))return{success:!1,error:`File not found: ${$}`};if(!g(z))return{success:!1,error:`Keys file not found: ${z}`};try{let Z=L(z,"utf-8"),{parsed:X}=C(Z),G=((J.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),j=G?`DOTENV_PRIVATE_KEY_${G}`:"DOTENV_PRIVATE_KEY",O=X[j];if(!O)return{success:!1,error:`Private key not found: ${j}`};let U=L($,"utf-8").split(`
14
- `),A=[];for(let M of U){let q=M.trim();if(!q||q.startsWith("#")){A.push(M);continue}if(q.startsWith("DOTENV_PUBLIC_KEY"))continue;let I=q.match(/^([^=]+)=(.*)$/);if(!I||I[1]===void 0||I[2]===void 0){A.push(M);continue}let R=I[1].trim(),D=I[2].trim();if(D.startsWith('"')&&D.endsWith('"')||D.startsWith("'")&&D.endsWith("'"))D=D.slice(1,-1);let w=D.startsWith("encrypted:");if(J.key&&!R.includes(J.key))w=!1;if(w)D=x(D,O);A.push(`${R}="${D}"`)}let B=A.join(`
15
- `);if(J.stdout)return{success:!0,output:B};return E($,B,"utf-8"),{success:!0,output:`\u2714 decrypted (${J.file||".env"})`}}catch(Z){return{success:!1,error:`Failed to decrypt: ${Z instanceof Error?Z.message:"Unknown error"}`}}}function wJ(J,Q,$={}){let z=$.cwd||process.cwd(),Z=T(z,$.file||".env");try{let X="";if(g(Z))X=L(Z,"utf-8");let W=X.split(`
16
- `),H=!1,G;for(let Y of W){let U=Y.trim();if(U.startsWith("DOTENV_PUBLIC_KEY=")){let A=U.match(/^DOTENV_PUBLIC_KEY=["']?([^"'\n]+)["']?/);if(A)G=A[1];break}}if(!$.plain&&!G){let Y=T(z,$.keysFile||".env.keys"),U=b();G=U.publicKey;let A="";if(g(Y))A=L(Y,"utf-8");let q=(($.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),I=q?`DOTENV_PUBLIC_KEY_${q}`:"DOTENV_PUBLIC_KEY",R=q?`DOTENV_PRIVATE_KEY_${q}`:"DOTENV_PRIVATE_KEY";A+=`
17
- ${I}="${U.publicKey}"
18
- ${R}="${U.privateKey}"
19
- `,E(Y,A,"utf-8"),W.unshift(`${I}="${G}"`)}let j=Q;if(!$.plain&&G)j=S(Q,G);for(let Y=0;Y<W.length;Y++){let U=W[Y];if(U===void 0)continue;if(U.trim().startsWith(`${J}=`)){W[Y]=`${J}="${j}"`,H=!0;break}}if(!H)W.push(`${J}="${j}"`);let O=W.join(`
20
- `);return E(Z,O,"utf-8"),{success:!0,output:`set ${J}${$.plain?"":" with encryption"} (${$.file||".env"})`}}catch(X){return{success:!1,error:`Failed to set: ${X instanceof Error?X.message:"Unknown error"}`}}}function fJ(J,Q={}){let $=Q.cwd||process.cwd(),z=T($,Q.file||".env");if(!g(z))return{success:!1,error:`File not found: ${z}`};try{let Z,X=T($,Q.keysFile||".env.keys");if(g(X)){let O=L(X,"utf-8"),{parsed:Y}=C(O),B=((Q.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),M=B?`DOTENV_PRIVATE_KEY_${B}`:"DOTENV_PRIVATE_KEY";Z=Y[M]}let W=L(z,"utf-8"),{parsed:H}=C(W,{privateKey:Z});if(J&&!Q.all){let O=H[J];if(O===void 0)return{success:!1,error:`Key not found: ${J}`};return{success:!0,output:O}}let G=Q.all?{...process.env,...H}:H,j;switch(Q.format){case"shell":j=Object.entries(G).map(([O,Y])=>`${O}=${Y}`).join(" ");break;case"eval":j=Object.entries(G).map(([O,Y])=>`${O}="${Y}"`).join(`
21
- `);break;case"json":default:j=Q.prettyPrint?JSON.stringify(G,null,2):JSON.stringify(G);break}return{success:!0,output:j}}catch(Z){return{success:!1,error:`Failed to get: ${Z instanceof Error?Z.message:"Unknown error"}`}}}function xJ(J,Q={}){let $=Q.cwd||process.cwd(),z=T($,Q.keysFile||".env.keys");if(!g(z))return{success:!1,error:`Keys file not found: ${z}`};try{let Z=L(z,"utf-8"),{parsed:X}=C(Z),G=((Q.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),j=G?`DOTENV_PUBLIC_KEY_${G}`:"DOTENV_PUBLIC_KEY",O=G?`DOTENV_PRIVATE_KEY_${G}`:"DOTENV_PRIVATE_KEY";if(J){let A=X[J];if(!A)return{success:!1,error:`Key not found: ${J}`};return{success:!0,output:A}}let Y={[j]:X[j],[O]:X[O]};return{success:!0,output:Q.format==="shell"?`${j}=${Y[j]} ${O}=${Y[O]}`:JSON.stringify(Y)}}catch(Z){return{success:!1,error:`Failed to get keypair: ${Z instanceof Error?Z.message:"Unknown error"}`}}}function SJ(J={}){let Q=e({file:J.file,keysFile:J.keysFile,stdout:!0,cwd:J.cwd});if(!Q.success)return Q;let $=J.cwd||process.cwd(),z=T($,J.file||".env"),Z=T($,J.keysFile||".env.keys");if(Q.output)E(z,Q.output,"utf-8");let X=b(),H=L(Z,"utf-8").split(`
22
- `),G=J.file?J.file.replace(/^\.env\./,"").toUpperCase():"",j=G?`DOTENV_PUBLIC_KEY_${G}`:"DOTENV_PUBLIC_KEY",O=G?`DOTENV_PRIVATE_KEY_${G}`:"DOTENV_PRIVATE_KEY";for(let Y=0;Y<H.length;Y++){let U=H[Y];if(U===void 0)continue;if(U.startsWith(`${j}=`))H[Y]=`${j}="${X.publicKey}"`;else if(U.startsWith(`${O}=`))H[Y]=`${O}="${X.privateKey}"`}return E(Z,H.join(`
23
- `),"utf-8"),t({file:J.file,keysFile:J.keysFile,key:J.key,excludeKey:J.excludeKey,stdout:J.stdout,cwd:J.cwd})}import _ from"process";import{platform as JJ}from"os";var u=typeof Bun<"u",c=typeof _<"u"&&_.versions?.node!==void 0,QJ=u?"bun":c?"node":"unknown",mJ={name:QJ,version:u?Bun.version:c?_.version:void 0},P=JJ(),hJ=P==="win32",kJ=P==="darwin",dJ=P==="linux",v=Boolean(_.stdout?.isTTY),uJ=typeof globalThis.window<"u",ZJ=Boolean(_.env.CI||_.env.CONTINUOUS_INTEGRATION||_.env.BUILD_NUMBER||_.env.RUN_ID),cJ=Boolean(_.env.DEBUG||_.env.VERBOSE||_.argv.includes("--debug")||_.argv.includes("--verbose")),$J=ZJ||!v,vJ=Boolean(!$J&&(v||_.env.COLORTERM||_.env.FORCE_COLOR||_.env.TERM&&_.env.TERM!=="dumb")),N={github:{name:"GitHub Actions",detected:Boolean(_.env.GITHUB_ACTIONS)},gitlab:{name:"GitLab CI",detected:Boolean(_.env.GITLAB_CI)},circle:{name:"CircleCI",detected:Boolean(_.env.CIRCLECI)},travis:{name:"Travis CI",detected:Boolean(_.env.TRAVIS)},jenkins:{name:"Jenkins",detected:Boolean(_.env.JENKINS_URL)},vercel:{name:"Vercel",detected:Boolean(_.env.VERCEL)},netlify:{name:"Netlify",detected:Boolean(_.env.NETLIFY)},heroku:{name:"Heroku",detected:Boolean(_.env.DYNO)},aws:{name:"AWS",detected:Boolean(_.env.AWS_REGION||_.env.AWS_LAMBDA_FUNCTION_NAME)},azure:{name:"Azure",detected:Boolean(_.env.AZURE_HTTP_USER_AGENT)},cloudflare:{name:"Cloudflare",detected:Boolean(_.env.CF_PAGES)},railway:{name:"Railway",detected:Boolean(_.env.RAILWAY_ENVIRONMENT)},render:{name:"Render",detected:Boolean(_.env.RENDER)}},zJ=Object.keys(N).find((J)=>{let Q=N[J];return Q!==void 0&&Q.detected})||"unknown",yJ=N[zJ]||{name:"Unknown",detected:!1};var GJ={get:(J,Q)=>{let $=J[Q],z=["_PORT","_TIMEOUT","_TTL","_SIZE","_LIMIT","_MAX","_MIN","_INTERVAL","_RETRIES","_CONCURRENCY","_WORKERS","_CONNECTIONS"];if(typeof $==="string"&&/^\d+$/.test($)&&!$.startsWith("0")&&z.some((Z)=>Q.endsWith(Z)))return Number($);if(typeof $==="string"){let Z=$.toLowerCase();if(Z==="true")return!0;if(Z==="false")return!1}return $}};function WJ(){return typeof Bun<"u"?Bun.env:XJ.env}var l=new Proxy(WJ(),GJ);function rJ(J,Q,$){let z=$?.path||jJ(".env"),X=y.readFileSync(z,"utf-8").split(`
24
- `),W=X.findIndex((j)=>j.startsWith(`${J}=`)),G=/[\s"'#$\\]/.test(Q)?`"${Q.replace(/"/g,"\\\"")}"`:Q;if(W!==-1)X[W]=`${J}=${G}`;else X.push(`${J}=${G}`);y.writeFileSync(z,X.join(`
25
- `))}function oJ(J=l){let Q=[];for(let[$,z]of Object.entries(K)){let Z=J[$];if(Z!==void 0&&Z!==""&&!z.includes(String(Z)))Q.push(`${$}="${Z}" is not valid. Allowed values: ${z.join(", ")}`)}return Q}function sJ(J,Q=l){let $=[];for(let z of J){let Z=Q[z];if(Z===void 0||Z===""||Z===null)$.push(z)}if($.length>0)throw Error(`[env] Missing required environment variable(s): ${$.join(", ")}. Set them in .env or your process environment before booting.`);return Q}export{rJ as writeEnv,oJ as validateEnv,wJ as setEnv,mJ as runtimeInfo,QJ as runtime,SJ as rotateKeypair,sJ as requireEnv,yJ as providerInfo,zJ as provider,WJ as process,P as platform,AJ as parseEnvFromKey,C as parse,_J as loadEnvFiles,d as loadEnv,hJ as isWindows,c as isNode,$J as isMinimal,kJ as isMacOS,dJ as isLinux,cJ as isDebug,vJ as isColorSupported,ZJ as isCI,u as isBun,uJ as hasWindow,v as hasTTY,h as getPrivateKey,xJ as getKeypair,fJ as getEnv,b as generateKeypair,CJ as envPlugin,K as envEnum,l as env,S as encryptValue,t as encryptEnv,x as decryptValue,e as decryptEnv,LJ as autoLoadEnv,a as aesEncrypt,n as aesDecrypt};
9
+ ${A}="${X}"
10
+ `;V(z,M,"utf-8")}let W=L($,"utf-8").split(`
11
+ `),G=[],j=J.file?J.file.replace(/^\.env\./,"").toUpperCase():"",q=j?`DOTENV_PUBLIC_KEY_${j}`:"DOTENV_PUBLIC_KEY";G.push("#/-------------------[DOTENV_PUBLIC_KEY]--------------------/"),G.push("#/ public-key encryption for .env files /"),G.push("#/ [how it works](https://stacksjs.com/encryption) /"),G.push("#/----------------------------------------------------------/"),G.push(`${q}="${Z}"`),G.push("");for(let H of W){let O=H.trim();if(!O||O.startsWith("#")){G.push(H);continue}if(O.startsWith("DOTENV_PUBLIC_KEY"))continue;let U=O.match(/^([^=]+)=(.*)$/);if(!U||U[1]===void 0||U[2]===void 0){G.push(H);continue}let B=U[1].trim(),I=U[2].trim();if(I.startsWith('"')&&I.endsWith('"')||I.startsWith("'")&&I.endsWith("'"))I=I.slice(1,-1);let A=!0;if(J.key&&!B.includes(J.key))A=!1;if(J.excludeKey&&B.includes(J.excludeKey))A=!1;if(I.startsWith("encrypted:"))A=!1;if(A)I=S(I,Z);G.push(`${B}="${I}"`)}let D=G.join(`
12
+ `);if(J.stdout)return{success:!0,output:D};return V($,D,"utf-8"),{success:!0,output:`\u2714 encrypted (${J.file||".env"})
13
+ \u2714 key added to ${J.keysFile||".env.keys"}`}}catch(Z){return{success:!1,error:`Failed to encrypt: ${Z instanceof Error?Z.message:"Unknown error"}`}}}function JJ(J={}){let Q=J.cwd||process.cwd(),$=C(Q,J.file||".env"),z=C(Q,J.keysFile||".env.keys");if(!g($))return{success:!1,error:`File not found: ${$}`};if(!g(z))return{success:!1,error:`Keys file not found: ${z}`};try{let Z=L(z,"utf-8"),{parsed:X}=T(Z),G=((J.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),j=G?`DOTENV_PRIVATE_KEY_${G}`:"DOTENV_PRIVATE_KEY",q=X[j];if(!q)return{success:!1,error:`Private key not found: ${j}`};let H=L($,"utf-8").split(`
14
+ `),O=[];for(let B of H){let I=B.trim();if(!I||I.startsWith("#")){O.push(B);continue}if(I.startsWith("DOTENV_PUBLIC_KEY"))continue;let A=I.match(/^([^=]+)=(.*)$/);if(!A||A[1]===void 0||A[2]===void 0){O.push(B);continue}let M=A[1].trim(),R=A[2].trim();if(R.startsWith('"')&&R.endsWith('"')||R.startsWith("'")&&R.endsWith("'"))R=R.slice(1,-1);let E=R.startsWith("encrypted:");if(J.key&&!M.includes(J.key))E=!1;if(E)R=x(R,q);O.push(`${M}="${R}"`)}let U=O.join(`
15
+ `);if(J.stdout)return{success:!0,output:U};return V($,U,"utf-8"),{success:!0,output:`\u2714 decrypted (${J.file||".env"})`}}catch(Z){return{success:!1,error:`Failed to decrypt: ${Z instanceof Error?Z.message:"Unknown error"}`}}}function bJ(J,Q,$={}){let z=$.cwd||process.cwd(),Z=C(z,$.file||".env"),X=C(z,$.keysFile||".env.keys");try{let Y="";if(g(Z))Y=L(Z,"utf-8");let W=Y.split(`
16
+ `),G=!1,j,H=(($.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),O=H?`DOTENV_PUBLIC_KEY_${H}`:"DOTENV_PUBLIC_KEY",U=H?`DOTENV_PRIVATE_KEY_${H}`:"DOTENV_PRIVATE_KEY";for(let A of W){let M=A.trim();if(M.startsWith(`${O}=`)){let R=M.match(/^[^=]+=["']?([^"'\n]+)["']?/);if(R)j=R[1];break}}if(j){let A=!1;if(g(X)){let M=L(X,"utf-8"),{parsed:R}=T(M);A=Boolean(R[U])}if(!A)j=void 0}if(!$.plain&&!j){let A=b();j=A.publicKey;let M="";if(g(X))M=L(X,"utf-8");M+=`
17
+ ${O}="${A.publicKey}"
18
+ ${U}="${A.privateKey}"
19
+ `,V(X,M,"utf-8");for(let R=W.length-1;R>=0;R--){let E=W[R];if(E!==void 0&&E.trim().startsWith(`${O}=`))W.splice(R,1)}W.unshift(`${O}="${j}"`)}let B=Q;if(!$.plain&&j)B=S(Q,j);for(let A=0;A<W.length;A++){let M=W[A];if(M===void 0)continue;if(M.trim().startsWith(`${J}=`)){W[A]=`${J}="${B}"`,G=!0;break}}if(!G)W.push(`${J}="${B}"`);let I=W.join(`
20
+ `);return V(Z,I,"utf-8"),{success:!0,output:`set ${J}${$.plain?"":" with encryption"} (${$.file||".env"})`}}catch(Y){return{success:!1,error:`Failed to set: ${Y instanceof Error?Y.message:"Unknown error"}`}}}function fJ(J,Q={}){let $=Q.cwd||process.cwd(),z=C($,Q.file||".env");if(!g(z))return{success:!1,error:`File not found: ${z}`};try{let Z,X=C($,Q.keysFile||".env.keys"),G=((Q.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),j=G?`DOTENV_PRIVATE_KEY_${G}`:"DOTENV_PRIVATE_KEY";if(g(X)){let U=L(X,"utf-8"),{parsed:B}=T(U);Z=B[j]}if(!Z)Z=process.env[j];let q=L(z,"utf-8"),{parsed:D}=T(q,{privateKey:Z});if(J&&!Q.all){let U=D[J];if(U===void 0)return{success:!1,error:`Key not found: ${J}`};return{success:!0,output:U}}let H=Q.all?{...process.env,...D}:D,O;switch(Q.format){case"shell":O=Object.entries(H).map(([U,B])=>`${U}=${B}`).join(" ");break;case"eval":O=Object.entries(H).map(([U,B])=>`${U}="${B}"`).join(`
21
+ `);break;case"json":default:O=Q.prettyPrint?JSON.stringify(H,null,2):JSON.stringify(H);break}return{success:!0,output:O}}catch(Z){return{success:!1,error:`Failed to get: ${Z instanceof Error?Z.message:"Unknown error"}`}}}function xJ(J,Q={}){let $=Q.cwd||process.cwd(),z=C($,Q.keysFile||".env.keys");if(!g(z))return{success:!1,error:`Keys file not found: ${z}`};try{let Z=L(z,"utf-8"),{parsed:X}=T(Z),G=((Q.file||".env").split("/").pop()||"").replace(/^\.env\./,"").replace(/^\.env$/,"").toUpperCase(),j=G?`DOTENV_PUBLIC_KEY_${G}`:"DOTENV_PUBLIC_KEY",q=G?`DOTENV_PRIVATE_KEY_${G}`:"DOTENV_PRIVATE_KEY";if(J){let O=X[J];if(!O)return{success:!1,error:`Key not found: ${J}`};return{success:!0,output:O}}let D={[j]:X[j],[q]:X[q]};return{success:!0,output:Q.format==="shell"?`${j}=${D[j]} ${q}=${D[q]}`:JSON.stringify(D)}}catch(Z){return{success:!1,error:`Failed to get keypair: ${Z instanceof Error?Z.message:"Unknown error"}`}}}function SJ(J={}){let Q=JJ({file:J.file,keysFile:J.keysFile,stdout:!0,cwd:J.cwd});if(!Q.success)return Q;let $=J.cwd||process.cwd(),z=C($,J.file||".env"),Z=C($,J.keysFile||".env.keys");if(Q.output)V(z,Q.output,"utf-8");let X=b(),W=L(Z,"utf-8").split(`
22
+ `),G=J.file?J.file.replace(/^\.env\./,"").toUpperCase():"",j=G?`DOTENV_PUBLIC_KEY_${G}`:"DOTENV_PUBLIC_KEY",q=G?`DOTENV_PRIVATE_KEY_${G}`:"DOTENV_PRIVATE_KEY";for(let D=0;D<W.length;D++){let H=W[D];if(H===void 0)continue;if(H.startsWith(`${j}=`))W[D]=`${j}="${X.publicKey}"`;else if(H.startsWith(`${q}=`))W[D]=`${q}="${X.privateKey}"`}return V(Z,W.join(`
23
+ `),"utf-8"),e({file:J.file,keysFile:J.keysFile,key:J.key,excludeKey:J.excludeKey,stdout:J.stdout,cwd:J.cwd})}import _ from"process";import{platform as QJ}from"os";var d=typeof Bun<"u",u=typeof _<"u"&&_.versions?.node!==void 0,ZJ=d?"bun":u?"node":"unknown",mJ={name:ZJ,version:d?Bun.version:u?_.version:void 0},P=QJ(),hJ=P==="win32",kJ=P==="darwin",dJ=P==="linux",c=Boolean(_.stdout?.isTTY),uJ=typeof globalThis.window<"u",$J=Boolean(_.env.CI||_.env.CONTINUOUS_INTEGRATION||_.env.BUILD_NUMBER||_.env.RUN_ID),cJ=Boolean(_.env.DEBUG||_.env.VERBOSE||_.argv.includes("--debug")||_.argv.includes("--verbose")),zJ=$J||!c,vJ=Boolean(!zJ&&(c||_.env.COLORTERM||_.env.FORCE_COLOR||_.env.TERM&&_.env.TERM!=="dumb")),N={github:{name:"GitHub Actions",detected:Boolean(_.env.GITHUB_ACTIONS)},gitlab:{name:"GitLab CI",detected:Boolean(_.env.GITLAB_CI)},circle:{name:"CircleCI",detected:Boolean(_.env.CIRCLECI)},travis:{name:"Travis CI",detected:Boolean(_.env.TRAVIS)},jenkins:{name:"Jenkins",detected:Boolean(_.env.JENKINS_URL)},vercel:{name:"Vercel",detected:Boolean(_.env.VERCEL)},netlify:{name:"Netlify",detected:Boolean(_.env.NETLIFY)},heroku:{name:"Heroku",detected:Boolean(_.env.DYNO)},aws:{name:"AWS",detected:Boolean(_.env.AWS_REGION||_.env.AWS_LAMBDA_FUNCTION_NAME)},azure:{name:"Azure",detected:Boolean(_.env.AZURE_HTTP_USER_AGENT)},cloudflare:{name:"Cloudflare",detected:Boolean(_.env.CF_PAGES)},railway:{name:"Railway",detected:Boolean(_.env.RAILWAY_ENVIRONMENT)},render:{name:"Render",detected:Boolean(_.env.RENDER)}},XJ=Object.keys(N).find((J)=>{let Q=N[J];return Q!==void 0&&Q.detected})||"unknown",lJ=N[XJ]||{name:"Unknown",detected:!1};import jJ from"process";import{projectPath as GJ}from"@stacksjs/path";import l from"fs";var v={APP_ENV:["local","dev","development","staging","prod","production"],DB_CONNECTION:["mysql","sqlite","postgres","dynamodb"],MAIL_MAILER:["smtp","mailgun","ses","log","sendgrid","mailtrap"],SEARCH_ENGINE_DRIVER:["opensearch","meilisearch","algolia","typesense"],FRONTEND_APP_ENV:["development","staging","production"]};var WJ={get:(J,Q)=>{let $=J[Q],z=["_PORT","_TIMEOUT","_TTL","_SIZE","_LIMIT","_MAX","_MIN","_INTERVAL","_RETRIES","_CONCURRENCY","_WORKERS","_CONNECTIONS"];if(typeof $==="string"&&/^\d+$/.test($)&&!$.startsWith("0")&&z.some((Z)=>Q.endsWith(Z)))return Number($);if(typeof $==="string"){let Z=$.toLowerCase();if(Z==="true")return!0;if(Z==="false")return!1}return $}};function OJ(){return typeof Bun<"u"?Bun.env:jJ.env}var y=new Proxy(OJ(),WJ);function oJ(J,Q,$){let z=$?.path||GJ(".env"),X=l.readFileSync(z,"utf-8").split(`
24
+ `),Y=X.findIndex((j)=>j.startsWith(`${J}=`)),G=/[\s"'#$\\]/.test(Q)?`"${Q.replace(/"/g,"\\\"")}"`:Q;if(Y!==-1)X[Y]=`${J}=${G}`;else X.push(`${J}=${G}`);l.writeFileSync(z,X.join(`
25
+ `))}function sJ(J=y){let Q=[];for(let[$,z]of Object.entries(v)){let Z=J[$];if(Z!==void 0&&Z!==""&&!z.includes(String(Z)))Q.push(`${$}="${Z}" is not valid. Allowed values: ${z.join(", ")}`)}return Q}function tJ(J,Q=y){let $=[];for(let z of J){let Z=Q[z];if(Z===void 0||Z===""||Z===null)$.push(z)}if($.length>0)throw Error(`[env] Missing required environment variable(s): ${$.join(", ")}. Set them in .env or your process environment before booting.`);return Q}export{oJ as writeEnv,sJ as validateEnv,bJ as setEnv,mJ as runtimeInfo,ZJ as runtime,SJ as rotateKeypair,tJ as requireEnv,lJ as providerInfo,XJ as provider,OJ as process,P as platform,AJ as parseEnvFromKey,T as parse,_J as loadEnvFiles,k as loadEnv,hJ as isWindows,u as isNode,zJ as isMinimal,kJ as isMacOS,dJ as isLinux,cJ as isDebug,vJ as isColorSupported,$J as isCI,d as isBun,uJ as hasWindow,c as hasTTY,m as getPrivateKey,xJ as getKeypair,fJ as getEnv,b as generateKeypair,t as envPlugin,v as envEnum,y as env,S as encryptValue,e as encryptEnv,x as decryptValue,JJ as decryptEnv,LJ as autoLoadEnv,a as aesEncrypt,n as aesDecrypt};
package/dist/parser.js ADDED
@@ -0,0 +1,4 @@
1
+ // @bun
2
+ import{createCipheriv as G,createDecipheriv as W,createHash as $,randomBytes as w}from"crypto";function A(J,j){let R=w(16),I=j.length===32?j:Buffer.from(j.toString("hex").slice(0,64),"hex"),Q=G("aes-256-gcm",I,R),q=Buffer.concat([Q.update(J,"utf8"),Q.final()]),U=Q.getAuthTag();return{ciphertext:q.toString("hex"),iv:R.toString("hex"),authTag:U.toString("hex")}}function O(J,j,R,I){let Q=j.length===32?j:Buffer.from(j.toString("hex").slice(0,64),"hex");try{let q=W("aes-256-gcm",Q,Buffer.from(R,"hex"));return q.setAuthTag(Buffer.from(I,"hex")),Buffer.concat([q.update(Buffer.from(J,"hex")),q.final()]).toString("utf8")}catch(q){throw Error(`Decryption failed (data may be corrupted or key is incorrect): ${q instanceof Error?q.message:String(q)}`)}}function B(){let J=w(32);return{publicKey:$("sha256").update(J).digest().toString("hex"),privateKey:J.toString("hex")}}function g(J,j){let R=$("sha256").update(Buffer.from(j,"hex")).digest(),{ciphertext:I,iv:Q,authTag:q}=A(J,R);return`encrypted:${Buffer.concat([Buffer.from(Q,"hex"),Buffer.from(q,"hex"),Buffer.from(I,"hex")]).toString("base64")}`}function z(J,j){if(!J.startsWith("encrypted:"))return J;let R=J.slice(10),I=Buffer.from(R,"base64");if(I.length<32)throw Error("Invalid encrypted data: payload too short (need at least iv + authTag = 32 bytes)");let Q=I.subarray(0,16).toString("hex"),q=I.subarray(16,32).toString("hex"),U=I.subarray(32).toString("hex"),X=$("sha256").update(Buffer.from(j,"hex")).digest(),Y=$("sha256").update(X).digest();return O(U,Y,Q,q)}function D(J){let j=J.match(/^DOTENV_PRIVATE_KEY_(.+)$/);return j&&j[1]?j[1].toLowerCase():""}function H(J=""){if(!J)return process.env.DOTENV_PRIVATE_KEY;let j=`DOTENV_PRIVATE_KEY_${J.toUpperCase()}`;return process.env[j]}function S(J,j={}){let R={},I=[],Q=J.split(`
3
+ `);for(let q of Q){let U=q.trim();if(!U||U.startsWith("#"))continue;if(U.startsWith("DOTENV_PUBLIC_KEY=")){let Z=U.match(/^DOTENV_PUBLIC_KEY=["']?([^"'\n]+)["']?/);if(Z&&Z[1]!==void 0)R.DOTENV_PUBLIC_KEY=Z[1];continue}let X=U.match(/^([^=]+)=(.*)$/);if(!X||X[1]===void 0||X[2]===void 0)continue;let Y=X[1].trim(),F=X[2].trim();if(F.startsWith('"')&&F.endsWith('"')||F.startsWith("'")&&F.endsWith("'")){if(F=F.slice(1,-1),F.includes("\\n"))F=F.replace(/\\n/g,`
4
+ `)}if(j.privateKey&&(F.startsWith("encrypted:")||F.startsWith("enc:")))try{let Z=F.startsWith("enc:")?`encrypted:${F.slice(4)}`:F;F=z(Z,j.privateKey)}catch(Z){I.push(`Failed to decrypt ${Y}: ${Z instanceof Error?Z.message:"Unknown error"}`)}F=_(F,{...j.processEnv||process.env,...R}),F=L(F),R[Y]=F}return{parsed:R,errors:I}}function _(J,j){return J.replace(/\$\{([^}]+)\}/g,(R,I)=>{let Q=I.match(/^([^:\-+]+)(:-|-)(.+)$/);if(Q){let[,U,X,Y]=Q,F=j[U];if(X===":-")return F||Y;else return F!==void 0?F:Y}let q=I.match(/^([^:\-+]+)(:?\+)(.+)$/);if(q){let[,U,X,Y]=q,F=j[U];if(X===":+")return F?Y:"";else return F!==void 0?Y:""}return j[I]||""})}var C=new Set(["date","hostname","whoami","uname","pwd","echo","printf","cat","basename","dirname"]);function L(J){return J.replace(/\$\(([^)]+)\)/g,(j,R)=>{try{let I=R.trim().split(/\s+/),Q=I[0];if(!Q||!C.has(Q))return console.warn(`[env] Blocked command substitution for disallowed command: ${Q}`),"";let q=Bun.spawnSync(I,{stdout:"pipe",stderr:"pipe"});if(q.exitCode===0)return new TextDecoder().decode(q.stdout).trim();console.warn(`[env] Command substitution failed (exit code ${q.exitCode}): ${Q}`)}catch(I){console.warn(`[env] Command substitution error: ${I instanceof Error?I.message:String(I)}`)}return""})}async function M(J,j={}){let R={},I=[];for(let Q of J)try{let q=Bun.file(Q);if(!q.size)continue;let U=await q.text(),{parsed:X,errors:Y}=S(U,j);I.push(...Y);for(let[F,Z]of Object.entries(X)){if(!j.overload&&R[F]!==void 0)continue;R[F]=Z}}catch(q){if(q?.code==="ENOENT")continue;I.push(`Failed to read ${Q}: ${q instanceof Error?q.message:String(q)}`)}return{parsed:R,errors:I}}export{S as parse,M as loadEnvFiles};
package/dist/plugin.js ADDED
@@ -0,0 +1,4 @@
1
+ // @bun
2
+ import{createCipheriv as E,createDecipheriv as S,createHash as C,randomBytes as T}from"crypto";function N(R,j){let U=T(16),I=j.length===32?j:Buffer.from(j.toString("hex").slice(0,64),"hex"),X=E("aes-256-gcm",I,U),J=Buffer.concat([X.update(R,"utf8"),X.final()]),Y=X.getAuthTag();return{ciphertext:J.toString("hex"),iv:U.toString("hex"),authTag:Y.toString("hex")}}function K(R,j,U,I){let X=j.length===32?j:Buffer.from(j.toString("hex").slice(0,64),"hex");try{let J=S("aes-256-gcm",X,Buffer.from(U,"hex"));return J.setAuthTag(Buffer.from(I,"hex")),Buffer.concat([J.update(Buffer.from(R,"hex")),J.final()]).toString("utf8")}catch(J){throw Error(`Decryption failed (data may be corrupted or key is incorrect): ${J instanceof Error?J.message:String(J)}`)}}function k(){let R=T(32);return{publicKey:C("sha256").update(R).digest().toString("hex"),privateKey:R.toString("hex")}}function h(R,j){let U=C("sha256").update(Buffer.from(j,"hex")).digest(),{ciphertext:I,iv:X,authTag:J}=N(R,U);return`encrypted:${Buffer.concat([Buffer.from(X,"hex"),Buffer.from(J,"hex"),Buffer.from(I,"hex")]).toString("base64")}`}function D(R,j){if(!R.startsWith("encrypted:"))return R;let U=R.slice(10),I=Buffer.from(U,"base64");if(I.length<32)throw Error("Invalid encrypted data: payload too short (need at least iv + authTag = 32 bytes)");let X=I.subarray(0,16).toString("hex"),J=I.subarray(16,32).toString("hex"),Y=I.subarray(32).toString("hex"),Z=C("sha256").update(Buffer.from(j,"hex")).digest(),$=C("sha256").update(Z).digest();return K(Y,$,X,J)}function d(R){let j=R.match(/^DOTENV_PRIVATE_KEY_(.+)$/);return j&&j[1]?j[1].toLowerCase():""}function M(R=""){if(!R)return process.env.DOTENV_PRIVATE_KEY;let j=`DOTENV_PRIVATE_KEY_${R.toUpperCase()}`;return process.env[j]}function H(R,j={}){let U={},I=[],X=R.split(`
3
+ `);for(let J of X){let Y=J.trim();if(!Y||Y.startsWith("#"))continue;if(Y.startsWith("DOTENV_PUBLIC_KEY=")){let z=Y.match(/^DOTENV_PUBLIC_KEY=["']?([^"'\n]+)["']?/);if(z&&z[1]!==void 0)U.DOTENV_PUBLIC_KEY=z[1];continue}let Z=Y.match(/^([^=]+)=(.*)$/);if(!Z||Z[1]===void 0||Z[2]===void 0)continue;let $=Z[1].trim(),Q=Z[2].trim();if(Q.startsWith('"')&&Q.endsWith('"')||Q.startsWith("'")&&Q.endsWith("'")){if(Q=Q.slice(1,-1),Q.includes("\\n"))Q=Q.replace(/\\n/g,`
4
+ `)}if(j.privateKey&&(Q.startsWith("encrypted:")||Q.startsWith("enc:")))try{let z=Q.startsWith("enc:")?`encrypted:${Q.slice(4)}`:Q;Q=D(z,j.privateKey)}catch(z){I.push(`Failed to decrypt ${$}: ${z instanceof Error?z.message:"Unknown error"}`)}Q=P(Q,{...j.processEnv||process.env,...U}),Q=f(Q),U[$]=Q}return{parsed:U,errors:I}}function P(R,j){return R.replace(/\$\{([^}]+)\}/g,(U,I)=>{let X=I.match(/^([^:\-+]+)(:-|-)(.+)$/);if(X){let[,Y,Z,$]=X,Q=j[Y];if(Z===":-")return Q||$;else return Q!==void 0?Q:$}let J=I.match(/^([^:\-+]+)(:?\+)(.+)$/);if(J){let[,Y,Z,$]=J,Q=j[Y];if(Z===":+")return Q?$:"";else return Q!==void 0?$:""}return j[I]||""})}var V=new Set(["date","hostname","whoami","uname","pwd","echo","printf","cat","basename","dirname"]);function f(R){return R.replace(/\$\(([^)]+)\)/g,(j,U)=>{try{let I=U.trim().split(/\s+/),X=I[0];if(!X||!V.has(X))return console.warn(`[env] Blocked command substitution for disallowed command: ${X}`),"";let J=Bun.spawnSync(I,{stdout:"pipe",stderr:"pipe"});if(J.exitCode===0)return new TextDecoder().decode(J.stdout).trim();console.warn(`[env] Command substitution failed (exit code ${J.exitCode}): ${X}`)}catch(I){console.warn(`[env] Command substitution error: ${I instanceof Error?I.message:String(I)}`)}return""})}async function c(R,j={}){let U={},I=[];for(let X of R)try{let J=Bun.file(X);if(!J.size)continue;let Y=await J.text(),{parsed:Z,errors:$}=H(Y,j);I.push(...$);for(let[Q,z]of Object.entries(Z)){if(!j.overload&&U[Q]!==void 0)continue;U[Q]=z}}catch(J){if(J?.code==="ENOENT")continue;I.push(`Failed to read ${X}: ${J instanceof Error?J.message:String(J)}`)}return{parsed:U,errors:I}}import{existsSync as A}from"fs";import{readFileSync as w}from"fs";import{resolve as O}from"path";function b(R={}){let{path:j=[".env"],overload:U=!1,env:I,privateKey:X,keysFile:J,quiet:Y=!1,cwd:Z=process.cwd()}=R,$=Array.isArray(j)?j:[j],Q=[],z=0,q=X;if(!q&&J){let _=O(Z,J);if(A(_))try{let G=w(_,"utf-8"),{parsed:W}=H(G);if(I){let B=`DOTENV_PRIVATE_KEY_${I.toUpperCase()}`;q=W[B]}else q=W.DOTENV_PRIVATE_KEY}catch(G){Q.push(`Failed to load keys file: ${G instanceof Error?G.message:"Unknown error"}`)}}if(!q)q=M(I||"");for(let _ of $){let G=O(Z,_);if(!A(G)){if(!Y)Q.push(`File not found: ${G}`);continue}try{let W=w(G,"utf-8"),{parsed:B,errors:g}=H(W,{privateKey:q,processEnv:process.env});Q.push(...g);for(let[L,F]of Object.entries(B)){if(L==="DOTENV_PUBLIC_KEY")continue;if(U||process.env[L]===void 0)process.env[L]=F,z++}if(!Y&&!process.env.__ENV_LOADED__)console.log(`[env] loaded ${Object.keys(B).length} variables from ${_}`),process.env.__ENV_LOADED__="1"}catch(W){Q.push(`Failed to load ${G}: ${W instanceof Error?W.message:"Unknown error"}`)}}return{loaded:z,errors:Q}}function x(R={}){return{name:"env-plugin",setup(j){b(R)}}}function t(R={}){let j=R.env||"development",U=R.cwd||process.cwd(),I=[],X=`.env.${j}`,J=`.env.${j}.local`;if(A(O(U,J)))I.push(J);if(A(O(U,X)))I.push(X);if(A(O(U,".env.local")))I.push(".env.local");if(A(O(U,".env")))I.push(".env");return b({...R,path:I,env:j})}var a=x;export{b as loadEnv,x as envPlugin,a as default,t as autoLoadEnv};
package/dist/types.d.ts CHANGED
@@ -125,6 +125,7 @@ export declare interface StacksEnv {
125
125
  AUTH_USERNAME_FIELD: string | undefined
126
126
  AUTH_PASSWORD_FIELD: string | undefined
127
127
  AUTH_TOKEN_EXPIRY: number | undefined
128
+ AUTH_REFRESH_TOKEN_EXPIRY: number | undefined
128
129
  AUTH_TOKEN_ROTATION: number | undefined
129
130
  AUTH_PASSWORD_RESET_EXPIRE: number | undefined
130
131
  AUTH_PASSWORD_RESET_THROTTLE: number | undefined
package/dist/utils.js ADDED
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import b from"process";import{platform as E}from"os";var w=typeof Bun<"u",x=typeof b<"u"&&b.versions?.node!==void 0,F=w?"bun":x?"node":"unknown",O={name:F,version:w?Bun.version:x?b.version:void 0},j=E(),Q=j==="win32",R=j==="darwin",S=j==="linux",z=Boolean(b.stdout?.isTTY),U=typeof globalThis.window<"u",G=Boolean(b.env.CI||b.env.CONTINUOUS_INTEGRATION||b.env.BUILD_NUMBER||b.env.RUN_ID),V=Boolean(b.env.DEBUG||b.env.VERBOSE||b.argv.includes("--debug")||b.argv.includes("--verbose")),H=G||!z,W=Boolean(!H&&(z||b.env.COLORTERM||b.env.FORCE_COLOR||b.env.TERM&&b.env.TERM!=="dumb")),g={github:{name:"GitHub Actions",detected:Boolean(b.env.GITHUB_ACTIONS)},gitlab:{name:"GitLab CI",detected:Boolean(b.env.GITLAB_CI)},circle:{name:"CircleCI",detected:Boolean(b.env.CIRCLECI)},travis:{name:"Travis CI",detected:Boolean(b.env.TRAVIS)},jenkins:{name:"Jenkins",detected:Boolean(b.env.JENKINS_URL)},vercel:{name:"Vercel",detected:Boolean(b.env.VERCEL)},netlify:{name:"Netlify",detected:Boolean(b.env.NETLIFY)},heroku:{name:"Heroku",detected:Boolean(b.env.DYNO)},aws:{name:"AWS",detected:Boolean(b.env.AWS_REGION||b.env.AWS_LAMBDA_FUNCTION_NAME)},azure:{name:"Azure",detected:Boolean(b.env.AZURE_HTTP_USER_AGENT)},cloudflare:{name:"Cloudflare",detected:Boolean(b.env.CF_PAGES)},railway:{name:"Railway",detected:Boolean(b.env.RAILWAY_ENVIRONMENT)},render:{name:"Render",detected:Boolean(b.env.RENDER)}},J=Object.keys(g).find((A)=>{let q=g[A];return q!==void 0&&q.detected})||"unknown",X=g[J]||{name:"Unknown",detected:!1};export{O as runtimeInfo,F as runtime,X as providerInfo,J as provider,j as platform,Q as isWindows,x as isNode,H as isMinimal,R as isMacOS,S as isLinux,V as isDebug,W as isColorSupported,G as isCI,w as isBun,U as hasWindow,z as hasTTY};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/env",
3
3
  "type": "module",
4
- "version": "0.70.45",
4
+ "version": "0.70.54",
5
5
  "description": "Stacks env helper methods.",
6
6
  "author": "Chris Breuer",
7
7
  "contributors": [
@@ -46,7 +46,7 @@
46
46
  },
47
47
  "devDependencies": {
48
48
  "better-dx": "^0.2.12",
49
- "@stacksjs/path": "^0.70.45",
50
- "@stacksjs/validation": "^0.70.45"
49
+ "@stacksjs/path": "0.70.54",
50
+ "@stacksjs/validation": "0.70.54"
51
51
  }
52
52
  }