@absolutejs/absolute 0.20.0-beta.34 → 0.20.0-beta.36

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.
@@ -1,29 +1,29 @@
1
1
  // @bun
2
- import{mkdir as k$,readFile as q$,rm as rb,writeFile as z$}from"fs/promises";import{join as Mb}from"path";import{createInterface as y$}from"readline";import{resolve as Nb}from"path";var ob=/^[A-Za-z][\w]*(?:\.[A-Za-z][\w]*)+$/,bw=/^[a-z][a-z0-9+.-]*$/,ww=/^[A-Z0-9]{10}$/,$w=/^[0-9A-F]{64}$/,Aw=/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(?:\.(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?))*$/,s=(b,w,$)=>{let A=Nb(b),S=Nb(A,w);if(S!==A&&!S.startsWith(`${A}/`))throw TypeError(`${$} must remain inside the project root.`);return S},V=(b,w)=>{let $=b.trim();if(!$)throw TypeError(`${w} must not be empty.`);return $},Sw=(b)=>{let w=V(b??"/","mobile.entry");if(!w.startsWith("/")||w.startsWith("//"))throw TypeError("mobile.entry must be an absolute application path.");return w},Mw=(b)=>{let w=new URL(V(b,"mobile.server.productionOrigin")),$=w.protocol==="http:"&&(w.hostname==="localhost"||w.hostname==="127.0.0.1"||w.hostname==="[::1]");if(w.protocol!=="https:"&&!$)throw TypeError("mobile.server.productionOrigin must use HTTPS, except for a loopback development origin.");if(w.username||w.password||w.pathname!=="/"||w.search||w.hash)throw TypeError("mobile.server.productionOrigin must be an origin without credentials, path, query, or hash.");return w.origin},Ow=(b)=>{let w=[...new Set(b??["ios","android"])];if(w.length===0)throw TypeError("mobile.platforms must contain at least one platform.");return w},Cw=(b,w)=>{let $=(M)=>{let O=V(M,"mobile.deepLinks.hosts").toLowerCase();if(!Aw.test(O))throw TypeError("mobile.deepLinks.hosts entries must be valid hostnames without ports, wildcards, or paths.");return O},A=new URL(w).hostname,S=new Set(A==="[::1]"?[]:[$(A)]);for(let M of b??[])S.add($(M));return[...S].sort()},Dw=(b)=>{if(b===void 0)return;let w=V(b,"mobile.deepLinks.apple.appIdPrefix").toUpperCase();if(!ww.test(w))throw TypeError("mobile.deepLinks.apple.appIdPrefix must contain ten letters or digits.");return w},xw=(b)=>{if(b===void 0)return;let w=V(b,"mobile.ios.version");if(!/^\d+(?:\.\d+){0,2}$/u.test(w))throw TypeError("mobile.ios.version must contain one to three dot-separated integer components, for example 1.4.0.");return w},Jw=(b)=>[...new Set((b??[]).map((w)=>V(w,"mobile.deepLinks.android.sha256CertificateFingerprints").replaceAll(":","").toUpperCase()).map((w)=>{if(!$w.test(w))throw TypeError("mobile.deepLinks.android.sha256CertificateFingerprints entries must be SHA-256 certificate fingerprints.");return w.match(/.{2}/g)?.join(":")??w}))].sort(),Tb=(b,w)=>{let $=V(b.appId,"mobile.appId");if(!ob.test($))throw TypeError("mobile.appId must use reverse-domain notation, for example com.example.app.");let A=Mw(b.server.productionOrigin),S=(b.deepLinks?.scheme??$).trim().toLowerCase();if(S&&!bw.test(S))throw TypeError("mobile.deepLinks.scheme is not a valid URL scheme.");return{androidCertificateFingerprints:Jw(b.deepLinks?.android?.sha256CertificateFingerprints),appId:$,appleAppIdPrefix:Dw(b.deepLinks?.apple?.appIdPrefix),appName:V(b.appName,"mobile.appName"),bundleDirectory:s(w,b.bundleDirectory??".absolutejs/mobile/web","mobile.bundleDirectory"),deepLinkHosts:Cw(b.deepLinks?.hosts,A),deepLinkScheme:S,engine:"capacitor",entry:Sw(b.entry),iosVersion:xw(b.ios?.version),nativeProjectDirectory:s(w,b.nativeProject?.directory??"mobile","mobile.nativeProject.directory"),platforms:Ow(b.platforms),productionOrigin:A,pushAndroidGoogleServicesFile:s(w,b.pushNotifications?.android?.googleServicesFile??"google-services.json","mobile.pushNotifications.android.googleServicesFile")}};import{createHash as mb,randomUUID as dw}from"crypto";import{access as jw,copyFile as kb,mkdir as z,readFile as a,rename as uw,rm as o,writeFile as L}from"fs/promises";import{isIP as cw}from"net";import{dirname as hb,isAbsolute as vw,join as X,relative as aw,resolve as r,sep as rw}from"path";import{access as Tw}from"fs/promises";import{homedir as Ub}from"os";import{join as P}from"path";import{existsSync as i$,readFileSync as Nw}from"fs";var l=1000;var Wb=60000;var n=2;var u=(b)=>{let w;if(b<l)w=`${b.toFixed(n)}ms`;else if(b<Wb)w=`${(b/l).toFixed(n)}s`;else{let $=Math.round(b/l),A=Math.floor($/60),S=$%60;w=S===0?`${A}m`:`${A}m ${S}s`}return w};var Kb=()=>{try{let b=Nw("/proc/version","utf-8");return/microsoft|wsl/i.test(b)}catch{return!1}};var Xb="AbsoluteJS_API_36",Ww=(b)=>{try{let w=Bun.spawnSync(b,{stderr:"ignore",stdout:"pipe"});return{exitCode:w.exitCode,stdout:w.stdout.toString()}}catch{return{exitCode:1,stdout:""}}},Kw=(b)=>{try{let w=JSON.parse(b);if(typeof w!=="object"||w===null)return!1;let $=Reflect.get(w,"runtimes");if(!Array.isArray($))return!1;return $.some((A)=>typeof A==="object"&&A!==null&&Reflect.get(A,"isAvailable")===!0&&typeof Reflect.get(A,"identifier")==="string"&&String(Reflect.get(A,"identifier")).includes("iOS"))}catch{return!1}},Uw=(b)=>{let w=/^([a-z]):[\\/](.*)$/i.exec(b.trim());if(!w)return b.trim().replaceAll("\\","/");return`/mnt/${w[1]?.toLowerCase()}/${w[2]?.replaceAll("\\","/")}`},Xw=()=>{try{let b=Bun.spawnSync(["cmd.exe","/d","/c","echo","%LOCALAPPDATA%"],{stderr:"ignore",stdout:"pipe"});if(b.exitCode!==0)return;let w=b.stdout.toString().trim();if(!w||w==="%LOCALAPPDATA%")return;return Uw(w)}catch{return}},_w=(b,w=process.env)=>{if(b==="windows")return P(w.LOCALAPPDATA??P(Ub(),"AppData","Local"),"AbsoluteJS","Android","Sdk");if(b==="wsl"){let $=Xw();if($)return P($,"AbsoluteJS","Android","Sdk")}return P(Ub(),".absolutejs","android-sdk")},Bw=async(b)=>{try{return await Tw(b),!0}catch{return!1}},c=(b=process.platform,w=Kb())=>{if(b==="darwin")return"macos";if(b==="win32")return"windows";if(b==="linux"&&w)return"wsl";return"linux"},Fw=(b,w)=>{if(b==="wsl")return[`${w}.exe`,`${w}.bat`,w];if(b==="windows")return[w,`${w}.exe`,`${w}.bat`];return[w]},Q=async(b,w,$,A)=>{let M=(await Promise.all(w.map(async(O)=>await $.exists(O)?O:void 0))).find((O)=>O!==void 0);if(M)return M;for(let O of Fw(A,b)){let D=$.which(O);if(D)return D}return},Z=(b,w,$,A,S)=>A?{id:b,label:w,path:A,platform:$,status:"pass"}:{id:b,label:w,platform:$,remediation:S,status:"fail"},_b=async(b={})=>{let w=b.env??process.env,$=b.host??c(),A=b.exists??Bw,S=b.which??((U)=>Bun.which(U)),M=b.capture??Ww,O=b.androidRoot===null?void 0:b.androidRoot??w.ANDROID_HOME??w.ANDROID_SDK_ROOT??_w($,w),D=$==="windows"||$==="wsl",C=(U)=>O?P(O,...U):void 0,J=(U)=>U.filter((K)=>Boolean(K)),_=await Q("adb",J([C(["platform-tools",D?"adb.exe":"adb"])]),{exists:A,which:S},$),T=await Q("emulator",J([C(["emulator",D?"emulator.exe":"emulator"])]),{exists:A,which:S},$),W=await Q("sdkmanager",J([C(["cmdline-tools","latest","bin",D?"sdkmanager.bat":"sdkmanager"])]),{exists:A,which:S},$),F=await Q("avdmanager",J([C(["cmdline-tools","latest","bin",D?"avdmanager.bat":"avdmanager"])]),{exists:A,which:S},$),x=await Q("java",[],{exists:A,which:S},$),N=[{id:"host",label:`Development host: ${$}`,platform:"host",status:"pass"},Z("android.adb","Android Debug Bridge","android",_,"Install Android SDK Platform Tools or expose adb on PATH."),Z("android.emulator","Android Emulator","android",T,"Install the Android Emulator from Android Studio SDK Manager."),Z("android.sdkmanager","Android SDK Manager","android",W,"Install Android SDK Command-line Tools (latest)."),Z("android.avdmanager","Android Virtual Device Manager","android",F,"Install Android SDK Command-line Tools (latest)."),Z("android.java","Java runtime","android",x,"Install the JDK required by the configured Android Gradle plugin.")];if(T){let U=M([T,"-list-avds"]),K=U.exitCode===0&&U.stdout.split(/\r?\n/).includes(Xb);N.push({id:"android.avd",label:`AbsoluteJS Android emulator (${Xb})`,platform:"android",remediation:K?void 0:"Run absolute mobile doctor android --fix to provision the managed emulator.",status:K?"pass":"fail"})}if($==="wsl")N.push({id:"android.virtualization",label:_?.endsWith(".exe")?"Windows-host Android bridge available to WSL":"WSL requires a Windows-host emulator bridge or Linux KVM",platform:"android",remediation:_?.endsWith(".exe")?void 0:"Expose the Windows Android SDK adb.exe to WSL, or enable /dev/kvm for a Linux SDK.",status:_?.endsWith(".exe")?"pass":"warn"});else if($==="linux"){let U=await A("/dev/kvm");N.push({id:"android.virtualization",label:"Linux KVM acceleration",platform:"android",remediation:U?void 0:"Enable KVM and grant the current user access to /dev/kvm.",status:U?"pass":"warn"})}if($!=="macos")return N.push({id:"ios.simulator",label:"iOS Simulator requires macOS and Xcode",platform:"ios",status:"skip"}),N;let B=await Q("xcrun",[],{exists:A,which:S},$),E=await Q("xcodebuild",[],{exists:A,which:S},$);if(N.push(Z("ios.xcrun","Xcode command runner","ios",B,"Install Xcode and select it with xcode-select."),Z("ios.xcodebuild","Xcode build system","ios",E,"Install Xcode and select it with xcode-select.")),B){let U=M([B,"simctl","list","runtimes","--json"]),K=U.exitCode===0&&Kw(U.stdout);N.push({id:"ios.runtime",label:"iOS Simulator runtime",platform:"ios",remediation:K?void 0:"Run absolute mobile doctor ios --fix to download an iOS Simulator runtime.",status:K?"pass":"fail"})}return N};import{access as Gw,readFile as Hw,rename as Iw,writeFile as Vw}from"fs/promises";import{relative as Yw,resolve as Bb}from"path";var Fb="capacitor.config.ts",i=(b,w)=>Yw(b,w).replaceAll("\\","/"),Ew=(b,w)=>`import type { CapacitorConfig } from '@capacitor/cli';
2
+ import{mkdir as k$,readFile as q$,rm as rb,writeFile as z$}from"fs/promises";import{join as Ob}from"path";import{createInterface as y$}from"readline";import{resolve as Nb}from"path";var ob=/^[A-Za-z][\w]*(?:\.[A-Za-z][\w]*)+$/,bw=/^[a-z][a-z0-9+.-]*$/,ww=/^[A-Z0-9]{10}$/,$w=/^[0-9A-F]{64}$/,Aw=/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(?:\.(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?))*$/,n=(b,w,$)=>{let A=Nb(b),S=Nb(A,w);if(S!==A&&!S.startsWith(`${A}/`))throw TypeError(`${$} must remain inside the project root.`);return S},V=(b,w)=>{let $=b.trim();if(!$)throw TypeError(`${w} must not be empty.`);return $},Sw=(b)=>{let w=V(b??"/","mobile.entry");if(!w.startsWith("/")||w.startsWith("//"))throw TypeError("mobile.entry must be an absolute application path.");return w},Mw=(b)=>{let w=new URL(V(b,"mobile.server.productionOrigin")),$=w.protocol==="http:"&&(w.hostname==="localhost"||w.hostname==="127.0.0.1"||w.hostname==="[::1]");if(w.protocol!=="https:"&&!$)throw TypeError("mobile.server.productionOrigin must use HTTPS, except for a loopback development origin.");if(w.username||w.password||w.pathname!=="/"||w.search||w.hash)throw TypeError("mobile.server.productionOrigin must be an origin without credentials, path, query, or hash.");return w.origin},Ow=(b)=>{let w=[...new Set(b??["ios","android"])];if(w.length===0)throw TypeError("mobile.platforms must contain at least one platform.");return w},Cw=(b,w)=>{let $=(M)=>{let O=V(M,"mobile.deepLinks.hosts").toLowerCase();if(!Aw.test(O))throw TypeError("mobile.deepLinks.hosts entries must be valid hostnames without ports, wildcards, or paths.");return O},A=new URL(w).hostname,S=new Set(A==="[::1]"?[]:[$(A)]);for(let M of b??[])S.add($(M));return[...S].sort()},Dw=(b)=>{if(b===void 0)return;let w=V(b,"mobile.deepLinks.apple.appIdPrefix").toUpperCase();if(!ww.test(w))throw TypeError("mobile.deepLinks.apple.appIdPrefix must contain ten letters or digits.");return w},xw=(b)=>{if(b===void 0)return;let w=V(b,"mobile.ios.version");if(!/^\d+(?:\.\d+){0,2}$/u.test(w))throw TypeError("mobile.ios.version must contain one to three dot-separated integer components, for example 1.4.0.");return w},Jw=(b)=>[...new Set((b??[]).map((w)=>V(w,"mobile.deepLinks.android.sha256CertificateFingerprints").replaceAll(":","").toUpperCase()).map((w)=>{if(!$w.test(w))throw TypeError("mobile.deepLinks.android.sha256CertificateFingerprints entries must be SHA-256 certificate fingerprints.");return w.match(/.{2}/g)?.join(":")??w}))].sort(),Tb=(b,w)=>{let $=V(b.appId,"mobile.appId");if(!ob.test($))throw TypeError("mobile.appId must use reverse-domain notation, for example com.example.app.");let A=Mw(b.server.productionOrigin),S=(b.deepLinks?.scheme??$).trim().toLowerCase();if(S&&!bw.test(S))throw TypeError("mobile.deepLinks.scheme is not a valid URL scheme.");return{androidCertificateFingerprints:Jw(b.deepLinks?.android?.sha256CertificateFingerprints),appId:$,appleAppIdPrefix:Dw(b.deepLinks?.apple?.appIdPrefix),appName:V(b.appName,"mobile.appName"),bundleDirectory:n(w,b.bundleDirectory??".absolutejs/mobile/web","mobile.bundleDirectory"),deepLinkHosts:Cw(b.deepLinks?.hosts,A),deepLinkScheme:S,engine:"capacitor",entry:Sw(b.entry),iosVersion:xw(b.ios?.version),nativeProjectDirectory:n(w,b.nativeProject?.directory??"mobile","mobile.nativeProject.directory"),platforms:Ow(b.platforms),productionOrigin:A,pushAndroidGoogleServicesFile:n(w,b.pushNotifications?.android?.googleServicesFile??"google-services.json","mobile.pushNotifications.android.googleServicesFile")}};import{createHash as mb,randomUUID as dw}from"crypto";import{access as jw,copyFile as kb,mkdir as z,readFile as a,rename as uw,rm as bb,writeFile as L}from"fs/promises";import{isIP as cw}from"net";import{dirname as hb,isAbsolute as vw,join as X,relative as aw,resolve as r,sep as rw}from"path";import{access as Tw}from"fs/promises";import{homedir as Kb}from"os";import{join as m}from"path";import{existsSync as i$,readFileSync as Nw}from"fs";var l=1000;var Wb=60000;var i=2;var P=(b)=>{let w;if(b<l)w=`${b.toFixed(i)}ms`;else if(b<Wb)w=`${(b/l).toFixed(i)}s`;else{let $=Math.round(b/l),A=Math.floor($/60),S=$%60;w=S===0?`${A}m`:`${A}m ${S}s`}return w};var Ub=()=>{try{let b=Nw("/proc/version","utf-8");return/microsoft|wsl/i.test(b)}catch{return!1}};var Xb="AbsoluteJS_API_36",Ww=(b)=>{try{let w=Bun.spawnSync(b,{stderr:"ignore",stdout:"pipe"});return{exitCode:w.exitCode,stdout:w.stdout.toString()}}catch{return{exitCode:1,stdout:""}}},Uw=(b)=>{try{let w=JSON.parse(b);if(typeof w!=="object"||w===null)return!1;let $=Reflect.get(w,"runtimes");if(!Array.isArray($))return!1;return $.some((A)=>typeof A==="object"&&A!==null&&Reflect.get(A,"isAvailable")===!0&&typeof Reflect.get(A,"identifier")==="string"&&String(Reflect.get(A,"identifier")).includes("iOS"))}catch{return!1}},Kw=(b)=>{let w=/^([a-z]):[\\/](.*)$/i.exec(b.trim());if(!w)return b.trim().replaceAll("\\","/");return`/mnt/${w[1]?.toLowerCase()}/${w[2]?.replaceAll("\\","/")}`},Xw=()=>{try{let b=Bun.spawnSync(["cmd.exe","/d","/c","echo","%LOCALAPPDATA%"],{stderr:"ignore",stdout:"pipe"});if(b.exitCode!==0)return;let w=b.stdout.toString().trim();if(!w||w==="%LOCALAPPDATA%")return;return Kw(w)}catch{return}},_w=(b,w=process.env)=>{if(b==="windows")return m(w.LOCALAPPDATA??m(Kb(),"AppData","Local"),"AbsoluteJS","Android","Sdk");if(b==="wsl"){let $=Xw();if($)return m($,"AbsoluteJS","Android","Sdk")}return m(Kb(),".absolutejs","android-sdk")},Bw=async(b)=>{try{return await Tw(b),!0}catch{return!1}},c=(b=process.platform,w=Ub())=>{if(b==="darwin")return"macos";if(b==="win32")return"windows";if(b==="linux"&&w)return"wsl";return"linux"},Fw=(b,w)=>{if(b==="wsl")return[`${w}.exe`,`${w}.bat`,w];if(b==="windows")return[w,`${w}.exe`,`${w}.bat`];return[w]},Q=async(b,w,$,A)=>{let M=(await Promise.all(w.map(async(O)=>await $.exists(O)?O:void 0))).find((O)=>O!==void 0);if(M)return M;for(let O of Fw(A,b)){let D=$.which(O);if(D)return D}return},Z=(b,w,$,A,S)=>A?{id:b,label:w,path:A,platform:$,status:"pass"}:{id:b,label:w,platform:$,remediation:S,status:"fail"},_b=async(b={})=>{let w=b.env??process.env,$=b.host??c(),A=b.exists??Bw,S=b.which??((K)=>Bun.which(K)),M=b.capture??Ww,O=b.androidRoot===null?void 0:b.androidRoot??w.ANDROID_HOME??w.ANDROID_SDK_ROOT??_w($,w),D=$==="windows"||$==="wsl",C=(K)=>O?m(O,...K):void 0,J=(K)=>K.filter((U)=>Boolean(U)),_=await Q("adb",J([C(["platform-tools",D?"adb.exe":"adb"])]),{exists:A,which:S},$),T=await Q("emulator",J([C(["emulator",D?"emulator.exe":"emulator"])]),{exists:A,which:S},$),W=await Q("sdkmanager",J([C(["cmdline-tools","latest","bin",D?"sdkmanager.bat":"sdkmanager"])]),{exists:A,which:S},$),F=await Q("avdmanager",J([C(["cmdline-tools","latest","bin",D?"avdmanager.bat":"avdmanager"])]),{exists:A,which:S},$),x=await Q("java",[],{exists:A,which:S},$),N=[{id:"host",label:`Development host: ${$}`,platform:"host",status:"pass"},Z("android.adb","Android Debug Bridge","android",_,"Install Android SDK Platform Tools or expose adb on PATH."),Z("android.emulator","Android Emulator","android",T,"Install the Android Emulator from Android Studio SDK Manager."),Z("android.sdkmanager","Android SDK Manager","android",W,"Install Android SDK Command-line Tools (latest)."),Z("android.avdmanager","Android Virtual Device Manager","android",F,"Install Android SDK Command-line Tools (latest)."),Z("android.java","Java runtime","android",x,"Install the JDK required by the configured Android Gradle plugin.")];if(T){let K=M([T,"-list-avds"]),U=K.exitCode===0&&K.stdout.split(/\r?\n/).includes(Xb);N.push({id:"android.avd",label:`AbsoluteJS Android emulator (${Xb})`,platform:"android",remediation:U?void 0:"Run absolute mobile doctor android --fix to provision the managed emulator.",status:U?"pass":"fail"})}if($==="wsl")N.push({id:"android.virtualization",label:_?.endsWith(".exe")?"Windows-host Android bridge available to WSL":"WSL requires a Windows-host emulator bridge or Linux KVM",platform:"android",remediation:_?.endsWith(".exe")?void 0:"Expose the Windows Android SDK adb.exe to WSL, or enable /dev/kvm for a Linux SDK.",status:_?.endsWith(".exe")?"pass":"warn"});else if($==="linux"){let K=await A("/dev/kvm");N.push({id:"android.virtualization",label:"Linux KVM acceleration",platform:"android",remediation:K?void 0:"Enable KVM and grant the current user access to /dev/kvm.",status:K?"pass":"warn"})}if($!=="macos")return N.push({id:"ios.simulator",label:"iOS Simulator requires macOS and Xcode",platform:"ios",status:"skip"}),N;let B=await Q("xcrun",[],{exists:A,which:S},$),E=await Q("xcodebuild",[],{exists:A,which:S},$);if(N.push(Z("ios.xcrun","Xcode command runner","ios",B,"Install Xcode and select it with xcode-select."),Z("ios.xcodebuild","Xcode build system","ios",E,"Install Xcode and select it with xcode-select.")),B){let K=M([B,"simctl","list","runtimes","--json"]),U=K.exitCode===0&&Uw(K.stdout);N.push({id:"ios.runtime",label:"iOS Simulator runtime",platform:"ios",remediation:U?void 0:"Run absolute mobile doctor ios --fix to download an iOS Simulator runtime.",status:U?"pass":"fail"})}return N};import{access as Gw,readFile as Iw,rename as Hw,writeFile as Vw}from"fs/promises";import{relative as Yw,resolve as Bb}from"path";var Fb="capacitor.config.ts",p=(b,w)=>Yw(b,w).replaceAll("\\","/"),Ew=(b,w)=>`import type { CapacitorConfig } from '@capacitor/cli';
3
3
 
