@stacksjs/rpx 0.11.4 → 0.11.5

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.
@@ -1,2 +1,2 @@
1
1
  import{createRequire as a}from"node:module";var c=a(import.meta.url);
2
- export{c as H};
2
+ export{c as I};
@@ -0,0 +1 @@
1
+ import{A as e,B as f,C as g,D as h,E as i,F as j,G as k,H as l,w as a,x as b,y as c,z as d}from"./chunk-cvt0dqrv.js";import"./chunk-sqn04kae.js";export{l as safeDeleteFile,k as resolvePathRewrite,e as isValidRootCA,i as isSingleProxyOptions,j as isSingleProxyConfig,h as isMultiProxyOptions,g as isMultiProxyConfig,a as getSudoPassword,f as getPrimaryDomain,d as extractHostname,b as execSudoSync,c as debugLog};
package/dist/https.d.ts CHANGED
@@ -24,16 +24,3 @@ export declare function loadSSLConfig(options: ProxyOption): Promise<SSLConfig |
24
24
  */
25
25
  export declare function forceTrustCertificate(certPath: string): Promise<boolean>;
26
26
  export declare function generateCertificate(options: ProxyOptions): Promise<void>;
27
- export declare function getSSLConfig(): { key: string, cert: string, ca?: string } | null;
28
- // needs to accept the options
29
- export declare function checkExistingCertificates(options?: ProxyOptions): Promise<SSLConfig | null>;
30
- export declare function httpsConfig(options: ProxyOption | ProxyOptions, verbose?: boolean): TlsConfig;
31
- /**
32
- * Clean up SSL certificates for a specific domain
33
- */
34
- export declare function cleanupCertificates(domain: string, verbose?: boolean): Promise<void>;
35
- /**
36
- * Checks if a certificate is trusted by the system (macOS only for now)
37
- * If options.regenerateUntrustedCerts is false, always returns true (skips trust check)
38
- */
39
- export declare function isCertTrusted(certPath: string, options?: { verbose?: boolean, regenerateUntrustedCerts?: boolean }): Promise<boolean>;
@@ -1,3 +1,4 @@
1
+ import * as process from 'node:process';
1
2
  import type { ChildProcess } from 'node:child_process';
2
3
  import type { StartOptions } from './types';
3
4
  export declare const processManager: ProcessManager;
package/dist/src/index.js CHANGED
@@ -1 +1 @@
1
- import{a as t,c as r,d as e,e as f,f as a,g as i,h as s,i as p,j as c,k as x,l as m,m as n,n as g,o as C,p as l,q as P,s as d,t as u,u as v,v as o}from"../chunk-pbbtnqsx.js";import"../chunk-3y886wa5.js";import{A as G,B as I,C as J,D as K,E as N,F as O,G as Q,w as j,x as q,y as z,z as B}from"../chunk-g5db14m7.js";import"../chunk-gbny098p.js";var U=o;export{u as startServer,v as startProxy,o as startProxies,Q as safeDeleteFile,f as removeHosts,P as portManager,i as loadSSLConfig,G as isValidRootCA,N as isSingleProxyOptions,O as isSingleProxyConfig,g as isPortInUse,K as isMultiProxyOptions,J as isMultiProxyConfig,n as isCertTrusted,x as httpsConfig,j as getSudoPassword,I as getPrimaryDomain,p as generateCertificate,s as forceTrustCertificate,C as findAvailablePort,B as extractHostname,q as execSudoSync,r as defaultConfig,U as default,z as debugLog,r as config,t as colors,m as cleanupCertificates,d as cleanup,a as checkHosts,c as checkExistingCertificates,e as addHosts,l as DefaultPortManager};
1
+ import{a as t,c as r,d as e,e as f,f as a,g as i,h as s,i as p,j as c,k as x,l as m,m as n,n as g,o as C,p as l,q as P,s as d,t as u,u as v,v as o}from"../chunk-grcvjvzg.js";import"../chunk-hj5q1vd6.js";import{A as G,B as I,C as J,D as K,E as N,F as O,G as Q,H as R,w as j,x as q,y as z,z as B}from"../chunk-cvt0dqrv.js";import"../chunk-sqn04kae.js";var U=o;export{u as startServer,v as startProxy,o as startProxies,R as safeDeleteFile,Q as resolvePathRewrite,f as removeHosts,P as portManager,i as loadSSLConfig,G as isValidRootCA,N as isSingleProxyOptions,O as isSingleProxyConfig,g as isPortInUse,K as isMultiProxyOptions,J as isMultiProxyConfig,n as isCertTrusted,x as httpsConfig,j as getSudoPassword,I as getPrimaryDomain,p as generateCertificate,s as forceTrustCertificate,C as findAvailablePort,B as extractHostname,q as execSudoSync,r as defaultConfig,U as default,z as debugLog,r as config,t as colors,m as cleanupCertificates,d as cleanup,a as checkHosts,c as checkExistingCertificates,e as addHosts,l as DefaultPortManager};
package/dist/start.d.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import * as http from 'node:http';
2
+ import * as http2 from 'node:http2';
3
+ import * as https from 'node:https';
1
4
  import type { CleanupOptions, ProxyOption, ProxyOptions, ProxySetupOptions, SingleProxyConfig } from './types';
2
5
  export declare function cleanup(options?: CleanupOptions): Promise<void>;
3
6
  export declare function startServer(options: SingleProxyConfig): Promise<void>;
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { MultiProxyConfig, ProxyConfigs, ProxyOption, ProxyOptions, SingleProxyConfig } from './types';
1
+ import type { MultiProxyConfig, PathRewrite, ProxyConfigs, ProxyOption, ProxyOptions, SingleProxyConfig } from './types';
2
2
  /**
3
3
  * Get sudo password from environment variable if set
4
4
  */
@@ -27,6 +27,16 @@ export declare function isMultiProxyOptions(options: ProxyOption | ProxyOptions)
27
27
  */
28
28
  export declare function isSingleProxyOptions(options: ProxyOption | ProxyOptions): options is SingleProxyConfig;
29
29
  export declare function isSingleProxyConfig(options: ProxyConfigs | ProxyOptions): options is SingleProxyConfig;
30
+ /**
31
+ * Resolve a path against a list of `pathRewrites`.
32
+ *
33
+ * Returns `null` if no rewrite matches; otherwise returns `{ targetHost, targetPath }`
34
+ * with the prefix preserved by default (or stripped when `stripPrefix === true`).
35
+ *
36
+ * Matching rule: rewrite matches if `pathname` is exactly `from` OR starts with
37
+ * `from + '/'`. So `/api` matches `/api`, `/api/`, `/api/cart` — but not `/apidocs`.
38
+ */
39
+ export declare function resolvePathRewrite(pathname: string, rewrites: PathRewrite[] | undefined): { targetHost: string, targetPath: string } | null;
30
40
  /**
31
41
  * Safely delete a file if it exists
32
42
  */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/rpx",
3
3
  "type": "module",
4
- "version": "0.11.4",
4
+ "version": "0.11.5",
5
5
  "description": "A modern and smart reverse proxy.",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",
7
7
  "license": "MIT",
package/src/start.ts CHANGED
@@ -20,7 +20,7 @@ import { addHosts, checkHosts, removeHosts } from './hosts'
20
20
  import { checkExistingCertificates, cleanupCertificates, generateCertificate, httpsConfig, loadSSLConfig } from './https'
21
21
  import { DefaultPortManager, findAvailablePort, isPortInUse } from './port-manager'
22
22
  import { ProcessManager } from './process-manager'
23
- import { debugLog, getSudoPassword } from './utils'
23
+ import { debugLog, getSudoPassword, resolvePathRewrite } from './utils'
24
24
 
25
25
  const processManager = new ProcessManager()
26
26
  // Create a global port manager for coordinating port usage
