serve-sim 0.1.45-beta.116.1 → 0.1.45
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/serve-sim.js +2 -2
- package/package.json +1 -1
package/dist/serve-sim.js
CHANGED
|
@@ -146,7 +146,7 @@ Usage:
|
|
|
146
146
|
serve-sim permissions reset <permission|all> <bundle-id> [-d <udid|name>]
|
|
147
147
|
serve-sim permissions list [bundle-id] [-d <udid|name>]
|
|
148
148
|
|
|
149
|
-
Permissions: ${w8().join(", ")}`),process.exit(1);let Y=J.device?o(J.device):Z$();if(!Y)console.error("No booted simulator. Boot one or pass -d <udid|name>."),process.exit(1);if(J.verb==="list"){let G={udid:Y,bundleId:J.bundleId??null,tcc:WZ(Y,J.bundleId),location:MZ(Y,J.bundleId),notifications:UZ(Y,J.bundleId)};console.log(JSON.stringify(G,null,Q?0:2)),process.exit(0)}let X=J.bundleId;try{if(J.permission==="all")for(let G of w8())p6(Y,"reset",G,void 0,X);else p6(Y,J.verb,J.permission,J.value,X)}catch(G){console.error(G?.message??String(G)),process.exit(1)}if(Q)console.log(JSON.stringify({udid:Y,verb:J.verb,permission:J.permission,value:J.value??null,bundleId:X}));else{let G=J.value?` (${J.value})`:"";console.log(`\uD83D\uDD10 ${J.verb} ${J.permission}${G} for ${X} on ${Y}`)}process.exit(0)}m8();i8();function N9($,Q={}){let Z=new Date($.timestamp),J=Number.isNaN(Z.getTime())?$.timestamp:Z.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"}),Y=Q.deviceLabel??($.device?$.device.slice(0,8):null),X=$.status==="error"?" failed":"";return[J,Y,`${GJ($)}${X?` (${X.trim()})`:""}`].filter(Boolean).join(" ")}function GJ($){if($.kind==="tap"){let Q=n0($.details,"current")??n0($.details,"start");return Q?`Tap at ${o8(Q)}`:"Tap"}if($.kind==="drag"){let Q=n0($.details,"start"),Z=n0($.details,"current");if(Q&&Z)return`Drag from ${o8(Q)} to ${o8(Z)}`;return"Drag"}if($.kind==="key"){let Q=zJ($.details,"key")??$.action??"key",Z=$.action==="down"?"down":$.action==="up"?"up":$.action;return Z?`Key ${Z} ${_9(Q)}`:`Key ${_9(Q)}`}if($.kind==="rotate"){let Q=$.action?B9($.action):"";return Q?`Rotate ${Q}`:"Rotate"}return WJ($.msg??$.summary)}function n0($,Q){let Z=$?.[Q];if(!Z||typeof Z!=="object"||Array.isArray(Z))return null;let J=Z;return typeof J.x==="number"&&typeof J.y==="number"?{x:J.x,y:J.y}:null}function zJ($,Q){let Z=$?.[Q];return typeof Z==="string"&&Z.length>0?Z:null}function o8($){return`${U9($.x)}, ${U9($.y)}`}function U9($){if(!Number.isFinite($))return"?";return(Math.round((KJ($,0,1)+Number.EPSILON)*100)/100).toFixed(2)}function KJ($,Q,Z){return Math.min(Z,Math.max(Q,$))}function WJ($){return $.replace(/\b[a-z]+(?:_[a-z]+)+\b/g,B9)}function B9($){return $.replace(/[-_]+/g," ")}function _9($){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"}[$]??$}var F9=["devices","tools","devtools"];function T9($){let Q=$.split(",").map((J)=>J.trim().toLowerCase()).filter(Boolean);if(Q.length===1&&Q[0]==="none")return[];if(Q.length===0||Q.includes("none"))throw Error("Expected 'none' or a comma-separated list of: devices, tools, devtools.");let Z=Q.filter((J)=>!F9.includes(J));if(Z.length>0)throw Error(`Unknown pane${Z.length===1?"":"s"}: ${Z.join(", ")}. Expected: ${F9.join(", ")}.`);return[...new Set(Q)]}function j9($){let Q=$.trim().toLowerCase();if(Q==="light"||Q==="dark")return Q;throw Error("Expected simulator theme: light or dark.")}s8();var C$=h0(import.meta.url);function VY(){return"0.1.45
|
|
149
|
+
Permissions: ${w8().join(", ")}`),process.exit(1);let Y=J.device?o(J.device):Z$();if(!Y)console.error("No booted simulator. Boot one or pass -d <udid|name>."),process.exit(1);if(J.verb==="list"){let G={udid:Y,bundleId:J.bundleId??null,tcc:WZ(Y,J.bundleId),location:MZ(Y,J.bundleId),notifications:UZ(Y,J.bundleId)};console.log(JSON.stringify(G,null,Q?0:2)),process.exit(0)}let X=J.bundleId;try{if(J.permission==="all")for(let G of w8())p6(Y,"reset",G,void 0,X);else p6(Y,J.verb,J.permission,J.value,X)}catch(G){console.error(G?.message??String(G)),process.exit(1)}if(Q)console.log(JSON.stringify({udid:Y,verb:J.verb,permission:J.permission,value:J.value??null,bundleId:X}));else{let G=J.value?` (${J.value})`:"";console.log(`\uD83D\uDD10 ${J.verb} ${J.permission}${G} for ${X} on ${Y}`)}process.exit(0)}m8();i8();function N9($,Q={}){let Z=new Date($.timestamp),J=Number.isNaN(Z.getTime())?$.timestamp:Z.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"}),Y=Q.deviceLabel??($.device?$.device.slice(0,8):null),X=$.status==="error"?" failed":"";return[J,Y,`${GJ($)}${X?` (${X.trim()})`:""}`].filter(Boolean).join(" ")}function GJ($){if($.kind==="tap"){let Q=n0($.details,"current")??n0($.details,"start");return Q?`Tap at ${o8(Q)}`:"Tap"}if($.kind==="drag"){let Q=n0($.details,"start"),Z=n0($.details,"current");if(Q&&Z)return`Drag from ${o8(Q)} to ${o8(Z)}`;return"Drag"}if($.kind==="key"){let Q=zJ($.details,"key")??$.action??"key",Z=$.action==="down"?"down":$.action==="up"?"up":$.action;return Z?`Key ${Z} ${_9(Q)}`:`Key ${_9(Q)}`}if($.kind==="rotate"){let Q=$.action?B9($.action):"";return Q?`Rotate ${Q}`:"Rotate"}return WJ($.msg??$.summary)}function n0($,Q){let Z=$?.[Q];if(!Z||typeof Z!=="object"||Array.isArray(Z))return null;let J=Z;return typeof J.x==="number"&&typeof J.y==="number"?{x:J.x,y:J.y}:null}function zJ($,Q){let Z=$?.[Q];return typeof Z==="string"&&Z.length>0?Z:null}function o8($){return`${U9($.x)}, ${U9($.y)}`}function U9($){if(!Number.isFinite($))return"?";return(Math.round((KJ($,0,1)+Number.EPSILON)*100)/100).toFixed(2)}function KJ($,Q,Z){return Math.min(Z,Math.max(Q,$))}function WJ($){return $.replace(/\b[a-z]+(?:_[a-z]+)+\b/g,B9)}function B9($){return $.replace(/[-_]+/g," ")}function _9($){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"}[$]??$}var F9=["devices","tools","devtools"];function T9($){let Q=$.split(",").map((J)=>J.trim().toLowerCase()).filter(Boolean);if(Q.length===1&&Q[0]==="none")return[];if(Q.length===0||Q.includes("none"))throw Error("Expected 'none' or a comma-separated list of: devices, tools, devtools.");let Z=Q.filter((J)=>!F9.includes(J));if(Z.length>0)throw Error(`Unknown pane${Z.length===1?"":"s"}: ${Z.join(", ")}. Expected: ${F9.join(", ")}.`);return[...new Set(Q)]}function j9($){let Q=$.trim().toLowerCase();if(Q==="light"||Q==="dark")return Q;throw Error("Expected simulator theme: light or dark.")}s8();var C$=h0(import.meta.url);function VY(){return"0.1.45"}function _5(){if(!K$(W$))tQ(W$,{recursive:!0})}function r($){if($)return rQ(W0($));for(let Q of f0()){let Z=rQ(Q);if(Z)return Z}return null}var U8={at:0,booted:null};function MY(){let $=Date.now();if(U8.booted&&$-U8.at<1000)return U8.booted;try{let Q=$$("xcrun simctl list devices booted -j",{encoding:"utf-8",stdio:["ignore","pipe","pipe"],timeout:3000}),Z=JSON.parse(Q),J=new Set;for(let Y of Object.values(Z.devices))for(let X of Y)if(X.state==="Booted")J.add(X.udid);return U8={at:$,booted:J},J}catch{return null}}function rQ($){try{if(!K$($))return V$("state file missing %s",$),null;let Q=JSON.parse(m$($,"utf-8"));try{process.kill(Q.pid,0)}catch{return V$("helper pid %d dead, removing stale state %s",Q.pid,$),g$($),null}let Z=MY();if(Z&&!Z.has(Q.device)){if(Q.pid===process.pid){V$("dropping own stale state for non-booted device %s",Q.device);try{g$($)}catch{}return null}V$("helper pid %d bound to non-booted device %s — killing stale helper",Q.pid,Q.device),console.error(`[serve-sim] Helper pid ${Q.pid} is bound to device ${Q.device} which is no longer booted — killing stale helper.`);try{process.kill(Q.pid,"SIGTERM")}catch{}try{g$($)}catch{}return null}return V$("state ok pid=%d device=%s port=%d",Q.pid,Q.device,Q.port),Q}catch(Q){return V$("readStateFile threw for %s: %o",$,Q),null}}function I0(){let $=[];for(let Q of f0()){let Z=rQ(Q);if(Z)$.push(Z)}return $}function HY($){_5(),Q6(W0($.device),JSON.stringify($,null,2)),V$("wrote state pid=%d device=%s port=%d",$.pid,$.device,$.port)}function c$($){if($){V$("clearState device=%s",$);try{g$(W0($))}catch{}}else{V$("clearState (all)");for(let Q of f0())try{g$(Q)}catch{}}}function Z6(){try{let $=$$("xcrun simctl list devices -j",{encoding:"utf-8"}),Q=JSON.parse($),Z=Object.keys(Q.devices).filter((J)=>/SimRuntime\.iOS-/i.test(J)).sort((J,Y)=>{let X=(J.match(/iOS-(\d+)-(\d+)/)??[]).slice(1).map(Number),G=(Y.match(/iOS-(\d+)-(\d+)/)??[]).slice(1).map(Number);return(G[0]??0)-(X[0]??0)||(G[1]??0)-(X[1]??0)});for(let J of Z){let X=(Q.devices[J]??[]).find((G)=>G.isAvailable!==!1&&/^iPhone\b/i.test(G.name));if(X)return{udid:X.udid,name:X.name}}}catch{}return null}function L5($){return N5().get($)??null}function N5(){let $=new Map;try{let Q=$$("xcrun simctl list devices -j",{encoding:"utf-8"}),Z=JSON.parse(Q);for(let J of Object.values(Z.devices))for(let Y of J)$.set(Y.udid,Y.name)}catch{}return $}function B5($){try{let Q=$$("xcrun simctl list devices -j",{encoding:"utf-8"}),Z=JSON.parse(Q);for(let J of Object.values(Z.devices))for(let Y of J)if(Y.udid===$)return Y.state==="Booted"}catch{}return!1}function sQ($){try{return process.kill($,0),!0}catch{return!1}}function F5($){try{process.kill($,"SIGTERM")}catch{return}let Q=Date.now()+500;while(Date.now()<Q)try{process.kill($,0),I$(25)}catch{return}try{process.kill($,"SIGKILL")}catch{}let Z=Date.now()+500;while(Date.now()<Z)try{process.kill($,0),I$(25)}catch{return}}function RY($){if(!B5($))try{$$(`xcrun simctl boot ${$}`,{encoding:"utf-8",stdio:"pipe"})}catch(Q){let Z=(Q.stderr??Q.message??"").toLowerCase();if(!Z.includes("booted")&&!Z.includes("current state"))throw Error(`Failed to boot device ${$}: ${Q.stderr||Q.message}`)}try{$$("open -ga Simulator",{encoding:"utf-8",stdio:"pipe",timeout:3000})}catch{}}function LY(){let $=WY();for(let Q of Object.values($))for(let Z of Q??[])if(Z.family==="IPv4"&&!Z.internal)return Z.address;return null}async function T5($){let Q=new Set(I0().map((Z)=>Z.port));for(let Z=$;Z<$+100;Z++){if(Q.has(Z))continue;if(await g6(Z))return Z}throw Error(`No available port found in range ${$}-${$+99}`)}async function UY($){RY($);try{$$(`xcrun simctl bootstatus ${$} -b`,{encoding:"utf-8",stdio:"pipe",timeout:60000})}catch(Q){if(!B5($))console.error(`Device ${$} failed to reach booted state: ${Q.stderr||Q.message}`),process.exit(1)}}function _Y($){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 NY($,Q=150000){let Z=Date.now();while(Date.now()-Z<Q){let J=r($);if(J)return J;await new Promise((Y)=>setTimeout(Y,200))}return null}async function j5($,Q,Z){n8("startHelper udid=%s port=%d detach=%s",$,Q,Z.detach);let J="127.0.0.1";_5(),c$($),m6(Q);let Y=M$(W$,`server-${$}.log`),X=eQ(Y,"w"),{command:G,args:V}=_Y([$,"--port",String(Q),"--host",J]),W=U5(G,V,{detached:Z.detach,stdio:["ignore",X,X]});if($6(X),Z.detach)W.unref();let z=await NY($);if(!z){if(W.pid)F5(W.pid);let K="";try{K=m$(Y,"utf-8").trim()}catch{}console.error(K?`Preview server failed:
|
|
150
150
|
${K}`:"Preview server failed to start"),process.exit(1)}return Z.detach?{pid:z.pid}:{pid:z.pid,child:W}}async function BY($,Q,Z){d8("follow devices=%o startPort=%d",$,Q);let J=$.length>0?$.map(o):(()=>{let z=Z$();if(z)return[z];let K=Z6();if(!K)console.error("No device specified and no available iOS simulator found."),process.exit(1);if(!Z)console.log(`No booted simulator — booting ${K.name}...`);return[K.udid]})(),Y=new Map,X=[],G=Q;for(let z of J){let K=r(z);if(K){if(!Z){let T=L5(z)??z;if(J.length>1)console.log(`
|
|
151
151
|
==> ${T} (${z}) <==`);console.log(` Already running on port ${K.port}`),console.log(` Stream: ${K.streamUrl}`),console.log(` WebSocket: ${K.wsUrl}`)}X.push(K);continue}G=await T5(G);let{child:R}=await j5(z,G,{detach:!1});if(R)Y.set(z,R);let H=r(z)??i$(z,G,"/","127.0.0.1");if(X.push(H),!Z){let T=L5(z)??z;if(J.length>1)console.log(`
|
|
152
152
|
==> ${T} (${z}) <==`);console.log(` Stream: ${H.streamUrl}`),console.log(` WebSocket: ${H.wsUrl}`),console.log(` Port: ${G}`)}G++}if(X.length===1){let z=X[0];console.log(JSON.stringify({url:z.url,streamUrl:z.streamUrl,wsUrl:z.wsUrl,port:z.port,device:z.device}))}else console.log(JSON.stringify({devices:X.map((z)=>({url:z.url,streamUrl:z.streamUrl,wsUrl:z.wsUrl,port:z.port,device:z.device}))}));if(Y.size===0)return;let V=!1,W=(z)=>{if(V)return;if(V=!0,!Z)console.log(`
|
|
@@ -202,5 +202,5 @@ Examples:
|
|
|
202
202
|
serve-sim --list Show all running streams
|
|
203
203
|
serve-sim --kill Stop all streams`).action(async($,Q)=>{if(Q.list!==void 0){jY(typeof Q.list==="string"?Q.list:void 0);return}if(Q.kill!==void 0){EY(typeof Q.kill==="string"?Q.kill:void 0);return}let Z=Q.port;if(Q.detach){let J=await FY($,Z??3100);TY(J)}else if(Q.preview===!1)await BY($,Z??3100,!!Q.quiet);else{let J=Q.panes!==void 0||Q.fit?{...Q.panes!==void 0?{panes:Q.panes}:{},...Q.fit?{fit:!0}:{}}:void 0;await pY(Z??3200,$,Z!==void 0,Q.host,Q.codec,J,Q.theme)}});var P$=["-d, --device <udid>","Target a specific simulator (udid or name)"];Y$.command("gesture").description("Send a touch gesture").argument("<json>",`Gesture JSON, e.g. '{"type":"begin","x":0.5,"y":0.5}'`).option(...P$).action(($,Q)=>DY($,Q.device));Y$.command("tap").description("Tap at normalized 0..1 coords").argument("<x>","X coord, normalized 0..1").argument("<y>","Y coord, normalized 0..1").option(...P$).action(($,Q,Z)=>CY($,Q,Z.device));Y$.command("button").description("Send a hardware button press").argument("[name]","Button name","home").option(...P$).action(($,Q)=>wY($,Q.device));Y$.command("type").description("Type text (US keyboard only)").argument("[text...]","Text to type").option(...P$).option("--stdin","Read text from stdin").option("--file <path>","Read text from a file").action(($,Q)=>PY($,{device:Q.device,stdin:Q.stdin,file:Q.file}));Y$.command("rotate").description("Set device orientation (portrait|portrait_upside_down|landscape_left|landscape_right)").argument("<orientation>").option(...P$).action(($,Q)=>IY($,Q.device));Y$.command("ca-debug").description("Toggle a CoreAnimation debug render flag (blended|copies|misaligned|offscreen|slow-animations)").argument("<option>").argument("<state>","on|off").option(...P$).action(($,Q,Z)=>SY($,Q,Z.device));Y$.command("memory-warning").description("Simulate a memory warning on the device").option(...P$).action(($)=>kY($.device));Y$.command("event-log").description("Show recent simulator events").option(...P$).option("-j, --json","Print JSON").option("-n, --limit <count>","Maximum number of events").action(($)=>OY($.device,{json:$.json,limit:$.limit}));Y$.command("camera").description("Inject a synthetic camera feed and launch an app (see `camera --help`)").allowUnknownOption(!0).helpOption(!1).argument("[args...]").action(($)=>mY($));Y$.command("permissions").description("Manage app permissions (see `permissions` with no args for usage)").allowUnknownOption(!0).helpOption(!1).argument("[args...]").action(($)=>s6($));Y$.command("ui").description("Get or set simulator-wide UI options (see `ui --help`)").allowUnknownOption(!0).helpOption(!1).argument("[args...]").action(($)=>Y9($));await Y$.parseAsync(process.argv);
|
|
204
204
|
|
|
205
|
-
//# debugId=
|
|
205
|
+
//# debugId=2199E398839F20F064756E2164756E21
|
|
206
206
|
//# sourceMappingURL=serve-sim.js.map
|