serve-sim 0.1.46 → 0.1.47-beta.118.1
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: ${k8().join(", ")}`),process.exit(1);let Y=J.device?o(J.device):Q$();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:RZ(Y,J.bundleId),location:UZ(Y,J.bundleId),notifications:FZ(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 k8())n6(Y,"reset",G,void 0,X);else n6(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)}l8();o8();function F7($,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,`${V1($)}${X?` (${X.trim()})`:""}`].filter(Boolean).join(" ")}function V1($){if($.kind==="tap"){let Q=i0($.details,"current")??i0($.details,"start");return Q?`Tap at ${a8(Q)}`:"Tap"}if($.kind==="drag"){let Q=i0($.details,"start"),Z=i0($.details,"current");if(Q&&Z)return`Drag from ${a8(Q)} to ${a8(Z)}`;return"Drag"}if($.kind==="key"){let Q=M1($.details,"key")??$.action??"key",Z=$.action==="down"?"down":$.action==="up"?"up":$.action;return Z?`Key ${Z} ${B7(Q)}`:`Key ${B7(Q)}`}if($.kind==="rotate"){let Q=$.action?T7($.action):"";return Q?`Rotate ${Q}`:"Rotate"}return R1($.msg??$.summary)}function i0($,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 M1($,Q){let Z=$?.[Q];return typeof Z==="string"&&Z.length>0?Z:null}function a8($){return`${N7($.x)}, ${N7($.y)}`}function N7($){if(!Number.isFinite($))return"?";return(Math.round((H1($,0,1)+Number.EPSILON)*100)/100).toFixed(2)}function H1($,Q,Z){return Math.min(Z,Math.max(Q,$))}function R1($){return $.replace(/\b[a-z]+(?:_[a-z]+)+\b/g,T7)}function T7($){return $.replace(/[-_]+/g," ")}function B7($){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 j7=["devices","tools","devtools"];function O7($){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)=>!j7.includes(J));if(Z.length>0)throw Error(`Unknown pane${Z.length===1?"":"s"}: ${Z.join(", ")}. Expected: ${j7.join(", ")}.`);return[...new Set(Q)]}function E7($){let Q=$.trim().toLowerCase();if(Q==="light"||Q==="dark")return Q;throw Error("Expected simulator theme: light or dark.")}s8();var C$=u0(import.meta.url);function LY(){return"0.1.
|
|
149
|
+
Permissions: ${k8().join(", ")}`),process.exit(1);let Y=J.device?o(J.device):Q$();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:RZ(Y,J.bundleId),location:UZ(Y,J.bundleId),notifications:FZ(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 k8())n6(Y,"reset",G,void 0,X);else n6(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)}l8();o8();function F7($,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,`${V1($)}${X?` (${X.trim()})`:""}`].filter(Boolean).join(" ")}function V1($){if($.kind==="tap"){let Q=i0($.details,"current")??i0($.details,"start");return Q?`Tap at ${a8(Q)}`:"Tap"}if($.kind==="drag"){let Q=i0($.details,"start"),Z=i0($.details,"current");if(Q&&Z)return`Drag from ${a8(Q)} to ${a8(Z)}`;return"Drag"}if($.kind==="key"){let Q=M1($.details,"key")??$.action??"key",Z=$.action==="down"?"down":$.action==="up"?"up":$.action;return Z?`Key ${Z} ${B7(Q)}`:`Key ${B7(Q)}`}if($.kind==="rotate"){let Q=$.action?T7($.action):"";return Q?`Rotate ${Q}`:"Rotate"}return R1($.msg??$.summary)}function i0($,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 M1($,Q){let Z=$?.[Q];return typeof Z==="string"&&Z.length>0?Z:null}function a8($){return`${N7($.x)}, ${N7($.y)}`}function N7($){if(!Number.isFinite($))return"?";return(Math.round((H1($,0,1)+Number.EPSILON)*100)/100).toFixed(2)}function H1($,Q,Z){return Math.min(Z,Math.max(Q,$))}function R1($){return $.replace(/\b[a-z]+(?:_[a-z]+)+\b/g,T7)}function T7($){return $.replace(/[-_]+/g," ")}function B7($){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 j7=["devices","tools","devtools"];function O7($){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)=>!j7.includes(J));if(Z.length>0)throw Error(`Unknown pane${Z.length===1?"":"s"}: ${Z.join(", ")}. Expected: ${j7.join(", ")}.`);return[...new Set(Q)]}function E7($){let Q=$.trim().toLowerCase();if(Q==="light"||Q==="dark")return Q;throw Error("Expected simulator theme: light or dark.")}s8();var C$=u0(import.meta.url);function LY(){return"0.1.47-beta.118.1"}function T4(){if(!K$(W$))$6(W$,{recursive:!0})}function r($){if($)return sQ(V0($));for(let Q of b0()){let Z=sQ(Q);if(Z)return Z}return null}var _8={at:0,booted:null};function UY(){let $=Date.now();if(_8.booted&&$-_8.at<1000)return _8.booted;try{let Q=J$("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 _8={at:$,booted:J},J}catch{return null}}function sQ($){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=UY();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 x0(){let $=[];for(let Q of b0()){let Z=sQ(Q);if(Z)$.push(Z)}return $}function _Y($){T4(),J6(V0($.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$(V0($))}catch{}}else{V$("clearState (all)");for(let Q of b0())try{g$(Q)}catch{}}}function Y6(){try{let $=J$("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 B4($){return j4().get($)??null}function j4(){let $=new Map;try{let Q=J$("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 O4($){try{let Q=J$("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 eQ($){try{return process.kill($,0),!0}catch{return!1}}function E4($){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 NY($){if(!O4($))try{J$(`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{J$("open -ga Simulator",{encoding:"utf-8",stdio:"pipe",timeout:3000})}catch{}}function BY(){let $=RY();for(let Q of Object.values($))for(let Z of Q??[])if(Z.family==="IPv4"&&!Z.internal)return Z.address;return null}async function q4($){let Q=new Set(x0().map((Z)=>Z.port));for(let Z=$;Z<$+100;Z++){if(Q.has(Z))continue;if(await m6(Z))return Z}throw Error(`No available port found in range ${$}-${$+99}`)}async function FY($){NY($);try{VY("xcrun",s0($),{encoding:"utf-8",stdio:"pipe",timeout:60000})}catch(Q){if(!O4($))console.error(`Device ${$} failed to reach booted state: ${Q.stderr||Q.message}`),process.exit(1)}}function TY($){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 jY($,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 A4($,Q,Z){i8("startHelper udid=%s port=%d detach=%s",$,Q,Z.detach);let J="127.0.0.1";T4(),c$($),p6(Q);let Y=M$(W$,`server-${$}.log`),X=Q6(Y,"w"),{command:G,args:V}=TY([$,"--port",String(Q),"--host",J]),W=F4(G,V,{detached:Z.detach,stdio:["ignore",X,X]});if(Z6(X),Z.detach)W.unref();let z=await jY($);if(!z){if(W.pid)E4(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 OY($,Q,Z){n8("follow devices=%o startPort=%d",$,Q);let J=$.length>0?$.map(o):(()=>{let z=Q$();if(z)return[z];let K=Y6();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=B4(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 q4(G);let{child:R}=await A4(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=B4(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){AY(typeof Q.list==="string"?Q.list:void 0);return}if(Q.kill!==void 0){DY(typeof Q.kill==="string"?Q.kill:void 0);return}let Z=Q.port;if(Q.detach){let J=await EY($,Z??3100);qY(J)}else if(Q.preview===!1)await OY($,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 oY(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)=>xY($,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)=>wY($,Q,Z.device));Y$.command("button").description("Send a hardware button press").argument("[name]","Button name","home").option(...P$).action(($,Q)=>fY($,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)=>kY($,{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)=>SY($,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)=>bY($,Q,Z.device));Y$.command("memory-warning").description("Simulate a memory warning on the device").option(...P$).action(($)=>vY($.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(($)=>CY($.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(($)=>nY($));Y$.command("permissions").description("Manage app permissions (see `permissions` with no args for usage)").allowUnknownOption(!0).helpOption(!1).argument("[args...]").action(($)=>e6($));Y$.command("ui").description("Get or set simulator-wide UI options (see `ui --help`)").allowUnknownOption(!0).helpOption(!1).argument("[args...]").action(($)=>G7($));await Y$.parseAsync(process.argv);
|
|
204
204
|
|
|
205
|
-
//# debugId=
|
|
205
|
+
//# debugId=A9C46951B3C900A664756E2164756E21
|
|
206
206
|
//# sourceMappingURL=serve-sim.js.map
|