4
4
  const config: CapacitorConfig = {
5
5
  appId: ${JSON.stringify(b.appId)},
6
6
  appName: ${JSON.stringify(b.appName)},
7
- webDir: ${JSON.stringify(i(w,b.bundleDirectory))},
7
+ webDir: ${JSON.stringify(p(w,b.bundleDirectory))},
8
8
  android: {
9
- path: ${JSON.stringify(i(w,`${b.nativeProjectDirectory}/android`))}
9
+ path: ${JSON.stringify(p(w,`${b.nativeProjectDirectory}/android`))}
10
10
  },
11
11
  ios: {
12
- path: ${JSON.stringify(i(w,`${b.nativeProjectDirectory}/ios`))}
12
+ path: ${JSON.stringify(p(w,`${b.nativeProjectDirectory}/ios`))}
13
13
  }
14
14
  };
15
15
 
16
16
  export default config;
17
- `,Qw=async(b)=>{try{return await Gw(b),!0}catch{return!1}},Gb=async(b,w)=>{let $=Bb(w.projectRoot),A=Bb($,Fb),S=Ew(b,$);if(await Qw(A)){if(await Hw(A,"utf8")===S)return{changed:!1,path:A};if(!w.force)throw TypeError(`${Fb} already exists and differs; rerun with --force only after reviewing it.`)}let M=`${A}.${crypto.randomUUID()}.tmp`;return await Vw(M,S,{flag:"wx"}),await Iw(M,A),{changed:!0,path:A}};import{createHash as Zw}from"crypto";import{access as xA,copyFile as JA,mkdir as NA,mkdtemp as TA,readdir as Lw,readFile as kw,rename as WA,rm as KA,stat as UA,writeFile as XA}from"fs/promises";import{dirname as BA,isAbsolute as FA,join as qw,relative as Hb,resolve as GA,sep as HA}from"path";var zw=new Set(["Pods","DerivedData","build","xcuserdata"]),Ib=async(b,w=b)=>{let $=await Lw(w,{withFileTypes:!0});return(await Promise.all($.sort((S,M)=>S.name.localeCompare(M.name)).map(async(S)=>{let M=qw(w,S.name),O=Hb(b,M).replaceAll("\\","/");if(S.isDirectory()&&(zw.has(S.name)||O==="App/App/public"))return[];if(S.isDirectory())return Ib(b,M);return S.isFile()?[M]:[]}))).flat()},Vb=async(b)=>{let w=Zw("sha256"),$=await Ib(b),A=await Promise.all($.map((S)=>kw(S)));return $.forEach((S,M)=>{w.update(Hb(b,S).replaceAll("\\","/")),w.update("\x00"),w.update(A[M]??new Uint8Array),w.update("\x00")}),w.digest("hex")};import{randomUUID as yw,X509Certificate as Rw}from"crypto";import{createServer as fw}from"http";import{connect as lw,createServer as Yb,isIP as Pw}from"net";import{readFile as mw}from"fs/promises";var p=(b)=>new Promise((w,$)=>{b.close((A)=>{if(A)$(A);else w()})}),Eb=(b,w)=>new Promise(($,A)=>{b.once("error",A),b.listen(w,"0.0.0.0",()=>{b.off("error",A);let S=b.address();if(!S||typeof S==="string"){A(Error("Could not determine the iOS device helper port."));return}$(S.port)})}),hw=async()=>{let b=Yb(),w=await new Promise(($,A)=>{b.once("error",A),b.listen(0,"127.0.0.1",()=>{let S=b.address();if(!S||typeof S==="string"){A(Error("Could not allocate the iOS CA enrollment port."));return}$(S.port)})});return await p(b),w},t=(b)=>{let w=b.trim();if(!w||w.length>253||/[\0\s/?#]/u.test(w))throw TypeError("Physical iOS development requires a valid LAN host.");return w},Qb=(b)=>{let w=b.trim();if(!w||w.length>256||/[\0\r\n]/u.test(w))throw TypeError("--ios-device requires a valid Xcode device identifier or name.");return w},gw=(b,w,$)=>{let A=new URL(`${b}://localhost:${$}`),S=t(w);return A.hostname=Pw(S)===6?`[${S}]`:S,A},Zb=async(b)=>{let $=new Rw(await mw(b.certificateAuthorityPath)).raw,S=`/${yw().replaceAll("-","")}/absolutejs-development-ca.cer`,M=fw((C,J)=>{if(C.method!=="GET"||C.url!==S){J.writeHead(404,{"Cache-Control":"no-store","Content-Type":"text/plain; charset=utf-8"}),J.end("Not found.");return}J.writeHead(200,{"Cache-Control":"no-store","Content-Disposition":'attachment; filename="absolutejs-development-ca.cer"',"Content-Length":String($.byteLength),"Content-Type":"application/x-x509-ca-cert","X-Content-Type-Options":"nosniff"}),J.end($)}),O=await hw();await Eb(M,O);let D=gw("http",b.displayHost,O);return D.pathname=S,{url:D.href,close:()=>p(M)}},Lb=async(b)=>{let w=Yb(($)=>{let A=lw({host:"127.0.0.1",port:b.targetPort});$.pipe(A),A.pipe($);let S=()=>{$.destroy(),A.destroy()};$.once("error",S),A.once("error",S)});return await Eb(w,b.listenPort),{close:()=>p(w)}};var e="AbsoluteJS iPhone",qb=180000,sw=1000,bb=1,wb=1,H=(b)=>typeof b==="object"&&b!==null&&!Array.isArray(b),Y=async(b)=>{try{return await jw(b),!0}catch{return!1}},q=(b)=>b?.throwIfAborted(),nw=(b,w={})=>{try{let $=Bun.spawnSync(b,{cwd:w.cwd,env:w.env,stderr:"pipe",stdin:"ignore",stdout:"pipe"});return{exitCode:$.exitCode,stderr:$.stderr.toString(),stdout:$.stdout.toString()}}catch($){return{exitCode:1,stderr:$ instanceof Error?$.message:String($),stdout:""}}},gb=async(b,w={})=>{return Bun.spawn(b,{cwd:w.cwd,env:w.env,signal:w.signal,stderr:"inherit",stdin:"inherit",stdout:"inherit"}).exited},iw=(b,w={})=>{Bun.spawn(b,{cwd:w.cwd,env:w.env,signal:w.signal,stderr:"ignore",stdin:"ignore",stdout:"ignore"})},zb=async(b,w)=>{let $=b.getReader(),A=new TextDecoder,S="",M=async()=>{let{done:O,value:D}=await $.read();if(O)return;S+=A.decode(D,{stream:!0});let C=S.split(/\r?\n/u);S=C.pop()??"",C.forEach(w),await M()};try{if(await M(),S+=A.decode(),S)w(S)}finally{$.releaseLock()}},pw=(b,w,$)=>{let A=Bun.spawn(b,{cwd:w.cwd,env:w.env,signal:w.signal,stderr:"pipe",stdin:"ignore",stdout:"pipe"});return zb(A.stdout,$),zb(A.stderr,$),{close:async()=>{try{A.kill()}catch{}await A.exited.catch(()=>{return})}}},G=async(b,w,$,A)=>{let S=await $(b,A);if(S!==0)throw Error(`${w} failed with status ${S}.`)},tw=async(b,w,$,A)=>{if(!b.https)return;if(!b.certificateAuthorityPath)throw Error("iOS Simulator HTTPS requires the AbsoluteJS development CA certificate.");await G([b.project.xcrun,"simctl","keychain",w,"add-root-cert",b.certificateAuthorityPath],"iOS Simulator development CA trust",$,{signal:b.signal}),A("Installed the AbsoluteJS development CA into this iOS Simulator trust store.")},yb=(b,w,$)=>$?[b.xcrun,"devicectl","device","process","launch","--terminate-existing","--device",w,b.config.appId]:[b.xcrun,"simctl","launch","--terminate-running-process",w,b.config.appId],h=(b,w)=>{if(b.exitCode!==0)throw Error(`${w} failed: ${b.stderr.trim()||b.stdout.trim()||`status ${b.exitCode}`}`);return b.stdout.trim()},$b=(b,w)=>{try{let $=JSON.parse(b);if(H($))return $}catch{}throw Error(`Invalid ${w} JSON from simctl.`)},ew=(b)=>{let $=$b(b,"device type").devicetypes;if(!Array.isArray($))return[];return $.flatMap((A)=>{if(!H(A))return[];let{identifier:S}=A,{name:M}=A;return typeof S==="string"&&typeof M==="string"?[{identifier:S,name:M}]:[]})},ow=(b)=>{let w=$b(b,"runtime"),{runtimes:$}=w;if(!Array.isArray($))return[];return $.flatMap((A)=>{if(!H(A))return[];let{identifier:S}=A,{name:M}=A,{version:O}=A;if(typeof S!=="string"||typeof M!=="string"||typeof O!=="string")return[];return[{identifier:S,isAvailable:A.isAvailable!==!1,name:M,version:O}]})},b$=(b)=>{let w=$b(b,"device"),{devices:$}=w;if(!H($))return[];return Object.entries($).flatMap(([A,S])=>{if(!Array.isArray(S))return[];return S.flatMap((M)=>{if(!H(M))return[];let{name:O}=M,{state:D}=M,{udid:C}=M;if(typeof O!=="string"||typeof D!=="string"||typeof C!=="string")return[];return[{isAvailable:M.isAvailable!==!1,name:O,runtime:A,state:D,udid:C}]})})},Rb=(b)=>b.split(".").map((w)=>Number(w)),w$=(b,w)=>{let $=Rb(b),A=Rb(w),S=Math.max($.length,A.length);for(let M=0;M<S;M++){let O=($[M]??0)-(A[M]??0);if(O!==0)return O}return 0},$$=(b)=>b.filter((w)=>w.isAvailable&&w.identifier.includes("SimRuntime.iOS-")).sort((w,$)=>w$($.version,w.version))[0],fb=(b)=>Number(/iPhone\s+(\d+)/u.exec(b)?.[1]??0),A$=(b)=>b.filter((w)=>w.name.startsWith("iPhone")).sort((w,$)=>{let A=fb($.name)-fb(w.name);if(A!==0)return A;let S=$.name.includes("Pro")?1:0,M=w.name.includes("Pro")?1:0;return S-M})[0],db=(b)=>{let w=X(b,".absolutejs","mobile","ios-dev-session");return{configBackup:X(w,"capacitor-config.backup"),infoBackup:X(w,"Info.plist.backup"),journal:X(w,"journal.json"),root:w}},jb=(b)=>X(b,".absolutejs","mobile","ios-native-cache.json"),m=(b,w)=>{let $=aw(r(b),r(w));return $===""||!$.startsWith(`..${rw}`)&&$!==".."&&!vw($)},S$=(b)=>{if(!H(b)||b.format!==bb)return null;let{configBackupPath:w}=b,{infoBackupPath:$}=b,{infoPath:A}=b,{nativeConfigPath:S}=b;if(typeof w!=="string"||typeof $!=="string"||typeof A!=="string"||typeof S!=="string")return null;return{configBackupPath:w,format:bb,infoBackupPath:$,infoPath:A,nativeConfigPath:S}},v=async(b)=>{let w=db(b);if(!await Y(w.journal))return await o(w.root,{force:!0,recursive:!0}),!1;let $=await a(w.journal,"utf8").then((A)=>S$(JSON.parse(A))).catch(()=>null);if(!$||!m(b,$.nativeConfigPath)||!m(b,$.infoPath)||!m(w.root,$.configBackupPath)||!m(w.root,$.infoBackupPath))throw Error(`Refusing unsafe or invalid iOS dev journal at ${w.journal}.`);if(await Y($.configBackupPath))await kb($.configBackupPath,$.nativeConfigPath);if(await Y($.infoBackupPath))await kb($.infoBackupPath,$.infoPath);return await o(w.root,{force:!0,recursive:!0}),!0},M$=(b,w)=>{if(!w)return b;let $=/(<key>NSAllowsArbitraryLoads<\/key>\s*)<false\s*\/>/u;if($.test(b))return b.replace($,"$1<true/>");if(/<key>NSAllowsArbitraryLoads<\/key>\s*<true\s*\/>/u.test(b))return b;let A=/(<key>NSAppTransportSecurity<\/key>\s*<dict>)/u;if(A.test(b))return b.replace(A,`$1
17
+ `,Qw=async(b)=>{try{return await Gw(b),!0}catch{return!1}},Gb=async(b,w)=>{let $=Bb(w.projectRoot),A=Bb($,Fb),S=Ew(b,$);if(await Qw(A)){if(await Iw(A,"utf8")===S)return{changed:!1,path:A};if(!w.force)throw TypeError(`${Fb} already exists and differs; rerun with --force only after reviewing it.`)}let M=`${A}.${crypto.randomUUID()}.tmp`;return await Vw(M,S,{flag:"wx"}),await Hw(M,A),{changed:!0,path:A}};import{createHash as Zw}from"crypto";import{access as xA,copyFile as JA,mkdir as NA,mkdtemp as TA,readdir as Lw,readFile as kw,rename as WA,rm as UA,stat as KA,writeFile as XA}from"fs/promises";import{dirname as BA,isAbsolute as FA,join as qw,relative as Ib,resolve as GA,sep as IA}from"path";var zw=new Set(["Pods","DerivedData","build","xcuserdata"]),Hb=async(b,w=b,$={})=>{let A=await Lw(w,{withFileTypes:!0});return(await Promise.all(A.sort((M,O)=>M.name.localeCompare(O.name)).map(async(M)=>{let O=qw(w,M.name),D=Ib(b,O).replaceAll("\\","/");if(M.isDirectory()&&(zw.has(M.name)||D==="App/App/public"&&$.includePublicBundle!==!0))return[];if(M.isDirectory())return Hb(b,O,$);return M.isFile()?[O]:[]}))).flat()},Vb=async(b,w={})=>{let $=Zw("sha256"),A=await Hb(b,b,w),S=await Promise.all(A.map((M)=>kw(M)));return A.forEach((M,O)=>{$.update(Ib(b,M).replaceAll("\\","/")),$.update("\x00"),$.update(S[O]??new Uint8Array),$.update("\x00")}),$.digest("hex")};import{randomUUID as yw,X509Certificate as Rw}from"crypto";import{createServer as fw}from"http";import{connect as lw,createServer as Yb,isIP as Pw}from"net";import{readFile as mw}from"fs/promises";var t=(b)=>new Promise((w,$)=>{b.close((A)=>{if(A)$(A);else w()})}),Eb=(b,w)=>new Promise(($,A)=>{b.once("error",A),b.listen(w,"0.0.0.0",()=>{b.off("error",A);let S=b.address();if(!S||typeof S==="string"){A(Error("Could not determine the iOS device helper port."));return}$(S.port)})}),hw=async()=>{let b=Yb(),w=await new Promise(($,A)=>{b.once("error",A),b.listen(0,"127.0.0.1",()=>{let S=b.address();if(!S||typeof S==="string"){A(Error("Could not allocate the iOS CA enrollment port."));return}$(S.port)})});return await t(b),w},e=(b)=>{let w=b.trim();if(!w||w.length>253||/[\0\s/?#]/u.test(w))throw TypeError("Physical iOS development requires a valid LAN host.");return w},Qb=(b)=>{let w=b.trim();if(!w||w.length>256||/[\0\r\n]/u.test(w))throw TypeError("--ios-device requires a valid Xcode device identifier or name.");return w},gw=(b,w,$)=>{let A=new URL(`${b}://localhost:${$}`),S=e(w);return A.hostname=Pw(S)===6?`[${S}]`:S,A},Zb=async(b)=>{let $=new Rw(await mw(b.certificateAuthorityPath)).raw,S=`/${yw().replaceAll("-","")}/absolutejs-development-ca.cer`,M=fw((C,J)=>{if(C.method!=="GET"||C.url!==S){J.writeHead(404,{"Cache-Control":"no-store","Content-Type":"text/plain; charset=utf-8"}),J.end("Not found.");return}J.writeHead(200,{"Cache-Control":"no-store","Content-Disposition":'attachment; filename="absolutejs-development-ca.cer"',"Content-Length":String($.byteLength),"Content-Type":"application/x-x509-ca-cert","X-Content-Type-Options":"nosniff"}),J.end($)}),O=await hw();await Eb(M,O);let D=gw("http",b.displayHost,O);return D.pathname=S,{url:D.href,close:()=>t(M)}},Lb=async(b)=>{let w=Yb(($)=>{let A=lw({host:"127.0.0.1",port:b.targetPort});$.pipe(A),A.pipe($);let S=()=>{$.destroy(),A.destroy()};$.once("error",S),A.once("error",S)});return await Eb(w,b.listenPort),{close:()=>t(w)}};var o="AbsoluteJS iPhone",qb=180000,sw=1000,wb=1,$b=1,I=(b)=>typeof b==="object"&&b!==null&&!Array.isArray(b),Y=async(b)=>{try{return await jw(b),!0}catch{return!1}},q=(b)=>b?.throwIfAborted(),nw=(b,w={})=>{try{let $=Bun.spawnSync(b,{cwd:w.cwd,env:w.env,stderr:"pipe",stdin:"ignore",stdout:"pipe"});return{exitCode:$.exitCode,stderr:$.stderr.toString(),stdout:$.stdout.toString()}}catch($){return{exitCode:1,stderr:$ instanceof Error?$.message:String($),stdout:""}}},gb=async(b,w={})=>{return Bun.spawn(b,{cwd:w.cwd,env:w.env,signal:w.signal,stderr:"inherit",stdin:"inherit",stdout:"inherit"}).exited},iw=(b,w={})=>{Bun.spawn(b,{cwd:w.cwd,env:w.env,signal:w.signal,stderr:"ignore",stdin:"ignore",stdout:"ignore"})},zb=async(b,w)=>{let $=b.getReader(),A=new TextDecoder,S="",M=async()=>{let{done:O,value:D}=await $.read();if(O)return;S+=A.decode(D,{stream:!0});let C=S.split(/\r?\n/u);S=C.pop()??"",C.forEach(w),await M()};try{if(await M(),S+=A.decode(),S)w(S)}finally{$.releaseLock()}},pw=(b,w,$)=>{let A=Bun.spawn(b,{cwd:w.cwd,env:w.env,signal:w.signal,stderr:"pipe",stdin:"ignore",stdout:"pipe"});return zb(A.stdout,$),zb(A.stderr,$),{close:async()=>{try{A.kill()}catch{}await A.exited.catch(()=>{return})}}},G=async(b,w,$,A)=>{let S=await $(b,A);if(S!==0)throw Error(`${w} failed with status ${S}.`)},tw=async(b,w,$,A)=>{if(!b.https)return;if(!b.certificateAuthorityPath)throw Error("iOS Simulator HTTPS requires the AbsoluteJS development CA certificate.");await G([b.project.xcrun,"simctl","keychain",w,"add-root-cert",b.certificateAuthorityPath],"iOS Simulator development CA trust",$,{signal:b.signal}),A("Installed the AbsoluteJS development CA into this iOS Simulator trust store.")},yb=(b,w,$)=>$?[b.xcrun,"devicectl","device","process","launch","--terminate-existing","--device",w,b.config.appId]:[b.xcrun,"simctl","launch","--terminate-running-process",w,b.config.appId],g=(b,w)=>{if(b.exitCode!==0)throw Error(`${w} failed: ${b.stderr.trim()||b.stdout.trim()||`status ${b.exitCode}`}`);return b.stdout.trim()},Ab=(b,w)=>{try{let $=JSON.parse(b);if(I($))return $}catch{}throw Error(`Invalid ${w} JSON from simctl.`)},ew=(b)=>{let $=Ab(b,"device type").devicetypes;if(!Array.isArray($))return[];return $.flatMap((A)=>{if(!I(A))return[];let{identifier:S}=A,{name:M}=A;return typeof S==="string"&&typeof M==="string"?[{identifier:S,name:M}]:[]})},ow=(b)=>{let w=Ab(b,"runtime"),{runtimes:$}=w;if(!Array.isArray($))return[];return $.flatMap((A)=>{if(!I(A))return[];let{identifier:S}=A,{name:M}=A,{version:O}=A;if(typeof S!=="string"||typeof M!=="string"||typeof O!=="string")return[];return[{identifier:S,isAvailable:A.isAvailable!==!1,name:M,version:O}]})},b$=(b)=>{let w=Ab(b,"device"),{devices:$}=w;if(!I($))return[];return Object.entries($).flatMap(([A,S])=>{if(!Array.isArray(S))return[];return S.flatMap((M)=>{if(!I(M))return[];let{name:O}=M,{state:D}=M,{udid:C}=M;if(typeof O!=="string"||typeof D!=="string"||typeof C!=="string")return[];return[{isAvailable:M.isAvailable!==!1,name:O,runtime:A,state:D,udid:C}]})})},Rb=(b)=>b.split(".").map((w)=>Number(w)),w$=(b,w)=>{let $=Rb(b),A=Rb(w),S=Math.max($.length,A.length);for(let M=0;M<S;M++){let O=($[M]??0)-(A[M]??0);if(O!==0)return O}return 0},$$=(b)=>b.filter((w)=>w.isAvailable&&w.identifier.includes("SimRuntime.iOS-")).sort((w,$)=>w$($.version,w.version))[0],fb=(b)=>Number(/iPhone\s+(\d+)/u.exec(b)?.[1]??0),A$=(b)=>b.filter((w)=>w.name.startsWith("iPhone")).sort((w,$)=>{let A=fb($.name)-fb(w.name);if(A!==0)return A;let S=$.name.includes("Pro")?1:0,M=w.name.includes("Pro")?1:0;return S-M})[0],db=(b)=>{let w=X(b,".absolutejs","mobile","ios-dev-session");return{configBackup:X(w,"capacitor-config.backup"),infoBackup:X(w,"Info.plist.backup"),journal:X(w,"journal.json"),root:w}},jb=(b)=>X(b,".absolutejs","mobile","ios-native-cache.json"),h=(b,w)=>{let $=aw(r(b),r(w));return $===""||!$.startsWith(`..${rw}`)&&$!==".."&&!vw($)},S$=(b)=>{if(!I(b)||b.format!==wb)return null;let{configBackupPath:w}=b,{infoBackupPath:$}=b,{infoPath:A}=b,{nativeConfigPath:S}=b;if(typeof w!=="string"||typeof $!=="string"||typeof A!=="string"||typeof S!=="string")return null;return{configBackupPath:w,format:wb,infoBackupPath:$,infoPath:A,nativeConfigPath:S}},v=async(b)=>{let w=db(b);if(!await Y(w.journal))return await bb(w.root,{force:!0,recursive:!0}),!1;let $=await a(w.journal,"utf8").then((A)=>S$(JSON.parse(A))).catch(()=>null);if(!$||!h(b,$.nativeConfigPath)||!h(b,$.infoPath)||!h(w.root,$.configBackupPath)||!h(w.root,$.infoBackupPath))throw Error(`Refusing unsafe or invalid iOS dev journal at ${w.journal}.`);if(await Y($.configBackupPath))await kb($.configBackupPath,$.nativeConfigPath);if(await Y($.infoBackupPath))await kb($.infoBackupPath,$.infoPath);return await bb(w.root,{force:!0,recursive:!0}),!0},M$=(b,w)=>{if(!w)return b;let $=/(<key>NSAllowsArbitraryLoads<\/key>\s*)<false\s*\/>/u;if($.test(b))return b.replace($,"$1<true/>");if(/<key>NSAllowsArbitraryLoads<\/key>\s*<true\s*\/>/u.test(b))return b;let A=/(<key>NSAppTransportSecurity<\/key>\s*<dict>)/u;if(A.test(b))return b.replace(A,`$1
18
18
  <key>NSAllowsArbitraryLoads</key>