@@ -1236,18 +1236,14 @@ export async function startProxies(options?: ProxyOptions): Promise<void> {
1236
1236
  let targetHost = route.sourceHost
1237
1237
  let targetPath = url.pathname
1238
1238
 
1239
- // Check path rewrites — route specific path prefixes to different backends
1240
- if (route.pathRewrites) {
1241
- for (const rewrite of route.pathRewrites) {
1242
- if (url.pathname === rewrite.from || url.pathname.startsWith(`${rewrite.from}/`)) {
1243
- targetHost = rewrite.to.startsWith('http') ? new URL(rewrite.to).host : rewrite.to
1244
- if (rewrite.stripPrefix !== false) {
1245
- targetPath = url.pathname.slice(rewrite.from.length) || '/'
1246
- }
1247
- debugLog('request', `Path rewrite: ${url.pathname} → ${targetHost}${targetPath}`, verbose)
1248
- break
1249
- }
1250
- }
1239
+ // Check path rewrites — route specific path prefixes to different backends.
1240
+ // By default the prefix is preserved (matches Vite/nginx/http-proxy-middleware
1241
+ // semantics); set `stripPrefix: true` per-rewrite to strip.
1242
+ const rewriteMatch = resolvePathRewrite(url.pathname, route.pathRewrites)
1243
+ if (rewriteMatch) {
1244
+ targetHost = rewriteMatch.targetHost
1245
+ targetPath = rewriteMatch.targetPath
1246
+ debugLog('request', `Path rewrite: ${url.pathname} → ${targetHost}${targetPath}`, verbose)
1251
1247
  }
1252
1248
 
1253
1249
  const targetUrl = `http://${targetHost}${targetPath}${url.search}`
package/src/types.ts CHANGED
@@ -11,7 +11,16 @@ export interface PathRewrite {
11
11
  from: string
12
12
  /** Target backend to route to, e.g. 'localhost:3008' */
13
13
  to: string
14
- /** Strip the matched prefix before forwarding (default: true) */
14
+ /**
15
+ * Strip the matched prefix before forwarding. Default: `false` (preserve path).
16
+ *
17
+ * Matches the behavior of Vite's `server.proxy`, nginx `proxy_pass http://host:port`
18
+ * (no trailing slash), and http-proxy-middleware's default. Most upstreams that own
19
+ * a `/api` namespace expect the prefix to remain on the request URL.
20
+ *
21
+ * Set to `true` only when the upstream registers routes WITHOUT the prefix
22
+ * (e.g., upstream serves `/cart/add` and you want `/api/cart/add` to reach it).
23
+ */
15
24
  stripPrefix?: boolean
16
25
  }
17
26
 
package/src/utils.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { MultiProxyConfig, ProxyConfigs, ProxyOption, ProxyOptions, SingleProxyConfig } from './types'
1
+ import type { MultiProxyConfig, PathRewrite, ProxyConfigs, ProxyOption, ProxyOptions, SingleProxyConfig } from './types'
2
2
  import { execSync } from 'node:child_process'
3
3
  import * as fs from 'node:fs/promises'
4
4
  import { Logger } from '@stacksjs/clarity'
@@ -109,6 +109,35 @@ export function isSingleProxyConfig(options: ProxyConfigs | ProxyOptions): optio
109
109
  return !!(options && 'to' in options && !('proxies' in options))
110
110
  }
111
111
 
112
+ /**
113
+ * Resolve a path against a list of `pathRewrites`.
114
+ *
115
+ * Returns `null` if no rewrite matches; otherwise returns `{ targetHost, targetPath }`
116
+ * with the prefix preserved by default (or stripped when `stripPrefix === true`).
117
+ *
118
+ * Matching rule: rewrite matches if `pathname` is exactly `from` OR starts with
119
+ * `from + '/'`. So `/api` matches `/api`, `/api/`, `/api/cart` — but not `/apidocs`.
120
+ */
121
+ export function resolvePathRewrite(
122
+ pathname: string,
123
+ rewrites: PathRewrite[] | undefined,
124
+ ): { targetHost: string, targetPath: string } | null {
125
+ if (!rewrites || rewrites.length === 0)
126
+ return null
127
+
128
+ for (const rewrite of rewrites) {
129
+ if (pathname === rewrite.from || pathname.startsWith(`${rewrite.from}/`)) {
130
+ const targetHost = rewrite.to.startsWith('http') ? new URL(rewrite.to).host : rewrite.to
131
+ const targetPath = rewrite.stripPrefix === true
132
+ ? (pathname.slice(rewrite.from.length) || '/')
133
+ : pathname
134
+ return { targetHost, targetPath }
135
+ }
136
+ }
137
+
138
+ return null
139
+ }
140
+
112
141
  /**
113
142
  * Safely delete a file if it exists
114
143
  */
@@ -1 +0,0 @@
1
- import{A as e,B as f,C as g,D as h,E as i,F as j,G as k,w as a,x as b,y as c,z as d}from"./chunk-g5db14m7.js";import"./chunk-gbny098p.js";export{k as safeDeleteFile,e as isValidRootCA,i as isSingleProxyOptions,j as isSingleProxyConfig,h as isMultiProxyOptions,g as isMultiProxyConfig,a as getSudoPassword,f as getPrimaryDomain,d as extractHostname,b as execSudoSync,c as debugLog};
@@ -1,19 +0,0 @@
1
- import{H as pH}from"./chunk-gbny098p.js";import{execSync as lH}from"node:child_process";import*as oH from"node:fs/promises";import{join as sH,relative as tH,resolve as TH}from"path";import e from"process";import{existsSync as mH,mkdirSync as gQ,readdirSync as nQ,writeFileSync as lQ}from"fs";import{homedir as XH}from"os";import{dirname as aQ,resolve as C}from"path";import g from"process";import{join as eH,relative as HQ,resolve as FH}from"path";import HH from"process";import{existsSync as cH,mkdirSync as HU,readdirSync as QU,writeFileSync as UU}from"fs";import{dirname as $U,resolve as QH}from"path";import LH from"process";import{Buffer as y}from"buffer";import{createCipheriv as QQ,createDecipheriv as UQ,randomBytes as YH}from"crypto";import{closeSync as JH,createReadStream as BH,createWriteStream as ZQ,existsSync as GH,fsyncSync as OH,openSync as jH,writeFileSync as $Q}from"fs";import{access as XQ,constants as MH,mkdir as YQ,readdir as l,rename as IH,stat as f,unlink as i,writeFile as qH}from"fs/promises";import{join as u}from"path";import O from"process";import{pipeline as JQ}from"stream/promises";import{createGzip as wH}from"zlib";import d from"process";import v from"process";import{Buffer as h}from"buffer";import{createCipheriv as OQ,createDecipheriv as jQ,randomBytes as zH}from"crypto";import{closeSync as _H,createReadStream as SH,createWriteStream as MQ,existsSync as a,fsyncSync as hH,openSync as vH,writeFileSync as IQ}from"fs";import{access as wQ,constants as bH,mkdir as CQ,readdir as r,rename as yH,stat as p,unlink as s,writeFile as RH}from"fs/promises";import{isAbsolute as kQ,join as m,resolve as xQ}from"path";import _ from"process";import{pipeline as PQ}from"stream/promises";import{createGzip as fH}from"zlib";import c from"process";import b from"process";function VH(H,Q){if(Array.isArray(Q)&&Array.isArray(H)&&Q.length===2&&H.length===2&&V(Q[0])&&"id"in Q[0]&&Q[0].id===3&&V(Q[1])&&"id"in Q[1]&&Q[1].id===4)return Q;if(V(Q)&&V(H)&&Object.keys(Q).length===2&&Object.keys(Q).includes("a")&&Q.a===null&&Object.keys(Q).includes("c")&&Q.c===void 0)return{a:null,b:2,c:void 0};if(Q===null||Q===void 0)return H;if(Array.isArray(Q)&&!Array.isArray(H))return Q;if(Array.isArray(Q)&&Array.isArray(H)){if(V(H)&&"arr"in H&&Array.isArray(H.arr)&&V(Q)&&"arr"in Q&&Array.isArray(Q.arr))return Q;if(Q.length>0&&H.length>0&&V(Q[0])&&V(H[0])){let Z=[...Q];for(let $ of H)if(V($)&&"name"in $){if(!Z.find((Y)=>V(Y)&&("name"in Y)&&Y.name===$.name))Z.push($)}else if(V($)&&"path"in $){if(!Z.find((Y)=>V(Y)&&("path"in Y)&&Y.path===$.path))Z.push($)}else if(!Z.some((X)=>UH(X,$)))Z.push($);return Z}if(Q.every((Z)=>typeof Z==="string")&&H.every((Z)=>typeof Z==="string")){let Z=[...Q];for(let $ of H)if(!Z.includes($))Z.push($);return Z}return Q}if(!V(Q)||!V(H))return Q;let U={...H};for(let Z in Q)if(Object.prototype.hasOwnProperty.call(Q,Z)){let $=Q[Z];if($===null||$===void 0)continue;else if(V($)&&V(U[Z]))U[Z]=VH(U[Z],$);else if(Array.isArray($)&&Array.isArray(U[Z]))if($.length>0&&U[Z].length>0&&V($[0])&&V(U[Z][0])){let X=[...$];for(let Y of U[Z])if(V(Y)&&"name"in Y){if(!X.find((J)=>V(J)&&("name"in J)&&J.name===Y.name))X.push(Y)}else if(V(Y)&&"path"in Y){if(!X.find((J)=>V(J)&&("path"in J)&&J.path===Y.path))X.push(Y)}else if(!X.some((G)=>UH(G,Y)))X.push(Y);U[Z]=X}else if($.every((X)=>typeof X==="string")&&U[Z].every((X)=>typeof X==="string")){let X=[...$];for(let Y of U[Z])if(!X.includes(Y))X.push(Y);U[Z]=X}else U[Z]=$;else U[Z]=$}return U}function UH(H,Q){if(H===Q)return!0;if(Array.isArray(H)&&Array.isArray(Q)){if(H.length!==Q.length)return!1;for(let U=0;U<H.length;U++)if(!UH(H[U],Q[U]))return!1;return!0}if(V(H)&&V(Q)){let U=Object.keys(H),Z=Object.keys(Q);if(U.length!==Z.length)return!1;for(let $ of U){if(!Object.prototype.hasOwnProperty.call(Q,$))return!1;if(!UH(H[$],Q[$]))return!1}return!0}return!1}function V(H){return Boolean(H&&typeof H==="object"&&!Array.isArray(H))}async function GQ(H,Q){if(!cH(H))return null;try{let U=await import(H),Z=U.default||U;if(typeof Z!=="object"||Z===null||Array.isArray(Z))return null;try{return VH(Q,Z)}catch{return null}}catch{return null}}async function qQ({name:H="",cwd:Q,defaultConfig:U}){let Z=Q||LH.cwd(),$=[".ts",".js",".mjs",".cjs",".json"],X=[`${H}.config`,`.${H}.config`,H,`.${H}`];for(let Y of X)for(let G of $){let J=QH(Z,`${Y}${G}`),q=await GQ(J,U);if(q!==null)return q}try{let Y=QH(Z,"package.json");if(cH(Y)){let J=(await import(Y))[H];if(J&&typeof J==="object"&&!Array.isArray(J))try{return VH(U,J)}catch{}}}catch{}return U}var KU=QH(LH.cwd(),"config"),LU=QH(LH.cwd(),"src/generated");function NQ(H,Q={}){let U=HH.cwd();while(U.includes("storage"))U=FH(U,"..");let Z=FH(U,H||"");if(Q?.relative)return HQ(HH.cwd(),Z);return Z}var AQ=HH.env.CLARITY_LOG_DIR||eH(NQ(),"logs"),NH={level:"info",defaultName:"clarity",timestamp:!0,colors:!0,format:"text",maxLogSize:10485760,logDatePattern:"YYYY-MM-DD",logDirectory:AQ,rotation:{frequency:"daily",maxSize:10485760,maxFiles:5,compress:!1,rotateHour:0,rotateMinute:0,rotateDayOfWeek:0,rotateDayOfMonth:1,encrypt:!1},verbose:!1};async function WQ(){try{let H=await qQ({name:"clarity",defaultConfig:NH,cwd:HH.cwd(),endpoint:"",headers:{}});return{...NH,...H}}catch{return NH}}var CH=await WQ();function E(){if(v.env.NODE_ENV==="test"||v.env.BUN_ENV==="test")return!1;return typeof window<"u"}async function zQ(){if(v.env.NODE_ENV==="test"||v.env.BUN_ENV==="test")return!0;if(typeof navigator<"u"&&navigator.product==="ReactNative")return!0;if(typeof v<"u"){let H=v.type;if(H==="renderer"||H==="worker")return!1;return!!(v.versions&&(v.versions.node||v.versions.bun))}return!1}class gH{async format(H){let Q=await zQ(),U=await this.getMetadata(Q);return JSON.stringify({timestamp:H.timestamp.toISOString(),level:H.level,name:H.name,message:H.message,metadata:U})}async getMetadata(H){if(H){let{hostname:Q}=await import("os");return{pid:d.pid,hostname:Q(),environment:d.env.NODE_ENV||"development",platform:d.platform,version:d.version}}return{userAgent:navigator.userAgent,hostname:window.location.hostname||"browser",environment:d.env.NODE_ENV||d.env.BUN_ENV||"development",viewport:{width:window.innerWidth,height:window.innerHeight},language:navigator.language}}}var w={red:(H)=>`\x1B[31m${H}\x1B[0m`,green:(H)=>`\x1B[32m${H}\x1B[0m`,yellow:(H)=>`\x1B[33m${H}\x1B[0m`,blue:(H)=>`\x1B[34m${H}\x1B[0m`,magenta:(H)=>`\x1B[35m${H}\x1B[0m`,cyan:(H)=>`\x1B[36m${H}\x1B[0m`,white:(H)=>`\x1B[37m${H}\x1B[0m`,gray:(H)=>`\x1B[90m${H}\x1B[0m`,bgRed:(H)=>`\x1B[41m${H}\x1B[0m`,bgYellow:(H)=>`\x1B[43m${H}\x1B[0m`,bold:(H)=>`\x1B[1m${H}\x1B[0m`,dim:(H)=>`\x1B[2m${H}\x1B[0m`,italic:(H)=>`\x1B[3m${H}\x1B[0m`,underline:(H)=>`\x1B[4m${H}\x1B[0m`,reset:"\x1B[0m"},L=w,VU=w.red,_Q=w.green,DU=w.yellow,RQ=w.blue,EU=w.magenta,TU=w.cyan,kH=w.white,FU=w.gray,KQ=w.bgRed,LQ=w.bgYellow,xH=w.bold,BU=w.dim,OU=w.italic,jU=w.underline,MU=w.reset,AH={activationLevel:"error",bufferSize:50,flushOnDeactivation:!0,stopBuffering:!1},VQ={debug:"\uD83D\uDD0D",info:RQ("ℹ"),success:_Q("✓"),warning:LQ(kH(xH(" WARN "))),error:KQ(kH(xH(" ERROR ")))};class $H{name;fileLocks=new Map;currentKeyId=null;keys=new Map;config;options;formatter;timers=new Set;subLoggers=new Set;fingersCrossedBuffer=[];fingersCrossedConfig;fingersCrossedActive=!1;currentLogFile;rotationTimeout;keyRotationTimeout;encryptionKeys;logBuffer=[];isActivated=!1;pendingOperations=[];enabled;fancy;tagFormat;timestampPosition;environment;ANSI_PATTERN=/\u001B\[.*?m/g;activeProgressBar=null;constructor(H,Q={}){this.name=H,this.config={...CH},this.options=this.normalizeOptions(Q),this.formatter=this.options.formatter||new gH,this.enabled=Q.enabled??!0,this.fancy=Q.fancy??!0,this.tagFormat=Q.tagFormat??{prefix:"[",suffix:"]"},this.timestampPosition=Q.timestampPosition??"right",this.environment=Q.environment??O.env.APP_ENV??"local",this.fingersCrossedConfig=this.initializeFingersCrossedConfig(Q);let U={...Q},Z=Q.timestamp!==void 0;if(Z)delete U.timestamp;if(this.config={...this.config,...U,timestamp:Z||this.config.timestamp},this.currentLogFile=this.generateLogFilename(),this.encryptionKeys=new Map,this.validateEncryptionConfig()){this.setupRotation();let $=this.generateKeyId(),X=this.generateKey();this.currentKeyId=$,this.keys.set($,X),this.encryptionKeys.set($,{key:X,createdAt:new Date}),this.setupKeyRotation()}}initializeFingersCrossedConfig(H){if(!H.fingersCrossedEnabled&&H.fingersCrossed)return{...AH,...H.fingersCrossed};if(!H.fingersCrossedEnabled)return null;if(!H.fingersCrossed)return{...AH};return{...AH,...H.fingersCrossed}}normalizeOptions(H){let Q={format:"json",level:"info",logDirectory:CH.logDirectory,rotation:void 0,timestamp:void 0,fingersCrossed:{},enabled:!0,showTags:!1,formatter:void 0},U={...Q,...Object.fromEntries(Object.entries(H).filter(([,Z])=>Z!==void 0))};if(!U.level||!["debug","info","success","warning","error"].includes(U.level))U.level=Q.level;return U}async writeToFile(H){let U=(async()=>{let $,X=0,Y=3,G=1000;while(X<Y)try{try{try{await XQ(this.config.logDirectory,MH.F_OK|MH.W_OK)}catch(q){if(q instanceof Error&&"code"in q)if(q.code==="ENOENT")await YQ(this.config.logDirectory,{recursive:!0,mode:493});else if(q.code==="EACCES")throw Error(`No write permission for log directory: ${this.config.logDirectory}`);else throw q;else throw q}}catch(q){throw console.error("Debug: [writeToFile] Failed to create log directory:",q),q}let J=this.validateEncryptionConfig()?(await this.encrypt(H)).encrypted:y.from(H);try{if(!GH(this.currentLogFile))await qH(this.currentLogFile,"",{mode:420});if($=jH(this.currentLogFile,"a",420),$Q($,J,{flag:"a"}),OH($),$!==void 0)JH($),$=void 0;if((await f(this.currentLogFile)).size===0){if(await qH(this.currentLogFile,J,{flag:"w",mode:420}),(await f(this.currentLogFile)).size===0)throw Error("File exists but is empty after retry write")}return}catch(q){let N=q;if(N.code&&["ENETDOWN","ENETUNREACH","ENOTFOUND","ETIMEDOUT"].includes(N.code)){if(X<Y-1){let A=typeof N.message==="string"?N.message:"Unknown error";console.error(`Network error during write attempt ${X+1}/${Y}:`,A);let z=G*2**X;await new Promise((W)=>setTimeout(W,z)),X++;continue}}if(N?.code&&["ENOSPC","EDQUOT"].includes(N.code))throw Error(`Disk quota exceeded or no space left on device: ${N.message}`);throw console.error("Debug: [writeToFile] Error writing to file:",N),N}finally{if($!==void 0)try{JH($)}catch(q){console.error("Debug: [writeToFile] Error closing file descriptor:",q)}}}catch(J){if(X===Y-1){let N=J,A=typeof N.message==="string"?N.message:"Unknown error";throw console.error("Debug: [writeToFile] Max retries reached. Final error:",A),J}X++;let q=G*2**(X-1);await new Promise((N)=>setTimeout(N,q))}})();this.pendingOperations.push(U);let Z=this.pendingOperations.length-1;try{await U}catch($){throw console.error("Debug: [writeToFile] Error in operation:",$),$}finally{this.pendingOperations.splice(Z,1)}}generateLogFilename(){if(this.name.includes("stream-throughput")||this.name.includes("decompress-perf-test")||this.name.includes("decompression-latency")||this.name.includes("concurrent-read-test")||this.name.includes("clock-change-test"))return u(this.config.logDirectory,`${this.name}.log`);if(this.name.includes("pending-test")||this.name.includes("temp-file-test")||this.name==="crash-test"||this.name==="corrupt-test"||this.name.includes("rotation-load-test")||this.name==="sigterm-test"||this.name==="sigint-test"||this.name==="failed-rotation-test"||this.name==="integration-test")return u(this.config.logDirectory,`${this.name}.log`);let H=new Date().toISOString().split("T")[0];return u(this.config.logDirectory,`${this.name}-${H}.log`)}setupRotation(){if(E())return;if(typeof this.config.rotation==="boolean")return;let H=this.config.rotation,Q;switch(H.frequency){case"daily":Q=86400000;break;case"weekly":Q=604800000;break;case"monthly":Q=2592000000;break;default:return}this.rotationTimeout=setInterval(()=>{this.rotateLog()},Q)}setupKeyRotation(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation setup");return}let Q=this.config.rotation.keyRotation;if(!Q?.enabled)return;let U=typeof Q.interval==="number"?Q.interval:60,Z=Math.max(U,60)*1000;this.keyRotationTimeout=setInterval(()=>{this.rotateKeys().catch(($)=>{console.error("Error rotating keys:",$)})},Z)}async rotateKeys(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation");return}let Q=this.config.rotation.keyRotation,U=this.generateKeyId(),Z=this.generateKey();this.currentKeyId=U,this.keys.set(U,Z),this.encryptionKeys.set(U,{key:Z,createdAt:new Date});let $=Array.from(this.encryptionKeys.entries()).sort(([,G],[,J])=>J.createdAt.getTime()-G.createdAt.getTime()),X=typeof Q.maxKeys==="number"?Q.maxKeys:1,Y=Math.max(1,X);if($.length>Y)for(let[G]of $.slice(Y))this.encryptionKeys.delete(G),this.keys.delete(G)}generateKeyId(){return YH(16).toString("hex")}generateKey(){return YH(32)}getCurrentKey(){if(!this.currentKeyId)throw Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");let H=this.keys.get(this.currentKeyId);if(!H)throw Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);return{key:H,id:this.currentKeyId}}encrypt(H){let{key:Q}=this.getCurrentKey(),U=YH(16),Z=QQ("aes-256-gcm",Q,U),$=y.concat([Z.update(H,"utf8"),Z.final()]),X=Z.getAuthTag();return{encrypted:y.concat([U,$,X]),iv:U}}async compressData(H){return new Promise((Q,U)=>{let Z=wH(),$=[];Z.on("data",(X)=>$.push(X)),Z.on("end",()=>Q(y.from(y.concat($)))),Z.on("error",U),Z.write(H),Z.end()})}getEncryptionOptions(){if(!this.config.rotation||typeof this.config.rotation==="boolean"||!this.config.rotation.encrypt)return{};let H={algorithm:"aes-256-cbc",compress:!1};if(typeof this.config.rotation.encrypt==="object"){let Q=this.config.rotation.encrypt;return{...H,...Q}}return H}async rotateLog(){if(E())return;let H=await f(this.currentLogFile).catch(()=>null);if(!H)return;let Q=this.config.rotation;if(typeof Q==="boolean")return;if(Q.maxSize&&H.size>=Q.maxSize){let U=this.currentLogFile,Z=this.generateLogFilename();if(this.name.includes("rotation-load-test")||this.name==="failed-rotation-test"){let $=await l(this.config.logDirectory),X=$.filter((J)=>J.startsWith(this.name)&&/\.log\.\d+$/.test(J)).sort((J,q)=>{let N=Number.parseInt(J.match(/\.log\.(\d+)$/)?.[1]||"0");return Number.parseInt(q.match(/\.log\.(\d+)$/)?.[1]||"0")-N}),Y=X.length>0?Number.parseInt(X[0].match(/\.log\.(\d+)$/)?.[1]||"0")+1:1,G=`${U}.${Y}`;if(await f(U).catch(()=>null))try{if(await IH(U,G),Q.compress)try{let J=`${G}.gz`;await this.compressLogFile(G,J),await i(G)}catch(J){console.error("Error compressing rotated file:",J)}if(X.length===0&&!$.some((J)=>J.endsWith(".log.1")))try{let J=`${U}.1`;await qH(J,"")}catch(J){console.error("Error creating backup file:",J)}}catch(J){console.error(`Error during rotation: ${J instanceof Error?J.message:String(J)}`)}}else{let $=new Date().toISOString().replace(/[:.]/g,"-"),X=U.replace(/\.log$/,`-${$}.log`);if(await f(U).catch(()=>null))await IH(U,X)}if(this.currentLogFile=Z,Q.maxFiles){let X=(await l(this.config.logDirectory)).filter((Y)=>Y.startsWith(this.name)).sort((Y,G)=>G.localeCompare(Y));for(let Y of X.slice(Q.maxFiles))await i(u(this.config.logDirectory,Y))}}}async compressLogFile(H,Q){let U=BH(H),Z=ZQ(Q),$=wH();await JQ(U,$,Z)}async handleFingersCrossedBuffer(H,Q){if(!this.fingersCrossedConfig)return;if(this.shouldActivateFingersCrossed(H)&&!this.isActivated){this.isActivated=!0;for(let U of this.logBuffer){let Z=await this.formatter.format(U);await this.writeToFile(Z),console.log(Z)}if(this.fingersCrossedConfig.stopBuffering)this.logBuffer=[]}if(this.isActivated)await this.writeToFile(Q),console.log(Q);else{if(this.logBuffer.length>=this.fingersCrossedConfig.bufferSize)this.logBuffer.shift();let U={timestamp:new Date,level:H,message:Q,name:this.name};this.logBuffer.push(U)}}shouldActivateFingersCrossed(H){if(!this.fingersCrossedConfig)return!1;return this.getLevelValue(H)>=this.getLevelValue(this.fingersCrossedConfig.activationLevel)}getLevelValue(H){return{debug:0,info:1,success:2,warning:3,error:4}[H]}shouldLog(H){if(!this.enabled)return!1;let Q={debug:0,info:1,success:2,warning:3,error:4};return Q[H]>=Q[this.config.level]}async flushPendingWrites(){if(await Promise.all(this.pendingOperations.map((H)=>{if(H instanceof Promise)return H.catch((Q)=>{console.error("Error in pending write operation:",Q)});return Promise.resolve()})),GH(this.currentLogFile))try{let H=jH(this.currentLogFile,"r+");OH(H),JH(H)}catch(H){console.error(`Error flushing file: ${H}`)}}async destroy(){if(this.rotationTimeout)clearInterval(this.rotationTimeout);if(this.keyRotationTimeout)clearInterval(this.keyRotationTimeout);this.timers.clear();for(let H of this.pendingOperations)if(typeof H.cancel==="function")H.cancel();return(async()=>{if(this.pendingOperations.length>0)try{await Promise.allSettled(this.pendingOperations)}catch(H){console.error("Error waiting for pending operations:",H)}if(!E()&&this.config.rotation&&typeof this.config.rotation!=="boolean"&&this.config.rotation.compress)try{let Q=(await l(this.config.logDirectory)).filter((U)=>(U.includes("temp")||U.includes(".tmp"))&&U.includes(this.name));for(let U of Q)try{await i(u(this.config.logDirectory,U))}catch(Z){console.error(`Failed to delete temp file ${U}:`,Z)}}catch(H){console.error("Error cleaning up temporary files:",H)}})()}getCurrentLogFilePath(){return this.currentLogFile}formatTag(H){if(!H)return"";return`${this.tagFormat.prefix}${H}${this.tagFormat.suffix}`}formatFileTimestamp(H){return`[${H.toISOString()}]`}formatConsoleTimestamp(H){return this.fancy?L.gray(H.toLocaleTimeString()):H.toLocaleTimeString()}formatConsoleMessage(H){let{timestamp:Q,icon:U="",tag:Z="",message:$,level:X,showTimestamp:Y=!0}=H,G=(W)=>W.replace(this.ANSI_PATTERN,"");if(!this.fancy){let W=[];if(Y)W.push(Q);if(X==="warning")W.push("WARN");else if(X==="error")W.push("ERROR");else if(U)W.push(U.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu,""));if(Z)W.push(Z.replace(/[[\]]/g,""));return W.push($),W.join(" ")}let J=O.stdout.columns||120,q="";if(X==="warning"||X==="error")q=`${U} ${$}`;else if(X==="info"||X==="success")q=`${U} ${Z} ${$}`;else q=`${U} ${Z} ${L.cyan($)}`;if(!Y)return q.trim();let N=G(q).trim().length,A=G(Q).length,z=Math.max(1,J-2-N-A);return`${q.trim()}${" ".repeat(z)}${Q}`}formatMessage(H,Q){if(Q.length===1&&Array.isArray(Q[0]))return H.replace(/\{(\d+)\}/g,(X,Y)=>{let G=Number.parseInt(Y,10);return G<Q[0].length?String(Q[0][G]):X});let U=/%([sdijfo%])/g,Z=0,$=H.replace(U,(X,Y)=>{if(Y==="%")return"%";if(Z>=Q.length)return X;let G=Q[Z++];switch(Y){case"s":return String(G);case"d":case"i":return Number(G).toString();case"j":case"o":return JSON.stringify(G,null,2);default:return X}});if(Z<Q.length)$+=` ${Q.slice(Z).map((X)=>typeof X==="object"?JSON.stringify(X,null,2):String(X)).join(" ")}`;return $}async log(H,Q,...U){let Z=new Date,$=this.formatConsoleTimestamp(Z),X=this.formatFileTimestamp(Z),Y,G;if(Q instanceof Error)Y=Q.message,G=Q.stack;else Y=this.formatMessage(Q,U);if(this.fancy&&!E()){let q=VQ[H],N=this.options.showTags!==!1&&this.name?L.gray(this.formatTag(this.name)):"",A;switch(H){case"debug":A=this.formatConsoleMessage({timestamp:$,icon:q,tag:N,message:L.gray(Y),level:H}),console.error(A);break;case"info":A=this.formatConsoleMessage({timestamp:$,icon:q,tag:N,message:Y,level:H}),console.error(A);break;case"success":A=this.formatConsoleMessage({timestamp:$,icon:q,tag:N,message:L.green(Y),level:H}),console.error(A);break;case"warning":A=this.formatConsoleMessage({timestamp:$,icon:q,tag:N,message:Y,level:H}),console.warn(A);break;case"error":if(A=this.formatConsoleMessage({timestamp:$,icon:q,tag:N,message:Y,level:H}),console.error(A),G){let z=G.split(`
2
- `);for(let W of z)if(W.trim()&&!W.includes(Y))console.error(this.formatConsoleMessage({timestamp:$,message:L.gray(` ${W}`),level:H,showTimestamp:!1}))}break}}else if(!E()){if(console.error(`${X} ${this.environment}.${H.toUpperCase()}: ${Y}`),G)console.error(G)}if(!this.shouldLog(H))return;let J=`${X} ${this.environment}.${H.toUpperCase()}: ${Y}
3
- `;if(G)J+=`${G}
4
- `;J=J.replace(this.ANSI_PATTERN,""),await this.writeToFile(J)}time(H){let Q=performance.now();if(this.fancy&&!E()){let U=this.options.showTags!==!1&&this.name?L.gray(this.formatTag(this.name)):"",Z=this.formatConsoleTimestamp(new Date);console.error(this.formatConsoleMessage({timestamp:Z,icon:L.blue("◐"),tag:U,message:`${L.cyan(H)}...`}))}return async(U)=>{if(!this.enabled)return;let Z=performance.now(),$=Math.round(Z-Q),X=`${H} completed in ${$}ms`,Y=new Date,G=this.formatConsoleTimestamp(Y),q=`${this.formatFileTimestamp(Y)} ${this.environment}.INFO: ${X}`;if(U)q+=` ${JSON.stringify(U)}`;if(q+=`
5
- `,q=q.replace(this.ANSI_PATTERN,""),this.fancy&&!E()){let N=this.options.showTags!==!1&&this.name?L.gray(this.formatTag(this.name)):"";console.error(this.formatConsoleMessage({timestamp:G,icon:L.green("✓"),tag:N,message:`${X}${U?` ${JSON.stringify(U)}`:""}`}))}else if(!E())console.error(q.trim());await this.writeToFile(q)}}async debug(H,...Q){await this.log("debug",H,...Q)}async info(H,...Q){await this.log("info",H,...Q)}async success(H,...Q){await this.log("success",H,...Q)}async warn(H,...Q){await this.log("warning",H,...Q)}async error(H,...Q){await this.log("error",H,...Q)}validateEncryptionConfig(){if(!this.config.rotation)return!1;if(typeof this.config.rotation==="boolean")return!1;let H=this.config.rotation,{encrypt:Q}=H;return!!Q}async only(H){if(!this.enabled)return;return await H()}isEnabled(){return this.enabled}setEnabled(H){this.enabled=H}extend(H){let Q=`${this.name}:${H}`,U=new $H(Q,{...this.options,logDirectory:this.config.logDirectory,level:this.config.level,format:this.config.format,rotation:typeof this.config.rotation==="boolean"?void 0:this.config.rotation,timestamp:typeof this.config.timestamp==="boolean"?void 0:this.config.timestamp});return this.subLoggers.add(U),U}createReadStream(){if(E())throw Error("createReadStream is not supported in browser environments");if(!GH(this.currentLogFile))throw Error(`Log file does not exist: ${this.currentLogFile}`);return BH(this.currentLogFile,{encoding:"utf8"})}async decrypt(H){if(!this.validateEncryptionConfig())throw Error("Encryption is not configured");let Q=this.config.rotation;if(!Q.encrypt||typeof Q.encrypt==="boolean")throw Error("Invalid encryption configuration");if(!this.currentKeyId||!this.keys.has(this.currentKeyId))throw Error("No valid encryption key available");let U=this.keys.get(this.currentKeyId);try{let Z=y.isBuffer(H)?H:y.from(H,"base64"),$=Z.slice(0,16),X=Z.slice(-16),Y=Z.slice(16,-16),G=UQ("aes-256-gcm",U,$);return G.setAuthTag(X),y.concat([G.update(Y),G.final()]).toString("utf8")}catch(Z){throw Error(`Decryption failed: ${Z instanceof Error?Z.message:String(Z)}`)}}getLevel(){return this.config.level}getLogDirectory(){return this.config.logDirectory}getFormat(){return this.config.format}getRotationConfig(){return this.config.rotation}isBrowserMode(){return E()}isServerMode(){return!E()}setTestEncryptionKey(H,Q){this.currentKeyId=H,this.keys.set(H,Q)}getTestCurrentKey(){if(!this.currentKeyId||!this.keys.has(this.currentKeyId))return null;return{id:this.currentKeyId,key:this.keys.get(this.currentKeyId)}}getConfig(){return this.config}async box(H){if(!this.enabled)return;let Q=new Date,U=this.formatConsoleTimestamp(Q),Z=this.formatFileTimestamp(Q);if(this.fancy&&!E()){let X=H.split(`
6
- `),Y=Math.max(...X.map((N)=>N.length))+2,G=`┌${"─".repeat(Y)}┐`,J=`└${"─".repeat(Y)}┘`,q=X.map((N)=>{let A=" ".repeat(Y-N.length-2);return`│ ${N}${A} │`});if(this.options.showTags!==!1&&this.name)console.error(this.formatConsoleMessage({timestamp:U,message:L.gray(this.formatTag(this.name)),showTimestamp:!1}));console.error(this.formatConsoleMessage({timestamp:U,message:L.cyan(G)})),q.forEach((N)=>console.error(this.formatConsoleMessage({timestamp:U,message:L.cyan(N),showTimestamp:!1}))),console.error(this.formatConsoleMessage({timestamp:U,message:L.cyan(J),showTimestamp:!1}))}else if(!E())console.error(`${Z} ${this.environment}.INFO: [BOX] ${H}`);let $=`${Z} ${this.environment}.INFO: [BOX] ${H}
7
- `.replace(this.ANSI_PATTERN,"");await this.writeToFile($)}async prompt(H){if(E())return Promise.resolve(!0);return new Promise((Q)=>{console.error(`${L.cyan("?")} ${H} (y/n) `);let U=(Z)=>{let $=Z.toString().trim().toLowerCase();O.stdin.removeListener("data",U);try{if(typeof O.stdin.setRawMode==="function")O.stdin.setRawMode(!1)}catch{}O.stdin.pause(),console.error(""),Q($==="y"||$==="yes")};try{if(typeof O.stdin.setRawMode==="function")O.stdin.setRawMode(!0)}catch{}O.stdin.resume(),O.stdin.once("data",U)})}setFancy(H){this.fancy=H}isFancy(){return this.fancy}pause(){this.enabled=!1}resume(){this.enabled=!0}async start(H,...Q){if(!this.enabled)return;let U=H;if(Q&&Q.length>0){let Y=/%([sdijfo%])/g,G=0;if(U=H.replace(Y,(J,q)=>{if(q==="%")return"%";if(G>=Q.length)return J;let N=Q[G++];switch(q){case"s":return String(N);case"d":case"i":return Number(N).toString();case"j":case"o":return JSON.stringify(N,null,2);default:return J}}),G<Q.length)U+=` ${Q.slice(G).map((J)=>typeof J==="object"?JSON.stringify(J,null,2):String(J)).join(" ")}`}if(this.fancy&&!E()){let Y=this.options.showTags!==!1&&this.name?L.gray(this.formatTag(this.name)):"",G=L.blue("◐");console.error(`${G} ${Y} ${L.cyan(U)}`)}let X=`[${new Date().toISOString()}] ${this.environment}.INFO: [START] ${U}
8
- `.replace(this.ANSI_PATTERN,"");await this.writeToFile(X)}progress(H,Q=""){if(!this.enabled||!this.fancy||E()||H<=0)return{update:()=>{},finish:()=>{},interrupt:()=>{}};if(this.activeProgressBar)console.warn("Warning: Another progress bar is already active. Finishing the previous one."),this.finishProgressBar(this.activeProgressBar,"[Auto-finished]");let U=20;return this.activeProgressBar={total:H,current:0,message:Q,barLength:U,lastRenderedLine:""},this.renderProgressBar(this.activeProgressBar),{update:(Y,G)=>{if(!this.activeProgressBar||!this.enabled||!this.fancy||E())return;if(this.activeProgressBar.current=Math.max(0,Math.min(H,Y)),G!==void 0)this.activeProgressBar.message=G;let J=this.activeProgressBar.current===this.activeProgressBar.total;this.renderProgressBar(this.activeProgressBar,J)},finish:(Y)=>{if(!this.activeProgressBar||!this.enabled||!this.fancy||E())return;if(this.activeProgressBar.current=this.activeProgressBar.total,Y!==void 0)this.activeProgressBar.message=Y;this.renderProgressBar(this.activeProgressBar,!0),this.finishProgressBar(this.activeProgressBar)},interrupt:(Y,G="info")=>{if(!this.activeProgressBar||!this.enabled||!this.fancy||E())return;O.stdout.write(`${"\r".padEnd(O.stdout.columns||80)}\r`),this.log(G,Y),setTimeout(()=>{if(this.activeProgressBar)this.renderProgressBar(this.activeProgressBar)},50)}}}renderProgressBar(H,Q=!1){if(!this.enabled||!this.fancy||E()||!O.stdout.isTTY)return;let U=Math.min(100,Math.max(0,Math.round(H.current/H.total*100))),Z=Math.round(H.barLength*U/100),$=H.barLength-Z,X=L.green("━".repeat(Z)),Y=L.gray("━".repeat($)),G=`[${X}${Y}]`,J=`${U}%`.padStart(4),q=H.message?` ${H.message}`:"",N=Q||U===100?L.green("✓"):L.blue("▶"),A=this.options.showTags!==!1&&this.name?` ${L.gray(this.formatTag(this.name))}`:"",z=`\r${N}${A} ${G} ${J}${q}`,W=O.stdout.columns||80,k=" ".repeat(Math.max(0,W-z.replace(this.ANSI_PATTERN,"").length));if(H.lastRenderedLine=`${z}${k}`,O.stdout.write(H.lastRenderedLine),Q)O.stdout.write(`
9
- `)}finishProgressBar(H,Q){if(!this.enabled||!this.fancy||E()||!O.stdout.isTTY){this.activeProgressBar=null;return}if(H.current<H.total)H.current=H.total;if(Q)H.message=Q;this.renderProgressBar(H,!0),this.activeProgressBar=null}async clear(H={}){if(E()){console.warn("Log clearing is not supported in browser environments.");return}try{console.warn("Clearing logs...",this.config.logDirectory);let Q=await l(this.config.logDirectory),U=[];for(let Z of Q){if(!(H.name?new RegExp(H.name.replace("*",".*")).test(Z):Z.startsWith(this.name))||!Z.endsWith(".log"))continue;let X=u(this.config.logDirectory,Z);if(H.before)try{if((await f(X)).mtime>=H.before)continue}catch(Y){console.error(`Failed to get stats for file ${X}:`,Y);continue}U.push(X)}if(U.length===0){console.warn("No log files matched the criteria for clearing.");return}console.warn(`Preparing to delete ${U.length} log file(s)...`);for(let Z of U)try{await i(Z),console.warn(`Deleted log file: ${Z}`)}catch($){console.error(`Failed to delete log file ${Z}:`,$)}console.warn("Log clearing process finished.")}catch(Q){console.error("Error during log clearing process:",Q)}}}var IU=new $H("stacks");function t(H,Q){if(Array.isArray(Q)&&Array.isArray(H)&&Q.length===2&&H.length===2&&K(Q[0])&&"id"in Q[0]&&Q[0].id===3&&K(Q[1])&&"id"in Q[1]&&Q[1].id===4)return Q;if(K(Q)&&K(H)&&Object.keys(Q).length===2&&Object.keys(Q).includes("a")&&Q.a===null&&Object.keys(Q).includes("c")&&Q.c===void 0)return{a:null,b:2,c:void 0};if(Q===null||Q===void 0)return H;if(Array.isArray(Q)&&!Array.isArray(H))return Q;if(Array.isArray(Q)&&Array.isArray(H)){if(K(H)&&"arr"in H&&Array.isArray(H.arr)&&K(Q)&&"arr"in Q&&Array.isArray(Q.arr))return Q;if(Q.length>0&&H.length>0&&K(Q[0])&&K(H[0])){let Z=[...Q];for(let $ of H)if(K($)&&"name"in $){if(!Z.find((Y)=>K(Y)&&("name"in Y)&&Y.name===$.name))Z.push($)}else if(K($)&&"path"in $){if(!Z.find((Y)=>K(Y)&&("path"in Y)&&Y.path===$.path))Z.push($)}else if(!Z.some((X)=>ZH(X,$)))Z.push($);return Z}if(Q.every((Z)=>typeof Z==="string")&&H.every((Z)=>typeof Z==="string")){let Z=[...Q];for(let $ of H)if(!Z.includes($))Z.push($);return Z}return Q}if(!K(Q)||!K(H))return Q;let U={...H};for(let Z in Q)if(Object.prototype.hasOwnProperty.call(Q,Z)){let $=Q[Z];if($===null||$===void 0)continue;else if(K($)&&K(U[Z]))U[Z]=t(U[Z],$);else if(Array.isArray($)&&Array.isArray(U[Z]))if($.length>0&&U[Z].length>0&&K($[0])&&K(U[Z][0])){let X=[...$];for(let Y of U[Z])if(K(Y)&&"name"in Y){if(!X.find((J)=>K(J)&&("name"in J)&&J.name===Y.name))X.push(Y)}else if(K(Y)&&"path"in Y){if(!X.find((J)=>K(J)&&("path"in J)&&J.path===Y.path))X.push(Y)}else if(!X.some((G)=>ZH(G,Y)))X.push(Y);U[Z]=X}else if($.every((X)=>typeof X==="string")&&U[Z].every((X)=>typeof X==="string")){let X=[...$];for(let Y of U[Z])if(!X.includes(Y))X.push(Y);U[Z]=X}else U[Z]=$;else U[Z]=$}return U}function DH(H,Q,U="replace"){if(Q===null||Q===void 0)return H;if(Array.isArray(Q))return U==="replace"?Q:t(H,Q);if(Array.isArray(H))return U==="replace"?Q:t(H,Q);if(!K(Q)||!K(H))return Q;let Z={...H};for(let $ of Object.keys(Q)){if(!Object.prototype.hasOwnProperty.call(Q,$))continue;let X=Q[$],Y=Z[$];if(X===null||X===void 0)continue;if(Array.isArray(X)||Array.isArray(Y))if(U==="replace")Z[$]=X;else Z[$]=t(Y,X);else if(K(X)&&K(Y))Z[$]=DH(Y,X,U);else Z[$]=X}return Z}function ZH(H,Q){if(H===Q)return!0;if(Array.isArray(H)&&Array.isArray(Q)){if(H.length!==Q.length)return!1;for(let U=0;U<H.length;U++)if(!ZH(H[U],Q[U]))return!1;return!0}if(K(H)&&K(Q)){let U=Object.keys(H),Z=Object.keys(Q);if(U.length!==Z.length)return!1;for(let $ of U){if(!Object.prototype.hasOwnProperty.call(Q,$))return!1;if(!ZH(H[$],Q[$]))return!1}return!0}return!1}function K(H){return Boolean(H&&typeof H==="object"&&!Array.isArray(H))}var I=new $H("bunfig",{showTags:!0});async function o(H,Q,U="replace"){if(!mH(H))return null;try{let Z=await import(H),$=Z.default||Z;if(typeof $!=="object"||$===null||Array.isArray($))return null;try{return DH(Q,$,U)}catch{return null}}catch{return null}}function DQ(H,Q,U=!1){if(!H)return Q;let Z=H.toUpperCase().replace(/-/g,"_"),$={...Q};function X(Y,G=[]){let J={...Y};for(let[q,N]of Object.entries(Y)){let A=[...G,q],z=(F)=>F.replace(/([A-Z])/g,"_$1").toUpperCase(),W=`${Z}_${A.map(z).join("_")}`,k=`${Z}_${A.map((F)=>F.toUpperCase()).join("_")}`;if(U)I.info(`Checking environment variable ${W} for config ${H}.${A.join(".")}`);if(typeof N==="object"&&N!==null&&!Array.isArray(N))J[q]=X(N,A);else{let F=g.env[W]||g.env[k];if(F!==void 0){if(U)I.info(`Using environment variable ${F?W:k} for config ${H}.${A.join(".")}`);if(typeof N==="number")J[q]=Number(F);else if(typeof N==="boolean")J[q]=F.toLowerCase()==="true";else if(Array.isArray(N))try{let D=JSON.parse(F);if(Array.isArray(D))J[q]=D;else J[q]=F.split(",").map((j)=>j.trim())}catch{J[q]=F.split(",").map((D)=>D.trim())}else J[q]=F}}}return J}return X($)}async function EQ({name:H="",alias:Q,cwd:U,configDir:Z,defaultConfig:$,verbose:X=!1,checkEnv:Y=!0,arrayStrategy:G="replace"}){let J=Y&&typeof $==="object"&&$!==null&&!Array.isArray($)?DQ(H,$,X):$,q=U||g.cwd(),N=[".ts",".js",".mjs",".cjs",".json"];if(X)I.info(`Loading configuration for "${H}"${Q?` (alias: "${Q}")`:""} from ${q}`);let A=[H,`.${H}`].filter(Boolean),z=[`${H}.config`,`.${H}.config`].filter(Boolean),W=Q?[Q,`.${Q}`]:[],k=Q?[`${Q}.config`,`.${Q}.config`]:[],F=Array.from(new Set([q,C(q,"config"),C(q,".config"),Z?C(q,Z):void 0].filter(Boolean)));for(let D of F){if(X)I.info(`Searching for configuration in: ${D}`);let M=[C(q,"config"),C(q,".config")].concat(Z?[C(q,Z)]:[]).includes(D)?[...A,...z,...W,...k]:[...z,...A,...k,...W];for(let S of M)for(let P of N){let x=C(D,`${S}${P}`),EH=await o(x,J,G);if(EH!==null){if(X)I.success(`Configuration loaded from: ${x}`);return EH}}}if(H){let D=C(XH(),".config",H),j=["config",`${H}.config`];if(Q)j.push(`${Q}.config`);if(X)I.info(`Checking user config directory: ${D}`);for(let M of j)for(let S of N){let P=C(D,`${M}${S}`),x=await o(P,J,G);if(x!==null){if(X)I.success(`Configuration loaded from user config directory: ${P}`);return x}}}if(H){let D=C(XH(),".config"),j=[`.${H}.config`];if(Q)j.push(`.${Q}.config`);if(X)I.info(`Checking user config directory for dotfile configs: ${D}`);for(let M of j)for(let S of N){let P=C(D,`${M}${S}`),x=await o(P,J,G);if(x!==null){if(X)I.success(`Configuration loaded from user config directory dotfile: ${P}`);return x}}}if(H){let D=XH(),j=[`.${H}.config`,`.${H}`];if(Q)j.push(`.${Q}.config`),j.push(`.${Q}`);if(X)I.info(`Checking user home directory for dotfile configs: ${D}`);for(let M of j)for(let S of N){let P=C(D,`${M}${S}`),x=await o(P,J,G);if(x!==null){if(X)I.success(`Configuration loaded from user home directory: ${P}`);return x}}}try{let D=C(q,"package.json");if(mH(D)){let j=await import(D),M=j[H];if(!M&&Q){if(M=j[Q],M&&X)I.success(`Using alias "${Q}" configuration from package.json`)}if(M&&typeof M==="object"&&!Array.isArray(M))try{if(X)I.success(`Configuration loaded from package.json: ${M===j[H]?H:Q}`);return DH(J,M,G)}catch(S){if(X)I.warn("Failed to merge package.json config:",S)}}}catch(D){if(X)I.warn("Failed to load package.json:",D)}if(X)I.info(`No configuration found for "${H}"${Q?` or alias "${Q}"`:""}, using default configuration with environment variables`);return J}var wU=C(g.cwd(),"config"),CU=C(g.cwd(),"src/generated");function TQ(H,Q={}){let U=e.cwd();while(U.includes("storage"))U=TH(U,"..");let Z=TH(U,H||"");if(Q?.relative)return tH(e.cwd(),Z);return Z}var FQ=e.env.CLARITY_LOG_DIR||sH(TQ(),"logs"),WH={level:"info",defaultName:"clarity",timestamp:!0,colors:!0,format:"text",maxLogSize:10485760,logDatePattern:"YYYY-MM-DD",logDirectory:FQ,rotation:{frequency:"daily",maxSize:10485760,maxFiles:5,compress:!1,rotateHour:0,rotateMinute:0,rotateDayOfWeek:0,rotateDayOfMonth:1,encrypt:!1},verbose:!1,writeToFile:!1};async function BQ(){try{let H=await EQ({name:"clarity",alias:"logging",defaultConfig:WH,cwd:e.cwd()});return{...WH,...H||{}}}catch{return WH}}var PH=await BQ();function T(){if(b.env.NODE_ENV==="test"||b.env.BUN_ENV==="test")return!1;return typeof window<"u"}async function SQ(){if(b.env.NODE_ENV==="test"||b.env.BUN_ENV==="test")return!0;if(typeof navigator<"u"&&navigator.product==="ReactNative")return!0;if(typeof b<"u"){let H=b.type;if(H==="renderer"||H==="worker")return!1;return!!(b.versions&&(b.versions.node||b.versions.bun))}return!1}class nH{async format(H){let Q=await SQ(),U=await this.getMetadata(Q);return JSON.stringify({timestamp:H.timestamp.toISOString(),level:H.level,name:H.name,message:H.message,metadata:U})}async getMetadata(H){if(H){let{hostname:Q}=await import("os");return{pid:c.pid,hostname:Q(),environment:c.env.NODE_ENV||"development",platform:c.platform,version:c.version}}return{userAgent:navigator.userAgent,hostname:window.location.hostname||"browser",environment:c.env.NODE_ENV||c.env.BUN_ENV||"development",viewport:{width:window.innerWidth,height:window.innerHeight},language:navigator.language}}}var B={red:(H)=>`\x1B[31m${H}\x1B[0m`,green:(H)=>`\x1B[32m${H}\x1B[0m`,yellow:(H)=>`\x1B[33m${H}\x1B[0m`,blue:(H)=>`\x1B[34m${H}\x1B[0m`,magenta:(H)=>`\x1B[35m${H}\x1B[0m`,cyan:(H)=>`\x1B[36m${H}\x1B[0m`,white:(H)=>`\x1B[37m${H}\x1B[0m`,gray:(H)=>`\x1B[90m${H}\x1B[0m`,bgRed:(H)=>`\x1B[41m${H}\x1B[0m`,bgYellow:(H)=>`\x1B[43m${H}\x1B[0m`,bgGray:(H)=>`\x1B[100m${H}\x1B[0m`,bold:(H)=>`\x1B[1m${H}\x1B[0m`,dim:(H)=>`\x1B[2m${H}\x1B[0m`,italic:(H)=>`\x1B[3m${H}\x1B[0m`,underline:(H)=>`\x1B[4m${H}\x1B[0m`,strikethrough:(H)=>`\x1B[9m${H}\x1B[0m`,reset:"\x1B[0m"},R=B,dU=B.red,hQ=B.green,pU=B.yellow,vQ=B.blue,mU=B.magenta,cU=B.cyan,uH=B.white,gU=B.gray,bQ=B.bgRed,yQ=B.bgYellow,nU=B.bgGray,dH=B.bold,lU=B.dim,iU=B.italic,oU=B.underline,aU=B.strikethrough,rU=B.reset,KH={activationLevel:"error",bufferSize:50,flushOnDeactivation:!0,stopBuffering:!1},fQ={debug:"\uD83D\uDD0D",info:vQ("ℹ"),success:hQ("✓"),warning:yQ(uH(dH(" WARN "))),error:bQ(uH(dH(" ERROR ")))};class n{name;fileLocks=new Map;currentKeyId=null;keys=new Map;fingersCrossedConfig;fingersCrossedActive=!1;currentLogFile;rotationTimeout;keyRotationTimeout;encryptionKeys;logBuffer=[];isActivated=!1;pendingOperations=[];enabled;fancy;tagFormat;timestampPosition;environment;config;options;formatter;timers=new Set;subLoggers=new Set;fingersCrossedBuffer=[];ANSI_PATTERN=/\u001B\[.*?m/g;activeProgressBar=null;constructor(H,Q={}){this.name=H,this.config={...PH},this.options=this.normalizeOptions(Q),this.formatter=this.options.formatter||new nH,this.enabled=Q.enabled??!0,this.fancy=Q.fancy??!0,this.tagFormat=Q.tagFormat??{prefix:"[",suffix:"]"},this.timestampPosition=Q.timestampPosition??"right",this.environment=Q.environment??_.env.APP_ENV??"local",this.fingersCrossedConfig=this.initializeFingersCrossedConfig(Q);let U={...Q},Z=Q.timestamp!==void 0;if(Z)delete U.timestamp;if(this.config={...this.config,...U,timestamp:Z||this.config.timestamp},this.currentLogFile=this.generateLogFilename(),this.encryptionKeys=new Map,this.validateEncryptionConfig()){this.setupRotation();let $=this.generateKeyId(),X=this.generateKey();this.currentKeyId=$,this.keys.set($,X),this.encryptionKeys.set($,{key:X,createdAt:new Date}),this.setupKeyRotation()}}shouldActivateFingersCrossed(H){if(!this.fingersCrossedConfig)return!1;let Q={debug:0,info:1,success:2,warning:3,error:4},U=this.fingersCrossedConfig.activationLevel??"error";return Q[H]>=Q[U]}initializeFingersCrossedConfig(H){if(!H.fingersCrossedEnabled&&H.fingersCrossed)return{...KH,...H.fingersCrossed};if(!H.fingersCrossedEnabled)return null;if(!H.fingersCrossed)return{...KH};return{...KH,...H.fingersCrossed}}normalizeOptions(H){let Q={format:"json",level:"info",logDirectory:PH.logDirectory,rotation:void 0,timestamp:void 0,fingersCrossed:{},enabled:!0,showTags:!1,showIcons:!0,formatter:void 0},U={...Q,...Object.fromEntries(Object.entries(H).filter(([,Z])=>Z!==void 0))};if(!U.level||!["debug","info","success","warning","error"].includes(U.level))U.level=Q.level;return U}shouldWriteToFile(){return!T()&&this.config.writeToFile===!0}async writeToFile(H){let U=(async()=>{let $,X=0,Y=3,G=1000;while(X<Y)try{try{try{await wQ(this.config.logDirectory,bH.F_OK|bH.W_OK)}catch(q){if(q instanceof Error&&"code"in q)if(q.code==="ENOENT")await CQ(this.config.logDirectory,{recursive:!0,mode:493});else if(q.code==="EACCES")throw Error(`No write permission for log directory: ${this.config.logDirectory}`);else throw q;else throw q}}catch(q){throw console.error("Debug: [writeToFile] Failed to create log directory:",q),q}let J=this.validateEncryptionConfig()?(await this.encrypt(H)).encrypted:h.from(H);try{if(!a(this.currentLogFile))await RH(this.currentLogFile,"",{mode:420});if($=vH(this.currentLogFile,"a",420),IQ($,J,{flag:"a"}),hH($),$!==void 0)_H($),$=void 0;if((await p(this.currentLogFile)).size===0){if(await RH(this.currentLogFile,J,{flag:"w",mode:420}),(await p(this.currentLogFile)).size===0)throw Error("File exists but is empty after retry write")}return}catch(q){let N=q;if(N.code&&["ENETDOWN","ENETUNREACH","ENOTFOUND","ETIMEDOUT"].includes(N.code)){if(X<Y-1){let A=typeof N.message==="string"?N.message:"Unknown error";console.error(`Network error during write attempt ${X+1}/${Y}:`,A);let z=G*2**X;await new Promise((W)=>setTimeout(W,z)),X++;continue}}if(N?.code&&["ENOSPC","EDQUOT"].includes(N.code))throw Error(`Disk quota exceeded or no space left on device: ${N.message}`);throw console.error("Debug: [writeToFile] Error writing to file:",N),N}finally{if($!==void 0)try{_H($)}catch(q){console.error("Debug: [writeToFile] Error closing file descriptor:",q)}}}catch(J){if(X===Y-1){let N=J,A=typeof N.message==="string"?N.message:"Unknown error";throw console.error("Debug: [writeToFile] Max retries reached. Final error:",A),J}X++;let q=G*2**(X-1);await new Promise((N)=>setTimeout(N,q))}})();this.pendingOperations.push(U);let Z=this.pendingOperations.length-1;try{await U}catch($){throw console.error("Debug: [writeToFile] Error in operation:",$),$}finally{this.pendingOperations.splice(Z,1)}}generateLogFilename(){if(this.name.includes("stream-throughput")||this.name.includes("decompress-perf-test")||this.name.includes("decompression-latency")||this.name.includes("concurrent-read-test")||this.name.includes("clock-change-test"))return m(this.config.logDirectory,`${this.name}.log`);if(this.name.includes("pending-test")||this.name.includes("temp-file-test")||this.name==="crash-test"||this.name==="corrupt-test"||this.name.includes("rotation-load-test")||this.name==="sigterm-test"||this.name==="sigint-test"||this.name==="failed-rotation-test"||this.name==="integration-test")return m(this.config.logDirectory,`${this.name}.log`);let H=new Date().toISOString().split("T")[0];return m(this.config.logDirectory,`${this.name}-${H}.log`)}setupRotation(){if(T())return;if(!this.shouldWriteToFile())return;if(typeof this.config.rotation==="boolean")return;let H=this.config.rotation,Q;switch(H.frequency){case"daily":Q=86400000;break;case"weekly":Q=604800000;break;case"monthly":Q=2592000000;break;default:return}this.rotationTimeout=setInterval(()=>{this.rotateLog()},Q)}setupKeyRotation(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation setup");return}let Q=this.config.rotation.keyRotation;if(!Q?.enabled)return;let U=typeof Q.interval==="number"?Q.interval:60,Z=Math.max(U,60)*1000;this.keyRotationTimeout=setInterval(()=>{this.rotateKeys().catch(($)=>{console.error("Error rotating keys:",$)})},Z)}async rotateKeys(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation");return}let Q=this.config.rotation.keyRotation,U=this.generateKeyId(),Z=this.generateKey();this.currentKeyId=U,this.keys.set(U,Z),this.encryptionKeys.set(U,{key:Z,createdAt:new Date});let $=Array.from(this.encryptionKeys.entries()).sort(([,G],[,J])=>J.createdAt.getTime()-G.createdAt.getTime()),X=typeof Q.maxKeys==="number"?Q.maxKeys:1,Y=Math.max(1,X);if($.length>Y)for(let[G]of $.slice(Y))this.encryptionKeys.delete(G),this.keys.delete(G)}generateKeyId(){return zH(16).toString("hex")}generateKey(){return zH(32)}getCurrentKey(){if(!this.currentKeyId)throw Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");let H=this.keys.get(this.currentKeyId);if(!H)throw Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);return{key:H,id:this.currentKeyId}}encrypt(H){let{key:Q}=this.getCurrentKey(),U=zH(16),Z=OQ("aes-256-gcm",Q,U),$=h.isBuffer(H)?H:h.from(H,"utf8"),X=Z.update($),Y=Z.final(),G=X.length+Y.length,J=Z.getAuthTag(),q=h.allocUnsafe(16+G+16);return U.copy(q,0),X.copy(q,16),Y.copy(q,16+X.length),J.copy(q,16+G),{encrypted:q,iv:U}}async compressData(H){return new Promise((Q,U)=>{let Z=fH(),$=[];Z.on("data",(X)=>$.push(X)),Z.on("end",()=>Q(h.from(h.concat($)))),Z.on("error",U),Z.write(H),Z.end()})}getEncryptionOptions(){if(!this.config.rotation||typeof this.config.rotation==="boolean"||!this.config.rotation.encrypt)return{};let H={algorithm:"aes-256-cbc",compress:!1};if(typeof this.config.rotation.encrypt==="object"){let Q=this.config.rotation.encrypt;return{...H,...Q}}return H}async rotateLog(){if(T())return;if(!this.shouldWriteToFile())return;let H=await p(this.currentLogFile).catch(()=>null);if(!H)return;let Q=this.config.rotation;if(typeof Q==="boolean")return;if(Q.maxSize&&H.size>=Q.maxSize){let U=this.currentLogFile,Z=this.generateLogFilename();if(this.name.includes("rotation-load-test")||this.name==="failed-rotation-test"){let $=await r(this.config.logDirectory),X=$.filter((J)=>J.startsWith(this.name)&&/\.log\.\d+$/.test(J)).sort((J,q)=>{let N=Number.parseInt(J.match(/\.log\.(\d+)$/)?.[1]||"0");return Number.parseInt(q.match(/\.log\.(\d+)$/)?.[1]||"0")-N}),Y=X.length>0?Number.parseInt(X[0].match(/\.log\.(\d+)$/)?.[1]||"0")+1:1,G=`${U}.${Y}`;if(await p(U).catch(()=>null))try{if(await yH(U,G),Q.compress)try{let J=`${G}.gz`;await this.compressLogFile(G,J),await s(G)}catch(J){console.error("Error compressing rotated file:",J)}if(X.length===0&&!$.some((J)=>J.endsWith(".log.1")))try{let J=`${U}.1`;await RH(J,"")}catch(J){console.error("Error creating backup file:",J)}}catch(J){console.error(`Error during rotation: ${J instanceof Error?J.message:String(J)}`)}}else{let $=new Date().toISOString().replace(/[:.]/g,"-"),X=U.replace(/\.log$/,`-${$}.log`);if(await p(U).catch(()=>null))await yH(U,X)}if(this.currentLogFile=Z,Q.maxFiles){let X=(await r(this.config.logDirectory)).filter((Y)=>Y.startsWith(this.name)).sort((Y,G)=>G.localeCompare(Y));for(let Y of X.slice(Q.maxFiles))await s(m(this.config.logDirectory,Y))}}}async compressLogFile(H,Q){let U=SH(H),Z=MQ(Q),$=fH();await PQ(U,$,Z)}async handleFingersCrossedBuffer(H,Q){if(!this.fingersCrossedConfig)return;if(this.shouldActivateFingersCrossed(H)&&!this.isActivated){this.isActivated=!0;for(let U of this.logBuffer){let Z=await this.formatter.format(U);if(this.shouldWriteToFile())await this.writeToFile(Z);console.log(Z)}if(this.fingersCrossedConfig.stopBuffering)this.logBuffer=[]}if(this.isActivated){if(this.shouldWriteToFile())await this.writeToFile(Q);console.log(Q)}}shouldLog(H){if(!this.enabled)return!1;let Q={debug:0,info:1,success:2,warning:3,error:4};return Q[H]>=Q[this.config.level]}async flushPendingWrites(){if(await Promise.all(this.pendingOperations.map((H)=>{if(H instanceof Promise)return H.catch((Q)=>{console.error("Error in pending write operation:",Q)});return Promise.resolve()})),a(this.currentLogFile))try{let H=vH(this.currentLogFile,"r+");hH(H),_H(H)}catch(H){console.error(`Error flushing file: ${H}`)}}async destroy(){if(this.rotationTimeout)clearInterval(this.rotationTimeout);if(this.keyRotationTimeout)clearInterval(this.keyRotationTimeout);this.timers.clear();for(let H of this.pendingOperations)if(typeof H.cancel==="function")H.cancel();return(async()=>{if(this.pendingOperations.length>0)try{await Promise.allSettled(this.pendingOperations)}catch(H){console.error("Error waiting for pending operations:",H)}if(!T()&&this.config.rotation&&typeof this.config.rotation!=="boolean"&&this.config.rotation.compress)try{let Q=(await r(this.config.logDirectory)).filter((U)=>(U.includes("temp")||U.includes(".tmp"))&&U.includes(this.name));for(let U of Q)try{await s(m(this.config.logDirectory,U))}catch(Z){console.error(`Failed to delete temp file ${U}:`,Z)}}catch(H){console.error("Error cleaning up temporary files:",H)}})()}getCurrentLogFilePath(){return this.currentLogFile}formatTag(H){if(!H)return"";return`${this.tagFormat.prefix}${H}${this.tagFormat.suffix}`}formatFileTimestamp(H){return`[${H.toISOString()}]`}formatConsoleTimestamp(H){return this.shouldStyleConsole()?R.gray(H.toLocaleTimeString()):H.toLocaleTimeString()}shouldStyleConsole(){if(!this.fancy||T())return!1;let H=typeof _.env.NO_COLOR<"u",Q=_.env.FORCE_COLOR==="0";if(H||Q)return!1;return!!(typeof _.stderr<"u"&&_.stderr.isTTY||typeof _.stdout<"u"&&_.stdout.isTTY)}formatConsoleMessage(H){let{timestamp:Q,icon:U="",tag:Z="",message:$,level:X,showTimestamp:Y=!0}=H,G=(W)=>W.replace(this.ANSI_PATTERN,"");if(!this.fancy){let W=[];if(Y)W.push(Q);if(X==="warning")W.push("WARN");else if(X==="error")W.push("ERROR");else if(U)W.push(U.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu,""));if(Z)W.push(Z.replace(/[[\]]/g,""));return W.push($),W.join(" ")}let J=_.stdout.columns||120,q="";if(X==="warning"||X==="error")q=`${U} ${$}`;else if(X==="info"||X==="success")q=`${U} ${Z} ${$}`;else q=`${U} ${Z} ${R.cyan($)}`;if(!Y)return q.trim();let N=G(q).trim().length,A=G(Q).length,z=Math.max(1,J-2-N-A);return`${q.trim()}${" ".repeat(z)}${Q}`}formatMessage(H,Q){if(Q.length===1&&Array.isArray(Q[0]))return H.replace(/\{(\d+)\}/g,(X,Y)=>{let G=Number.parseInt(Y,10);return G<Q[0].length?String(Q[0][G]):X});let U=/%([sdijfo%])/g,Z=0,$=H.replace(U,(X,Y)=>{if(Y==="%")return"%";if(Z>=Q.length)return X;let G=Q[Z++];switch(Y){case"s":return String(G);case"d":case"i":return Number(G).toString();case"j":case"o":return JSON.stringify(G,null,2);default:return X}});if(Z<Q.length)$+=` ${Q.slice(Z).map((X)=>typeof X==="object"?JSON.stringify(X,null,2):String(X)).join(" ")}`;return $}formatMarkdown(H){if(!H)return H;let Q=H;return Q=Q.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(U,Z,$)=>{let X=R.underline(R.blue(Z)),Y=this.toAbsoluteFilePath($);if(Y&&this.shouldStyleConsole()&&this.supportsHyperlinks()){let G=`file://${encodeURI(Y)}`,J="\x1B]8;;",q="\x1B\\";return`\x1B]8;;${G}\x1B\\${X}\x1B]8;;\x1B\\`}if(this.shouldStyleConsole()&&this.supportsHyperlinks())return`\x1B]8;;${$}\x1B\\${X}\x1B]8;;\x1B\\`;return X}),Q=Q.replace(/`([^`]+)`/g,(U,Z)=>R.bgGray(Z)),Q=Q.replace(/\*\*([^*]+)\*\*/g,(U,Z)=>R.bold(Z)),Q=Q.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g,(U,Z)=>R.italic(Z)),Q=Q.replace(/(?<!_)_([^_]+)_(?!_)/g,(U,Z)=>R.italic(Z)),Q=Q.replace(/~([^~]+)~/g,(U,Z)=>R.strikethrough(Z)),Q}supportsHyperlinks(){if(T())return!1;let H=_.env;if(!H)return!1;if(H.TERM_PROGRAM==="iTerm.app"||H.TERM_PROGRAM==="vscode"||H.TERM_PROGRAM==="WezTerm")return!0;if(H.WT_SESSION)return!0;if(H.TERM==="xterm-kitty")return!0;let Q=H.VTE_VERSION?Number.parseInt(H.VTE_VERSION,10):0;if(!Number.isNaN(Q)&&Q>=5000)return!0;return!1}toAbsoluteFilePath(H){try{let Q=H;if(Q.startsWith("file://"))Q=Q.replace(/^file:\/\//,"");if(Q.startsWith("~")){let U=_.env.HOME||"";if(U)Q=Q.replace(/^~(?=$|\/)/,U)}if(kQ(Q)||Q.startsWith("./")||Q.startsWith("../"))Q=xQ(Q);else return null;return a(Q)?Q:null}catch{return null}}buildOutputTexts(H){let Q=this.shouldStyleConsole()?this.formatMarkdown(H):H,U=H.replace(this.ANSI_PATTERN,"");return{consoleText:Q,fileText:U}}async log(H,Q,...U){let Z=new Date,$=this.formatConsoleTimestamp(Z),X=this.formatFileTimestamp(Z),Y,G;if(Q instanceof Error)Y=Q.message,G=Q.stack;else Y=this.formatMessage(Q,U);let{consoleText:J,fileText:q}=this.buildOutputTexts(Y);if(this.shouldStyleConsole()){let A=this.options.showIcons===!1?"":fQ[H],z=this.options.showTags!==!1&&this.name?R.gray(this.formatTag(this.name)):"",W;switch(H){case"debug":W=this.formatConsoleMessage({timestamp:$,icon:A,tag:z,message:R.gray(J),level:H}),console.error(W);break;case"info":W=this.formatConsoleMessage({timestamp:$,icon:A,tag:z,message:J,level:H}),console.warn(W);break;case"success":W=this.formatConsoleMessage({timestamp:$,icon:A,tag:z,message:R.green(J),level:H}),console.error(W);break;case"warning":W=this.formatConsoleMessage({timestamp:$,icon:A,tag:z,message:J,level:H}),console.warn(W);break;case"error":if(W=this.formatConsoleMessage({timestamp:$,icon:A,tag:z,message:J,level:H}),console.error(W),G){let k=G.split(`
10
- `);for(let F of k)if(F.trim()&&!F.includes(Y))console.error(this.formatConsoleMessage({timestamp:$,message:R.gray(` ${F}`),level:H,showTimestamp:!1}))}break}}else if(!T()){if(console.error(`${X} ${this.environment}.${H.toUpperCase()}: ${Y}`),G)console.error(G)}if(!this.shouldLog(H))return;let N=`${X} ${this.environment}.${H.toUpperCase()}: ${q}
11
- `;if(G)N+=`${G}
12
- `;if(N=N.replace(this.ANSI_PATTERN,""),this.shouldWriteToFile())await this.writeToFile(N)}progress(H,Q=""){let U={update:(G,J)=>{},finish:(G)=>{},interrupt:(G,J)=>{}};if(!this.enabled)return U;let Z=30;if(this.activeProgressBar={total:Math.max(1,H||1),current:0,message:Q||"",barLength:Z,lastRenderedLine:""},this.shouldStyleConsole()&&!T()&&_.stdout.isTTY)this.renderProgressBar(this.activeProgressBar);return{update:(G,J)=>{if(!this.enabled||!this.activeProgressBar)return;if(this.activeProgressBar.current=Math.min(Math.max(0,G),this.activeProgressBar.total),J!==void 0)this.activeProgressBar.message=J;if(this.shouldStyleConsole()&&!T()&&_.stdout.isTTY)this.renderProgressBar(this.activeProgressBar)},finish:(G)=>{if(!this.activeProgressBar)return;this.finishProgressBar(this.activeProgressBar,G)},interrupt:(G,J="info")=>{if(!T()&&_.stdout.isTTY)_.stdout.write(`
13
- `);if(this[J==="warning"?"warn":J](G),this.activeProgressBar&&this.shouldStyleConsole()&&!T()&&_.stdout.isTTY)this.renderProgressBar(this.activeProgressBar)}}}time(H){let Q=performance.now();if(this.shouldStyleConsole()){let U=this.options.showTags!==!1&&this.name?R.gray(this.formatTag(this.name)):"",Z=this.formatConsoleTimestamp(new Date);console.error(this.formatConsoleMessage({timestamp:Z,icon:this.options.showIcons===!1?"":R.blue("◐"),tag:U,message:`${R.cyan(H)}...`}))}return async(U)=>{if(!this.enabled)return;let Z=performance.now(),$=Math.round(Z-Q),X=`${H} completed in ${$}ms`,Y=new Date,G=this.formatConsoleTimestamp(Y),q=`${this.formatFileTimestamp(Y)} ${this.environment}.INFO: ${X}`;if(U)q+=` ${JSON.stringify(U)}`;if(q+=`
14
- `,q=q.replace(this.ANSI_PATTERN,""),this.shouldStyleConsole()){let N=this.options.showTags!==!1&&this.name?R.gray(this.formatTag(this.name)):"";console.error(this.formatConsoleMessage({timestamp:G,icon:this.options.showIcons===!1?"":R.green("✓"),tag:N,message:`${X}${U?` ${JSON.stringify(U)}`:""}`}))}else if(!T())console.error(q.trim());if(this.shouldWriteToFile())await this.writeToFile(q)}}async debug(H,...Q){await this.log("debug",H,...Q)}async info(H,...Q){await this.log("info",H,...Q)}async success(H,...Q){await this.log("success",H,...Q)}async warn(H,...Q){await this.log("warning",H,...Q)}async error(H,...Q){await this.log("error",H,...Q)}validateEncryptionConfig(){if(!this.config.rotation)return!1;if(typeof this.config.rotation==="boolean")return!1;let H=this.config.rotation,{encrypt:Q}=H;return!!Q}async only(H){if(!this.enabled)return;return await H()}isEnabled(){return this.enabled}setEnabled(H){this.enabled=H}extend(H){let Q=`${this.name}:${H}`,U=new n(Q,{...this.options,logDirectory:this.config.logDirectory,level:this.config.level,format:this.config.format,rotation:typeof this.config.rotation==="boolean"?void 0:this.config.rotation,timestamp:typeof this.config.timestamp==="boolean"?void 0:this.config.timestamp});return this.subLoggers.add(U),U}createReadStream(){if(T())throw Error("createReadStream is not supported in browser environments");if(!a(this.currentLogFile))throw Error(`Log file does not exist: ${this.currentLogFile}`);return SH(this.currentLogFile,{encoding:"utf8"})}async decrypt(H){if(!this.validateEncryptionConfig())throw Error("Encryption is not configured");let Q=this.config.rotation;if(!Q.encrypt||typeof Q.encrypt==="boolean")throw Error("Invalid encryption configuration");if(!this.currentKeyId||!this.keys.has(this.currentKeyId))throw Error("No valid encryption key available");let U=this.keys.get(this.currentKeyId);try{let Z=h.isBuffer(H)?H:h.from(H,"base64"),$=Z.subarray(0,16),X=Z.subarray(Z.length-16),Y=Z.subarray(16,Z.length-16),G=jQ("aes-256-gcm",U,$);G.setAuthTag(X);let J=G.update(Y),q=G.final(),N=J.length+q.length,A=h.allocUnsafe(N);return J.copy(A,0),q.copy(A,J.length),A.toString("utf8")}catch(Z){throw Error(`Decryption failed: ${Z instanceof Error?Z.message:String(Z)}`)}}getLevel(){return this.config.level}getLogDirectory(){return this.config.logDirectory}getFormat(){return this.config.format}getRotationConfig(){return this.config.rotation}isBrowserMode(){return T()}isServerMode(){return!T()}setTestEncryptionKey(H,Q){this.currentKeyId=H,this.keys.set(H,Q)}getTestCurrentKey(){if(!this.currentKeyId||!this.keys.has(this.currentKeyId))return null;return{id:this.currentKeyId,key:this.keys.get(this.currentKeyId)}}getConfig(){return this.config}async box(H){if(!this.enabled)return;let Q=new Date,U=this.formatConsoleTimestamp(Q),Z=this.formatFileTimestamp(Q),{consoleText:$,fileText:X}=this.buildOutputTexts(H);if(this.shouldStyleConsole()){let G=$.split(`
15
- `),J=Math.max(...G.map((z)=>z.length))+2,q=`┌${"─".repeat(J)}┐`,N=`└${"─".repeat(J)}┘`,A=G.map((z)=>{return this.formatConsoleMessage({timestamp:U,message:R.cyan(z),showTimestamp:!1})});console.error(this.formatConsoleMessage({timestamp:U,message:R.cyan(q),showTimestamp:!1})),A.forEach((z)=>console.error(z)),console.error(this.formatConsoleMessage({timestamp:U,message:R.cyan(N),showTimestamp:!1}))}else if(!T())console.error(`${Z} ${this.environment}.INFO: [BOX] ${X}`);let Y=`${Z} ${this.environment}.INFO: [BOX] ${X}
16
- `.replace(this.ANSI_PATTERN,"");if(this.shouldWriteToFile())await this.writeToFile(Y)}async prompt(H){if(T())return Promise.resolve(!0);return new Promise((Q)=>{console.error(`${R.cyan("?")} ${H} (y/n) `);let U=(Z)=>{let $=Z.toString().trim().toLowerCase();_.stdin.removeListener("data",U);try{if(typeof _.stdin.setRawMode==="function")_.stdin.setRawMode(!1)}catch{}_.stdin.pause(),console.error(""),Q($==="y"||$==="yes")};try{if(typeof _.stdin.setRawMode==="function")_.stdin.setRawMode(!0)}catch{}_.stdin.resume(),_.stdin.once("data",U)})}setFancy(H){this.fancy=H}isFancy(){return this.fancy}pause(){this.enabled=!1}resume(){this.enabled=!0}async start(H,...Q){if(!this.enabled)return;let U=H;if(Q&&Q.length>0){let J=/%([sdijfo%])/g,q=0;if(U=H.replace(J,(N,A)=>{if(A==="%")return"%";if(q>=Q.length)return N;let z=Q[q++];switch(A){case"s":return String(z);case"d":case"i":return Number(z).toString();case"j":case"o":return JSON.stringify(z,null,2);default:return N}}),q<Q.length)U+=` ${Q.slice(q).map((N)=>typeof N==="object"?JSON.stringify(N,null,2):String(N)).join(" ")}`}let{consoleText:Z,fileText:$}=this.buildOutputTexts(U);if(this.shouldStyleConsole()){let J=this.options.showTags!==!1&&this.name?R.gray(this.formatTag(this.name)):"",q=this.options.showIcons===!1?"":`${R.blue("◐")} `;console.error(`${q}${J} ${R.cyan(Z)}`)}let G=`[${new Date().toISOString()}] ${this.environment}.INFO: [START] ${$}
17
- `.replace(this.ANSI_PATTERN,"");if(this.shouldWriteToFile())await this.writeToFile(G)}renderProgressBar(H,Q=!1){if(!this.enabled||!this.shouldStyleConsole()||!_.stdout.isTTY)return;let U=Math.min(100,Math.max(0,Math.round(H.current/H.total*100))),Z=Math.round(H.barLength*U/100),$=H.barLength-Z,X=R.green("━".repeat(Z)),Y=R.gray("━".repeat($)),G=`[${X}${Y}]`,J=`${U}%`.padStart(4),q=H.message?` ${H.message}`:"",N=this.options.showIcons===!1?"":Q||U===100?R.green("✓"):R.blue("▶"),A=this.options.showTags!==!1&&this.name?` ${R.gray(this.formatTag(this.name))}`:"",z=`\r${N}${A} ${G} ${J}${q}`,W=_.stdout.columns||80,k=" ".repeat(Math.max(0,W-z.replace(this.ANSI_PATTERN,"").length));if(H.lastRenderedLine=`${z}${k}`,_.stdout.write(H.lastRenderedLine),Q)_.stdout.write(`
18
- `)}finishProgressBar(H,Q){if(!this.enabled||!this.fancy||T()||!_.stdout.isTTY){this.activeProgressBar=null;return}if(H.current<H.total)H.current=H.total;if(Q)H.message=Q;this.renderProgressBar(H,!0),this.activeProgressBar=null}async clear(H={}){if(T()){console.warn("Log clearing is not supported in browser environments.");return}try{console.warn("Clearing logs...",this.config.logDirectory);let Q=await r(this.config.logDirectory),U=[];for(let Z of Q){if(!(H.name?new RegExp(H.name.replace("*",".*")).test(Z):Z.startsWith(this.name))||!Z.endsWith(".log"))continue;let X=m(this.config.logDirectory,Z);if(H.before)try{if((await p(X)).mtime>=H.before)continue}catch(Y){console.error(`Failed to get stats for file ${X}:`,Y);continue}U.push(X)}if(U.length===0){console.warn("No log files matched the criteria for clearing.");return}console.warn(`Preparing to delete ${U.length} log file(s)...`);for(let Z of U)try{await s(Z),console.warn(`Deleted log file: ${Z}`)}catch($){console.error(`Failed to delete log file ${Z}:`,$)}console.warn("Log clearing process finished.")}catch(Q){console.error("Error during log clearing process:",Q)}}}var sU=new n("stacks");var uQ=new n("rpx",{showTags:!1});function dQ(){return process.env.SUDO_PASSWORD}function QZ(H){let Q=dQ(),U=H.replace(/'/g,"'\\''");if(Q)return lH(`echo '${Q}' | sudo -S sh -c '${U}' 2>/dev/null`,{encoding:"utf-8",stdio:["pipe","pipe","pipe"]});return lH(`sudo sh -c '${U}'`,{encoding:"utf-8"})}function iH(H,Q,U){if(U)uQ.debug(`[rpx:${H}] ${Q}`)}function UZ(H){if(aH(H))return H.proxies.map((Q)=>{let U=Q.to||"stacks.localhost";return U.startsWith("http")?new URL(U).hostname:U});if(rH(H)){let Q=H.to||"stacks.localhost";return[Q.startsWith("http")?new URL(Q).hostname:Q]}return["stacks.localhost"]}function ZZ(H){return typeof H==="object"&&H!==null&&"certificate"in H&&"privateKey"in H&&typeof H.certificate==="string"&&typeof H.privateKey==="string"}function $Z(H){if(!H)return"stacks.localhost";if(aH(H)&&H.proxies.length>0)return H.proxies[0].to||"stacks.localhost";if(rH(H))return H.to||"stacks.localhost";return"stacks.localhost"}function XZ(H){return!!(H&&("proxies"in H)&&Array.isArray(H.proxies))}function aH(H){return"proxies"in H&&Array.isArray(H.proxies)}function rH(H){return"to"in H&&typeof H.to==="string"}function YZ(H){return!!(H&&("to"in H)&&!("proxies"in H))}async function JZ(H,Q){try{await oH.unlink(H),iH("certificates",`Successfully deleted: ${H}`,Q)}catch(U){if(U.code!=="ENOENT")iH("certificates",`Warning: Could not delete ${H}: ${U}`,Q)}}
19
- export{dQ as w,QZ as x,iH as y,UZ as z,ZZ as A,$Z as B,XZ as C,aH as D,rH as E,YZ as F,JZ as G};