@limrun/ui 0.9.0-rc.8 → 0.9.0-rc.9
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/device-install/index.cjs +1 -1
- package/dist/device-install/index.js +2 -2
- package/dist/device-install/react.cjs +1 -1
- package/dist/device-install/react.js +1 -1
- package/dist/{device-install-dialog-DgWsZF6o.mjs → device-install-dialog-CqxDEH85.mjs} +1 -1
- package/dist/{device-install-dialog-DGn2ZdBB.js → device-install-dialog-jvqQ-fuo.js} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +3 -3
- package/dist/{use-device-install-ByUSmeYz.js → use-device-install-CAPli9MR.js} +1 -1
- package/dist/{use-device-install-Y42p84we.mjs → use-device-install-H8dqqvbR.mjs} +1 -1
- package/package.json +1 -1
- package/src/core/device-install/operations/limbuild-client.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as G, jsxs as L, Fragment as ke } from "react/jsx-runtime";
|
|
2
2
|
import { memo as ge, useState as N, useEffect as IA, useMemo as FA, useCallback as tt, forwardRef as it, useRef as l, useImperativeHandle as nt } from "react";
|
|
3
|
-
import { c as CA } from "./device-install-dialog-
|
|
4
|
-
import { D as ni, D as ri } from "./device-install-dialog-
|
|
3
|
+
import { c as CA } from "./device-install-dialog-CqxDEH85.mjs";
|
|
4
|
+
import { D as ni, D as ri } from "./device-install-dialog-CqxDEH85.mjs";
|
|
5
5
|
import { createPortal as rt } from "react-dom";
|
|
6
|
-
import { u as si } from "./use-device-install-
|
|
6
|
+
import { u as si } from "./use-device-install-H8dqqvbR.mjs";
|
|
7
7
|
import './index.css';const _A = {
|
|
8
8
|
INJECT_KEYCODE: 0,
|
|
9
9
|
INJECT_TOUCH_EVENT: 2,
|
|
@@ -27,5 +27,5 @@ ${i.join(`
|
|
|
27
27
|
${r.join(`
|
|
28
28
|
`)}
|
|
29
29
|
-----END ${t}-----
|
|
30
|
-
`}function tr(t){let e="";for(const r of t)e+=String.fromCharCode(r);return btoa(e)}function uo(t){return btoa(t)}function lo(t){return atob(t)}function po(t){const e=new Uint8Array(t.byteLength);return e.set(t),e.buffer}const vi="limbuild-device-pairing",gi=1,Ut="pairRecords",ba="limbuild-device-signing",Ta=1,mt="signingAssets";function Tt(t){return(t??"").replace(/-/g,"").replace(/[^a-fA-F0-9]/g,"")}function At(t){return(t??"").trim()}async function yi(t){const e=Tt(t);if(!e)return;const r=await $t(vi,gi,Ut,"udid");return Wt(r.transaction(Ut,"readonly").objectStore(Ut).get(e))}async function mi(t,e={}){const r=Tt(t.udid);if(!r)throw new Error("Cannot store pair record without a UDID.");const i={...t,udid:r,productName:e.productName,updatedAt:new Date().toISOString()},p=await $t(vi,gi,Ut,"udid");return await Wt(p.transaction(Ut,"readwrite").objectStore(Ut).put(i)),i}async function Ci({deviceUDID:t,bundleID:e}){const r=At(e);if(!r)return;const i=Tt(t),p=await In(la("bundle",r));if(p)return p;if(i){const c=await In(la(i,r));if(c)return c}return(await xi(r))[0]}async function rr(){return(await wa()).sort((e,r)=>new Date(r.updatedAt).getTime()-new Date(e.updatedAt).getTime())[0]}async function Ei(t){return(await wa()).filter(r=>!r.certificateID||!r.certificateP12Base64||!r.certificatePassword?!1:!t||!r.teamID||r.teamID===t).sort((r,i)=>new Date(i.updatedAt).getTime()-new Date(r.updatedAt).getTime())[0]}async function Aa(t){const e=At(t.bundleID);if(!e)throw new Error("Cannot store signing assets without a bundle ID.");const r=Tt(t.deviceUDID),i=la("bundle",e),p={...t,id:i,deviceUDID:r||void 0,bundleID:e,updatedAt:new Date().toISOString()},v=await $t(ba,Ta,mt,"id");return await Wt(v.transaction(mt,"readwrite").objectStore(mt).put(p)),p}async function xi(t){const e=At(t);return e?(await wa()).filter(i=>i.bundleID===e):[]}function Ht(t,e){const r=Tt(e);return!!r&&t.provisionedDevices.some(i=>Tt(i)===r)}function Ia(t,e){const r=At(e),i=At(t.bundleID);if(!r||!i)return!1;if(i===r||i==="*")return!0;if(!i.endsWith(".*"))return!1;const p=i.slice(0,-1);return r.startsWith(p)}async function Si(t){return Ba(new Uint8Array(await t.arrayBuffer()))}function bi(t){const e=atob(t),r=new Uint8Array(e.length);for(let i=0;i<e.length;i+=1)r[i]=e.charCodeAt(i);return Ba(r)}function Ba(t){const e=new TextDecoder("latin1").decode(t),r=e.indexOf("<?xml"),i=e.indexOf("</plist>");if(r<0||i<r)throw new Error("Provisioning profile plist not found.");const p=e.slice(r,i+8),v=new DOMParser().parseFromString(p,"application/xml");if(v.querySelector("parsererror"))throw new Error("Provisioning profile plist could not be parsed.");const c=v.querySelector("plist > dict");if(!c)throw new Error("Provisioning profile plist dictionary not found.");const a=Na(c);if(!wn(a))throw new Error("Provisioning profile plist has an unexpected shape.");const g=wn(a.Entitlements)?a.Entitlements:{},l=Ot(g["application-identifier"]),x=ho(l);return{name:Ot(a.Name),uuid:Ot(a.UUID),teamID:Ot(g["com.apple.developer.team-identifier"])??Bn(a.TeamIdentifier)[0],applicationIdentifier:l,bundleID:x,provisionedDevices:Bn(a.ProvisionedDevices),expirationDate:Ot(a.ExpirationDate)}}async function In(t){if(!t)return;const e=await $t(ba,Ta,mt,"id");return Wt(e.transaction(mt,"readonly").objectStore(mt).get(t))}async function wa(){const t=await $t(ba,Ta,mt,"id");return Wt(t.transaction(mt,"readonly").objectStore(mt).getAll())}function la(t,e){return`${t}:${e}`}function ho(t){if(!t)return;const e=t.indexOf(".");return e>=0?t.slice(e+1):void 0}function Na(t){switch(t.tagName){case"dict":return vo(t);case"array":return Array.from(t.children).map(Na);case"string":case"date":return t.textContent??"";default:return t.textContent??""}}function vo(t){const e={},r=Array.from(t.children);for(let i=0;i<r.length;i+=2){const p=r[i],v=r[i+1];!p||p.tagName!=="key"||!v||(e[p.textContent??""]=Na(v))}return e}function Ot(t){return typeof t=="string"&&t?t:void 0}function Bn(t){return Array.isArray(t)?t.filter(e=>typeof e=="string"):[]}function wn(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function $t(t,e,r,i){return new Promise((p,v)=>{const c=indexedDB.open(t,e);c.onupgradeneeded=()=>{const a=c.result;a.objectStoreNames.contains(r)||a.createObjectStore(r,{keyPath:i})},c.onsuccess=()=>p(c.result),c.onerror=()=>v(c.error??new Error("Open IndexedDB failed"))})}function Wt(t){return new Promise((e,r)=>{t.onsuccess=()=>e(t.result),t.onerror=()=>r(t.error??new Error("IndexedDB request failed"))})}function Ti(){return{method:"POST",path:"/account/listTeams.action",payload:{}}}function Ra({bundleID:t,teamID:e=""}){return pr("/account/ios/identifiers/listAppIds.action",e,{sort:"name=asc"})}function Ai({deviceUDID:t,teamID:e=""}){return pr("/account/ios/device/listDevices.action",e,{sort:"name=asc",includeRemovedDevices:!1})}function Ii(t=""){return pr("/account/ios/certificate/listCertRequests.action",t,{sort:"name=asc",types:"83Q87W3TGH,5QPB9NHCEI"})}function Bi({bundleID:t,teamID:e=""}){return pr("/account/ios/profile/listProvisioningProfiles.action",e,{search:t,sort:"name=asc"})}function wi({deviceUDID:t,teamID:e="",name:r="Limrun iPhone"}){return{method:"POST",path:"/account/ios/device/addDevices.action",payload:{teamId:e,deviceNames:r,deviceNumbers:Tt(t),deviceClasses:"iphone",register:"single"}}}function Ni({bundleID:t,teamID:e="",name:r}){return{method:"POST",path:"/account/ios/identifiers/addAppId.action",payload:{teamId:e,name:r??t,identifier:t,type:"explicit"}}}function Ri({csrPEM:t,teamID:e=""}){return{method:"POST",path:"/account/ios/certificate/submitCertificateRequest.action",payload:{teamId:e,type:"83Q87W3TGH",csrContent:t}}}function _i(t,e=""){return{method:"GET",path:"/account/ios/certificate/downloadCertificateContent.action",payload:{teamId:e,certificateId:t,type:"83Q87W3TGH"}}}function Di({bundleID:t,teamID:e="",appIDID:r,certificateID:i,deviceIDs:p,name:v}){return{method:"POST",path:"/account/ios/profile/createProvisioningProfile.action",payload:{teamId:e,provisioningProfileName:v??`Limrun ${t}`,certificateIds:[i],appIdId:r,deviceIds:p,distributionType:"limited",subPlatform:"ios"}}}function Li(t,e=""){return{method:"GET",path:"/account/ios/profile/downloadProfileContent",payload:{teamId:e,provisioningProfileId:t}}}async function da({bundleID:t,deviceUDID:e,teamID:r}){const i=await Ci({bundleID:t,deviceUDID:e});if(!(!i||!Ui(i,{bundleID:t,deviceUDID:e,teamID:r})))return i}async function Pi(t){return Aa({...t,certificateFileName:t.certificateID?`${t.certificateID}.p12`:"apple-development.p12",profileFileName:t.profile.uuid?`${t.profile.uuid}.mobileprovision`:"apple-development.mobileprovision"})}function Ui(t,{bundleID:e,deviceUDID:r,teamID:i}){return!Ia(t.profile,e)||i&&t.teamID&&t.teamID!==i||r&&!Ht(t.profile,r)||t.profile.expirationDate&&new Date(t.profile.expirationDate).getTime()<=Date.now()?!1:At(t.bundleID)===At(e)}function go(t){const e=t;return e?.teams?.[0]??e?.provider??e?.availableProviders?.[0]}function yo(t){const e=t,r=[...e?.teams??[],...e?.provider?[e.provider]:[],...e?.availableProviders??[]],i=new Set;for(const p of r)for(const v of[p.teamId,p.providerId,p.publicProviderId])v!==void 0&&v!==""&&i.add(String(v));return[...i]}function pr(t,e,r={}){const i={pageNumber:1,pageSize:200,...r};return e&&(i.teamId=e),{method:"POST",path:t,payload:i}}async function ki(t,e){const r=new URL(`${t}/info`);e&&r.searchParams.set("token",e);const i=await fetch(r.toString(),{headers:e?{Authorization:`Bearer ${e}`}:void 0});if(!i.ok){const p=await i.text();throw new Error(`Info request failed: HTTP ${i.status} ${p}`)}return await i.json()}async function Vi({limbuildApiUrl:t,token:e,certificateP12Base64:r,certificatePassword:i,provisioningProfileBase64:p}){const v=new URL(`${t}/exec`);e&&v.searchParams.set("token",e);const c=await fetch(v.toString(),{method:"POST",headers:{"Content-Type":"application/json",...e?{Authorization:`Bearer ${e}`}:{}},body:JSON.stringify({command:"xcodebuild",xcodebuild:{sdk:"iphoneos"},signing:{certificateP12Base64:r,certificatePassword:i,provisioningProfileBase64:p}})});if(!c.ok){const a=await c.text();throw new Error(`Build request failed: HTTP ${c.status} ${a}`)}return await c.json()}function Oi({limbuildApiUrl:t,execId:e,token:r,onLine:i,onStatus:p,onError:v}){const c=new URL(`${t}/exec/${e}/events`);r&&c.searchParams.set("token",r);const a=new EventSource(c.toString());return p("running"),a.addEventListener("command",g=>i({type:"command",data:g.data})),a.addEventListener("stdout",g=>i({type:"stdout",data:g.data})),a.addEventListener("stderr",g=>i({type:"stderr",data:g.data})),a.addEventListener("exitCode",g=>{const l=parseInt(g.data,10);p(l===0?"succeeded":l<0?"cancelled":"failed"),a.close()}),a.onerror=()=>{a.close(),v?.(new Error("Build log stream closed before completion."))},()=>a.close()}const _a=1,_t=16,Je={DeviceHello:1,OpenStream:2,OpenResult:3,StreamData:4,StreamClose:5,InstallProgress:6,Error:7,Ping:8,Pong:9,StartPairing:10,StartInstall:11,PairRecordReady:12};function Fi(t){const e=new Uint8Array(_t+t.payload.byteLength),r=new DataView(e.buffer);return r.setUint8(0,_a),r.setUint8(1,t.type),r.setUint8(2,0),r.setUint8(3,0),r.setUint32(4,t.requestId),r.setUint32(8,t.streamId),r.setUint32(12,t.payload.byteLength),e.set(t.payload,_t),e}function Ki(t){if(t.byteLength<_t)throw new Error(`Relay frame too short: ${t.byteLength}`);const e=new DataView(t.buffer,t.byteOffset,t.byteLength),r=e.getUint8(0);if(r!==_a)throw new Error(`Unsupported relay protocol version ${r}`);const i=e.getUint32(12);if(t.byteLength!==_t+i)throw new Error(`Relay frame length mismatch: got ${t.byteLength}, expected ${_t+i}`);return{type:e.getUint8(1),requestId:e.getUint32(4),streamId:e.getUint32(8),payload:t.slice(_t)}}function Nt(t){return new TextEncoder().encode(JSON.stringify(t))}function ar(t){return JSON.parse(new TextDecoder().decode(t))}async function Mi(){if(!navigator.usb)throw new Error("WebUSB is not available in this browser.");return navigator.usb.requestDevice({filters:[{vendorId:1452}]})}function qi(t){const e=[],r=t.configuration?.configurationValue,i=t.configurations.find(p=>p.configurationValue===r);i&&e.push(...Nn(i));for(const p of t.configurations)p.configurationValue!==r&&e.push(...Nn(p));return e}function Nn(t){const e=[];for(const r of t.interfaces)for(const i of r.alternates)i.interfaceClass===255&&i.interfaceSubclass===254&&i.interfaceProtocol===2&&e.push({configurationValue:t.configurationValue,interfaceNumber:r.interfaceNumber,alternateSetting:i.alternateSetting,endpoints:i.endpoints});return e}async function Hi(t,e){t.opened||await t.open(),(!t.configuration||t.configuration.configurationValue!==e.configurationValue)&&await t.selectConfiguration(e.configurationValue),await t.claimInterface(e.interfaceNumber),e.alternateSetting!==0&&await t.selectAlternateInterface(e.interfaceNumber,e.alternateSetting)}function Gi(t){const e=t.endpoints.find(i=>i.direction==="out"&&i.type==="bulk"),r=t.endpoints.find(i=>i.direction==="in"&&i.type==="bulk");if(!e||!r)throw new Error("Could not find usbmux bulk endpoints.");return{outEndpoint:e,inEndpoint:r}}async function Da(t,e,r){const i=await t.transferOut(e.endpointNumber,r);if(i.status!=="ok")throw new Error(`USB transferOut failed: ${i.status}`);r.byteLength%e.packetSize===0&&await t.transferOut(e.endpointNumber,new Uint8Array)}async function zi(t,e,r=16384){const i=await t.transferIn(e.endpointNumber,r);if(i.status!=="ok"||!i.data)throw new Error(`USB transferIn failed: ${i.status}`);return new Uint8Array(i.data.buffer,i.data.byteOffset,i.data.byteLength)}const Qi=0,mo=2,$i=6,Co=4277009102,pa=2,Eo=4,Mt=16,xo=49152;async function Wi(t,e){const{inEndpoint:r,outEndpoint:i}=Gi(e),p=new Uint8Array(12),v=new DataView(p.buffer);v.setUint32(0,2),v.setUint32(4,0),v.setUint32(8,0),await Da(t,i,es(Qi,p));const c=await Ji(t,r,1),a=new DataView(c.payload.buffer,c.payload.byteOffset).getUint32(0),g={device:t,candidate:e,inEndpoint:r,outEndpoint:i,muxVersion:a,txSeq:0,rxSeq:65535,nextSport:xo,streams:new Map,writeChain:Promise.resolve(),closed:!1};return a>=2&&await Zi(g,mo,new Uint8Array([7])),So(g),g}async function Yi(t,e){if(t.closed)throw new Error("usbmux session is closed.");let r,i;const p={session:t,sport:t.nextSport++,dport:e,seq:0,ack:0,queue:[],waiters:[],opened:new Promise((v,c)=>{r=v,i=c}),resolveOpened:r,rejectOpened:i};return t.streams.set(ha(e,p.sport),p),await sr(p,pa,new Uint8Array),await p.opened,p}async function ji(t,e){if(t.session.closed)throw new Error("usbmux session is closed.");await sr(t,Mt,e),t.seq+=e.byteLength}async function Xi(t){if(t.queue.length>0)return t.queue.shift();if(t.error)throw t.error;return new Promise(e=>{t.waiters.push(e)})}function La(t){t.closed=!0;for(const e of t.streams.values())for(e.error=new Error("usbmux session closed"),e.rejectOpened(e.error);e.waiters.length>0;)e.waiters.shift()(new Uint8Array);t.streams.clear()}async function sr(t,e,r){const i=new Uint8Array(20+r.byteLength),p=new DataView(i.buffer);p.setUint16(0,t.sport),p.setUint16(2,t.dport),p.setUint32(4,t.seq),p.setUint32(8,t.ack),p.setUint8(12,80),p.setUint8(13,e),p.setUint16(14,512),i.set(r,20),await Zi(t.session,$i,i)}async function Zi(t,e,r){if(t.closed)throw new Error("usbmux session is closed.");return t.writeChain=t.writeChain.then(async()=>{if(t.closed)return;const i=t.muxVersion>=2?bo(e,r,t.txSeq++,t.rxSeq):es(e,r);await Da(t.device,t.outEndpoint,i)}),t.writeChain}async function So(t){try{for(;;){if(t.closed)return;const e=await Ji(t.device,t.inEndpoint,t.muxVersion);if(t.closed)return;if(e.rxSeq!==void 0&&(t.rxSeq=e.rxSeq),e.protocol!==$i)continue;const r=Ao(e.payload),i=t.streams.get(ha(r.sport,r.dport));if(i){if(r.flags&Eo){for(i.error=new Error(`Device reset stream ${i.dport}`),i.rejectOpened(i.error);i.waiters.length>0;)i.waiters.shift()(new Uint8Array);t.streams.delete(ha(i.dport,i.sport));continue}if((r.flags&(pa|Mt))===(pa|Mt)){i.seq+=1,i.ack=r.seq+1,await sr(i,Mt,new Uint8Array),i.resolveOpened();continue}r.payload.byteLength!==0&&(i.ack=r.seq+r.payload.byteLength,await sr(i,Mt,new Uint8Array),i.waiters.length>0?i.waiters.shift()(r.payload):i.queue.push(r.payload))}}}catch{t.closed||La(t)}}async function Ji(t,e,r){for(;;){const i=await zi(t,e),p=To(i,r);if(!(r===1&&p.protocol!==Qi))return p}}function es(t,e){const r=new Uint8Array(8+e.byteLength),i=new DataView(r.buffer);return i.setUint32(0,t),i.setUint32(4,r.byteLength),r.set(e,8),r}function bo(t,e,r,i){const p=new Uint8Array(16+e.byteLength),v=new DataView(p.buffer);return v.setUint32(0,t),v.setUint32(4,p.byteLength),v.setUint32(8,Co),v.setUint16(12,r),v.setUint16(14,i),p.set(e,16),p}function To(t,e){const r=new DataView(t.buffer,t.byteOffset,t.byteLength),i=r.getUint32(0),p=r.getUint32(4),v=e>=2?16:8;return{protocol:i,length:p,rxSeq:e>=2?r.getUint16(14):void 0,payload:t.slice(v,p)}}function Ao(t){const e=new DataView(t.buffer,t.byteOffset,t.byteLength),r=(e.getUint8(12)>>4)*4;return{sport:e.getUint16(0),dport:e.getUint16(2),seq:e.getUint32(4),ack:e.getUint32(8),flags:e.getUint8(13),payload:t.slice(r)}}function ha(t,e){return`${t}:${e}`}class ts{constructor(e,r,i,p){this.webSocketUrl=e,this.session=r,this.deviceHello=i,this.log=p}socket;streams=new Map;frameQueue=Promise.resolve();closed=!1;pairRecordWaiter;async connect(){const e=new WebSocket(this.webSocketUrl);e.binaryType="arraybuffer",this.socket=e,e.onclose=()=>{this.closed=!0,this.log("Relay socket closed"),this.pairRecordWaiter&&(this.pairRecordWaiter.reject(new Error("Relay socket closed")),this.pairRecordWaiter=void 0)},await new Promise((r,i)=>{e.onopen=()=>r(),e.onerror=()=>i(new Error("WebSocket connection failed"))}),e.onmessage=r=>{const i=r.data instanceof ArrayBuffer?new Uint8Array(r.data):new Uint8Array;this.enqueueFrame(i)},await this.send({type:Je.DeviceHello,requestId:0,streamId:0,payload:Nt(this.deviceHello)}),this.log("Connected WebSocket relay")}async startPairing(){const e=new Promise((r,i)=>{this.pairRecordWaiter={resolve:r,reject:i}});return await this.send({type:Je.StartPairing,requestId:0,streamId:0,payload:Nt({})}),this.log("Pairing requested"),e}async startInstall(e){await this.send({type:Je.StartInstall,requestId:0,streamId:0,payload:Nt(e)}),this.log("Installation requested")}close(){this.closed=!0,this.socket?.close()}enqueueFrame(e){this.frameQueue=this.frameQueue.then(()=>this.handleFrame(Ki(e))).catch(r=>{this.log("Relay frame handling failed",r instanceof Error?r.message:String(r))})}async handleFrame(e){switch(e.type){case Je.OpenStream:await this.handleOpenStream(e.requestId,e.streamId,ar(e.payload).port);break;case Je.StreamData:{const r=this.streams.get(e.streamId);if(!r)throw new Error(`Unknown stream ${e.streamId}`);await ji(r,e.payload);break}case Je.StreamClose:this.streams.delete(e.streamId);break;case Je.InstallProgress:this.log(Bo(ar(e.payload).message));break;case Je.Error:this.handleError(e.payload);break;case Je.PairRecordReady:this.handlePairRecordReady(ar(e.payload));break;case Je.Ping:await this.send({type:Je.Pong,requestId:e.requestId,streamId:0,payload:new Uint8Array});break}}handleError(e){const r=Io(e);this.log("Server error",r),this.pairRecordWaiter&&(this.pairRecordWaiter.reject(new Error(r)),this.pairRecordWaiter=void 0)}handlePairRecordReady(e){this.log("Pair record received",e.udid),this.pairRecordWaiter?.resolve(e),this.pairRecordWaiter=void 0}async handleOpenStream(e,r,i){try{const p=await Yi(this.session,i);this.streams.set(r,p),await this.send({type:Je.OpenResult,requestId:e,streamId:r,payload:Nt({ok:!0})}),this.log(`Opened device stream ${r} to port ${i}`),this.pumpDeviceToServer(r,p)}catch(p){this.log(`Open device stream ${r} failed`,p instanceof Error?p.message:String(p)),await this.send({type:Je.OpenResult,requestId:e,streamId:r,payload:Nt({ok:!1,error:p instanceof Error?p.message:String(p)})})}}async pumpDeviceToServer(e,r){try{for(;;){const i=await Xi(r);if(this.closed)return;await this.send({type:Je.StreamData,requestId:0,streamId:e,payload:i})}}catch(i){this.log(`Device stream ${e} closed`,i instanceof Error?i.message:String(i)),await this.send({type:Je.StreamClose,requestId:0,streamId:e,payload:Nt({reason:i instanceof Error?i.message:String(i)})})}}async send(e){if(!this.closed){if(!this.socket||this.socket.readyState!==WebSocket.OPEN){this.closed=!0;return}this.socket.send(Fi(e))}}}function Io(t){const e=new TextDecoder().decode(t);try{const r=JSON.parse(e);return Rn(r.error??e)}catch{return Rn(e)}}function Rn(t){return t.replace(/libimobiledevice/g,"").trim()}function Bo(t){const e="install status: ";if(!t.startsWith(e))return t;const r=t.slice(e.length),p=new DOMParser().parseFromString(r,"application/xml").querySelector("plist > dict");if(!p)return t;const v=wo(p),c=v.Status??"Unknown";return`Install progress: ${v.PercentComplete?`${v.PercentComplete}% `:""}${c}`}function wo(t){const e={},r=Array.from(t.children);for(let i=0;i<r.length;i+=2){const p=r[i],v=r[i+1];!p||p.tagName!=="key"||!v||(e[p.textContent??""]=v.textContent??"")}return e}async function rs({log:t}){t("Selecting USB device");const e=await Mi(),r=Ro(e);return t("Selected USB device",`${e.manufacturerName??""} ${e.productName??""} ${e.serialNumber??""}`.trim()),r}async function as({limbuildApiUrl:t,token:e,log:r,target:i}){const p=Pa(t,e);let v;try{v=await is(p,i,r);const c=await v.startPairing();return{relay:v,pairRecord:c,target:i}}catch(c){throw v?.close(),c}}async function ns({limbuildApiUrl:t,token:e,log:r,target:i,pairRecord:p}){const v=Pa(t,e);let c;try{return c=await is(v,i,r),await c.startInstall(p),c}catch(a){throw c?.close(),a}}async function Rt(t,e){if(t){if(t.session&&(La(t.session),t.session=void 0),t.claimedInterfaceNumber!==void 0)try{await t.device.releaseInterface(t.claimedInterfaceNumber),e?.("Released usbmux interface")}catch(r){e?.("USB interface release failed",va(r))}finally{t.claimedInterfaceNumber=void 0}if(t.device.opened)try{await t.device.close(),e?.("Closed USB device")}catch(r){e?.("USB device close failed",va(r))}}}async function is(t,e,r){await No(e,r);const i=new ts(t,e.session,e.hello,r);return await i.connect(),i}async function No(t,e){if(!t.session)try{t.candidate=await _o(t,e),t.session=await Wi(t.device,t.candidate),e("Created usbmux session")}catch(r){throw await Rt(t,e),r}}function Ro(t){return{device:t,candidate:Do(t),hello:{serialNumber:t.serialNumber,productName:t.productName,manufacturerName:t.manufacturerName,productId:t.productId,vendorId:t.vendorId}}}async function _o(t,e){const r=ss(t.device);if(r.length===0)throw new Error("No Apple usbmux interface found.");let i;for(const p of r)for(const v of[1,2])try{return t.device.opened||await t.device.open(),e("Claiming usbmux interface",`configuration ${p.configurationValue}, interface ${p.interfaceNumber}, alternate ${p.alternateSetting}, attempt ${v}`),await Hi(t.device,p),t.claimedInterfaceNumber=p.interfaceNumber,e("Claimed usbmux interface",`configuration ${p.configurationValue}, interface ${p.interfaceNumber}`),p}catch(c){i=c,e("USB interface claim failed",`configuration ${p.configurationValue}, interface ${p.interfaceNumber}: ${va(c)}`),await Lo(t),await Po(250)}throw i instanceof Error?i:new Error("Unable to claim any Apple usbmux interface.")}function Do(t){const e=ss(t)[0];if(!e)throw new Error("No Apple usbmux interface found.");return e}function ss(t){const e=qi(t),r=t.configuration?.configurationValue;return[...e.filter(i=>i.configurationValue===r),...e.filter(i=>i.configurationValue!==r)]}function Pa(t,e){const r=new URL(t);return r.protocol=r.protocol==="https:"?"wss:":"ws:",r.pathname=`${r.pathname.replace(/\/$/,"")}/device/ws`,e&&r.searchParams.set("token",e),r.toString()}function va(t){return t instanceof Error?t.message:String(t)}async function Lo(t){if(t.claimedInterfaceNumber!==void 0){try{await t.device.releaseInterface(t.claimedInterfaceNumber)}catch{}t.claimedInterfaceNumber=void 0}if(t.device.opened)try{await t.device.close()}catch{}}function Po(t){return new Promise(e=>setTimeout(e,t))}const Uo={signing:"idle",connect:"idle",build:"idle",install:"idle"};function ko({apiUrl:t,token:e}){const[r,i]=de.useState("signing"),[p,v]=de.useState(Uo),[c,a]=de.useState(),[g,l]=de.useState(),[x,L]=de.useState(),[b,u]=de.useState(["Ready. Prepare signing assets, build, connect and pair the iPhone, then install."]),[m,E]=de.useState([]),[C,o]=de.useState("idle"),[h,y]=de.useState("idle"),[I,R]=de.useState([]),[d,s]=de.useState([]),[n,B]=de.useState([]),[P,O]=de.useState([]),[U,F]=de.useState(),[q,M]=de.useState(),[H,Q]=de.useState(""),[j,ee]=de.useState(),[oe,ce]=de.useState(!1),[he,pe]=de.useState(),[ve,W]=de.useState(),[X,Re]=de.useState(!1),[ye,S]=de.useState({}),D=de.useRef(void 0),_=de.useRef(void 0),N=de.useRef(void 0),f=de.useRef(void 0),T=de.useCallback((te,re)=>{const ie=re?`${te}
|
|
30
|
+
`}function tr(t){let e="";for(const r of t)e+=String.fromCharCode(r);return btoa(e)}function uo(t){return btoa(t)}function lo(t){return atob(t)}function po(t){const e=new Uint8Array(t.byteLength);return e.set(t),e.buffer}const vi="limbuild-device-pairing",gi=1,Ut="pairRecords",ba="limbuild-device-signing",Ta=1,mt="signingAssets";function Tt(t){return(t??"").replace(/-/g,"").replace(/[^a-fA-F0-9]/g,"")}function At(t){return(t??"").trim()}async function yi(t){const e=Tt(t);if(!e)return;const r=await $t(vi,gi,Ut,"udid");return Wt(r.transaction(Ut,"readonly").objectStore(Ut).get(e))}async function mi(t,e={}){const r=Tt(t.udid);if(!r)throw new Error("Cannot store pair record without a UDID.");const i={...t,udid:r,productName:e.productName,updatedAt:new Date().toISOString()},p=await $t(vi,gi,Ut,"udid");return await Wt(p.transaction(Ut,"readwrite").objectStore(Ut).put(i)),i}async function Ci({deviceUDID:t,bundleID:e}){const r=At(e);if(!r)return;const i=Tt(t),p=await In(la("bundle",r));if(p)return p;if(i){const c=await In(la(i,r));if(c)return c}return(await xi(r))[0]}async function rr(){return(await wa()).sort((e,r)=>new Date(r.updatedAt).getTime()-new Date(e.updatedAt).getTime())[0]}async function Ei(t){return(await wa()).filter(r=>!r.certificateID||!r.certificateP12Base64||!r.certificatePassword?!1:!t||!r.teamID||r.teamID===t).sort((r,i)=>new Date(i.updatedAt).getTime()-new Date(r.updatedAt).getTime())[0]}async function Aa(t){const e=At(t.bundleID);if(!e)throw new Error("Cannot store signing assets without a bundle ID.");const r=Tt(t.deviceUDID),i=la("bundle",e),p={...t,id:i,deviceUDID:r||void 0,bundleID:e,updatedAt:new Date().toISOString()},v=await $t(ba,Ta,mt,"id");return await Wt(v.transaction(mt,"readwrite").objectStore(mt).put(p)),p}async function xi(t){const e=At(t);return e?(await wa()).filter(i=>i.bundleID===e):[]}function Ht(t,e){const r=Tt(e);return!!r&&t.provisionedDevices.some(i=>Tt(i)===r)}function Ia(t,e){const r=At(e),i=At(t.bundleID);if(!r||!i)return!1;if(i===r||i==="*")return!0;if(!i.endsWith(".*"))return!1;const p=i.slice(0,-1);return r.startsWith(p)}async function Si(t){return Ba(new Uint8Array(await t.arrayBuffer()))}function bi(t){const e=atob(t),r=new Uint8Array(e.length);for(let i=0;i<e.length;i+=1)r[i]=e.charCodeAt(i);return Ba(r)}function Ba(t){const e=new TextDecoder("latin1").decode(t),r=e.indexOf("<?xml"),i=e.indexOf("</plist>");if(r<0||i<r)throw new Error("Provisioning profile plist not found.");const p=e.slice(r,i+8),v=new DOMParser().parseFromString(p,"application/xml");if(v.querySelector("parsererror"))throw new Error("Provisioning profile plist could not be parsed.");const c=v.querySelector("plist > dict");if(!c)throw new Error("Provisioning profile plist dictionary not found.");const a=Na(c);if(!wn(a))throw new Error("Provisioning profile plist has an unexpected shape.");const g=wn(a.Entitlements)?a.Entitlements:{},l=Ot(g["application-identifier"]),x=ho(l);return{name:Ot(a.Name),uuid:Ot(a.UUID),teamID:Ot(g["com.apple.developer.team-identifier"])??Bn(a.TeamIdentifier)[0],applicationIdentifier:l,bundleID:x,provisionedDevices:Bn(a.ProvisionedDevices),expirationDate:Ot(a.ExpirationDate)}}async function In(t){if(!t)return;const e=await $t(ba,Ta,mt,"id");return Wt(e.transaction(mt,"readonly").objectStore(mt).get(t))}async function wa(){const t=await $t(ba,Ta,mt,"id");return Wt(t.transaction(mt,"readonly").objectStore(mt).getAll())}function la(t,e){return`${t}:${e}`}function ho(t){if(!t)return;const e=t.indexOf(".");return e>=0?t.slice(e+1):void 0}function Na(t){switch(t.tagName){case"dict":return vo(t);case"array":return Array.from(t.children).map(Na);case"string":case"date":return t.textContent??"";default:return t.textContent??""}}function vo(t){const e={},r=Array.from(t.children);for(let i=0;i<r.length;i+=2){const p=r[i],v=r[i+1];!p||p.tagName!=="key"||!v||(e[p.textContent??""]=Na(v))}return e}function Ot(t){return typeof t=="string"&&t?t:void 0}function Bn(t){return Array.isArray(t)?t.filter(e=>typeof e=="string"):[]}function wn(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function $t(t,e,r,i){return new Promise((p,v)=>{const c=indexedDB.open(t,e);c.onupgradeneeded=()=>{const a=c.result;a.objectStoreNames.contains(r)||a.createObjectStore(r,{keyPath:i})},c.onsuccess=()=>p(c.result),c.onerror=()=>v(c.error??new Error("Open IndexedDB failed"))})}function Wt(t){return new Promise((e,r)=>{t.onsuccess=()=>e(t.result),t.onerror=()=>r(t.error??new Error("IndexedDB request failed"))})}function Ti(){return{method:"POST",path:"/account/listTeams.action",payload:{}}}function Ra({bundleID:t,teamID:e=""}){return pr("/account/ios/identifiers/listAppIds.action",e,{sort:"name=asc"})}function Ai({deviceUDID:t,teamID:e=""}){return pr("/account/ios/device/listDevices.action",e,{sort:"name=asc",includeRemovedDevices:!1})}function Ii(t=""){return pr("/account/ios/certificate/listCertRequests.action",t,{sort:"name=asc",types:"83Q87W3TGH,5QPB9NHCEI"})}function Bi({bundleID:t,teamID:e=""}){return pr("/account/ios/profile/listProvisioningProfiles.action",e,{search:t,sort:"name=asc"})}function wi({deviceUDID:t,teamID:e="",name:r="Limrun iPhone"}){return{method:"POST",path:"/account/ios/device/addDevices.action",payload:{teamId:e,deviceNames:r,deviceNumbers:Tt(t),deviceClasses:"iphone",register:"single"}}}function Ni({bundleID:t,teamID:e="",name:r}){return{method:"POST",path:"/account/ios/identifiers/addAppId.action",payload:{teamId:e,name:r??t,identifier:t,type:"explicit"}}}function Ri({csrPEM:t,teamID:e=""}){return{method:"POST",path:"/account/ios/certificate/submitCertificateRequest.action",payload:{teamId:e,type:"83Q87W3TGH",csrContent:t}}}function _i(t,e=""){return{method:"GET",path:"/account/ios/certificate/downloadCertificateContent.action",payload:{teamId:e,certificateId:t,type:"83Q87W3TGH"}}}function Di({bundleID:t,teamID:e="",appIDID:r,certificateID:i,deviceIDs:p,name:v}){return{method:"POST",path:"/account/ios/profile/createProvisioningProfile.action",payload:{teamId:e,provisioningProfileName:v??`Limrun ${t}`,certificateIds:[i],appIdId:r,deviceIds:p,distributionType:"limited",subPlatform:"ios"}}}function Li(t,e=""){return{method:"GET",path:"/account/ios/profile/downloadProfileContent",payload:{teamId:e,provisioningProfileId:t}}}async function da({bundleID:t,deviceUDID:e,teamID:r}){const i=await Ci({bundleID:t,deviceUDID:e});if(!(!i||!Ui(i,{bundleID:t,deviceUDID:e,teamID:r})))return i}async function Pi(t){return Aa({...t,certificateFileName:t.certificateID?`${t.certificateID}.p12`:"apple-development.p12",profileFileName:t.profile.uuid?`${t.profile.uuid}.mobileprovision`:"apple-development.mobileprovision"})}function Ui(t,{bundleID:e,deviceUDID:r,teamID:i}){return!Ia(t.profile,e)||i&&t.teamID&&t.teamID!==i||r&&!Ht(t.profile,r)||t.profile.expirationDate&&new Date(t.profile.expirationDate).getTime()<=Date.now()?!1:At(t.bundleID)===At(e)}function go(t){const e=t;return e?.teams?.[0]??e?.provider??e?.availableProviders?.[0]}function yo(t){const e=t,r=[...e?.teams??[],...e?.provider?[e.provider]:[],...e?.availableProviders??[]],i=new Set;for(const p of r)for(const v of[p.teamId,p.providerId,p.publicProviderId])v!==void 0&&v!==""&&i.add(String(v));return[...i]}function pr(t,e,r={}){const i={pageNumber:1,pageSize:200,...r};return e&&(i.teamId=e),{method:"POST",path:t,payload:i}}async function ki(t,e){const r=new URL(`${t}/info`);e&&r.searchParams.set("token",e);const i=await fetch(r.toString(),{headers:e?{Authorization:`Bearer ${e}`}:void 0});if(!i.ok){const p=await i.text();throw new Error(`Info request failed: HTTP ${i.status} ${p}`)}return await i.json()}async function Vi({limbuildApiUrl:t,token:e,certificateP12Base64:r,certificatePassword:i,provisioningProfileBase64:p}){const v=new URL(`${t}/exec`);e&&v.searchParams.set("token",e);const c=await fetch(v.toString(),{method:"POST",headers:{"Content-Type":"application/json",...e?{Authorization:`Bearer ${e}`}:{}},body:JSON.stringify({command:"xcodebuild",xcodebuild:{sdk:"iphoneos",configuration:"Debug"},signing:{certificateP12Base64:r,certificatePassword:i,provisioningProfileBase64:p}})});if(!c.ok){const a=await c.text();throw new Error(`Build request failed: HTTP ${c.status} ${a}`)}return await c.json()}function Oi({limbuildApiUrl:t,execId:e,token:r,onLine:i,onStatus:p,onError:v}){const c=new URL(`${t}/exec/${e}/events`);r&&c.searchParams.set("token",r);const a=new EventSource(c.toString());return p("running"),a.addEventListener("command",g=>i({type:"command",data:g.data})),a.addEventListener("stdout",g=>i({type:"stdout",data:g.data})),a.addEventListener("stderr",g=>i({type:"stderr",data:g.data})),a.addEventListener("exitCode",g=>{const l=parseInt(g.data,10);p(l===0?"succeeded":l<0?"cancelled":"failed"),a.close()}),a.onerror=()=>{a.close(),v?.(new Error("Build log stream closed before completion."))},()=>a.close()}const _a=1,_t=16,Je={DeviceHello:1,OpenStream:2,OpenResult:3,StreamData:4,StreamClose:5,InstallProgress:6,Error:7,Ping:8,Pong:9,StartPairing:10,StartInstall:11,PairRecordReady:12};function Fi(t){const e=new Uint8Array(_t+t.payload.byteLength),r=new DataView(e.buffer);return r.setUint8(0,_a),r.setUint8(1,t.type),r.setUint8(2,0),r.setUint8(3,0),r.setUint32(4,t.requestId),r.setUint32(8,t.streamId),r.setUint32(12,t.payload.byteLength),e.set(t.payload,_t),e}function Ki(t){if(t.byteLength<_t)throw new Error(`Relay frame too short: ${t.byteLength}`);const e=new DataView(t.buffer,t.byteOffset,t.byteLength),r=e.getUint8(0);if(r!==_a)throw new Error(`Unsupported relay protocol version ${r}`);const i=e.getUint32(12);if(t.byteLength!==_t+i)throw new Error(`Relay frame length mismatch: got ${t.byteLength}, expected ${_t+i}`);return{type:e.getUint8(1),requestId:e.getUint32(4),streamId:e.getUint32(8),payload:t.slice(_t)}}function Nt(t){return new TextEncoder().encode(JSON.stringify(t))}function ar(t){return JSON.parse(new TextDecoder().decode(t))}async function Mi(){if(!navigator.usb)throw new Error("WebUSB is not available in this browser.");return navigator.usb.requestDevice({filters:[{vendorId:1452}]})}function qi(t){const e=[],r=t.configuration?.configurationValue,i=t.configurations.find(p=>p.configurationValue===r);i&&e.push(...Nn(i));for(const p of t.configurations)p.configurationValue!==r&&e.push(...Nn(p));return e}function Nn(t){const e=[];for(const r of t.interfaces)for(const i of r.alternates)i.interfaceClass===255&&i.interfaceSubclass===254&&i.interfaceProtocol===2&&e.push({configurationValue:t.configurationValue,interfaceNumber:r.interfaceNumber,alternateSetting:i.alternateSetting,endpoints:i.endpoints});return e}async function Hi(t,e){t.opened||await t.open(),(!t.configuration||t.configuration.configurationValue!==e.configurationValue)&&await t.selectConfiguration(e.configurationValue),await t.claimInterface(e.interfaceNumber),e.alternateSetting!==0&&await t.selectAlternateInterface(e.interfaceNumber,e.alternateSetting)}function Gi(t){const e=t.endpoints.find(i=>i.direction==="out"&&i.type==="bulk"),r=t.endpoints.find(i=>i.direction==="in"&&i.type==="bulk");if(!e||!r)throw new Error("Could not find usbmux bulk endpoints.");return{outEndpoint:e,inEndpoint:r}}async function Da(t,e,r){const i=await t.transferOut(e.endpointNumber,r);if(i.status!=="ok")throw new Error(`USB transferOut failed: ${i.status}`);r.byteLength%e.packetSize===0&&await t.transferOut(e.endpointNumber,new Uint8Array)}async function zi(t,e,r=16384){const i=await t.transferIn(e.endpointNumber,r);if(i.status!=="ok"||!i.data)throw new Error(`USB transferIn failed: ${i.status}`);return new Uint8Array(i.data.buffer,i.data.byteOffset,i.data.byteLength)}const Qi=0,mo=2,$i=6,Co=4277009102,pa=2,Eo=4,Mt=16,xo=49152;async function Wi(t,e){const{inEndpoint:r,outEndpoint:i}=Gi(e),p=new Uint8Array(12),v=new DataView(p.buffer);v.setUint32(0,2),v.setUint32(4,0),v.setUint32(8,0),await Da(t,i,es(Qi,p));const c=await Ji(t,r,1),a=new DataView(c.payload.buffer,c.payload.byteOffset).getUint32(0),g={device:t,candidate:e,inEndpoint:r,outEndpoint:i,muxVersion:a,txSeq:0,rxSeq:65535,nextSport:xo,streams:new Map,writeChain:Promise.resolve(),closed:!1};return a>=2&&await Zi(g,mo,new Uint8Array([7])),So(g),g}async function Yi(t,e){if(t.closed)throw new Error("usbmux session is closed.");let r,i;const p={session:t,sport:t.nextSport++,dport:e,seq:0,ack:0,queue:[],waiters:[],opened:new Promise((v,c)=>{r=v,i=c}),resolveOpened:r,rejectOpened:i};return t.streams.set(ha(e,p.sport),p),await sr(p,pa,new Uint8Array),await p.opened,p}async function ji(t,e){if(t.session.closed)throw new Error("usbmux session is closed.");await sr(t,Mt,e),t.seq+=e.byteLength}async function Xi(t){if(t.queue.length>0)return t.queue.shift();if(t.error)throw t.error;return new Promise(e=>{t.waiters.push(e)})}function La(t){t.closed=!0;for(const e of t.streams.values())for(e.error=new Error("usbmux session closed"),e.rejectOpened(e.error);e.waiters.length>0;)e.waiters.shift()(new Uint8Array);t.streams.clear()}async function sr(t,e,r){const i=new Uint8Array(20+r.byteLength),p=new DataView(i.buffer);p.setUint16(0,t.sport),p.setUint16(2,t.dport),p.setUint32(4,t.seq),p.setUint32(8,t.ack),p.setUint8(12,80),p.setUint8(13,e),p.setUint16(14,512),i.set(r,20),await Zi(t.session,$i,i)}async function Zi(t,e,r){if(t.closed)throw new Error("usbmux session is closed.");return t.writeChain=t.writeChain.then(async()=>{if(t.closed)return;const i=t.muxVersion>=2?bo(e,r,t.txSeq++,t.rxSeq):es(e,r);await Da(t.device,t.outEndpoint,i)}),t.writeChain}async function So(t){try{for(;;){if(t.closed)return;const e=await Ji(t.device,t.inEndpoint,t.muxVersion);if(t.closed)return;if(e.rxSeq!==void 0&&(t.rxSeq=e.rxSeq),e.protocol!==$i)continue;const r=Ao(e.payload),i=t.streams.get(ha(r.sport,r.dport));if(i){if(r.flags&Eo){for(i.error=new Error(`Device reset stream ${i.dport}`),i.rejectOpened(i.error);i.waiters.length>0;)i.waiters.shift()(new Uint8Array);t.streams.delete(ha(i.dport,i.sport));continue}if((r.flags&(pa|Mt))===(pa|Mt)){i.seq+=1,i.ack=r.seq+1,await sr(i,Mt,new Uint8Array),i.resolveOpened();continue}r.payload.byteLength!==0&&(i.ack=r.seq+r.payload.byteLength,await sr(i,Mt,new Uint8Array),i.waiters.length>0?i.waiters.shift()(r.payload):i.queue.push(r.payload))}}}catch{t.closed||La(t)}}async function Ji(t,e,r){for(;;){const i=await zi(t,e),p=To(i,r);if(!(r===1&&p.protocol!==Qi))return p}}function es(t,e){const r=new Uint8Array(8+e.byteLength),i=new DataView(r.buffer);return i.setUint32(0,t),i.setUint32(4,r.byteLength),r.set(e,8),r}function bo(t,e,r,i){const p=new Uint8Array(16+e.byteLength),v=new DataView(p.buffer);return v.setUint32(0,t),v.setUint32(4,p.byteLength),v.setUint32(8,Co),v.setUint16(12,r),v.setUint16(14,i),p.set(e,16),p}function To(t,e){const r=new DataView(t.buffer,t.byteOffset,t.byteLength),i=r.getUint32(0),p=r.getUint32(4),v=e>=2?16:8;return{protocol:i,length:p,rxSeq:e>=2?r.getUint16(14):void 0,payload:t.slice(v,p)}}function Ao(t){const e=new DataView(t.buffer,t.byteOffset,t.byteLength),r=(e.getUint8(12)>>4)*4;return{sport:e.getUint16(0),dport:e.getUint16(2),seq:e.getUint32(4),ack:e.getUint32(8),flags:e.getUint8(13),payload:t.slice(r)}}function ha(t,e){return`${t}:${e}`}class ts{constructor(e,r,i,p){this.webSocketUrl=e,this.session=r,this.deviceHello=i,this.log=p}socket;streams=new Map;frameQueue=Promise.resolve();closed=!1;pairRecordWaiter;async connect(){const e=new WebSocket(this.webSocketUrl);e.binaryType="arraybuffer",this.socket=e,e.onclose=()=>{this.closed=!0,this.log("Relay socket closed"),this.pairRecordWaiter&&(this.pairRecordWaiter.reject(new Error("Relay socket closed")),this.pairRecordWaiter=void 0)},await new Promise((r,i)=>{e.onopen=()=>r(),e.onerror=()=>i(new Error("WebSocket connection failed"))}),e.onmessage=r=>{const i=r.data instanceof ArrayBuffer?new Uint8Array(r.data):new Uint8Array;this.enqueueFrame(i)},await this.send({type:Je.DeviceHello,requestId:0,streamId:0,payload:Nt(this.deviceHello)}),this.log("Connected WebSocket relay")}async startPairing(){const e=new Promise((r,i)=>{this.pairRecordWaiter={resolve:r,reject:i}});return await this.send({type:Je.StartPairing,requestId:0,streamId:0,payload:Nt({})}),this.log("Pairing requested"),e}async startInstall(e){await this.send({type:Je.StartInstall,requestId:0,streamId:0,payload:Nt(e)}),this.log("Installation requested")}close(){this.closed=!0,this.socket?.close()}enqueueFrame(e){this.frameQueue=this.frameQueue.then(()=>this.handleFrame(Ki(e))).catch(r=>{this.log("Relay frame handling failed",r instanceof Error?r.message:String(r))})}async handleFrame(e){switch(e.type){case Je.OpenStream:await this.handleOpenStream(e.requestId,e.streamId,ar(e.payload).port);break;case Je.StreamData:{const r=this.streams.get(e.streamId);if(!r)throw new Error(`Unknown stream ${e.streamId}`);await ji(r,e.payload);break}case Je.StreamClose:this.streams.delete(e.streamId);break;case Je.InstallProgress:this.log(Bo(ar(e.payload).message));break;case Je.Error:this.handleError(e.payload);break;case Je.PairRecordReady:this.handlePairRecordReady(ar(e.payload));break;case Je.Ping:await this.send({type:Je.Pong,requestId:e.requestId,streamId:0,payload:new Uint8Array});break}}handleError(e){const r=Io(e);this.log("Server error",r),this.pairRecordWaiter&&(this.pairRecordWaiter.reject(new Error(r)),this.pairRecordWaiter=void 0)}handlePairRecordReady(e){this.log("Pair record received",e.udid),this.pairRecordWaiter?.resolve(e),this.pairRecordWaiter=void 0}async handleOpenStream(e,r,i){try{const p=await Yi(this.session,i);this.streams.set(r,p),await this.send({type:Je.OpenResult,requestId:e,streamId:r,payload:Nt({ok:!0})}),this.log(`Opened device stream ${r} to port ${i}`),this.pumpDeviceToServer(r,p)}catch(p){this.log(`Open device stream ${r} failed`,p instanceof Error?p.message:String(p)),await this.send({type:Je.OpenResult,requestId:e,streamId:r,payload:Nt({ok:!1,error:p instanceof Error?p.message:String(p)})})}}async pumpDeviceToServer(e,r){try{for(;;){const i=await Xi(r);if(this.closed)return;await this.send({type:Je.StreamData,requestId:0,streamId:e,payload:i})}}catch(i){this.log(`Device stream ${e} closed`,i instanceof Error?i.message:String(i)),await this.send({type:Je.StreamClose,requestId:0,streamId:e,payload:Nt({reason:i instanceof Error?i.message:String(i)})})}}async send(e){if(!this.closed){if(!this.socket||this.socket.readyState!==WebSocket.OPEN){this.closed=!0;return}this.socket.send(Fi(e))}}}function Io(t){const e=new TextDecoder().decode(t);try{const r=JSON.parse(e);return Rn(r.error??e)}catch{return Rn(e)}}function Rn(t){return t.replace(/libimobiledevice/g,"").trim()}function Bo(t){const e="install status: ";if(!t.startsWith(e))return t;const r=t.slice(e.length),p=new DOMParser().parseFromString(r,"application/xml").querySelector("plist > dict");if(!p)return t;const v=wo(p),c=v.Status??"Unknown";return`Install progress: ${v.PercentComplete?`${v.PercentComplete}% `:""}${c}`}function wo(t){const e={},r=Array.from(t.children);for(let i=0;i<r.length;i+=2){const p=r[i],v=r[i+1];!p||p.tagName!=="key"||!v||(e[p.textContent??""]=v.textContent??"")}return e}async function rs({log:t}){t("Selecting USB device");const e=await Mi(),r=Ro(e);return t("Selected USB device",`${e.manufacturerName??""} ${e.productName??""} ${e.serialNumber??""}`.trim()),r}async function as({limbuildApiUrl:t,token:e,log:r,target:i}){const p=Pa(t,e);let v;try{v=await is(p,i,r);const c=await v.startPairing();return{relay:v,pairRecord:c,target:i}}catch(c){throw v?.close(),c}}async function ns({limbuildApiUrl:t,token:e,log:r,target:i,pairRecord:p}){const v=Pa(t,e);let c;try{return c=await is(v,i,r),await c.startInstall(p),c}catch(a){throw c?.close(),a}}async function Rt(t,e){if(t){if(t.session&&(La(t.session),t.session=void 0),t.claimedInterfaceNumber!==void 0)try{await t.device.releaseInterface(t.claimedInterfaceNumber),e?.("Released usbmux interface")}catch(r){e?.("USB interface release failed",va(r))}finally{t.claimedInterfaceNumber=void 0}if(t.device.opened)try{await t.device.close(),e?.("Closed USB device")}catch(r){e?.("USB device close failed",va(r))}}}async function is(t,e,r){await No(e,r);const i=new ts(t,e.session,e.hello,r);return await i.connect(),i}async function No(t,e){if(!t.session)try{t.candidate=await _o(t,e),t.session=await Wi(t.device,t.candidate),e("Created usbmux session")}catch(r){throw await Rt(t,e),r}}function Ro(t){return{device:t,candidate:Do(t),hello:{serialNumber:t.serialNumber,productName:t.productName,manufacturerName:t.manufacturerName,productId:t.productId,vendorId:t.vendorId}}}async function _o(t,e){const r=ss(t.device);if(r.length===0)throw new Error("No Apple usbmux interface found.");let i;for(const p of r)for(const v of[1,2])try{return t.device.opened||await t.device.open(),e("Claiming usbmux interface",`configuration ${p.configurationValue}, interface ${p.interfaceNumber}, alternate ${p.alternateSetting}, attempt ${v}`),await Hi(t.device,p),t.claimedInterfaceNumber=p.interfaceNumber,e("Claimed usbmux interface",`configuration ${p.configurationValue}, interface ${p.interfaceNumber}`),p}catch(c){i=c,e("USB interface claim failed",`configuration ${p.configurationValue}, interface ${p.interfaceNumber}: ${va(c)}`),await Lo(t),await Po(250)}throw i instanceof Error?i:new Error("Unable to claim any Apple usbmux interface.")}function Do(t){const e=ss(t)[0];if(!e)throw new Error("No Apple usbmux interface found.");return e}function ss(t){const e=qi(t),r=t.configuration?.configurationValue;return[...e.filter(i=>i.configurationValue===r),...e.filter(i=>i.configurationValue!==r)]}function Pa(t,e){const r=new URL(t);return r.protocol=r.protocol==="https:"?"wss:":"ws:",r.pathname=`${r.pathname.replace(/\/$/,"")}/device/ws`,e&&r.searchParams.set("token",e),r.toString()}function va(t){return t instanceof Error?t.message:String(t)}async function Lo(t){if(t.claimedInterfaceNumber!==void 0){try{await t.device.releaseInterface(t.claimedInterfaceNumber)}catch{}t.claimedInterfaceNumber=void 0}if(t.device.opened)try{await t.device.close()}catch{}}function Po(t){return new Promise(e=>setTimeout(e,t))}const Uo={signing:"idle",connect:"idle",build:"idle",install:"idle"};function ko({apiUrl:t,token:e}){const[r,i]=de.useState("signing"),[p,v]=de.useState(Uo),[c,a]=de.useState(),[g,l]=de.useState(),[x,L]=de.useState(),[b,u]=de.useState(["Ready. Prepare signing assets, build, connect and pair the iPhone, then install."]),[m,E]=de.useState([]),[C,o]=de.useState("idle"),[h,y]=de.useState("idle"),[I,R]=de.useState([]),[d,s]=de.useState([]),[n,B]=de.useState([]),[P,O]=de.useState([]),[U,F]=de.useState(),[q,M]=de.useState(),[H,Q]=de.useState(""),[j,ee]=de.useState(),[oe,ce]=de.useState(!1),[he,pe]=de.useState(),[ve,W]=de.useState(),[X,Re]=de.useState(!1),[ye,S]=de.useState({}),D=de.useRef(void 0),_=de.useRef(void 0),N=de.useRef(void 0),f=de.useRef(void 0),T=de.useCallback((te,re)=>{const ie=re?`${te}
|
|
31
31
|
${re}`:te;u(le=>[ie,...le].slice(0,100))},[]),V=de.useCallback((te,re)=>{v(ie=>({...ie,[te]:re}))},[]),G=de.useCallback(te=>{S(re=>{const ie={...re,...te},le=!!ie.certificateFile&&!!ie.provisioningProfileFile&&!!ie.certificatePassword;return V("signing",le?"complete":"active"),le&&(y("assets-ready"),i("build")),ie}),L(void 0)},[V]);de.useEffect(()=>{let te=!1;return rr().then(re=>{te||!re||(L(re),Q(re.bundleID),y("using-cached-profile"),V("signing","complete"),i("build"),T("Using stored signing assets",re.bundleID))}),()=>{te=!0}},[T,V]);const Z=de.useCallback(()=>cr(I.find(te=>or(te)===q)),[I,q]);de.useEffect(()=>{const te=Z();if(!te){ee(void 0);return}let re=!1;return Vo(te).then(ie=>{re||ee(ie)}),()=>{re=!0}},[Z]);const z=!!(c?.hello.serialNumber?d.find(te=>Gt(te.deviceNumber)===Gt(c.hello.serialNumber)):void 0)?.deviceId,J=!!ye.certificateFile&&!!ye.provisioningProfileFile&&!!ye.certificatePassword,fe=!!x||J,me=c?.hello.serialNumber&&x?Ht(x.profile,c.hello.serialNumber):void 0;de.useEffect(()=>{_.current=c},[c]);const ue=de.useCallback(async()=>{D.current?.close(),D.current=void 0,await Rt(_.current,T)},[T]);de.useEffect(()=>()=>{N.current?.(),f.current?.close(),f.current=void 0,ue()},[ue]);const Te=de.useCallback(async()=>{const te=H.trim();if((!te||x&&Ia(x.profile,te))&&x)return T("Using prepared signing assets",x.bundleID),x;const re=te?void 0:t?await os(t,e).catch(()=>{}):void 0,ie=te||re?.lastBuildConfig?.bundleId;if(ie){const gt=await da({bundleID:ie,deviceUDID:c?.hello.serialNumber,teamID:Z()});if(gt)return y("using-cached-profile"),T("Using cached Apple signing profile",gt.bundleID),L(gt),gt}const le=await rr();if(le)return T("Using stored signing assets",le.bundleID),L(le),le;if(!ye.certificateFile||!ye.provisioningProfileFile||!ye.certificatePassword)throw new Error("Upload a certificate, provisioning profile, and certificate password.");T("Preparing signing assets");const[Se,tt,st]=await Promise.all([Dn(ye.certificateFile),Dn(ye.provisioningProfileFile),Si(ye.provisioningProfileFile)]);if(c?.hello.serialNumber&&!Ht(st,c.hello.serialNumber))throw new Error("Provisioning profile does not include the selected iPhone.");const vt=st.bundleID??st.applicationIdentifier??ye.provisioningProfileFile.name,xt=await Aa({deviceUDID:c?.hello.serialNumber,bundleID:vt,certificateP12Base64:Se,certificateFileName:ye.certificateFile.name,certificatePassword:ye.certificatePassword,provisioningProfileBase64:tt,profileFileName:ye.provisioningProfileFile.name,profile:st});return L(xt),T("Signing assets stored locally",vt),xt},[t,H,T,Z,c?.hello.serialNumber,x,ye,e]),Ne=de.useCallback(async({accountName:te,password:re})=>{if(t){pe("signing"),W(void 0),i("signing"),V("signing","active"),y("authenticating");try{await f.current?.close().catch(()=>{});const ie=await Zn({limbuildApiUrl:t,token:e,accountName:te,password:re});if(f.current=ie,!ie.requiresTwoFactor){const le=await ie.finalize().catch(()=>{}),Se=await _n(t,ie.appleSessionId,e,R,M,le?.body);await aa(t,ie.appleSessionId,e,Se,B,Q),Se&&await Ft({apiUrl:t,token:e,appleSessionId:ie.appleSessionId,teamID:Se,setAppleDevices:s,setSelectedAppleDeviceIDs:O,log:T}),await na(t,ie.appleSessionId,e,Se,F,T)}y(ie.requiresTwoFactor?"two-factor-required":"authenticated"),T(ie.requiresTwoFactor?"Apple ID requires two-factor authentication":"Apple ID authenticated",te)}catch(ie){const le=dt(ie);W(le),y("error"),T("Apple ID authentication failed",le)}finally{pe(void 0)}}},[t,T,V,e]),Be=de.useCallback(async te=>{const re=f.current;if(!re)throw new Error("Start Apple ID login before submitting a two-factor code.");pe("signing"),W(void 0),i("signing"),V("signing","active");try{if(await re.finishTwoFactor(te),t){const ie=await re.finalize().catch(()=>{}),le=await _n(t,re.appleSessionId,e,R,M,ie?.body);await aa(t,re.appleSessionId,e,le,B,Q),le&&await Ft({apiUrl:t,token:e,appleSessionId:re.appleSessionId,teamID:le,setAppleDevices:s,setSelectedAppleDeviceIDs:O,log:T}),await na(t,re.appleSessionId,e,le,F,T)}y("authenticated"),T("Apple ID two-factor authentication accepted")}catch(ie){const le=dt(ie);W(le),y("error"),T("Apple ID two-factor authentication failed",le)}finally{pe(void 0)}},[t,T,V,e]),Ie=de.useCallback(()=>{f.current?.close(),f.current=void 0,R([]),s([]),B([]),O([]),F(void 0),M(void 0),ee(void 0),y("idle"),V("signing","idle"),T("Apple ID login state cleared")},[T,V]),Ae=de.useCallback(te=>{M(te),B([]),s([]),O([]),F(void 0),Q(""),L(void 0);const re=f.current;if(!t||!re||!te)return;const ie=cr(I.find(le=>or(le)===te));ie&&(async()=>{try{await aa(t,re.appleSessionId,e,ie,B,Q),await na(t,re.appleSessionId,e,ie,F,T),await Ft({apiUrl:t,token:e,appleSessionId:re.appleSessionId,teamID:ie,connectedUDID:_.current?.hello.serialNumber,setAppleDevices:s,setSelectedAppleDeviceIDs:O,log:T})}catch(le){const Se=dt(le);W(Se),T("Apple team refresh failed",Se)}})()},[t,I,T,e]),be=de.useCallback(async()=>{const te=Z();if(!(!t||!f.current||!c?.hello.serialNumber||!te)){pe("signing"),W(void 0);try{const re=Gt(c.hello.serialNumber),ie=await it(t,f.current.appleSessionId,wi({deviceUDID:re,teamID:te,name:c.hello.productName??"Limrun iPhone"}),e);pt(ie.body,"Apple device registration"),await Ft({apiUrl:t,token:e,appleSessionId:f.current.appleSessionId,teamID:te,connectedUDID:c.hello.serialNumber,setAppleDevices:s,setSelectedAppleDeviceIDs:O,log:T}),T("Connected iPhone registered with Apple Developer",re)}catch(re){const ie=dt(re);W(ie),T("Apple device registration failed",ie)}finally{pe(void 0)}}},[t,T,Z,c?.hello.productName,c?.hello.serialNumber,e]),Ee=de.useCallback(async()=>{if(!t||!f.current)return;const te=H.trim();if(!te)throw new Error("Enter a bundle ID before preparing signing assets.");if(!q)throw new Error("Select an Apple Developer team before preparing signing assets.");const re=Z();if(!re)throw new Error("Selected Apple team does not include a Developer Portal team ID.");if(P.length===0)throw new Error("Select at least one Apple Developer device before preparing signing assets.");if(!j&&!ye.certificatePassword)throw new Error("Enter a .p12 password before preparing signing assets.");const ie=d.find(Se=>P.includes(Se.deviceId??"")),le=c?.hello.serialNumber??ie?.deviceNumber;if(!le)throw new Error("Select an Apple Developer device before preparing signing assets.");pe("signing"),W(void 0),i("signing"),V("signing","active"),y("preparing-assets");try{const Se=await da({bundleID:te,deviceUDID:le,teamID:re});if(Se){L(Se),y("assets-ready"),V("signing","complete"),i("build"),T("Using cached Apple signing assets",te);return}const tt=await Fo({apiUrl:t,token:e,appleSessionId:f.current.appleSessionId,teamID:re,bundleID:te,deviceUDID:le,deviceIDs:P,certificatePassword:ye.certificatePassword,reusableCertificate:j});L(tt),y("assets-ready"),V("signing","complete"),i("build"),T("Apple signing assets stored locally",`${te} for ${le}`)}catch(Se){const tt=dt(Se);W(tt),y("error"),T("Apple signing asset preparation failed",tt)}finally{pe(void 0)}},[t,H,d,I,T,q,P,Z,c?.hello.serialNumber,V,j,ye.certificatePassword,e]),_e=de.useCallback(async()=>{if(t){pe("build"),W(void 0),i("build"),V("build","active"),ce(!0),E([]),o("queued"),N.current?.();try{const te=await Te();T("Starting signed device build");const re=await Vi({limbuildApiUrl:t,token:e,certificateP12Base64:te.certificateP12Base64,certificatePassword:te.certificatePassword,provisioningProfileBase64:te.provisioningProfileBase64});if(!re.execId)throw new Error("Build request did not return an exec ID.");T("Signed device build started",re.execId),N.current=Oi({limbuildApiUrl:t,execId:re.execId,token:e,onLine:ie=>E(le=>[...le,ie]),onStatus:ie=>{o(ie),ie==="succeeded"?(V("build","complete"),V("connect","active"),i("connect")):(ie==="failed"||ie==="cancelled")&&V("build","error")},onError:ie=>{const le=dt(ie);W(le),T("Build log stream failed",le)}})}catch(te){const re=dt(te);W(re),o("failed"),V("build","error"),T("Signed device build failed",re)}finally{pe(void 0)}}},[t,T,Te,V,e]),De=de.useCallback(async()=>{pe("usb"),W(void 0),i("connect"),V("connect","active");let te;try{await ue(),te=await rs({log:T}),Re(!1);const re=await yi(te.hello.serialNumber),ie=x??(J?void 0:await rr());if(ie){if(!Ht(ie.profile,te.hello.serialNumber))throw new Error("Stored provisioning profile does not include the selected iPhone.");L(ie)}if(t&&f.current){const le=Z();le&&await Ft({apiUrl:t,token:e,appleSessionId:f.current.appleSessionId,teamID:le,connectedUDID:te.hello.serialNumber,setAppleDevices:s,setSelectedAppleDeviceIDs:O,log:T})}a(te),l(re),V("connect",re?"complete":"active"),i(re?"install":"connect"),T(re?"Pair record found":"No pair record found",te.hello.serialNumber)}catch(re){await Rt(te,T),a(void 0),l(void 0);const ie=dt(re);W(ie),V("connect","error"),T("USB access failed",ie)}finally{pe(void 0)}},[t,ue,T,J,Z,V,x,e]),Pe=de.useCallback(async()=>{if(!(!t||!c)){pe("pair"),W(void 0),Re(!1),i("connect"),V("connect","active");try{await ue();const te=await as({limbuildApiUrl:t,token:e,log:T,target:c}),re=await mi(te.pairRecord,{productName:c.hello.productName});te.relay.close(),await Rt(c,T),l(re),Re(!1),V("connect","complete"),i("install"),T("Device paired","The pair record was stored locally in this browser.")}catch(te){await Rt(c,T);const re=dt(te);Re(!0),W("Unlock the iPhone, tap Trust, then confirm the pair record."),V("connect","error"),T("Device pairing failed",re)}finally{pe(void 0)}}},[t,ue,T,c,V,e]),Ue=de.useCallback(async()=>{if(!(!t||!c||!g)){pe("install"),W(void 0),i("install"),V("install","active");try{await ue(),D.current=await ns({limbuildApiUrl:t,token:e,log:T,target:c,pairRecord:g}),V("install","complete"),T("Device install started","Installation will continue through the connected iPhone.")}catch(te){await Rt(c,T);const re=dt(te);W(re),V("install","error"),T("Device install relay failed",re)}finally{pe(void 0)}}},[t,ue,T,g,c,V,e]),Ze=de.useCallback(()=>{ue(),T("Device relay stopped")},[ue,T]);return{currentStep:r,stepStatuses:p,device:c?.hello,hasPairRecord:!!g,hasSigningAssets:!!x,hasSigningInputs:fe,pairConfirmationRequired:X,logs:b,buildLogs:m,buildStatus:C,appleSigningStatus:h,appleTeams:I,appleDevices:d,appleAppIDs:n,applePortalSummary:U,selectedAppleTeamID:q,selectedAppleDeviceIDs:P,connectedAppleDeviceRegistered:z,connectedDeviceInProfile:me,hasReusableAppleCertificate:!!j,appleBundleID:H,buildLogPanelOpen:oe,busyAction:he,error:ve,canBuild:!!t&&!he&&fe,canPrepareAppleSigningAssets:!!t&&!he&&!!f.current&&!!H.trim()&&!!Z()&&P.length>0&&(!!j||!!ye.certificatePassword),canRequestUSBAccess:!he&&C==="succeeded",canPairBrowser:!!t&&!he&&C==="succeeded"&&!!c,canInstall:!!t&&!he&&C==="succeeded"&&!!c&&!!g,setSigningFiles:G,setAppleBundleID:Q,setSelectedAppleDeviceIDs:O,setBuildLogPanelOpen:ce,startAppleIDLogin:Ne,submitAppleTwoFactorCode:Be,setSelectedAppleTeamID:Ae,clearAppleIDLogin:Ie,registerConnectedAppleDevice:be,prepareAppleSigningAssets:Ee,startDeviceBuild:_e,requestUSBAccess:De,pairBrowser:Pe,startInstallation:Ue,stopRelay:Ze}}async function os(t,e){return ki(t,e)}async function Vo(t){const e=await Ei(t);if(!(!e?.certificateID||!e.certificateP12Base64||!e.certificatePassword))return{certificateID:e.certificateID,certificateP12Base64:e.certificateP12Base64,certificatePassword:e.certificatePassword,teamID:e.teamID}}async function _n(t,e,r,i,p,v){const c=await it(t,e,Ti(),r);pt(c.body,"Apple Developer team list");const a=Oo([...c.body?.teams??[]]);i(a);const g=a.find(x=>cr(x)),l=or(g??a[0]);if(l&&p(l),a.length===0)throw new Error("Apple Developer account did not return any teams or providers.");return a.map(cr).find(x=>!!x)}function Oo(t){const e=new Set,r=[];for(const i of t){const v=or(i)??i.name??JSON.stringify(i);e.has(v)||(e.add(v),r.push(i))}return r}async function aa(t,e,r,i,p,v){if(!i)return;const c=await it(t,e,Ra({bundleID:"",teamID:i}),r);pt(c.body,"Apple bundle ID list");const a=c.body?.appIds??[];p(a);const g=Mo(a[0]);if(g){v(g);return}const l=await os(t,r).catch(()=>{});l?.lastBuildConfig?.bundleId&&v(l.lastBuildConfig.bundleId)}async function na(t,e,r,i,p,v){const[c,a]=await Promise.all([it(t,e,Ii(i??""),r),it(t,e,Bi({bundleID:"",teamID:i??""}),r)]);pt(c.body,"Apple Developer certificate list"),pt(a.body,"Apple Developer profile list");const g={certificateCount:c.body?.certRequests?.length??0,profileCount:a.body?.provisioningProfiles?.length??0};p(g),v("Apple Developer resources fetched",`${g.certificateCount} certificates, ${g.profileCount} provisioning profiles`)}async function Ft({apiUrl:t,token:e,appleSessionId:r,teamID:i,connectedUDID:p,setAppleDevices:v,setSelectedAppleDeviceIDs:c,log:a}){const g=await it(t,r,Ai({deviceUDID:p??"",teamID:i}),e);pt(g.body,"Apple device list");const l=g.body?.devices??[];v(l);const x=l.find(b=>!!b.deviceId)?.deviceId;if(!p){c(x?[x]:[]),a("Apple Developer devices fetched",`${l.length} devices`);return}const L=l.find(b=>Gt(b.deviceNumber)===Gt(p));L?.deviceId?(c([L.deviceId]),a("Connected iPhone found in Apple Developer devices",L.name??L.deviceNumber)):(c(x?[x]:[]),a("Connected iPhone is not registered with Apple Developer",p))}async function Fo({apiUrl:t,token:e,appleSessionId:r,teamID:i,bundleID:p,deviceUDID:v,certificatePassword:c,deviceIDs:a,reusableCertificate:g}){const l=v.replace(/-/g,"").replace(/[^a-fA-F0-9]/g,""),x=await Ko({apiUrl:t,token:e,appleSessionId:r,teamID:i,bundleID:p});let L=g?.certificateID,b=g?.certificateP12Base64,u=g?.certificatePassword;if(!L||!b||!u){if(!c)throw new Error("Enter a .p12 password before preparing signing assets.");const I=await di({commonName:`Limrun ${p}`}),R=await it(t,r,Ri({csrPEM:I.csrPEM,teamID:i}),e);if(pt(R.body,"Apple Development certificate creation"),L=rt(R.body?.certRequest,"certificateId")??rt(R.body?.certRequest,"certRequestId")??rt(R.body,"certificateId")??rt(R.body,"certRequestId"),!L)throw new Error("Apple certificate creation did not return a certificate ID.");const d=await it(t,r,_i(L,i),e);if(d.status<200||d.status>=300||!d.rawBodyBase64)throw new Error(`Apple certificate download failed: HTTP ${d.status}`);b=pi({privateKeyPKCS8Base64:I.privateKeyPKCS8Base64,certificateBase64:d.rawBodyBase64,password:c,friendlyName:`Apple Development ${p}`}),u=c}const m=`Limrun ${p}`,E=await it(t,r,Di({bundleID:p,teamID:i,appIDID:x,certificateID:L,deviceIDs:a,name:m}),e);pt(E.body,"Apple provisioning profile creation");const C=rt(E.body?.provisioningProfile,"provisioningProfileId")??rt(E.body,"provisioningProfileId");if(!C)throw new Error("Apple provisioning profile creation did not return a profile ID.");const o=await it(t,r,Li(C,i),e);if(o.status<200||o.status>=300||!o.rawBodyBase64)throw new Error(`Apple provisioning profile download failed: HTTP ${o.status}`);const h=o.rawBodyBase64,y=bi(h);return Pi({bundleID:p,deviceUDID:l,teamID:i,certificateID:L,certificateP12Base64:b,certificatePassword:u,provisioningProfileBase64:h,profile:y})}async function Ko({apiUrl:t,token:e,appleSessionId:r,teamID:i,bundleID:p}){const v=await it(t,r,Ra({bundleID:p,teamID:i}),e);pt(v.body,"Apple bundle ID lookup");const c=v.body?.appIds?.find(x=>rt(x,"identifier")===p||rt(x,"bundleId")===p),a=rt(c,"appIdId")??rt(c,"appId");if(a)return a;const g=await it(t,r,Ni({bundleID:p,teamID:i,name:p}),e);pt(g.body,"Apple bundle ID creation");const l=rt(g.body?.appId,"appIdId")??rt(g.body?.appId,"appId")??rt(g.body,"appIdId")??rt(g.body,"appId");if(!l)throw new Error("Apple bundle ID creation did not return an App ID.");return l}function pt(t,e){if(!t)throw new Error(`${e} returned an empty response.`);if(t.resultCode!==void 0&&t.resultCode!==0)throw new Error(`${e} failed: ${t.userString??t.resultString??t.resultCode}`)}function rt(t,e){const r=t?.[e];if(typeof r=="string")return r;if(typeof r=="number"||typeof r=="boolean")return String(r)}function Gt(t){return(t??"").replace(/-/g,"").replace(/[^a-fA-F0-9]/g,"").toUpperCase()}function or(t){const e=t?.teamId??t?.providerId??t?.publicProviderId;return e===void 0||e===""?void 0:String(e)}function cr(t){return t?.teamId&&t.teamId!==""?t.teamId:void 0}function Mo(t){return t?.identifier||t?.bundleId||void 0}async function Dn(t){const e=await t.arrayBuffer();let r="";const i=new Uint8Array(e);for(const p of i)r+=String.fromCharCode(p);return btoa(r)}function dt(t){return t instanceof Error?t.message:String(t)}exports.AppleGsaSrpClient=Kn;exports.RELAY_HEADER_BYTES=_t;exports.RELAY_PROTOCOL_VERSION=_a;exports.RelayClient=ts;exports.RelayMessageType=Je;exports.claimUsbmux=Hi;exports.closeDeviceRelayTarget=Rt;exports.closeUsbmuxSession=La;exports.createAppleRelaySession=Mn;exports.createBundleIDRequest=Ni;exports.createDevelopmentProfileRequest=Di;exports.createUsbmuxSession=Wi;exports.decodeFrame=Ki;exports.decodeJson=ar;exports.deleteAppleRelaySession=fa;exports.deviceRelayWebSocketUrl=Pa;exports.downloadCertificateRequest=_i;exports.downloadProfileRequest=Li;exports.encodeFrame=Fi;exports.encodeJson=Nt;exports.exportAppleCertificateP12=pi;exports.fetchAppleAccountSession=Wn;exports.fetchLimbuildInfo=ki;exports.findBundleIDRequest=Ra;exports.findDevelopmentCertificatesRequest=Ii;exports.findDevelopmentProfilesRequest=Bi;exports.findDeviceRequest=Ai;exports.findSigningAssetsForBundle=xi;exports.findUsbmuxCandidates=qi;exports.generateAppleSigningKeyAndCSR=di;exports.getBulkEndpoints=Gi;exports.getLatestSigningAssets=rr;exports.getLatestSigningAssetsWithCertificate=Ei;exports.getPairRecord=yi;exports.getReusableAppleSigningAssets=da;exports.getSigningAssets=Ci;exports.listTeamsRequest=Ti;exports.normalizeBundleID=At;exports.normalizeUDID=Tt;exports.openStream=Yi;exports.parseProvisioningProfile=Si;exports.parseProvisioningProfileBase64=bi;exports.parseProvisioningProfileBytes=Ba;exports.profileContainsDevice=Ht;exports.profileMatchesBundleID=Ia;exports.proxyPhoneTwoFactorCode=$n;exports.proxyProvisioningRequest=it;exports.proxySrpComplete=Hn;exports.proxySrpInit=qn;exports.proxyTwoFactorCode=Qn;exports.putAppleGeneratedSigningAssets=Pi;exports.putPairRecord=mi;exports.putSigningAssets=Aa;exports.receiveStreamData=Xi;exports.registerDeviceRequest=wi;exports.requestAppleDevice=Mi;exports.requestUSBAccess=rs;exports.selectDeveloperPortalTeam=go;exports.sendStreamData=ji;exports.startBrowserOwnedAppleIDLogin=Zn;exports.startInstallRelay=ns;exports.startPairingRelay=as;exports.startSignedDeviceBuild=Vi;exports.storedSigningAssetsReusable=Ui;exports.submitDevelopmentCSRRequest=Ri;exports.teamIDCandidates=yo;exports.transferIn=zi;exports.transferOutWithZlp=Da;exports.triggerPhoneTwoFactor=zn;exports.triggerTrustedDeviceTwoFactor=Gn;exports.useDeviceInstall=ko;exports.watchBuildLogEvents=Oi;
|
|
@@ -12268,7 +12268,7 @@ async function to({
|
|
|
12268
12268
|
},
|
|
12269
12269
|
body: JSON.stringify({
|
|
12270
12270
|
command: "xcodebuild",
|
|
12271
|
-
xcodebuild: { sdk: "iphoneos" },
|
|
12271
|
+
xcodebuild: { sdk: "iphoneos", configuration: "Debug" },
|
|
12272
12272
|
signing: {
|
|
12273
12273
|
certificateP12Base64: r,
|
|
12274
12274
|
certificatePassword: i,
|
package/package.json
CHANGED
|
@@ -59,7 +59,7 @@ export async function startSignedDeviceBuild({
|
|
|
59
59
|
},
|
|
60
60
|
body: JSON.stringify({
|
|
61
61
|
command: 'xcodebuild',
|
|
62
|
-
xcodebuild: { sdk: 'iphoneos' },
|
|
62
|
+
xcodebuild: { sdk: 'iphoneos', configuration: 'Debug' },
|
|
63
63
|
signing: {
|
|
64
64
|
certificateP12Base64,
|
|
65
65
|
certificatePassword,
|