19
19
  <true/>`);return b.replace(/<dict>/u,`<dict>
20
20
  <key>NSAppTransportSecurity</key>
21
21
  <dict>
22
22
  <key>NSAllowsArbitraryLoads</key>
23
23
  <true/>
24
- </dict>`)},O$=async(b,w,$,A="localhost")=>{let S=db(b.projectRoot);await v(b.projectRoot);let M=X(b.nativeDirectory,"App","App","capacitor.config.json"),O=X(b.nativeDirectory,"App","App","Info.plist"),[D,C]=await Promise.all([a(M,"utf8"),a(O,"utf8")]),J=JSON.parse(D);if(!H(J))throw Error(`Invalid Capacitor native config at ${M}.`);await z(S.root,{recursive:!0}),await Promise.all([L(S.configBackup,D,{flag:"wx"}),L(S.infoBackup,C,{flag:"wx"})]);let _={configBackupPath:S.configBackup,format:bb,infoBackupPath:S.infoBackup,infoPath:O,nativeConfigPath:M};await L(S.journal,`${JSON.stringify(_,null,"\t")}
25
- `,{flag:"wx"});let T=new URL(`${$?"https":"http"}://localhost:${w}${b.config.entry}`);T.hostname=cw(A)===6?`[${A}]`:A,T.searchParams.set("__absolute_target","capacitor-ios");let W=J.server;J.server={...H(W)?W:{},cleartext:!$,url:T.href},await Promise.all([L(M,`${JSON.stringify(J,null,"\t")}
26
- `),L(O,M$(C,!$))])},C$=(b)=>{if(!H(b))return null;let{appId:w,fingerprint:$,format:A,installations:S}=b;if(A!==wb||typeof w!=="string"||typeof $!=="string"||!H(S)||!Object.values(S).every((M)=>typeof M==="string"))return null;return{appId:w,fingerprint:$,format:A,installations:Object.fromEntries(Object.entries(S).map(([M,O])=>[M,String(O)]))}},D$=(b)=>a(jb(b),"utf8").then((w)=>C$(JSON.parse(w))).catch(()=>null),ub=async(b,w)=>{let $=jb(b),A=`${$}.${process.pid}.${dw()}.tmp`;await z(hb($),{recursive:!0});try{await L(A,`${JSON.stringify(w,null,"\t")}
27
- `,{flag:"wx"}),await uw(A,$)}finally{await o(A,{force:!0}).catch(()=>{return})}},x$=async(b)=>Vb(b.nativeDirectory),cb=(b,w)=>{let $=w([b,"simctl","list","devices","available","-j"]);return b$(h($,"iOS simulator discovery"))},J$=async(b,w)=>{let $=ow(h(w([b.xcrun,"simctl","list","runtimes","-j"]),"iOS runtime discovery")),A=$$($);if(!A)throw Error("No available iOS Simulator runtime. Run absolute mobile doctor ios --fix.");let[S]=cb(b.xcrun,w).filter((C)=>C.isAvailable&&C.name===e&&C.runtime===A.identifier).sort((C,J)=>Number(J.state==="Booted")-Number(C.state==="Booted"));if(S)return{created:!1,device:S};let M=ew(h(w([b.xcrun,"simctl","list","devicetypes","-j"]),"iOS device-type discovery")),O=A$(M);if(!O)throw Error("Xcode did not report an iPhone simulator type.");let[D]=h(w([b.xcrun,"simctl","create",e,O.identifier,A.identifier]),"iOS simulator creation").split(/\s/u);if(!D)throw Error("simctl did not return the created simulator UDID.");return{created:!0,device:{isAvailable:!0,name:e,runtime:A.identifier,state:"Shutdown",udid:D}}},N$=async(b,w,$,A,S)=>{let M=Date.now()+qb,O=async()=>{if(q(S),cb(b.xcrun,$).find((C)=>C.udid===w)?.state==="Booted")return;if(Date.now()>M)throw Error(`iOS simulator ${w} did not finish booting within ${qb/1000}s.`);await A(sw),await O()};return O()},T$=(b,w,$)=>{if(w.state==="Booted")return;h($([b.xcrun,"simctl","boot",w.udid]),"iOS simulator boot")},lb=(b,w,$)=>{let A=$([b.xcrun,"simctl","get_app_container",w,b.config.appId,"app"]);return A.exitCode===0&&A.stdout.trim()?A.stdout.trim():void 0},W$=(b,w,$)=>{let A=$([b.xcrun,"devicectl","device","info","details","--device",w]);if(A.exitCode!==0)throw Error(`Physical iOS device ${JSON.stringify(w)} is unavailable: ${A.stderr.trim()||A.stdout.trim()||"pair it in Xcode Device Hub, trust this Mac, unlock it, and enable Developer Mode."}`)},K$=(b,w,$)=>{let A=$([b.xcrun,"devicectl","device","info","apps","--device",w]);return A.exitCode===0&&A.stdout.includes(b.config.appId)},U$=async(b,w,$,A,S)=>{let M=X(b.projectRoot,".absolutejs","mobile","ios-derived-data",mb("sha256").update(b.config.appId).digest("hex").slice(0,16));await z(M,{recursive:!0}),await G([b.xcodebuild,"-workspace",X(b.nativeDirectory,"App","App.xcworkspace"),"-scheme","App","-configuration","Debug","-destination",`platform=iOS Simulator,id=${w}`,"-derivedDataPath",M,"build"],"iOS simulator build",A,{cwd:b.nativeDirectory,signal:S});let O=X(M,"Build","Products","Debug-iphonesimulator","App.app");if(!await Y(O))throw Error(`Xcode did not produce the simulator app at ${O}.`);return O},X$=async(b,w,$,A)=>{let S=X(b.projectRoot,".absolutejs","mobile","ios-derived-data",mb("sha256").update(b.config.appId).digest("hex").slice(0,16));await z(S,{recursive:!0}),await G([b.xcodebuild,"-workspace",X(b.nativeDirectory,"App","App.xcworkspace"),"-scheme","App","-configuration","Debug","-destination",`platform=iOS,id=${w}`,"-derivedDataPath",S,"-allowProvisioningUpdates","build"],"iOS physical-device build (configure automatic signing and a Development Team in Xcode if this is the first run)",$,{cwd:b.nativeDirectory,signal:A});let M=X(S,"Build","Products","Debug-iphoneos","App.app");if(!await Y(M))throw Error(`Xcode did not produce the physical-device app at ${M}.`);return M},_$=async(b)=>{if(b.cache?.appId===b.project.config.appId&&b.cache.fingerprint===b.fingerprint&&b.cache.installations[b.identifier]===b.fingerprint&&K$(b.project,b.identifier,b.capture))return b.log("iOS native app is unchanged on the selected physical device; skipped Xcode build and install."),!0;b.log("iOS native inputs changed or the physical-device install is stale; rebuilding."),b.transition("building");let $=await X$(b.project,b.identifier,b.run,b.signal);return q(b.signal),b.transition("installing"),await G([b.project.xcrun,"devicectl","device","install","app","--device",b.identifier,$],"iOS physical-device app installation",b.run,{signal:b.signal}),await ub(b.project.projectRoot,{appId:b.project.config.appId,fingerprint:b.fingerprint,format:wb,installations:{...b.cache?.appId===b.project.config.appId?b.cache.installations:{},[b.identifier]:b.fingerprint}}).catch((A)=>b.log(`iOS native cache could not be saved: ${A instanceof Error?A.message:String(A)}`)),!1},B$=async(b)=>{let w=lb(b.project,b.udid,b.capture);if(b.cache?.appId===b.project.config.appId&&b.cache.fingerprint===b.fingerprint&&w!==void 0&&b.cache.installations[b.udid]===w)return b.log(`iOS native app is unchanged on ${b.udid}; skipped Xcode build and install.`),!0;b.log("iOS native inputs changed or the installed app is stale; rebuilding."),b.transition("building");let A=await U$(b.project,b.udid,b.fingerprint,b.run,b.signal);q(b.signal),b.transition("installing"),await G([b.project.xcrun,"simctl","install",b.udid,A],"iOS simulator app installation",b.run,{signal:b.signal});let S=lb(b.project,b.udid,b.capture);if(S)await ub(b.project.projectRoot,{appId:b.project.config.appId,fingerprint:b.fingerprint,format:wb,installations:{[b.udid]:S}}).catch((M)=>b.log(`iOS native cache could not be saved: ${M instanceof Error?M.message:String(M)}`));return!1},F$=/((?:authorization|cookie|password|secret|token|oauth[_-]?code)\s*[:=]\s*)([^\s,;]+)/giu,G$=new RegExp(String.raw`\bBearer\s+[A-Za-z0-9._~+/-]+=*`,"giu"),H$=/\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/gu,I$=new RegExp(String.raw`\s(Debug|Info|Notice|Error|Fault)\s+.*?\[[^\]]+\]\s+\[([^\]]+)\]\s*(.*)$`,"iu"),V$=(b)=>{let w=Y$(b).trim();if(!w)return null;let $=I$.exec(w),A=$?.[1]?.toLowerCase();return{level:A==="debug"||A==="error"||A==="fault"||A==="notice"?A:"info",message:$?.[3]?.trim()||w,tag:$?.[2]?.trim()||"App"}},Y$=(b)=>b.replaceAll(G$,"Bearer [REDACTED]").replaceAll(H$,"[REDACTED_JWT]").replaceAll(F$,"$1[REDACTED]").replaceAll(/\p{C}/gu,""),Pb=(b,w,$)=>{if(!$.nativeLog)return null;let A=$.startNativeLogs??pw,S=$.deviceIdentifier?[b.xcrun,"devicectl","device","process","launch","--console","--terminate-existing","--device",w,b.config.appId]:[b.xcrun,"simctl","spawn",w,"log","stream","--style","compact","--level","debug","--predicate",'process == "App"'];return A(S,{signal:$.signal},(M)=>{let O=V$(M);if(O)$.nativeLog?.(O)})},E$=[["syncing","Capacitor sync"],["configuring","dev config"],["fingerprinting","fingerprint"],["booting","simulator"],["connecting","device ready"],["enrolling-trust","HTTPS trust"],["checking-native","app check"],["building","Xcode"],["installing","install"],["launching","launch"],["streaming-logs","logs"]],Q$=(b)=>E$.map(([w,$])=>{let A=b[w];return A===void 0?null:`${$} ${u(A)}`}).filter((w)=>w!==null).join(", "),vb=async(b,w)=>{if(c()!=="macos")throw Error("iOS development requires macOS and Xcode.");let $=w.target??"simulator",A=r(w.projectRoot),S=await _b({host:"macos"}),M=S.filter((T)=>T.platform==="ios"&&!($==="device"&&T.id==="ios.runtime")&&(T.status==="fail"||T.status==="warn"));if(M.length>0)throw Error(`iOS ${$} development is not ready: ${M.map(({label:T})=>T).join(", ")}.`);let O=S.find((T)=>T.id==="ios.xcrun")?.path,D=S.find((T)=>T.id==="ios.xcodebuild")?.path;if(!O||!D)throw Error("Xcode tools disappeared after readiness checks.");let C=X(A,"node_modules",".bin","cap");if(!await Y(C))throw Error("Capacitor CLI is not installed. Run absolute mobile init first.");await Gb(b,{projectRoot:A}),await z(b.bundleDirectory,{recursive:!0});let J=X(b.bundleDirectory,"index.html");if(!await Y(J))await L(J,`<!doctype html><title>AbsoluteJS mobile development</title>
28
- `);let _=X(b.nativeProjectDirectory,"ios");if(!await Y(_)){if(!w.createNativeProject)throw Error("iOS native project has not been created.");if(await(w.run??gb)([C,"add","ios"],{cwd:A})!==0)throw Error("Capacitor iOS project creation failed.")}return{cap:C,config:b,nativeDirectory:_,projectRoot:A,xcodebuild:D,xcrun:O}},Z$=async(b)=>{if(b.transition("connecting"),W$(b.project,b.deviceIdentifier,b.capture),!b.startOptions.https)return{caEnrollmentServer:null,startedSimulator:!1,udid:b.deviceIdentifier};if(!b.startOptions.certificateAuthorityPath)throw Error("Physical iOS HTTPS development requires the AbsoluteJS development CA certificate.");b.transition("enrolling-trust");let $=await(b.startOptions.startCaEnrollmentServer??Zb)({certificateAuthorityPath:b.startOptions.certificateAuthorityPath,displayHost:b.serverHost});return b.log(`On the iOS device, open ${$.url}, install the AbsoluteJS development CA profile, then enable it under Settings > General > About > Certificate Trust Settings. This public CA endpoint exists only for this dev session.`),{caEnrollmentServer:$,startedSimulator:!1,udid:b.deviceIdentifier}},L$=async(b)=>{b.transition("booting");let w=await J$(b.project,b.capture),{device:$}=w,A=w.created||$.state!=="Booted";return T$(b.project,$,b.capture),b.spawn(["open","-a","Simulator","--args","-CurrentDeviceUDID",$.udid]),b.transition("connecting"),await N$(b.project,$.udid,b.capture,b.sleep,b.startOptions.signal),await G([b.project.xcrun,"simctl","bootstatus",$.udid,"-b"],"iOS simulator boot readiness",b.run,{signal:b.startOptions.signal}),await tw(b.startOptions,$.udid,b.run,b.log),{caEnrollmentServer:null,startedSimulator:A,udid:$.udid}},Ab=async(b)=>{let{project:w}=b,$=b.deviceIdentifier?Qb(b.deviceIdentifier):void 0,A=$?"device":"simulator",S=$?t(b.serverHost??""):"localhost",M=b.capture??nw,O=b.run??gb,D=b.sleep??Bun.sleep,C=b.spawn??iw,J=b.log??console.log,_=performance.now(),T=performance.now(),W={},F="syncing",x=(K)=>{if(K===F){b.onStateChange?.(K);return}let R=performance.now(),g=R-T;W[F]=(W[F]??0)+g,b.onPhaseTiming?.({durationMs:g,phase:F,totalMs:R-_}),F=K,T=R,b.onStateChange?.(K)},N=null,B=null,E=async()=>{let K=N;N=null,await K?.close().catch(()=>{return})},U=async(K)=>{if($&&b.nativeLog){await E(),N=Pb(w,K,b);return}await G(yb(w,K,$!==void 0),"iOS app relaunch",O,{signal:b.signal})};try{await v(w.projectRoot),q(b.signal),x("syncing"),await G([w.cap,"sync","ios"],"Capacitor iOS synchronization",O,{cwd:w.projectRoot,signal:b.signal}),x("configuring"),await O$(w,b.port,b.https===!0,S),q(b.signal);let K=performance.now(),R=x$(w).then((f)=>{return W.fingerprinting=performance.now()-K,f}),g=$?await Z$({capture:M,deviceIdentifier:$,log:J,project:w,serverHost:S,startOptions:b,transition:x}):await L$({capture:M,log:J,project:w,run:O,sleep:D,spawn:C,startOptions:b,transition:x}),{caEnrollmentServer:tb,startedSimulator:eb,udid:k}=g;B=tb;let Cb=await R;x("checking-native");let Db=await D$(w.projectRoot),xb=$?await _$({cache:Db,capture:M,fingerprint:Cb,identifier:$,log:J,project:w,run:O,signal:b.signal,transition:x}):await B$({cache:Db,capture:M,fingerprint:Cb,log:J,project:w,run:O,signal:b.signal,transition:x,udid:k});if(q(b.signal),b.nativeLog)x("streaming-logs");if(N=Pb(w,k,b),x("launching"),!$||!N)await G(yb(w,k,$!==void 0),"iOS app launch",O,{signal:b.signal});x("ready"),W.total=performance.now()-_,J(`iOS ${A} connected with HMR on port ${b.port} in ${u(W.total)} (${xb?"native cache hit":"native build installed"}).`),J(`iOS startup: ${Q$(W)}.`);let d=!1,Jb=async()=>{if(d)return;d=!0,x("closing"),await E(),await B?.close().catch(()=>{return}),B=null,await v(w.projectRoot),x("closed")};return{close:Jb,nativeCacheHit:xb,startedSimulator:eb,targetKind:A,timings:{...W},udid:k,rebuild:async()=>{if(d)throw Error("iOS development session is closed.");return J("iOS native inputs changed; rebuilding without restarting the dev server."),await Jb(),Ab(b)},relaunch:async()=>{if(d)throw Error("iOS development session is closed.");x("launching");try{await U(k),x("ready"),J(`iOS app relaunched on the selected ${A}.`)}catch(f){throw x("failed"),f}},screenshot:async(f)=>{if($)throw Error("Physical iOS screenshots are captured in Xcode Device Hub; the CLI never records a device screen automatically.");let j=r(w.projectRoot,f);if(!m(w.projectRoot,j))throw Error("iOS screenshot destination must remain inside the project.");return await z(hb(j),{recursive:!0}),await G([w.xcrun,"simctl","io",k,"screenshot",j],"iOS simulator screenshot",O,{signal:b.signal}),j},get state(){return F}}}catch(K){throw x("failed"),await E(),await B?.close().catch(()=>{return}),await v(w.projectRoot),K}};var ab="ABSOLUTE_REMOTE_MAC\t",Sb=1;var I=(b)=>process.stdout.write(`${ab}${JSON.stringify({...b,v:Sb})}
29
- `),Ob=(b)=>b instanceof Error?b.message:String(b),y=(b,w)=>{let $=b.indexOf(w);return $<0?void 0:b[$+1]},R$=(b)=>{let w=Number(y(b,"--port"));if(!Number.isInteger(w)||w<1||w>65535)throw TypeError("Remote iOS agent requires a valid --port.");return w},f$=(b,w)=>{let $=y(b,w);if($===void 0)return;let A=Number($);if(!Number.isInteger(A)||A<1||A>65535)throw TypeError(`Remote iOS agent requires a valid ${w}.`);return A},l$=(b)=>{let w=y(b,"--mobile-config");if(!w)throw TypeError("Remote iOS agent requires --mobile-config.");let $=JSON.parse(Buffer.from(w,"base64url").toString("utf8"));if(typeof $!=="object"||$===null)throw TypeError("Remote iOS agent received an invalid mobile config.");return $},sb=async(b,w)=>{let $=b.getReader(),A=new TextDecoder,S="";try{while(!0){let{done:M,value:O}=await $.read();if(M)break;S+=A.decode(O,{stream:!0});let D=S.split(/\r?\n/u);S=D.pop()??"",D.forEach(w)}}finally{$.releaseLock()}},nb=async(b,w={})=>{let $=Bun.spawn(b,{cwd:w.cwd,env:w.env,signal:w.signal,stderr:"pipe",stdin:"ignore",stdout:"pipe"});return sb($.stdout,(A)=>I({message:A,type:"log"})),sb($.stderr,(A)=>I({message:A,type:"log"})),$.exited},P$=(b,w={})=>{try{let $=Bun.spawnSync(b,{cwd:w.cwd,env:w.env,stderr:"pipe",stdin:"ignore",stdout:"pipe"});return{exitCode:$.exitCode,stderr:$.stderr.toString(),stdout:$.stdout.toString()}}catch($){return{exitCode:1,stderr:Ob($),stdout:""}}},ib=(b)=>({nativeCacheHit:b.nativeCacheHit,startedSimulator:b.startedSimulator,targetKind:b.targetKind,timings:b.timings,type:"ready",udid:b.udid}),m$=async(b)=>{if(process.platform!=="darwin")throw Error("The AbsoluteJS remote iOS agent can run only on macOS.");let w=process.cwd(),$=Tb(l$(b),w),A=R$(b),S=y(b,"--ios-device"),M=y(b,"--server-host"),O=f$(b,"--relay-port");if(S&&(!M||O===void 0))throw TypeError("Remote physical iOS development requires --server-host and --relay-port.");let D=y(b,"--certificate-authority"),C=D?Mb(w,".absolutejs","mobile",`remote-dev-ca-${process.pid}.pem`):void 0;if(C&&D)await k$(Mb(w,".absolutejs","mobile"),{recursive:!0}),await z$(C,Buffer.from(D,"base64url"));let J=await vb($,{createNativeProject:!1,projectRoot:w,run:nb,target:S?"device":"simulator"}),_=S?await Lb({listenPort:A,targetPort:O??0}):void 0,T={capture:P$,certificateAuthorityPath:C,deviceIdentifier:S,https:b.includes("--https"),port:A,project:J,run:nb,serverHost:M,log:(x)=>I({message:x,type:"log"}),nativeLog:(x)=>I({entry:x,type:"native-log"}),onPhaseTiming:(x)=>I({...x,type:"timing"}),onStateChange:(x)=>I({state:x,type:"state"}),spawn:(x,N={})=>{Bun.spawn(x,{cwd:N.cwd,env:N.env,signal:N.signal,stderr:"ignore",stdin:"ignore",stdout:"ignore"})}},W;try{W=await Ab(T)}catch(x){if(await _?.close().catch(()=>{return}),C)await rb(C,{force:!0});throw x}I(ib(W));let F=y$({input:process.stdin,terminal:!1});try{for await(let x of F){let N;try{if(N=JSON.parse(x),N.v!==Sb||typeof N.id!=="string")throw Error("Invalid remote Mac request.");let B;if(N.command==="close")await W.close();else if(N.command==="relaunch")await W.relaunch();else if(N.command==="rebuild")W=await W.rebuild(),B=ib(W);else if(N.command==="screenshot"){let E=Mb(".absolutejs","mobile","remote-screenshot.png"),U=await W.screenshot(E);B={data:(await q$(U)).toString("base64")}}else throw Error("Unknown remote Mac request.");if(I({id:N.id,ok:!0,result:B,type:"response"}),N.command==="close")return}catch(B){I({error:Ob(B),id:N?.id??"",ok:!1,type:"response"})}}}finally{if(F.close(),await W.close().catch(()=>{return}),await _?.close().catch(()=>{return}),C)await rb(C,{force:!0})}},pb=async(b)=>{try{await m$(b)}catch(w){I({error:Ob(w),type:"fatal"}),process.exitCode=1}};await pb(process.argv.slice(2));
24
+ </dict>`)},O$=async(b,w,$,A="localhost")=>{let S=db(b.projectRoot);await v(b.projectRoot);let M=X(b.nativeDirectory,"App","App","capacitor.config.json"),O=X(b.nativeDirectory,"App","App","Info.plist"),[D,C]=await Promise.all([a(M,"utf8"),a(O,"utf8")]),J=JSON.parse(D);if(!I(J))throw Error(`Invalid Capacitor native config at ${M}.`);await z(S.root,{recursive:!0}),await Promise.all([L(S.configBackup,D,{flag:"wx"}),L(S.infoBackup,C,{flag:"wx"})]);let _={configBackupPath:S.configBackup,format:wb,infoBackupPath:S.infoBackup,infoPath:O,nativeConfigPath:M};await L(S.journal,`${JSON.stringify(_,null,"\t")}
25
+ `,{flag:"wx"});let T=new URL(`${$?"https":"http"}://localhost:${w}${b.config.entry}`);T.hostname=cw(A)===6?`[${A}]`:A,T.searchParams.set("__absolute_target","capacitor-ios");let W=J.server;J.server={...I(W)?W:{},cleartext:!$,url:T.href},await Promise.all([L(M,`${JSON.stringify(J,null,"\t")}
26
+ `),L(O,M$(C,!$))])},C$=(b)=>{if(!I(b))return null;let{appId:w,fingerprint:$,format:A,installations:S}=b;if(A!==$b||typeof w!=="string"||typeof $!=="string"||!I(S)||!Object.values(S).every((M)=>typeof M==="string"))return null;return{appId:w,fingerprint:$,format:A,installations:Object.fromEntries(Object.entries(S).map(([M,O])=>[M,String(O)]))}},D$=(b)=>a(jb(b),"utf8").then((w)=>C$(JSON.parse(w))).catch(()=>null),ub=async(b,w)=>{let $=jb(b),A=`${$}.${process.pid}.${dw()}.tmp`;await z(hb($),{recursive:!0});try{await L(A,`${JSON.stringify(w,null,"\t")}
27
+ `,{flag:"wx"}),await uw(A,$)}finally{await bb(A,{force:!0}).catch(()=>{return})}},x$=async(b,w={})=>Vb(b.nativeDirectory,w),cb=(b,w)=>{let $=w([b,"simctl","list","devices","available","-j"]);return b$(g($,"iOS simulator discovery"))},J$=async(b,w)=>{let $=ow(g(w([b.xcrun,"simctl","list","runtimes","-j"]),"iOS runtime discovery")),A=$$($);if(!A)throw Error("No available iOS Simulator runtime. Run absolute mobile doctor ios --fix.");let[S]=cb(b.xcrun,w).filter((C)=>C.isAvailable&&C.name===o&&C.runtime===A.identifier).sort((C,J)=>Number(J.state==="Booted")-Number(C.state==="Booted"));if(S)return{created:!1,device:S};let M=ew(g(w([b.xcrun,"simctl","list","devicetypes","-j"]),"iOS device-type discovery")),O=A$(M);if(!O)throw Error("Xcode did not report an iPhone simulator type.");let[D]=g(w([b.xcrun,"simctl","create",o,O.identifier,A.identifier]),"iOS simulator creation").split(/\s/u);if(!D)throw Error("simctl did not return the created simulator UDID.");return{created:!0,device:{isAvailable:!0,name:o,runtime:A.identifier,state:"Shutdown",udid:D}}},N$=async(b,w,$,A,S)=>{let M=Date.now()+qb,O=async()=>{if(q(S),cb(b.xcrun,$).find((C)=>C.udid===w)?.state==="Booted")return;if(Date.now()>M)throw Error(`iOS simulator ${w} did not finish booting within ${qb/1000}s.`);await A(sw),await O()};return O()},T$=(b,w,$)=>{if(w.state==="Booted")return;g($([b.xcrun,"simctl","boot",w.udid]),"iOS simulator boot")},lb=(b,w,$)=>{let A=$([b.xcrun,"simctl","get_app_container",w,b.config.appId,"app"]);return A.exitCode===0&&A.stdout.trim()?A.stdout.trim():void 0},W$=(b,w,$)=>{let A=$([b.xcrun,"devicectl","device","info","details","--device",w]);if(A.exitCode!==0)throw Error(`Physical iOS device ${JSON.stringify(w)} is unavailable: ${A.stderr.trim()||A.stdout.trim()||"pair it in Xcode Device Hub, trust this Mac, unlock it, and enable Developer Mode."}`)},U$=(b,w,$)=>{let A=$([b.xcrun,"devicectl","device","info","apps","--device",w]);return A.exitCode===0&&A.stdout.includes(b.config.appId)},K$=async(b,w,$,A,S)=>{let M=X(b.projectRoot,".absolutejs","mobile","ios-derived-data",mb("sha256").update(b.config.appId).digest("hex").slice(0,16));await z(M,{recursive:!0}),await G([b.xcodebuild,"-workspace",X(b.nativeDirectory,"App","App.xcworkspace"),"-scheme","App","-configuration","Debug","-destination",`platform=iOS Simulator,id=${w}`,"-derivedDataPath",M,"build"],"iOS simulator build",A,{cwd:b.nativeDirectory,signal:S});let O=X(M,"Build","Products","Debug-iphonesimulator","App.app");if(!await Y(O))throw Error(`Xcode did not produce the simulator app at ${O}.`);return O},X$=async(b,w,$,A)=>{let S=X(b.projectRoot,".absolutejs","mobile","ios-derived-data",mb("sha256").update(b.config.appId).digest("hex").slice(0,16));await z(S,{recursive:!0}),await G([b.xcodebuild,"-workspace",X(b.nativeDirectory,"App","App.xcworkspace"),"-scheme","App","-configuration","Debug","-destination",`platform=iOS,id=${w}`,"-derivedDataPath",S,"-allowProvisioningUpdates","build"],"iOS physical-device build (configure automatic signing and a Development Team in Xcode if this is the first run)",$,{cwd:b.nativeDirectory,signal:A});let M=X(S,"Build","Products","Debug-iphoneos","App.app");if(!await Y(M))throw Error(`Xcode did not produce the physical-device app at ${M}.`);return M},_$=async(b)=>{if(b.cache?.appId===b.project.config.appId&&b.cache.fingerprint===b.fingerprint&&b.cache.installations[b.identifier]===b.fingerprint&&U$(b.project,b.identifier,b.capture))return b.log("iOS native app is unchanged on the selected physical device; skipped Xcode build and install."),!0;b.log("iOS native inputs changed or the physical-device install is stale; rebuilding."),b.transition("building");let $=await X$(b.project,b.identifier,b.run,b.signal);return q(b.signal),b.transition("installing"),await G([b.project.xcrun,"devicectl","device","install","app","--device",b.identifier,$],"iOS physical-device app installation",b.run,{signal:b.signal}),await ub(b.project.projectRoot,{appId:b.project.config.appId,fingerprint:b.fingerprint,format:$b,installations:{...b.cache?.appId===b.project.config.appId?b.cache.installations:{},[b.identifier]:b.fingerprint}}).catch((A)=>b.log(`iOS native cache could not be saved: ${A instanceof Error?A.message:String(A)}`)),!1},B$=async(b)=>{let w=lb(b.project,b.udid,b.capture);if(b.cache?.appId===b.project.config.appId&&b.cache.fingerprint===b.fingerprint&&w!==void 0&&b.cache.installations[b.udid]===w)return b.log(`iOS native app is unchanged on ${b.udid}; skipped Xcode build and install.`),!0;b.log("iOS native inputs changed or the installed app is stale; rebuilding."),b.transition("building");let A=await K$(b.project,b.udid,b.fingerprint,b.run,b.signal);q(b.signal),b.transition("installing"),await G([b.project.xcrun,"simctl","install",b.udid,A],"iOS simulator app installation",b.run,{signal:b.signal});let S=lb(b.project,b.udid,b.capture);if(S)await ub(b.project.projectRoot,{appId:b.project.config.appId,fingerprint:b.fingerprint,format:$b,installations:{[b.udid]:S}}).catch((M)=>b.log(`iOS native cache could not be saved: ${M instanceof Error?M.message:String(M)}`));return!1},F$=/((?:authorization|cookie|password|secret|token|oauth[_-]?code)\s*[:=]\s*)([^\s,;]+)/giu,G$=new RegExp(String.raw`\bBearer\s+[A-Za-z0-9._~+/-]+=*`,"giu"),I$=/\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/gu,H$=new RegExp(String.raw`\s(Debug|Info|Notice|Error|Fault)\s+.*?\[[^\]]+\]\s+\[([^\]]+)\]\s*(.*)$`,"iu"),V$=(b)=>{let w=Y$(b).trim();if(!w)return null;let $=H$.exec(w),A=$?.[1]?.toLowerCase();return{level:A==="debug"||A==="error"||A==="fault"||A==="notice"?A:"info",message:$?.[3]?.trim()||w,tag:$?.[2]?.trim()||"App"}},Y$=(b)=>b.replaceAll(G$,"Bearer [REDACTED]").replaceAll(I$,"[REDACTED_JWT]").replaceAll(F$,"$1[REDACTED]").replaceAll(/\p{C}/gu,""),Pb=(b,w,$)=>{if(!$.nativeLog)return null;let A=$.startNativeLogs??pw,S=$.deviceIdentifier?[b.xcrun,"devicectl","device","process","launch","--console","--terminate-existing","--device",w,b.config.appId]:[b.xcrun,"simctl","spawn",w,"log","stream","--style","compact","--level","debug","--predicate",'process == "App"'];return A(S,{signal:$.signal},(M)=>{let O=V$(M);if(O)$.nativeLog?.(O)})},E$=[["syncing","Capacitor sync"],["configuring","dev config"],["fingerprinting","fingerprint"],["booting","simulator"],["connecting","device ready"],["enrolling-trust","HTTPS trust"],["checking-native","app check"],["building","Xcode"],["installing","install"],["launching","launch"],["streaming-logs","logs"]],Q$=(b)=>E$.map(([w,$])=>{let A=b[w];return A===void 0?null:`${$} ${P(A)}`}).filter((w)=>w!==null).join(", "),vb=async(b,w)=>{if(c()!=="macos")throw Error("iOS development requires macOS and Xcode.");let $=w.target??"simulator",A=r(w.projectRoot),S=await _b({host:"macos"}),M=S.filter((T)=>T.platform==="ios"&&!($==="device"&&T.id==="ios.runtime")&&(T.status==="fail"||T.status==="warn"));if(M.length>0)throw Error(`iOS ${$} development is not ready: ${M.map(({label:T})=>T).join(", ")}.`);let O=S.find((T)=>T.id==="ios.xcrun")?.path,D=S.find((T)=>T.id==="ios.xcodebuild")?.path;if(!O||!D)throw Error("Xcode tools disappeared after readiness checks.");let C=X(A,"node_modules",".bin","cap");if(!await Y(C))throw Error("Capacitor CLI is not installed. Run absolute mobile init first.");await Gb(b,{projectRoot:A}),await z(b.bundleDirectory,{recursive:!0});let J=X(b.bundleDirectory,"index.html");if(!await Y(J))await L(J,`<!doctype html><title>AbsoluteJS mobile development</title>
28
+ `);let _=X(b.nativeProjectDirectory,"ios");if(!await Y(_)){if(!w.createNativeProject)throw Error("iOS native project has not been created.");if(await(w.run??gb)([C,"add","ios"],{cwd:A})!==0)throw Error("Capacitor iOS project creation failed.")}return{cap:C,config:b,nativeDirectory:_,projectRoot:A,xcodebuild:D,xcrun:O}},Z$=async(b)=>{if(b.transition("connecting"),W$(b.project,b.deviceIdentifier,b.capture),!b.startOptions.https)return{caEnrollmentServer:null,startedSimulator:!1,udid:b.deviceIdentifier};if(!b.startOptions.certificateAuthorityPath)throw Error("Physical iOS HTTPS development requires the AbsoluteJS development CA certificate.");b.transition("enrolling-trust");let $=await(b.startOptions.startCaEnrollmentServer??Zb)({certificateAuthorityPath:b.startOptions.certificateAuthorityPath,displayHost:b.serverHost});return b.log(`On the iOS device, open ${$.url}, install the AbsoluteJS development CA profile, then enable it under Settings > General > About > Certificate Trust Settings. This public CA endpoint exists only for this dev session.`),{caEnrollmentServer:$,startedSimulator:!1,udid:b.deviceIdentifier}},L$=async(b)=>{b.transition("booting");let w=await J$(b.project,b.capture),{device:$}=w,A=w.created||$.state!=="Booted";return T$(b.project,$,b.capture),b.spawn(["open","-a","Simulator","--args","-CurrentDeviceUDID",$.udid]),b.transition("connecting"),await N$(b.project,$.udid,b.capture,b.sleep,b.startOptions.signal),await G([b.project.xcrun,"simctl","bootstatus",$.udid,"-b"],"iOS simulator boot readiness",b.run,{signal:b.startOptions.signal}),await tw(b.startOptions,$.udid,b.run,b.log),{caEnrollmentServer:null,startedSimulator:A,udid:$.udid}},Sb=async(b)=>{let{project:w}=b,$=b.deviceIdentifier?Qb(b.deviceIdentifier):void 0,A=$?"device":"simulator",S=$?e(b.serverHost??""):"localhost",M=b.capture??nw,O=b.run??gb,D=b.sleep??Bun.sleep,C=b.spawn??iw,J=b.log??console.log,_=performance.now(),T=performance.now(),W={},F="syncing",x=(U)=>{if(U===F){b.onStateChange?.(U);return}let R=performance.now(),d=R-T;W[F]=(W[F]??0)+d,b.onPhaseTiming?.({durationMs:d,phase:F,totalMs:R-_}),F=U,T=R,b.onStateChange?.(U)},N=null,B=null,E=async()=>{let U=N;N=null,await U?.close().catch(()=>{return})},K=async(U)=>{if($&&b.nativeLog){await E(),N=Pb(w,U,b);return}await G(yb(w,U,$!==void 0),"iOS app relaunch",O,{signal:b.signal})};try{if(await v(w.projectRoot),q(b.signal),x("syncing"),await G([w.cap,"sync","ios"],"Capacitor iOS synchronization",O,{cwd:w.projectRoot,signal:b.signal}),x("configuring"),b.embeddedBundle!==!0)await O$(w,b.port,b.https===!0,S);q(b.signal);let U=performance.now(),R=x$(w,{includePublicBundle:b.embeddedBundle===!0}).then((f)=>{return W.fingerprinting=performance.now()-U,f}),d=$?await Z$({capture:M,deviceIdentifier:$,log:J,project:w,serverHost:S,startOptions:b,transition:x}):await L$({capture:M,log:J,project:w,run:O,sleep:D,spawn:C,startOptions:b,transition:x}),{caEnrollmentServer:tb,startedSimulator:eb,udid:k}=d;B=tb;let Db=await R;x("checking-native");let xb=await D$(w.projectRoot),s=$?await _$({cache:xb,capture:M,fingerprint:Db,identifier:$,log:J,project:w,run:O,signal:b.signal,transition:x}):await B$({cache:xb,capture:M,fingerprint:Db,log:J,project:w,run:O,signal:b.signal,transition:x,udid:k});if(q(b.signal),b.nativeLog)x("streaming-logs");if(N=Pb(w,k,b),x("launching"),!$||!N)await G(yb(w,k,$!==void 0),"iOS app launch",O,{signal:b.signal});x("ready"),W.total=performance.now()-_,J(b.embeddedBundle===!0?`iOS ${A} connected with the embedded bundle and backend on port ${b.port} in ${P(W.total)} (${s?"native cache hit":"native build installed"}).`:`iOS ${A} connected with HMR on port ${b.port} in ${P(W.total)} (${s?"native cache hit":"native build installed"}).`),J(`iOS startup: ${Q$(W)}.`);let j=!1,Jb=async()=>{if(j)return;j=!0,x("closing"),await E(),await B?.close().catch(()=>{return}),B=null,await v(w.projectRoot),x("closed")};return{close:Jb,nativeCacheHit:s,startedSimulator:eb,targetKind:A,timings:{...W},udid:k,rebuild:async()=>{if(j)throw Error("iOS development session is closed.");return J("iOS native inputs changed; rebuilding without restarting the dev server."),await Jb(),Sb(b)},relaunch:async()=>{if(j)throw Error("iOS development session is closed.");x("launching");try{await K(k),x("ready"),J(`iOS app relaunched on the selected ${A}.`)}catch(f){throw x("failed"),f}},screenshot:async(f)=>{if($)throw Error("Physical iOS screenshots are captured in Xcode Device Hub; the CLI never records a device screen automatically.");let u=r(w.projectRoot,f);if(!h(w.projectRoot,u))throw Error("iOS screenshot destination must remain inside the project.");return await z(hb(u),{recursive:!0}),await G([w.xcrun,"simctl","io",k,"screenshot",u],"iOS simulator screenshot",O,{signal:b.signal}),u},get state(){return F}}}catch(U){throw x("failed"),await E(),await B?.close().catch(()=>{return}),await v(w.projectRoot),U}};var ab="ABSOLUTE_REMOTE_MAC\t",Mb=1;var H=(b)=>process.stdout.write(`${ab}${JSON.stringify({...b,v:Mb})}
29
+ `),Cb=(b)=>b instanceof Error?b.message:String(b),y=(b,w)=>{let $=b.indexOf(w);return $<0?void 0:b[$+1]},R$=(b)=>{let w=Number(y(b,"--port"));if(!Number.isInteger(w)||w<1||w>65535)throw TypeError("Remote iOS agent requires a valid --port.");return w},f$=(b,w)=>{let $=y(b,w);if($===void 0)return;let A=Number($);if(!Number.isInteger(A)||A<1||A>65535)throw TypeError(`Remote iOS agent requires a valid ${w}.`);return A},l$=(b)=>{let w=y(b,"--mobile-config");if(!w)throw TypeError("Remote iOS agent requires --mobile-config.");let $=JSON.parse(Buffer.from(w,"base64url").toString("utf8"));if(typeof $!=="object"||$===null)throw TypeError("Remote iOS agent received an invalid mobile config.");return $},sb=async(b,w)=>{let $=b.getReader(),A=new TextDecoder,S="";try{while(!0){let{done:M,value:O}=await $.read();if(M)break;S+=A.decode(O,{stream:!0});let D=S.split(/\r?\n/u);S=D.pop()??"",D.forEach(w)}}finally{$.releaseLock()}},nb=async(b,w={})=>{let $=Bun.spawn(b,{cwd:w.cwd,env:w.env,signal:w.signal,stderr:"pipe",stdin:"ignore",stdout:"pipe"});return sb($.stdout,(A)=>H({message:A,type:"log"})),sb($.stderr,(A)=>H({message:A,type:"log"})),$.exited},P$=(b,w={})=>{try{let $=Bun.spawnSync(b,{cwd:w.cwd,env:w.env,stderr:"pipe",stdin:"ignore",stdout:"pipe"});return{exitCode:$.exitCode,stderr:$.stderr.toString(),stdout:$.stdout.toString()}}catch($){return{exitCode:1,stderr:Cb($),stdout:""}}},ib=(b)=>({nativeCacheHit:b.nativeCacheHit,startedSimulator:b.startedSimulator,targetKind:b.targetKind,timings:b.timings,type:"ready",udid:b.udid}),m$=async(b)=>{if(process.platform!=="darwin")throw Error("The AbsoluteJS remote iOS agent can run only on macOS.");let w=process.cwd(),$=Tb(l$(b),w),A=R$(b),S=y(b,"--ios-device"),M=y(b,"--server-host"),O=f$(b,"--relay-port");if(S&&(!M||O===void 0))throw TypeError("Remote physical iOS development requires --server-host and --relay-port.");let D=y(b,"--certificate-authority"),C=D?Ob(w,".absolutejs","mobile",`remote-dev-ca-${process.pid}.pem`):void 0;if(C&&D)await k$(Ob(w,".absolutejs","mobile"),{recursive:!0}),await z$(C,Buffer.from(D,"base64url"));let J=await vb($,{createNativeProject:!1,projectRoot:w,run:nb,target:S?"device":"simulator"}),_=S?await Lb({listenPort:A,targetPort:O??0}):void 0,T={capture:P$,certificateAuthorityPath:C,deviceIdentifier:S,https:b.includes("--https"),port:A,project:J,run:nb,serverHost:M,log:(x)=>H({message:x,type:"log"}),nativeLog:(x)=>H({entry:x,type:"native-log"}),onPhaseTiming:(x)=>H({...x,type:"timing"}),onStateChange:(x)=>H({state:x,type:"state"}),spawn:(x,N={})=>{Bun.spawn(x,{cwd:N.cwd,env:N.env,signal:N.signal,stderr:"ignore",stdin:"ignore",stdout:"ignore"})}},W;try{W=await Sb(T)}catch(x){if(await _?.close().catch(()=>{return}),C)await rb(C,{force:!0});throw x}H(ib(W));let F=y$({input:process.stdin,terminal:!1});try{for await(let x of F){let N;try{if(N=JSON.parse(x),N.v!==Mb||typeof N.id!=="string")throw Error("Invalid remote Mac request.");let B;if(N.command==="close")await W.close();else if(N.command==="relaunch")await W.relaunch();else if(N.command==="rebuild")W=await W.rebuild(),B=ib(W);else if(N.command==="screenshot"){let E=Ob(".absolutejs","mobile","remote-screenshot.png"),K=await W.screenshot(E);B={data:(await q$(K)).toString("base64")}}else throw Error("Unknown remote Mac request.");if(H({id:N.id,ok:!0,result:B,type:"response"}),N.command==="close")return}catch(B){H({error:Cb(B),id:N?.id??"",ok:!1,type:"response"})}}}finally{if(F.close(),await W.close().catch(()=>{return}),await _?.close().catch(()=>{return}),C)await rb(C,{force:!0})}},pb=async(b)=>{try{await m$(b)}catch(w){H({error:Cb(w),type:"fatal"}),process.exitCode=1}};await pb(process.argv.slice(2));
@@ -11,6 +11,7 @@ export declare const enrichInstances: (records: InstanceRecord[]) => Promise<{
11
11
  frameworks: string[];
12
12
  host: string;
13
13
  https: boolean;
14
+ iosRemoteMac?: string;
14
15
  logFile: string | null;
15
16
  name: string;
16
17
  pid: number;
@@ -153,8 +153,11 @@ export declare const prepare: (configOrPath?: string) => Promise<{
153
153
  entryWatcherReady: boolean;
154
154
  isRebuilding: boolean;
155
155
  manifestKeys: string[];
156
+ pendingBundleRebuilds: ("svelte" | "vue" | "angular")[];
157
+ pendingFileChanges: number;
156
158
  rebuildCount: number;
157
159
  rebuildQueue: string[];
160
+ rebuildScheduled: boolean;
158
161
  timestamp: number;
159
162
  };
160
163
  };
