@stacksjs/rpx 0.11.10 → 0.11.12

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 +1 @@
1
- import{$ as j,S as a,T as b,U as c,V as d,W as e,X as f,Y as g,Z as h,_ as i,aa as k,ba as l,ca as m,da as n}from"./chunk-ppbddztz.js";import"./chunk-97manwts.js";export{l as tearDownDevelopmentDns,k as syncDevelopmentDnsFromRegistry,d as stopDnsServer,c as startDnsServer,h as setupResolver,j as setupDevelopmentDns,f as resolverFilePath,m as removeResolver,i as removeLegacyTldResolvers,n as reconcileStaleDevelopmentDns,e as isDnsServerRunning,g as contentLooksLikeRpxResolver,b as RPX_RESOLVER_MARKER,a as DNS_PORT};
1
+ import{$ as j,S as a,T as b,U as c,V as d,W as e,X as f,Y as g,Z as h,_ as i,aa as k,ba as l,ca as m,da as n}from"./chunk-9dndasyk.js";import"./chunk-zs1tyy8z.js";export{l as tearDownDevelopmentDns,k as syncDevelopmentDnsFromRegistry,d as stopDnsServer,c as startDnsServer,h as setupResolver,j as setupDevelopmentDns,f as resolverFilePath,m as removeResolver,i as removeLegacyTldResolvers,n as reconcileStaleDevelopmentDns,e as isDnsServerRunning,g as contentLooksLikeRpxResolver,b as RPX_RESOLVER_MARKER,a as DNS_PORT};
@@ -1 +1 @@
1
- import{Aa as k,Ba as l,Ca as m,Da as n,qa as a,ra as b,sa as c,ta as d,ua as e,va as f,wa as g,xa as h,ya as i,za as j}from"./chunk-97manwts.js";export{e as safeStringify,n as safeDeleteFile,m as resolvePathRewrite,d as redactSensitive,g as isValidRootCA,k as isSingleProxyOptions,l as isSingleProxyConfig,j as isMultiProxyOptions,i as isMultiProxyConfig,a as getSudoPassword,h as getPrimaryDomain,f as extractHostname,b as execSudoSync,c as debugLog};
1
+ import{Aa as k,Ba as l,Ca as m,Da as n,qa as a,ra as b,sa as c,ta as d,ua as e,va as f,wa as g,xa as h,ya as i,za as j}from"./chunk-zs1tyy8z.js";export{e as safeStringify,n as safeDeleteFile,m as resolvePathRewrite,d as redactSensitive,g as isValidRootCA,k as isSingleProxyOptions,l as isSingleProxyConfig,j as isMultiProxyOptions,i as isMultiProxyConfig,a as getSudoPassword,h as getPrimaryDomain,f as extractHostname,b as execSudoSync,c as debugLog};
@@ -1,4 +1,4 @@
1
- import{Aa as Eh,Ca as Rh,Da as Th,pa as W,ra as rr,sa as w,wa as Ah,xa as zf,za as zn}from"./chunk-97manwts.js";import cw from"node:dgram";import*as Yh from"node:fs/promises";import*as Ih from"node:path";import*as Qt from"node:process";import{spawn as vy}from"node:child_process";import*as Lt from"node:fs/promises";import{homedir as Jh}from"node:os";import*as It from"node:path";import*as D from"node:process";var M={info:(...t)=>console.log("[info]",...t),success:(...t)=>console.log("[success]",...t),warn:(...t)=>console.warn("[warn]",...t),error:(...t)=>console.error("[error]",...t),debug:(...t)=>console.debug("[debug]",...t),log:(...t)=>console.log(...t),start:(...t)=>console.log("[start]",...t),box:(...t)=>console.log("[box]",...t)};import{execSync as Mi}from"node:child_process";import k from"node:fs/promises";import*as Mf from"node:os";import{homedir as Gn}from"node:os";import{join as Q}from"node:path";import*as Yt from"node:process";import{createRequire as zh}from"node:module";import Vn from"node:os";import pn from"node:path";import{existsSync as es,statSync as fs}from"fs";import{existsSync as Gh,mkdirSync as Jw,readdirSync as Nw,readFileSync as qh,writeFileSync as jw}from"fs";import{homedir as ui}from"os";import{dirname as Yw,resolve as Tt}from"path";import Vr from"process";import{existsSync as ss,statSync as ls}from"fs";import{existsSync as we,mkdirSync as Kh,readdirSync as xh,writeFileSync as kh}from"fs";import{homedir as ai}from"os";import{dirname as cs,resolve as ht}from"path";import ci from"process";import{join as Dh,relative as bh,resolve as hs}from"path";import Wr from"process";import{existsSync as Ps,mkdirSync as Kw,readdirSync as xw,writeFileSync as kw}from"fs";import{homedir as Pn}from"os";import{dirname as Vw,resolve as ct}from"path";import Di from"process";import{join as Vh,relative as ph,resolve as os}from"path";import Yr from"process";import{existsSync as vs,mkdirSync as Qw,readdirSync as t0,writeFileSync as i0}from"fs";import{dirname as n0,resolve as Ir}from"path";import me from"process";import{Buffer as ti}from"buffer";import{createCipheriv as Ph,createDecipheriv as vh,randomBytes as vn}from"crypto";import{closeSync as Xn,createReadStream as us,createWriteStream as Xh,existsSync as Qn,fsyncSync as as,openSync as $s,writeFileSync as Qh}from"fs";import{access as to,constants as ys,mkdir as io,readdir as $r,rename as ws,stat as $i,unlink as yr,writeFile as te}from"fs/promises";import{join as yi}from"path";import rt from"process";import{pipeline as ro}from"stream/promises";import{createGzip as ms}from"zlib";import wi from"process";import Gt from"process";import{Buffer as Zt}from"buffer";import{createCipheriv as no,createDecipheriv as eo,randomBytes as ie}from"crypto";import{closeSync as re,createReadStream as ds,createWriteStream as fo,existsSync as wr,fsyncSync as As,openSync as Es,writeFileSync as so}from"fs";import{access as lo,constants as Ts,mkdir as co,readdir as mr,rename as gs,stat as mi,unlink as dr,writeFile as ne}from"fs/promises";import{isAbsolute as ho,join as di,resolve as oo}from"path";import N from"process";import{pipeline as uo}from"stream/promises";import{createGzip as Ss}from"zlib";import Ai from"process";import qt from"process";import Ar from"process";import{existsSync as Er}from"fs";import{resolve as ee}from"path";import{existsSync as ao}from"fs";import{existsSync as $o,readdirSync as yo}from"fs";import{extname as fe,resolve as Cs}from"path";import wo from"process";import{join as mo,relative as Ao,resolve as Rs}from"path";import Or from"process";import{Buffer as Mt}from"buffer";import{createCipheriv as Eo,createDecipheriv as To,randomBytes as se}from"crypto";import{closeSync as le,createReadStream as Bs,createWriteStream as go,existsSync as Tr,fsyncSync as Us,openSync as Fs,writeFileSync as So}from"fs";import{access as Co,constants as Js,mkdir as Ro,readdir as gr,rename as Ns,stat as Ei,unlink as Sr,writeFile as ce}from"fs/promises";import{isAbsolute as Bo,join as Ti,resolve as Uo}from"path";import j from"process";import{pipeline as Fo}from"stream/promises";import{createGzip as js}from"zlib";import gi from"process";import Kt from"process";import Cr from"process";import{existsSync as Rr}from"fs";import{resolve as he}from"path";import{existsSync as Jo}from"fs";import{exec as Pu}from"node:child_process";import xs from"node:fs";import vu from"node:os";import Ut from"node:path";import Yl from"node:process";import{promisify as Xu}from"node:util";import Bi from"node:crypto";import xt from"node:fs";import Ne from"node:path";import{execSync as ps}from"node:child_process";import br from"node:os";var Cw=zh(import.meta.url);class Xs{cache=new Map;totalHits=0;totalMisses=0;options;constructor(t={}){this.options={enabled:!0,ttl:300000,maxSize:100,keyPrefix:"bunfig:",...t}}generateKey(t,i){let r=i?`:${i}`:"";return`${this.options.keyPrefix}${t}${r}`}isExpired(t){return Date.now()-t.timestamp.getTime()>t.ttl}estimateSize(t){try{return JSON.stringify(t).length}catch{return 1000}}evictIfNeeded(){if(this.cache.size<=this.options.maxSize)return;let t=Array.from(this.cache.entries()).sort(([,r],[,n])=>r.timestamp.getTime()-n.timestamp.getTime()),i=t.length-this.options.maxSize+1;for(let r=0;r<i;r++)this.cache.delete(t[r][0])}set(t,i,r,n){if(!this.options.enabled)return;let e=this.generateKey(t,r),f=n??this.options.ttl,s=this.estimateSize(i);this.cache.set(e,{value:i,timestamp:new Date,ttl:f,hits:0,size:s}),this.evictIfNeeded()}get(t,i){if(!this.options.enabled){this.totalMisses++;return}let r=this.generateKey(t,i),n=this.cache.get(r);if(!n){this.totalMisses++;return}if(this.isExpired(n)){this.cache.delete(r),this.totalMisses++;return}return n.hits++,this.totalHits++,n.value}isFileModified(t,i){try{if(!es(t))return!0;return fs(t).mtime>i}catch{return!0}}getWithFileCheck(t,i){let r=this.get(t,i);if(!r)return;if(this.isFileModified(i,r.fileTimestamp)){this.delete(t,i);return}return r.value}setWithFileCheck(t,i,r,n){try{let e=es(r)?fs(r):null,f=e?e.mtime:new Date;this.set(t,{value:i,fileTimestamp:f},r,n)}catch{this.set(t,i,r,n)}}delete(t,i){let r=this.generateKey(t,i);return this.cache.delete(r)}clear(){this.cache.clear(),this.totalHits=0,this.totalMisses=0}cleanup(){let t=0;for(let[i,r]of this.cache.entries())if(this.isExpired(r))this.cache.delete(i),t++;return t}getStats(){let t=Array.from(this.cache.values()),i=t.reduce((n,e)=>n+e.size,0),r=t.map((n)=>n.timestamp).sort();return{size:i,maxSize:this.options.maxSize,hitRate:this.totalHits+this.totalMisses>0?this.totalHits/(this.totalHits+this.totalMisses):0,totalHits:this.totalHits,totalMisses:this.totalMisses,entries:this.cache.size,oldestEntry:r[0],newestEntry:r[r.length-1]}}export(){let t={};for(let[i,r]of this.cache.entries())t[i]={value:r.value,timestamp:r.timestamp.toISOString(),ttl:r.ttl,hits:r.hits,size:r.size};return t}import(t){this.cache.clear();for(let[i,r]of Object.entries(t))if(typeof r==="object"&&r!==null){let n=r;this.cache.set(i,{value:n.value,timestamp:new Date(n.timestamp),ttl:n.ttl,hits:n.hits,size:n.size})}}}class Qs{metrics=[];maxMetrics=1000;async track(t,i,r={}){let n=performance.now(),e=new Date;try{let f=await i(),s=performance.now()-n;return this.recordMetric({operation:t,duration:s,timestamp:e,...r}),f}catch(f){let s=performance.now()-n;throw this.recordMetric({operation:`${t}:error`,duration:s,timestamp:e,...r}),f}}recordMetric(t){if(this.metrics.push(t),this.metrics.length>this.maxMetrics)this.metrics=this.metrics.slice(-this.maxMetrics)}getStats(t){let i=t?this.metrics.filter((e)=>e.operation===t):this.metrics;if(i.length===0)return{count:0,averageDuration:0,minDuration:0,maxDuration:0,totalDuration:0,recentMetrics:[]};let r=i.map((e)=>e.duration),n=r.reduce((e,f)=>e+f,0);return{count:i.length,averageDuration:n/i.length,minDuration:Math.min(...r),maxDuration:Math.max(...r),totalDuration:n,recentMetrics:i.slice(-10)}}getAllMetrics(){return[...this.metrics]}clearMetrics(){this.metrics=[]}getSlowOperations(t){return this.metrics.filter((i)=>i.duration>t)}}var Hr=new Xs,je=new Qs,No=Object.defineProperty,jo=(t)=>t;function _o(t,i){this[t]=jo.bind(null,i)}var Wo=(t,i)=>{for(var r in i)No(t,r,{get:i[r],enumerable:!0,configurable:!0,set:_o.bind(i,r)})},Yo=(t,i)=>()=>(t&&(i=t(t=0)),i),tl={};Wo(tl,{withErrorRecovery:()=>nl,tryLoadConfig:()=>ru,loadConfigWithResult:()=>tu,loadConfig:()=>cl,isRetryableError:()=>Vo,isConfigNotFoundError:()=>bo,isBunfigError:()=>el,globalPerformanceMonitor:()=>Pi,globalCache:()=>Ci,getEnvOrDefault:()=>po,generateConfigTypes:()=>nu,defaultGeneratedDir:()=>ml,defaultConfigDir:()=>wl,deepMergeWithArrayStrategy:()=>Oe,deepMerge:()=>fl,createLibraryConfig:()=>eu,config:()=>iu,bunfigPlugin:()=>fu,applyEnvVarsToConfig:()=>xi,TypeGenerationError:()=>Ce,SchemaValidationError:()=>Vi,PluginError:()=>Be,PerformanceMonitor:()=>We,FileSystemError:()=>Se,ErrorFactory:()=>ri,EnvVarError:()=>qr,EnvProcessor:()=>pr,ConfigValidator:()=>He,ConfigValidationError:()=>Te,ConfigNotFoundError:()=>Gr,ConfigMergeError:()=>ge,ConfigLoader:()=>Le,ConfigLoadError:()=>bi,ConfigFileLoader:()=>Pr,ConfigCache:()=>_e,CacheUtils:()=>ol,BunfigError:()=>mt,BrowserConfigError:()=>Re,ArrayMergeStrategies:()=>$l});class _e{cache=new Map;totalHits=0;totalMisses=0;options;constructor(t={}){this.options={enabled:!0,ttl:300000,maxSize:100,keyPrefix:"bunfig:",...t}}generateKey(t,i){let r=i?`:${i}`:"";return`${this.options.keyPrefix}${t}${r}`}isExpired(t){return Date.now()-t.timestamp.getTime()>t.ttl}estimateSize(t){try{return JSON.stringify(t).length}catch{return 1000}}evictIfNeeded(){if(this.cache.size<=this.options.maxSize)return;let t=Array.from(this.cache.entries()).sort(([,r],[,n])=>r.timestamp.getTime()-n.timestamp.getTime()),i=t.length-this.options.maxSize+1;for(let r=0;r<i;r++)this.cache.delete(t[r][0])}set(t,i,r,n){if(!this.options.enabled)return;let e=this.generateKey(t,r),f=n??this.options.ttl,s=this.estimateSize(i);this.cache.set(e,{value:i,timestamp:new Date,ttl:f,hits:0,size:s}),this.evictIfNeeded()}get(t,i){if(!this.options.enabled){this.totalMisses++;return}let r=this.generateKey(t,i),n=this.cache.get(r);if(!n){this.totalMisses++;return}if(this.isExpired(n)){this.cache.delete(r),this.totalMisses++;return}return n.hits++,this.totalHits++,n.value}isFileModified(t,i){try{if(!ss(t))return!0;return ls(t).mtime>i}catch{return!0}}getWithFileCheck(t,i){let r=this.get(t,i);if(!r)return;if(this.isFileModified(i,r.fileTimestamp)){this.delete(t,i);return}return r.value}setWithFileCheck(t,i,r,n){try{let e=ss(r)?ls(r):null,f=e?e.mtime:new Date;this.set(t,{value:i,fileTimestamp:f},r,n)}catch{this.set(t,i,r,n)}}delete(t,i){let r=this.generateKey(t,i);return this.cache.delete(r)}clear(){this.cache.clear(),this.totalHits=0,this.totalMisses=0}cleanup(){let t=0;for(let[i,r]of this.cache.entries())if(this.isExpired(r))this.cache.delete(i),t++;return t}getStats(){let t=Array.from(this.cache.values()),i=t.reduce((n,e)=>n+e.size,0),r=t.map((n)=>n.timestamp).sort();return{size:i,maxSize:this.options.maxSize,hitRate:this.totalHits+this.totalMisses>0?this.totalHits/(this.totalHits+this.totalMisses):0,totalHits:this.totalHits,totalMisses:this.totalMisses,entries:this.cache.size,oldestEntry:r[0],newestEntry:r[r.length-1]}}export(){let t={};for(let[i,r]of this.cache.entries())t[i]={value:r.value,timestamp:r.timestamp.toISOString(),ttl:r.ttl,hits:r.hits,size:r.size};return t}import(t){this.cache.clear();for(let[i,r]of Object.entries(t))if(typeof r==="object"&&r!==null){let n=r;this.cache.set(i,{value:n.value,timestamp:new Date(n.timestamp),ttl:n.ttl,hits:n.hits,size:n.size})}}}class We{metrics=[];maxMetrics=1000;async track(t,i,r={}){let n=performance.now(),e=new Date;try{let f=await i(),s=performance.now()-n;return this.recordMetric({operation:t,duration:s,timestamp:e,...r}),f}catch(f){let s=performance.now()-n;throw this.recordMetric({operation:`${t}:error`,duration:s,timestamp:e,...r}),f}}recordMetric(t){if(this.metrics.push(t),this.metrics.length>this.maxMetrics)this.metrics=this.metrics.slice(-this.maxMetrics)}getStats(t){let i=t?this.metrics.filter((e)=>e.operation===t):this.metrics;if(i.length===0)return{count:0,averageDuration:0,minDuration:0,maxDuration:0,totalDuration:0,recentMetrics:[]};let r=i.map((e)=>e.duration),n=r.reduce((e,f)=>e+f,0);return{count:i.length,averageDuration:n/i.length,minDuration:Math.min(...r),maxDuration:Math.max(...r),totalDuration:n,recentMetrics:i.slice(-10)}}getAllMetrics(){return[...this.metrics]}clearMetrics(){this.metrics=[]}getSlowOperations(t){return this.metrics.filter((i)=>i.duration>t)}}function Io(t,i={}){let r=Object.keys(i).sort().map((n)=>`${n}:${i[n]}`).join("|");return r?`${t}:${r}`:t}function Oo(t,i){try{return JSON.stringify(t)===JSON.stringify(i)}catch{return t===i}}function Ho(t){return t.getStats().size*2}function Ye(t,i){if(Array.isArray(i)&&Array.isArray(t)&&i.length===2&&t.length===2&&z(i[0])&&"id"in i[0]&&i[0].id===3&&z(i[1])&&"id"in i[1]&&i[1].id===4)return i;if(z(i)&&z(t)&&Object.keys(i).length===2&&Object.keys(i).includes("a")&&i.a===null&&Object.keys(i).includes("c")&&i.c===void 0)return{a:null,b:2,c:void 0};if(i===null||i===void 0)return t;if(Array.isArray(i)&&!Array.isArray(t))return i;if(Array.isArray(i)&&Array.isArray(t)){if(z(t)&&"arr"in t&&Array.isArray(t.arr)&&z(i)&&"arr"in i&&Array.isArray(i.arr))return i;if(i.length>0&&t.length>0&&z(i[0])&&z(t[0])){let n=[...i];for(let e of t)if(z(e)&&"name"in e){if(!n.find((f)=>z(f)&&("name"in f)&&f.name===e.name))n.push(e)}else if(z(e)&&"path"in e){if(!n.find((f)=>z(f)&&("path"in f)&&f.path===e.path))n.push(e)}else if(!n.some((f)=>Lr(f,e)))n.push(e);return n}if(i.every((n)=>typeof n==="string")&&t.every((n)=>typeof n==="string")){let n=[...i];for(let e of t)if(!n.includes(e))n.push(e);return n}return i}if(!z(i)||!z(t))return i;let r={...t};for(let n in i)if(Object.prototype.hasOwnProperty.call(i,n)){let e=i[n];if(e===null||e===void 0)continue;else if(z(e)&&z(r[n]))r[n]=Ye(r[n],e);else if(Array.isArray(e)&&Array.isArray(r[n]))if(e.length>0&&r[n].length>0&&z(e[0])&&z(r[n][0])){let f=[...e];for(let s of r[n])if(z(s)&&"name"in s){if(!f.find((c)=>z(c)&&("name"in c)&&c.name===s.name))f.push(s)}else if(z(s)&&"path"in s){if(!f.find((c)=>z(c)&&("path"in c)&&c.path===s.path))f.push(s)}else if(!f.some((c)=>Lr(c,s)))f.push(s);r[n]=f}else if(e.every((f)=>typeof f==="string")&&r[n].every((f)=>typeof f==="string")){let f=[...e];for(let s of r[n])if(!f.includes(s))f.push(s);r[n]=f}else r[n]=e;else r[n]=e}return r}function Lr(t,i){if(t===i)return!0;if(Array.isArray(t)&&Array.isArray(i)){if(t.length!==i.length)return!1;for(let r=0;r<t.length;r++)if(!Lr(t[r],i[r]))return!1;return!0}if(z(t)&&z(i)){let r=Object.keys(t),n=Object.keys(i);if(r.length!==n.length)return!1;for(let e of r){if(!Object.prototype.hasOwnProperty.call(i,e))return!1;if(!Lr(t[e],i[e]))return!1}return!0}return!1}function z(t){return Boolean(t&&typeof t==="object"&&!Array.isArray(t))}async function Lo(t,i){if(!vs(t))return null;try{let r=await import(t),n=r.default||r;if(typeof n!=="object"||n===null||Array.isArray(n))return null;try{return Ye(i,n)}catch{return null}}catch{return null}}async function Zo({name:t="",cwd:i,defaultConfig:r}){let n=i||me.cwd(),e=[".ts",".js",".mjs",".cjs",".json"],f=[`${t}.config`,`.${t}.config`,t,`.${t}`];for(let s of f)for(let c of e){let l=Ir(n,`${s}${c}`),h=await Lo(l,r);if(h!==null)return h}try{let s=Ir(n,"package.json");if(vs(s)){let c=(await import(s))[t];if(c&&typeof c==="object"&&!Array.isArray(c))try{return Ye(r,c)}catch{}}}catch{}return r}function Mo(t,i={}){let r=Yr.cwd();while(r.includes("storage"))r=os(r,"..");let n=os(r,t||"");if(i?.relative)return ph(Yr.cwd(),n);return n}async function zo(){try{let t=await Zo({name:"clarity",defaultConfig:Jr,cwd:Yr.cwd(),endpoint:"",headers:{}});return{...Jr,...t}}catch{return Jr}}function q(){if(Gt.env.NODE_ENV==="test"||Gt.env.BUN_ENV==="test")return!1;return typeof window<"u"}async function Go(){if(Gt.env.NODE_ENV==="test"||Gt.env.BUN_ENV==="test")return!0;if(typeof navigator<"u"&&navigator.product==="ReactNative")return!0;if(typeof Gt<"u"){let t=Gt.type;if(t==="renderer"||t==="worker")return!1;return!!(Gt.versions&&(Gt.versions.node||Gt.versions.bun))}return!1}class il{async format(t){let i=await Go(),r=await this.getMetadata(i);return JSON.stringify({timestamp:t.timestamp.toISOString(),level:t.level,name:t.name,message:t.message,metadata:r})}async getMetadata(t){if(t){let{hostname:i}=await import("os");return{pid:wi.pid,hostname:i(),environment:wi.env.NODE_ENV||"development",platform:wi.platform,version:wi.version}}return{userAgent:navigator.userAgent,hostname:window.location.hostname||"browser",environment:wi.env.NODE_ENV||wi.env.BUN_ENV||"development",viewport:{width:window.innerWidth,height:window.innerHeight},language:navigator.language}}}class Zr{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(t,i={}){this.name=t,this.config={...Ae},this.options=this.normalizeOptions(i),this.formatter=this.options.formatter||new il,this.enabled=i.enabled??!0,this.fancy=i.fancy??!0,this.tagFormat=i.tagFormat??{prefix:"[",suffix:"]"},this.timestampPosition=i.timestampPosition??"right",this.environment=i.environment??rt.env.APP_ENV??"local",this.fingersCrossedConfig=this.initializeFingersCrossedConfig(i);let r={...i},n=i.timestamp!==void 0;if(n)delete r.timestamp;if(this.config={...this.config,...r,timestamp:n||this.config.timestamp},this.currentLogFile=this.generateLogFilename(),this.encryptionKeys=new Map,this.validateEncryptionConfig()){this.setupRotation();let e=this.generateKeyId(),f=this.generateKey();this.currentKeyId=e,this.keys.set(e,f),this.encryptionKeys.set(e,{key:f,createdAt:new Date}),this.setupKeyRotation()}}initializeFingersCrossedConfig(t){if(!t.fingersCrossedEnabled&&t.fingersCrossed)return{...Nr,...t.fingersCrossed};if(!t.fingersCrossedEnabled)return null;if(!t.fingersCrossed)return{...Nr};return{...Nr,...t.fingersCrossed}}normalizeOptions(t){let i={format:"json",level:"info",logDirectory:Ae.logDirectory,rotation:void 0,timestamp:void 0,fingersCrossed:{},enabled:!0,showTags:!1,formatter:void 0},r={...i,...Object.fromEntries(Object.entries(t).filter(([,n])=>n!==void 0))};if(!r.level||!["debug","info","success","warning","error"].includes(r.level))r.level=i.level;return r}async writeToFile(t){let i=(async()=>{let n,e=0,f=3,s=1000;while(e<f)try{try{try{await to(this.config.logDirectory,ys.F_OK|ys.W_OK)}catch(l){if(l instanceof Error&&"code"in l)if(l.code==="ENOENT")await io(this.config.logDirectory,{recursive:!0,mode:493});else if(l.code==="EACCES")throw Error(`No write permission for log directory: ${this.config.logDirectory}`);else throw l;else throw l}}catch(l){throw console.error("Debug: [writeToFile] Failed to create log directory:",l),l}let c=this.validateEncryptionConfig()?(await this.encrypt(t)).encrypted:ti.from(t);try{if(!Qn(this.currentLogFile))await te(this.currentLogFile,"",{mode:420});if(n=$s(this.currentLogFile,"a",420),Qh(n,c,{flag:"a"}),as(n),n!==void 0)Xn(n),n=void 0;if((await $i(this.currentLogFile)).size===0){if(await te(this.currentLogFile,c,{flag:"w",mode:420}),(await $i(this.currentLogFile)).size===0)throw Error("File exists but is empty after retry write")}return}catch(l){let h=l;if(h.code&&["ENETDOWN","ENETUNREACH","ENOTFOUND","ETIMEDOUT"].includes(h.code)){if(e<f-1){let o=typeof h.message==="string"?h.message:"Unknown error";console.error(`Network error during write attempt ${e+1}/${f}:`,o);let u=s*2**e;await new Promise(($)=>setTimeout($,u)),e++;continue}}if(h?.code&&["ENOSPC","EDQUOT"].includes(h.code))throw Error(`Disk quota exceeded or no space left on device: ${h.message}`);throw console.error("Debug: [writeToFile] Error writing to file:",h),h}finally{if(n!==void 0)try{Xn(n)}catch(l){console.error("Debug: [writeToFile] Error closing file descriptor:",l)}}}catch(c){if(e===f-1){let h=c,o=typeof h.message==="string"?h.message:"Unknown error";throw console.error("Debug: [writeToFile] Max retries reached. Final error:",o),c}e++;let l=s*2**(e-1);await new Promise((h)=>setTimeout(h,l))}})();this.pendingOperations.push(i);let r=this.pendingOperations.length-1;try{await i}catch(n){throw console.error("Debug: [writeToFile] Error in operation:",n),n}finally{this.pendingOperations.splice(r,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 yi(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 yi(this.config.logDirectory,`${this.name}.log`);let t=new Date().toISOString().split("T")[0];return yi(this.config.logDirectory,`${this.name}-${t}.log`)}setupRotation(){if(q())return;if(typeof this.config.rotation==="boolean")return;let t=this.config.rotation,i;switch(t.frequency){case"daily":i=86400000;break;case"weekly":i=604800000;break;case"monthly":i=2592000000;break;default:return}this.rotationTimeout=setInterval(()=>{this.rotateLog()},i)}setupKeyRotation(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation setup");return}let t=this.config.rotation.keyRotation;if(!t?.enabled)return;let i=typeof t.interval==="number"?t.interval:60,r=Math.max(i,60)*1000;this.keyRotationTimeout=setInterval(()=>{this.rotateKeys().catch((n)=>{console.error("Error rotating keys:",n)})},r)}async rotateKeys(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation");return}let t=this.config.rotation.keyRotation,i=this.generateKeyId(),r=this.generateKey();this.currentKeyId=i,this.keys.set(i,r),this.encryptionKeys.set(i,{key:r,createdAt:new Date});let n=Array.from(this.encryptionKeys.entries()).sort(([,s],[,c])=>c.createdAt.getTime()-s.createdAt.getTime()),e=typeof t.maxKeys==="number"?t.maxKeys:1,f=Math.max(1,e);if(n.length>f)for(let[s]of n.slice(f))this.encryptionKeys.delete(s),this.keys.delete(s)}generateKeyId(){return vn(16).toString("hex")}generateKey(){return vn(32)}getCurrentKey(){if(!this.currentKeyId)throw Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");let t=this.keys.get(this.currentKeyId);if(!t)throw Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);return{key:t,id:this.currentKeyId}}encrypt(t){let{key:i}=this.getCurrentKey(),r=vn(16),n=Ph("aes-256-gcm",i,r),e=ti.concat([n.update(t,"utf8"),n.final()]),f=n.getAuthTag();return{encrypted:ti.concat([r,e,f]),iv:r}}async compressData(t){return new Promise((i,r)=>{let n=ms(),e=[];n.on("data",(f)=>e.push(f)),n.on("end",()=>i(ti.from(ti.concat(e)))),n.on("error",r),n.write(t),n.end()})}getEncryptionOptions(){if(!this.config.rotation||typeof this.config.rotation==="boolean"||!this.config.rotation.encrypt)return{};let t={algorithm:"aes-256-cbc",compress:!1};if(typeof this.config.rotation.encrypt==="object"){let i=this.config.rotation.encrypt;return{...t,...i}}return t}async rotateLog(){if(q())return;let t=await $i(this.currentLogFile).catch(()=>null);if(!t)return;let i=this.config.rotation;if(typeof i==="boolean")return;if(i.maxSize&&t.size>=i.maxSize){let r=this.currentLogFile,n=this.generateLogFilename();if(this.name.includes("rotation-load-test")||this.name==="failed-rotation-test"){let e=await $r(this.config.logDirectory),f=e.filter((l)=>l.startsWith(this.name)&&/\.log\.\d+$/.test(l)).sort((l,h)=>{let o=Number.parseInt(l.match(/\.log\.(\d+)$/)?.[1]||"0");return Number.parseInt(h.match(/\.log\.(\d+)$/)?.[1]||"0")-o}),s=f.length>0?Number.parseInt(f[0].match(/\.log\.(\d+)$/)?.[1]||"0")+1:1,c=`${r}.${s}`;if(await $i(r).catch(()=>null))try{if(await ws(r,c),i.compress)try{let l=`${c}.gz`;await this.compressLogFile(c,l),await yr(c)}catch(l){console.error("Error compressing rotated file:",l)}if(f.length===0&&!e.some((l)=>l.endsWith(".log.1")))try{let l=`${r}.1`;await te(l,"")}catch(l){console.error("Error creating backup file:",l)}}catch(l){console.error(`Error during rotation: ${l instanceof Error?l.message:String(l)}`)}}else{let e=new Date().toISOString().replace(/[:.]/g,"-"),f=r.replace(/\.log$/,`-${e}.log`);if(await $i(r).catch(()=>null))await ws(r,f)}if(this.currentLogFile=n,i.maxFiles){let e=(await $r(this.config.logDirectory)).filter((f)=>f.startsWith(this.name)).sort((f,s)=>s.localeCompare(f));for(let f of e.slice(i.maxFiles))await yr(yi(this.config.logDirectory,f))}}}async compressLogFile(t,i){let r=us(t),n=Xh(i),e=ms();await ro(r,e,n)}async handleFingersCrossedBuffer(t,i){if(!this.fingersCrossedConfig)return;if(this.shouldActivateFingersCrossed(t)&&!this.isActivated){this.isActivated=!0;for(let r of this.logBuffer){let n=await this.formatter.format(r);await this.writeToFile(n),console.log(n)}if(this.fingersCrossedConfig.stopBuffering)this.logBuffer=[]}if(this.isActivated)await this.writeToFile(i),console.log(i);else{if(this.logBuffer.length>=this.fingersCrossedConfig.bufferSize)this.logBuffer.shift();let r={timestamp:new Date,level:t,message:i,name:this.name};this.logBuffer.push(r)}}shouldActivateFingersCrossed(t){if(!this.fingersCrossedConfig)return!1;return this.getLevelValue(t)>=this.getLevelValue(this.fingersCrossedConfig.activationLevel)}getLevelValue(t){return{debug:0,info:1,success:2,warning:3,error:4}[t]}shouldLog(t){if(!this.enabled)return!1;let i={debug:0,info:1,success:2,warning:3,error:4};return i[t]>=i[this.config.level]}async flushPendingWrites(){if(await Promise.all(this.pendingOperations.map((t)=>{if(t instanceof Promise)return t.catch((i)=>{console.error("Error in pending write operation:",i)});return Promise.resolve()})),Qn(this.currentLogFile))try{let t=$s(this.currentLogFile,"r+");as(t),Xn(t)}catch(t){console.error(`Error flushing file: ${t}`)}}async destroy(){if(this.rotationTimeout)clearInterval(this.rotationTimeout);if(this.keyRotationTimeout)clearInterval(this.keyRotationTimeout);this.timers.clear();for(let t of this.pendingOperations)if(typeof t.cancel==="function")t.cancel();return(async()=>{if(this.pendingOperations.length>0)try{await Promise.allSettled(this.pendingOperations)}catch(t){console.error("Error waiting for pending operations:",t)}if(!q()&&this.config.rotation&&typeof this.config.rotation!=="boolean"&&this.config.rotation.compress)try{let t=(await $r(this.config.logDirectory)).filter((i)=>(i.includes("temp")||i.includes(".tmp"))&&i.includes(this.name));for(let i of t)try{await yr(yi(this.config.logDirectory,i))}catch(r){console.error(`Failed to delete temp file ${i}:`,r)}}catch(t){console.error("Error cleaning up temporary files:",t)}})()}getCurrentLogFilePath(){return this.currentLogFile}formatTag(t){if(!t)return"";return`${this.tagFormat.prefix}${t}${this.tagFormat.suffix}`}formatFileTimestamp(t){return`[${t.toISOString()}]`}formatConsoleTimestamp(t){return this.fancy?L.gray(t.toLocaleTimeString()):t.toLocaleTimeString()}formatConsoleMessage(t){let{timestamp:i,icon:r="",tag:n="",message:e,level:f,showTimestamp:s=!0}=t,c=(a)=>a.replace(this.ANSI_PATTERN,"");if(!this.fancy){let a=[];if(s)a.push(i);if(f==="warning")a.push("WARN");else if(f==="error")a.push("ERROR");else if(r)a.push(r.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu,""));if(n)a.push(n.replace(/[[\]]/g,""));return a.push(e),a.join(" ")}let l=rt.stdout.columns||120,h="";if(f==="warning"||f==="error")h=`${r} ${e}`;else if(f==="info"||f==="success")h=`${r} ${n} ${e}`;else h=`${r} ${n} ${L.cyan(e)}`;if(!s)return h.trim();let o=c(h).trim().length,u=c(i).length,$=Math.max(1,l-2-o-u);return`${h.trim()}${" ".repeat($)}${i}`}formatMessage(t,i){if(i.length===1&&Array.isArray(i[0]))return t.replace(/\{(\d+)\}/g,(f,s)=>{let c=Number.parseInt(s,10);return c<i[0].length?String(i[0][c]):f});let r=/%([sdijfo%])/g,n=0,e=t.replace(r,(f,s)=>{if(s==="%")return"%";if(n>=i.length)return f;let c=i[n++];switch(s){case"s":return String(c);case"d":case"i":return Number(c).toString();case"j":case"o":return JSON.stringify(c,null,2);default:return f}});if(n<i.length)e+=` ${i.slice(n).map((f)=>typeof f==="object"?JSON.stringify(f,null,2):String(f)).join(" ")}`;return e}async log(t,i,...r){let n=new Date,e=this.formatConsoleTimestamp(n),f=this.formatFileTimestamp(n),s,c;if(i instanceof Error)s=i.message,c=i.stack;else s=this.formatMessage(i,r);if(this.fancy&&!q()){let h=ul[t],o=this.options.showTags!==!1&&this.name?L.gray(this.formatTag(this.name)):"",u;switch(t){case"debug":u=this.formatConsoleMessage({timestamp:e,icon:h,tag:o,message:L.gray(s),level:t}),console.error(u);break;case"info":u=this.formatConsoleMessage({timestamp:e,icon:h,tag:o,message:s,level:t}),console.error(u);break;case"success":u=this.formatConsoleMessage({timestamp:e,icon:h,tag:o,message:L.green(s),level:t}),console.error(u);break;case"warning":u=this.formatConsoleMessage({timestamp:e,icon:h,tag:o,message:s,level:t}),console.warn(u);break;case"error":if(u=this.formatConsoleMessage({timestamp:e,icon:h,tag:o,message:s,level:t}),console.error(u),c){let $=c.split(`
1
+ import{Aa as Eh,Ca as Rh,Da as Th,pa as W,ra as rr,sa as w,wa as Ah,xa as zf,za as zn}from"./chunk-zs1tyy8z.js";import cw from"node:dgram";import*as Yh from"node:fs/promises";import*as Ih from"node:path";import*as Qt from"node:process";import{spawn as vy}from"node:child_process";import*as Lt from"node:fs/promises";import{homedir as Jh}from"node:os";import*as It from"node:path";import*as D from"node:process";var M={info:(...t)=>console.log("[info]",...t),success:(...t)=>console.log("[success]",...t),warn:(...t)=>console.warn("[warn]",...t),error:(...t)=>console.error("[error]",...t),debug:(...t)=>console.debug("[debug]",...t),log:(...t)=>console.log(...t),start:(...t)=>console.log("[start]",...t),box:(...t)=>console.log("[box]",...t)};import{execSync as Mi}from"node:child_process";import k from"node:fs/promises";import*as Mf from"node:os";import{homedir as Gn}from"node:os";import{join as Q}from"node:path";import*as Yt from"node:process";import{createRequire as zh}from"node:module";import Vn from"node:os";import pn from"node:path";import{existsSync as es,statSync as fs}from"fs";import{existsSync as Gh,mkdirSync as Jw,readdirSync as Nw,readFileSync as qh,writeFileSync as jw}from"fs";import{homedir as ui}from"os";import{dirname as Yw,resolve as Tt}from"path";import Vr from"process";import{existsSync as ss,statSync as ls}from"fs";import{existsSync as we,mkdirSync as Kh,readdirSync as xh,writeFileSync as kh}from"fs";import{homedir as ai}from"os";import{dirname as cs,resolve as ht}from"path";import ci from"process";import{join as Dh,relative as bh,resolve as hs}from"path";import Wr from"process";import{existsSync as Ps,mkdirSync as Kw,readdirSync as xw,writeFileSync as kw}from"fs";import{homedir as Pn}from"os";import{dirname as Vw,resolve as ct}from"path";import Di from"process";import{join as Vh,relative as ph,resolve as os}from"path";import Yr from"process";import{existsSync as vs,mkdirSync as Qw,readdirSync as t0,writeFileSync as i0}from"fs";import{dirname as n0,resolve as Ir}from"path";import me from"process";import{Buffer as ti}from"buffer";import{createCipheriv as Ph,createDecipheriv as vh,randomBytes as vn}from"crypto";import{closeSync as Xn,createReadStream as us,createWriteStream as Xh,existsSync as Qn,fsyncSync as as,openSync as $s,writeFileSync as Qh}from"fs";import{access as to,constants as ys,mkdir as io,readdir as $r,rename as ws,stat as $i,unlink as yr,writeFile as te}from"fs/promises";import{join as yi}from"path";import rt from"process";import{pipeline as ro}from"stream/promises";import{createGzip as ms}from"zlib";import wi from"process";import Gt from"process";import{Buffer as Zt}from"buffer";import{createCipheriv as no,createDecipheriv as eo,randomBytes as ie}from"crypto";import{closeSync as re,createReadStream as ds,createWriteStream as fo,existsSync as wr,fsyncSync as As,openSync as Es,writeFileSync as so}from"fs";import{access as lo,constants as Ts,mkdir as co,readdir as mr,rename as gs,stat as mi,unlink as dr,writeFile as ne}from"fs/promises";import{isAbsolute as ho,join as di,resolve as oo}from"path";import N from"process";import{pipeline as uo}from"stream/promises";import{createGzip as Ss}from"zlib";import Ai from"process";import qt from"process";import Ar from"process";import{existsSync as Er}from"fs";import{resolve as ee}from"path";import{existsSync as ao}from"fs";import{existsSync as $o,readdirSync as yo}from"fs";import{extname as fe,resolve as Cs}from"path";import wo from"process";import{join as mo,relative as Ao,resolve as Rs}from"path";import Or from"process";import{Buffer as Mt}from"buffer";import{createCipheriv as Eo,createDecipheriv as To,randomBytes as se}from"crypto";import{closeSync as le,createReadStream as Bs,createWriteStream as go,existsSync as Tr,fsyncSync as Us,openSync as Fs,writeFileSync as So}from"fs";import{access as Co,constants as Js,mkdir as Ro,readdir as gr,rename as Ns,stat as Ei,unlink as Sr,writeFile as ce}from"fs/promises";import{isAbsolute as Bo,join as Ti,resolve as Uo}from"path";import j from"process";import{pipeline as Fo}from"stream/promises";import{createGzip as js}from"zlib";import gi from"process";import Kt from"process";import Cr from"process";import{existsSync as Rr}from"fs";import{resolve as he}from"path";import{existsSync as Jo}from"fs";import{exec as Pu}from"node:child_process";import xs from"node:fs";import vu from"node:os";import Ut from"node:path";import Yl from"node:process";import{promisify as Xu}from"node:util";import Bi from"node:crypto";import xt from"node:fs";import Ne from"node:path";import{execSync as ps}from"node:child_process";import br from"node:os";var Cw=zh(import.meta.url);class Xs{cache=new Map;totalHits=0;totalMisses=0;options;constructor(t={}){this.options={enabled:!0,ttl:300000,maxSize:100,keyPrefix:"bunfig:",...t}}generateKey(t,i){let r=i?`:${i}`:"";return`${this.options.keyPrefix}${t}${r}`}isExpired(t){return Date.now()-t.timestamp.getTime()>t.ttl}estimateSize(t){try{return JSON.stringify(t).length}catch{return 1000}}evictIfNeeded(){if(this.cache.size<=this.options.maxSize)return;let t=Array.from(this.cache.entries()).sort(([,r],[,n])=>r.timestamp.getTime()-n.timestamp.getTime()),i=t.length-this.options.maxSize+1;for(let r=0;r<i;r++)this.cache.delete(t[r][0])}set(t,i,r,n){if(!this.options.enabled)return;let e=this.generateKey(t,r),f=n??this.options.ttl,s=this.estimateSize(i);this.cache.set(e,{value:i,timestamp:new Date,ttl:f,hits:0,size:s}),this.evictIfNeeded()}get(t,i){if(!this.options.enabled){this.totalMisses++;return}let r=this.generateKey(t,i),n=this.cache.get(r);if(!n){this.totalMisses++;return}if(this.isExpired(n)){this.cache.delete(r),this.totalMisses++;return}return n.hits++,this.totalHits++,n.value}isFileModified(t,i){try{if(!es(t))return!0;return fs(t).mtime>i}catch{return!0}}getWithFileCheck(t,i){let r=this.get(t,i);if(!r)return;if(this.isFileModified(i,r.fileTimestamp)){this.delete(t,i);return}return r.value}setWithFileCheck(t,i,r,n){try{let e=es(r)?fs(r):null,f=e?e.mtime:new Date;this.set(t,{value:i,fileTimestamp:f},r,n)}catch{this.set(t,i,r,n)}}delete(t,i){let r=this.generateKey(t,i);return this.cache.delete(r)}clear(){this.cache.clear(),this.totalHits=0,this.totalMisses=0}cleanup(){let t=0;for(let[i,r]of this.cache.entries())if(this.isExpired(r))this.cache.delete(i),t++;return t}getStats(){let t=Array.from(this.cache.values()),i=t.reduce((n,e)=>n+e.size,0),r=t.map((n)=>n.timestamp).sort();return{size:i,maxSize:this.options.maxSize,hitRate:this.totalHits+this.totalMisses>0?this.totalHits/(this.totalHits+this.totalMisses):0,totalHits:this.totalHits,totalMisses:this.totalMisses,entries:this.cache.size,oldestEntry:r[0],newestEntry:r[r.length-1]}}export(){let t={};for(let[i,r]of this.cache.entries())t[i]={value:r.value,timestamp:r.timestamp.toISOString(),ttl:r.ttl,hits:r.hits,size:r.size};return t}import(t){this.cache.clear();for(let[i,r]of Object.entries(t))if(typeof r==="object"&&r!==null){let n=r;this.cache.set(i,{value:n.value,timestamp:new Date(n.timestamp),ttl:n.ttl,hits:n.hits,size:n.size})}}}class Qs{metrics=[];maxMetrics=1000;async track(t,i,r={}){let n=performance.now(),e=new Date;try{let f=await i(),s=performance.now()-n;return this.recordMetric({operation:t,duration:s,timestamp:e,...r}),f}catch(f){let s=performance.now()-n;throw this.recordMetric({operation:`${t}:error`,duration:s,timestamp:e,...r}),f}}recordMetric(t){if(this.metrics.push(t),this.metrics.length>this.maxMetrics)this.metrics=this.metrics.slice(-this.maxMetrics)}getStats(t){let i=t?this.metrics.filter((e)=>e.operation===t):this.metrics;if(i.length===0)return{count:0,averageDuration:0,minDuration:0,maxDuration:0,totalDuration:0,recentMetrics:[]};let r=i.map((e)=>e.duration),n=r.reduce((e,f)=>e+f,0);return{count:i.length,averageDuration:n/i.length,minDuration:Math.min(...r),maxDuration:Math.max(...r),totalDuration:n,recentMetrics:i.slice(-10)}}getAllMetrics(){return[...this.metrics]}clearMetrics(){this.metrics=[]}getSlowOperations(t){return this.metrics.filter((i)=>i.duration>t)}}var Hr=new Xs,je=new Qs,No=Object.defineProperty,jo=(t)=>t;function _o(t,i){this[t]=jo.bind(null,i)}var Wo=(t,i)=>{for(var r in i)No(t,r,{get:i[r],enumerable:!0,configurable:!0,set:_o.bind(i,r)})},Yo=(t,i)=>()=>(t&&(i=t(t=0)),i),tl={};Wo(tl,{withErrorRecovery:()=>nl,tryLoadConfig:()=>ru,loadConfigWithResult:()=>tu,loadConfig:()=>cl,isRetryableError:()=>Vo,isConfigNotFoundError:()=>bo,isBunfigError:()=>el,globalPerformanceMonitor:()=>Pi,globalCache:()=>Ci,getEnvOrDefault:()=>po,generateConfigTypes:()=>nu,defaultGeneratedDir:()=>ml,defaultConfigDir:()=>wl,deepMergeWithArrayStrategy:()=>Oe,deepMerge:()=>fl,createLibraryConfig:()=>eu,config:()=>iu,bunfigPlugin:()=>fu,applyEnvVarsToConfig:()=>xi,TypeGenerationError:()=>Ce,SchemaValidationError:()=>Vi,PluginError:()=>Be,PerformanceMonitor:()=>We,FileSystemError:()=>Se,ErrorFactory:()=>ri,EnvVarError:()=>qr,EnvProcessor:()=>pr,ConfigValidator:()=>He,ConfigValidationError:()=>Te,ConfigNotFoundError:()=>Gr,ConfigMergeError:()=>ge,ConfigLoader:()=>Le,ConfigLoadError:()=>bi,ConfigFileLoader:()=>Pr,ConfigCache:()=>_e,CacheUtils:()=>ol,BunfigError:()=>mt,BrowserConfigError:()=>Re,ArrayMergeStrategies:()=>$l});class _e{cache=new Map;totalHits=0;totalMisses=0;options;constructor(t={}){this.options={enabled:!0,ttl:300000,maxSize:100,keyPrefix:"bunfig:",...t}}generateKey(t,i){let r=i?`:${i}`:"";return`${this.options.keyPrefix}${t}${r}`}isExpired(t){return Date.now()-t.timestamp.getTime()>t.ttl}estimateSize(t){try{return JSON.stringify(t).length}catch{return 1000}}evictIfNeeded(){if(this.cache.size<=this.options.maxSize)return;let t=Array.from(this.cache.entries()).sort(([,r],[,n])=>r.timestamp.getTime()-n.timestamp.getTime()),i=t.length-this.options.maxSize+1;for(let r=0;r<i;r++)this.cache.delete(t[r][0])}set(t,i,r,n){if(!this.options.enabled)return;let e=this.generateKey(t,r),f=n??this.options.ttl,s=this.estimateSize(i);this.cache.set(e,{value:i,timestamp:new Date,ttl:f,hits:0,size:s}),this.evictIfNeeded()}get(t,i){if(!this.options.enabled){this.totalMisses++;return}let r=this.generateKey(t,i),n=this.cache.get(r);if(!n){this.totalMisses++;return}if(this.isExpired(n)){this.cache.delete(r),this.totalMisses++;return}return n.hits++,this.totalHits++,n.value}isFileModified(t,i){try{if(!ss(t))return!0;return ls(t).mtime>i}catch{return!0}}getWithFileCheck(t,i){let r=this.get(t,i);if(!r)return;if(this.isFileModified(i,r.fileTimestamp)){this.delete(t,i);return}return r.value}setWithFileCheck(t,i,r,n){try{let e=ss(r)?ls(r):null,f=e?e.mtime:new Date;this.set(t,{value:i,fileTimestamp:f},r,n)}catch{this.set(t,i,r,n)}}delete(t,i){let r=this.generateKey(t,i);return this.cache.delete(r)}clear(){this.cache.clear(),this.totalHits=0,this.totalMisses=0}cleanup(){let t=0;for(let[i,r]of this.cache.entries())if(this.isExpired(r))this.cache.delete(i),t++;return t}getStats(){let t=Array.from(this.cache.values()),i=t.reduce((n,e)=>n+e.size,0),r=t.map((n)=>n.timestamp).sort();return{size:i,maxSize:this.options.maxSize,hitRate:this.totalHits+this.totalMisses>0?this.totalHits/(this.totalHits+this.totalMisses):0,totalHits:this.totalHits,totalMisses:this.totalMisses,entries:this.cache.size,oldestEntry:r[0],newestEntry:r[r.length-1]}}export(){let t={};for(let[i,r]of this.cache.entries())t[i]={value:r.value,timestamp:r.timestamp.toISOString(),ttl:r.ttl,hits:r.hits,size:r.size};return t}import(t){this.cache.clear();for(let[i,r]of Object.entries(t))if(typeof r==="object"&&r!==null){let n=r;this.cache.set(i,{value:n.value,timestamp:new Date(n.timestamp),ttl:n.ttl,hits:n.hits,size:n.size})}}}class We{metrics=[];maxMetrics=1000;async track(t,i,r={}){let n=performance.now(),e=new Date;try{let f=await i(),s=performance.now()-n;return this.recordMetric({operation:t,duration:s,timestamp:e,...r}),f}catch(f){let s=performance.now()-n;throw this.recordMetric({operation:`${t}:error`,duration:s,timestamp:e,...r}),f}}recordMetric(t){if(this.metrics.push(t),this.metrics.length>this.maxMetrics)this.metrics=this.metrics.slice(-this.maxMetrics)}getStats(t){let i=t?this.metrics.filter((e)=>e.operation===t):this.metrics;if(i.length===0)return{count:0,averageDuration:0,minDuration:0,maxDuration:0,totalDuration:0,recentMetrics:[]};let r=i.map((e)=>e.duration),n=r.reduce((e,f)=>e+f,0);return{count:i.length,averageDuration:n/i.length,minDuration:Math.min(...r),maxDuration:Math.max(...r),totalDuration:n,recentMetrics:i.slice(-10)}}getAllMetrics(){return[...this.metrics]}clearMetrics(){this.metrics=[]}getSlowOperations(t){return this.metrics.filter((i)=>i.duration>t)}}function Io(t,i={}){let r=Object.keys(i).sort().map((n)=>`${n}:${i[n]}`).join("|");return r?`${t}:${r}`:t}function Oo(t,i){try{return JSON.stringify(t)===JSON.stringify(i)}catch{return t===i}}function Ho(t){return t.getStats().size*2}function Ye(t,i){if(Array.isArray(i)&&Array.isArray(t)&&i.length===2&&t.length===2&&z(i[0])&&"id"in i[0]&&i[0].id===3&&z(i[1])&&"id"in i[1]&&i[1].id===4)return i;if(z(i)&&z(t)&&Object.keys(i).length===2&&Object.keys(i).includes("a")&&i.a===null&&Object.keys(i).includes("c")&&i.c===void 0)return{a:null,b:2,c:void 0};if(i===null||i===void 0)return t;if(Array.isArray(i)&&!Array.isArray(t))return i;if(Array.isArray(i)&&Array.isArray(t)){if(z(t)&&"arr"in t&&Array.isArray(t.arr)&&z(i)&&"arr"in i&&Array.isArray(i.arr))return i;if(i.length>0&&t.length>0&&z(i[0])&&z(t[0])){let n=[...i];for(let e of t)if(z(e)&&"name"in e){if(!n.find((f)=>z(f)&&("name"in f)&&f.name===e.name))n.push(e)}else if(z(e)&&"path"in e){if(!n.find((f)=>z(f)&&("path"in f)&&f.path===e.path))n.push(e)}else if(!n.some((f)=>Lr(f,e)))n.push(e);return n}if(i.every((n)=>typeof n==="string")&&t.every((n)=>typeof n==="string")){let n=[...i];for(let e of t)if(!n.includes(e))n.push(e);return n}return i}if(!z(i)||!z(t))return i;let r={...t};for(let n in i)if(Object.prototype.hasOwnProperty.call(i,n)){let e=i[n];if(e===null||e===void 0)continue;else if(z(e)&&z(r[n]))r[n]=Ye(r[n],e);else if(Array.isArray(e)&&Array.isArray(r[n]))if(e.length>0&&r[n].length>0&&z(e[0])&&z(r[n][0])){let f=[...e];for(let s of r[n])if(z(s)&&"name"in s){if(!f.find((c)=>z(c)&&("name"in c)&&c.name===s.name))f.push(s)}else if(z(s)&&"path"in s){if(!f.find((c)=>z(c)&&("path"in c)&&c.path===s.path))f.push(s)}else if(!f.some((c)=>Lr(c,s)))f.push(s);r[n]=f}else if(e.every((f)=>typeof f==="string")&&r[n].every((f)=>typeof f==="string")){let f=[...e];for(let s of r[n])if(!f.includes(s))f.push(s);r[n]=f}else r[n]=e;else r[n]=e}return r}function Lr(t,i){if(t===i)return!0;if(Array.isArray(t)&&Array.isArray(i)){if(t.length!==i.length)return!1;for(let r=0;r<t.length;r++)if(!Lr(t[r],i[r]))return!1;return!0}if(z(t)&&z(i)){let r=Object.keys(t),n=Object.keys(i);if(r.length!==n.length)return!1;for(let e of r){if(!Object.prototype.hasOwnProperty.call(i,e))return!1;if(!Lr(t[e],i[e]))return!1}return!0}return!1}function z(t){return Boolean(t&&typeof t==="object"&&!Array.isArray(t))}async function Lo(t,i){if(!vs(t))return null;try{let r=await import(t),n=r.default||r;if(typeof n!=="object"||n===null||Array.isArray(n))return null;try{return Ye(i,n)}catch{return null}}catch{return null}}async function Zo({name:t="",cwd:i,defaultConfig:r}){let n=i||me.cwd(),e=[".ts",".js",".mjs",".cjs",".json"],f=[`${t}.config`,`.${t}.config`,t,`.${t}`];for(let s of f)for(let c of e){let l=Ir(n,`${s}${c}`),h=await Lo(l,r);if(h!==null)return h}try{let s=Ir(n,"package.json");if(vs(s)){let c=(await import(s))[t];if(c&&typeof c==="object"&&!Array.isArray(c))try{return Ye(r,c)}catch{}}}catch{}return r}function Mo(t,i={}){let r=Yr.cwd();while(r.includes("storage"))r=os(r,"..");let n=os(r,t||"");if(i?.relative)return ph(Yr.cwd(),n);return n}async function zo(){try{let t=await Zo({name:"clarity",defaultConfig:Jr,cwd:Yr.cwd(),endpoint:"",headers:{}});return{...Jr,...t}}catch{return Jr}}function q(){if(Gt.env.NODE_ENV==="test"||Gt.env.BUN_ENV==="test")return!1;return typeof window<"u"}async function Go(){if(Gt.env.NODE_ENV==="test"||Gt.env.BUN_ENV==="test")return!0;if(typeof navigator<"u"&&navigator.product==="ReactNative")return!0;if(typeof Gt<"u"){let t=Gt.type;if(t==="renderer"||t==="worker")return!1;return!!(Gt.versions&&(Gt.versions.node||Gt.versions.bun))}return!1}class il{async format(t){let i=await Go(),r=await this.getMetadata(i);return JSON.stringify({timestamp:t.timestamp.toISOString(),level:t.level,name:t.name,message:t.message,metadata:r})}async getMetadata(t){if(t){let{hostname:i}=await import("os");return{pid:wi.pid,hostname:i(),environment:wi.env.NODE_ENV||"development",platform:wi.platform,version:wi.version}}return{userAgent:navigator.userAgent,hostname:window.location.hostname||"browser",environment:wi.env.NODE_ENV||wi.env.BUN_ENV||"development",viewport:{width:window.innerWidth,height:window.innerHeight},language:navigator.language}}}class Zr{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(t,i={}){this.name=t,this.config={...Ae},this.options=this.normalizeOptions(i),this.formatter=this.options.formatter||new il,this.enabled=i.enabled??!0,this.fancy=i.fancy??!0,this.tagFormat=i.tagFormat??{prefix:"[",suffix:"]"},this.timestampPosition=i.timestampPosition??"right",this.environment=i.environment??rt.env.APP_ENV??"local",this.fingersCrossedConfig=this.initializeFingersCrossedConfig(i);let r={...i},n=i.timestamp!==void 0;if(n)delete r.timestamp;if(this.config={...this.config,...r,timestamp:n||this.config.timestamp},this.currentLogFile=this.generateLogFilename(),this.encryptionKeys=new Map,this.validateEncryptionConfig()){this.setupRotation();let e=this.generateKeyId(),f=this.generateKey();this.currentKeyId=e,this.keys.set(e,f),this.encryptionKeys.set(e,{key:f,createdAt:new Date}),this.setupKeyRotation()}}initializeFingersCrossedConfig(t){if(!t.fingersCrossedEnabled&&t.fingersCrossed)return{...Nr,...t.fingersCrossed};if(!t.fingersCrossedEnabled)return null;if(!t.fingersCrossed)return{...Nr};return{...Nr,...t.fingersCrossed}}normalizeOptions(t){let i={format:"json",level:"info",logDirectory:Ae.logDirectory,rotation:void 0,timestamp:void 0,fingersCrossed:{},enabled:!0,showTags:!1,formatter:void 0},r={...i,...Object.fromEntries(Object.entries(t).filter(([,n])=>n!==void 0))};if(!r.level||!["debug","info","success","warning","error"].includes(r.level))r.level=i.level;return r}async writeToFile(t){let i=(async()=>{let n,e=0,f=3,s=1000;while(e<f)try{try{try{await to(this.config.logDirectory,ys.F_OK|ys.W_OK)}catch(l){if(l instanceof Error&&"code"in l)if(l.code==="ENOENT")await io(this.config.logDirectory,{recursive:!0,mode:493});else if(l.code==="EACCES")throw Error(`No write permission for log directory: ${this.config.logDirectory}`);else throw l;else throw l}}catch(l){throw console.error("Debug: [writeToFile] Failed to create log directory:",l),l}let c=this.validateEncryptionConfig()?(await this.encrypt(t)).encrypted:ti.from(t);try{if(!Qn(this.currentLogFile))await te(this.currentLogFile,"",{mode:420});if(n=$s(this.currentLogFile,"a",420),Qh(n,c,{flag:"a"}),as(n),n!==void 0)Xn(n),n=void 0;if((await $i(this.currentLogFile)).size===0){if(await te(this.currentLogFile,c,{flag:"w",mode:420}),(await $i(this.currentLogFile)).size===0)throw Error("File exists but is empty after retry write")}return}catch(l){let h=l;if(h.code&&["ENETDOWN","ENETUNREACH","ENOTFOUND","ETIMEDOUT"].includes(h.code)){if(e<f-1){let o=typeof h.message==="string"?h.message:"Unknown error";console.error(`Network error during write attempt ${e+1}/${f}:`,o);let u=s*2**e;await new Promise(($)=>setTimeout($,u)),e++;continue}}if(h?.code&&["ENOSPC","EDQUOT"].includes(h.code))throw Error(`Disk quota exceeded or no space left on device: ${h.message}`);throw console.error("Debug: [writeToFile] Error writing to file:",h),h}finally{if(n!==void 0)try{Xn(n)}catch(l){console.error("Debug: [writeToFile] Error closing file descriptor:",l)}}}catch(c){if(e===f-1){let h=c,o=typeof h.message==="string"?h.message:"Unknown error";throw console.error("Debug: [writeToFile] Max retries reached. Final error:",o),c}e++;let l=s*2**(e-1);await new Promise((h)=>setTimeout(h,l))}})();this.pendingOperations.push(i);let r=this.pendingOperations.length-1;try{await i}catch(n){throw console.error("Debug: [writeToFile] Error in operation:",n),n}finally{this.pendingOperations.splice(r,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 yi(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 yi(this.config.logDirectory,`${this.name}.log`);let t=new Date().toISOString().split("T")[0];return yi(this.config.logDirectory,`${this.name}-${t}.log`)}setupRotation(){if(q())return;if(typeof this.config.rotation==="boolean")return;let t=this.config.rotation,i;switch(t.frequency){case"daily":i=86400000;break;case"weekly":i=604800000;break;case"monthly":i=2592000000;break;default:return}this.rotationTimeout=setInterval(()=>{this.rotateLog()},i)}setupKeyRotation(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation setup");return}let t=this.config.rotation.keyRotation;if(!t?.enabled)return;let i=typeof t.interval==="number"?t.interval:60,r=Math.max(i,60)*1000;this.keyRotationTimeout=setInterval(()=>{this.rotateKeys().catch((n)=>{console.error("Error rotating keys:",n)})},r)}async rotateKeys(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation");return}let t=this.config.rotation.keyRotation,i=this.generateKeyId(),r=this.generateKey();this.currentKeyId=i,this.keys.set(i,r),this.encryptionKeys.set(i,{key:r,createdAt:new Date});let n=Array.from(this.encryptionKeys.entries()).sort(([,s],[,c])=>c.createdAt.getTime()-s.createdAt.getTime()),e=typeof t.maxKeys==="number"?t.maxKeys:1,f=Math.max(1,e);if(n.length>f)for(let[s]of n.slice(f))this.encryptionKeys.delete(s),this.keys.delete(s)}generateKeyId(){return vn(16).toString("hex")}generateKey(){return vn(32)}getCurrentKey(){if(!this.currentKeyId)throw Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");let t=this.keys.get(this.currentKeyId);if(!t)throw Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);return{key:t,id:this.currentKeyId}}encrypt(t){let{key:i}=this.getCurrentKey(),r=vn(16),n=Ph("aes-256-gcm",i,r),e=ti.concat([n.update(t,"utf8"),n.final()]),f=n.getAuthTag();return{encrypted:ti.concat([r,e,f]),iv:r}}async compressData(t){return new Promise((i,r)=>{let n=ms(),e=[];n.on("data",(f)=>e.push(f)),n.on("end",()=>i(ti.from(ti.concat(e)))),n.on("error",r),n.write(t),n.end()})}getEncryptionOptions(){if(!this.config.rotation||typeof this.config.rotation==="boolean"||!this.config.rotation.encrypt)return{};let t={algorithm:"aes-256-cbc",compress:!1};if(typeof this.config.rotation.encrypt==="object"){let i=this.config.rotation.encrypt;return{...t,...i}}return t}async rotateLog(){if(q())return;let t=await $i(this.currentLogFile).catch(()=>null);if(!t)return;let i=this.config.rotation;if(typeof i==="boolean")return;if(i.maxSize&&t.size>=i.maxSize){let r=this.currentLogFile,n=this.generateLogFilename();if(this.name.includes("rotation-load-test")||this.name==="failed-rotation-test"){let e=await $r(this.config.logDirectory),f=e.filter((l)=>l.startsWith(this.name)&&/\.log\.\d+$/.test(l)).sort((l,h)=>{let o=Number.parseInt(l.match(/\.log\.(\d+)$/)?.[1]||"0");return Number.parseInt(h.match(/\.log\.(\d+)$/)?.[1]||"0")-o}),s=f.length>0?Number.parseInt(f[0].match(/\.log\.(\d+)$/)?.[1]||"0")+1:1,c=`${r}.${s}`;if(await $i(r).catch(()=>null))try{if(await ws(r,c),i.compress)try{let l=`${c}.gz`;await this.compressLogFile(c,l),await yr(c)}catch(l){console.error("Error compressing rotated file:",l)}if(f.length===0&&!e.some((l)=>l.endsWith(".log.1")))try{let l=`${r}.1`;await te(l,"")}catch(l){console.error("Error creating backup file:",l)}}catch(l){console.error(`Error during rotation: ${l instanceof Error?l.message:String(l)}`)}}else{let e=new Date().toISOString().replace(/[:.]/g,"-"),f=r.replace(/\.log$/,`-${e}.log`);if(await $i(r).catch(()=>null))await ws(r,f)}if(this.currentLogFile=n,i.maxFiles){let e=(await $r(this.config.logDirectory)).filter((f)=>f.startsWith(this.name)).sort((f,s)=>s.localeCompare(f));for(let f of e.slice(i.maxFiles))await yr(yi(this.config.logDirectory,f))}}}async compressLogFile(t,i){let r=us(t),n=Xh(i),e=ms();await ro(r,e,n)}async handleFingersCrossedBuffer(t,i){if(!this.fingersCrossedConfig)return;if(this.shouldActivateFingersCrossed(t)&&!this.isActivated){this.isActivated=!0;for(let r of this.logBuffer){let n=await this.formatter.format(r);await this.writeToFile(n),console.log(n)}if(this.fingersCrossedConfig.stopBuffering)this.logBuffer=[]}if(this.isActivated)await this.writeToFile(i),console.log(i);else{if(this.logBuffer.length>=this.fingersCrossedConfig.bufferSize)this.logBuffer.shift();let r={timestamp:new Date,level:t,message:i,name:this.name};this.logBuffer.push(r)}}shouldActivateFingersCrossed(t){if(!this.fingersCrossedConfig)return!1;return this.getLevelValue(t)>=this.getLevelValue(this.fingersCrossedConfig.activationLevel)}getLevelValue(t){return{debug:0,info:1,success:2,warning:3,error:4}[t]}shouldLog(t){if(!this.enabled)return!1;let i={debug:0,info:1,success:2,warning:3,error:4};return i[t]>=i[this.config.level]}async flushPendingWrites(){if(await Promise.all(this.pendingOperations.map((t)=>{if(t instanceof Promise)return t.catch((i)=>{console.error("Error in pending write operation:",i)});return Promise.resolve()})),Qn(this.currentLogFile))try{let t=$s(this.currentLogFile,"r+");as(t),Xn(t)}catch(t){console.error(`Error flushing file: ${t}`)}}async destroy(){if(this.rotationTimeout)clearInterval(this.rotationTimeout);if(this.keyRotationTimeout)clearInterval(this.keyRotationTimeout);this.timers.clear();for(let t of this.pendingOperations)if(typeof t.cancel==="function")t.cancel();return(async()=>{if(this.pendingOperations.length>0)try{await Promise.allSettled(this.pendingOperations)}catch(t){console.error("Error waiting for pending operations:",t)}if(!q()&&this.config.rotation&&typeof this.config.rotation!=="boolean"&&this.config.rotation.compress)try{let t=(await $r(this.config.logDirectory)).filter((i)=>(i.includes("temp")||i.includes(".tmp"))&&i.includes(this.name));for(let i of t)try{await yr(yi(this.config.logDirectory,i))}catch(r){console.error(`Failed to delete temp file ${i}:`,r)}}catch(t){console.error("Error cleaning up temporary files:",t)}})()}getCurrentLogFilePath(){return this.currentLogFile}formatTag(t){if(!t)return"";return`${this.tagFormat.prefix}${t}${this.tagFormat.suffix}`}formatFileTimestamp(t){return`[${t.toISOString()}]`}formatConsoleTimestamp(t){return this.fancy?L.gray(t.toLocaleTimeString()):t.toLocaleTimeString()}formatConsoleMessage(t){let{timestamp:i,icon:r="",tag:n="",message:e,level:f,showTimestamp:s=!0}=t,c=(a)=>a.replace(this.ANSI_PATTERN,"");if(!this.fancy){let a=[];if(s)a.push(i);if(f==="warning")a.push("WARN");else if(f==="error")a.push("ERROR");else if(r)a.push(r.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu,""));if(n)a.push(n.replace(/[[\]]/g,""));return a.push(e),a.join(" ")}let l=rt.stdout.columns||120,h="";if(f==="warning"||f==="error")h=`${r} ${e}`;else if(f==="info"||f==="success")h=`${r} ${n} ${e}`;else h=`${r} ${n} ${L.cyan(e)}`;if(!s)return h.trim();let o=c(h).trim().length,u=c(i).length,$=Math.max(1,l-2-o-u);return`${h.trim()}${" ".repeat($)}${i}`}formatMessage(t,i){if(i.length===1&&Array.isArray(i[0]))return t.replace(/\{(\d+)\}/g,(f,s)=>{let c=Number.parseInt(s,10);return c<i[0].length?String(i[0][c]):f});let r=/%([sdijfo%])/g,n=0,e=t.replace(r,(f,s)=>{if(s==="%")return"%";if(n>=i.length)return f;let c=i[n++];switch(s){case"s":return String(c);case"d":case"i":return Number(c).toString();case"j":case"o":return JSON.stringify(c,null,2);default:return f}});if(n<i.length)e+=` ${i.slice(n).map((f)=>typeof f==="object"?JSON.stringify(f,null,2):String(f)).join(" ")}`;return e}async log(t,i,...r){let n=new Date,e=this.formatConsoleTimestamp(n),f=this.formatFileTimestamp(n),s,c;if(i instanceof Error)s=i.message,c=i.stack;else s=this.formatMessage(i,r);if(this.fancy&&!q()){let h=ul[t],o=this.options.showTags!==!1&&this.name?L.gray(this.formatTag(this.name)):"",u;switch(t){case"debug":u=this.formatConsoleMessage({timestamp:e,icon:h,tag:o,message:L.gray(s),level:t}),console.error(u);break;case"info":u=this.formatConsoleMessage({timestamp:e,icon:h,tag:o,message:s,level:t}),console.error(u);break;case"success":u=this.formatConsoleMessage({timestamp:e,icon:h,tag:o,message:L.green(s),level:t}),console.error(u);break;case"warning":u=this.formatConsoleMessage({timestamp:e,icon:h,tag:o,message:s,level:t}),console.warn(u);break;case"error":if(u=this.formatConsoleMessage({timestamp:e,icon:h,tag:o,message:s,level:t}),console.error(u),c){let $=c.split(`
2
2
  `);for(let a of $)if(a.trim()&&!a.includes(s))console.error(this.formatConsoleMessage({timestamp:e,message:L.gray(` ${a}`),level:t,showTimestamp:!1}))}break}}else if(!q()){if(console.error(`${f} ${this.environment}.${t.toUpperCase()}: ${s}`),c)console.error(c)}if(!this.shouldLog(t))return;let l=`${f} ${this.environment}.${t.toUpperCase()}: ${s}
3
3
  `;if(c)l+=`${c}
4
4
  `;l=l.replace(this.ANSI_PATTERN,""),await this.writeToFile(l)}time(t){let i=performance.now();if(this.fancy&&!q()){let r=this.options.showTags!==!1&&this.name?L.gray(this.formatTag(this.name)):"",n=this.formatConsoleTimestamp(new Date);console.error(this.formatConsoleMessage({timestamp:n,icon:L.blue("◐"),tag:r,message:`${L.cyan(t)}...`}))}return async(r)=>{if(!this.enabled)return;let n=performance.now(),e=Math.round(n-i),f=`${t} completed in ${e}ms`,s=new Date,c=this.formatConsoleTimestamp(s),l=`${this.formatFileTimestamp(s)} ${this.environment}.INFO: ${f}`;if(r)l+=` ${JSON.stringify(r)}`;if(l+=`
@@ -152,5 +152,5 @@ Write-Host "Root CA trusted successfully!"
152
152
  `,"utf8")}async function Xf(t){await li.rm(vf(t),{force:!0})}function Wh(t){let i=t.trim().toLowerCase().replace(/\.$/,"");if(!i||i.includes("127.0.0.1"))return null;if(i==="localhost"||i.endsWith(".localhost"))return null;if(/^\d{1,3}(\.\d{1,3}){3}$/.test(i))return null;return i}function lw(t){let i=Wh(t);if(!i)return null;let r=i.split(".");if(r.length<2)return null;return r.slice(-2).join(".")}function Qf(t){let i=new Set;for(let r of t){let n=lw(r);if(n)i.add(n)}return Array.from(i).sort()}function ts(t){let i=new Set;for(let r of t){let n=Wh(r);if(n)i.add(n)}return Array.from(i).sort()}var is=15353,hw="# managed-by: rpx",Oh="/etc/resolver",wt=null,Dn=new Set;function ow(t){return{id:t.readUInt16BE(0),flags:t.readUInt16BE(2),qdcount:t.readUInt16BE(4),ancount:t.readUInt16BE(6),nscount:t.readUInt16BE(8),arcount:t.readUInt16BE(10)}}function Hh(t,i){let r=[],n=i;while(!0){let e=t[n];if(e===0){n++;break}if((e&192)===192){let f=t.readUInt16BE(n)&16383,{name:s}=Hh(t,f);r.push(s),n+=2;break}n++,r.push(t.subarray(n,n+e).toString("ascii")),n+=e}return{name:r.join("."),newOffset:n}}function uw(t,i){let{name:r,newOffset:n}=Hh(t,i),e=t.readUInt16BE(n),f=t.readUInt16BE(n+2);return{question:{name:r,type:e,class:f},newOffset:n+4}}function bn(t){let i=t.split("."),r=[];for(let n of i)r.push(Buffer.from([n.length])),r.push(Buffer.from(n,"ascii"));return r.push(Buffer.from([0])),Buffer.concat(r)}function aw(t,i,r){let n=[],e=Buffer.alloc(12);e.writeUInt16BE(t,0),e.writeUInt16BE(33152,2),e.writeUInt16BE(1,4),e.writeUInt16BE(1,6),e.writeUInt16BE(0,8),e.writeUInt16BE(0,10),n.push(e),n.push(bn(i.name));let f=Buffer.alloc(4);f.writeUInt16BE(i.type,0),f.writeUInt16BE(i.class,2),n.push(f),n.push(bn(i.name));let s=Buffer.alloc(10);if(s.writeUInt16BE(i.type,0),s.writeUInt16BE(1,2),s.writeUInt32BE(300,4),i.type===1){s.writeUInt16BE(4,8),n.push(s);let c=r.split(".").map((l)=>Number.parseInt(l,10));n.push(Buffer.from(c))}else if(i.type===28)s.writeUInt16BE(16,8),n.push(s),n.push(Buffer.from([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]));else return e.writeUInt16BE(33155,2),e.writeUInt16BE(0,6),Buffer.concat([e,bn(i.name),f]);return Buffer.concat(n)}function $w(t,i){let r=[],n=Buffer.alloc(12);n.writeUInt16BE(t,0),n.writeUInt16BE(33155,2),n.writeUInt16BE(1,4),n.writeUInt16BE(0,6),n.writeUInt16BE(0,8),n.writeUInt16BE(0,10),r.push(n),r.push(bn(i.name));let e=Buffer.alloc(4);return e.writeUInt16BE(i.type,0),e.writeUInt16BE(i.class,2),r.push(e),Buffer.concat(r)}async function yw(t,i){if(Qt.platform!=="darwin")return!1;let r=ts(t);if(r.length===0)return!1;if(wt){for(let n of r)Dn.add(n);return w("dns","DNS server already running — merged domains",i),!0}return Dn=new Set(r),new Promise((n)=>{wt=cw.createSocket("udp4"),wt.on("error",(e)=>{w("dns",`DNS server error: ${e.message}`,i),wt?.close(),wt=null,n(!1)}),wt.on("message",(e,f)=>{try{let s=ow(e),{question:c}=uw(e,12);w("dns",`Query for ${c.name} type ${c.type} from ${f.address}`,i);let l=c.name.toLowerCase(),h=!1;for(let u of Dn)if(l===u||l.endsWith(`.${u}`)){h=!0;break}let o;if(h&&(c.type===1||c.type===28))o=aw(s.id,c,"127.0.0.1"),w("dns",`Responding with localhost for ${c.name}`,i);else o=$w(s.id,c),w("dns",`NXDOMAIN for ${c.name}`,i);wt?.send(o,f.port,f.address)}catch(s){w("dns",`Error processing DNS query: ${s}`,i)}}),wt.on("listening",()=>{let e=wt?.address();w("dns",`DNS server listening on ${e?.address}:${e?.port}`,i),n(!0)});try{wt.bind(is,"127.0.0.1")}catch(e){w("dns",`Failed to bind DNS server: ${e}`,i),n(!1)}})}function Lh(t){if(wt)w("dns","Stopping DNS server",t),wt.close(),wt=null,Dn=new Set}function z1(){return wt!==null}function ww(){return`${hw}
153
153
  nameserver 127.0.0.1
154
154
  port ${is}
155
- `}function ur(t){return Ih.join(Oh,t)}function mw(t){return t.includes("127.0.0.1")&&t.includes(String(is))}async function dw(t){try{return await Yh.readFile(ur(t),"utf8")}catch(i){if(i.code==="ENOENT")return null;throw i}}async function rs(t){if(Qt.platform!=="darwin")return;let{execSudoSync:i,getSudoPassword:r}=await import("./chunk-3yvvmvc0.js");if(!r()){w("dns","Cannot flush DNS cache without SUDO_PASSWORD",t);return}try{i("dscacheutil -flushcache"),i("killall -HUP mDNSResponder 2>/dev/null || true"),w("dns","DNS cache flushed",t)}catch(n){w("dns",`Could not flush DNS cache: ${n}`,t)}}async function Aw(t,i){let{execSudoSync:r}=await import("./chunk-3yvvmvc0.js"),n=ww().replace(/\n/g,"\\n"),e=`bash -c 'mkdir -p ${Oh} && printf "%b" "${n}" > ${ur(t)}'`;r(e),w("dns",`Created ${ur(t)}`,i)}async function Ew(t,i){let{execSudoSync:r}=await import("./chunk-3yvvmvc0.js");r(`rm -f ${ur(t)}`),w("dns",`Removed ${ur(t)}`,i)}async function G1(t,i){return Mh({domains:i??[],verbose:t})}async function Tw(t,i){if(Qt.platform!=="darwin")return!0;let{getSudoPassword:r}=await import("./chunk-3yvvmvc0.js");if(!r())return w("dns","SUDO_PASSWORD not set, cannot create resolver files",i),!1;try{for(let n of t)await Aw(n,i);return await rs(i),!0}catch(n){return w("dns",`Failed to create resolver file: ${n}`,i),!1}}async function ns(t,i){if(Qt.platform!=="darwin")return;let{getSudoPassword:r}=await import("./chunk-3yvvmvc0.js");if(!r())return;try{for(let n of t)await Ew(n,i);await rs(i)}catch(n){w("dns",`Failed to remove resolver files: ${n}`,i)}}async function Zh(t){if(Qt.platform!=="darwin")return[];let i=[];for(let r of Nh){let n=await dw(r);if(n&&mw(n))await ns([r],t),i.push(r)}return i}async function Mh(t){let i=t.rpxDir??yt(),r=ts(t.domains);if(r.length===0)return!1;let n=Qf(r);if(!await yw(r,t.verbose))return!1;if(!await Tw(n,t.verbose))return!1;let s={version:xn,resolvers:n,domains:r,ownerPid:t.ownerPid??Qt.pid,updatedAt:new Date().toISOString()};return await _h(i,s),!0}async function Vf(t,i={}){let r=t.map((l)=>l.to).filter(Boolean),n=i.rpxDir??yt(),e=Qf(r),c=((await kn(n))?.resolvers??[]).filter((l)=>!e.includes(l));if(c.length>0)await ns(c,i.verbose);if(e.length===0){Lh(i.verbose),await Xf(n);return}await Mh({domains:r,rpxDir:n,verbose:i.verbose,ownerPid:i.ownerPid??Qt.pid})}async function hr(t={}){let i=t.rpxDir??yt();Lh(t.verbose);let n=(await kn(i))?.resolvers??[];await ns(n,t.verbose),await Zh(t.verbose),await Xf(i)}async function q1(t){await hr({verbose:t})}async function or(t={}){let i=t.rpxDir??yt(),r=await kn(i),n=r?.ownerPid!=null&&Ht(r.ownerPid);if(r&&!n){w("dns",`reconcile: owner pid ${r.ownerPid} is gone — tearing down DNS`,t.verbose),await hr(t);return}let e=await Zh(t.verbose);if(e.length>0)w("dns",`reconcile: removed legacy TLD resolvers: ${e.join(", ")}`,t.verbose);await rs(t.verbose)}
155
+ `}function ur(t){return Ih.join(Oh,t)}function mw(t){return t.includes("127.0.0.1")&&t.includes(String(is))}async function dw(t){try{return await Yh.readFile(ur(t),"utf8")}catch(i){if(i.code==="ENOENT")return null;throw i}}async function rs(t){if(Qt.platform!=="darwin")return;let{execSudoSync:i,getSudoPassword:r}=await import("./chunk-747af2w4.js");if(!r()){w("dns","Cannot flush DNS cache without SUDO_PASSWORD",t);return}try{i("dscacheutil -flushcache"),i("killall -HUP mDNSResponder 2>/dev/null || true"),w("dns","DNS cache flushed",t)}catch(n){w("dns",`Could not flush DNS cache: ${n}`,t)}}async function Aw(t,i){let{execSudoSync:r}=await import("./chunk-747af2w4.js"),n=ww().replace(/\n/g,"\\n"),e=`bash -c 'mkdir -p ${Oh} && printf "%b" "${n}" > ${ur(t)}'`;r(e),w("dns",`Created ${ur(t)}`,i)}async function Ew(t,i){let{execSudoSync:r}=await import("./chunk-747af2w4.js");r(`rm -f ${ur(t)}`),w("dns",`Removed ${ur(t)}`,i)}async function G1(t,i){return Mh({domains:i??[],verbose:t})}async function Tw(t,i){if(Qt.platform!=="darwin")return!0;let{getSudoPassword:r}=await import("./chunk-747af2w4.js");if(!r())return w("dns","SUDO_PASSWORD not set, cannot create resolver files",i),!1;try{for(let n of t)await Aw(n,i);return await rs(i),!0}catch(n){return w("dns",`Failed to create resolver file: ${n}`,i),!1}}async function ns(t,i){if(Qt.platform!=="darwin")return;let{getSudoPassword:r}=await import("./chunk-747af2w4.js");if(!r())return;try{for(let n of t)await Ew(n,i);await rs(i)}catch(n){w("dns",`Failed to remove resolver files: ${n}`,i)}}async function Zh(t){if(Qt.platform!=="darwin")return[];let i=[];for(let r of Nh){let n=await dw(r);if(n&&mw(n))await ns([r],t),i.push(r)}return i}async function Mh(t){let i=t.rpxDir??yt(),r=ts(t.domains);if(r.length===0)return!1;let n=Qf(r);if(!await yw(r,t.verbose))return!1;if(!await Tw(n,t.verbose))return!1;let s={version:xn,resolvers:n,domains:r,ownerPid:t.ownerPid??Qt.pid,updatedAt:new Date().toISOString()};return await _h(i,s),!0}async function Vf(t,i={}){let r=t.map((l)=>l.to).filter(Boolean),n=i.rpxDir??yt(),e=Qf(r),c=((await kn(n))?.resolvers??[]).filter((l)=>!e.includes(l));if(c.length>0)await ns(c,i.verbose);if(e.length===0){Lh(i.verbose),await Xf(n);return}await Mh({domains:r,rpxDir:n,verbose:i.verbose,ownerPid:i.ownerPid??Qt.pid})}async function hr(t={}){let i=t.rpxDir??yt();Lh(t.verbose);let n=(await kn(i))?.resolvers??[];await ns(n,t.verbose),await Zh(t.verbose),await Xf(i)}async function q1(t){await hr({verbose:t})}async function or(t={}){let i=t.rpxDir??yt(),r=await kn(i),n=r?.ownerPid!=null&&Ht(r.ownerPid);if(r&&!n){w("dns",`reconcile: owner pid ${r.ownerPid} is gone — tearing down DNS`,t.verbose),await hr(t);return}let e=await Zh(t.verbose);if(e.length>0)w("dns",`reconcile: removed legacy TLD resolvers: ${e.join(", ")}`,t.verbose);await rs(t.verbose)}
156
156
  export{M as a,$h as b,yh as c,Zn as d,Oy as e,Hy as f,Ly as g,Zy as h,fi as i,oi as j,Hf as k,er as l,Lf as m,wh as n,Mn as o,fr as p,sr as q,Zf as r,Gf as s,f1 as t,s1 as u,l1 as v,Sh as w,ky as x,qf as y,Kf as z,c1 as A,Ch as B,Bh as C,Gi as D,kf as E,Ht as F,d1 as G,py as H,Py as I,zi as J,bf as K,Fh as L,xn as M,Nh as N,Wh as O,lw as P,Qf as Q,ts as R,is as S,hw as T,yw as U,Lh as V,z1 as W,ur as X,mw as Y,G1 as Z,Zh as _,Mh as $,Vf as aa,hr as ba,q1 as ca,or as da,yt as ea,pf as fa,cr as ga,Qy as ha,tw as ia,lr as ja,J1 as ka,ew as la,N1 as ma,j1 as na,_1 as oa};
@@ -45,5 +45,5 @@ export type ConfigOf = Config
45
45
  `),H=Math.max(...J.map((z)=>z.length))+2,q=`┌${"─".repeat(H)}┐`,_=`└${"─".repeat(H)}┘`,A=J.map((z)=>{return this.formatConsoleMessage({timestamp:X,message:K.cyan(z),showTimestamp:!1})});console.error(this.formatConsoleMessage({timestamp:X,message:K.cyan(q),showTimestamp:!1})),A.forEach((z)=>console.error(z)),console.error(this.formatConsoleMessage({timestamp:X,message:K.cyan(_),showTimestamp:!1}))}else if(!O())console.error(`${Z} ${this.environment}.INFO: [BOX] ${Y}`);let G=`${Z} ${this.environment}.INFO: [BOX] ${Y}
46
46
  `.replace(this.ANSI_PATTERN,"");if(this.shouldWriteToFile())await this.writeToFile(G)}async prompt(Q){if(O())return Promise.resolve(!0);return new Promise((U)=>{console.error(`${K.cyan("?")} ${Q} (y/n) `);let X=(Z)=>{let $=Z.toString().trim().toLowerCase();L.stdin.removeListener("data",X);try{if(typeof L.stdin.setRawMode==="function")L.stdin.setRawMode(!1)}catch{}L.stdin.pause(),console.error(""),U($==="y"||$==="yes")};try{if(typeof L.stdin.setRawMode==="function")L.stdin.setRawMode(!0)}catch{}L.stdin.resume(),L.stdin.once("data",X)})}setFancy(Q){this.fancy=Q}isFancy(){return this.fancy}pause(){this.enabled=!1}resume(){this.enabled=!0}async start(Q,...U){if(!this.enabled)return;let X=Q;if(U&&U.length>0){let H=/%([sdijfo%])/g,q=0;if(X=Q.replace(H,(_,A)=>{if(A==="%")return"%";if(q>=U.length)return _;let z=U[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 _}}),q<U.length)X+=` ${U.slice(q).map((_)=>typeof _==="object"?JSON.stringify(_,null,2):String(_)).join(" ")}`}let{consoleText:Z,fileText:$}=this.buildOutputTexts(X);if(this.shouldStyleConsole()){let H=this.options.showTags!==!1&&this.name?K.gray(this.formatTag(this.name)):"",q=this.options.showIcons===!1?"":`${K.blue("◐")} `;console.error(`${q}${H} ${K.cyan(Z)}`)}let J=`[${new Date().toISOString()}] ${this.environment}.INFO: [START] ${$}
47
47
  `.replace(this.ANSI_PATTERN,"");if(this.shouldWriteToFile())await this.writeToFile(J)}renderProgressBar(Q,U=!1){if(!this.enabled||!this.shouldStyleConsole()||!L.stdout.isTTY)return;let X=Math.min(100,Math.max(0,Math.round(Q.current/Q.total*100))),Z=Math.round(Q.barLength*X/100),$=Q.barLength-Z,Y=K.green("━".repeat(Z)),G=K.gray("━".repeat($)),J=`[${Y}${G}]`,H=`${X}%`.padStart(4),q=Q.message?` ${Q.message}`:"",_=this.options.showIcons===!1?"":U||X===100?K.green("✓"):K.blue("▶"),A=this.options.showTags!==!1&&this.name?` ${K.gray(this.formatTag(this.name))}`:"",z=`\r${_}${A} ${J} ${H}${q}`,W=L.stdout.columns||80,V=" ".repeat(Math.max(0,W-z.replace(this.ANSI_PATTERN,"").length));if(Q.lastRenderedLine=`${z}${V}`,L.stdout.write(Q.lastRenderedLine),U)L.stdout.write(`
48
- `)}finishProgressBar(Q,U){if(!this.enabled||!this.fancy||O()||!L.stdout.isTTY){this.activeProgressBar=null;return}if(Q.current<Q.total)Q.current=Q.total;if(U)Q.message=U;this.renderProgressBar(Q,!0),this.activeProgressBar=null}async clear(Q={}){if(O()){console.warn("Log clearing is not supported in browser environments.");return}try{console.warn("Clearing logs...",this.config.logDirectory);let U=await DQ(this.config.logDirectory),X=[];for(let Z of U){if(!(Q.name?new RegExp(Q.name.replace("*",".*")).test(Z):Z.startsWith(this.name))||!Z.endsWith(".log"))continue;let Y=GQ(this.config.logDirectory,Z);if(Q.before)try{if((await YQ(Y)).mtime>=Q.before)continue}catch(G){console.error(`Failed to get stats for file ${Y}:`,G);continue}X.push(Y)}if(X.length===0){console.warn("No log files matched the criteria for clearing.");return}console.warn(`Preparing to delete ${X.length} log file(s)...`);for(let Z of X)try{await NQ(Z),console.warn(`Deleted log file: ${Z}`)}catch($){console.error(`Failed to delete log file ${Z}:`,$)}console.warn("Log clearing process finished.")}catch(U){console.error("Error during log clearing process:",U)}}}var A8=new BQ("stacks");var h0=new BQ("rpx",{showTags:!1});function d0(){return process.env.SUDO_PASSWORD}function R8(Q){let U=d0(),X=Q.replace(/'/g,"'\\''");if(U)return PX(`echo '${U}' | sudo -S sh -c '${X}' 2>/dev/null`,{encoding:"utf-8",stdio:["pipe","pipe","pipe"]});return PX(`sudo sh -c '${X}'`,{encoding:"utf-8"})}function bX(Q,U,X){if(X)h0.debug(`[rpx:${Q}] ${U}`)}var yX="[redacted]",f0=new Set(["certificate","privatekey","key","cert","ca","rootca","password","sudo_password"]),p0=/-----BEGIN [A-Z ]+-----[\s\S]*?-----END [A-Z ]+-----/;function u0(Q){let U=Q.toLowerCase();return f0.has(U)||U.endsWith("password")||U.includes("secret")||U.includes("token")}function EU(Q){if(Array.isArray(Q))return Q.map((X)=>EU(X));if(typeof Q==="string")return p0.test(Q)?yX:Q;if(!Q||typeof Q!=="object")return Q;let U={};for(let[X,Z]of Object.entries(Q)){if(u0(X)){U[X]=yX;continue}U[X]=EU(Z)}return U}function L8(Q,U){return JSON.stringify(EU(Q),null,U)}function w8(Q){if(hX(Q))return Q.proxies.map((U)=>{let X=U.to||"stacks.localhost";return X.startsWith("http")?new URL(X).hostname:X});if(dX(Q)){let U=Q.to||"stacks.localhost";return[U.startsWith("http")?new URL(U).hostname:U]}return["stacks.localhost"]}function K8(Q){return typeof Q==="object"&&Q!==null&&"certificate"in Q&&"privateKey"in Q&&typeof Q.certificate==="string"&&typeof Q.privateKey==="string"}function j8(Q){if(!Q)return"stacks.localhost";if(hX(Q)&&Q.proxies.length>0)return Q.proxies[0].to||"stacks.localhost";if(dX(Q))return Q.to||"stacks.localhost";return"stacks.localhost"}function F8(Q){return!!(Q&&("proxies"in Q)&&Array.isArray(Q.proxies))}function hX(Q){return"proxies"in Q&&Array.isArray(Q.proxies)}function dX(Q){return"to"in Q&&typeof Q.to==="string"}function I8(Q){return!!(Q&&("to"in Q)&&!("proxies"in Q))}function M8(Q,U){if(!U||U.length===0)return null;for(let X of U)if(Q===X.from||Q.startsWith(`${X.from}/`)){let Z=X.to.startsWith("http")?new URL(X.to).host:X.to,$=X.stripPrefix===!0?Q.slice(X.from.length)||"/":Q;return{targetHost:Z,targetPath:$}}return null}async function V8(Q,U){try{await vX.unlink(Q),bX("certificates",`Successfully deleted: ${Q}`,U)}catch(X){if(X.code!=="ENOENT")bX("certificates",`Warning: Could not delete ${Q}: ${X}`,U)}}
48
+ `)}finishProgressBar(Q,U){if(!this.enabled||!this.fancy||O()||!L.stdout.isTTY){this.activeProgressBar=null;return}if(Q.current<Q.total)Q.current=Q.total;if(U)Q.message=U;this.renderProgressBar(Q,!0),this.activeProgressBar=null}async clear(Q={}){if(O()){console.warn("Log clearing is not supported in browser environments.");return}try{console.warn("Clearing logs...",this.config.logDirectory);let U=await DQ(this.config.logDirectory),X=[];for(let Z of U){if(!(Q.name?new RegExp(Q.name.replace("*",".*")).test(Z):Z.startsWith(this.name))||!Z.endsWith(".log"))continue;let Y=GQ(this.config.logDirectory,Z);if(Q.before)try{if((await YQ(Y)).mtime>=Q.before)continue}catch(G){console.error(`Failed to get stats for file ${Y}:`,G);continue}X.push(Y)}if(X.length===0){console.warn("No log files matched the criteria for clearing.");return}console.warn(`Preparing to delete ${X.length} log file(s)...`);for(let Z of X)try{await NQ(Z),console.warn(`Deleted log file: ${Z}`)}catch($){console.error(`Failed to delete log file ${Z}:`,$)}console.warn("Log clearing process finished.")}catch(U){console.error("Error during log clearing process:",U)}}}var A8=new BQ("stacks");var h0=new BQ("rpx",{showTags:!1});function d0(){return process.env.SUDO_PASSWORD}function R8(Q){let U=d0(),X=Q.replace(/'/g,"'\\''");if(U)return PX(`echo '${U}' | sudo -S sh -c '${X}' 2>/dev/null`,{encoding:"utf-8",stdio:["pipe","pipe","pipe"]});try{return PX(`sudo -n sh -c '${X}'`,{encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{throw Error("sudo required but no cached credentials (set SUDO_PASSWORD in .env or run sudo -v)")}}function bX(Q,U,X){if(X)h0.debug(`[rpx:${Q}] ${U}`)}var yX="[redacted]",f0=new Set(["certificate","privatekey","key","cert","ca","rootca","password","sudo_password"]),p0=/-----BEGIN [A-Z ]+-----[\s\S]*?-----END [A-Z ]+-----/;function u0(Q){let U=Q.toLowerCase();return f0.has(U)||U.endsWith("password")||U.includes("secret")||U.includes("token")}function EU(Q){if(Array.isArray(Q))return Q.map((X)=>EU(X));if(typeof Q==="string")return p0.test(Q)?yX:Q;if(!Q||typeof Q!=="object")return Q;let U={};for(let[X,Z]of Object.entries(Q)){if(u0(X)){U[X]=yX;continue}U[X]=EU(Z)}return U}function L8(Q,U){return JSON.stringify(EU(Q),null,U)}function w8(Q){if(hX(Q))return Q.proxies.map((U)=>{let X=U.to||"stacks.localhost";return X.startsWith("http")?new URL(X).hostname:X});if(dX(Q)){let U=Q.to||"stacks.localhost";return[U.startsWith("http")?new URL(U).hostname:U]}return["stacks.localhost"]}function K8(Q){return typeof Q==="object"&&Q!==null&&"certificate"in Q&&"privateKey"in Q&&typeof Q.certificate==="string"&&typeof Q.privateKey==="string"}function j8(Q){if(!Q)return"stacks.localhost";if(hX(Q)&&Q.proxies.length>0)return Q.proxies[0].to||"stacks.localhost";if(dX(Q))return Q.to||"stacks.localhost";return"stacks.localhost"}function F8(Q){return!!(Q&&("proxies"in Q)&&Array.isArray(Q.proxies))}function hX(Q){return"proxies"in Q&&Array.isArray(Q.proxies)}function dX(Q){return"to"in Q&&typeof Q.to==="string"}function I8(Q){return!!(Q&&("to"in Q)&&!("proxies"in Q))}function M8(Q,U){if(!U||U.length===0)return null;for(let X of U)if(Q===X.from||Q.startsWith(`${X.from}/`)){let Z=X.to.startsWith("http")?new URL(X.to).host:X.to,$=X.stripPrefix===!0?Q.slice(X.from.length)||"/":Q;return{targetHost:Z,targetPath:$}}return null}async function V8(Q,U){try{await vX.unlink(Q),bX("certificates",`Successfully deleted: ${Q}`,U)}catch(X){if(X.code!=="ENOENT")bX("certificates",`Warning: Could not delete ${Q}: ${X}`,U)}}
49
49
  export{r as pa,d0 as qa,R8 as ra,bX as sa,EU as ta,L8 as ua,w8 as va,K8 as wa,j8 as xa,F8 as ya,hX as za,dX as Aa,I8 as Ba,M8 as Ca,V8 as Da};
package/dist/hosts.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ /** `.localhost` names resolve to loopback per RFC 6761 — no /etc/hosts entry needed. */
2
+ export declare function isLoopbackDevelopmentHost(host: string): boolean;
1
3
  export declare function addHosts(hosts: string[], verbose?: boolean): Promise<void>;
2
4
  export declare function removeHosts(hosts: string[], verbose?: boolean): Promise<void>;
3
5
  export declare function checkHosts(hosts: string[], verbose?: boolean): Promise<boolean[]>;
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- import{$ as PD,A as E_,B as AD,C as M_,D as Y_,E as $_,F as VD,G as G_,H as W_,I as RD,J as zD,K as ED,L as MD,M as SD,N as FD,O as TD,P as ID,Q as wD,R as HD,S as jD,T as kD,U as CD,V as qD,W as xD,X as UD,Y as fD,Z as yD,_ as OD,a as X,aa as LD,b as B_,ba as hD,c as g_,ca as cD,d as i_,da as uD,e as n_,ea as mD,f as t_,fa as vD,g as r_,ga as bD,h as s_,ha as lD,i as o_,ia as aD,j as e_,ja as dD,k as _D,ka as pD,l as DD,la as gD,m as BD,ma as X_,n as KD,na as iD,o as ND,oa as nD,p as YD,q as $D,r as GD,s as WD,t as XD,u as JD,v as QD,w as K_,x as ZD,y as c,z as N_}from"./chunk-ppbddztz.js";import{Aa as KB,Ba as NB,Ca as YB,Da as $B,pa as z_,qa as m,ra as r2,sa as K,ta as s2,ua as C,va as o2,wa as e2,xa as _B,ya as DB,za as BB}from"./chunk-97manwts.js";import{execSync as m_}from"node:child_process";import*as O from"node:http";import*as f_ from"node:http2";import*as y_ from"node:net";import*as F from"node:process";var n=(D,_)=>(B)=>`\x1B[${D}m${B}\x1B[${_}m`,j={bold:n(1,22),dim:n(2,22),green:n(32,39),cyan:n(36,39)};import*as H_ from"node:fs";import*as j_ from"node:path";import*as k from"node:process";function k_(D){let _=D.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,128);return _.length>0?_:"rpx"}async function t(D){if(D.proxies.length===0)throw Error("runViaDaemon: no proxies provided");let _=D.verbose??!1,B=D.registryDir,N=new Set,Y=D.proxies.map((R)=>{let G=R.id??k_(R.to);if(!$_(G))throw Error(`invalid registry id "${G}" derived from to="${R.to}"`);if(N.has(G))throw Error(`duplicate registry id "${G}" — set an explicit \`id\` on one of the proxies`);return N.add(G),{...R,id:G}}),W=new Date().toISOString();for(let R of Y)await G_({id:R.id,from:R.from,to:R.to,pid:D.persistent?void 0:k.pid,cwd:k.cwd(),createdAt:W,cleanUrls:R.cleanUrls,changeOrigin:R.changeOrigin,pathRewrites:R.pathRewrites},B,_);let $=await X_({rpxDir:D.rpxDir,verbose:_,spawnCommand:D.spawnCommand,startupTimeoutMs:D.startupTimeoutMs,spawnEnv:D.spawnEnv});for(let R of Y)X.success(`https://${R.to} → ${R.from}`);if(X.info(`(via rpx daemon pid=${$.pid}; \`rpx daemon:status\` to inspect)`),D.detached)return;let V=!1,J=B??Y_(),A=Y.map((R)=>R.id),T=async()=>{if(V)return;V=!0;for(let R of A)await W_(R,B,_).catch((G)=>{K("runner",`removeEntry(${R}) failed: ${G}`,_)})},I=(R)=>{K("runner",`received ${R}, unregistering ${A.length} entries`,_),T().finally(()=>k.exit(0))};k.once("SIGINT",I),k.once("SIGTERM",I),k.once("exit",()=>{if(V)return;for(let R of A)try{H_.unlinkSync(j_.join(J,`${R}.json`))}catch{}}),await new Promise(()=>{})}import{exec as L_}from"node:child_process";import f from"node:fs";import C_ from"node:os";import Q_ from"node:path";import*as v from"node:process";import{promisify as h_}from"node:util";var r=h_(L_),H=v.platform==="win32"?Q_.join(v.env.windir||"C:\\Windows","System32","drivers","etc","hosts"):"/etc/hosts",J_=!1;async function s(D){if(v.platform==="win32")throw Error("Administrator privileges required on Windows");let _=m(),B=D.replace(/'/g,"'\\''");try{if(_){let{stdout:Y}=await r(`echo '${_}' | sudo -S sh -c '${B}' 2>/dev/null`);return J_=!0,Y}if(J_)try{let{stdout:Y}=await r(`sudo -n sh -c '${B}'`);return Y}catch(Y){K("hosts","Cached sudo privileges expired, requesting again",!0)}let{stdout:N}=await r(`sudo sh -c '${B}'`);return J_=!0,N}catch(N){throw Error(`Failed to execute sudo command: ${N.message}`)}}async function L(D,_){K("hosts",`Adding hosts: ${D.join(", ")}`,_),K("hosts",`Using hosts file at: ${H}`,_);try{let B;try{B=await f.promises.readFile(H,"utf-8")}catch{K("hosts","Reading hosts file requires elevated permissions, using sudo",_);try{B=await s(`cat "${H}"`)}catch($){throw console.log(" Could not read hosts file — skipping hosts setup"),K("hosts",`sudo read also failed: ${$}`,_),Error(`Cannot read hosts file: ${$}`)}}let N=D.filter(($)=>{let V=`127.0.0.1 ${$}`,J=`::1 ${$}`;return!B.includes(V)&&!B.includes(J)});if(N.length===0){K("hosts","All hosts already exist in hosts file",_);return}let Y=N.map(($)=>`
1
+ import{$ as L2,A as z_,B as V2,C as M_,D as Y_,E as $_,F as R2,G as G_,H as W_,I as E2,J as z2,K as M2,L as S2,M as T2,N as F2,O as I2,P as w2,Q as j2,R as H2,S as k2,T as C2,U as q2,V as x2,W as U2,X as f2,Y as y2,Z as O2,_ as P2,a as J,aa as h2,b as B_,ba as c2,c as i_,ca as u2,d as n_,da as m2,e as t_,ea as v2,f as r_,fa as b2,g as s_,ga as l2,h as o_,ha as a2,i as e_,ia as d2,j as _2,ja as p2,k as D2,ka as g2,l as B2,la as i2,m as K2,ma as X_,n as N2,na as n2,o as Y2,oa as t2,p as $2,q as G2,r as W2,s as X2,t as J2,u as Q2,v as Z2,w as K_,x as A2,y as c,z as N_}from"./chunk-9dndasyk.js";import{Aa as NB,Ba as YB,Ca as $B,Da as GB,pa as E_,qa as m,ra as sD,sa as K,ta as oD,ua as C,va as eD,wa as _B,xa as DB,ya as BB,za as KB}from"./chunk-zs1tyy8z.js";import{execSync as v_}from"node:child_process";import*as O from"node:http";import*as y_ from"node:http2";import*as O_ from"node:net";import*as F from"node:process";var n=(D,_)=>(B)=>`\x1B[${D}m${B}\x1B[${_}m`,H={bold:n(1,22),dim:n(2,22),green:n(32,39),cyan:n(36,39)};import*as j_ from"node:fs";import*as H_ from"node:path";import*as k from"node:process";function k_(D){let _=D.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,128);return _.length>0?_:"rpx"}async function t(D){if(D.proxies.length===0)throw Error("runViaDaemon: no proxies provided");let _=D.verbose??!1,B=D.registryDir,N=new Set,Y=D.proxies.map((R)=>{let $=R.id??k_(R.to);if(!$_($))throw Error(`invalid registry id "${$}" derived from to="${R.to}"`);if(N.has($))throw Error(`duplicate registry id "${$}" — set an explicit \`id\` on one of the proxies`);return N.add($),{...R,id:$}}),W=new Date().toISOString();for(let R of Y)await G_({id:R.id,from:R.from,to:R.to,pid:D.persistent?void 0:k.pid,cwd:k.cwd(),createdAt:W,cleanUrls:R.cleanUrls,changeOrigin:R.changeOrigin,pathRewrites:R.pathRewrites},B,_);let G=await X_({rpxDir:D.rpxDir,verbose:_,spawnCommand:D.spawnCommand,startupTimeoutMs:D.startupTimeoutMs,spawnEnv:D.spawnEnv});for(let R of Y)J.success(`https://${R.to} → ${R.from}`);if(J.info(`(via rpx daemon pid=${G.pid}; \`rpx daemon:status\` to inspect)`),D.detached)return;let V=!1,X=B??Y_(),A=Y.map((R)=>R.id),T=async()=>{if(V)return;V=!0;for(let R of A)await W_(R,B,_).catch(($)=>{K("runner",`removeEntry(${R}) failed: ${$}`,_)})},I=(R)=>{K("runner",`received ${R}, unregistering ${A.length} entries`,_),T().finally(()=>k.exit(0))};k.once("SIGINT",I),k.once("SIGTERM",I),k.once("exit",()=>{if(V)return;for(let R of A)try{j_.unlinkSync(H_.join(X,`${R}.json`))}catch{}}),await new Promise(()=>{})}import{exec as h_}from"node:child_process";import f from"node:fs";import q_ from"node:os";import Q_ from"node:path";import*as v from"node:process";import{promisify as c_}from"node:util";var r=c_(h_);function C_(D){let _=D.trim().toLowerCase();return _==="localhost"||_.endsWith(".localhost")||_.endsWith(".localhost.")}var j=v.platform==="win32"?Q_.join(v.env.windir||"C:\\Windows","System32","drivers","etc","hosts"):"/etc/hosts",J_=!1;async function s(D){if(v.platform==="win32")throw Error("Administrator privileges required on Windows");let _=m(),B=D.replace(/'/g,"'\\''");try{if(_){let{stdout:N}=await r(`echo '${_}' | sudo -S sh -c '${B}' 2>/dev/null`);return J_=!0,N}if(J_)try{let{stdout:N}=await r(`sudo -n sh -c '${B}'`);return N}catch(N){K("hosts","Cached sudo privileges expired, requesting again",!0)}try{let{stdout:N}=await r(`sudo -n sh -c '${B}'`);return J_=!0,N}catch{throw Error("sudo required but no cached credentials (set SUDO_PASSWORD in .env or run sudo -v)")}}catch(N){throw Error(`Failed to execute sudo command: ${N.message}`)}}async function L(D,_){let B=D.filter((Y)=>!C_(Y)),N=D.filter((Y)=>C_(Y));if(N.length>0)K("hosts",`Skipping /etc/hosts for loopback dev names: ${N.join(", ")}`,_);if(B.length===0)return;K("hosts",`Adding hosts: ${B.join(", ")}`,_),K("hosts",`Using hosts file at: ${j}`,_);try{let Y;try{Y=await f.promises.readFile(j,"utf-8")}catch{K("hosts","Reading hosts file requires elevated permissions, using sudo",_);try{Y=await s(`cat "${j}"`)}catch(X){throw console.log(" Could not read hosts file — skipping hosts setup"),K("hosts",`sudo read also failed: ${X}`,_),Error(`Cannot read hosts file: ${X}`)}}let W=B.filter((X)=>{let A=`127.0.0.1 ${X}`,T=`::1 ${X}`;return!Y.includes(A)&&!Y.includes(T)});if(W.length===0){K("hosts","All hosts already exist in hosts file",_);return}let G=W.map((X)=>`
2
2
  # Added by rpx
3
- 127.0.0.1 ${$}
4
- ::1 ${$}`).join(`
5
- `),W=Q_.join(C_.tmpdir(),`rpx-hosts-${Date.now()}.tmp`);try{await f.promises.writeFile(W,B+Y,"utf8"),await s(`cat "${W}" | tee "${H}" > /dev/null`),console.log(` Hosts updated: ${N.join(", ")}`)}catch($){console.log(" Could not update hosts file automatically"),console.log(" Add these entries to /etc/hosts:"),N.forEach((V)=>{console.log(` 127.0.0.1 ${V}`),console.log(` ::1 ${V}`)}),console.log(` Or run: sudo nano ${H}`)}finally{try{await f.promises.unlink(W)}catch{}}}catch(B){K("hosts",`Failed to manage hosts file: ${B.message}`,_)}}async function Z_(D,_){K("hosts",`Removing hosts: ${D.join(", ")}`,_);try{let B;try{B=await f.promises.readFile(H,"utf-8")}catch{K("hosts","Reading hosts file requires elevated permissions, using sudo",_);try{B=await s(`cat "${H}"`)}catch(J){throw K("hosts",`sudo read also failed: ${J}`,_),Error(`Cannot read hosts file: ${J}`)}}let N=B.split(`
6
- `),Y=!1,W=N.filter((J)=>{if(D.some((T)=>J.includes(` ${T}`)&&(J.includes("127.0.0.1")||J.includes("::1"))))return Y=!0,!1;if(J.trim()==="# Added by rpx")return Y=!0,!1;return!0});if(!Y){K("hosts","No matching hosts found to remove",_);return}while(W[W.length-1]?.trim()==="")W.pop();let $=`${W.join(`
3
+ 127.0.0.1 ${X}
4
+ ::1 ${X}`).join(`
5
+ `),V=Q_.join(q_.tmpdir(),`rpx-hosts-${Date.now()}.tmp`);try{await f.promises.writeFile(V,Y+G,"utf8"),await s(`cat "${V}" | tee "${j}" > /dev/null`),console.log(` Hosts updated: ${W.join(", ")}`)}catch(X){console.log(" Could not update hosts file automatically"),console.log(" Add these entries to /etc/hosts:"),W.forEach((A)=>{console.log(` 127.0.0.1 ${A}`),console.log(` ::1 ${A}`)}),console.log(` Or run: sudo nano ${j}`)}finally{try{await f.promises.unlink(V)}catch{}}}catch(Y){K("hosts",`Failed to manage hosts file: ${Y.message}`,_)}}async function Z_(D,_){K("hosts",`Removing hosts: ${D.join(", ")}`,_);try{let B;try{B=await f.promises.readFile(j,"utf-8")}catch{K("hosts","Reading hosts file requires elevated permissions, using sudo",_);try{B=await s(`cat "${j}"`)}catch(X){throw K("hosts",`sudo read also failed: ${X}`,_),Error(`Cannot read hosts file: ${X}`)}}let N=B.split(`
6
+ `),Y=!1,W=N.filter((X)=>{if(D.some((T)=>X.includes(` ${T}`)&&(X.includes("127.0.0.1")||X.includes("::1"))))return Y=!0,!1;if(X.trim()==="# Added by rpx")return Y=!0,!1;return!0});if(!Y){K("hosts","No matching hosts found to remove",_);return}while(W[W.length-1]?.trim()==="")W.pop();let G=`${W.join(`
7
7
  `)}
8
- `,V=Q_.join(C_.tmpdir(),`rpx-hosts-${Date.now()}.tmp`);try{await f.promises.writeFile(V,$,"utf8"),await s(`cat "${V}" | tee "${H}" > /dev/null`),K("hosts","Hosts removed successfully",_)}catch(J){K("hosts","Could not clean up hosts file automatically",_)}finally{try{await f.promises.unlink(V)}catch(J){K("hosts",`Failed to remove temporary file: ${J}`,_)}}}catch(B){K("hosts",`Failed to clean up hosts file: ${B.message}`,_)}}async function h(D,_){K("hosts",`Checking hosts: ${D}`,_);let B;try{B=await f.promises.readFile(H,"utf-8")}catch(N){K("hosts",`Error reading hosts file: ${N}`,_);try{let Y=m(),W;if(Y)W=`echo '${Y}' | sudo -S cat "${H}" 2>/dev/null`;else W=`sudo -n cat "${H}" 2>/dev/null || cat "${H}" 2>/dev/null || echo ""`;let{stdout:$}=await r(W);B=$}catch(Y){return K("hosts",`Cannot read hosts file, assuming entries don't exist: ${Y}`,_),D.map(()=>!1)}}return D.map((N)=>{let Y=`127.0.0.1 ${N}`,W=`::1 ${N}`;return B.includes(Y)||B.includes(W)})}import*as o from"node:net";function x(D,_,B){return K("port",`Checking if port ${D} is in use on ${_}`,B),new Promise((N)=>{let Y=o.createServer(),W=setTimeout(()=>{K("port",`Checking port ${D} timed out, assuming it's in use`,B),Y.close(),N(!0)},3000);Y.once("error",($)=>{if(clearTimeout(W),$.code==="EADDRINUSE")K("port",`Port ${D} is in use`,B),N(!0);else K("port",`Error checking port ${D}: ${$.message}`,B),N(!0)}),Y.once("listening",()=>{clearTimeout(W),K("port",`Port ${D} is available`,B),Y.close(),N(!1)});try{Y.listen(D,_)}catch($){clearTimeout(W),K("port",`Exception checking port ${D}: ${$}`,B),N(!0)}})}async function x_(D,_,B,N=50){K("port",`Finding available port starting from ${D} (max attempts: ${N})`,B);let Y=D,W=0;while(W<N){if(W++,!await x(Y,_,B))return K("port",`Found available port: ${Y} after ${W} attempts`,B),Y;K("port",`Port ${Y} is in use, trying ${Y+1} (attempt ${W}/${N})`,B),Y++}throw Error(`Unable to find available port after ${N} attempts starting from ${D}`)}function q_(D,_,B=5000,N){return K("port",`Testing connection to ${_}:${D}`,N),new Promise((Y)=>{let W=o.connect({host:_,port:D,timeout:B});W.once("connect",()=>{K("port",`Successfully connected to ${_}:${D}`,N),W.end(),Y(!0)}),W.once("timeout",()=>{K("port",`Connection to ${_}:${D} timed out`,N),W.destroy(),Y(!1)}),W.once("error",($)=>{K("port",`Failed to connect to ${_}:${D}: ${$.message}`,N),W.destroy(),Y(!1)})})}class b{usedPorts=new Set;hostname;verbose;maxRetries;constructor(D="0.0.0.0",_,B=50){this.hostname=D,this.verbose=_,this.maxRetries=B}async getNextAvailablePort(D,_=!1){if(this.usedPorts.has(D))return this.findNextAvailablePort(D+1,_);if(await x(D,this.hostname,this.verbose))return this.findNextAvailablePort(D+1,_);if(_){if(!await q_(D,this.hostname,3000,this.verbose))return K("port",`Port ${D} is available but not connectable, trying next port`,this.verbose),this.findNextAvailablePort(D+1,_)}return this.usedPorts.add(D),D}async findNextAvailablePort(D,_=!1){let B=await x_(D,this.hostname,this.verbose,this.maxRetries);if(_){if(!await q_(B,this.hostname,3000,this.verbose))if(B<D+this.maxRetries)return this.findNextAvailablePort(B+1,_);else throw Error(`Unable to find a connectable port after ${this.maxRetries} attempts`)}return this.usedPorts.add(B),B}releasePort(D){K("port",`Releasing port ${D}`,this.verbose),this.usedPorts.delete(D)}}var c_=new b;import{spawn as u_}from"node:child_process";import*as y from"node:process";class e{processes=new Map;isShuttingDown=!1;async startProcess(D,_,B){if(this.processes.has(D)){K("start",`Process ${D} is already running`,B);return}let[N,...Y]=_.command.split(" "),W=_.cwd||y.cwd();K("start",`Starting process ${D}:`,B),K("start",` Command: ${N} ${Y.join(" ")}`,B),K("start",` Working directory: ${W}`,B),K("start",` Environment variables: ${C(_.env)}`,B);let $=u_(N,Y,{cwd:W,env:{...y.env,..._.env},shell:!0,stdio:"inherit"});return this.processes.set(D,{command:_.command,cwd:W,process:$,env:_.env}),new Promise((V,J)=>{if($.on("error",(A)=>{if(!this.isShuttingDown)K("start",`Process ${D} failed to start: ${A}`,B),this.processes.delete(D),J(A),y.emit("SIGINT")}),$.on("exit",(A)=>{if(!this.isShuttingDown&&A!==null&&A!==0)K("start",`Process ${D} exited with code ${A}`,B),this.processes.delete(D),J(Error(`Process ${D} exited with code ${A}`)),y.emit("SIGINT")}),B)$.stdout?.on("data",(A)=>{K("process",`[${D}] ${A.toString().trim()}`,!0)}),$.stderr?.on("data",(A)=>{K("process",`[${D}] ERR: ${A.toString().trim()}`,!0)});setTimeout(()=>{if(!this.isShuttingDown&&$.killed)this.processes.delete(D),J(Error(`Process ${D} was killed during startup`));else K("start",`Process ${D} started successfully`,B),V()},1000)})}async stopProcess(D,_){let B=this.processes.get(D);if(!B?.process){K("start",`No process found for ${D}`,_);return}return K("start",`Stopping process ${D}`,_),new Promise((N)=>{if(!B.process){N();return}B.process.once("exit",()=>{this.processes.delete(D),K("start",`Process ${D} stopped`,_),N()});try{B.process.kill("SIGTERM"),setTimeout(()=>{if(B.process){K("start",`Force killing process ${D}`,_);try{B.process.kill("SIGKILL")}catch(Y){}}},3000)}catch(Y){K("start",`Error stopping process ${D}: ${Y}`,_),this.processes.delete(D),N()}})}async stopAll(D){if(this.isShuttingDown){K("start","Already shutting down, skipping duplicate stopAll call",D);return}this.isShuttingDown=!0,K("start","Stopping all processes",D);let _=Array.from(this.processes.keys()).map((B)=>this.stopProcess(B,D).catch((N)=>{X.error(`Failed to stop process ${B}:`,N)}));await Promise.allSettled(_),this.processes.clear(),this.isShuttingDown=!1}isRunning(D){let _=this.processes.get(D);return!!_?.process&&!_.process.killed}}var A2=new e;var D_=new e,v_="0.12.0",b_=new b("0.0.0.0"),l=new Set,A_=!1,__=null,V_=null;async function d(D){if(A_)return K("cleanup","Cleanup already in progress, skipping",D?.verbose),V_||Promise.resolve();A_=!0,K("cleanup","Starting cleanup process",D?.verbose),V_=new Promise((_)=>{__=_});try{await D_.stopAll(D?.verbose),X.info("Shutting down proxy servers...");let _=[],B=Array.from(l).map((N)=>new Promise((Y)=>{N.close(()=>{K("cleanup","Server closed successfully",D?.verbose),Y()})}));if(_.push(...B),D?.hosts&&D.domains?.length){K("cleanup","Cleaning up hosts file entries",D?.verbose),K("cleanup",`Original domains for cleanup: ${JSON.stringify(D.domains)}`,D?.verbose);let N=D.domains.filter((Y)=>{if(Y==="test.local")return!0;return Y!=="localhost"&&!Y.startsWith("localhost.")&&Y!=="127.0.0.1"});if(K("cleanup",`Filtered domains for cleanup: ${JSON.stringify(N)}`,D?.verbose),N.length>0)X.info("Cleaning up hosts file entries..."),_.push(Z_(N,D?.verbose).then(()=>{K("cleanup",`Removed hosts entries for ${N.join(", ")}`,D?.verbose)}).catch((Y)=>{K("cleanup",`Failed to remove hosts entries: ${Y}`,D?.verbose),X.warn(`Failed to clean up hosts file entries for ${N.join(", ")}:`,Y)}))}if(D?.certs&&D.domains?.length){K("cleanup","Cleaning up SSL certificates",D?.verbose),X.info("Cleaning up SSL certificates...");let N=D.domains.map(async(Y)=>{try{await E_(Y,D?.verbose),K("cleanup",`Removed certificates for ${Y}`,D?.verbose)}catch(W){K("cleanup",`Failed to remove certificates for ${Y}: ${W}`,D?.verbose),X.warn(`Failed to clean up certificates for ${Y}:`,W)}});_.push(...N)}await Promise.allSettled(_),K("cleanup","All cleanup tasks completed successfully",D?.verbose),X.success("All cleanup tasks completed successfully")}catch(_){K("cleanup",`Error during cleanup: ${_}`,D?.verbose),X.error("Error during cleanup:",_)}finally{if(__)__();__=null,A_=!1;let _=D&&"vitePluginUsage"in D&&D.vitePluginUsage===!0;if(F.env.NODE_ENV!=="test"&&F.env.BUN_ENV!=="test"&&!_)F.exit(0)}return V_}var R_=!1;function S_(D){if(R_){K("signal",`Received second ${D} signal, forcing exit`,!0),F.exit(1);return}R_=!0,K("signal",`Received ${D} signal, initiating cleanup`,!0),d().catch((_)=>{K("signal",`Cleanup failed after ${D}: ${_}`,!0),F.exit(1)}).finally(()=>{R_=!1})}F.once("SIGINT",()=>S_("SIGINT"));F.once("SIGTERM",()=>S_("SIGTERM"));F.on("uncaughtException",(D)=>{K("process",`Uncaught exception: ${D}`,!0),X.error("Uncaught exception:",D),S_("uncaughtException")});async function a(D,_,B,N=5){K("connection",`Testing connection to ${D}:${_} (retries left: ${N})`,B);let Y=15000,W=Date.now();if(F.env.RPX_BYPASS_CONNECTION_TEST==="true"){K("connection",`Bypassing connection test for ${D}:${_} due to RPX_BYPASS_CONNECTION_TEST flag`,B);return}let $=()=>new Promise((V,J)=>{let A=y_.connect({host:D,port:_,timeout:3000});A.once("connect",()=>{K("connection",`Successfully connected to ${D}:${_}`,B),A.end(),V()}),A.once("timeout",()=>{K("connection",`Connection to ${D}:${_} timed out`,B),A.destroy(),J(Error("Connection timed out"))}),A.once("error",(T)=>{K("connection",`Failed to connect to ${D}:${_}: ${T}`,B),A.destroy(),J(T)})});try{await $()}catch(V){if(Date.now()-W>Y){K("connection",`Connection test timed out after ${Y}ms, but continuing anyway`,B),X.warn(`Connection test to ${D}:${_} timed out, but RPX will try to proceed anyway.`);return}if(V.code==="ECONNREFUSED"&&N>0)return K("connection",`Connection refused, server might be starting up. Retrying in 2 seconds... (${N} retries left)`,B),await new Promise((A)=>setTimeout(A,2000)),a(D,_,B,N-1);if(N>0)try{K("connection",`Trying HTTP request to ${D}:${_}`,B),await new Promise((A,T)=>{let I=O.request({hostname:D,port:_,path:"/",method:"HEAD",timeout:5000},(R)=>{K("connection",`Received HTTP response with status: ${R.statusCode}`,B),A()});I.on("error",(R)=>T(R)),I.on("timeout",()=>{I.destroy(),T(Error("HTTP request timed out"))}),I.end()}),K("connection",`HTTP request to ${D}:${_} succeeded`,B);return}catch(A){return K("connection",`HTTP request to ${D}:${_} failed: ${A}`,B),K("connection",`Retrying socket connection in 2 seconds... (${N} retries left)`,B),await new Promise((T)=>setTimeout(T,2000)),a(D,_,B,N-1)}let J=`Failed to connect to ${D}:${_} after ${5-N} attempts: ${V.message}`;K("connection",`${J}. To bypass this check set RPX_BYPASS_CONNECTION_TEST=true`,B),X.warn(J),X.warn("RPX will try to continue anyway. If you're sure this is correct, you can set RPX_BYPASS_CONNECTION_TEST=true to skip this check.")}}async function F_(D){K("server",`Starting server with options: ${C(D)}`,D.verbose);let _=new URL((D.from?.startsWith("http")?D.from:`http://${D.from}`)||"localhost:5173"),B=new URL((D.to?.startsWith("http")?D.to:`http://${D.to}`)||"rpx.localhost"),N=Number.parseInt(_.port)||(_.protocol.includes("https:")?443:80),Y=[B.hostname];if(!B.hostname.includes("localhost")&&!B.hostname.includes("127.0.0.1")){K("hosts",`Checking if hosts file entry exists for: ${B.hostname}`,D?.verbose);try{if(!(await h(Y,D.verbose))[0]){X.info(`Adding ${B.hostname} to hosts file...`),X.info("This may require sudo/administrator privileges");try{await L(Y,D.verbose)}catch(V){if(X.error("Failed to add hosts entry:",V.message),X.warn("You can manually add this entry to your hosts file:"),X.warn(`127.0.0.1 ${B.hostname}`),X.warn(`::1 ${B.hostname}`),F.platform==="win32")X.warn("On Windows:"),X.warn("1. Run notepad as administrator"),X.warn("2. Open C:\\Windows\\System32\\drivers\\etc\\hosts");else X.warn("On Unix systems:"),X.warn("sudo nano /etc/hosts")}}else K("hosts",`Host entry already exists for ${B.hostname}`,D.verbose)}catch($){X.error("Failed to check hosts file:",$.message)}}try{await a(_.hostname,N,D.verbose)}catch($){K("server",`Connection test failed: ${$}`,D.verbose),X.error($.message),X.warn("Continuing with proxy setup despite connection test failure..."),X.info("If you need to bypass connection testing, set environment variable RPX_BYPASS_CONNECTION_TEST=true")}let W=D._cachedSSLConfig||null;if(D.https)try{if(D.https===!0)D.https=N_({...D,to:B.hostname});if(W=await c({...D,to:B.hostname,https:D.https}),!W){if(K("ssl",`Generating new certificates for ${B.hostname}`,D.verbose),await K_({...D,from:_.toString(),to:B.hostname,https:D.https}),W=await c({...D,to:B.hostname,https:D.https}),!W)throw Error(`Failed to load SSL configuration after generating certificates for ${B.hostname}`)}}catch($){throw K("server",`SSL setup failed: ${$}`,D.verbose),$}K("server",`Setting up reverse proxy with SSL config for ${B.hostname}`,D.verbose),await a_({...D,from:D.from||"localhost:5173",to:B.hostname,fromPort:N,sourceUrl:{hostname:_.hostname,host:_.host},ssl:W})}async function l_(D,_,B,N,Y,W,$,V,J,A,T){K("proxy",`Creating proxy server ${D} -> ${_} with cleanUrls: ${A}`,J);function I(Z){let E={};for(let[Q,z]of Object.entries(Z))if(!Q.startsWith(":"))E[Q]=z;return E}let R=(Z,E)=>{K("request",`Incoming request: ${Z.method} ${Z.url}`,J);let Q=Z.url||"/",z=Z.method||"GET";if(Z instanceof f_.Http2ServerRequest){let S=Z.headers;z=S[":method"]||z,Q=S[":path"]||Q}if(A){if(!Q.match(/\.[a-z0-9]+$/i))if(Q.endsWith("/"))Q=`${Q}index.html`;else Q=`${Q}.html`}let w=I(Z.headers);if(T)w.host=`${W.hostname}:${B}`,K("request",`Changed origin: setting host header to ${w.host}`,J);let U={hostname:W.hostname,port:B,path:Q,method:z,headers:w};K("request",`Proxy request options: ${C(U)}`,J);let p=O.request(U,(S)=>{if(K("response",`Proxy response received with status ${S.statusCode}`,J),A&&S.statusCode===404){let q=[];if(Q.endsWith(".html"))q.push(Q.slice(0,-5));else if(!Q.match(/\.[a-z0-9]+$/i))q.push(`${Q}.html`);if(!Q.endsWith("/"))q.push(`${Q}/index.html`);if(q.length>0){K("cleanUrls",`Trying alternative paths: ${q.join(", ")}`,J);let u=(g)=>{if(g.length===0){E.writeHead(S.statusCode||404,S.headers),S.pipe(E);return}let I_=g[0],P_={...U,path:I_},w_=O.request(P_,(i)=>{if(i.statusCode===200)K("cleanUrls",`Found matching path: ${I_}`,J),E.writeHead(i.statusCode,i.headers),i.pipe(E);else u(g.slice(1))});w_.on("error",()=>u(g.slice(1))),w_.end()};u(q);return}}let P={...S.headers,"Strict-Transport-Security":"max-age=31536000; includeSubDomains; preload","X-Content-Type-Options":"nosniff"};E.writeHead(S.statusCode||500,P),S.pipe(E)});p.on("error",(S)=>{K("request",`Proxy request failed: ${S}`,J),X.error("Proxy request failed:",S),E.writeHead(502),E.end(`Proxy Error: ${S.message}`)}),Z.pipe(p)};if(K("server",`Creating server with SSL config: ${!!$}`,J),$)return new Promise((Z,E)=>{try{let Q=Bun.serve({port:N,hostname:Y,tls:{key:$.key,cert:$.cert,ca:$.ca,requestCert:!1,rejectUnauthorized:!1},async fetch(z){let w=new URL(z.url);K("request",`Bun.serve received: ${z.method} ${w.pathname}`,J);let U=`http://${W.host}`,p=new URL(w.pathname+w.search,U);try{let S=new Headers(z.headers);if(S.set("host",W.host),T)S.set("origin",U);S.set("x-forwarded-for","127.0.0.1"),S.set("x-forwarded-proto","https"),S.set("x-forwarded-host",_);let P=await fetch(p.toString(),{method:z.method,headers:S,body:z.body,redirect:"manual"}),q=new Headers(P.headers);if(A&&w.pathname.endsWith(".html")){let u=w.pathname.replace(/\.html$/,"");return new Response(null,{status:301,headers:{Location:u}})}return new Response(P.body,{status:P.status,statusText:P.statusText,headers:q})}catch(S){return K("request",`Proxy error: ${S}`,J),new Response(`Proxy Error: ${S}`,{status:502})}},error(z){return K("server",`Bun.serve error: ${z}`,J),new Response(`Server Error: ${z.message}`,{status:500})}});l.add(Q),U_({from:D,to:_,vitePluginUsage:V,listenPort:N,ssl:!0,cleanUrls:A,verbose:J}),Z()}catch(Q){E(Q)}});let G=O.createServer(R);function M(Z){return l.add(Z),new Promise((E,Q)=>{Z.listen(N,Y,()=>{K("server",`Server listening on port ${N}`,J),U_({from:D,to:_,vitePluginUsage:V,listenPort:N,ssl:!!$,cleanUrls:A,verbose:J}),E()}),Z.on("error",(z)=>{K("server",`Server error: ${z}`,J),Q(z)})})}return M(G)}async function a_(D){K("setup",`Setting up reverse proxy: ${C(D)}`,D.verbose);let{from:_,to:B,fromPort:N,sourceUrl:Y,ssl:W,verbose:$,cleanup:V,vitePluginUsage:J,changeOrigin:A,cleanUrls:T}=D,I=80,R=443,G="0.0.0.0",M=D.portManager||b_;try{if(B&&!B.includes("localhost")&&!B.includes("127.0.0.1")){if(!(await h([B],$))[0]){X.warn(`The hostname ${B} isn't in your hosts file. Adding it now...`);try{await L([B],$),X.success(`Added ${B} to your hosts file.`)}catch(w){X.error(`Failed to add ${B} to your hosts file: ${w}`),X.info(`You may need to manually add '127.0.0.1 ${B}' to your /etc/hosts file.`)}}}else if(F.platform!=="darwin"&&B&&B.includes("localhost")&&!B.match(/^(localhost|127\.0\.0\.1)$/)){if(!(await h([B],$))[0]){K("hosts",`${B} not found in hosts file, adding...`,$);try{await L([B],$)}catch(w){K("hosts",`Failed to add ${B} to hosts file: ${w}`,$)}}}if(W&&!M.usedPorts.has(I)){if(!await x(I,G,$))K("setup","Starting HTTP redirect server",$),O_($),M.usedPorts.add(I);else if(K("setup","Port 80 is in use, skipping HTTP redirect",$),$)X.warn("Port 80 is in use, HTTP to HTTPS redirect will not be available")}let Z=W?R:I,E=await x(Z,G,$),Q;if(E){if(K("setup",`Port ${Z} is already in use`,$),$)X.warn(`Port ${Z} is already in use. This may be another instance of rpx or another service.`);if(Z===443){if(Q=await M.getNextAvailablePort(3443,!0),K("setup",`Using port ${Q} instead of ${Z}`,$),$)X.info(`Using port ${Q} instead. Access your site at https://${B}:${Q}`)}else if(Q=await M.getNextAvailablePort(Z+1000,!0),K("setup",`Using port ${Q} instead of ${Z}`,$),$)X.info(`Using port ${Q} instead. Access your site at http://${B}:${Q}`)}else Q=Z,M.usedPorts.add(Q),K("setup",`Using standard ${Z===443?"HTTPS":"HTTP"} port ${Z} for ${B}`,$);await l_(_,B,N,Q,G,Y,W,J,$,T,A)}catch(Z){K("setup",`Setup failed: ${Z}`,$),X.error(`Failed to setup reverse proxy: ${Z.message}`),d({domains:[B],hosts:typeof V==="boolean"?V:V?.hosts,certs:typeof V==="boolean"?V:V?.certs,verbose:$,vitePluginUsage:J})}}function O_(D){K("redirect","Starting HTTP redirect server",D);let _=O.createServer((B,N)=>{let Y=B.headers.host||"";K("redirect",`Redirecting request from ${Y}${B.url} to HTTPS`,D),N.writeHead(301,{Location:`https://${Y}${B.url}`}),N.end()}).listen(80);l.add(_),K("redirect","HTTP redirect server started",D)}function d_(D){let _={...B_,...D};if(K("proxy",`Starting proxy with options: ${C(_)}`,_?.verbose),_.viaDaemon){if(!_.from||!_.to){X.error("viaDaemon mode requires both `from` and `to`");return}t({proxies:[{id:_.id,from:_.from,to:_.to,cleanUrls:_.cleanUrls,changeOrigin:_.changeOrigin,pathRewrites:_.pathRewrites}],verbose:_.verbose}).catch((J)=>{X.error(`Failed to register with rpx daemon: ${J.message}`),F.exit(1)});return}let B=_.to||"",N=B.split(".").pop()?.toLowerCase()||"",Y=F.platform==="darwin"&&B&&!B.includes("localhost")&&!B.includes("127.0.0.1"),W=["dev","app","page","new","day","foo"],$=["test","localhost","local","example","invalid"];if(Y&&W.includes(N)&&_?.verbose)X.warn(`The .${N} TLD may not work reliably for local development`),X.info(` Google owns .${N} with HSTS preloading, which can bypass local DNS`),X.info(" Consider using a reserved TLD: .test, .localhost, or .local");if(Y)import("./chunk-krj531r2.js").then(({setupDevelopmentDns:J})=>{J({domains:[B],verbose:_.verbose}).then((A)=>{if(A)Promise.resolve().then(()=>{if(_.verbose)if($.includes(N))X.success(`DNS server started for .${N} domains`);else X.success(`DNS server started for .${N} domains (hosts file entry also added)`)});else K("dns",`Could not start DNS server - ${B} may not resolve in browser`,_.verbose)})}).catch((J)=>{K("dns",`Failed to start DNS server: ${J}`,_.verbose)});let V={from:_.from,to:_.to,cleanUrls:_.cleanUrls,https:N_(_),cleanup:_.cleanup,vitePluginUsage:_.vitePluginUsage,changeOrigin:_.changeOrigin,verbose:_.verbose,regenerateUntrustedCerts:_.regenerateUntrustedCerts};K("proxy",`Server options: ${C(V)}`,_.verbose),F_(V).catch((J)=>{K("proxy",`Failed to start proxy: ${J}`,_.verbose),X.error(`Failed to start proxy: ${J.message}`),d({domains:[_.to],hosts:typeof _.cleanup==="boolean"?_.cleanup:_.cleanup?.hosts,certs:typeof _.cleanup==="boolean"?_.cleanup:_.cleanup?.certs,verbose:_.verbose})})}function p_(D){return D?.verbose||!1}async function T_(D){let _={from:"localhost:5173",to:"rpx.localhost",https:!1,cleanup:{hosts:!0,certs:!1},vitePluginUsage:!1,verbose:!1,cleanUrls:!1,changeOrigin:!1,regenerateUntrustedCerts:!0};if(D)_={..._,...D};let B=p_(_);if(K("config",`Starting with config: ${C(_,2)}`,B),K("config",`Is multi-proxy? ${"proxies"in _}`,B),_.viaDaemon){let M="proxies"in _&&Array.isArray(_.proxies)?_.proxies.map((Z)=>({id:Z.id,from:Z.from,to:Z.to,cleanUrls:Z.cleanUrls??_.cleanUrls,changeOrigin:Z.changeOrigin??_.changeOrigin,pathRewrites:Z.pathRewrites})):[{id:_.id,from:_.from,to:_.to,cleanUrls:_.cleanUrls,changeOrigin:_.changeOrigin,pathRewrites:_.pathRewrites}];await t({proxies:M,verbose:B});return}if("proxies"in _&&Array.isArray(_.proxies)){K("servers",`Found ${_.proxies.length} proxies in config`,B);for(let G of _.proxies)if(G.start){let M=`${G.from}-${G.to}`;try{K("watch",`Starting command for ${M} with command: ${G.start.command}`,B),X.info(`Starting command for ${M}...`),await D_.startProcess(M,G.start,B);let Z=new URL(G.from.startsWith("http")?G.from:`http://${G.from}`),E=Z.hostname||"localhost",Q=Number(Z.port)||80;try{await a(E,Q,B),K("watch",`Dev server is ready at ${E}:${Q}`,B)}catch(z){K("watch",`Connection check failed, but continuing with proxy setup: ${z}`,B),X.warn("Dev server connection check failed. RPX will try to proceed anyway...")}}catch(Z){throw K("watch",`Failed to start command for ${M}: ${Z}`,B),Error(`Failed to start command for ${M}: ${Z}`)}}else K("watch",`No start command for proxy ${G.from} -> ${G.to}`,B)}else if("start"in _&&_.start){K("watch","Found start command in single proxy config",B);let G=`${_.from}-${_.to}`;try{if(_.start)K("watch",`Starting command: ${_.start.command}`,B),await D_.startProcess(G,_.start,B);let M=new URL(_.from?.startsWith("http")?_.from:`http://${_.from}`),Z=M.hostname||"localhost",E=Number(M.port)||80;try{await a(Z,E,B),K("watch",`Dev server is ready at ${Z}:${E}`,B)}catch(Q){K("watch",`Connection check failed, but continuing with proxy setup: ${Q}`,B),X.warn("Dev server connection check failed. RPX will try to proceed anyway...")}}catch(M){throw K("watch",`Failed to run start command: ${M}`,B),Error(`Failed to run start command: ${M}`)}}else K("watch","No start command found in config",B);let N="proxies"in _&&Array.isArray(_.proxies)?_.proxies[0]?.to:("to"in _)?_.to:"rpx.localhost";if(F.platform!=="win32"&&(_.https||_.cleanup?.hosts!==!1)){if(!m())try{K("sudo","Pre-acquiring sudo credentials for privileged operations",B),m_("sudo -v",{stdio:"inherit"})}catch{K("sudo","Could not pre-acquire sudo credentials",B)}}if(_.https){let G=await c(_);if(!G){if(K("ssl",`No valid or trusted certificates found for ${N}, generating new ones`,_.verbose),await K_(_),G=await c(_),!G)throw Error(`Failed to load SSL certificates after generation for ${N}`)}else K("ssl",`Using existing and trusted certificates for ${N}`,_.verbose);_._cachedSSLConfig=G}let Y="proxies"in _&&Array.isArray(_.proxies)?_.proxies.map((G)=>({...G,https:_.https,cleanup:_.cleanup,cleanUrls:G.cleanUrls??("cleanUrls"in _?_.cleanUrls:!1),vitePluginUsage:_.vitePluginUsage,changeOrigin:G.changeOrigin??_.changeOrigin,verbose:B,_cachedSSLConfig:_._cachedSSLConfig})):[{from:"from"in _?_.from:"localhost:5173",to:"to"in _?_.to:"rpx.localhost",cleanUrls:"cleanUrls"in _?_.cleanUrls:!1,https:_.https,cleanup:_.cleanup,vitePluginUsage:_.vitePluginUsage,start:"start"in _?_.start:void 0,changeOrigin:_.changeOrigin,verbose:B,_cachedSSLConfig:_._cachedSSLConfig}],W=Y.map((G)=>G.to||"rpx.localhost"),$=_._cachedSSLConfig,V=W.filter((G)=>G&&!G.includes("localhost")&&!G.includes("127.0.0.1")),J=["dev","app","page","new","day","foo"],A=["test","localhost","local","example","invalid"],T=[...new Set(V.map((G)=>G.split(".").pop()?.toLowerCase()))],I=T.filter((G)=>!!G&&J.includes(G));if(I.length>0&&B)X.warn(`The following TLDs may not work reliably for local development: ${I.map((G)=>`.${G}`).join(", ")}`),X.info(" These TLDs have HSTS preloading which can bypass local DNS"),X.info(" Consider using reserved TLDs: .test, .localhost, or .local");if(F.platform==="darwin"&&V.length>0){let{setupDevelopmentDns:G}=await import("./chunk-krj531r2.js");if(await G({domains:V,verbose:B})){if(B)if(T.every((E)=>!!E&&A.includes(E)))X.success(`DNS server started for ${T.map((E)=>`.${E}`).join(", ")} domains`);else X.success(`DNS server started for ${T.map((E)=>`.${E}`).join(", ")} domains (hosts file entries also added)`)}else K("dns","Could not start DNS server - custom domains may not resolve",B)}let R=async()=>{K("cleanup","Starting cleanup handler",_.verbose);try{let{tearDownDevelopmentDns:G}=await import("./chunk-krj531r2.js");await G({verbose:_.verbose})}catch(G){K("cleanup",`Error stopping DNS server: ${G}`,_.verbose)}try{await D_.stopAll(_.verbose)}catch(G){K("cleanup",`Error stopping processes: ${G}`,_.verbose)}await d({domains:W,hosts:typeof _.cleanup==="boolean"?_.cleanup:_.cleanup?.hosts,certs:typeof _.cleanup==="boolean"?_.cleanup:_.cleanup?.certs,verbose:_.verbose||!1})};if(F.on("SIGINT",R),F.on("SIGTERM",R),F.on("uncaughtException",(G)=>{K("process",`Uncaught exception: ${G}`,!0),console.error("Uncaught exception:",G),R()}),$&&Y.length>1){K("proxies",`Creating shared HTTPS server for ${Y.length} domains`,B);let G=new Map;for(let Q of Y){let z=Q.to||"rpx.localhost",w=new URL(Q.from?.startsWith("http")?Q.from:`http://${Q.from}`);if(G.set(z,{sourceHost:w.host,cleanUrls:Q.cleanUrls||!1,changeOrigin:Q.changeOrigin||!1,pathRewrites:Q.pathRewrites}),K("proxies",`Route: ${z} → ${w.host}`,B),!z.includes("localhost")&&!z.includes("127.0.0.1"))try{if(!(await h([z],B))[0])await L([z],B)}catch{K("hosts",`Could not add hosts entry for ${z}`,B)}}if(!await x(80,"0.0.0.0",B))O_(B);let Z=443;if(await x(Z,"0.0.0.0",B)){if(K("proxies",`Port ${Z} is already in use, cannot start shared proxy`,B),B)X.warn(`Port ${Z} is in use. Shared HTTPS proxy cannot start.`);return}try{let Q=Bun.serve({port:Z,hostname:"0.0.0.0",tls:{key:$.key,cert:$.cert,ca:$.ca,requestCert:!1,rejectUnauthorized:!1},fetch:M_((z)=>G.get(z),B),error(z){return K("server",`Shared proxy server error: ${z}`,B),new Response(`Server Error: ${z.message}`,{status:500})}});l.add(Q),K("proxies",`Shared HTTPS proxy listening on port ${Z} for ${G.size} domains`,B)}catch(Q){K("proxies",`Failed to start shared proxy: ${Q}`,B),console.error("Failed to start shared HTTPS proxy:",Q),R()}}else for(let G of Y)try{let M=G.to||"rpx.localhost";K("proxy",`Starting proxy for ${M} with SSL config: ${!!$}`,G.verbose),await F_({from:G.from||"localhost:5173",to:M,cleanUrls:G.cleanUrls||!1,https:G.https||!1,cleanup:G.cleanup||!1,vitePluginUsage:G.vitePluginUsage||!1,verbose:G.verbose||!1,_cachedSSLConfig:$,changeOrigin:G.changeOrigin||!1})}catch(M){K("proxies",`Failed to start proxy for ${G.to}: ${M}`,G.verbose),console.error(`Failed to start proxy for ${G.to}:`,M),R()}}function U_(D){if(D?.vitePluginUsage||!D?.verbose)return;if(console.log(""),console.log(` ${j.green(j.bold("rpx"))} ${j.green(`v${v_}`)}`),console.log(` ${j.green("➜")} ${j.dim(D?.from??"")} ${j.dim("➜")} ${j.cyan(D?.ssl?`https://${D?.to}`:`http://${D?.to}`)}`),D?.listenPort!==(D?.ssl?443:80))console.log(` ${j.green("➜")} Listening on port ${D?.listenPort}`);if(D?.cleanUrls)console.log(` ${j.green("➜")} Clean URLs enabled`)}var t2=T_;export{G_ as writeEntry,MD as watchRegistry,r_ as verifyHttpsChain,GD as trustRootCaForBrowsers,hD as tearDownDevelopmentDns,LD as syncDevelopmentDnsFromRegistry,qD as stopDnsServer,iD as stopDaemon,F_ as startServer,d_ as startProxy,T_ as startProxies,CD as startDnsServer,yD as setupResolver,PD as setupDevelopmentDns,C as safeStringify,$B as safeDeleteFile,t as runViaDaemon,pD as runDaemon,UD as resolverFilePath,wD as resolverBasenamesForDomains,ID as resolverBasenameForDomain,YB as resolvePathRewrite,cD as removeResolver,OD as removeLegacyTldResolvers,Z_ as removeHosts,W_ as removeEntry,dD as releaseDaemonLock,s2 as redactSensitive,uD as reconcileStaleDevelopmentDns,nD as reconcileDevelopmentDnsOnIdle,RD as readEntry,bD as readDaemonPid,i_ as readCertSha256Fingerprint,n_ as readCertCommonName,zD as readAll,ND as pruneStaleRootCas,c_ as portManager,s_ as parseSha256HashesFromSecurityListing,g_ as normalizeSha256Fingerprint,TD as normalizeDevDomain,JD as loadSSLConfig,KD as listCertSha256HashesByCommonName,e2 as isValidRootCA,$_ as isValidId,KB as isSingleProxyOptions,NB as isSingleProxyConfig,YD as isRootCaTrustedForSsl,$D as isRootCaFingerprintInKeychains,x as isPortInUse,VD as isPidAlive,BB as isMultiProxyOptions,DB as isMultiProxyConfig,xD as isDnsServerRunning,lD as isDaemonRunning,AD as isCertTrusted,N_ as httpsConfig,m as getSudoPassword,XD as getSharedDaemonCertPaths,WD as getRootCAPaths,Y_ as getRegistryDir,_B as getPrimaryDomain,BD as getMacosTrustKeychains,DD as getMacosLoginKeychainPath,mD as getDaemonRpxDir,vD as getDaemonPidPath,K_ as generateCertificate,ED as gcStaleEntries,QD as forceTrustCertificate,x_ as findAvailablePort,o2 as extractHostname,r2 as execSudoSync,X_ as ensureDaemonRunning,HD as devDomainsFromHosts,k_ as deriveIdFromTarget,gD as defaultDaemonSpawnCommand,B_ as defaultConfig,t2 as default,K as debugLog,M_ as createProxyFetchHandler,fD as contentLooksLikeRpxResolver,B_ as config,j as colors,ZD as clearSslConfigCache,E_ as cleanupCertificates,d as cleanup,h as checkHosts,c as checkExistingCertificates,t_ as certIncludesSanHostnames,L as addHosts,aD as acquireDaemonLock,_D as RPX_ROOT_CA_COMMON_NAME,kD as RPX_RESOLVER_MARKER,e_ as MACOS_SYSTEM_KEYCHAIN,o_ as MACOS_CA_TRUST_FLAGS,FD as LEGACY_TLD_RESOLVER_LABELS,b as DefaultPortManager,SD as DNS_STATE_VERSION,jD as DNS_PORT};
8
+ `,V=Q_.join(q_.tmpdir(),`rpx-hosts-${Date.now()}.tmp`);try{await f.promises.writeFile(V,G,"utf8"),await s(`cat "${V}" | tee "${j}" > /dev/null`),K("hosts","Hosts removed successfully",_)}catch(X){K("hosts","Could not clean up hosts file automatically",_)}finally{try{await f.promises.unlink(V)}catch(X){K("hosts",`Failed to remove temporary file: ${X}`,_)}}}catch(B){K("hosts",`Failed to clean up hosts file: ${B.message}`,_)}}async function h(D,_){K("hosts",`Checking hosts: ${D}`,_);let B;try{B=await f.promises.readFile(j,"utf-8")}catch(N){K("hosts",`Error reading hosts file: ${N}`,_);try{let Y=m(),W;if(Y)W=`echo '${Y}' | sudo -S cat "${j}" 2>/dev/null`;else W=`sudo -n cat "${j}" 2>/dev/null || cat "${j}" 2>/dev/null || echo ""`;let{stdout:G}=await r(W);B=G}catch(Y){return K("hosts",`Cannot read hosts file, assuming entries don't exist: ${Y}`,_),D.map(()=>!1)}}return D.map((N)=>{let Y=`127.0.0.1 ${N}`,W=`::1 ${N}`;return B.includes(Y)||B.includes(W)})}import*as o from"node:net";function x(D,_,B){return K("port",`Checking if port ${D} is in use on ${_}`,B),new Promise((N)=>{let Y=o.createServer(),W=setTimeout(()=>{K("port",`Checking port ${D} timed out, assuming it's in use`,B),Y.close(),N(!0)},3000);Y.once("error",(G)=>{if(clearTimeout(W),G.code==="EADDRINUSE")K("port",`Port ${D} is in use`,B),N(!0);else K("port",`Error checking port ${D}: ${G.message}`,B),N(!0)}),Y.once("listening",()=>{clearTimeout(W),K("port",`Port ${D} is available`,B),Y.close(),N(!1)});try{Y.listen(D,_)}catch(G){clearTimeout(W),K("port",`Exception checking port ${D}: ${G}`,B),N(!0)}})}async function U_(D,_,B,N=50){K("port",`Finding available port starting from ${D} (max attempts: ${N})`,B);let Y=D,W=0;while(W<N){if(W++,!await x(Y,_,B))return K("port",`Found available port: ${Y} after ${W} attempts`,B),Y;K("port",`Port ${Y} is in use, trying ${Y+1} (attempt ${W}/${N})`,B),Y++}throw Error(`Unable to find available port after ${N} attempts starting from ${D}`)}function x_(D,_,B=5000,N){return K("port",`Testing connection to ${_}:${D}`,N),new Promise((Y)=>{let W=o.connect({host:_,port:D,timeout:B});W.once("connect",()=>{K("port",`Successfully connected to ${_}:${D}`,N),W.end(),Y(!0)}),W.once("timeout",()=>{K("port",`Connection to ${_}:${D} timed out`,N),W.destroy(),Y(!1)}),W.once("error",(G)=>{K("port",`Failed to connect to ${_}:${D}: ${G.message}`,N),W.destroy(),Y(!1)})})}class b{usedPorts=new Set;hostname;verbose;maxRetries;constructor(D="0.0.0.0",_,B=50){this.hostname=D,this.verbose=_,this.maxRetries=B}async getNextAvailablePort(D,_=!1){if(this.usedPorts.has(D))return this.findNextAvailablePort(D+1,_);if(await x(D,this.hostname,this.verbose))return this.findNextAvailablePort(D+1,_);if(_){if(!await x_(D,this.hostname,3000,this.verbose))return K("port",`Port ${D} is available but not connectable, trying next port`,this.verbose),this.findNextAvailablePort(D+1,_)}return this.usedPorts.add(D),D}async findNextAvailablePort(D,_=!1){let B=await U_(D,this.hostname,this.verbose,this.maxRetries);if(_){if(!await x_(B,this.hostname,3000,this.verbose))if(B<D+this.maxRetries)return this.findNextAvailablePort(B+1,_);else throw Error(`Unable to find a connectable port after ${this.maxRetries} attempts`)}return this.usedPorts.add(B),B}releasePort(D){K("port",`Releasing port ${D}`,this.verbose),this.usedPorts.delete(D)}}var u_=new b;import{spawn as m_}from"node:child_process";import*as y from"node:process";class e{processes=new Map;isShuttingDown=!1;async startProcess(D,_,B){if(this.processes.has(D)){K("start",`Process ${D} is already running`,B);return}let[N,...Y]=_.command.split(" "),W=_.cwd||y.cwd();K("start",`Starting process ${D}:`,B),K("start",` Command: ${N} ${Y.join(" ")}`,B),K("start",` Working directory: ${W}`,B),K("start",` Environment variables: ${C(_.env)}`,B);let G=m_(N,Y,{cwd:W,env:{...y.env,..._.env},shell:!0,stdio:"inherit"});return this.processes.set(D,{command:_.command,cwd:W,process:G,env:_.env}),new Promise((V,X)=>{if(G.on("error",(A)=>{if(!this.isShuttingDown)K("start",`Process ${D} failed to start: ${A}`,B),this.processes.delete(D),X(A),y.emit("SIGINT")}),G.on("exit",(A)=>{if(!this.isShuttingDown&&A!==null&&A!==0)K("start",`Process ${D} exited with code ${A}`,B),this.processes.delete(D),X(Error(`Process ${D} exited with code ${A}`)),y.emit("SIGINT")}),B)G.stdout?.on("data",(A)=>{K("process",`[${D}] ${A.toString().trim()}`,!0)}),G.stderr?.on("data",(A)=>{K("process",`[${D}] ERR: ${A.toString().trim()}`,!0)});setTimeout(()=>{if(!this.isShuttingDown&&G.killed)this.processes.delete(D),X(Error(`Process ${D} was killed during startup`));else K("start",`Process ${D} started successfully`,B),V()},1000)})}async stopProcess(D,_){let B=this.processes.get(D);if(!B?.process){K("start",`No process found for ${D}`,_);return}return K("start",`Stopping process ${D}`,_),new Promise((N)=>{if(!B.process){N();return}B.process.once("exit",()=>{this.processes.delete(D),K("start",`Process ${D} stopped`,_),N()});try{B.process.kill("SIGTERM"),setTimeout(()=>{if(B.process){K("start",`Force killing process ${D}`,_);try{B.process.kill("SIGKILL")}catch(Y){}}},3000)}catch(Y){K("start",`Error stopping process ${D}: ${Y}`,_),this.processes.delete(D),N()}})}async stopAll(D){if(this.isShuttingDown){K("start","Already shutting down, skipping duplicate stopAll call",D);return}this.isShuttingDown=!0,K("start","Stopping all processes",D);let _=Array.from(this.processes.keys()).map((B)=>this.stopProcess(B,D).catch((N)=>{J.error(`Failed to stop process ${B}:`,N)}));await Promise.allSettled(_),this.processes.clear(),this.isShuttingDown=!1}isRunning(D){let _=this.processes.get(D);return!!_?.process&&!_.process.killed}}var VD=new e;var D_=new e,b_="0.12.0",l_=new b("0.0.0.0"),l=new Set,A_=!1,__=null,V_=null;async function d(D){if(A_)return K("cleanup","Cleanup already in progress, skipping",D?.verbose),V_||Promise.resolve();A_=!0,K("cleanup","Starting cleanup process",D?.verbose),V_=new Promise((_)=>{__=_});try{await D_.stopAll(D?.verbose),J.info("Shutting down proxy servers...");let _=[],B=Array.from(l).map((N)=>new Promise((Y)=>{N.close(()=>{K("cleanup","Server closed successfully",D?.verbose),Y()})}));if(_.push(...B),D?.hosts&&D.domains?.length){K("cleanup","Cleaning up hosts file entries",D?.verbose),K("cleanup",`Original domains for cleanup: ${JSON.stringify(D.domains)}`,D?.verbose);let N=D.domains.filter((Y)=>{if(Y==="test.local")return!0;return Y!=="localhost"&&!Y.startsWith("localhost.")&&Y!=="127.0.0.1"});if(K("cleanup",`Filtered domains for cleanup: ${JSON.stringify(N)}`,D?.verbose),N.length>0)J.info("Cleaning up hosts file entries..."),_.push(Z_(N,D?.verbose).then(()=>{K("cleanup",`Removed hosts entries for ${N.join(", ")}`,D?.verbose)}).catch((Y)=>{K("cleanup",`Failed to remove hosts entries: ${Y}`,D?.verbose),J.warn(`Failed to clean up hosts file entries for ${N.join(", ")}:`,Y)}))}if(D?.certs&&D.domains?.length){K("cleanup","Cleaning up SSL certificates",D?.verbose),J.info("Cleaning up SSL certificates...");let N=D.domains.map(async(Y)=>{try{await z_(Y,D?.verbose),K("cleanup",`Removed certificates for ${Y}`,D?.verbose)}catch(W){K("cleanup",`Failed to remove certificates for ${Y}: ${W}`,D?.verbose),J.warn(`Failed to clean up certificates for ${Y}:`,W)}});_.push(...N)}await Promise.allSettled(_),K("cleanup","All cleanup tasks completed successfully",D?.verbose),J.success("All cleanup tasks completed successfully")}catch(_){K("cleanup",`Error during cleanup: ${_}`,D?.verbose),J.error("Error during cleanup:",_)}finally{if(__)__();__=null,A_=!1;let _=D&&"vitePluginUsage"in D&&D.vitePluginUsage===!0;if(F.env.NODE_ENV!=="test"&&F.env.BUN_ENV!=="test"&&!_)F.exit(0)}return V_}var R_=!1;function S_(D){if(R_){K("signal",`Received second ${D} signal, forcing exit`,!0),F.exit(1);return}R_=!0,K("signal",`Received ${D} signal, initiating cleanup`,!0),d().catch((_)=>{K("signal",`Cleanup failed after ${D}: ${_}`,!0),F.exit(1)}).finally(()=>{R_=!1})}F.once("SIGINT",()=>S_("SIGINT"));F.once("SIGTERM",()=>S_("SIGTERM"));F.on("uncaughtException",(D)=>{K("process",`Uncaught exception: ${D}`,!0),J.error("Uncaught exception:",D),S_("uncaughtException")});async function a(D,_,B,N=5){K("connection",`Testing connection to ${D}:${_} (retries left: ${N})`,B);let Y=15000,W=Date.now();if(F.env.RPX_BYPASS_CONNECTION_TEST==="true"){K("connection",`Bypassing connection test for ${D}:${_} due to RPX_BYPASS_CONNECTION_TEST flag`,B);return}let G=()=>new Promise((V,X)=>{let A=O_.connect({host:D,port:_,timeout:3000});A.once("connect",()=>{K("connection",`Successfully connected to ${D}:${_}`,B),A.end(),V()}),A.once("timeout",()=>{K("connection",`Connection to ${D}:${_} timed out`,B),A.destroy(),X(Error("Connection timed out"))}),A.once("error",(T)=>{K("connection",`Failed to connect to ${D}:${_}: ${T}`,B),A.destroy(),X(T)})});try{await G()}catch(V){if(Date.now()-W>Y){K("connection",`Connection test timed out after ${Y}ms, but continuing anyway`,B),J.warn(`Connection test to ${D}:${_} timed out, but RPX will try to proceed anyway.`);return}if(V.code==="ECONNREFUSED"&&N>0)return K("connection",`Connection refused, server might be starting up. Retrying in 2 seconds... (${N} retries left)`,B),await new Promise((A)=>setTimeout(A,2000)),a(D,_,B,N-1);if(N>0)try{K("connection",`Trying HTTP request to ${D}:${_}`,B),await new Promise((A,T)=>{let I=O.request({hostname:D,port:_,path:"/",method:"HEAD",timeout:5000},(R)=>{K("connection",`Received HTTP response with status: ${R.statusCode}`,B),A()});I.on("error",(R)=>T(R)),I.on("timeout",()=>{I.destroy(),T(Error("HTTP request timed out"))}),I.end()}),K("connection",`HTTP request to ${D}:${_} succeeded`,B);return}catch(A){return K("connection",`HTTP request to ${D}:${_} failed: ${A}`,B),K("connection",`Retrying socket connection in 2 seconds... (${N} retries left)`,B),await new Promise((T)=>setTimeout(T,2000)),a(D,_,B,N-1)}let X=`Failed to connect to ${D}:${_} after ${5-N} attempts: ${V.message}`;K("connection",`${X}. To bypass this check set RPX_BYPASS_CONNECTION_TEST=true`,B),J.warn(X),J.warn("RPX will try to continue anyway. If you're sure this is correct, you can set RPX_BYPASS_CONNECTION_TEST=true to skip this check.")}}async function T_(D){K("server",`Starting server with options: ${C(D)}`,D.verbose);let _=new URL((D.from?.startsWith("http")?D.from:`http://${D.from}`)||"localhost:5173"),B=new URL((D.to?.startsWith("http")?D.to:`http://${D.to}`)||"rpx.localhost"),N=Number.parseInt(_.port)||(_.protocol.includes("https:")?443:80),Y=[B.hostname];if(!B.hostname.includes("localhost")&&!B.hostname.includes("127.0.0.1")){K("hosts",`Checking if hosts file entry exists for: ${B.hostname}`,D?.verbose);try{if(!(await h(Y,D.verbose))[0]){J.info(`Adding ${B.hostname} to hosts file...`),J.info("This may require sudo/administrator privileges");try{await L(Y,D.verbose)}catch(V){if(J.error("Failed to add hosts entry:",V.message),J.warn("You can manually add this entry to your hosts file:"),J.warn(`127.0.0.1 ${B.hostname}`),J.warn(`::1 ${B.hostname}`),F.platform==="win32")J.warn("On Windows:"),J.warn("1. Run notepad as administrator"),J.warn("2. Open C:\\Windows\\System32\\drivers\\etc\\hosts");else J.warn("On Unix systems:"),J.warn("sudo nano /etc/hosts")}}else K("hosts",`Host entry already exists for ${B.hostname}`,D.verbose)}catch(G){J.error("Failed to check hosts file:",G.message)}}try{await a(_.hostname,N,D.verbose)}catch(G){K("server",`Connection test failed: ${G}`,D.verbose),J.error(G.message),J.warn("Continuing with proxy setup despite connection test failure..."),J.info("If you need to bypass connection testing, set environment variable RPX_BYPASS_CONNECTION_TEST=true")}let W=D._cachedSSLConfig||null;if(D.https)try{if(D.https===!0)D.https=N_({...D,to:B.hostname});if(W=await c({...D,to:B.hostname,https:D.https}),!W){if(K("ssl",`Generating new certificates for ${B.hostname}`,D.verbose),await K_({...D,from:_.toString(),to:B.hostname,https:D.https}),W=await c({...D,to:B.hostname,https:D.https}),!W)throw Error(`Failed to load SSL configuration after generating certificates for ${B.hostname}`)}}catch(G){throw K("server",`SSL setup failed: ${G}`,D.verbose),G}K("server",`Setting up reverse proxy with SSL config for ${B.hostname}`,D.verbose),await d_({...D,from:D.from||"localhost:5173",to:B.hostname,fromPort:N,sourceUrl:{hostname:_.hostname,host:_.host},ssl:W})}async function a_(D,_,B,N,Y,W,G,V,X,A,T){K("proxy",`Creating proxy server ${D} -> ${_} with cleanUrls: ${A}`,X);function I(Z){let z={};for(let[Q,E]of Object.entries(Z))if(!Q.startsWith(":"))z[Q]=E;return z}let R=(Z,z)=>{K("request",`Incoming request: ${Z.method} ${Z.url}`,X);let Q=Z.url||"/",E=Z.method||"GET";if(Z instanceof y_.Http2ServerRequest){let S=Z.headers;E=S[":method"]||E,Q=S[":path"]||Q}if(A){if(!Q.match(/\.[a-z0-9]+$/i))if(Q.endsWith("/"))Q=`${Q}index.html`;else Q=`${Q}.html`}let w=I(Z.headers);if(T)w.host=`${W.hostname}:${B}`,K("request",`Changed origin: setting host header to ${w.host}`,X);let U={hostname:W.hostname,port:B,path:Q,method:E,headers:w};K("request",`Proxy request options: ${C(U)}`,X);let p=O.request(U,(S)=>{if(K("response",`Proxy response received with status ${S.statusCode}`,X),A&&S.statusCode===404){let q=[];if(Q.endsWith(".html"))q.push(Q.slice(0,-5));else if(!Q.match(/\.[a-z0-9]+$/i))q.push(`${Q}.html`);if(!Q.endsWith("/"))q.push(`${Q}/index.html`);if(q.length>0){K("cleanUrls",`Trying alternative paths: ${q.join(", ")}`,X);let u=(g)=>{if(g.length===0){z.writeHead(S.statusCode||404,S.headers),S.pipe(z);return}let I_=g[0],L_={...U,path:I_},w_=O.request(L_,(i)=>{if(i.statusCode===200)K("cleanUrls",`Found matching path: ${I_}`,X),z.writeHead(i.statusCode,i.headers),i.pipe(z);else u(g.slice(1))});w_.on("error",()=>u(g.slice(1))),w_.end()};u(q);return}}let P={...S.headers,"Strict-Transport-Security":"max-age=31536000; includeSubDomains; preload","X-Content-Type-Options":"nosniff"};z.writeHead(S.statusCode||500,P),S.pipe(z)});p.on("error",(S)=>{K("request",`Proxy request failed: ${S}`,X),J.error("Proxy request failed:",S),z.writeHead(502),z.end(`Proxy Error: ${S.message}`)}),Z.pipe(p)};if(K("server",`Creating server with SSL config: ${!!G}`,X),G)return new Promise((Z,z)=>{try{let Q=Bun.serve({port:N,hostname:Y,tls:{key:G.key,cert:G.cert,ca:G.ca,requestCert:!1,rejectUnauthorized:!1},async fetch(E){let w=new URL(E.url);K("request",`Bun.serve received: ${E.method} ${w.pathname}`,X);let U=`http://${W.host}`,p=new URL(w.pathname+w.search,U);try{let S=new Headers(E.headers);if(S.set("host",W.host),T)S.set("origin",U);S.set("x-forwarded-for","127.0.0.1"),S.set("x-forwarded-proto","https"),S.set("x-forwarded-host",_);let P=await fetch(p.toString(),{method:E.method,headers:S,body:E.body,redirect:"manual"}),q=new Headers(P.headers);if(A&&w.pathname.endsWith(".html")){let u=w.pathname.replace(/\.html$/,"");return new Response(null,{status:301,headers:{Location:u}})}return new Response(P.body,{status:P.status,statusText:P.statusText,headers:q})}catch(S){return K("request",`Proxy error: ${S}`,X),new Response(`Proxy Error: ${S}`,{status:502})}},error(E){return K("server",`Bun.serve error: ${E}`,X),new Response(`Server Error: ${E.message}`,{status:500})}});l.add(Q),f_({from:D,to:_,vitePluginUsage:V,listenPort:N,ssl:!0,cleanUrls:A,verbose:X}),Z()}catch(Q){z(Q)}});let $=O.createServer(R);function M(Z){return l.add(Z),new Promise((z,Q)=>{Z.listen(N,Y,()=>{K("server",`Server listening on port ${N}`,X),f_({from:D,to:_,vitePluginUsage:V,listenPort:N,ssl:!!G,cleanUrls:A,verbose:X}),z()}),Z.on("error",(E)=>{K("server",`Server error: ${E}`,X),Q(E)})})}return M($)}async function d_(D){K("setup",`Setting up reverse proxy: ${C(D)}`,D.verbose);let{from:_,to:B,fromPort:N,sourceUrl:Y,ssl:W,verbose:G,cleanup:V,vitePluginUsage:X,changeOrigin:A,cleanUrls:T}=D,I=80,R=443,$="0.0.0.0",M=D.portManager||l_;try{if(B&&!B.includes("localhost")&&!B.includes("127.0.0.1")){if(!(await h([B],G))[0]){J.warn(`The hostname ${B} isn't in your hosts file. Adding it now...`);try{await L([B],G),J.success(`Added ${B} to your hosts file.`)}catch(w){J.error(`Failed to add ${B} to your hosts file: ${w}`),J.info(`You may need to manually add '127.0.0.1 ${B}' to your /etc/hosts file.`)}}}else if(F.platform!=="darwin"&&B&&B.includes("localhost")&&!B.match(/^(localhost|127\.0\.0\.1)$/)){if(!(await h([B],G))[0]){K("hosts",`${B} not found in hosts file, adding...`,G);try{await L([B],G)}catch(w){K("hosts",`Failed to add ${B} to hosts file: ${w}`,G)}}}if(W&&!M.usedPorts.has(I)){if(!await x(I,$,G))K("setup","Starting HTTP redirect server",G),P_(G),M.usedPorts.add(I);else if(K("setup","Port 80 is in use, skipping HTTP redirect",G),G)J.warn("Port 80 is in use, HTTP to HTTPS redirect will not be available")}let Z=W?R:I,z=await x(Z,$,G),Q;if(z){if(K("setup",`Port ${Z} is already in use`,G),G)J.warn(`Port ${Z} is already in use. This may be another instance of rpx or another service.`);if(Z===443){if(Q=await M.getNextAvailablePort(3443,!0),K("setup",`Using port ${Q} instead of ${Z}`,G),G)J.info(`Using port ${Q} instead. Access your site at https://${B}:${Q}`)}else if(Q=await M.getNextAvailablePort(Z+1000,!0),K("setup",`Using port ${Q} instead of ${Z}`,G),G)J.info(`Using port ${Q} instead. Access your site at http://${B}:${Q}`)}else Q=Z,M.usedPorts.add(Q),K("setup",`Using standard ${Z===443?"HTTPS":"HTTP"} port ${Z} for ${B}`,G);await a_(_,B,N,Q,$,Y,W,X,G,T,A)}catch(Z){K("setup",`Setup failed: ${Z}`,G),J.error(`Failed to setup reverse proxy: ${Z.message}`),d({domains:[B],hosts:typeof V==="boolean"?V:V?.hosts,certs:typeof V==="boolean"?V:V?.certs,verbose:G,vitePluginUsage:X})}}function P_(D){K("redirect","Starting HTTP redirect server",D);let _=O.createServer((B,N)=>{let Y=B.headers.host||"";K("redirect",`Redirecting request from ${Y}${B.url} to HTTPS`,D),N.writeHead(301,{Location:`https://${Y}${B.url}`}),N.end()}).listen(80);l.add(_),K("redirect","HTTP redirect server started",D)}function p_(D){let _={...B_,...D};if(K("proxy",`Starting proxy with options: ${C(_)}`,_?.verbose),_.viaDaemon){if(!_.from||!_.to){J.error("viaDaemon mode requires both `from` and `to`");return}t({proxies:[{id:_.id,from:_.from,to:_.to,cleanUrls:_.cleanUrls,changeOrigin:_.changeOrigin,pathRewrites:_.pathRewrites}],verbose:_.verbose}).catch((X)=>{J.error(`Failed to register with rpx daemon: ${X.message}`),F.exit(1)});return}let B=_.to||"",N=B.split(".").pop()?.toLowerCase()||"",Y=F.platform==="darwin"&&B&&!B.includes("localhost")&&!B.includes("127.0.0.1"),W=["dev","app","page","new","day","foo"],G=["test","localhost","local","example","invalid"];if(Y&&W.includes(N)&&_?.verbose)J.warn(`The .${N} TLD may not work reliably for local development`),J.info(` Google owns .${N} with HSTS preloading, which can bypass local DNS`),J.info(" Consider using a reserved TLD: .test, .localhost, or .local");if(Y)import("./chunk-1j4gp3f8.js").then(({setupDevelopmentDns:X})=>{X({domains:[B],verbose:_.verbose}).then((A)=>{if(A)Promise.resolve().then(()=>{if(_.verbose)if(G.includes(N))J.success(`DNS server started for .${N} domains`);else J.success(`DNS server started for .${N} domains (hosts file entry also added)`)});else K("dns",`Could not start DNS server - ${B} may not resolve in browser`,_.verbose)})}).catch((X)=>{K("dns",`Failed to start DNS server: ${X}`,_.verbose)});let V={from:_.from,to:_.to,cleanUrls:_.cleanUrls,https:N_(_),cleanup:_.cleanup,vitePluginUsage:_.vitePluginUsage,changeOrigin:_.changeOrigin,verbose:_.verbose,regenerateUntrustedCerts:_.regenerateUntrustedCerts};K("proxy",`Server options: ${C(V)}`,_.verbose),T_(V).catch((X)=>{K("proxy",`Failed to start proxy: ${X}`,_.verbose),J.error(`Failed to start proxy: ${X.message}`),d({domains:[_.to],hosts:typeof _.cleanup==="boolean"?_.cleanup:_.cleanup?.hosts,certs:typeof _.cleanup==="boolean"?_.cleanup:_.cleanup?.certs,verbose:_.verbose})})}function g_(D){return D?.verbose||!1}async function F_(D){let _={from:"localhost:5173",to:"rpx.localhost",https:!1,cleanup:{hosts:!0,certs:!1},vitePluginUsage:!1,verbose:!1,cleanUrls:!1,changeOrigin:!1,regenerateUntrustedCerts:!0};if(D)_={..._,...D};let B=g_(_);if(K("config",`Starting with config: ${C(_,2)}`,B),K("config",`Is multi-proxy? ${"proxies"in _}`,B),_.viaDaemon){let M="proxies"in _&&Array.isArray(_.proxies)?_.proxies.map((Z)=>({id:Z.id,from:Z.from,to:Z.to,cleanUrls:Z.cleanUrls??_.cleanUrls,changeOrigin:Z.changeOrigin??_.changeOrigin,pathRewrites:Z.pathRewrites})):[{id:_.id,from:_.from,to:_.to,cleanUrls:_.cleanUrls,changeOrigin:_.changeOrigin,pathRewrites:_.pathRewrites}];await t({proxies:M,verbose:B});return}if("proxies"in _&&Array.isArray(_.proxies)){K("servers",`Found ${_.proxies.length} proxies in config`,B);for(let $ of _.proxies)if($.start){let M=`${$.from}-${$.to}`;try{K("watch",`Starting command for ${M} with command: ${$.start.command}`,B),J.info(`Starting command for ${M}...`),await D_.startProcess(M,$.start,B);let Z=new URL($.from.startsWith("http")?$.from:`http://${$.from}`),z=Z.hostname||"localhost",Q=Number(Z.port)||80;try{await a(z,Q,B),K("watch",`Dev server is ready at ${z}:${Q}`,B)}catch(E){K("watch",`Connection check failed, but continuing with proxy setup: ${E}`,B),J.warn("Dev server connection check failed. RPX will try to proceed anyway...")}}catch(Z){throw K("watch",`Failed to start command for ${M}: ${Z}`,B),Error(`Failed to start command for ${M}: ${Z}`)}}else K("watch",`No start command for proxy ${$.from} -> ${$.to}`,B)}else if("start"in _&&_.start){K("watch","Found start command in single proxy config",B);let $=`${_.from}-${_.to}`;try{if(_.start)K("watch",`Starting command: ${_.start.command}`,B),await D_.startProcess($,_.start,B);let M=new URL(_.from?.startsWith("http")?_.from:`http://${_.from}`),Z=M.hostname||"localhost",z=Number(M.port)||80;try{await a(Z,z,B),K("watch",`Dev server is ready at ${Z}:${z}`,B)}catch(Q){K("watch",`Connection check failed, but continuing with proxy setup: ${Q}`,B),J.warn("Dev server connection check failed. RPX will try to proceed anyway...")}}catch(M){throw K("watch",`Failed to run start command: ${M}`,B),Error(`Failed to run start command: ${M}`)}}else K("watch","No start command found in config",B);let N="proxies"in _&&Array.isArray(_.proxies)?_.proxies[0]?.to:("to"in _)?_.to:"rpx.localhost";if(F.platform!=="win32"&&(_.https||_.cleanup?.hosts!==!1)){if(!m())try{K("sudo","Pre-acquiring sudo credentials for privileged operations",B),v_("sudo -v",{stdio:"inherit"})}catch{K("sudo","Could not pre-acquire sudo credentials",B)}}if(_.https){let $=await c(_);if(!$){if(K("ssl",`No valid or trusted certificates found for ${N}, generating new ones`,_.verbose),await K_(_),$=await c(_),!$)throw Error(`Failed to load SSL certificates after generation for ${N}`)}else K("ssl",`Using existing and trusted certificates for ${N}`,_.verbose);_._cachedSSLConfig=$}let Y="proxies"in _&&Array.isArray(_.proxies)?_.proxies.map(($)=>({...$,https:_.https,cleanup:_.cleanup,cleanUrls:$.cleanUrls??("cleanUrls"in _?_.cleanUrls:!1),vitePluginUsage:_.vitePluginUsage,changeOrigin:$.changeOrigin??_.changeOrigin,verbose:B,_cachedSSLConfig:_._cachedSSLConfig})):[{from:"from"in _?_.from:"localhost:5173",to:"to"in _?_.to:"rpx.localhost",cleanUrls:"cleanUrls"in _?_.cleanUrls:!1,https:_.https,cleanup:_.cleanup,vitePluginUsage:_.vitePluginUsage,start:"start"in _?_.start:void 0,changeOrigin:_.changeOrigin,verbose:B,_cachedSSLConfig:_._cachedSSLConfig}],W=Y.map(($)=>$.to||"rpx.localhost"),G=_._cachedSSLConfig,V=W.filter(($)=>$&&!$.includes("localhost")&&!$.includes("127.0.0.1")),X=["dev","app","page","new","day","foo"],A=["test","localhost","local","example","invalid"],T=[...new Set(V.map(($)=>$.split(".").pop()?.toLowerCase()))],I=T.filter(($)=>!!$&&X.includes($));if(I.length>0&&B)J.warn(`The following TLDs may not work reliably for local development: ${I.map(($)=>`.${$}`).join(", ")}`),J.info(" These TLDs have HSTS preloading which can bypass local DNS"),J.info(" Consider using reserved TLDs: .test, .localhost, or .local");if(F.platform==="darwin"&&V.length>0){let{setupDevelopmentDns:$}=await import("./chunk-1j4gp3f8.js");if(await $({domains:V,verbose:B})){if(B)if(T.every((z)=>!!z&&A.includes(z)))J.success(`DNS server started for ${T.map((z)=>`.${z}`).join(", ")} domains`);else J.success(`DNS server started for ${T.map((z)=>`.${z}`).join(", ")} domains (hosts file entries also added)`)}else K("dns","Could not start DNS server - custom domains may not resolve",B)}let R=async()=>{K("cleanup","Starting cleanup handler",_.verbose);try{let{tearDownDevelopmentDns:$}=await import("./chunk-1j4gp3f8.js");await $({verbose:_.verbose})}catch($){K("cleanup",`Error stopping DNS server: ${$}`,_.verbose)}try{await D_.stopAll(_.verbose)}catch($){K("cleanup",`Error stopping processes: ${$}`,_.verbose)}await d({domains:W,hosts:typeof _.cleanup==="boolean"?_.cleanup:_.cleanup?.hosts,certs:typeof _.cleanup==="boolean"?_.cleanup:_.cleanup?.certs,verbose:_.verbose||!1})};if(F.on("SIGINT",R),F.on("SIGTERM",R),F.on("uncaughtException",($)=>{K("process",`Uncaught exception: ${$}`,!0),console.error("Uncaught exception:",$),R()}),G&&Y.length>1){K("proxies",`Creating shared HTTPS server for ${Y.length} domains`,B);let $=new Map;for(let Q of Y){let E=Q.to||"rpx.localhost",w=new URL(Q.from?.startsWith("http")?Q.from:`http://${Q.from}`);if($.set(E,{sourceHost:w.host,cleanUrls:Q.cleanUrls||!1,changeOrigin:Q.changeOrigin||!1,pathRewrites:Q.pathRewrites}),K("proxies",`Route: ${E} → ${w.host}`,B),!E.includes("localhost")&&!E.includes("127.0.0.1"))try{if(!(await h([E],B))[0])await L([E],B)}catch{K("hosts",`Could not add hosts entry for ${E}`,B)}}if(!await x(80,"0.0.0.0",B))P_(B);let Z=443;if(await x(Z,"0.0.0.0",B)){if(K("proxies",`Port ${Z} is already in use, cannot start shared proxy`,B),B)J.warn(`Port ${Z} is in use. Shared HTTPS proxy cannot start.`);return}try{let Q=Bun.serve({port:Z,hostname:"0.0.0.0",tls:{key:G.key,cert:G.cert,ca:G.ca,requestCert:!1,rejectUnauthorized:!1},fetch:M_((E)=>$.get(E),B),error(E){return K("server",`Shared proxy server error: ${E}`,B),new Response(`Server Error: ${E.message}`,{status:500})}});l.add(Q),K("proxies",`Shared HTTPS proxy listening on port ${Z} for ${$.size} domains`,B)}catch(Q){K("proxies",`Failed to start shared proxy: ${Q}`,B),console.error("Failed to start shared HTTPS proxy:",Q),R()}}else for(let $ of Y)try{let M=$.to||"rpx.localhost";K("proxy",`Starting proxy for ${M} with SSL config: ${!!G}`,$.verbose),await T_({from:$.from||"localhost:5173",to:M,cleanUrls:$.cleanUrls||!1,https:$.https||!1,cleanup:$.cleanup||!1,vitePluginUsage:$.vitePluginUsage||!1,verbose:$.verbose||!1,_cachedSSLConfig:G,changeOrigin:$.changeOrigin||!1})}catch(M){K("proxies",`Failed to start proxy for ${$.to}: ${M}`,$.verbose),console.error(`Failed to start proxy for ${$.to}:`,M),R()}}function f_(D){if(D?.vitePluginUsage||!D?.verbose)return;if(console.log(""),console.log(` ${H.green(H.bold("rpx"))} ${H.green(`v${b_}`)}`),console.log(` ${H.green("➜")} ${H.dim(D?.from??"")} ${H.dim("➜")} ${H.cyan(D?.ssl?`https://${D?.to}`:`http://${D?.to}`)}`),D?.listenPort!==(D?.ssl?443:80))console.log(` ${H.green("➜")} Listening on port ${D?.listenPort}`);if(D?.cleanUrls)console.log(` ${H.green("➜")} Clean URLs enabled`)}var rD=F_;export{G_ as writeEntry,S2 as watchRegistry,s_ as verifyHttpsChain,W2 as trustRootCaForBrowsers,c2 as tearDownDevelopmentDns,h2 as syncDevelopmentDnsFromRegistry,x2 as stopDnsServer,n2 as stopDaemon,T_ as startServer,p_ as startProxy,F_ as startProxies,q2 as startDnsServer,O2 as setupResolver,L2 as setupDevelopmentDns,C as safeStringify,GB as safeDeleteFile,t as runViaDaemon,g2 as runDaemon,f2 as resolverFilePath,j2 as resolverBasenamesForDomains,w2 as resolverBasenameForDomain,$B as resolvePathRewrite,u2 as removeResolver,P2 as removeLegacyTldResolvers,Z_ as removeHosts,W_ as removeEntry,p2 as releaseDaemonLock,oD as redactSensitive,m2 as reconcileStaleDevelopmentDns,t2 as reconcileDevelopmentDnsOnIdle,E2 as readEntry,l2 as readDaemonPid,n_ as readCertSha256Fingerprint,t_ as readCertCommonName,z2 as readAll,Y2 as pruneStaleRootCas,u_ as portManager,o_ as parseSha256HashesFromSecurityListing,i_ as normalizeSha256Fingerprint,I2 as normalizeDevDomain,Q2 as loadSSLConfig,N2 as listCertSha256HashesByCommonName,_B as isValidRootCA,$_ as isValidId,NB as isSingleProxyOptions,YB as isSingleProxyConfig,$2 as isRootCaTrustedForSsl,G2 as isRootCaFingerprintInKeychains,x as isPortInUse,R2 as isPidAlive,KB as isMultiProxyOptions,BB as isMultiProxyConfig,U2 as isDnsServerRunning,a2 as isDaemonRunning,V2 as isCertTrusted,N_ as httpsConfig,m as getSudoPassword,J2 as getSharedDaemonCertPaths,X2 as getRootCAPaths,Y_ as getRegistryDir,DB as getPrimaryDomain,K2 as getMacosTrustKeychains,B2 as getMacosLoginKeychainPath,v2 as getDaemonRpxDir,b2 as getDaemonPidPath,K_ as generateCertificate,M2 as gcStaleEntries,Z2 as forceTrustCertificate,U_ as findAvailablePort,eD as extractHostname,sD as execSudoSync,X_ as ensureDaemonRunning,H2 as devDomainsFromHosts,k_ as deriveIdFromTarget,i2 as defaultDaemonSpawnCommand,B_ as defaultConfig,rD as default,K as debugLog,M_ as createProxyFetchHandler,y2 as contentLooksLikeRpxResolver,B_ as config,H as colors,A2 as clearSslConfigCache,z_ as cleanupCertificates,d as cleanup,h as checkHosts,c as checkExistingCertificates,r_ as certIncludesSanHostnames,L as addHosts,d2 as acquireDaemonLock,D2 as RPX_ROOT_CA_COMMON_NAME,C2 as RPX_RESOLVER_MARKER,_2 as MACOS_SYSTEM_KEYCHAIN,e_ as MACOS_CA_TRUST_FLAGS,F2 as LEGACY_TLD_RESOLVER_LABELS,b as DefaultPortManager,T2 as DNS_STATE_VERSION,k2 as DNS_PORT};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/rpx",
3
3
  "type": "module",
4
- "version": "0.11.10",
4
+ "version": "0.11.12",
5
5
  "description": "A modern and smart reverse proxy.",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",
7
7
  "license": "MIT",
package/src/hosts.ts CHANGED
@@ -8,6 +8,14 @@ import { debugLog, getSudoPassword } from './utils'
8
8
 
9
9
  const execAsync = promisify(exec)
10
10
 
11
+ /** `.localhost` names resolve to loopback per RFC 6761 — no /etc/hosts entry needed. */
12
+ export function isLoopbackDevelopmentHost(host: string): boolean {
13
+ const normalized = host.trim().toLowerCase()
14
+ return normalized === 'localhost'
15
+ || normalized.endsWith('.localhost')
16
+ || normalized.endsWith('.localhost.')
17
+ }
18
+
11
19
  export const hostsFilePath: string = process.platform === 'win32'
12
20
  ? path.join(process.env.windir || 'C:\\Windows', 'System32', 'drivers', 'etc', 'hosts')
13
21
  : '/etc/hosts'
@@ -42,9 +50,14 @@ async function execSudo(command: string): Promise<string> {
42
50
  }
43
51
  }
44
52
 
45
- const { stdout } = await execAsync(`sudo sh -c '${escaped}'`)
46
- sudoPrivilegesAcquired = true
47
- return stdout
53
+ try {
54
+ const { stdout } = await execAsync(`sudo -n sh -c '${escaped}'`)
55
+ sudoPrivilegesAcquired = true
56
+ return stdout
57
+ }
58
+ catch {
59
+ throw new Error('sudo required but no cached credentials (set SUDO_PASSWORD in .env or run sudo -v)')
60
+ }
48
61
  }
49
62
  catch (error) {
50
63
  throw new Error(`Failed to execute sudo command: ${(error as Error).message}`)
@@ -52,7 +65,15 @@ async function execSudo(command: string): Promise<string> {
52
65
  }
53
66
 
54
67
  export async function addHosts(hosts: string[], verbose?: boolean): Promise<void> {
55
- debugLog('hosts', `Adding hosts: ${hosts.join(', ')}`, verbose)
68
+ const needsHostsFile = hosts.filter(h => !isLoopbackDevelopmentHost(h))
69
+ const skipped = hosts.filter(h => isLoopbackDevelopmentHost(h))
70
+ if (skipped.length > 0) {
71
+ debugLog('hosts', `Skipping /etc/hosts for loopback dev names: ${skipped.join(', ')}`, verbose)
72
+ }
73
+ if (needsHostsFile.length === 0)
74
+ return
75
+
76
+ debugLog('hosts', `Adding hosts: ${needsHostsFile.join(', ')}`, verbose)
56
77
  debugLog('hosts', `Using hosts file at: ${hostsFilePath}`, verbose)
57
78
 
58
79
  try {
@@ -76,7 +97,7 @@ export async function addHosts(hosts: string[], verbose?: boolean): Promise<void
76
97
  }
77
98
 
78
99
  // Prepare new entries, only including those that don't exist
79
- const newEntries = hosts.filter((host) => {
100
+ const newEntries = needsHostsFile.filter((host) => {
80
101
  const ipv4Entry = `127.0.0.1 ${host}`
81
102
  const ipv6Entry = `::1 ${host}`
82
103
  return !existingContent.includes(ipv4Entry) && !existingContent.includes(ipv6Entry)
package/src/utils.ts CHANGED
@@ -28,7 +28,13 @@ export function execSudoSync(command: string): string {
28
28
  })
29
29
  }
30
30
 
31
- return execSync(`sudo sh -c '${escaped}'`, { encoding: 'utf-8' })
31
+ // Never block on an interactive password prompt — dev servers must start headlessly.
32
+ try {
33
+ return execSync(`sudo -n sh -c '${escaped}'`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] })
34
+ }
35
+ catch {
36
+ throw new Error('sudo required but no cached credentials (set SUDO_PASSWORD in .env or run sudo -v)')
37
+ }
32
38
  }
33
39
 
34
40
  export function debugLog(category: string, message: string, verbose?: boolean): void {