@expo/serve-sim 0.10.1 → 0.10.2-canary-20261019-059ca8e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/middleware.js
CHANGED
|
@@ -106,7 +106,7 @@ button:hover{background:#ccc}
|
|
|
106
106
|
${Z?"Could not deliver the capture proxy's startup credentials.":q||R.trim()||"No output from mitmproxy."}`);if(v1(W)&&b){if(!vE(G))throw await P(),new RW("Another capture saved the shared CA first; starting again with it.");return T=!0,{address:`127.0.0.1:${Y}`,portFile:N,caPem:async()=>w5(W,"utf8"),setFields:(B)=>{v(B),z.setFields(B)},close:P}}await new Promise((B)=>setTimeout(B,GE))}let E=v1(W)?"It started but its reporting addon never loaded, so nothing would have been captured.":`Check that no other process holds 127.0.0.1:${Y}.`;throw await P(),Error(`The capture proxy did not start within ${Gj/1000}s. ${E}
|
|
107
107
|
${R.trim()}`)}function PE($){let J=b$($,"capture-fields");return{path:J,write(Q){let X=`${J}.${Dj(4).toString("hex")}.tmp`;LW(X,Q.join(","),{mode:384}),Ij(X,J)}}}function TE($){let J=$ instanceof Error?$.message:String($);return/EADDRINUSE|address already in use/i.test(J)}async function Vj($,J={}){ZE();let Q=zE();if(!Q)throw Error(DE(process.env.SERVE_SIM_MITMDUMP));let X=jE(),_=J.fields??K1,U=J.upstream??null,Y;for(let G=0;G<WE;G++)try{return await AE($,J,Q,X,_,U)}catch(W){if(Y=W,!TE(W)&&!(W instanceof RW)&&!(W instanceof Q8))throw W}throw Y}var ZW,Gj=30000,GE=200,WE=3,Hj="serve-sim-capture-",BJ,Wj="mitmproxy-ca-cert.pem",NE="SERVE_SIM_CAPTURE_CA_DIR",RW,IE,BE=60000,Mj,PW,Nj=!1,RE="SERVE_SIM_CAPTURE_FIELDS_FILE";var TW=_$(()=>{s_();k1();j0();B0();Yj();ZW=y4(import.meta.url),BJ=["mitmproxy-ca.pem","mitmproxy-ca-cert.pem"];RW=class RW extends Error{};IE=["/opt/homebrew/bin/mitmdump","/usr/local/bin/mitmdump","/Applications/mitmproxy.app/Contents/MacOS/mitmdump"];Mj=["SIGINT","SIGTERM","SIGHUP"],PW=new Set});import{execFile as EE,execFileSync as qE}from"child_process";import{promisify as CE}from"util";function Oj($,J){return $[0]==="getenv"&&$[2]==="DYLD_INSERT_LIBRARIES"||$[0]==="spawn"&&$[2]==="launchctl"&&$[3]==="getenv"&&$[4]==="DYLD_INSERT_LIBRARIES"?J.replace(/\n$/,""):J.trim()}function Fj($){let J=typeof $==="number"?{timeout:$}:$;return{timeout:J.timeout??kE,maxBuffer:J.maxBuffer??xE,...J.env?{env:J.env}:{}}}async function EW($,J={}){let Q=Fj(J),{stdout:X}=await SE("xcrun",["simctl",...$],{encoding:"utf-8",timeout:Q.timeout,maxBuffer:Q.maxBuffer,env:{...$[0]==="boot"||$[0]==="bootstatus"?X2($[1]):process.env,...Q.env}}).catch((_)=>{if(_ instanceof Error&&"stdout"in _)delete _.stdout;if(_ instanceof Error&&"code"in _&&_.code==="ERR_CHILD_PROCESS_STDIO_MAXBUFFER")throw _;let U=_ instanceof Error&&"stderr"in _?String(_.stderr).trim():"";throw U?Error(`simctl ${$[0]}: ${U}`,{cause:_}):_});return X}async function j$($,J={}){return Oj($,await EW($,J))}function V0($,J={}){let Q=Fj(J),X=qE("xcrun",["simctl",...$],{encoding:"utf-8",stdio:["ignore","pipe","pipe"],timeout:Q.timeout,maxBuffer:Q.maxBuffer,env:{...process.env,...Q.env}});return Oj($,X)}var SE,kE=30000,xE=4194304;var I1=_$(()=>{G8();SE=CE(EE)});function wE($){let J=$ instanceof Error?$.message:String($);return/Unable to shutdown device in current state: Shutdown/i.test(J)}function b5($){let J=$ instanceof Error?$.message:String($);return/because device is not booted/i.test(J)}async function Aj($){await j$(["shutdown",$],gE).catch((J)=>{if(!wE(J))throw J})}async function Rj($){await j$(["boot",$],Lj),await j$(["bootstatus",$,"-b"],Lj)}var gE=60000,Lj=120000;var MJ=_$(()=>{I1()});var Pj=()=>{};async function Tj($,J){let Q=await $.setEnabled(J);if(!Q)return null;return{capability:{name:$.name,dylib:Q.dylib,env:Q.env,scope:$.scope,loadDelayMs:$.loadDelayMs,loadPhase:$.loadPhase},resources:Q}}function qW($,J){let Q=[];for(let{resources:X}of $)try{X.failed?.(J)}catch(_){Q.push(_)}return Q}async function CW($,J,Q,X=[]){let _=[Q,...X];for(let{resources:U}of[...J].reverse())try{await U.rollback?.(Q)}catch(Y){_.push(Y)}if(_.length>1)throw AggregateError(_,`Capability preparation cleanup failed on ${$}. Retry cleanup before enabling it again.`)}import{existsSync as bE,mkdirSync as fE,readFileSync as yE,renameSync as hE,unlinkSync as mE,writeFileSync as uE}from"fs";import{join as lE}from"path";function nE($){return $==="userApps"||$==="allApps"}function SW($){return lE(I$(),`launch-${$}.json`)}function kW($){if($===null)return!1;try{return process.kill($,0),!1}catch{return!0}}function g$($,J){let Q;try{Q=JSON.parse(yE(SW($),"utf-8"))}catch{return null}if(typeof Q!=="object"||Q===null)return null;let{bundleId:X,launchArgs:_,capabilities:U,sessionPids:Y}=Q;return{...typeof X==="string"&&X?{bundleId:X}:{},launchArgs:Array.isArray(_)?_.filter((G)=>typeof G==="string"):[],capabilities:iE(U,J),...Array.isArray(Y)?{sessionPids:Y.filter((G)=>Number.isInteger(G)&&G>0&&!kW(G))}:{}}}function iE($,J){if(typeof $!=="object"||$===null)return{};let Q={};for(let[X,_]of Object.entries($)){if(typeof _!=="object"||_===null)continue;let{name:U,dylib:Y,scope:G,bundleId:W,ownerPid:N}=_;if(typeof U!=="string"||typeof Y!=="string"||!nE(G))continue;let K=typeof N==="number"?N:null;if(K!==J&&kW(K))continue;Q[X]={..._,bundleId:typeof W==="string"?W:null,ownerPid:K}}return Q}function ZJ($){try{mE(SW($))}catch{}}function O0($,J){if(!bE(I$()))fE(I$(),{recursive:!0});let Q=SW($),X=`${Q}.${process.pid}.tmp`;uE(X,JSON.stringify(J)),hE(X,Q)}var f5=_$(()=>{S4()});import{existsSync as xW,readFileSync as gW,rmSync as Sj,unlinkSync as kj}from"fs";import{basename as cE}from"path";function xj($,J,Q){let X=g$($,J);if(!X)return!1;let _=Object.fromEntries(Object.entries(X.capabilities).filter(([,G])=>G.ownerPid!==J)),U=X.sessionPids?.filter((G)=>G!==J);for(let G of Object.values(X.capabilities))if(G.ownerPid===J)Q?.(G);if(Object.keys(_).length===0&&!U?.length)return ZJ($),!1;let Y={...X,capabilities:_,...U?{sessionPids:U}:{}};return O0($,Y),u6($,m6(Y)),!0}function gj($,J,Q,X){D5($,()=>{let _=K6($);if(!xj($,J,Q))uj($);else mj($,_);J6.delete($)},X)}async function wj($,J,Q){await pG(),await i4($,async()=>{let X=K6($);if(!xj($,J,Q))uj($);else mj($,X);J6.delete($)})}function bj(){return[...J6]}function oE($){let J=cE($);return J===pE||J==="libServeSimTrampoline.dylib"}function wW($,J=[]){let Q=new Set(Q2());return $.split(":").filter((X)=>X!==""&&(Q.has(X)||!oE(X)&&!J.includes(X)))}async function bW($){return j$(["spawn",$,"launchctl","getenv",O4],15000)}function VJ($){return Object.values($).filter((J)=>J.loadPhase==="startup"||J.loadPhase==="startupAndDeferred").map((J)=>J.dylib)}async function dE($,J,Q=g$($)?.capabilities??{},X=K6($)){let _=VJ(Q),U=wW(await bW($),X),Y=[...new Set([...U,J,..._,...Q2()])].join(":");v6($,[...X,..._]),await j$(["spawn",$,"launchctl","setenv",z1,j4($)],15000),await j$(["spawn",$,"launchctl","setenv",O4,Y],15000),v6($,_),J6.add($)}async function fj($){let J=null;try{J=gW(j4($),"utf8")}catch(U){if(U.code!=="ENOENT")throw U}let Q=K6($),X=await bW($),_=(await j$(["spawn",$,"launchctl","getenv",z1],15000)).trim();return{config:J,configPath:_,insert:X,startupDylibs:Q}}async function qj($,J,Q){await j$(["spawn",$,"launchctl",...Q?["setenv",J,Q]:["unsetenv",J]],15000)}async function yj($,J,Q){if(v6($,[...J.startupDylibs,...Q]),J.config===null)Sj(j4($),{force:!0});else u6($,J.config);await qj($,z1,J.configPath),await qj($,O4,J.insert),v6($,J.startupDylibs)}function hj($){for(let J of $)if(!xW(J))throw Error(`Startup capability not built: ${J}. Rebuild the native artifacts before enabling it.`)}async function OJ($,J){let Q=m6(J),X=VJ(J.capabilities);hj(X);let _=await fj($),U=g$($)?.capabilities??{},Y=Object.fromEntries(Object.entries(J.capabilities).filter(([W,N])=>JSON.stringify(U[W])===JSON.stringify(N))),G=m6({...J,capabilities:Y});try{if(u6($,G),await dE($,N6(),J.capabilities,_.startupDylibs),Q!==G)u6($,Q);O0($,J)}catch(W){try{await yj($,_,X)}catch(N){throw new F0([W,N],`Could not restore capability launch state on ${$}. Retry cleanup before launching apps.`)}throw W}}function mj($,J){let Q=VJ(g$($)?.capabilities??{}),X=J.filter((G)=>!Q.includes(G));if(X.length===0)return;let _=V0(["spawn",$,"launchctl","getenv",O4],15000),U=new Set(Q2()),Y=_.split(":").filter((G)=>U.has(G)||!X.includes(G)).join(":");V0(Y?["spawn",$,"launchctl","setenv",O4,Y]:["spawn",$,"launchctl","unsetenv",O4],15000),v6($,Q)}async function y5($){let J=N6();if(!xW(J))throw Error(`Capability loader not found at ${J}, so capabilities on ${$} cannot be restored. Rebuild serve-sim's native artifacts and try again.`);J6.add($),await i4($,async()=>{let Q=g$($)??{launchArgs:[],capabilities:{}};await OJ($,{...Q,sessionPids:[...new Set([...Q.sessionPids??[],process.pid])]})})}function uj($){try{V0(["spawn",$,"launchctl","unsetenv",z1],15000);let J=V0(["spawn",$,"launchctl","getenv",O4],15000),Q=wW(J,K6($)).join(":");V0(Q===""?["spawn",$,"launchctl","unsetenv",O4]:["spawn",$,"launchctl","setenv",O4,Q],15000),v6($,[]);try{kj(j4($))}catch{}}catch(J){console.error(`Could not disarm the capability loader on ${$}; it is still inserted into every app that simulator starts. Clear it with: xcrun simctl spawn ${$} launchctl unsetenv DYLD_INSERT_LIBRARIES (${J instanceof Error?J.message:String(J)})`)}J6.delete($)}async function rE($){await j$(["spawn",$,"launchctl","unsetenv",z1],15000).catch(()=>{return});let J=wW(await bW($),K6($)).join(":");await j$(J===""?["spawn",$,"launchctl","unsetenv",O4]:["spawn",$,"launchctl","setenv",O4,J],15000),v6($,[]);try{kj(j4($))}catch{}J6.delete($)}async function lj($,{bundleId:J,launchArgs:Q=[],restart:X=!1,openUrl:_}){await i4($,async()=>{let U=g$($),Y={...U,bundleId:J,launchArgs:Q,capabilities:U?.capabilities??{}},G;try{G=gW(j4($),"utf8")}catch(v){if(v.code!=="ENOENT")throw v}let W=Object.keys(Y.capabilities).length>0;if(W)hj(VJ(Y.capabilities));let N=W?await fj($):void 0,K=J6.has($);try{if(W)await OJ($,Y);else u6($,m6(Y)),O0($,Y);if(X)await dj($,J);await j$(["launch",$,J,...Q])}catch(v){try{if(U)O0($,U);else ZJ($);if(N){if(await yj($,N,VJ(Y.capabilities)),!K)J6.delete($)}else if(G===void 0)Sj(j4($),{force:!0});else u6($,G)}catch(I){throw new F0([v,I],"Could not restore the previous app launch state.")}throw v}if(_)await nj($,J,_)})}async function nj($,J,Q){await Qq($,J,Q),await j$(["openurl",$,Q])}async function ij($,J,Q){await i4($,()=>nj($,J,Q))}async function cj($,J,Q){await i4($,()=>rj($,J,Q))}async function pj($,J){await i4($,()=>j$(["terminate",$,J]))}function oj($,J,Q){if(!J.exclusive)return!1;let X=g$($)?.capabilities[J.name];return X!==void 0&&X.ownerPid!==Q}function tE($,J,Q){if(oj($,J,Q))throw Error(`Capability ${J.name} on ${$} belongs to another session. Stop that session before enabling it here.`)}async function FJ($,J,{bundleId:Q=null,options:X={},enabled:_,relaunch:U=!0,ownerPid:Y=process.pid}){let G={udid:$,bundleId:Q,options:X,enabled:_};await i4($,async()=>{if(!_){if(!oj($,J,Y))await $q($,Q,J.name,{relaunch:!1});await J.setEnabled(G);return}tE($,J,Y);let W=await Tj(J,G);if(!W)throw Error(`Capability ${J.name} declined to start on ${$}. Check its configuration and retry.`);if(await aE($,Q,[W],Y),U){let N=g$($);if(N)await fW($,Q,N)}})}async function aE($,J,Q,X=process.pid){let _=g$($);try{let U=Q.map(({capability:Y})=>Y);await sE($,J,U,{relaunch:!1,ownerPid:X})}catch(U){let Y=qW(Q,U);if(U instanceof F0){if(Y.length>0)throw new F0([U,...Y],U.message);throw U}throw await CW($,Q,U,Y),U}try{for(let{resources:U}of Q)U.committed?.()}catch(U){let Y=qW(Q,U);try{if(_)await OJ($,_);else await rE($),ZJ($)}catch(G){throw new F0([U,G,...Y],`Could not withdraw a failed capability on ${$}; its resources were kept. Retry cleanup before launching apps.`)}throw await CW($,Q,U,Y),U}}function LJ($,J){let Q=g$($);return Q!==null&&J in Q.capabilities}async function sE($,J,Q,{relaunch:X=!0,ownerPid:_=process.pid}={}){if(Q.length===0)return;let U=N6();if(!xW(U))throw Error(`Capability loader not built: ${U} is missing. Run \`bun run packages/serve-sim/build.ts\` to build the native artifacts, then retry.`);let Y=g$($),G=Object.fromEntries(Q.map((N)=>[N.name,{...N,bundleId:J,ownerPid:_}])),W={...Y??{launchArgs:[],capabilities:{}},capabilities:{...Y?.capabilities,...G}};if(await OJ($,W),X)await fW($,J,W)}async function eE($,J){let Q=await j$(["spawn",$,"launchctl","list"],15000).catch(()=>null);if(Q===null)return null;return Q.includes(`UIKitApplication:${J}`)}async function dj($,J){try{await j$(["terminate",$,J],Ej);return}catch{}let Q=await eE($,J);if(Q===!1)return;throw Error(Q===null?`Could not stop ${J} on ${$}, and could not check whether it is still running. Relaunching now would do nothing if it is. Check the simulator and retry.`:`Could not stop ${J} on ${$}, so it cannot be relaunched with its capabilities loaded. simctl terminate did not take effect within ${Ej/1000}s. Stop the app yourself and retry.`)}async function fW($,J,Q){let X=J??Q.bundleId;if(!X)return;let _=X===Q.bundleId?Q.launchArgs:[];await dj($,X),await j$(["launch",$,X,..._])}async function Cj($,J){try{return await OJ($,J),!0}catch(Q){if(!b5(Q))throw Q;return O0($,J),!1}}async function $q($,J,Q,{relaunch:X=!0}={}){let _=g$($);if(!_||!(Q in _.capabilities)){if(K6($).length>0)await Cj($,_??{launchArgs:[],capabilities:{}});return}let U=Object.fromEntries(Object.entries(_.capabilities).filter(([W])=>W!==Q)),Y={..._,capabilities:U},G=await Cj($,Y);if(X&&G)await fW($,J,Y)}async function Qq($,J,Q){let X=new URL(Q).protocol.slice(0,-1);if(X==="http"||X==="https")return;try{await rj($,J,X)}catch{console.error(`Could not pre-approve the ${X}: URL scheme for ${J}. Opening the URL anyway; the Simulator may ask you to confirm it.`)}}async function rj($,J,Q){await j$(["spawn",$,"defaults","write",Jq,`${_q}${Q}`,"-string",J],15000)}async function h5($,J,Q={},X=j$){let _=g$($)?.capabilities[J];if(!_||Object.entries(Q).some(([z,D])=>_.env?.[z]!==D))return!1;let U=j4($);if(((await X(["spawn",$,"launchctl","getenv",z1])).trim()||(await X(["getenv",$,z1]).catch(()=>"")).trim())!==U)return!1;let G;try{G=gW(U,"utf8")}catch(z){if(z.code==="ENOENT")return!1;throw z}let W=m6({launchArgs:[],capabilities:{[J]:_}}).trimEnd().split(`
|
|
108
108
|
`),N=new Set(G.split(`
|
|
109
|
-
`));if(!W.every((z)=>N.has(z)))return!1;let v=(await X(["spawn",$,"launchctl","getenv",O4])||await X(["getenv",$,O4]).catch(()=>"")).split(":"),I=_.loadPhase==="startup"||_.loadPhase==="startupAndDeferred";return v.includes(N6())&&(!I||v.includes(_.dylib))}var pE="libServeSimCapabilityLoader.dylib",O4="DYLD_INSERT_LIBRARIES",z1="SERVE_SIM_CAPABILITIES_CONFIG",Ej=15000,J6,F0,Jq="com.apple.launchservices.schemeapproval",_q="com.apple.CoreSimulator.CoreSimulatorBridge-->";var D1=_$(()=>{Pj();Y8();f5();H0();MJ();I1();G8();f5();Y8();H0();J6=new Set;F0=class F0 extends AggregateError{}});import{existsSync as Xq,mkdtempSync as Uq,readFileSync as Yq,rmSync as Gq,writeFileSync as Wq}from"node:fs";import{tmpdir as Nq}from"node:os";import{join as AJ}from"node:path";async function tj($,J){let Q=Uq(AJ(Nq(),"serve-sim-ca-")),X=AJ(Q,"capture-root.crt");try{Wq(X,J),await j$(["keychain",$,"add-root-cert",X])}finally{Gq(Q,{recursive:!0,force:!0})}}function Kq(){return[AJ(yW,"simnet",hW),AJ(yW,"..","dist","simnet",hW),AJ(yW,"..","..","dist","simnet",hW)]}function aj(){return Kq().find(($)=>Xq($))??null}async function sj($,J,Q={}){let X;try{X=Number(Yq(J,"utf8").trim())}catch(_){if(_.code==="ENOENT")return!1;throw _}if(!Number.isInteger(X)||X<1||X>65535||Q.expectedPort!==void 0&&X!==Q.expectedPort)return!1;return h5($,"networkCapture",{SIMNET_PROXY_PORT_FILE:J},Q.read)}var yW,hW="libSimNetProxy.dylib";var ej=_$(()=>{D1();k1();I1();yW=y4(import.meta.url)});import{readFileSync as vq}from"node:fs";import{dirname as Iq,join as zq}from"node:path";import{fileURLToPath as Dq}from"node:url";function m5(){return"0.10.
|
|
109
|
+
`));if(!W.every((z)=>N.has(z)))return!1;let v=(await X(["spawn",$,"launchctl","getenv",O4])||await X(["getenv",$,O4]).catch(()=>"")).split(":"),I=_.loadPhase==="startup"||_.loadPhase==="startupAndDeferred";return v.includes(N6())&&(!I||v.includes(_.dylib))}var pE="libServeSimCapabilityLoader.dylib",O4="DYLD_INSERT_LIBRARIES",z1="SERVE_SIM_CAPABILITIES_CONFIG",Ej=15000,J6,F0,Jq="com.apple.launchservices.schemeapproval",_q="com.apple.CoreSimulator.CoreSimulatorBridge-->";var D1=_$(()=>{Pj();Y8();f5();H0();MJ();I1();G8();f5();Y8();H0();J6=new Set;F0=class F0 extends AggregateError{}});import{existsSync as Xq,mkdtempSync as Uq,readFileSync as Yq,rmSync as Gq,writeFileSync as Wq}from"node:fs";import{tmpdir as Nq}from"node:os";import{join as AJ}from"node:path";async function tj($,J){let Q=Uq(AJ(Nq(),"serve-sim-ca-")),X=AJ(Q,"capture-root.crt");try{Wq(X,J),await j$(["keychain",$,"add-root-cert",X])}finally{Gq(Q,{recursive:!0,force:!0})}}function Kq(){return[AJ(yW,"simnet",hW),AJ(yW,"..","dist","simnet",hW),AJ(yW,"..","..","dist","simnet",hW)]}function aj(){return Kq().find(($)=>Xq($))??null}async function sj($,J,Q={}){let X;try{X=Number(Yq(J,"utf8").trim())}catch(_){if(_.code==="ENOENT")return!1;throw _}if(!Number.isInteger(X)||X<1||X>65535||Q.expectedPort!==void 0&&X!==Q.expectedPort)return!1;return h5($,"networkCapture",{SIMNET_PROXY_PORT_FILE:J},Q.read)}var yW,hW="libSimNetProxy.dylib";var ej=_$(()=>{D1();k1();I1();yW=y4(import.meta.url)});import{readFileSync as vq}from"node:fs";import{dirname as Iq,join as zq}from"node:path";import{fileURLToPath as Dq}from"node:url";function m5(){return"0.10.2-canary-20261019-059ca8e"}var mW=()=>{};class JH{#$=new Map;enqueue($,J){let Q=this.#$.get($),X=Q?Q.then(J):J(),_=X.then(()=>{},()=>{});return this.#$.set($,_),_.then(()=>{if(this.#$.get($)===_)this.#$.delete($)}),X}devices(){return this.#$.keys()}}function u5($,J){return{schemaVersion:DJ,udid:$,proxyAddress:null,attachment:"not-enabled",attachError:null,droppedOversizedBodies:0,fields:[...J]}}function _H($,J){return{...u5($,J),attachment:"failed",attachError:"Capture was turned off while it was waiting to start. Enable it again to retry."}}function L0($,J,Q){if(J.cancelled)throw new _6(_H($,J.fields??Q))}function uW($,J){return $.length===J.length&&$.every((Q)=>J.includes(Q))}function Mq($){if(QH.add($),$H)return;$H=!0,process.on("exit",Zq)}function Zq(){for(let $ of QH)$()}function lW($={}){let J=$.fields??K1,Q=$.upstream,X=$.startProxy??((V,F)=>Vj(V,F)),_=$.trustCa??tj,U=$.configure??FJ,Y=$.dylib??aj,G=$.isInjected??((V,F,w)=>sj(V,F,{expectedPort:Number(new URL(`http://${w}`).port)})),W=$.checkIntervalMs??jq,N=$.writeDiskArtifacts!==!1,K=$.creatorVersion??"0.0.0",v=new Map,I=()=>{for(let V of v.values())try{V.disk?.discardSync()}catch{}},z=new Map,D=new JH,Z=new Map,R=null,L=new Map,M=new Map,O=(V,F)=>{for(let w of L.get(V)??[])try{w(F)}catch{}},T=(V)=>v.get(V)?.meta??M.get(V)??u5(V,J),q=(V,F)=>{if(!N)return{disk:null,stopDisk:null};if(!$.captureDirFor)QW([...v.keys(),V]);let w=$.captureDirFor?{dir:$.captureDirFor(V),networkCapturePath:void 0,harPath:void 0}:A5(V),y=new W1({dir:w.dir,networkCapturePath:w.networkCapturePath,harPath:w.harPath,creatorVersion:K,flushIntervalMs:$.flushIntervalMs,harRebuildIntervalMs:Bq});return Mq(I),{disk:y,stopDisk:y.attach(F)}},H=async(V,F)=>{if(F.cleanup??=(async()=>{await F.proxy?.close(),F.proxy=null,F.meta.proxyAddress=null,await F.stopDisk?.(),F.stopDisk=null,F.disk=null})().catch((w)=>{throw F.cleanup=void 0,console.warn(`Network capture: cleanup for ${V} failed:`,w),w}),await F.cleanup,v.get(V)===F)v.delete(V)},j=async(V,F)=>{if(R)throw Error(R);if(F)L0(V,F,J);let w=v.get(V);if(w?.proxy){if(w.meta.attachment==="failed")throw Error("The previous capture session failed. Disable capture before retrying so its launch configuration can be removed safely.");if(F)F.session=w;return{dylib:A(),env:{SIMNET_PROXY_PORT_FILE:w.proxy.portFile}}}let y=A(),i=[...F?.fields??J],n=new jJ,c={schemaVersion:DJ,udid:V,proxyAddress:null,attachment:"starting",attachError:null,droppedOversizedBodies:0,fields:i},s={store:n,meta:c,proxy:null,...q(V,n)};if(F)F.session=s;n.subscribe((v$)=>{if(v.get(V)===s)O(V,v$)}),M.delete(V),v.set(V,s),O(V,{type:"cleared"}),O(V,{type:"meta",meta:c});try{let v$=await X(n,{upstream:Q,fields:i,onUnexpectedExit:(D$)=>{if(v.get(V)!==s)return;c.attachment="failed",c.attachError=`${D$}
|
|
110
110
|
|
|
111
111
|
Relaunch apps after restarting capture; their existing sessions may still point at the stopped proxy.`,n.publishMeta(c)},onOversizedControlBody:()=>{if(v.get(V)!==s)return;c.droppedOversizedBodies+=1,n.publishMeta(c)}});if(s.proxy=v$,c.proxyAddress=v$.address,F?.fields&&!uW(i,F.fields))v$.setFields(F.fields),c.fields=[...F.fields];if(F)L0(V,F,J);if(await _(V,await v$.caPem()),F)L0(V,F,J);if(c.attachment==="failed")throw Error(c.attachError??"The capture proxy stopped during startup.");return{dylib:y,env:{SIMNET_PROXY_PORT_FILE:v$.portFile},committed(){if(c.attachment==="failed")throw Error(c.attachError??"The capture proxy stopped during startup.");c.attachment="capturing",n.publishMeta(c)},failed(D$){c.attachment="failed",c.attachError=D$ instanceof Error?D$.message:String(D$),n.publishMeta(c)},async rollback(){if(F)F.failed=!0;await H(V,s),v.set(V,s)}}}catch(v$){if(F)F.failed=!0;throw c.attachment="failed",c.attachError=v$ instanceof Error?v$.message:String(v$),await H(V,s),v.set(V,s),n.publishMeta(c),v$}};function A(){let V=Y();if(!V)throw Error("Network capture library is missing. Rebuild serve-sim's native artifacts before enabling capture.");return V}let P={name:"networkCapture",exclusive:!0,scope:"userApps",loadPhase:"startupAndDeferred",defaultEnabled:!1,async setEnabled({udid:V,enabled:F}){if(F)return j(V);let w=v.get(V);if(w)await H(V,w);if(M.delete(V),!v.has(V))O(V,{type:"meta",meta:u5(V,J)});return null}},g=(V)=>U(V,P,{enabled:!1,relaunch:!1}),b=(V)=>{let F=Z.get(V);if(F)F.cancelled=!0;return Z.delete(V),D.enqueue(V,()=>g(V))},E=(V,F,w)=>{let y=v.get(V);if(y?.proxy&&y.meta.attachment==="starting"&&F.session===y)y.proxy.setFields(w),y.meta.fields=[...w],y.store.publishMeta(y.meta);F.fields=[...w]},B=(V,F)=>{let w=v.get(V);if(!w?.proxy||w.meta.attachment!=="capturing"){let i=Z.get(V);if(!i||i.failed||i.cancelled)return null;return E(V,i,F),T(V)}w.proxy.setFields(F);let y=Z.get(V);if(y&&!y.failed&&y.session===w)y.fields=[...F];return w.meta.fields=[...F],w.store.publishMeta(w.meta),w.meta};return{capability:P,shouldCaptureDevice(V,F){return z.get(V)??F},setDeviceCaptureEnabled(V,F){z.set(V,F)},creatorVersion:K,setUpstream(V){Q=V},setFields(V){J=V},defaultFields(){return J},enableForDevice(V,F){let w=Z.get(V);if(w&&!w.failed&&(F===void 0||uW(w.fields??J,F))){if(F!==void 0)w.fields=[...F];return w.promise}let y=w&&!w.failed?w:void 0,i=y?.promise,n=y??{cancelled:!1,failed:!1,promise:Promise.resolve(u5(V,J))};if(F!==void 0)try{E(V,n,F)}catch(v$){return Promise.reject(v$)}let c=D.enqueue(V,async()=>{if(L0(V,n,J),n.session=v.get(V),i)await i;let v$;try{if(R)throw Error(R);if(v.get(V)?.meta.attachment==="failed")await g(V),L0(V,n,J);if(await U(V,{...P,setEnabled:({enabled:u})=>u?j(V,n):P.setEnabled({udid:V,enabled:!1,bundleId:null,options:{}})},{enabled:!0,relaunch:!1}),n.cancelled)await g(V),L0(V,n,J);let J4=v.get(V);if(!J4)throw Error("The capture session disappeared during startup. Enable capture again.");v$=J4.meta}catch(D$){n.failed=!0;let J4=v.get(V),u=J4?.meta??_H(V,n.fields??J);if(u.attachment="failed",u.attachError=D$ instanceof Error?D$.message:String(D$),J4)J4.store.publishMeta(u);else M.set(V,u),O(V,{type:"meta",meta:u});throw new _6(u)}if(n.fields!==void 0&&!uW(v$.fields,n.fields))B(V,n.fields);return v$});n.promise=c,Z.set(V,n);let s=()=>{if(Z.get(V)===n&&n.promise===c)Z.delete(V)};return c.then(s,s),c},disableForDevice:b,refuseCapture(V){R=V},async disableAll(){let V=new Set([...v.keys(),...M.keys(),...D.devices()]),w=(await Promise.allSettled([...V].map(b))).flatMap((y)=>y.status==="rejected"?[y.reason]:[]);if(w.length>0)throw AggregateError(w,`Could not disable network capture on ${w.length} device(s).`)},discardArtifactsSync:I,subscribe(V,F){let w=L.get(V);if(!w)L.set(V,w=new Set);return w.add(F),{meta:T(V),unsubscribe:()=>{if(w.delete(F),w.size===0&&L.get(V)===w)L.delete(V)}}},metaFor(V){return T(V)},async refreshForDevice(V){let F=v.get(V);if(!F)return T(V);if(F.meta.attachment!=="capturing"||!F.proxy)return F.meta;let w=Date.now();if(F.checking)return F.checking;if(F.checkedAt!==void 0&&w-F.checkedAt<W)return F.meta;let y=F.proxy.portFile,i=F.proxy.address;return F.checking=(async()=>{try{let n;try{n=await G(V,y,i)}catch(c){if(!b5(c))return console.warn(`Network capture: injection probe for ${V} failed:`,c instanceof Error?c.message:c),F.injectMisses=0,F.meta;n=!1}if(n)return F.injectMisses=0,F.meta;if(v.get(V)!==F||F.meta.attachment!=="capturing")return F.meta;if(F.injectMisses=(F.injectMisses??0)+1,F.injectMisses<Hq)return F.meta;return F.meta.attachment="failed",F.meta.attachError="This device stopped capturing. It may have restarted or shut down since capture was enabled. Enable capture again after it boots.",F.store.publishMeta(F.meta),F.meta}finally{F.checkedAt=Date.now(),F.checking=void 0}})(),F.checking},storeFor(V){return v.get(V)?.store??null},artifactPathsFor(V){let F=v.get(V)?.disk;if(!F)return null;return{networkCapturePath:F.networkCapturePath,harPath:F.harPath,entriesPath:F.entriesPath}},async flushEntriesPathFor(V){let F=v.get(V)?.disk;if(!F)return null;return await F.flushEntries(),F.entriesPath},async flushHarPathFor(V){let F=v.get(V)?.disk;if(!F)return null;return await F.flush(),F.harPath},setFieldsForDevice:B,clearForDevice(V){let F=v.get(V);if(!F)return!1;return F.store.clear(),!0},throughputFor(V){let F=v.get(V);if(!F||F.meta.attachment!=="capturing")return null;return F.store.throughput()}}}var _6,jq=1e4,Hq=2,Bq=60000,QH,$H=!1,C$;var l5=_$(()=>{MJ();ej();D1();R5();B0();TW();mW();_6=class _6 extends Error{meta;constructor($){super($.attachError??"Network capture could not start");this.name="CaptureEnableError",this.meta=$}};QH=new Set;C$=lW({creatorVersion:m5()})});var XH=180000;import xi from"ws";function Vq(){let $={};for(let _=0;_<26;_++){let U=4+_;$[String.fromCharCode(97+_)]={usage:U,shift:!1},$[String.fromCharCode(65+_)]={usage:U,shift:!0}}let J="1234567890",Q="!@#$%^&*()";for(let _=0;_<10;_++){let U=30+_;$[J[_]]={usage:U,shift:!1},$[Q[_]]={usage:U,shift:!0}}let X=[["-","_",45],["=","+",46],["[","{",47],["]","}",48],["\\","|",49],[";",":",51],["'",'"',52],["`","~",53],[",","<",54],[".",">",55],["/","?",56]];for(let[_,U,Y]of X)$[_]={usage:Y,shift:!1},$[U]={usage:Y,shift:!0};return $[" "]={usage:44,shift:!1},$[`
|
|
112
112
|
`]={usage:40,shift:!1},$["\t"]={usage:43,shift:!1},$}var UH;var YH=_$(()=>{UH=Vq()});import{execFile as Oq,spawn as Fq}from"child_process";import{existsSync as GH}from"fs";import{tmpdir as Lq}from"os";import{join as RJ,resolve as Aq}from"path";import{promisify as Rq}from"util";function cW(){return R0("serve-sim-pasteboard")}function R0($){let J=process.env.SERVE_SIM_SIMPB_DIR,Q=[...J?[RJ(J,$)]:[],RJ(iW,"..","dist","simpb",$),RJ(iW,"simpb",$)].find(GH);return Q?Aq(Q):null}async function P0($,J){let Q=nW.get($);if(!Q){let _=RJ(iW,"..","Sources",$,"build.sh");if(!GH(_))throw Error(`${$} source not found. Reinstall from a build that includes clipboard support.`);console.error(`[serve-sim] building ${$}…`),Q=Pq("bash",[_]).finally(()=>nW.delete($)),nW.set($,Q)}await Q;let X=R0(J);if(!X)throw Error(`${$} build succeeded but ${J} was not found.`);return X}function R6($,J,Q=Tq){let X=RJ(Lq(),"serve-sim-pasteboard-locks",`${$}.lock`);return A6(X,Q,()=>new A0,J)}function n5($,J){return R6($,()=>pW($,J))}async function pW($,J){let Q=cW()??await P0("SimPasteboard","serve-sim-pasteboard");return new Promise((X,_)=>{let U=Fq("xcrun",["simctl","spawn",$,Q,"--write"],{stdio:["pipe","ignore","pipe"]}),Y="",G=!1,W=null;U.stderr.setEncoding("utf-8"),U.stderr.on("data",(K)=>{Y+=K});let N=setTimeout(()=>{G=!0,U.kill("SIGKILL")},30000);U.once("error",(K)=>{clearTimeout(N),_(K)}),U.once("close",(K)=>{if(clearTimeout(N),G)_(Error("simctl pasteboard write timed out"));else if(K===0&&!W)X();else _(Error(Y.trim()||W?.message||`simctl pasteboard write exited ${K}`))}),U.stdin.once("error",(K)=>{W=K,U.kill("SIGKILL")}),U.stdin.end(J,"utf-8")})}async function oW($,J={}){try{return await EW($,{...J,maxBuffer:w4})}catch(Q){if(Q instanceof Error&&"code"in Q&&Q.code==="ERR_CHILD_PROCESS_STDIO_MAXBUFFER"&&Q.message.startsWith("stdout "))throw new Q6("Simulator clipboard text is too large");throw Q}}async function WH($){return{text:await oW(["pbpaste",$],{env:{LANG:"en_US.UTF-8",LC_ALL:"en_US.UTF-8"}})}}var iW,Pq,Tq=90000,j1=1000,w4=4194304,Q6,A0,nW;var H1=_$(()=>{k1();I1();j0();iW=y4(import.meta.url),Pq=Rq(Oq);Q6=class Q6 extends Error{};A0=class A0 extends Error{constructor(){super("Simulator clipboard is busy. Try again.")}};nW=new Map});function vH($){return KH.includes($)}function IH($,J){let Q=KH.filter((U)=>$.has(U)),X=Q.map((U)=>({type:"up",usage:U})),_=$.has(227)||$.has(231);if(!_)X.push({type:"down",usage:227});if(X.push({type:"down",usage:J}),X.push({type:"up",usage:J}),!_)X.push({type:"up",usage:227});for(let U of Q)X.push({type:"down",usage:U});return X}var NH=6,dW=25,KH;var zH=_$(()=>{KH=[224,228,225,229,226,230]});function rW($,J,Q,X){return R6($,async()=>{return X?.(),await pW($,J),Q()},j1)}var DH=_$(()=>{H1()});import{readFile as jH}from"fs/promises";import{join as HH}from"path";import{setTimeout as Eq}from"timers/promises";function MH($,J){if(J&&$ instanceof Error)Object.assign($,{cleanupWarning:J});return $}function c5($){let J=$ instanceof Error?$.cleanupWarning:void 0;return typeof J==="string"?{cleanupWarning:J}:{}}async function BH($){let J=cW()??await P0("SimPasteboard","serve-sim-pasteboard"),Q=await j$(["spawn",$,J,"--change-count"],3000);if(!/^\d+$/.test(Q))throw Error("Invalid simulator pasteboard change count");let X=Number(Q);if(!Number.isSafeInteger(X))throw Error("Invalid simulator pasteboard change count");return X}async function Sq($,J){let[Q,X]=await Promise.all([jH($),jH(J)]).catch(()=>[null,null]);return!!Q&&!!X&&Q.equals(X)}async function kq($){let J=R0("ServeSimPasteboard.app")??await P0("SimPasteboard","ServeSimPasteboard.app"),Q=HH(J,"serve-sim-pasteboard"),X=await j$(["get_app_container",$,tW,"app"]).catch(()=>null);if(!X||X==="(null)")await j$(["install",$,J]);else if(!await Sq(HH(X,"serve-sim-pasteboard"),Q))await j$(["uninstall",$,tW]),await j$(["install",$,J]);return await j$(["privacy",$,"grant","pasteboard",tW]),Q}async function xq($,J,Q=qq){let X=Date.now()+Q;while(!0){if(await $()!==J)return;let _=X-Date.now();if(_<=0)throw new i5;await Eq(Math.min(Cq,_))}}async function ZH($,J,Q=(X)=>X()){return{text:await Q(()=>R6($,async()=>{let _=await kq($),U=await BH($);return await J(),await xq(()=>BH($),U),oW(["spawn",$,_,"--read-text"],{timeout:8000})},j1))}}var qq=5000,Cq=75,tW="com.expo.serve-sim-pasteboard",i5;var p5=_$(()=>{I1();H1();i5=class i5 extends Error{constructor(){super("The simulator app did not update the clipboard after Copy. Try again after selecting text.")}}});var OH=h6((ei,VH)=>{var T0=1000,E0=T0*60,q0=E0*60,B1=q0*24,gq=B1*7,wq=B1*365.25;VH.exports=function($,J){J=J||{};var Q=typeof $;if(Q==="string"&&$.length>0)return bq($);else if(Q==="number"&&isFinite($))return J.long?yq($):fq($);throw Error("val is not a non-empty string or a valid number. val="+JSON.stringify($))};function bq($){if($=String($),$.length>100)return;var J=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec($);if(!J)return;var Q=parseFloat(J[1]),X=(J[2]||"ms").toLowerCase();switch(X){case"years":case"year":case"yrs":case"yr":case"y":return Q*wq;case"weeks":case"week":case"w":return Q*gq;case"days":case"day":case"d":return Q*B1;case"hours":case"hour":case"hrs":case"hr":case"h":return Q*q0;case"minutes":case"minute":case"mins":case"min":case"m":return Q*E0;case"seconds":case"second":case"secs":case"sec":case"s":return Q*T0;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return Q;default:return}}function fq($){var J=Math.abs($);if(J>=B1)return Math.round($/B1)+"d";if(J>=q0)return Math.round($/q0)+"h";if(J>=E0)return Math.round($/E0)+"m";if(J>=T0)return Math.round($/T0)+"s";return $+"ms"}function yq($){var J=Math.abs($);if(J>=B1)return o5($,J,B1,"day");if(J>=q0)return o5($,J,q0,"hour");if(J>=E0)return o5($,J,E0,"minute");if(J>=T0)return o5($,J,T0,"second");return $+" ms"}function o5($,J,Q,X){var _=J>=Q*1.5;return Math.round($/Q)+" "+X+(_?"s":"")}});var aW=h6(($c,FH)=>{function hq($){Q.debug=Q,Q.default=Q,Q.coerce=W,Q.disable=Y,Q.enable=_,Q.enabled=G,Q.humanize=OH(),Q.destroy=N,Object.keys($).forEach((K)=>{Q[K]=$[K]}),Q.names=[],Q.skips=[],Q.formatters={};function J(K){let v=0;for(let I=0;I<K.length;I++)v=(v<<5)-v+K.charCodeAt(I),v|=0;return Q.colors[Math.abs(v)%Q.colors.length]}Q.selectColor=J;function Q(K){let v,I=null,z,D;function Z(...R){if(!Z.enabled)return;let L=Z,M=Number(new Date),O=M-(v||M);if(L.diff=O,L.prev=v,L.curr=M,v=M,R[0]=Q.coerce(R[0]),typeof R[0]!=="string")R.unshift("%O");let T=0;R[0]=R[0].replace(/%([a-zA-Z%])/g,(H,j)=>{if(H==="%%")return"%";T++;let A=Q.formatters[j];if(typeof A==="function"){let P=R[T];H=A.call(L,P),R.splice(T,1),T--}return H}),Q.formatArgs.call(L,R),(L.log||Q.log).apply(L,R)}if(Z.namespace=K,Z.useColors=Q.useColors(),Z.color=Q.selectColor(K),Z.extend=X,Z.destroy=Q.destroy,Object.defineProperty(Z,"enabled",{enumerable:!0,configurable:!1,get:()=>{if(I!==null)return I;if(z!==Q.namespaces)z=Q.namespaces,D=Q.enabled(K);return D},set:(R)=>{I=R}}),typeof Q.init==="function")Q.init(Z);return Z}function X(K,v){let I=Q(this.namespace+(typeof v>"u"?":":v)+K);return I.log=this.log,I}function _(K){Q.save(K),Q.namespaces=K,Q.names=[],Q.skips=[];let v=(typeof K==="string"?K:"").trim().replace(/\s+/g,",").split(",").filter(Boolean);for(let I of v)if(I[0]==="-")Q.skips.push(I.slice(1));else Q.names.push(I)}function U(K,v){let I=0,z=0,D=-1,Z=0;while(I<K.length)if(z<v.length&&(v[z]===K[I]||v[z]==="*"))if(v[z]==="*")D=z,Z=I,z++;else I++,z++;else if(D!==-1)z=D+1,Z++,I=Z;else return!1;while(z<v.length&&v[z]==="*")z++;return z===v.length}function Y(){let K=[...Q.names,...Q.skips.map((v)=>"-"+v)].join(",");return Q.enable(""),K}function G(K){for(let v of Q.skips)if(U(K,v))return!1;for(let v of Q.names)if(U(K,v))return!0;return!1}function W(K){if(K instanceof Error)return K.stack||K.message;return K}function N(){console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.")}return Q.enable(Q.load()),Q}FH.exports=hq});var AH=h6((LH,d5)=>{LH.formatArgs=uq;LH.save=lq;LH.load=nq;LH.useColors=mq;LH.storage=iq();LH.destroy=(()=>{let $=!1;return()=>{if(!$)$=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.")}})();LH.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"];function mq(){if(typeof window<"u"&&window.process&&(window.process.type==="renderer"||window.process.__nwjs))return!0;if(typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))return!1;let $;return typeof document<"u"&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||typeof window<"u"&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||typeof navigator<"u"&&navigator.userAgent&&($=navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/))&&parseInt($[1],10)>=31||typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)}function uq($){if($[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+$[0]+(this.useColors?"%c ":" ")+"+"+d5.exports.humanize(this.diff),!this.useColors)return;let J="color: "+this.color;$.splice(1,0,J,"color: inherit");let Q=0,X=0;$[0].replace(/%[a-zA-Z%]/g,(_)=>{if(_==="%%")return;if(Q++,_==="%c")X=Q}),$.splice(X,0,J)}LH.log=console.debug||console.log||(()=>{});function lq($){try{if($)LH.storage.setItem("debug",$);else LH.storage.removeItem("debug")}catch(J){}}function nq(){let $;try{$=LH.storage.getItem("debug")||LH.storage.getItem("DEBUG")}catch(J){}if(!$&&typeof process<"u"&&"env"in process)$=process.env.DEBUG;return $}function iq(){try{return localStorage}catch($){}}d5.exports=aW()(LH);var{formatters:cq}=d5.exports;cq.j=function($){try{return JSON.stringify($)}catch(J){return"[UnexpectedJSONParseError]: "+J.message}}});var PH=h6((_c,RH)=>{RH.exports=($,J=process.argv)=>{let Q=$.startsWith("-")?"":$.length===1?"-":"--",X=J.indexOf(Q+$),_=J.indexOf("--");return X!==-1&&(_===-1||X<_)}});var qH=h6((Qc,EH)=>{var eq=$2("os"),TH=$2("tty"),P4=PH(),{env:u$}=process,P6;if(P4("no-color")||P4("no-colors")||P4("color=false")||P4("color=never"))P6=0;else if(P4("color")||P4("colors")||P4("color=true")||P4("color=always"))P6=1;if("FORCE_COLOR"in u$)if(u$.FORCE_COLOR==="true")P6=1;else if(u$.FORCE_COLOR==="false")P6=0;else P6=u$.FORCE_COLOR.length===0?1:Math.min(parseInt(u$.FORCE_COLOR,10),3);function sW($){if($===0)return!1;return{level:$,hasBasic:!0,has256:$>=2,has16m:$>=3}}function eW($,J){if(P6===0)return 0;if(P4("color=16m")||P4("color=full")||P4("color=truecolor"))return 3;if(P4("color=256"))return 2;if($&&!J&&P6===void 0)return 0;let Q=P6||0;if(u$.TERM==="dumb")return Q;if(process.platform==="win32"){let X=eq.release().split(".");if(Number(X[0])>=10&&Number(X[2])>=10586)return Number(X[2])>=14931?3:2;return 1}if("CI"in u$){if(["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((X)=>(X in u$))||u$.CI_NAME==="codeship")return 1;return Q}if("TEAMCITY_VERSION"in u$)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(u$.TEAMCITY_VERSION)?1:0;if(u$.COLORTERM==="truecolor")return 3;if("TERM_PROGRAM"in u$){let X=parseInt((u$.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(u$.TERM_PROGRAM){case"iTerm.app":return X>=3?3:2;case"Apple_Terminal":return 2}}if(/-256(color)?$/i.test(u$.TERM))return 2;if(/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(u$.TERM))return 1;if("COLORTERM"in u$)return 1;return Q}function $C($){let J=eW($,$&&$.isTTY);return sW(J)}EH.exports={supportsColor:$C,stdout:sW(eW(!0,TH.isatty(1))),stderr:sW(eW(!0,TH.isatty(2)))}});var xH=h6((SH,t5)=>{var JC=$2("tty"),r5=$2("util");SH.init=WC;SH.log=UC;SH.formatArgs=QC;SH.save=YC;SH.load=GC;SH.useColors=_C;SH.destroy=r5.deprecate(()=>{},"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");SH.colors=[6,2,3,4,5,1];try{let $=qH();if($&&($.stderr||$).level>=2)SH.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221]}catch($){}SH.inspectOpts=Object.keys(process.env).filter(($)=>{return/^debug_/i.test($)}).reduce(($,J)=>{let Q=J.substring(6).toLowerCase().replace(/_([a-z])/g,(_,U)=>{return U.toUpperCase()}),X=process.env[J];if(/^(yes|on|true|enabled)$/i.test(X))X=!0;else if(/^(no|off|false|disabled)$/i.test(X))X=!1;else if(X==="null")X=null;else X=Number(X);return $[Q]=X,$},{});function _C(){return"colors"in SH.inspectOpts?Boolean(SH.inspectOpts.colors):JC.isatty(process.stderr.fd)}function QC($){let{namespace:J,useColors:Q}=this;if(Q){let X=this.color,_="\x1B[3"+(X<8?X:"8;5;"+X),U=` ${_};1m${J} \x1B[0m`;$[0]=U+$[0].split(`
|
|
@@ -319,5 +319,5 @@ ${s}`)}})();return}if(!y){B.destroy();return}let n=y.device??w;if(QK(y.upstreamP
|
|
|
319
319
|
\r
|
|
320
320
|
`)};let g=async(E)=>{return TZ(P,E)},b=YZ({path:`${Q}/exec-ws`,execToken:G,streamSettings:J,corsOrigins:N,ssePrefixes:Yf(Q),onUiRequest:H,serveSimBinPath:If(),onActionResult:(E,B,V)=>yb(E,B,V),onSseRequest(E,B){let V=new URL(E,B.url),F=B.headers.get("origin"),w=B.headers.get("sec-fetch-site");return g(new Request(V,{headers:{accept:"text/event-stream",authorization:`Bearer ${G}`,...F?{origin:F}:{},...w?{"sec-fetch-site":w}:{}}}))}});return g.handleWebSocket=(E,B)=>{if(B.on("error",()=>B.close()),!Z(E.headers.get("host"))||!HW(IJ(E),G,{required:W}))return B.close(),!0;if(b(E,B))return!0;if(AZ(E,B,{helperProxyTarget:(V)=>LK(V,X),fallbackDevice:$?.device??null,resolveSession:(V)=>y0(V,J)}))return!0;return!1},g.handleUpgrade=(E,B,V)=>{P.handleUpgrade?.(E,B,V)},g.dispose=async()=>{await O?.dispose()},g}export{_f as startDeviceInProcess,Yf as sseStreamPaths,vt as simMiddleware,I4 as selectServeSimState,i_ as rewriteStateForRequestHost,Xf as retryPendingCaptureCleanup,$4 as readServeSimStates,RK as previewConfigForState,VV as parseGridPaging,Kt as matchInstalledAppByDisplayName,Ff as handleNetworkCaptureRequest,Of as handleMetricsRequest,Vf as handleLogsRequest,VZ as handleCrashesRequest,JK as handleCrashReportRequest,Af as handleCaptureHarRequest,Rf as handleCaptureEntriesRequest,Lf as handleCaptureBodyRequest,$f as gridStateToken,Jf as gridDeviceState,Qf as enableNetworkCaptureForStartedDevice,SK as disableNetworkCaptureForStoppedDevice,cb as deviceNameFromBootedNames};
|
|
321
321
|
|
|
322
|
-
//# debugId=
|
|
322
|
+
//# debugId=B0D3F981DFABE81A64756E2164756E21
|
|
323
323
|
//# sourceMappingURL=middleware.js.map
|
|
Binary file
|
package/dist/serve-sim.js
CHANGED
|
@@ -100,7 +100,7 @@ button:hover{background:#ccc}
|
|
|
100
100
|
`);if(X=Q.pop()??"",X.length>4096)X="";for(let Y of Q)if(Y.startsWith("[servesim-capture]"))J(Y.trimEnd())})}function kq($={}){let J=$.list??(()=>{try{return Mq(mX()).filter((G)=>G.startsWith(rH)).map((G)=>h$(mX(),G))}catch{return[]}}),X=$.psOutput??(()=>{let G=lX("ps",["-eo","pid=,command="],{encoding:"utf8"});return G.status===0&&typeof G.stdout==="string"?G.stdout:null}),_=$.remove??((G)=>A0(G,{recursive:!0,force:!0})),Q=$.ageMs??((G)=>{try{return Date.now()-pH(G).mtimeMs}catch{return 0}}),Y=X();if(Y===null)return 0;let U=0;for(let G of J()){if(Y.includes(dH(G))||Q(G)<qq)continue;try{_(G),U++}catch{}}return U}async function Sq(){let $=jq();return new Promise((J,X)=>{$.once("error",X),$.listen(0,"127.0.0.1",()=>{let _=$.address();if(_==null||typeof _==="string"){$.close(()=>X(Error("Could not reserve a local port for the capture proxy.")));return}let{port:Q}=_;$.close(()=>J(Q))})})}function xq($,J,X){let _=[];for(let Q of $.split(`
|
|
101
101
|
`)){if(!Q.includes(J))continue;let Y=Number(Q.trim().split(/\s+/)[0]);if(Number.isFinite(Y)&&Y!==X)_.push(Y)}return _}function uX(){for(let $ of pX)try{$()}catch{}}function sH($){if(process.listenerCount($)>1)return;uX(),process.removeListener("exit",uX);for(let J of aH)process.removeListener(J,sH);process.kill(process.pid,$)}function wq($){if(pX.add($),lH)return;lH=!0,process.once("exit",uX);for(let J of aH)process.on(J,sH)}function bq($){pX.delete($)}async function nH($){await new Promise((J)=>{try{$.server.close(()=>J())}catch{J()}})}async function gq($,J,X,_,Q,Y){let U=await(J.allocatePort??Sq)();OH(Y,U);let G=Bq(h$(mX(),rH)),W=h$(G,"mitmproxy-ca-cert.pem"),K=h$(G,"proxy-port"),{path:z,write:N}=yq(G),j=oH(16).toString("hex"),I;try{I=await yH({store:$,token:j,fields:Q,onOversizedBody:J.onOversizedControlBody})}catch(M){throw A0(G,{recursive:!0,force:!0}),M}let Z,D=!1;try{Oq(G),nX(K,String(U)),N(Q),Z=Nq(X,["-q","--listen-host","127.0.0.1","--listen-port",String(U),"--set","anticomp=true",...Y?["--mode",`upstream:${Y.url}`]:[],"--set",`confdir=${G}`,"-s",_],{stdio:["pipe","pipe","pipe"],env:{...process.env,SERVE_SIM_CAPTURE_CONTROL_URL:`http://127.0.0.1:${I.port}`,SERVE_SIM_CAPTURE_CONTROL_TOKEN:j,SERVE_SIM_CAPTURE_FIELDS:Q.join(","),[fq]:z,[v0]:String(PJ())}}),Z.stdin.once("error",()=>{D=!0,Z.kill("SIGTERM")}),Z.stdin.end(Y?.auth??"")}catch(M){throw await nH(I),A0(G,{recursive:!0,force:!0}),M}let v="",T=(M)=>{v=(v+M.toString("utf8")).slice(-4000)};if(Z.stdout?.on("data",T),Z.stderr?.on("data",T),Z.stderr)Cq(Z.stderr);let L=!1,O=!1,P=!1;Z.once("exit",(M)=>{if(L=!0,O||!P)return;J.onUnexpectedExit?.(v.trim()||`The capture proxy stopped unexpectedly (exit ${M??"signal"}).`)});let E="";Z.once("error",(M)=>{L=!0,E=M.message});let B=dH(G),H=(M)=>{let F=lX("ps",["-eo","pid=,command="],{encoding:"utf8"});if(F.status!==0||typeof F.stdout!=="string")return;for(let A of xq(F.stdout,B,process.pid))try{process.kill(A,M)}catch{}},V=()=>{H("SIGKILL"),A0(G,{recursive:!0,force:!0})};wq(V);let R=async()=>{O=!0;try{if(!L&&Z.pid!=null){let M=new Promise((A)=>{let g=setTimeout(A,5000);Z.once("exit",()=>{clearTimeout(g),A()})});Z.kill("SIGTERM");let F=setTimeout(()=>Z.kill("SIGKILL"),3000);await M,clearTimeout(F)}H("SIGTERM"),await new Promise((M)=>setTimeout(M,500)),H("SIGKILL"),await nH(I),A0(G,{recursive:!0,force:!0,maxRetries:3,retryDelay:100})}finally{bq(V)}},w=Date.now()+mH,f=!1;I.ready.then(()=>{f=!0});while(Date.now()<w){if(L||D)throw await R(),Error(`The capture proxy exited before it started listening.
|
|
102
102
|
${D?"Could not deliver the capture proxy's startup credentials.":E||v.trim()||"No output from mitmproxy."}`);if(P1(W)&&f){if(!Rq(G))throw await R(),new iX("Another capture saved the shared CA first; starting again with it.");return P=!0,{address:`127.0.0.1:${U}`,portFile:K,caPem:async()=>z5(W,"utf8"),setFields:(M)=>{N(M),I.setFields(M)},close:R}}await new Promise((M)=>setTimeout(M,Vq))}let q=P1(W)?"It started but its reporting addon never loaded, so nothing would have been captured.":`Check that no other process holds 127.0.0.1:${U}.`;throw await R(),Error(`The capture proxy did not start within ${mH/1000}s. ${q}
|
|
103
|
-
${v.trim()}`)}function yq($){let J=h$($,"capture-fields");return{path:J,write(X){let _=`${J}.${oH(4).toString("hex")}.tmp`;nX(_,X.join(","),{mode:384}),iH(_,J)}}}function hq($){let J=$ instanceof Error?$.message:String($);return/EADDRINUSE|address already in use/i.test(J)}async function eH($,J={}){kq();let X=vq();if(!X)throw Error(Aq(process.env.SERVE_SIM_MITMDUMP));let _=Pq(),Q=J.fields??v1,Y=J.upstream??null,U;for(let G=0;G<Lq;G++)try{return await gq($,J,X,_,Q,Y)}catch(W){if(U=W,!hq(W)&&!(W instanceof iX)&&!(W instanceof Y5))throw W}throw U}var hX,mH=30000,Vq=200,Lq=3,rH="serve-sim-capture-",EJ,uH="mitmproxy-ca-cert.pem",Fq="SERVE_SIM_CAPTURE_CA_DIR",iX,Tq,qq=60000,aH,pX,lH=!1,fq="SERVE_SIM_CAPTURE_FIELDS_FILE";var oX=x(()=>{U5();w6();O0();A1();hH();hX=b4(import.meta.url),EJ=["mitmproxy-ca.pem","mitmproxy-ca-cert.pem"];iX=class iX extends Error{};Tq=["/opt/homebrew/bin/mitmdump","/usr/local/bin/mitmdump","/Applications/mitmproxy.app/Contents/MacOS/mitmdump"];aH=["SIGINT","SIGTERM","SIGHUP"],pX=new Set});import{readFileSync as mq}from"node:fs";import{dirname as uq,join as lq}from"node:path";import{fileURLToPath as nq}from"node:url";function N5(){return"0.10.
|
|
103
|
+
${v.trim()}`)}function yq($){let J=h$($,"capture-fields");return{path:J,write(X){let _=`${J}.${oH(4).toString("hex")}.tmp`;nX(_,X.join(","),{mode:384}),iH(_,J)}}}function hq($){let J=$ instanceof Error?$.message:String($);return/EADDRINUSE|address already in use/i.test(J)}async function eH($,J={}){kq();let X=vq();if(!X)throw Error(Aq(process.env.SERVE_SIM_MITMDUMP));let _=Pq(),Q=J.fields??v1,Y=J.upstream??null,U;for(let G=0;G<Lq;G++)try{return await gq($,J,X,_,Q,Y)}catch(W){if(U=W,!hq(W)&&!(W instanceof iX)&&!(W instanceof Y5))throw W}throw U}var hX,mH=30000,Vq=200,Lq=3,rH="serve-sim-capture-",EJ,uH="mitmproxy-ca-cert.pem",Fq="SERVE_SIM_CAPTURE_CA_DIR",iX,Tq,qq=60000,aH,pX,lH=!1,fq="SERVE_SIM_CAPTURE_FIELDS_FILE";var oX=x(()=>{U5();w6();O0();A1();hH();hX=b4(import.meta.url),EJ=["mitmproxy-ca.pem","mitmproxy-ca-cert.pem"];iX=class iX extends Error{};Tq=["/opt/homebrew/bin/mitmdump","/usr/local/bin/mitmdump","/Applications/mitmproxy.app/Contents/MacOS/mitmdump"];aH=["SIGINT","SIGTERM","SIGHUP"],pX=new Set});import{readFileSync as mq}from"node:fs";import{dirname as uq,join as lq}from"node:path";import{fileURLToPath as nq}from"node:url";function N5(){return"0.10.2-canary-20261019-059ca8e"}var dX=()=>{};class JB{#$=new Map;enqueue($,J){let X=this.#$.get($),_=X?X.then(J):J(),Q=_.then(()=>{},()=>{});return this.#$.set($,Q),Q.then(()=>{if(this.#$.get($)===Q)this.#$.delete($)}),_}devices(){return this.#$.keys()}}function j5($,J){return{schemaVersion:LJ,udid:$,proxyAddress:null,attachment:"not-enabled",attachError:null,droppedOversizedBodies:0,fields:[...J]}}function QB($,J){return{...j5($,J),attachment:"failed",attachError:"Capture was turned off while it was waiting to start. Enable it again to retry."}}function P0($,J,X){if(J.cancelled)throw new O6(QB($,J.fields??X))}function rX($,J){return $.length===J.length&&$.every((X)=>J.includes(X))}function oq($){if(XB.add($),$B)return;$B=!0,process.on("exit",dq)}function dq(){for(let $ of XB)$()}function tX($={}){let J=$.fields??v1,X=$.upstream,_=$.startProxy??((F,A)=>eH(F,A)),Q=$.trustCa??pZ,Y=$.configure??WJ,U=$.dylib??oZ,G=$.isInjected??((F,A,g)=>dZ(F,A,{expectedPort:Number(new URL(`http://${g}`).port)})),W=$.checkIntervalMs??cq,K=$.writeDiskArtifacts!==!1,z=$.creatorVersion??"0.0.0",N=new Map,j=()=>{for(let F of N.values())try{F.disk?.discardSync()}catch{}},I=new Map,Z=new JB,D=new Map,v=null,T=new Map,L=new Map,O=(F,A)=>{for(let g of T.get(F)??[])try{g(A)}catch{}},P=(F)=>N.get(F)?.meta??L.get(F)??j5(F,J),E=(F,A)=>{if(!K)return{disk:null,stopDisk:null};if(!$.captureDirFor)AX([...N.keys(),F]);let g=$.captureDirFor?{dir:$.captureDirFor(F),networkCapturePath:void 0,harPath:void 0}:s9(F),h=new R1({dir:g.dir,networkCapturePath:g.networkCapturePath,harPath:g.harPath,creatorVersion:z,flushIntervalMs:$.flushIntervalMs,harRebuildIntervalMs:pq});return oq(j),{disk:h,stopDisk:h.attach(A)}},B=async(F,A)=>{if(A.cleanup??=(async()=>{await A.proxy?.close(),A.proxy=null,A.meta.proxyAddress=null,await A.stopDisk?.(),A.stopDisk=null,A.disk=null})().catch((g)=>{throw A.cleanup=void 0,console.warn(`Network capture: cleanup for ${F} failed:`,g),g}),await A.cleanup,N.get(F)===A)N.delete(F)},H=async(F,A)=>{if(v)throw Error(v);if(A)P0(F,A,J);let g=N.get(F);if(g?.proxy){if(g.meta.attachment==="failed")throw Error("The previous capture session failed. Disable capture before retrying so its launch configuration can be removed safely.");if(A)A.session=g;return{dylib:V(),env:{SIMNET_PROXY_PORT_FILE:g.proxy.portFile}}}let h=V(),i=[...A?.fields??J],c=new FJ,p={schemaVersion:LJ,udid:F,proxyAddress:null,attachment:"starting",attachError:null,droppedOversizedBodies:0,fields:i},$$={store:c,meta:p,proxy:null,...E(F,c)};if(A)A.session=$$;c.subscribe((I$)=>{if(N.get(F)===$$)O(F,I$)}),L.delete(F),N.set(F,$$),O(F,{type:"cleared"}),O(F,{type:"meta",meta:p});try{let I$=await _(c,{upstream:X,fields:i,onUnexpectedExit:(B$)=>{if(N.get(F)!==$$)return;p.attachment="failed",p.attachError=`${B$}
|
|
104
104
|
|
|
105
105
|
Relaunch apps after restarting capture; their existing sessions may still point at the stopped proxy.`,c.publishMeta(p)},onOversizedControlBody:()=>{if(N.get(F)!==$$)return;p.droppedOversizedBodies+=1,c.publishMeta(p)}});if($$.proxy=I$,p.proxyAddress=I$.address,A?.fields&&!rX(i,A.fields))I$.setFields(A.fields),p.fields=[...A.fields];if(A)P0(F,A,J);if(await Q(F,await I$.caPem()),A)P0(F,A,J);if(p.attachment==="failed")throw Error(p.attachError??"The capture proxy stopped during startup.");return{dylib:h,env:{SIMNET_PROXY_PORT_FILE:I$.portFile},committed(){if(p.attachment==="failed")throw Error(p.attachError??"The capture proxy stopped during startup.");p.attachment="capturing",c.publishMeta(p)},failed(B$){p.attachment="failed",p.attachError=B$ instanceof Error?B$.message:String(B$),c.publishMeta(p)},async rollback(){if(A)A.failed=!0;await B(F,$$),N.set(F,$$)}}}catch(I$){if(A)A.failed=!0;throw p.attachment="failed",p.attachError=I$ instanceof Error?I$.message:String(I$),await B(F,$$),N.set(F,$$),c.publishMeta(p),I$}};function V(){let F=U();if(!F)throw Error("Network capture library is missing. Rebuild serve-sim's native artifacts before enabling capture.");return F}let R={name:"networkCapture",exclusive:!0,scope:"userApps",loadPhase:"startupAndDeferred",defaultEnabled:!1,async setEnabled({udid:F,enabled:A}){if(A)return H(F);let g=N.get(F);if(g)await B(F,g);if(L.delete(F),!N.has(F))O(F,{type:"meta",meta:j5(F,J)});return null}},w=(F)=>Y(F,R,{enabled:!1,relaunch:!1}),f=(F)=>{let A=D.get(F);if(A)A.cancelled=!0;return D.delete(F),Z.enqueue(F,()=>w(F))},q=(F,A,g)=>{let h=N.get(F);if(h?.proxy&&h.meta.attachment==="starting"&&A.session===h)h.proxy.setFields(g),h.meta.fields=[...g],h.store.publishMeta(h.meta);A.fields=[...g]},M=(F,A)=>{let g=N.get(F);if(!g?.proxy||g.meta.attachment!=="capturing"){let i=D.get(F);if(!i||i.failed||i.cancelled)return null;return q(F,i,A),P(F)}g.proxy.setFields(A);let h=D.get(F);if(h&&!h.failed&&h.session===g)h.fields=[...A];return g.meta.fields=[...A],g.store.publishMeta(g.meta),g.meta};return{capability:R,shouldCaptureDevice(F,A){return I.get(F)??A},setDeviceCaptureEnabled(F,A){I.set(F,A)},creatorVersion:z,setUpstream(F){X=F},setFields(F){J=F},defaultFields(){return J},enableForDevice(F,A){let g=D.get(F);if(g&&!g.failed&&(A===void 0||rX(g.fields??J,A))){if(A!==void 0)g.fields=[...A];return g.promise}let h=g&&!g.failed?g:void 0,i=h?.promise,c=h??{cancelled:!1,failed:!1,promise:Promise.resolve(j5(F,J))};if(A!==void 0)try{q(F,c,A)}catch(I$){return Promise.reject(I$)}let p=Z.enqueue(F,async()=>{if(P0(F,c,J),c.session=N.get(F),i)await i;let I$;try{if(v)throw Error(v);if(N.get(F)?.meta.attachment==="failed")await w(F),P0(F,c,J);if(await Y(F,{...R,setEnabled:({enabled:l})=>l?H(F,c):R.setEnabled({udid:F,enabled:!1,bundleId:null,options:{}})},{enabled:!0,relaunch:!1}),c.cancelled)await w(F),P0(F,c,J);let z4=N.get(F);if(!z4)throw Error("The capture session disappeared during startup. Enable capture again.");I$=z4.meta}catch(B$){c.failed=!0;let z4=N.get(F),l=z4?.meta??QB(F,c.fields??J);if(l.attachment="failed",l.attachError=B$ instanceof Error?B$.message:String(B$),z4)z4.store.publishMeta(l);else L.set(F,l),O(F,{type:"meta",meta:l});throw new O6(l)}if(c.fields!==void 0&&!rX(I$.fields,c.fields))M(F,c.fields);return I$});c.promise=p,D.set(F,c);let $$=()=>{if(D.get(F)===c&&c.promise===p)D.delete(F)};return p.then($$,$$),p},disableForDevice:f,refuseCapture(F){v=F},async disableAll(){let F=new Set([...N.keys(),...L.keys(),...Z.devices()]),g=(await Promise.allSettled([...F].map(f))).flatMap((h)=>h.status==="rejected"?[h.reason]:[]);if(g.length>0)throw AggregateError(g,`Could not disable network capture on ${g.length} device(s).`)},discardArtifactsSync:j,subscribe(F,A){let g=T.get(F);if(!g)T.set(F,g=new Set);return g.add(A),{meta:P(F),unsubscribe:()=>{if(g.delete(A),g.size===0&&T.get(F)===g)T.delete(F)}}},metaFor(F){return P(F)},async refreshForDevice(F){let A=N.get(F);if(!A)return P(F);if(A.meta.attachment!=="capturing"||!A.proxy)return A.meta;let g=Date.now();if(A.checking)return A.checking;if(A.checkedAt!==void 0&&g-A.checkedAt<W)return A.meta;let h=A.proxy.portFile,i=A.proxy.address;return A.checking=(async()=>{try{let c;try{c=await G(F,h,i)}catch(p){if(!C9(p))return console.warn(`Network capture: injection probe for ${F} failed:`,p instanceof Error?p.message:p),A.injectMisses=0,A.meta;c=!1}if(c)return A.injectMisses=0,A.meta;if(N.get(F)!==A||A.meta.attachment!=="capturing")return A.meta;if(A.injectMisses=(A.injectMisses??0)+1,A.injectMisses<iq)return A.meta;return A.meta.attachment="failed",A.meta.attachError="This device stopped capturing. It may have restarted or shut down since capture was enabled. Enable capture again after it boots.",A.store.publishMeta(A.meta),A.meta}finally{A.checkedAt=Date.now(),A.checking=void 0}})(),A.checking},storeFor(F){return N.get(F)?.store??null},artifactPathsFor(F){let A=N.get(F)?.disk;if(!A)return null;return{networkCapturePath:A.networkCapturePath,harPath:A.harPath,entriesPath:A.entriesPath}},async flushEntriesPathFor(F){let A=N.get(F)?.disk;if(!A)return null;return await A.flushEntries(),A.entriesPath},async flushHarPathFor(F){let A=N.get(F)?.disk;if(!A)return null;return await A.flush(),A.harPath},setFieldsForDevice:M,clearForDevice(F){let A=N.get(F);if(!A)return!1;return A.store.clear(),!0},throughputFor(F){let A=N.get(F);if(!A||A.meta.attachment!=="capturing")return null;return A.store.throughput()}}}var O6,cq=1e4,iq=2,pq=60000,XB,$B=!1,E$;var qJ=x(()=>{V1();rZ();F6();e9();A1();oX();dX();O6=class O6 extends Error{meta;constructor($){super($.attachError??"Network capture could not start");this.name="CaptureEnableError",this.meta=$}};XB=new Set;E$=tX({creatorVersion:N5()})});import aX from"ws";function rq(){let $={};for(let Q=0;Q<26;Q++){let Y=4+Q;$[String.fromCharCode(97+Q)]={usage:Y,shift:!1},$[String.fromCharCode(65+Q)]={usage:Y,shift:!0}}let J="1234567890",X="!@#$%^&*()";for(let Q=0;Q<10;Q++){let Y=30+Q;$[J[Q]]={usage:Y,shift:!1},$[X[Q]]={usage:Y,shift:!0}}let _=[["-","_",45],["=","+",46],["[","{",47],["]","}",48],["\\","|",49],[";",":",51],["'",'"',52],["`","~",53],[",","<",54],[".",">",55],["/","?",56]];for(let[Q,Y,U]of _)$[Q]={usage:U,shift:!1},$[Y]={usage:U,shift:!0};return $[" "]={usage:44,shift:!1},$[`
|
|
106
106
|
`]={usage:40,shift:!1},$["\t"]={usage:43,shift:!1},$}async function YB($,J,{token:X,perEventDelayMs:_=4}={}){return new Promise((Q,Y)=>{let U=new aX($,X?{headers:{Authorization:`Bearer ${X}`}}:void 0);U.binaryType="arraybuffer";let G=!1,W=setTimeout(()=>{Y(Error("Simulator keyboard input did not finish. Retry with a shorter string.")),U.close()},Math.max(30000,J.length*1000));U.onclose=({code:K,reason:z})=>{if(clearTimeout(W),G)Q();else Y(Error(`Keyboard input interrupted (${K}${z?`: ${z}`:""}). Some text may not have been delivered.`))},U.onmessage=({data:K})=>{let z=Buffer.from(K);if(z[0]!==145)return;if(z[1]===1)G=!0,U.close(1000);else Y(Error("Simulator keyboard input failed. Check the preview logs and retry.")),U.close()},U.onopen=async()=>{try{for(let K of J){if(U.readyState!==aX.OPEN)return;let z=new TextEncoder().encode(JSON.stringify(K)),N=new Uint8Array(1+z.length);if(N[0]=6,N.set(z,1),U.send(N),_>0)await new Promise((j)=>setTimeout(j,_))}if(U.readyState===aX.OPEN)U.send(Uint8Array.of(17))}catch(K){U.close(),Y(K)}},U.onerror=()=>{Y(Error(`WebSocket connection failed: ${$}`))}})}function UB($){let J=[];for(let X of $){if(X==="\r")continue;let _=sX[X];if(!_)throw new I5(X);if(_.shift)J.push({type:"down",usage:_B});if(J.push({type:"down",usage:_.usage,..._.shift?{key:X,shifted:!0}:{}}),J.push({type:"up",usage:_.usage}),_.shift)J.push({type:"up",usage:_B})}return J}var _B=225,sX,I5;var eX=x(()=>{sX=rq();I5=class I5 extends Error{char;constructor($){super(`Unsupported character: ${JSON.stringify($)}`);this.char=$}}});function WB($){return typeof $==="number"&&Number.isFinite($)?$:null}function KB($,J,X,_){let Q=WB($);return Q==null?J:Math.min(_,Math.max(X,Q))}function Z5($,J,X,_){return Math.round(KB($,J,X,_))}function aq($){if(!Array.isArray($)||$.length>16)return null;let J=[];for(let X of $){if(!X||typeof X!=="object")return null;let _=X.urls;if(!Array.isArray(_)||_.length===0||_.length>16||!_.every((U)=>typeof U==="string"&&U.length<=2048&&/^(stun|stuns|turn|turns):/i.test(U)))return null;let{username:Q,credential:Y}=X;if(Q!==void 0&&typeof Q!=="string")return null;if(Y!==void 0&&typeof Y!=="string")return null;J.push({urls:_,...typeof Q==="string"?{username:Q}:{},...typeof Y==="string"?{credential:Y}:{}})}return J}function zB($,J){if(!$||typeof $!=="object"||Array.isArray($))return null;let X=$,_=Object.keys(X),Q=J==="webrtc"?eq:sq;if(_.length===0||_.some((Y)=>!Q.has(Y)))return null;for(let Y of["mjpegFps","mjpegQuality","maxDimension","h264Bitrate","h264Fps"])if(Y in X&&WB(X[Y])==null)return null;return X}function GB($={},J=tq){let _=Object.prototype.hasOwnProperty.call($,"iceServers")?aq($.iceServers):J.iceServers,Q=_===null?J.iceServers:_&&_.length>0?_:void 0;return{transport:$.transport==="http"||$.transport==="webrtc"?$.transport:J.transport,httpCodec:$.httpCodec==="auto"||$.httpCodec==="mjpeg"||$.httpCodec==="h264"?$.httpCodec:J.httpCodec,webRtcCodec:$.webRtcCodec==="vp8"||$.webRtcCodec==="vp9"||$.webRtcCodec==="h264"?$.webRtcCodec:J.webRtcCodec,...Q?{iceServers:Q}:{},...E0($,J)}}function E0($={},J=H5){return{mjpegFps:Z5($.mjpegFps,J.mjpegFps,1,120),mjpegQuality:KB($.mjpegQuality,J.mjpegQuality,0.05,1),maxDimension:Z5($.maxDimension,J.maxDimension,0,4096),h264Bitrate:Z5($.h264Bitrate,J.h264Bitrate,1e5,50000000),h264Fps:Z5($.h264Fps,J.h264Fps,1,140)}}function NB($){return{mjpegFps:$.mjpegFps,mjpegQuality:$.mjpegQuality,maxDimension:$.maxDimension,h264Bitrate:$.h264Bitrate,h264Fps:$.h264Fps}}function Q_($,J){if(J==="webrtc")return{maxDimension:$.maxDimension,h264Bitrate:$.h264Bitrate,h264Fps:$.h264Fps};return{mjpegFps:$.mjpegFps,mjpegQuality:$.mjpegQuality,maxDimension:$.maxDimension,h264Bitrate:$.h264Bitrate,h264Fps:$.h264Fps}}function jB($){let J=$?{mjpegFps:$.mjpegFps,mjpegQuality:$.mjpegQuality,maxDimension:$.maxDimension,h264Bitrate:$.h264Bitrate,h264Fps:$.h264Fps}:{};if($?.transport==="webrtc")return GB({transport:"webrtc",webRtcCodec:$.codec,iceServers:$.iceServers,...J});return GB({transport:"http",httpCodec:$?.codec??"auto",...J})}var $_=120,J_=140,H5,tq,sq,eq;var CJ=x(()=>{H5={mjpegFps:60,mjpegQuality:0.7,maxDimension:0,h264Bitrate:6000000,h264Fps:60},tq={transport:"http",httpCodec:"auto",webRtcCodec:"h264",...H5};sq=new Set(["mjpegFps","mjpegQuality","maxDimension","h264Bitrate","h264Fps"]),eq=new Set(["maxDimension","h264Bitrate","h264Fps"])});function y6($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function B5($){return typeof $==="number"&&Number.isFinite($)?$:0}function K$($){return typeof $==="number"&&Number.isFinite($)?$:null}function E1($){return typeof $==="string"&&$.length>0?$:null}function $C($){if(!y6($))return{};let J={};for(let[X,_]of Object.entries($)){let Q=K$(_);if(Q!==null)J[X]=Q*1000}return J}function JC($,J){let X=[E1($),E1(J)];if(X.some((_)=>_===null))return"unknown";return X.includes("relay")?"relay":"direct"}function QC($){let J=B5($.framesEncoded),X=B5($.packetsSent),_=B5($.packetsLost),Q=K$($.totalEncodeTime),Y=K$($.targetBitrate),U=K$($.roundTripTime);return{sessionId:E1($.sessionId)??"",sourceFrames:K$($.sourceFrames),sourceFps:K$($.sourceFramesPerSecond),sourceFramesDropped:K$($.sourceFramesDropped),sourceLongEdge:K$($.sourceLongEdge),levelMaxLongEdge:K$($.levelMaxLongEdge),codec:E1($.codec),connected:$.connected===!0,qualityLimitationReason:E1($.qualityLimitationReason),qualityLimitationMs:$C($.qualityLimitationDurations),framesEncoded:J,framesSent:B5($.framesSent),reportedFps:K$($.framesPerSecond),targetKbps:Y===null?null:Y/1000,totalEncodeMs:Q===null?null:Q*1000,encodeMsPerFrame:Q===null||J<=0?null:Q*1000/J,width:K$($.frameWidth),height:K$($.frameHeight),packetsSent:X,packetsLost:_,lossRatio:X>0?Math.max(0,_)/X:null,roundTripMs:U===null?null:U*1000,path:JC($.localCandidateType,$.remoteCandidateType)}}function XC($){if(!y6($))return null;let J={id:E1($.id),hardware:typeof $.hardware==="boolean"?$.hardware:null,codec:E1($.codec),probe:$.probe===!0};if(J.id===null&&J.hardware===null&&J.codec===null)return null;return J}function IB($){if(!y6($)||!Array.isArray($.sessions))return{sessions:[]};return{sessions:$.sessions.filter(y6).map(QC),capture:YC($.capture),encoder:XC($.encoder),viewerResize:y6($.viewerResize)?$.viewerResize:null,sharedCanvas:_C($.sharedCanvas),sharedEncoderPeers:Array.isArray($.sharedEncoderPeers)?$.sharedEncoderPeers.filter(y6):null}}function _C($){if(!y6($))return null;let{width:J,height:X,scale:_,step:Q,steps:Y}=$;if([J,X,_,Q,Y].some((U)=>typeof U!=="number"))return null;return{width:J,height:X,scale:_,step:Q,steps:Y,starvedRecoveries:K$($.starvedRecoveries),lowLatencyFallbacks:K$($.lowLatencyFallbacks)}}function YC($){if(!y6($))return null;let{screenFrames:J,idleFrames:X}=$;if(typeof J!=="number"||typeof X!=="number")return null;return{pickCount:K$($.pickCount),pickSumMs:K$($.pickSumMs),...typeof $.rebooting==="boolean"?{rebooting:$.rebooting}:{},pickMaxMs:K$($.pickMaxMs),screenFrames:J,idleFrames:X,offeredFrames:K$($.offeredFrames),forwardedFrames:K$($.forwardedFrames),sharedEncodedFrames:K$($.sharedEncodedFrames),pumpRestarts:K$($.pumpRestarts),canvasMismatchDrops:K$($.canvasMismatchDrops),pumpDeferrals:K$($.pumpDeferrals),pumpRepeats:K$($.pumpRepeats),unchangedFrames:K$($.unchangedFrames),pumpTimerTicks:K$($.pumpTimerTicks),pumpTimerLateSumMs:K$($.pumpTimerLateSumMs),pumpTimerLateMaxMs:K$($.pumpTimerLateMaxMs),sourceSubmitCount:K$($.sourceSubmitCount),sourceSubmitSumMs:K$($.sourceSubmitSumMs),sourceSubmitMaxMs:K$($.sourceSubmitMaxMs),cpuFallbacks:K$($.cpuFallbacks),poolDrops:K$($.poolDrops),attempts:K$($.attempts),stalls:K$($.stalls),gapSumMs:K$($.gapSumMs),stallSumMs:K$($.stallSumMs),pollTicks:K$($.pollTicks),pollLateSumMs:K$($.pollLateSumMs),surfaceLosses:K$($.surfaceLosses),surfaceLostMs:K$($.surfaceLostMs),rewires:K$($.rewires)}}import{createRequire as UC}from"module";import{dirname as X_,join as __}from"path";import{existsSync as GC}from"fs";import{fileURLToPath as ZB}from"url";function HB(){return[__(X_(process.execPath),"native","serve-sim-native.node"),__(X_(ZB(import.meta.url)),"native","serve-sim-native.node"),__(X_(ZB(import.meta.url)),"..","dist","native","serve-sim-native.node")]}function IC(){return HB().find(GC)??null}function ZC(){let $=IC();if($)return $;throw Error(`serve-sim-native.node not found. Looked in:
|
|
@@ -359,7 +359,7 @@ Usage:
|
|
|
359
359
|
serve-sim permissions reset <permission|all> <bundle-id> [-d <udid|name>]
|
|
360
360
|
serve-sim permissions list [bundle-id] [-d <udid|name>]
|
|
361
361
|
|
|
362
|
-
Permissions: ${$j().join(", ")}`),process.exit(1);let Q=_.device?d$(_.device):A4();if(!Q)console.error("No booted simulator. Boot one or pass -d <udid|name>."),process.exit(1);if(_.verb==="list"){let U={udid:Q,bundleId:_.bundleId??null,tcc:Mh(Q,_.bundleId),location:Vh(Q,_.bundleId),notifications:Rh(Q,_.bundleId)};console.log(JSON.stringify(U,null,J?0:2));return}let Y=_.bundleId;try{if(_.permission==="all")for(let U of $j())PO(Q,"reset",U,void 0,Y);else PO(Q,_.verb,_.permission,_.value,Y)}catch(U){console.error(U?.message??String(U)),process.exit(1)}if(J)console.log(JSON.stringify({udid:Q,verb:_.verb,permission:_.permission,value:_.value??null,bundleId:Y}));else{let U=_.value?` (${_.value})`:"";console.log(`\uD83D\uDD10 ${_.verb} ${_.permission}${U} for ${Y} on ${Q}`)}}uJ();gJ();function fO($,J={}){let X=new Date($.timestamp),_=Number.isNaN(X.getTime())?$.timestamp:X.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"}),Q=J.deviceLabel??($.device?$.device.slice(0,8):null),Y=$.status==="error"?" failed":"";return[_,Q,`${Th($)}${Y?` (${Y.trim()})`:""}`].filter(Boolean).join(" ")}function Th($){if($.kind==="tap"){let J=_3($.details,"current")??_3($.details,"start");return J?`Tap at ${Yj(J)}`:"Tap"}if($.kind==="drag"){let J=_3($.details,"start"),X=_3($.details,"current");if(J&&X)return`Drag from ${Yj(J)} to ${Yj(X)}`;return"Drag"}if($.kind==="key"){let J=vh($.details,"key")??$.action??"key",X=$.action==="down"?"down":$.action==="up"?"up":$.action;return X?`Key ${X} ${gO(J)}`:`Key ${gO(J)}`}if($.kind==="rotate"){let J=$.action?yO($.action):"";return J?`Rotate ${J}`:"Rotate"}return Ph($.msg??$.summary)}function _3($,J){let X=$?.[J];if(!X||typeof X!=="object"||Array.isArray(X))return null;let _=X;return typeof _.x==="number"&&typeof _.y==="number"?{x:_.x,y:_.y}:null}function vh($,J){let X=$?.[J];return typeof X==="string"&&X.length>0?X:null}function Yj($){return`${bO($.x)}, ${bO($.y)}`}function bO($){if(!Number.isFinite($))return"?";return(Math.round((Ah($,0,1)+Number.EPSILON)*100)/100).toFixed(2)}function Ah($,J,X){return Math.min(X,Math.max(J,$))}function Ph($){return $.replace(/\b[a-z]+(?:_[a-z]+)+\b/g,yO)}function yO($){return $.replace(/[-_]+/g," ")}function gO($){return{MetaLeft:"Left Command",MetaRight:"Right Command",AltLeft:"Left Option",AltRight:"Right Option",ControlLeft:"Left Control",ControlRight:"Right Control",ShiftLeft:"Left Shift",ShiftRight:"Right Shift",ArrowLeft:"Left Arrow",ArrowRight:"Right Arrow",ArrowUp:"Up Arrow",ArrowDown:"Down Arrow"}[$]??$}Wj();CJ();function Kj($,J){let X=$.split(",").map((Q)=>Q.trim()).filter(Boolean),_=J==="stun"?/^stuns?:/i:/^turns?:/i;if(X.length===0||X.length>16||X.some((Q)=>Q.length>2048||!_.test(Q)))throw Error(`Expected one or more comma-separated ${J.toUpperCase()} URLs`);return X}function zj($,J){let X=$??{transport:"http"},_=J??{transport:"http"};if(X.transport!==_.transport)return!1;let Q=E0(X),Y=E0(_);if(Q.mjpegFps!==Y.mjpegFps||Q.mjpegQuality!==Y.mjpegQuality||Q.maxDimension!==Y.maxDimension||Q.h264Bitrate!==Y.h264Bitrate||Q.h264Fps!==Y.h264Fps)return!1;if(X.transport==="http"&&_.transport==="http")return(X.codec??"auto")===(_.codec??"auto");if(X.transport!=="webrtc"||_.transport!=="webrtc")return!1;if(X.codec!==_.codec)return!1;let U=X.iceServers??[],G=_.iceServers??[];if(U.length!==G.length)return!1;return U.every((W,K)=>{let z=G[K];return W.username===z.username&&W.credential===z.credential&&W.urls.length===z.urls.length&&W.urls.every((N,j)=>N===z.urls[j])})}function uO($,J){let X=[];for(let _ of $??[])for(let Q of _.urls){let Y=Q.toLowerCase();if(J.some((U)=>Y.startsWith(U)))X.push(Q)}return X}function Sh($){for(let J of $??[])if(J.urls.some((X)=>/^turns?:/i.test(X)))return J;return null}function xh($){if(!$)return[];let J=[];if(J.push("--transport",$.transport),$.transport==="http"){if($.codec)J.push("--codec",$.codec)}else{J.push("--webrtc-codec",$.codec);let X=uO($.iceServers,["stun:","stuns:"]);if(X.length)J.push("--stun-url",X.join(","));let _=uO($.iceServers,["turn:","turns:"]);if(_.length){J.push("--turn-url",_.join(","));let Q=Sh($.iceServers);if(Q?.username)J.push("--turn-username",Q.username);if(Q?.credential)J.push("--turn-credential",Q.credential)}}if($.mjpegFps!==void 0)J.push("--mjpeg-fps",String($.mjpegFps));if($.mjpegQuality!==void 0)J.push("--mjpeg-quality",String($.mjpegQuality));if($.maxDimension!==void 0)J.push("--max-dimension",String($.maxDimension));if($.h264Bitrate!==void 0)J.push("--video-bitrate",String($.h264Bitrate));if($.h264Fps!==void 0)J.push("--video-fps",String($.h264Fps));return J}function lO($,J,X,_){return[$,"--port",String(J),"--host",X,...xh(_)]}CJ();u6();jj();u6();import nO from"ws";async function cO($,J,X={}){if(!Q4(J))throw Error("Hinge angle must be between 0–180 degrees");return new Promise((_,Q)=>{let Y=new nO($,{headers:X.token?{Authorization:`Bearer ${X.token}`}:void 0}),U=!1,G=(K)=>{if(U)return;if(U=!0,clearTimeout(W),Y.close(),K)Q(K);else _()},W=setTimeout(()=>G(Error("Timed out waiting for hinge control acknowledgement")),X.timeoutMs??5000);Y.on("open",()=>{Y.send(Buffer.concat([Buffer.from([15]),Buffer.from(JSON.stringify({angle:J}))]))}),Y.on("message",(K)=>{let z=Buffer.from(K);if(z[0]!==143)return;let N;try{N=JSON.parse(z.subarray(1).toString())}catch{G(Error("Invalid hinge control acknowledgement"));return}if(!N||typeof N!=="object"||typeof N.ok!=="boolean"){G(Error("Invalid hinge control acknowledgement"));return}if(!N.ok)G(Error(N.error||"Hinge control is unavailable on this simulator"));else if(N.angle===J)G();else G(Error("Server acknowledged a different hinge angle"))}),Y.on("error",(K)=>G(Error(`Hinge control connection failed: ${K.message}`))),Y.on("close",()=>G(Error("Connection closed before hinge control acknowledgement")))})}async function iO($,J={}){return new Promise((X,_)=>{let Q=new nO($,{headers:J.token?{Authorization:`Bearer ${J.token}`}:void 0}),Y=!1,U=(W)=>{if(Y)return;if(Y=!0,clearTimeout(G),Q.close(),W instanceof Error)_(W);else X(W)},G=setTimeout(()=>U(Error("Timed out waiting for the simulator's hinge state")),J.timeoutMs??5000);Q.on("message",(W)=>{let K=Buffer.from(W);if(K[0]!==130)return;let z;try{z=JSON.parse(K.subarray(1).toString())}catch{U(Error("Invalid screen config from the serve-sim server"));return}if(z.supportsHingeAngle===void 0)return;if(!z.supportsHingeAngle){U(Error("Hinge control is unavailable on this simulator"));return}let{hingeAngle:N,hingePose:j,physicalOrientation:I,tableMode:Z,tableModeAvailable:D}=z;U({hingeAngle:N,hingePose:j,physicalOrientation:I,tableMode:Z,tableModeAvailable:D})}),Q.on("error",(W)=>U(Error(`Hinge state connection failed: ${W.message}`))),Q.on("close",()=>U(Error("Connection closed before the hinge state arrived")))})}n0();Z4();import{existsSync as wh,readFileSync as bh,unlinkSync as pO}from"node:fs";var z3=500,dO=65000;function K3($,J){return{exitCode:$?.exitCode??null,signalCode:$?.signalCode??null,forced:J}}function N3($,J){if(J)return J.exitCode!==null||J.signalCode!==null;try{return process.kill($,0),!1}catch{return!0}}async function oO($,J,X){let _=Date.now()+X;while(Date.now()<_){if(N3($,J))return!0;await new Promise((Q)=>setTimeout(Q,50))}return N3($,J)}async function Ij($,J){try{let X=await fetch($,{headers:J?{Authorization:`Bearer ${J}`}:void 0,signal:AbortSignal.timeout(1000)});if(!X.ok)return z3;return(await X.json()).active===!0?dO:z3}catch{return z3}}async function rO($){let J=T9($.pid);try{pO(J)}catch{}let X=await Ij($.streamUrl.replace(/\/stream\.mjpeg$/,"/recording/video"),$.token),_=await j3($.pid,void 0,X);if(!N3($.pid))throw Error(`Previous serve-sim helper ${$.pid} is still running; cannot replace it`);let Q;if(wh(J))try{let Y=JSON.parse(bh(J,"utf8"));Q=Array.isArray(Y.errors)?Y.errors.map(String).join("; ")||"Recording finalization failed":"Recording finalization failed"}catch{Q="Recording finalization failed"}if(Q)try{pO(J)}catch{}return{forced:_.forced,recordingError:Q??(X===dO&&_.forced?"Active recording was interrupted when the helper required SIGKILL":void 0)}}async function j3($,J,X=z3){if(N3($,J))return K3(J,!1);try{process.kill($,"SIGTERM")}catch{return K3(J,!1)}if(await oO($,J,X))return K3(J,!1);try{process.kill($,"SIGKILL")}catch{}return await oO($,J,1000),K3(J,!0)}c4();var _i=20000,MA=65000,Yi=12000,I1=b4(import.meta.url);function TA(){return"0.10.1"}var vA=!1;async function AA($){let J=await rO($);if(J.forced)console.error(`Previous serve-sim helper ${$.pid} required SIGKILL during stream-settings replacement.`);if(J.recordingError)vA=!0,process.exitCode=1,console.error(`Recording finalization failed while replacing helper ${$.pid}: ${J.recordingError}. Starting the replacement helper.`)}function PA(){RI(N$(),{recursive:!0})}function w4($){if($)return FI(r2($));for(let J of H0()){let X=FI(J);if(X)return X}return null}var F9={at:0,booted:null};function Ui(){let $=Date.now();if(F9.booted&&$-F9.at<1000)return F9.booted;try{let J=z0("xcrun simctl list devices booted -j",{encoding:"utf-8",stdio:["ignore","pipe","pipe"],timeout:3000}),X=JSON.parse(J),_=new Set;for(let Q of Object.values(X.devices))for(let Y of Q)if(Y.state==="Booted")_.add(Y.udid);return F9={at:$,booted:_},_}catch{return null}}function x6($){if(!$)return w4();let J=w4($);if(J)return J;let X=e3($).map((_)=>w4(_)).filter((_)=>_!==null);if(X.length>1)console.error(`Ambiguous streaming device "${$}": ${X.map((_)=>_.device).join(", ")}. Use --device <UDID> to select one.`),process.exit(1);return X[0]??null}function FI($){try{if(!o4($))return t4("state file missing %s",$),null;let J=JSON.parse(Z1($,"utf-8"));try{process.kill(J.pid,0)}catch{return t4("helper pid %d dead, removing stale state %s",J.pid,$),K0($),null}let X=Ui();if(X&&!X.has(J.device)){if(c0(J.device,F9.at))return t4("keeping state for capture reboot on device %s",J.device),J;if(J.pid===process.pid){t4("dropping own stale state for non-booted device %s",J.device);try{K0($)}catch{}return null}t4("helper pid %d bound to non-booted device %s — killing stale helper",J.pid,J.device),console.error(`[serve-sim] Helper pid ${J.pid} is bound to device ${J.device} which is no longer booted — killing stale helper.`);try{process.kill(J.pid,"SIGTERM")}catch{}try{K0($)}catch{}return null}return t4("state ok pid=%d device=%s port=%d",J.pid,J.device,J.port),J}catch(J){return t4("readStateFile threw for %s: %o",$,J),null}}function l3(){let $=[];for(let J of H0()){let X=FI(J);if(X)$.push(X)}return $}function Gi($){PA(),v9($),t4("wrote state pid=%d device=%s port=%d",$.pid,$.device,$.port)}function Wi($){return new Xi($.wsUrl,$.token?{headers:{Authorization:`Bearer ${$.token}`}}:void 0)}function u2($,J){if(J===void 0)return Uint8Array.of($);let X=new TextEncoder().encode(JSON.stringify(J)),_=new Uint8Array(1+X.length);return _[0]=$,_.set(X,1),_}function l2($,J){return new Promise((X,_)=>{let Q=Wi($);Q.binaryType="arraybuffer",p5(Q,$.inputAdmission===!0,()=>{Q.send(J),setTimeout(()=>{Q.close(),X()},50)},_),Q.onerror=()=>{console.error("Failed to connect to serve-sim server at",$.wsUrl),_(Error("WebSocket connection failed"))}})}function m2($){if($){t4("clearState device=%s",$);try{K0(r2($))}catch{}}else{t4("clearState (all)");for(let J of H0())try{K0(J)}catch{}}}function PI(){try{let $=z0("xcrun simctl list devices -j",{encoding:"utf-8"}),J=JSON.parse($),X=Object.keys(J.devices).filter((_)=>/SimRuntime\.iOS-/i.test(_)).sort((_,Q)=>{let Y=(_.match(/iOS-(\d+)-(\d+)/)??[]).slice(1).map(Number),U=(Q.match(/iOS-(\d+)-(\d+)/)??[]).slice(1).map(Number);return(U[0]??0)-(Y[0]??0)||(U[1]??0)-(Y[1]??0)});for(let _ of X){let Y=(J.devices[_]??[]).find((U)=>U.isAvailable!==!1&&/^iPhone\b/i.test(U.name));if(Y)return{udid:Y.udid,name:Y.name}}}catch{}return null}function DA($){return EA().get($)??null}function EA(){let $=new Map;try{let J=z0("xcrun simctl list devices -j",{encoding:"utf-8"}),X=JSON.parse(J);for(let _ of Object.values(X.devices))for(let Q of _)$.set(Q.udid,Q.name)}catch{}return $}function Ki($){try{let J=z0("xcrun simctl list devices -j",{encoding:"utf-8"}),X=JSON.parse(J);for(let _ of Object.values(X.devices))for(let Q of _)if(Q.udid===$)return Q.state==="Booted"}catch{}return!1}function OI($){try{return process.kill($,0),!0}catch{return!1}}function zi($){if(!Ki($))try{L9("xcrun",["simctl","boot",$],{encoding:"utf-8",stdio:"pipe",env:D1($)})}catch(J){let X=(J.stderr??J.message??"").toLowerCase();if(!X.includes("booted")&&!X.includes("current state"))throw Error(`Failed to boot device ${$}: ${J.stderr||J.message}`)}try{IO($)}catch{}}function Ni(){let $=Ji();for(let J of Object.values($))for(let X of J??[])if(X.family==="IPv4"&&!X.internal)return X.address;return null}async function qA($){let J=new Set(l3().map((X)=>X.port));for(let X=$;X<$+100;X++){if(J.has(X))continue;if(await tI(X))return X}throw Error(`No available port found in range ${$}-${$+99}`)}async function ji($){zi($);try{await Z$(["bootstatus",$,"-b"],s2)}catch(J){let X=J.killed?`boot did not finish within ${s2/1000}s`:`boot did not finish: ${J instanceof Error?J.message:String(J)}`;throw Error(`Simulator ${$} ${X}`,{cause:J})}await gZ($)}function CA(){for(let $ of YJ())try{y9($,process.pid,(J)=>{if(J.name==="camera")O9($)})}catch(J){console.error(`Could not clean up capabilities on ${$}: ${J instanceof Error?J.message:String(J)}`)}}var $4=!1,kA=!1,Ii;function u3(){return Ii??=(async()=>{await JJ();for(let $ of YJ())try{await _J($,process.pid,(J)=>{if(J.name==="camera")O9($)})}catch(J){console.error(`Could not clean up capabilities on ${$}: ${J instanceof Error?J.message:String(J)}`)}})()}var SA="SERVE_SIM_STREAM_HELPER";function Zi($){if(process.argv[0]&&/(^|\/)serve-sim$/.test(process.argv[0]))return{command:process.argv[0],args:$};return{command:process.argv[0],args:[process.argv[1],...$]}}async function Hi($,J=150000){let X=Date.now();while(Date.now()-X<J){let _=w4($);if(_)return _;await new Promise((Q)=>setTimeout(Q,200))}return null}async function xA($,J,X){O_("startHelper udid=%s port=%d detach=%s",$,J,X.detach);let _="127.0.0.1";PA(),NO(J),m2($);let Q=p4(N$(),`server-${$}.log`),Y=TI(Q,"w"),{command:U,args:G}=Zi(lO($,J,_,X.stream)),W=OA(U,G,{detached:X.detach,stdio:["ignore",Y,Y],env:{...process.env,[SA]:"1"}});if(vI(Y),X.detach)W.unref();let K=await Hi($);if(!K){if(W.pid)await j3(W.pid,W);let z="";try{z=Z1(Q,"utf-8").trim()}catch{}console.error(z?`Preview server failed:
|
|
362
|
+
Permissions: ${$j().join(", ")}`),process.exit(1);let Q=_.device?d$(_.device):A4();if(!Q)console.error("No booted simulator. Boot one or pass -d <udid|name>."),process.exit(1);if(_.verb==="list"){let U={udid:Q,bundleId:_.bundleId??null,tcc:Mh(Q,_.bundleId),location:Vh(Q,_.bundleId),notifications:Rh(Q,_.bundleId)};console.log(JSON.stringify(U,null,J?0:2));return}let Y=_.bundleId;try{if(_.permission==="all")for(let U of $j())PO(Q,"reset",U,void 0,Y);else PO(Q,_.verb,_.permission,_.value,Y)}catch(U){console.error(U?.message??String(U)),process.exit(1)}if(J)console.log(JSON.stringify({udid:Q,verb:_.verb,permission:_.permission,value:_.value??null,bundleId:Y}));else{let U=_.value?` (${_.value})`:"";console.log(`\uD83D\uDD10 ${_.verb} ${_.permission}${U} for ${Y} on ${Q}`)}}uJ();gJ();function fO($,J={}){let X=new Date($.timestamp),_=Number.isNaN(X.getTime())?$.timestamp:X.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"}),Q=J.deviceLabel??($.device?$.device.slice(0,8):null),Y=$.status==="error"?" failed":"";return[_,Q,`${Th($)}${Y?` (${Y.trim()})`:""}`].filter(Boolean).join(" ")}function Th($){if($.kind==="tap"){let J=_3($.details,"current")??_3($.details,"start");return J?`Tap at ${Yj(J)}`:"Tap"}if($.kind==="drag"){let J=_3($.details,"start"),X=_3($.details,"current");if(J&&X)return`Drag from ${Yj(J)} to ${Yj(X)}`;return"Drag"}if($.kind==="key"){let J=vh($.details,"key")??$.action??"key",X=$.action==="down"?"down":$.action==="up"?"up":$.action;return X?`Key ${X} ${gO(J)}`:`Key ${gO(J)}`}if($.kind==="rotate"){let J=$.action?yO($.action):"";return J?`Rotate ${J}`:"Rotate"}return Ph($.msg??$.summary)}function _3($,J){let X=$?.[J];if(!X||typeof X!=="object"||Array.isArray(X))return null;let _=X;return typeof _.x==="number"&&typeof _.y==="number"?{x:_.x,y:_.y}:null}function vh($,J){let X=$?.[J];return typeof X==="string"&&X.length>0?X:null}function Yj($){return`${bO($.x)}, ${bO($.y)}`}function bO($){if(!Number.isFinite($))return"?";return(Math.round((Ah($,0,1)+Number.EPSILON)*100)/100).toFixed(2)}function Ah($,J,X){return Math.min(X,Math.max(J,$))}function Ph($){return $.replace(/\b[a-z]+(?:_[a-z]+)+\b/g,yO)}function yO($){return $.replace(/[-_]+/g," ")}function gO($){return{MetaLeft:"Left Command",MetaRight:"Right Command",AltLeft:"Left Option",AltRight:"Right Option",ControlLeft:"Left Control",ControlRight:"Right Control",ShiftLeft:"Left Shift",ShiftRight:"Right Shift",ArrowLeft:"Left Arrow",ArrowRight:"Right Arrow",ArrowUp:"Up Arrow",ArrowDown:"Down Arrow"}[$]??$}Wj();CJ();function Kj($,J){let X=$.split(",").map((Q)=>Q.trim()).filter(Boolean),_=J==="stun"?/^stuns?:/i:/^turns?:/i;if(X.length===0||X.length>16||X.some((Q)=>Q.length>2048||!_.test(Q)))throw Error(`Expected one or more comma-separated ${J.toUpperCase()} URLs`);return X}function zj($,J){let X=$??{transport:"http"},_=J??{transport:"http"};if(X.transport!==_.transport)return!1;let Q=E0(X),Y=E0(_);if(Q.mjpegFps!==Y.mjpegFps||Q.mjpegQuality!==Y.mjpegQuality||Q.maxDimension!==Y.maxDimension||Q.h264Bitrate!==Y.h264Bitrate||Q.h264Fps!==Y.h264Fps)return!1;if(X.transport==="http"&&_.transport==="http")return(X.codec??"auto")===(_.codec??"auto");if(X.transport!=="webrtc"||_.transport!=="webrtc")return!1;if(X.codec!==_.codec)return!1;let U=X.iceServers??[],G=_.iceServers??[];if(U.length!==G.length)return!1;return U.every((W,K)=>{let z=G[K];return W.username===z.username&&W.credential===z.credential&&W.urls.length===z.urls.length&&W.urls.every((N,j)=>N===z.urls[j])})}function uO($,J){let X=[];for(let _ of $??[])for(let Q of _.urls){let Y=Q.toLowerCase();if(J.some((U)=>Y.startsWith(U)))X.push(Q)}return X}function Sh($){for(let J of $??[])if(J.urls.some((X)=>/^turns?:/i.test(X)))return J;return null}function xh($){if(!$)return[];let J=[];if(J.push("--transport",$.transport),$.transport==="http"){if($.codec)J.push("--codec",$.codec)}else{J.push("--webrtc-codec",$.codec);let X=uO($.iceServers,["stun:","stuns:"]);if(X.length)J.push("--stun-url",X.join(","));let _=uO($.iceServers,["turn:","turns:"]);if(_.length){J.push("--turn-url",_.join(","));let Q=Sh($.iceServers);if(Q?.username)J.push("--turn-username",Q.username);if(Q?.credential)J.push("--turn-credential",Q.credential)}}if($.mjpegFps!==void 0)J.push("--mjpeg-fps",String($.mjpegFps));if($.mjpegQuality!==void 0)J.push("--mjpeg-quality",String($.mjpegQuality));if($.maxDimension!==void 0)J.push("--max-dimension",String($.maxDimension));if($.h264Bitrate!==void 0)J.push("--video-bitrate",String($.h264Bitrate));if($.h264Fps!==void 0)J.push("--video-fps",String($.h264Fps));return J}function lO($,J,X,_){return[$,"--port",String(J),"--host",X,...xh(_)]}CJ();u6();jj();u6();import nO from"ws";async function cO($,J,X={}){if(!Q4(J))throw Error("Hinge angle must be between 0–180 degrees");return new Promise((_,Q)=>{let Y=new nO($,{headers:X.token?{Authorization:`Bearer ${X.token}`}:void 0}),U=!1,G=(K)=>{if(U)return;if(U=!0,clearTimeout(W),Y.close(),K)Q(K);else _()},W=setTimeout(()=>G(Error("Timed out waiting for hinge control acknowledgement")),X.timeoutMs??5000);Y.on("open",()=>{Y.send(Buffer.concat([Buffer.from([15]),Buffer.from(JSON.stringify({angle:J}))]))}),Y.on("message",(K)=>{let z=Buffer.from(K);if(z[0]!==143)return;let N;try{N=JSON.parse(z.subarray(1).toString())}catch{G(Error("Invalid hinge control acknowledgement"));return}if(!N||typeof N!=="object"||typeof N.ok!=="boolean"){G(Error("Invalid hinge control acknowledgement"));return}if(!N.ok)G(Error(N.error||"Hinge control is unavailable on this simulator"));else if(N.angle===J)G();else G(Error("Server acknowledged a different hinge angle"))}),Y.on("error",(K)=>G(Error(`Hinge control connection failed: ${K.message}`))),Y.on("close",()=>G(Error("Connection closed before hinge control acknowledgement")))})}async function iO($,J={}){return new Promise((X,_)=>{let Q=new nO($,{headers:J.token?{Authorization:`Bearer ${J.token}`}:void 0}),Y=!1,U=(W)=>{if(Y)return;if(Y=!0,clearTimeout(G),Q.close(),W instanceof Error)_(W);else X(W)},G=setTimeout(()=>U(Error("Timed out waiting for the simulator's hinge state")),J.timeoutMs??5000);Q.on("message",(W)=>{let K=Buffer.from(W);if(K[0]!==130)return;let z;try{z=JSON.parse(K.subarray(1).toString())}catch{U(Error("Invalid screen config from the serve-sim server"));return}if(z.supportsHingeAngle===void 0)return;if(!z.supportsHingeAngle){U(Error("Hinge control is unavailable on this simulator"));return}let{hingeAngle:N,hingePose:j,physicalOrientation:I,tableMode:Z,tableModeAvailable:D}=z;U({hingeAngle:N,hingePose:j,physicalOrientation:I,tableMode:Z,tableModeAvailable:D})}),Q.on("error",(W)=>U(Error(`Hinge state connection failed: ${W.message}`))),Q.on("close",()=>U(Error("Connection closed before the hinge state arrived")))})}n0();Z4();import{existsSync as wh,readFileSync as bh,unlinkSync as pO}from"node:fs";var z3=500,dO=65000;function K3($,J){return{exitCode:$?.exitCode??null,signalCode:$?.signalCode??null,forced:J}}function N3($,J){if(J)return J.exitCode!==null||J.signalCode!==null;try{return process.kill($,0),!1}catch{return!0}}async function oO($,J,X){let _=Date.now()+X;while(Date.now()<_){if(N3($,J))return!0;await new Promise((Q)=>setTimeout(Q,50))}return N3($,J)}async function Ij($,J){try{let X=await fetch($,{headers:J?{Authorization:`Bearer ${J}`}:void 0,signal:AbortSignal.timeout(1000)});if(!X.ok)return z3;return(await X.json()).active===!0?dO:z3}catch{return z3}}async function rO($){let J=T9($.pid);try{pO(J)}catch{}let X=await Ij($.streamUrl.replace(/\/stream\.mjpeg$/,"/recording/video"),$.token),_=await j3($.pid,void 0,X);if(!N3($.pid))throw Error(`Previous serve-sim helper ${$.pid} is still running; cannot replace it`);let Q;if(wh(J))try{let Y=JSON.parse(bh(J,"utf8"));Q=Array.isArray(Y.errors)?Y.errors.map(String).join("; ")||"Recording finalization failed":"Recording finalization failed"}catch{Q="Recording finalization failed"}if(Q)try{pO(J)}catch{}return{forced:_.forced,recordingError:Q??(X===dO&&_.forced?"Active recording was interrupted when the helper required SIGKILL":void 0)}}async function j3($,J,X=z3){if(N3($,J))return K3(J,!1);try{process.kill($,"SIGTERM")}catch{return K3(J,!1)}if(await oO($,J,X))return K3(J,!1);try{process.kill($,"SIGKILL")}catch{}return await oO($,J,1000),K3(J,!0)}c4();var _i=20000,MA=65000,Yi=12000,I1=b4(import.meta.url);function TA(){return"0.10.2-canary-20261019-059ca8e"}var vA=!1;async function AA($){let J=await rO($);if(J.forced)console.error(`Previous serve-sim helper ${$.pid} required SIGKILL during stream-settings replacement.`);if(J.recordingError)vA=!0,process.exitCode=1,console.error(`Recording finalization failed while replacing helper ${$.pid}: ${J.recordingError}. Starting the replacement helper.`)}function PA(){RI(N$(),{recursive:!0})}function w4($){if($)return FI(r2($));for(let J of H0()){let X=FI(J);if(X)return X}return null}var F9={at:0,booted:null};function Ui(){let $=Date.now();if(F9.booted&&$-F9.at<1000)return F9.booted;try{let J=z0("xcrun simctl list devices booted -j",{encoding:"utf-8",stdio:["ignore","pipe","pipe"],timeout:3000}),X=JSON.parse(J),_=new Set;for(let Q of Object.values(X.devices))for(let Y of Q)if(Y.state==="Booted")_.add(Y.udid);return F9={at:$,booted:_},_}catch{return null}}function x6($){if(!$)return w4();let J=w4($);if(J)return J;let X=e3($).map((_)=>w4(_)).filter((_)=>_!==null);if(X.length>1)console.error(`Ambiguous streaming device "${$}": ${X.map((_)=>_.device).join(", ")}. Use --device <UDID> to select one.`),process.exit(1);return X[0]??null}function FI($){try{if(!o4($))return t4("state file missing %s",$),null;let J=JSON.parse(Z1($,"utf-8"));try{process.kill(J.pid,0)}catch{return t4("helper pid %d dead, removing stale state %s",J.pid,$),K0($),null}let X=Ui();if(X&&!X.has(J.device)){if(c0(J.device,F9.at))return t4("keeping state for capture reboot on device %s",J.device),J;if(J.pid===process.pid){t4("dropping own stale state for non-booted device %s",J.device);try{K0($)}catch{}return null}t4("helper pid %d bound to non-booted device %s — killing stale helper",J.pid,J.device),console.error(`[serve-sim] Helper pid ${J.pid} is bound to device ${J.device} which is no longer booted — killing stale helper.`);try{process.kill(J.pid,"SIGTERM")}catch{}try{K0($)}catch{}return null}return t4("state ok pid=%d device=%s port=%d",J.pid,J.device,J.port),J}catch(J){return t4("readStateFile threw for %s: %o",$,J),null}}function l3(){let $=[];for(let J of H0()){let X=FI(J);if(X)$.push(X)}return $}function Gi($){PA(),v9($),t4("wrote state pid=%d device=%s port=%d",$.pid,$.device,$.port)}function Wi($){return new Xi($.wsUrl,$.token?{headers:{Authorization:`Bearer ${$.token}`}}:void 0)}function u2($,J){if(J===void 0)return Uint8Array.of($);let X=new TextEncoder().encode(JSON.stringify(J)),_=new Uint8Array(1+X.length);return _[0]=$,_.set(X,1),_}function l2($,J){return new Promise((X,_)=>{let Q=Wi($);Q.binaryType="arraybuffer",p5(Q,$.inputAdmission===!0,()=>{Q.send(J),setTimeout(()=>{Q.close(),X()},50)},_),Q.onerror=()=>{console.error("Failed to connect to serve-sim server at",$.wsUrl),_(Error("WebSocket connection failed"))}})}function m2($){if($){t4("clearState device=%s",$);try{K0(r2($))}catch{}}else{t4("clearState (all)");for(let J of H0())try{K0(J)}catch{}}}function PI(){try{let $=z0("xcrun simctl list devices -j",{encoding:"utf-8"}),J=JSON.parse($),X=Object.keys(J.devices).filter((_)=>/SimRuntime\.iOS-/i.test(_)).sort((_,Q)=>{let Y=(_.match(/iOS-(\d+)-(\d+)/)??[]).slice(1).map(Number),U=(Q.match(/iOS-(\d+)-(\d+)/)??[]).slice(1).map(Number);return(U[0]??0)-(Y[0]??0)||(U[1]??0)-(Y[1]??0)});for(let _ of X){let Y=(J.devices[_]??[]).find((U)=>U.isAvailable!==!1&&/^iPhone\b/i.test(U.name));if(Y)return{udid:Y.udid,name:Y.name}}}catch{}return null}function DA($){return EA().get($)??null}function EA(){let $=new Map;try{let J=z0("xcrun simctl list devices -j",{encoding:"utf-8"}),X=JSON.parse(J);for(let _ of Object.values(X.devices))for(let Q of _)$.set(Q.udid,Q.name)}catch{}return $}function Ki($){try{let J=z0("xcrun simctl list devices -j",{encoding:"utf-8"}),X=JSON.parse(J);for(let _ of Object.values(X.devices))for(let Q of _)if(Q.udid===$)return Q.state==="Booted"}catch{}return!1}function OI($){try{return process.kill($,0),!0}catch{return!1}}function zi($){if(!Ki($))try{L9("xcrun",["simctl","boot",$],{encoding:"utf-8",stdio:"pipe",env:D1($)})}catch(J){let X=(J.stderr??J.message??"").toLowerCase();if(!X.includes("booted")&&!X.includes("current state"))throw Error(`Failed to boot device ${$}: ${J.stderr||J.message}`)}try{IO($)}catch{}}function Ni(){let $=Ji();for(let J of Object.values($))for(let X of J??[])if(X.family==="IPv4"&&!X.internal)return X.address;return null}async function qA($){let J=new Set(l3().map((X)=>X.port));for(let X=$;X<$+100;X++){if(J.has(X))continue;if(await tI(X))return X}throw Error(`No available port found in range ${$}-${$+99}`)}async function ji($){zi($);try{await Z$(["bootstatus",$,"-b"],s2)}catch(J){let X=J.killed?`boot did not finish within ${s2/1000}s`:`boot did not finish: ${J instanceof Error?J.message:String(J)}`;throw Error(`Simulator ${$} ${X}`,{cause:J})}await gZ($)}function CA(){for(let $ of YJ())try{y9($,process.pid,(J)=>{if(J.name==="camera")O9($)})}catch(J){console.error(`Could not clean up capabilities on ${$}: ${J instanceof Error?J.message:String(J)}`)}}var $4=!1,kA=!1,Ii;function u3(){return Ii??=(async()=>{await JJ();for(let $ of YJ())try{await _J($,process.pid,(J)=>{if(J.name==="camera")O9($)})}catch(J){console.error(`Could not clean up capabilities on ${$}: ${J instanceof Error?J.message:String(J)}`)}})()}var SA="SERVE_SIM_STREAM_HELPER";function Zi($){if(process.argv[0]&&/(^|\/)serve-sim$/.test(process.argv[0]))return{command:process.argv[0],args:$};return{command:process.argv[0],args:[process.argv[1],...$]}}async function Hi($,J=150000){let X=Date.now();while(Date.now()-X<J){let _=w4($);if(_)return _;await new Promise((Q)=>setTimeout(Q,200))}return null}async function xA($,J,X){O_("startHelper udid=%s port=%d detach=%s",$,J,X.detach);let _="127.0.0.1";PA(),NO(J),m2($);let Q=p4(N$(),`server-${$}.log`),Y=TI(Q,"w"),{command:U,args:G}=Zi(lO($,J,_,X.stream)),W=OA(U,G,{detached:X.detach,stdio:["ignore",Y,Y],env:{...process.env,[SA]:"1"}});if(vI(Y),X.detach)W.unref();let K=await Hi($);if(!K){if(W.pid)await j3(W.pid,W);let z="";try{z=Z1(Q,"utf-8").trim()}catch{}console.error(z?`Preview server failed:
|
|
363
363
|
${z}`:"Preview server failed to start"),process.exit(1)}return X.detach?{pid:K.pid}:{pid:K.pid,child:W}}async function Bi($,J,X,_,Q=!1){F_("follow devices=%o startPort=%d",$,J);let Y=$.length>0?$.map(d$):(()=>{let N=A4();if(N)return[N];let j=PI();if(!j)console.error("No device specified and no available iOS simulator found."),process.exit(1);if(!X)console.log(`No booted simulator — booting ${j.name}...`);return[j.udid]})(),U=new Map,G=[],W=J;for(let N of Y){let j=w4(N);if(j)if(Q&&!zj(j.streamSettings,_))await AA(j),m2(N);else{if(!X){let D=DA(N)??N;if(Y.length>1)console.log(`
|
|
364
364
|
==> ${D} (${N}) <==`);console.log(` Already running on port ${j.port}`),console.log(` Stream: ${j.streamUrl}`),console.log(` WebSocket: ${j.wsUrl}`)}G.push(j);continue}W=await qA(W);let{child:I}=await xA(N,W,{detach:!1,stream:_});if(I)U.set(N,I);let Z=w4(N)??H1(N,W,"/","127.0.0.1");if(G.push(Z),!X){let D=DA(N)??N;if(Y.length>1)console.log(`
|
|
365
365
|
==> ${D} (${N}) <==`);console.log(` Stream: ${Z.streamUrl}`),console.log(` WebSocket: ${Z.wsUrl}`),console.log(` Port: ${W}`)}W++}if(G.length===1){let N=G[0];console.log(JSON.stringify({url:N.url,streamUrl:N.streamUrl,wsUrl:N.wsUrl,port:N.port,device:N.device}))}else console.log(JSON.stringify({devices:G.map((N)=>({url:N.url,streamUrl:N.streamUrl,wsUrl:N.wsUrl,port:N.port,device:N.device}))}));if(U.size===0)return;let K=!1,z=async(N)=>{if(K)return;if(K=!0,$4=!0,!X)console.log(`
|
|
@@ -417,5 +417,5 @@ Examples:
|
|
|
417
417
|
Launch an installed app, then start the stream`).action(async($,J)=>{if(J.list!==void 0){Vi(typeof J.list==="string"?J.list:void 0);return}if(J.kill!==void 0){await Li(typeof J.kill==="string"?J.kill:void 0);return}try{V0()}catch(B){W0(B instanceof Error?B.message:String(B),!!J.quiet),process.exit(1)}try{let B=_5(J.networkCaptureProxy);if(B!==null&&(J.detach||J.preview===!1))throw Error("--network-capture-proxy needs the preview server, so drop --detach/--no-preview. Their stream helpers would capture without it.");E$.setUpstream(B)}catch(B){W0(B instanceof Error?B.message:String(B),!!J.quiet),process.exit(1)}if(J.transport!=="http"&&J.transport!=="webrtc")console.error("--transport must be one of: http, webrtc."),process.exit(1);let X=(B)=>l$.getOptionValueSource(B)==="cli",_=["webrtcCodec","stunUrl","turnUrl","turnUsername","turnCredential"].some(X);if(J.transport==="http"&&_)console.error("WebRTC options require --transport webrtc."),process.exit(1);if(J.transport==="webrtc"&&X("codec"))console.error("--codec configures HTTP streaming; use --webrtc-codec with --transport webrtc."),process.exit(1);if(J.turnUsername===void 0!==(J.turnCredential===void 0))console.error("--turn-username and --turn-credential must be provided together."),process.exit(1);if((J.turnUsername!==void 0||J.turnCredential!==void 0)&&!J.turnUrl)console.error("--turn-username and --turn-credential require --turn-url."),process.exit(1);let Q=J.stunUrl??[],Y=[];if(Q.length)Y.push({urls:Q});if(J.turnUrl)Y.push({urls:J.turnUrl,username:J.turnUsername,credential:J.turnCredential});let U=["mjpegFps","mjpegQuality","maxDimension","videoBitrate","videoFps"],G={...X("mjpegFps")?{mjpegFps:J.mjpegFps}:{},...X("mjpegQuality")?{mjpegQuality:J.mjpegQuality}:{},...X("maxDimension")?{maxDimension:J.maxDimension}:{},...X("videoBitrate")?{h264Bitrate:J.videoBitrate}:{},...X("videoFps")?{h264Fps:J.videoFps}:{}},W=J.transport==="webrtc"?{transport:"webrtc",codec:J.webrtcCodec,...Y.length?{iceServers:Y}:{},...G}:{transport:"http",codec:J.codec,...G},K=typeof J.launchAppIdentifier==="string"?J.launchAppIdentifier.trim():"";if(J.launchAppIdentifier!==void 0&&!K)console.error("--launch-app-identifier needs an app bundle identifier, such as host.exp.Exponent."),process.exit(1);let z=J.installAppPath===void 0?void 0:J6(J.installAppPath);if(z){try{if(Qi(z)!==".app"||!sc(z).isDirectory())throw Error("expected a .app directory")}catch{W0(`--install-app-path needs an existing .app directory: ${z}`,!!J.quiet),process.exit(1)}let B=await U4({file:"plutil",args:["-extract","CFBundleIdentifier","raw","-expect","string","-o","-",p4(z,"Info.plist")]});if(B.exitCode!==0||!B.stdout.trim())W0(`Could not read CFBundleIdentifier from ${z}/Info.plist: ${B.stderr.trim()||"expected a non-empty string"}`,!!J.quiet),process.exit(1)}let N=J.launchArg??[],j=J.openUrl;if(!K&&(N.length>0||j))console.error("--launch-arg and --open-url apply to an app launch. Pass --launch-app-identifier with the app to launch."),process.exit(1);let I={enable:J.enable??[],disable:J.disable??[]};try{QX([...I.enable,...I.disable])}catch(B){console.error(B instanceof Error?B.message:B),process.exit(1)}let Z=process.env[SA]==="1",D=J.port,v=X("transport")||X("codec")||_||U.some(X),T=J.debugStream?.trim();if(J.debugStream!==void 0){let B=!T?"--debug-stream needs a file path, for example --debug-stream ./stream.ndjson":J.detach||J.preview===!1?"--debug-stream needs the preview server, so drop --detach/--no-preview.":W.transport!=="webrtc"?"--debug-stream records sender statistics, which only exist on --transport webrtc.":null;if(B!==null)console.error(B),process.exit(1)}if(J.networkCapture&&(J.detach||J.preview===!1))console.error("--network-capture needs the preview server, so drop --detach/--no-preview. The proxy and its recordings live in that process; these modes exit and would leave nothing capturing."),process.exit(1);let L=J.networkCapture?"--network-capture":I.enable.includes("networkCapture")&&!I.disable.includes("networkCapture")?"--enable networkCapture":null;if(L&&!J.requireToken&&!s1(J.host))console.error(`${L} on --host ${J.host} needs --require-token. Without it the preview page, open to anyone who can reach it, carries the session token, and that token also reads the captured traffic.`),process.exit(1);if(J.requireToken&&(J.detach||J.preview===!1))console.error("--require-token needs the preview server, so drop --detach/--no-preview. It gates the network-exposed preview; those modes bind loopback only, where the token does nothing."),process.exit(1);if(J.detach){let B=[...z?["--install-app-path"]:[],...K?["--launch-app-identifier"]:[],...N.length>0?["--launch-arg"]:[],...j?["--open-url"]:[],...I.enable.length>0?["--enable"]:[],...I.disable.length>0?["--disable"]:[]];if(B.length>0)console.error(`${B.join(", ")} ${B.length===1?"needs":"need"} the foreground session, so drop --detach. A detached helper only streams: it does not arm the capability loader or launch an app.`),process.exit(1)}let O=$,P=null,E=()=>{return P??=(async()=>{await(await Promise.resolve().then(() => (c4(),Z6))).captureRuntime.disableAll()})(),P};if(!J.detach)try{O=ni($);{process.on("exit",()=>{CA()});for(let B of["SIGINT","SIGTERM","SIGHUP"])process.on(B,async()=>{if($4=!0,J.preview!==!1&&kA)return;try{await E()}catch(H){console.error(`Network capture teardown failed: ${H instanceof Error?H.message:String(H)}`)}if(await u3(),J.preview===!1&&process.listenerCount(B)>1)return;process.exit(0)})}for(let B of O)if(await ji(B),$4)return;if(!Z){for(let B of O)if(await wZ(B),$4)return}if((await Promise.resolve().then(() => (c4(),Z6))).captureRuntime.refuseCapture(yA(J.host,!!J.requireToken)),await hA(J.networkCapture?O:[],J.networkCaptureField,!!J.quiet),$4)return;for(let B of Z?[]:O){if($4)return;if(z){let H=await U4(e7(B,z));if(H.exitCode!==0)throw Error(`Could not install ${z} on ${B}: ${H.stderr.trim()||`simctl exited ${H.exitCode}`}`);if($4)return}if(K)await zO(B,{bundleId:K,launchArgs:N,openUrl:j,capabilities:I});else{let H=await u9(B,null,I),V=jZ(I,H);if(V.length>0)throw Error(`Requested ${V.join(", ")} but ${V.length===1?"it":"they"} did not apply on ${B}. See the message above for why.`)}}}catch(B){if($4)return;W0(B instanceof Error?B.message:String(B),!!J.quiet),$4=!0;try{await E()}finally{await u3()}process.exit(1)}if($4)return;if(J.detach){let B=await Mi(O,D??3100,W,v);Di(B)}else if(J.preview===!1)await Bi(O,D??3100,!!J.quiet,W,v);else await ci(D??3200,O,D!==void 0,J.host,{stream:W,corsOrigins:J.corsOrigin,frameAncestors:J.frameAncestor,shareUrl:J.shareUrl,disableShare:!!J.disableShare,allowAnyHostWhenInsecure:!!J.allowAnyHostWhenInsecure,debugStreamPath:T,requireToken:!!J.requireToken,quiet:!!J.quiet,networkCapture:!!J.networkCapture,networkCaptureProxy:J.networkCaptureProxy,clipboard:Z?"unmanaged":!I.disable.includes("clipboard"),networkCaptureFields:J.networkCaptureField})});var Q6=["-d, --device <udid>","Target a specific simulator (udid or name)"];async function LA($,J){let X=Date.now()+J;while(!o4($)&&Date.now()<X)await new Promise((_)=>setTimeout(_,250));return o4($)}async function FA($,J){let X=Date.now()+J;while(Date.now()<X){try{process.kill($,0)}catch{return!0}await new Promise((_)=>setTimeout(_,250))}try{process.kill($,0)}catch{return!0}return!1}async function oi($,J){let X=w4($);if(!X)throw Error(`No running serve-sim session found for ${$}; start serve-sim for this device and retry.`);let _=X.streamUrl.replace(/\/stream\.mjpeg$/,"/recording/video"),Q=J6(J),Y=p4(Q,"session.json");if(o4(Y))throw Error(`Recording manifest already exists at ${Y}; choose an empty output directory.`);let U=RA(16).toString("hex"),G={"x-recording-id":U};if(X.token)G.Authorization=`Bearer ${X.token}`;let W=()=>{},K=new Promise((V)=>{W=V}),z=!1,N=!1,j=new AbortController,I=()=>{if(z=!0,!N)j.abort();W()},Z=setInterval(()=>{},60000),D,v=!1,T=new AbortController,L=!1,O=()=>{},P=new Promise((V,R)=>{O=R});P.catch(()=>{});let E=!1,B=!1,H=!1;process.on("SIGINT",I),process.on("SIGTERM",I);try{try{let M=await fetch(_,{method:"POST",headers:{...G,"Content-Type":"application/json"},body:JSON.stringify({start:!0,output:Q,recordingId:U}),signal:AbortSignal.any([AbortSignal.timeout(30000),j.signal])});if(!M.ok)throw Error(`Recording start failed (${M.status}): ${await M.text()}`)}catch(M){if(!z)throw M;let F=await fetch(_,{method:"DELETE",headers:G,signal:AbortSignal.timeout(120000)});if(B=!0,F.status===200){if((await F.json()).manifest===Y&&await LA(Y,120000)){E=!0,console.log(Y);return}}throw Error(`Recording start was interrupted before a video was saved: ${String(M)}`)}N=!0,console.error("serve-sim:recording-started"),D=setInterval(()=>{if(L||v)return;v=!0,fetch(_,{method:"PUT",headers:G,signal:AbortSignal.any([AbortSignal.timeout(120000),T.signal])}).then(async(M)=>{if(!M.ok&&M.status<500&&M.status!==408&&M.status!==429&&!L)O(Error(`Recording lease was lost (${M.status})`));await M.body?.cancel()}).catch(async(M)=>{if(!L&&await FA(X.pid,0))O(M instanceof Error?M:Error(String(M)))}).finally(()=>{v=!1})},5000);let V;try{await Promise.race([K,P])}catch(M){V=M}L=!0,T.abort(),clearInterval(D),D=void 0;let R,w=!1;try{let M;try{M=await fetch(_,{method:"DELETE",headers:G,signal:AbortSignal.timeout(120000)})}catch(A){throw w=!0,A}if(!M.ok)throw Error(`Recording stop failed (${M.status}): ${await M.text()}`);if((await M.json()).manifest!==Y)throw Error("Recording stop returned an unexpected manifest path");if(H=!0,V)R=V,w=!0}catch(M){R=M}if(R&&!w)throw R;if(!await LA(Y,w?hI:yI))throw R??Error("Recording stopped without a session.json manifest; inspect the serve-sim session log and retry.");let q=JSON.parse(Z1(Y,"utf8"));if(q.status==="failed")throw H=!0,Error(`Recording finalized a partial MP4: ${q.error??"native recording failed"}. Saved manifest: ${Y}`);if(R&&!z&&!await FA(X.pid,5000)){if(!z)throw Error(`Recording ended before a stop was requested: ${String(R)}. A partial video is available at ${Y}.`)}E=!0,console.log(Y)}finally{if(L=!0,T.abort(),D)clearInterval(D);if(!E&&!B&&!H)try{await fetch(_,{method:"DELETE",headers:G,signal:AbortSignal.timeout(1e4)})}catch{}clearInterval(Z),process.off("SIGINT",I),process.off("SIGTERM",I)}}l$.command("record-video").description("Record native-size hardware H.264 simulator video until SIGINT").requiredOption("--udid <udid>","Simulator UDID").requiredOption("--output <dir>","Output directory").action(async($)=>oi($.udid,$.output));l$.command("gesture").description("Send a touch event or a complete begin/move/end event array").argument("<json>",`Gesture JSON, e.g. '{"type":"begin","x":0.5,"y":0.5}'`).option(...Q6).action(($,J)=>Ti($,J.device));l$.command("tap").description("Tap at normalized 0..1 coords").argument("<x>","X coord, normalized 0..1").argument("<y>","Y coord, normalized 0..1").option(...Q6).action(($,J,X)=>vi($,J,X.device));l$.command("button").description("Send a hardware button press").argument("[name]","Button name","home").option(...Q6).action(($,J)=>Ci($,J.device));l$.command("type").description("Type text (US keyboard only)").argument("[text...]","Text to type").option(...Q6).option("--stdin","Read text from stdin").option("--file <path>","Read text from a file").action(($,J)=>Ai($,{device:J.device,stdin:J.stdin,file:J.file}));l$.command("rotate").description("Set device orientation (portrait|portrait_upside_down|landscape_left|landscape_right)").argument("<orientation>").option(...Q6).action(($,J)=>Ei($,J.device));l$.command("hinge").description("Set or read a foldable simulator's hinge angle (0° folded, 90° half folded, 180° unfolded)").argument("[position]","fold|half|unfold or an angle from 0 to 180 degrees",($)=>{let J=aB($);if(J===void 0)throw new G6("Expected fold, half, unfold, or an angle from 0 to 180");return J}).option(...Q6).action(($,J)=>Pi($,J.device));l$.command("ca-debug").description(`Toggle a CoreAnimation debug render flag (${Object.keys(X0).join("|")})`).argument("<option>").argument("<state>","on|off").option(...Q6).action(($,J,X)=>ki($,J,X.device));l$.command("memory-warning").description("Simulate a memory warning on the device").option(...Q6).action(($)=>Si($.device));l$.command("software-keyboard").description("Show or hide the on-screen keyboard").option(...Q6).action(($)=>xi($.device));l$.command("event-log").description("Show recent simulator events").option(...Q6).option("-j, --json","Print JSON").option("-n, --limit <count>","Maximum number of events").action(($)=>Fi($.device,{json:$.json,limit:$.limit}));l$.command("camera").description("Inject a synthetic camera feed and launch an app (see `camera --help`)").allowUnknownOption(!0).helpOption(!1).argument("[args...]").action(($)=>li($,!!l$.opts().quiet));l$.command("permissions").description("Manage app permissions (see `permissions` with no args for usage)").allowUnknownOption(!0).helpOption(!1).argument("[args...]").action(($)=>wO($));l$.command("ui").description("Get or set simulator-wide UI options (see `ui --help`)").allowUnknownOption(!0).helpOption(!1).argument("[args...]").action(($)=>BM($));JX(E2);JX(E$.capability);l$.command("capture").description("Network capture helpers").command("har").description("Follow the capture stream; write a HAR and its event log").requiredOption("-o, --out <path>","HAR file to keep rewriting").option("--events <path>","NDJSON event log (default: <name>.network-capture.json beside the HAR)").option(...Q6).option("--flush-ms <ms>","How often to rewrite the HAR, in milliseconds (250-3600000)",(J)=>h2(J,"--flush-ms",250,3600000,!0),5000).option("--force","Replace a recording that already holds requests at --out").action(async(J)=>{let X=J.device?d$(J.device):void 0,_=w4(X);if(!_)console.error("No serve-sim server running. Run `serve-sim --network-capture` first."),process.exit(1);if(!_.token)console.error("This serve-sim session recorded no access token, so the capture routes cannot be reached. Restart serve-sim on localhost, or with --require-token."),process.exit(1);let Q=J6(J.out),Y=J.events?J6(J.events):void 0,U=new AbortController,G=()=>U.abort();process.on("SIGINT",G),process.on("SIGTERM",G),console.error(`Recording capture for ${_.device} → ${Q} (+ ${Y??e8(Q).eventsPath}) (Ctrl-C to stop)`);let W=!1;try{let K=await H3({onBegin:()=>{W=!0},onPause:(z)=>console.error(`${z}
|
|
418
418
|
Still recording to ${Q}; requests are appended when capture is on again (Ctrl-C to stop).`),onResume:()=>console.error("Capture is on again; recording continues."),replace:!!J.force,baseUrl:uI(_),device:_.device,outPath:Q,eventsPath:Y,flushIntervalMs:J.flushMs,signal:U.signal,version:TA(),token:_.token});console.error(`The capture stream closed before you stopped the recording, so later requests are not in the HAR. serve-sim stopped or the connection dropped. To keep recording, run \`serve-sim capture har\` again with a new --out path. Wrote ${K.size} entries to ${Q}.`),process.exit(1)}catch(K){if(K?.name==="AbortError"){console.error(W?`Stopped. HAR at ${Q}`:`Stopped before recording began; ${Q} was not written.`);return}console.error(K instanceof Error?K.message:String(K)),process.exit(1)}});await l$.parseAsync(process.argv);
|
|
419
419
|
|
|
420
|
-
//# debugId=
|
|
420
|
+
//# debugId=D58AF0F75E84B7DC64756E2164756E21
|
|
421
421
|
//# sourceMappingURL=serve-sim.js.map
|