@@ -301,8 +304,11 @@ export declare const prepare: (configOrPath?: string) => Promise<{
301
304
  entryWatcherReady: boolean;
302
305
  isRebuilding: boolean;
303
306
  manifestKeys: string[];
307
+ pendingBundleRebuilds: ("svelte" | "vue" | "angular")[];
308
+ pendingFileChanges: number;
304
309
  rebuildCount: number;
305
310
  rebuildQueue: string[];
311
+ rebuildScheduled: boolean;
306
312
  timestamp: number;
307
313
  };
308
314
  };
@@ -466,8 +472,11 @@ export declare const prepare: (configOrPath?: string) => Promise<{
466
472
  entryWatcherReady: boolean;
467
473
  isRebuilding: boolean;
468
474
  manifestKeys: string[];
475
+ pendingBundleRebuilds: ("svelte" | "vue" | "angular")[];
476
+ pendingFileChanges: number;
469
477
  rebuildCount: number;
470
478
  rebuildQueue: string[];
479
+ rebuildScheduled: boolean;
471
480
  timestamp: number;
472
481
  };
473
482
  };
@@ -641,8 +650,11 @@ export declare const prepare: (configOrPath?: string) => Promise<{
641
650
  entryWatcherReady: boolean;
642
651
  isRebuilding: boolean;
643
652
  manifestKeys: string[];
653
+ pendingBundleRebuilds: ("svelte" | "vue" | "angular")[];
654
+ pendingFileChanges: number;
644
655
  rebuildCount: number;
645
656
  rebuildQueue: string[];
657
+ rebuildScheduled: boolean;
646
658
  timestamp: number;
647
659
  };
