@stacksjs/rpx 0.11.9 → 0.11.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/start.ts CHANGED
@@ -877,10 +877,10 @@ export function startProxy(options: ProxyOption): void {
877
877
  }
878
878
 
879
879
  if (isCustomDomain) {
880
- import('./dns').then(({ startDnsServer, setupResolver }) => {
881
- startDnsServer([targetDomain], mergedOptions.verbose).then((started) => {
880
+ import('./dns').then(({ setupDevelopmentDns }) => {
881
+ setupDevelopmentDns({ domains: [targetDomain], verbose: mergedOptions.verbose }).then((started) => {
882
882
  if (started) {
883
- setupResolver(mergedOptions.verbose, [targetDomain]).then(() => {
883
+ Promise.resolve().then(() => {
884
884
  if (mergedOptions.verbose) {
885
885
  if (reservedTlds.includes(tld)) {
886
886
  log.success(`DNS server started for .${tld} domains`)
@@ -1152,10 +1152,9 @@ export async function startProxies(options?: ProxyOptions): Promise<void> {
1152
1152
  }
1153
1153
 
1154
1154
  if (process.platform === 'darwin' && customDomains.length > 0) {
1155
- const { startDnsServer, setupResolver } = await import('./dns')
1156
- const dnsStarted = await startDnsServer(customDomains, verbose)
1155
+ const { setupDevelopmentDns } = await import('./dns')
1156
+ const dnsStarted = await setupDevelopmentDns({ domains: customDomains, verbose })
1157
1157
  if (dnsStarted) {
1158
- await setupResolver(verbose, customDomains)
1159
1158
  if (verbose) {
1160
1159
  const hasReservedOnly = uniqueTlds.every((t): t is string => !!t && reservedTlds.includes(t as string))
1161
1160
  if (hasReservedOnly) {
@@ -1177,9 +1176,8 @@ export async function startProxies(options?: ProxyOptions): Promise<void> {
1177
1176
 
1178
1177
  try {
1179
1178
  // Stop DNS server
1180
- const { stopDnsServer, removeResolver } = await import('./dns')
1181
- stopDnsServer(mergedOptions.verbose)
1182
- await removeResolver(mergedOptions.verbose)
1179
+ const { tearDownDevelopmentDns } = await import('./dns')
1180
+ await tearDownDevelopmentDns({ verbose: mergedOptions.verbose })
1183
1181
  }
1184
1182
  catch (err) {
1185
1183
  debugLog('cleanup', `Error stopping DNS server: ${err}`, mergedOptions.verbose)
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 {
@@ -1 +0,0 @@
1
- import{a as X,d as F}from"./chunk-jpf41gb9.js";import Q from"node:dgram";var $=15353;function _(k){return{id:k.readUInt16BE(0),flags:k.readUInt16BE(2),qdcount:k.readUInt16BE(4),ancount:k.readUInt16BE(6),nscount:k.readUInt16BE(8),arcount:k.readUInt16BE(10)}}function C(k,z){let A=[],j=z;while(!0){let B=k[j];if(B===0){j++;break}if((B&192)===192){let G=k.readUInt16BE(j)&16383,{name:E}=C(k,G);A.push(E),j+=2;break}j++,A.push(k.subarray(j,j+B).toString("ascii")),j+=B}return{name:A.join("."),newOffset:j}}function H(k,z){let{name:A,newOffset:j}=C(k,z),B=k.readUInt16BE(j),G=k.readUInt16BE(j+2);return{question:{name:A,type:B,class:G},newOffset:j+4}}function U(k){let z=k.split("."),A=[];for(let j of z)A.push(Buffer.from([j.length])),A.push(Buffer.from(j,"ascii"));return A.push(Buffer.from([0])),Buffer.concat(A)}function T(k,z,A){let j=[],B=Buffer.alloc(12);B.writeUInt16BE(k,0),B.writeUInt16BE(33152,2),B.writeUInt16BE(1,4),B.writeUInt16BE(1,6),B.writeUInt16BE(0,8),B.writeUInt16BE(0,10),j.push(B),j.push(U(z.name));let G=Buffer.alloc(4);G.writeUInt16BE(z.type,0),G.writeUInt16BE(z.class,2),j.push(G),j.push(U(z.name));let E=Buffer.alloc(10);if(E.writeUInt16BE(z.type,0),E.writeUInt16BE(1,2),E.writeUInt32BE(300,4),z.type===1){E.writeUInt16BE(4,8),j.push(E);let K=A.split(".").map((M)=>Number.parseInt(M,10));j.push(Buffer.from(K))}else if(z.type===28)E.writeUInt16BE(16,8),j.push(E),j.push(Buffer.from([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]));else return B.writeUInt16BE(33155,2),B.writeUInt16BE(0,6),Buffer.concat([B,U(z.name),G]);return Buffer.concat(j)}function I(k,z){let A=[],j=Buffer.alloc(12);j.writeUInt16BE(k,0),j.writeUInt16BE(33155,2),j.writeUInt16BE(1,4),j.writeUInt16BE(0,6),j.writeUInt16BE(0,8),j.writeUInt16BE(0,10),A.push(j),A.push(U(z.name));let B=Buffer.alloc(4);return B.writeUInt16BE(z.type,0),B.writeUInt16BE(z.class,2),A.push(B),Buffer.concat(A)}var J=null,Z=new Set;async function R(k,z){if(J)return F("dns","DNS server already running",z),!0;return Z=new Set(k.map((A)=>A.toLowerCase())),new Promise((A)=>{J=Q.createSocket("udp4"),J.on("error",(j)=>{if(F("dns",`DNS server error: ${j.message}`,z),j.message.includes("EACCES")||j.message.includes("permission"))F("dns","DNS server requires root privileges to bind to port 53",z);J?.close(),J=null,A(!1)}),J.on("message",(j,B)=>{try{let G=_(j),{question:E}=H(j,12);F("dns",`Query for ${E.name} type ${E.type} from ${B.address}`,z);let K=E.name.toLowerCase(),M=!1;for(let Y of Z)if(K===Y||K.endsWith(`.${Y}`)){M=!0;break}let W;if(M&&(E.type===1||E.type===28))W=T(G.id,E,"127.0.0.1"),F("dns",`Responding with localhost for ${E.name}`,z);else W=I(G.id,E),F("dns",`NXDOMAIN for ${E.name}`,z);J?.send(W,B.port,B.address)}catch(G){F("dns",`Error processing DNS query: ${G}`,z)}}),J.on("listening",()=>{let j=J?.address();F("dns",`DNS server listening on ${j?.address}:${j?.port}`,z),A(!0)});try{J.bind($,"127.0.0.1")}catch(j){F("dns",`Failed to bind DNS server: ${j}`,z),A(!1)}})}function O(k){if(J)F("dns","Stopping DNS server",k),J.close(),J=null}function w(){return J!==null}function x(k){let z=new Set;for(let A of k){let j=A.split(".");if(j.length>=2)z.add(j[j.length-1])}return Array.from(z)}var V=new Set;async function D(k){if(process.platform!=="darwin")return;let{execSudoSync:z,getSudoPassword:A}=await import("./chunk-qcdcnadb.js");if(!A()){F("dns","Cannot flush DNS cache without SUDO_PASSWORD",k);return}try{z("dscacheutil -flushcache"),z("killall -HUP mDNSResponder 2>/dev/null || true"),F("dns","DNS cache flushed",k)}catch(B){F("dns",`Could not flush DNS cache: ${B}`,k)}}async function y(k,z){if(process.platform!=="darwin")return F("dns","Resolver setup only needed on macOS",k),!0;let{execSudoSync:A,getSudoPassword:j}=await import("./chunk-qcdcnadb.js");if(!j())return F("dns","SUDO_PASSWORD not set, cannot create resolver files",k),!1;let G=z?x(z):["test"];try{for(let E of G){if(V.has(E))continue;let K=`bash -c 'mkdir -p /etc/resolver && echo -e "nameserver 127.0.0.1\\nport ${$}" > /etc/resolver/${E}'`;A(K),V.add(E),F("dns",`Created /etc/resolver/${E} for .${E} TLD`,k)}return await D(k),!0}catch(E){return F("dns",`Failed to create resolver file: ${E}`,k),!1}}async function L(k){if(process.platform!=="darwin")return;let{execSudoSync:z,getSudoPassword:A}=await import("./chunk-qcdcnadb.js");try{if(A()){for(let B of V)z(`rm -f /etc/resolver/${B}`),F("dns",`Removed /etc/resolver/${B}`,k);V.clear()}}catch(j){F("dns",`Failed to remove resolver files: ${j}`,k)}}export{O as stopDnsServer,R as startDnsServer,y as setupResolver,L as removeResolver,w as isDnsServerRunning};
@@ -1 +0,0 @@
1
- import{b as a,c as b,d as c,e as d,f as e,g as f,h as g,i as h,j as i,k as j,l as k,m as l,n as m,o as n}from"./chunk-jpf41gb9.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};