648
660
  };
@@ -17,6 +17,7 @@ export type HMRState = {
17
17
  isRebuilding: boolean;
18
18
  rebuildQueue: Set<string>;
19
19
  rebuildTimeout: NodeJS.Timeout | null;
20
+ pendingBundleRebuilds: Set<'angular' | 'svelte' | 'vue'>;
20
21
  fileChangeQueue: Map<string, string[]>;
21
22
  debounceTimeout: NodeJS.Timeout | null;
22
23
  fileHashes: Map<string, number>;
@@ -7,6 +7,7 @@ export * from './iosSimulatorController';
7
7
  export * from './iosPhysicalDeviceTransport';
8
8
  export * from './iosNativeWatcher';
9
9
  export * from './remoteMacProtocol';
10
+ export * from './iosDeviceAcceptance';
10
11
  export * from './associationFiles';
11
12
  export * from './buildMetadata';
12
13
  export * from './buildPipeline';
@@ -0,0 +1,32 @@
1
+ export type AbsoluteIosDeviceAcceptanceResult = {
2
+ hmrConnected: true;
3
+ installed: true;
4
+ relaunchMs: number;
5
+ };
6
+ type CommandResult = {
7
+ exitCode: number;
8
+ stderr: string;
9
+ stdout: string;
10
+ };
11
+ export declare const absoluteIosDeviceAcceptanceCommands: (options: {
12
+ appId: string;
13
+ device: string;
14
+ xcrun?: string;
15
+ }) => {
16
+ apps: string[];
17
+ details: string[];
18
+ launch: string[];
19
+ };
20
+ /**
21
+ * Validate and relaunch a physical iOS app without retaining device inventory,
22
+ * signing output, or console output in the acceptance result.
23
+ */
24
+ export declare const testAbsoluteIosPhysicalDevice: (options: {
25
+ appId: string;
26
+ capture: (command: string[]) => Promise<CommandResult>;
27
+ device: string;
28
+ now?: () => number;
29
+ waitForHmr: () => Promise<void>;
30
+ xcrun?: string;
31
+ }) => Promise<AbsoluteIosDeviceAcceptanceResult>;
32
+ export {};
@@ -37,7 +37,9 @@ export type BuildAbsoluteIosReleaseOptions = {
37
37
  run?: (command: string[], options?: CommandOptions) => Promise<number>;
38
38
  buildNumber?: number;
39
39
  };
40
- export declare const fingerprintAbsoluteIosNativeProject: (nativeDirectory: string) => Promise<string>;
40
+ export declare const fingerprintAbsoluteIosNativeProject: (nativeDirectory: string, options?: {
41
+ includePublicBundle?: boolean;
42
+ }) => Promise<string>;
41
43
  export declare const buildAbsoluteIosRelease: (options: BuildAbsoluteIosReleaseOptions) => Promise<{
42
44
  artifactPath: string;
43
45
  metadata: {
@@ -57,6 +57,9 @@ export type StartAbsoluteIosDevOptions = {
57
57
  capture?: (command: string[], options?: AbsoluteIosCommandOptions) => AbsoluteIosCommandResult;
58
58
  /** Xcode device identifier or name. Omit to use the managed Simulator. */
59
59
  deviceIdentifier?: string;
60
+ /** Launch the locally embedded production web bundle. `port` remains the
61
+ * configured backend port and no temporary development URL is projected. */
62
+ embeddedBundle?: boolean;
60
63
  https?: boolean;
61
64
  log?: (message: string) => void;
62
65
  nativeLog?: (entry: AbsoluteIosNativeLogEntry) => void;
@@ -94,7 +97,9 @@ export declare const parseIosSimulators: (source: string) => {
94
97
  udid: string;
95
98
  }[];
96
99
  export declare const repairAbsoluteIosDevSession: (projectRoot: string) => Promise<boolean>;
97
- export declare const fingerprintAbsoluteIosDevProject: (project: Pick<AbsoluteIosDevProject, "nativeDirectory">) => Promise<string>;
100
+ export declare const fingerprintAbsoluteIosDevProject: (project: Pick<AbsoluteIosDevProject, "nativeDirectory">, options?: {
101
+ includePublicBundle?: boolean;
102
+ }) => Promise<string>;
98
103
  export declare const parseAbsoluteIosLogLine: (line: string) => AbsoluteIosNativeLogEntry | null;
99
104
  export declare const redactAbsoluteIosLog: (value: string) => string;
100
105
  export declare const prepareAbsoluteIosDevProject: (config: NormalizedAbsoluteMobileConfig, options: PrepareAbsoluteIosDevOptions) => Promise<AbsoluteIosDevProject>;
@@ -1,6 +1,7 @@
1
1
  import { type AbsoluteNativeAutomatedRun, type AbsoluteNativeTestReport } from './nativeTestReport';
2
2
  export type AbsoluteIosAutomatedResult = Omit<AbsoluteNativeAutomatedRun, 'platform' | 'targetId' | 'targetKind'> & {
3
- udid: string;
3
+ targetId: string;
4
+ targetKind: 'device' | 'simulator';
4
5
  };
5
6
  export type AbsoluteIosPartnerReport = AbsoluteNativeTestReport;
6
7
  type CreateAbsoluteIosPartnerReportOptions = {
@@ -33,6 +33,11 @@ export type AbsoluteNativeSyncMigrationResult = {
33
33
  };
34
34
  export type AbsoluteNativeAutomatedRun = {
35
35
  appId: string;
36
+ deviceAcceptance?: {
37
+ https: boolean;
38
+ relaunchMs: number;
39
+ remote: boolean;
40
+ };
36
41
  durationMs: number;
37
42
  error?: string;
38
43
  hmr?: AbsoluteNativeHmrResult;
@@ -69,6 +74,7 @@ type CreateAbsoluteNativeTestReportOptions = {
69
74
  automatedChecks?: AbsoluteNativeReportCheck[];
70
75
  generatedAt?: string;
71
76
  manualChecks: readonly AbsoluteNativeManualCheckDefinition[];
77
+ manualCheckResults?: Record<string, AbsoluteNativeReportCheck>;
72
78
  metadata: AbsoluteNativeTestReport['metadata'];
73
79
  run: AbsoluteNativeAutomatedRun;
74
80
  };
@@ -72,6 +72,13 @@ export declare const validateAbsoluteSshDestination: (destination: string) => st
72
72
  export declare const absoluteRemoteMacSshBase: (profile: Pick<AbsoluteRemoteMacProfile, "destination" | "port">, options?: {
73
73
  acceptNew?: boolean;
74
74
  }) => string[];
75
+ /** Run a non-interactive command on an already paired Mac.
76
+ *
77
+ * Arguments are quoted independently before crossing SSH. This is intended for
78
+ * small, read-only inspections and lifecycle commands that do not need the
79
+ * long-running remote development agent.
80
+ */
81
+ export declare const captureAbsoluteRemoteMacCommand: (profile: AbsoluteRemoteMacProfile, command: string[], transport?: Pick<AbsoluteRemoteMacTransport, "capture">) => Promise<AbsoluteRemoteMacCommandResult>;
75
82
  export declare const getAbsoluteRemoteMacProfile: (name?: string, profilePath?: string) => Promise<AbsoluteRemoteMacProfile | undefined>;
76
83
  export declare const inspectAbsoluteRemoteMac: (destination: string, options?: {
77
84
  acceptNew?: boolean;
@@ -86,7 +86,10 @@ export declare const hmr: (hmrState: HMRState, manifest: Record<string, string>,
86
86
  entryWatcherReady: boolean;
87
87
  isRebuilding: boolean;
88
88
  manifestKeys: string[];
89
+ pendingBundleRebuilds: ("svelte" | "vue" | "angular")[];
90
+ pendingFileChanges: number;
89
91
  rebuildCount: number;
90
92
  rebuildQueue: string[];
93
+ rebuildScheduled: boolean;
91
94
  timestamp: number;
92
95
  }>;
@@ -23,6 +23,7 @@ export type InstanceRecord = {
23
23
  frameworks: string[];
24
24
  host: string;
25
25
  https: boolean;
26
+ iosRemoteMac?: string;
26
27
  logFile: string | null;
27
28
  name: string;
28
29
  pid: number;
package/package.json CHANGED
@@ -455,7 +455,9 @@
455
455
  "test:native:android:hmr": "ABSOLUTE_TEST_NATIVE_ANDROID=1 bun test tests/native/android-hmr-conformance.test.ts",
456
456
  "test:native:android:lifecycle": "ABSOLUTE_TEST_NATIVE_ANDROID=1 bun test tests/native/android-lifecycle-conformance.test.ts",
457
457
  "test:native:android:upgrade": "ABSOLUTE_TEST_NATIVE_ANDROID=1 bun test tests/native/android-embedded-bundle-conformance.test.ts -t 'installed APK upgrade'",
458
- "test:native:ios": "ABSOLUTE_TEST_NATIVE_IOS=1 bun test tests/native/ios-lifecycle-conformance.test.ts",
458
+ "test:native:ios": "bun run test:native:ios:lifecycle && bun run test:native:ios:bundle",
459
+ "test:native:ios:bundle": "ABSOLUTE_TEST_NATIVE_IOS=1 bun test tests/native/ios-embedded-bundle-conformance.test.ts",
460
+ "test:native:ios:lifecycle": "ABSOLUTE_TEST_NATIVE_IOS=1 bun test tests/native/ios-lifecycle-conformance.test.ts",
459
461
  "test:unit": "bun test --max-concurrency 1 tests/unit",
460
462
  "typecheck": "bun run src/cli/index.ts typecheck --config example/absolute.config.ts",
461
463
  "verify:release-versions": "bun run scripts/verifyReleaseVersions.ts"
@@ -504,7 +506,7 @@
504
506
  ]
505
507
  }
506
508
  },
507
- "version": "0.20.0-beta.34",
509
+ "version": "0.20.0-beta.36",
508
510
  "workspaces": [
509
511
  "tests/fixtures/*",
510
512
  "tests/fixtures/_packages/*"