agent-device 0.21.22 → 0.21.24
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/README.md +6 -6
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.22.apk → agent-device-android-ime-helper-0.21.24.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.24.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.22.manifest.json → agent-device-android-ime-helper-0.21.24.manifest.json} +4 -4
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.24.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.24.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.22.manifest.json → agent-device-android-snapshot-helper-0.21.24.manifest.json} +6 -6
- package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/SnapshotTraversal.swift +12 -6
- package/apple/macos-helper/Tests/AgentDeviceMacOSHelperTests/RectResponseTests.swift +21 -0
- package/apple/snapshot-bridge/README.md +9 -7
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandDispatch.swift +56 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +14 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +8 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +12 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCaptureTarget.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotExecution.swift +29 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +34 -10
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +19 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +3 -3
- package/dist/src/adapter.js +1 -1
- package/dist/src/adb.js +1 -1
- package/dist/src/agent-browser-lifecycle.js +1 -1
- package/dist/src/agent-browser-process-record.js +1 -1
- package/dist/src/agent-browser-provider.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/alert-runtime.js +1 -1
- package/dist/src/alert.js +1 -1
- package/dist/src/android-adb.d.ts +3 -2
- package/dist/src/android-input-ownership.js +1 -1
- package/dist/src/app-backend.js +1 -1
- package/dist/src/app-inventory.d.ts +4 -0
- package/dist/src/app-launch.js +1 -1
- package/dist/src/app-lifecycle.js +1 -1
- package/dist/src/app-log-reconnect.js +1 -1
- package/dist/src/app-log-runtime2.js +3 -3
- package/dist/src/app-resolution.js +2 -2
- package/dist/src/app-state-runtime.d.ts +15 -0
- package/dist/src/apple-runner-platform.js +1 -1
- package/dist/src/application-lifecycle-interaction.js +1 -1
- package/dist/src/aws-device-farm-connection.js +1 -0
- package/dist/src/back-mode.js +1 -1
- package/dist/src/backend-snapshot-options.js +1 -1
- package/dist/src/browserstack-connection.js +1 -0
- package/dist/src/browserstack-device-features.js +1 -0
- package/dist/src/browserstack.js +1 -0
- package/dist/src/cache.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +35 -19
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +3 -4
- package/dist/src/client-companion-tunnel.js +1 -0
- package/dist/src/client-metro-companion.js +1 -1
- package/dist/src/client-metro.js +1 -1
- package/dist/src/client-options.js +3 -3
- package/dist/src/client-types.d.ts +7 -5
- package/dist/src/cloud-artifacts.d.ts +9 -2
- package/dist/src/code-signature-cache.js +1 -1
- package/dist/src/command-metadata.js +1 -1
- package/dist/src/command-schema.js +1 -1
- package/dist/src/command-tools.js +2 -2
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/connection-verification.js +1 -0
- package/dist/src/connection.js +5 -5
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/daemon-client-lease-beat.js +1 -1
- package/dist/src/daemon-client-lifecycle.js +1 -1
- package/dist/src/daemon-client-transport.js +1 -1
- package/dist/src/daemon-http.js +1 -1
- package/dist/src/daemon-policy-file.js +1 -1
- package/dist/src/daemon-registration-owner.js +1 -1
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-input-state.d.ts +2 -15
- package/dist/src/device-readiness-runtime.js +1 -1
- package/dist/src/device-selection-resolver.js +1 -1
- package/dist/src/device-session.js +3 -1
- package/dist/src/device.js +1 -1
- package/dist/src/device2.js +1 -1
- package/dist/src/device3.js +1 -1
- package/dist/src/dispatch-resolve.js +3 -3
- package/dist/src/doctor-facade.js +1 -1
- package/dist/src/durable-capture-resource.js +1 -1
- package/dist/src/durable-resource.js +1 -1
- package/dist/src/exec.js +1 -1
- package/dist/src/file.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/format.js +2 -1
- package/dist/src/gesture-admission.js +1 -1
- package/dist/src/gesture-plan-types.d.ts +2 -5
- package/dist/src/gesture-runtime.js +1 -1
- package/dist/src/helper.js +2 -2
- package/dist/src/human-control.js +1 -1
- package/dist/src/ime-rebind.js +1 -0
- package/dist/src/ime-settings-record.js +1 -0
- package/dist/src/ime-state.js +1 -0
- package/dist/src/index.d.ts +3 -3
- package/dist/src/input-actions.js +1 -1
- package/dist/src/input-actions2.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/instance-client.js +1 -1
- package/dist/src/interaction-positionals.js +1 -1
- package/dist/src/interaction-ref-policy.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interaction2.js +1 -1
- package/dist/src/interactor.js +5 -5
- package/dist/src/interactors.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +1 -1
- package/dist/src/inventory2.js +1 -1
- package/dist/src/ios-client.js +4 -4
- package/dist/src/ios-snapshot-acquisition.js +1 -1
- package/dist/src/ios-snapshot-engine.js +1 -1
- package/dist/src/ios-snapshot-runtime.js +1 -1
- package/dist/src/launch-confirmation.js +1 -1
- package/dist/src/lease-scope.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun.d.ts +4 -555
- package/dist/src/load.js +1 -1
- package/dist/src/local-interactor-operation-set.js +1 -1
- package/dist/src/log-stream.js +33 -0
- package/dist/src/managed-device-scope.js +1 -1
- package/dist/src/manifest.js +1 -0
- package/dist/src/mechanics.js +16 -16
- package/dist/src/mobile-snapshot-semantics.js +1 -1
- package/dist/src/node-http.js +1 -0
- package/dist/src/observation.js +1 -2
- package/dist/src/overlay.js +3 -3
- package/dist/src/owner-identity.js +3 -3
- package/dist/src/perf-facade.js +1 -1
- package/dist/src/perf-runtime-plan.js +1 -1
- package/dist/src/perf-target.js +1 -1
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/platform-request-scope.js +1 -1
- package/dist/src/platform-runtime-app-log-process.js +1 -1
- package/dist/src/platform-runtime-open-target.js +1 -1
- package/dist/src/platform-runtime-operation-host.js +4 -4
- package/dist/src/platform-runtime-runtime-hints.js +1 -1
- package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-process-host.js +1 -1
- package/dist/src/platform-runtime-unavailable.js +1 -1
- package/dist/src/platform-runtime.js +1 -1
- package/dist/src/platform-runtime2.js +1 -1
- package/dist/src/plugin.js +1 -0
- package/dist/src/plugins/webdriver.d.ts +111 -0
- package/dist/src/plugins/webdriver.js +1 -0
- package/dist/src/plugins.d.ts +2 -1
- package/dist/src/plugins2.js +1 -1
- package/dist/src/process-exit.js +1 -1
- package/dist/src/process.js +1 -1
- package/dist/src/provider-credential-fingerprint.js +1 -1
- package/dist/src/provider-device-admission.js +1 -1
- package/dist/src/provider-device-runtime.d.ts +556 -0
- package/dist/src/provider-policy.js +1 -0
- package/dist/src/provider-profile-fields.js +1 -1
- package/dist/src/provider-webdriver.js +1 -2
- package/dist/src/providers.js +1 -1
- package/dist/src/proxy.js +2 -2
- package/dist/src/react-devtools.js +2 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/record-trace.js +1 -1
- package/dist/src/recording.js +1 -1
- package/dist/src/registry.js +24 -24
- package/dist/src/remote-bridge.js +1 -0
- package/dist/src/remote-config-core.js +1 -0
- package/dist/src/remote-config.js +1 -1
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/remote-connection-state.js +1 -0
- package/dist/src/replay.js +2 -2
- package/dist/src/request-admission.js +1 -1
- package/dist/src/request-runtime-binding.js +1 -1
- package/dist/src/result-serialization.js +1 -1
- package/dist/src/retry.js +1 -1
- package/dist/src/retry2.js +1 -0
- package/dist/src/runner-artifact-manifest.js +1 -1
- package/dist/src/runner-cache-metadata.js +2 -3
- package/dist/src/runner-cache-retention.js +1 -0
- package/dist/src/runner-cache-trim.js +1 -0
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-dev-tools-security.js +1 -1
- package/dist/src/runner-device-readiness.js +1 -1
- package/dist/src/runner-device-set.js +1 -0
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-error-classification.js +1 -1
- package/dist/src/runner-exchange.js +1 -1
- package/dist/src/runner-lease.js +1 -0
- package/dist/src/runner-operations-facade.js +1 -1
- package/dist/src/runner-session-types.js +1 -1
- package/dist/src/runner-start-budget.js +1 -1
- package/dist/src/runner-toolchain-probe.js +2 -0
- package/dist/src/runner.js +1 -1
- package/dist/src/runtime-deployment.js +1 -0
- package/dist/src/runtime.js +1 -1
- package/dist/src/runtime10.js +1 -2
- package/dist/src/runtime11.js +2 -0
- package/dist/src/runtime2.js +2 -5
- package/dist/src/runtime3.js +5 -1
- package/dist/src/runtime4.js +1 -5
- package/dist/src/runtime5.js +5 -1
- package/dist/src/runtime6.js +1 -1
- package/dist/src/runtime7.js +1 -1
- package/dist/src/runtime8.js +1 -1
- package/dist/src/runtime9.js +1 -1
- package/dist/src/screen-recording-transport.js +1 -1
- package/dist/src/screenshot-density.js +1 -1
- package/dist/src/screenshot-overlay-draw.js +1 -1
- package/dist/src/screenshot3.js +2 -2
- package/dist/src/script.js +1 -1
- package/dist/src/scroll-gesture.js +1 -1
- package/dist/src/sdk-batch.js +2 -2
- package/dist/src/sdk-contracts.d.ts +25 -33
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-device.js +1 -1
- package/dist/src/sdk-finders.d.ts +1 -1
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-remote-config.d.ts +4 -0
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.d.ts +1 -1
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selection.js +0 -0
- package/dist/src/selector-pipeline-policy.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session-snapshot.js +1 -1
- package/dist/src/session2.js +5 -5
- package/dist/src/simctl.js +1 -1
- package/dist/src/simulator-boot.js +1 -1
- package/dist/src/simulator-state.js +1 -1
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-capture-annotations.js +1 -1
- package/dist/src/snapshot-desktop-projection.js +1 -1
- package/dist/src/snapshot-private-evidence.js +1 -0
- package/dist/src/snapshot-runtime-binding.js +1 -1
- package/dist/src/snapshot-runtime.js +1 -1
- package/dist/src/snapshot-state.js +1 -1
- package/dist/src/snapshot4.js +1 -1
- package/dist/src/src2.js +1 -1
- package/dist/src/src3.js +1 -1
- package/dist/src/src4.js +1 -1
- package/dist/src/src5.js +1 -1
- package/dist/src/src6.js +1 -1
- package/dist/src/src7.js +1 -1
- package/dist/src/src8.js +20 -20
- package/dist/src/store.js +1 -1
- package/dist/src/target-evidence.js +1 -1
- package/dist/src/text-entry-focus.js +1 -1
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/touch-runtime2.js +1 -1
- package/dist/src/tree.js +1 -1
- package/dist/src/type-text-runtime.js +1 -1
- package/dist/src/video.js +1 -1
- package/package.json +24 -16
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.22.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.22.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.22.apk.sha256 +0 -1
- package/dist/src/capabilities.js +0 -1
- package/dist/src/compatibility-policy.js +0 -1
- package/dist/src/daemon-artifacts.js +0 -1
- package/dist/src/device-claim-rule.js +0 -1
- package/dist/src/human-control-contract.js +0 -1
- package/dist/src/prepare-kind.js +0 -1
- package/dist/src/provider-device-runtimes.js +0 -1
- package/dist/src/screen-recording-admission-ledger.js +0 -1
- package/dist/src/screenshot-runtime.js +0 -1
- package/dist/src/session-routing.js +0 -1
- package/dist/src/session-runtime-admission.js +0 -1
- package/dist/src/session-stream.js +0 -27
- package/dist/src/timeouts.js +0 -1
- package/dist/src/touch-reference-frame.js +0 -1
- package/dist/src/vars.js +0 -2
- package/dist/src/viewport.js +0 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{P as e}from"./sdk-contracts.js";import{A as t,C as n,D as r,E as i,F as a,M as o,N as s,O as c,P as l,S as u,T as d,_ as f,b as p,f as m,g as h,h as g,j as _,k as v,m as ee,v as te,w as y,x as ne,y as re}from"./session-stream.js";import{i as ie,r as b}from"./ios-client.js";import"./instance-client.js";import{promises as ae}from"fs";import"net";import oe from"os";import x,{basename as se}from"path";import ce,{createHash as le}from"crypto";import"child_process";function S(e,t,n,r,i){if(r===`m`)throw TypeError(`Private method is not writable`);if(r===`a`&&!i)throw TypeError(`Private accessor was defined without a setter`);if(typeof t==`function`?e!==t||!i:!t.has(e))throw TypeError(`Cannot write private member to an object whose class did not declare it`);return r===`a`?i.call(e,n):i?i.value=n:t.set(e,n),n}function C(e,t,n,r){if(n===`a`&&!r)throw TypeError(`Private accessor was defined without a getter`);if(typeof t==`function`?e!==t||!r:!t.has(e))throw TypeError(`Cannot read private member from an object whose class did not declare it`);return n===`m`?r:n===`a`?r.call(e):r?r.value:t.get(e)}let ue=function(){let{crypto:e}=globalThis;if(e?.randomUUID)return ue=e.randomUUID.bind(e),e.randomUUID();let t=new Uint8Array(1),n=e?()=>e.getRandomValues(t)[0]:()=>Math.random()*255&255;return`10000000-1000-4000-8000-100000000000`.replace(/[018]/g,e=>(e^n()&15>>e/4).toString(16))};const de=/^[a-z][a-z0-9+.-]*:/i,fe=e=>de.test(e);let w=e=>(w=Array.isArray,w(e)),pe=w;function me(e){return typeof e==`object`?e??{}:{}}function he(e){if(!e)return!0;for(let t in e)return!1;return!0}function ge(e,t){return Object.prototype.hasOwnProperty.call(e,t)}const _e=(e,t)=>{if(typeof t!=`number`||!Number.isInteger(t))throw new v(`${e} must be an integer`);if(t<0)throw new v(`${e} must be a positive integer`);return t},ve=e=>{try{return JSON.parse(e)}catch{return}},T=`0.49.3`;function ye(){return typeof Deno<`u`&&Deno.build!=null?`deno`:typeof EdgeRuntime<`u`?`edge`:Object.prototype.toString.call(globalThis.process===void 0?0:globalThis.process)===`[object process]`?`node`:`unknown`}const be=()=>{let e=ye();if(e===`deno`)return{"X-Stainless-Lang":`js`,"X-Stainless-Package-Version":T,"X-Stainless-OS":E(Deno.build.os),"X-Stainless-Arch":Se(Deno.build.arch),"X-Stainless-Runtime":`deno`,"X-Stainless-Runtime-Version":typeof Deno.version==`string`?Deno.version:Deno.version?.deno??`unknown`};if(typeof EdgeRuntime<`u`)return{"X-Stainless-Lang":`js`,"X-Stainless-Package-Version":T,"X-Stainless-OS":`Unknown`,"X-Stainless-Arch":`other:${EdgeRuntime}`,"X-Stainless-Runtime":`edge`,"X-Stainless-Runtime-Version":globalThis.process.version};if(e===`node`)return{"X-Stainless-Lang":`js`,"X-Stainless-Package-Version":T,"X-Stainless-OS":E(globalThis.process.platform??`unknown`),"X-Stainless-Arch":Se(globalThis.process.arch??`unknown`),"X-Stainless-Runtime":`node`,"X-Stainless-Runtime-Version":globalThis.process.version??`unknown`};let t=xe();return t?{"X-Stainless-Lang":`js`,"X-Stainless-Package-Version":T,"X-Stainless-OS":`Unknown`,"X-Stainless-Arch":`unknown`,"X-Stainless-Runtime":`browser:${t.browser}`,"X-Stainless-Runtime-Version":t.version}:{"X-Stainless-Lang":`js`,"X-Stainless-Package-Version":T,"X-Stainless-OS":`Unknown`,"X-Stainless-Arch":`unknown`,"X-Stainless-Runtime":`unknown`,"X-Stainless-Runtime-Version":`unknown`}};function xe(){if(typeof navigator>`u`||!navigator)return null;for(let{key:e,pattern:t}of[{key:`edge`,pattern:/Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:`ie`,pattern:/MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:`ie`,pattern:/Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:`chrome`,pattern:/Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:`firefox`,pattern:/Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:`safari`,pattern:/(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/}]){let n=t.exec(navigator.userAgent);if(n)return{browser:e,version:`${n[1]||0}.${n[2]||0}.${n[3]||0}`}}return null}const Se=e=>e===`x32`?`x32`:e===`x86_64`||e===`x64`?`x64`:e===`arm`?`arm`:e===`aarch64`||e===`arm64`?`arm64`:e?`other:${e}`:`unknown`,E=e=>(e=e.toLowerCase(),e.includes(`ios`)?`iOS`:e===`android`?`Android`:e===`darwin`?`MacOS`:e===`win32`?`Windows`:e===`freebsd`?`FreeBSD`:e===`openbsd`?`OpenBSD`:e===`linux`?`Linux`:e?`Other:${e}`:`Unknown`);let Ce;const we=()=>Ce??=be();function Te(){if(typeof fetch<`u`)return p.fetch;throw Error("`fetch` is not defined as a global; Either pass `fetch` to the client, `new Limrun({ fetch })` or polyfill the global, `globalThis.fetch = fetch`")}function Ee(...e){let t=globalThis.ReadableStream;if(t===void 0)throw Error("`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`");return new t(...e)}function De(e){let t=Symbol.asyncIterator in e?e[Symbol.asyncIterator]():e[Symbol.iterator]();return Ee({start(){},async pull(e){let{done:n,value:r}=await t.next();n?e.close():e.enqueue(r)},async cancel(){await t.return?.()}})}async function Oe(e){if(typeof e!=`object`||!e)return;if(e[Symbol.asyncIterator]){await e[Symbol.asyncIterator]().return?.();return}let t=e.getReader(),n=t.cancel();t.releaseLock(),await n}const ke=({headers:e,body:t})=>({bodyHeaders:{"content-type":`application/json`},body:JSON.stringify(t)});function Ae(e){return Object.entries(e).filter(([e,t])=>t!==void 0).map(([e,t])=>{if(typeof t==`string`||typeof t==`number`||typeof t==`boolean`)return`${encodeURIComponent(e)}=${encodeURIComponent(t)}`;if(t===null)return`${encodeURIComponent(e)}=`;throw new v(`Cannot stringify type ${typeof t}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`)}).join(`&`)}const D={off:0,error:200,warn:300,info:400,debug:500},O=(e,t,n)=>{if(e){if(ge(D,e))return e;M(n).warn(`${t} was set to ${JSON.stringify(e)}, expected one of ${JSON.stringify(Object.keys(D))}`)}};function k(){}function A(e,t,n){return!t||D[e]>D[n]?k:t[e].bind(t)}const je={error:k,warn:k,info:k,debug:k};let j=new WeakMap;function M(e){let t=e.logger,n=e.logLevel??`off`;if(!t)return je;let r=j.get(t);if(r&&r[0]===n)return r[1];let i={error:A(`error`,t,n),warn:A(`warn`,t,n),info:A(`info`,t,n),debug:A(`debug`,t,n)};return j.set(t,[n,i]),i}const N=e=>(e.options&&(e.options={...e.options},delete e.options.headers),e.headers&&=Object.fromEntries((e.headers instanceof Headers?[...e.headers]:Object.entries(e.headers)).map(([e,t])=>[e,e.toLowerCase()===`authorization`||e.toLowerCase()===`api-key`||e.toLowerCase()===`x-api-key`||e.toLowerCase()===`cookie`||e.toLowerCase()===`set-cookie`?`***`:t])),`retryOfRequestLogID`in e&&(e.retryOfRequestLogID&&(e.retryOf=e.retryOfRequestLogID),delete e.retryOfRequestLogID),e);async function P(e,t){let{response:n,requestLogID:r,retryOfRequestLogID:i,startTime:a}=t,o=await(async()=>{if(n.status===204)return null;if(t.options.__binaryResponse)return n;let e=n.headers.get(`content-type`)?.split(`;`)[0]?.trim();return e?.includes(`application/json`)||e?.endsWith(`+json`)?n.headers.get(`content-length`)===`0`?void 0:await n.json():await n.text()})();return M(e).debug(`[${r}] response parsed`,N({retryOfRequestLogID:i,url:n.url,status:n.status,body:o,durationMs:Date.now()-a})),o}var F,I=class e extends Promise{constructor(e,t,n=P){super(e=>{e(null)}),this.responsePromise=t,this.parseResponse=n,F.set(this,void 0),S(this,F,e,`f`)}_thenUnwrap(t){return new e(C(this,F,`f`),this.responsePromise,async(e,n)=>t(await this.parseResponse(e,n),n))}asResponse(){return this.responsePromise.then(e=>e.response)}async withResponse(){let[e,t]=await Promise.all([this.parse(),this.asResponse()]);return{data:e,response:t}}parse(){return this.parsedPromise||=this.responsePromise.then(e=>this.parseResponse(C(this,F,`f`),e)),this.parsedPromise}then(e,t){return this.parse().then(e,t)}catch(e){return this.parse().catch(e)}finally(e){return this.parse().finally(e)}};F=new WeakMap;var L,Me=class{constructor(e,t,n,r){L.set(this,void 0),S(this,L,e,`f`),this.options=r,this.response=t,this.body=n}hasNextPage(){return this.getPaginatedItems().length?this.nextPageRequestOptions()!=null:!1}async getNextPage(){let e=this.nextPageRequestOptions();if(!e)throw new v("No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`.");return await C(this,L,`f`).requestAPIList(this.constructor,e)}async*iterPages(){let e=this;for(yield e;e.hasNextPage();)e=await e.getNextPage(),yield e}async*[(L=new WeakMap,Symbol.asyncIterator)](){for await(let e of this.iterPages())for(let t of e.getPaginatedItems())yield t}},Ne=class extends I{constructor(e,t,n){super(e,t,async(e,t)=>new n(e,t.response,await P(e,t),t.options))}async*[Symbol.asyncIterator](){let e=await this;for await(let t of e)yield t}},R=class extends Me{constructor(e,t,n,r){super(e,t,n,r),this.items=n||[]}getPaginatedItems(){return this.items??[]}nextPageRequestOptions(){let e=this.getPaginatedItems();if(!(typeof this.options.query==`object`&&`endingBefore`in(this.options.query||{}))){let t=e[e.length-1]?.metadata.id;return t?{...this.options,query:{...me(this.options.query),startingAfter:t}}:null}let t=e[0]?.metadata.id;return t?{...this.options,query:{...me(this.options.query),endingBefore:t}}:null}};const Pe=()=>{if(typeof File>`u`){let{process:e}=globalThis,t=typeof e?.versions?.node==`string`&&parseInt(e.versions.node.split(`.`))<20;throw Error("`File` is not defined as a global, which is required for file uploads."+(t?" Update to Node 20 LTS or newer, or set `globalThis.File` to `import('node:buffer').File`.":``))}};function z(e,t,n){return Pe(),new File(e,t??`unknown_file`,n)}function Fe(e){return(typeof e==`object`&&!!e&&(`name`in e&&e.name&&String(e.name)||`url`in e&&e.url&&String(e.url)||`filename`in e&&e.filename&&String(e.filename)||`path`in e&&e.path&&String(e.path))||``).split(/[\\/]/).pop()||void 0}const Ie=e=>typeof e==`object`&&!!e&&typeof e[Symbol.asyncIterator]==`function`,Le=e=>typeof e==`object`&&!!e&&typeof e.size==`number`&&typeof e.type==`string`&&typeof e.text==`function`&&typeof e.slice==`function`&&typeof e.arrayBuffer==`function`,Re=e=>typeof e==`object`&&!!e&&typeof e.name==`string`&&typeof e.lastModified==`number`&&Le(e),ze=e=>typeof e==`object`&&!!e&&typeof e.url==`string`&&typeof e.blob==`function`;async function Be(e,t,n){if(Pe(),e=await e,Re(e))return e instanceof File?e:z([await e.arrayBuffer()],e.name);if(ze(e)){let r=await e.blob();return t||=new URL(e.url).pathname.split(/[\\/]/).pop(),z(await B(r),t,n)}let r=await B(e);if(t||=Fe(e),!n?.type){let e=r.find(e=>typeof e==`object`&&`type`in e&&e.type);typeof e==`string`&&(n={...n,type:e})}return z(r,t,n)}async function B(e){let t=[];if(typeof e==`string`||ArrayBuffer.isView(e)||e instanceof ArrayBuffer)t.push(e);else if(Le(e))t.push(e instanceof Blob?e:await e.arrayBuffer());else if(Ie(e))for await(let n of e)t.push(...await B(n));else{let t=e?.constructor?.name;throw Error(`Unexpected data type: ${typeof e}${t?`; constructor: ${t}`:``}${Ve(e)}`)}return t}function Ve(e){return typeof e!=`object`||!e?``:`; props: [${Object.getOwnPropertyNames(e).map(e=>`"${e}"`).join(`, `)}]`}var V=class{constructor(e){this._client=e}},He=class extends V{get(e,t){return this._client.get(`/v1/analytics`,{query:e,...t})}getInstances(e,t){return this._client.get(`/v1/analytics/instances`,{query:e,...t})}};const Ue=Symbol(`brand.privateNullableHeaders`);function*We(e){if(!e)return;if(Ue in e){let{values:t,nulls:n}=e;yield*t.entries();for(let e of n)yield[e,null];return}let t=!1,n;e instanceof Headers?n=e.entries():pe(e)?n=e:(t=!0,n=Object.entries(e??{}));for(let e of n){let n=e[0];if(typeof n!=`string`)throw TypeError(`expected header name to be a string`);let r=pe(e[1])?e[1]:[e[1]],i=!1;for(let e of r)e!==void 0&&(t&&!i&&(i=!0,yield[n,null]),yield[n,e])}}const H=e=>{let t=new Headers,n=new Set;for(let r of e){let e=new Set;for(let[i,a]of We(r)){let r=i.toLowerCase();e.has(r)||(t.delete(i),e.add(r)),a===null?(t.delete(i),n.add(r)):(t.append(i,a),n.delete(r))}}return{[Ue]:!0,values:t,nulls:n}};function Ge(e){return e.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g,encodeURIComponent)}const Ke=Object.freeze(Object.create(null)),U=((e=Ge)=>function(t,...n){if(t.length===1)return t[0];let r=!1,i=[],a=t.reduce((t,a,o)=>{/[?#]/.test(a)&&(r=!0);let s=n[o],c=(r?encodeURIComponent:e)(``+s);return o!==n.length&&(s==null||typeof s==`object`&&s.toString===Object.getPrototypeOf(Object.getPrototypeOf(s.hasOwnProperty??Ke)??Ke)?.toString)&&(c=s+``,i.push({start:t.length+a.length,length:c.length,error:`Value of type ${Object.prototype.toString.call(s).slice(8,-1)} is not a valid path parameter`})),t+a+(o===n.length?``:c)},``),o=a.split(/[?#]/,1)[0],s=/(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi,c;for(;(c=s.exec(o))!==null;)i.push({start:c.index,length:c[0].length,error:`Value "${c[0]}" can\'t be safely passed as a path parameter`});if(i.sort((e,t)=>e.start-t.start),i.length>0){let e=0,t=i.reduce((t,n)=>{let r=` `.repeat(n.start-e),i=`^`.repeat(n.length);return e=n.start+n.length,t+r+i},``);throw new v(`Path parameters result in path with invalid segments:\n${i.map(e=>e.error).join(`
|
|
2
|
-
`)}\n${a}\n${t}`)}return a})(Ge);var W=class extends V{create(e,t){let{reuseIfExists:n,wait:r,...i}=e;return this._client.post(`/v1/gradle_instances`,{query:{reuseIfExists:n,wait:r},body:i,...t})}list(e={},t){return this._client.getAPIList(`/v1/gradle_instances`,R,{query:e,...t})}delete(e,t){return this._client.delete(U`/v1/gradle_instances/${e}`,{...t,headers:H([{Accept:`*/*`},t?.headers])})}get(e,t){return this._client.get(U`/v1/gradle_instances/${e}`,t)}},qe=class extends V{create(e,t){return this._client.post(`/v1/scoped_tokens`,{body:e,...t})}},Je=class extends V{list(e={},t){return this._client.get(`/v1/assets`,{query:e,...t})}delete(e,t){return this._client.delete(U`/v1/assets/${e}`,{...t,headers:H([{Accept:`*/*`},t?.headers])})}get(e,t={},n){return this._client.get(U`/v1/assets/${e}`,{query:t,...n})}getOrCreate(e,t){return this._client.put(`/v1/assets`,{body:e,...t})}};function Ye(e,t){if(!t)return{body:e};let n=0;return{body:new ReadableStream({pull(r){if(n>=e.length){r.close();return}let i=e.subarray(n,Math.min(n+262144,e.length));n+=i.length,r.enqueue(i),t(n,e.length)}}),duplex:`half`}}var Xe=class extends Je{async getOrUpload(e,t){let n=await this.getOrCreate({name:e.name??se(e.path),kind:e.kind??`App`,...e.platform&&{platform:e.platform},...e.ttl&&{ttl:e.ttl},...e.uploadOptions},t),r=await ae.readFile(e.path),i=le(`md5`).update(r).digest(`hex`);if(n.md5&&n.md5===i)return{id:n.id,name:n.name,signedDownloadUrl:n.signedDownloadUrl,kind:n.kind,...n.platform&&{platform:n.platform},md5:n.md5,...n.expiresAt&&{expiresAt:n.expiresAt}};let a=await p.fetch(n.signedUploadUrl,{headers:{...e.onUploadProgress&&{"Content-Length":r.length.toString()},"Content-Type":`application/octet-stream`},method:`PUT`,...Ye(r,e.onUploadProgress)});if(a.status!==200)throw Error(`Failed to upload asset: ${a.status} ${await a.text()}`);return{id:n.id,name:n.name,signedDownloadUrl:n.signedDownloadUrl,kind:n.kind,...n.platform&&{platform:n.platform},md5:i,...n.expiresAt&&{expiresAt:n.expiresAt}}}},Ze=class extends V{create(e,t){let{reuseIfExists:n,wait:r,...i}=e;return this._client.post(`/v1/ios_instances`,{query:{reuseIfExists:n,wait:r},body:i,...t})}list(e={},t){return this._client.getAPIList(`/v1/ios_instances`,R,{query:e,...t})}delete(e,t){return this._client.delete(U`/v1/ios_instances/${e}`,{...t,headers:H([{Accept:`*/*`},t?.headers])})}get(e,t){return this._client.get(U`/v1/ios_instances/${e}`,t)}},Qe=class extends Ze{listSessionArtifacts(e,t,n){return this._client.get(U`/v1/ios_instances/${e}/session_artifacts`,{query:t?{kind:t}:void 0,...n})}listRecordings(e,t){return this.listSessionArtifacts(e,`recording`,t)}listAppLogs(e,t){return this.listSessionArtifacts(e,`appLog`,t)}listEvents(e,t){return this.listSessionArtifacts(e,`eventLog`,t)}},$e=class extends V{create(e,t){let{reuseIfExists:n,wait:r,...i}=e;return this._client.post(`/v1/android_instances`,{query:{reuseIfExists:n,wait:r},body:i,...t})}list(e={},t){return this._client.getAPIList(`/v1/android_instances`,R,{query:e,...t})}delete(e,t){return this._client.delete(U`/v1/android_instances/${e}`,{...t,headers:H([{Accept:`*/*`},t?.headers])})}get(e,t){return this._client.get(U`/v1/android_instances/${e}`,t)}},et=class extends $e{listSessionArtifacts(e,t,n){return this._client.get(U`/v1/android_instances/${e}/session_artifacts`,{query:t?{kind:t}:void 0,...n})}listRecordings(e,t){return this.listSessionArtifacts(e,`recording`,t)}listAppLogs(e,t){return this.listSessionArtifacts(e,`appLog`,t)}listEvents(e,t){return this.listSessionArtifacts(e,`eventLog`,t)}},tt=class extends V{create(e,t){let{reuseIfExists:n,wait:r,...i}=e;return this._client.post(`/v1/xcode_instances`,{query:{reuseIfExists:n,wait:r},body:i,...t})}list(e={},t){return this._client.getAPIList(`/v1/xcode_instances`,R,{query:e,...t})}delete(e,t){return this._client.delete(U`/v1/xcode_instances/${e}`,{...t,headers:H([{Accept:`*/*`},t?.headers])})}get(e,t){return this._client.get(U`/v1/xcode_instances/${e}`,t)}},nt=class extends Error{constructor(e){super(`Instance ${e} was gone before it reported any cache status`),this.instanceId=e,this.name=`XcodeCacheGoneError`}},rt=class extends Error{constructor(e,t,n){super(`Timed out after ${Math.round(t/1e3)}s waiting for the cache ${e} to finish`+(n?` (last phase: ${n[e].phase})`:``)),this.side=e,this.timeoutMs=t,this.cache=n,this.name=`XcodeCacheTimeoutError`}};const it={restore:12e5,save:72e4};function at(e){return e===`disabled`||e===`unsupported`||e===`restored`||e===`skipped`||e===`failed`}function ot(e){return e===`disabled`||e===`published`||e===`skipped`||e===`failed`||e===`timed_out`}function st(e,t){return t===`restore`?at(e.restore.phase):ot(e.save.phase)}function ct(e,t={}){let n=t.side??`restore`,r=t.timeoutMs??it[n],i=e.baseURL;for(;i.endsWith(`/`);)i=i.slice(0,-1);let a=`${i}/v1/xcode_instances/${encodeURIComponent(e.instanceId)}/cache`;return new Promise((i,o)=>{let s,c=``,l=!1,u=e=>{if(!l){l=!0,clearTimeout(d),t.signal?.removeEventListener(`abort`,f);try{g.close()}catch{}e()}},d=setTimeout(()=>u(()=>o(new rt(n,r,s))),r),f=()=>u(()=>o(t.signal?.reason??Error(`aborted`))),m=!1,h=()=>{m||l||(m=!0,p.fetch(a,{headers:{Authorization:`Bearer ${e.apiKey}`,Accept:`application/json`}}).then(async t=>{if(m=!1,t.status!==404){await t.text().catch(()=>void 0);return}u(()=>s?i({cache:s,gone:!0}):o(new nt(e.instanceId)))}).catch(()=>{m=!1}))},g=re({url:a,fetch:async(t,n)=>{let r=await p.fetch(t,n);return r.status===404&&u(()=>s?i({cache:s,gone:!0}):o(new nt(e.instanceId))),r},onConnect:()=>t.onOpen?.(),headers:{Authorization:`Bearer ${e.apiKey}`,Accept:`text/event-stream`},onMessage:e=>{if(e.event!==`cache`&&e.event!==`gone`)return;let r;try{r=JSON.parse(typeof e.data==`string`?e.data:String(e.data))}catch(e){u(()=>o(Error(`Cache stream sent unreadable data: ${e}`)));return}if(s=r,e.event===`gone`){h();return}let a=`${r.restore.phase}/${r.restore.reason??``}|${r.save.phase}/${r.save.reason??``}`;a!==c&&(c=a,t.onUpdate?.(r)),st(r,n)&&u(()=>i({cache:r,gone:!1}))}});if(t.signal?.aborted){f();return}t.signal?.addEventListener(`abort`,f,{once:!0})})}function lt(e,t){let n=x.resolve(e),r=`limsync-cache-${x.basename(n)}-${ce.createHash(`sha1`).update(n).digest(`hex`).slice(0,8)}`;return{cacheKey:r,basisCacheDir:t??x.join(oe.tmpdir(),r)}}function G(e,t,n,r){return e.getOrCreate({name:t,ttl:n||`336h`,...r}).catch(e=>{let n=`Failed to create upload URL for asset '${t}': ${e instanceof Error?e.message:e}`;throw Error(n,{cause:e})})}const ut=[`none`,`error`,`warn`,`info`,`debug`];function dt(e,t){let n=ut.indexOf(t),r=e=>n>=ut.indexOf(e);return(t,n)=>{r(t)&&(t===`error`||t===`warn`?console[t](e,n):console.log(e,n))}}const ft=/^[A-Z0-9_]+$/,pt=4096,mt=65536;function ht(e){let t=Object.entries(e);if(t.length>32)throw Error(`too many build settings: got ${t.length}, max 32`);let n=0;for(let[e,r]of t){if(!ft.test(e))throw Error(`invalid build setting key "${e}": keys must match ^[A-Z0-9_]+$`);if(typeof r!=`string`)throw Error(`invalid build setting value for "${e}": value must be a string`);let t=Buffer.byteLength(r,`utf8`);if(t>pt)throw Error(`build setting value for "${e}" is too large: got ${t} bytes, max ${pt} bytes`);if(n+=Buffer.byteLength(e,`utf8`)+t,n>mt)throw Error(`build settings payload is too large: max ${mt} bytes`)}}const gt=e=>new Promise(t=>setTimeout(t,e)),_t=/failed: (?:502|503|504)\b|\bEOF\b|ECONNRESET|ECONNREFUSED|socket hang up|fetch failed/i;function vt(e){let t=e instanceof Error?e.message:String(e);return _t.test(t)}async function yt(e,t={}){let n=t.sleep??gt,r=t.attempts??5,i=t.retryOn??vt,a;for(let o=1;o<=r;o++)try{return await e()}catch(e){if(!i(e))throw e;if(a=e,o<r){let r=e instanceof Error?e.message:String(e);t.log?.(`Retrying after error (${r.trim()})...`),await n(2e3*o)}}throw a}function bt(e){if(e===``||e.startsWith(`/`)||e.includes(`\\`)||e.includes(`\0`))throw Error(`invalid sandbox home path from server: ${e}`);let t=e.split(`/`);if(t.some(e=>e===``||e===`.`||e===`..`))throw Error(`invalid sandbox home path from server: ${e}`);return t.join(`/`)}async function xt(e,t){let n=await J(await p.fetch(`${e}/info`,{method:`GET`,headers:{Authorization:`Bearer ${t}`}}),`GET /info`);if(!n.homeDir)throw Error(`GET /info response is missing homeDir`);return{homeDir:bt(n.homeDir),...n.xcode?{xcode:n.xcode}:{}}}function St(e){let t=new URL(e);if(t.protocol===`https:`)t.protocol=`wss:`;else if(t.protocol===`http:`)t.protocol=`ws:`;else throw Error(`Unsupported apiUrl protocol for rbe tunnel: ${t.protocol}`);return t.pathname=`${t.pathname.replace(/\/+$/,``)}/rbe/tunnel`,t.search=``,t.hash=``,t.toString()}var Ct=class extends v{constructor(e){super(`Remote build execution is not available on this Xcode instance (${e} returned 404). Its limbuild may predate RBE support, or you may be targeting the wrong environment (for example production instead of staging).`),this.name=`RbeUnsupportedError`}},wt=class extends v{constructor(e){super(`Xcode version selection is not available on this sandbox (${e} returned 404): its daemon predates Xcode selection. Create a new sandbox, or omit the Xcode version to build with its default.`),this.name=`XcodeSelectionUnsupportedError`}};function Tt(e,t){return q(e,t,e=>new wt(e))}function K(e,t){return q(e,t,e=>new Ct(e))}async function q(e,t,n){if(e.status===404)throw await e.text().catch(()=>void 0),n(t);return J(e,t)}async function J(e,t){let n=await e.text();if(!e.ok)throw g(t,e.status,n,e.headers);if(!n.trim())throw Error(`${t} returned an empty response`);return JSON.parse(n)}var Et=class extends tt{listBuildLogs(e,t){return this._client.get(U`/v1/xcode_instances/${e}/build_logs`,t)}listBazelBuildLogs(e,t){return this._client.get(U`/v1/xcode_instances/${e}/bazel_build_logs`,t)}create(e,t){return super.create(e,t)}getCache(e,t){return this._client.get(U`/v1/xcode_instances/${e}/cache`,t)}bindCacheKey(e,t,n){return this._client.put(U`/v1/xcode_instances/${e}/cache`,{body:{key:t},...n})}followCache(e,t){let n=this._client.apiKey;if(!n)throw Error(`Following cache status needs an API key on the client`);return ct({baseURL:this._client.baseURL,apiKey:n,instanceId:e},t)}async createClient(e){let t,n;if(`instance`in e){if(!e.instance.status.apiUrl)throw Error(`Instance not ready: apiUrl is not available`);t=e.instance.status.apiUrl,n=e.instance.status.token}else t=e.apiUrl,n=e.token;let r=dt(`[XcodeInstance]`,e.logLevel??`info`),i=this._client,a,o=()=>(a??=xt(t,n),a),s=async e=>{let r,i;if(`status`in e){if(!e.status.apiUrl)throw Error(`Simulator instance not ready: apiUrl is not available`);r=e.status.apiUrl,i=e.status.token}else r=e.apiUrl,i=e.token;return J(await p.fetch(`${t}/simulator`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${n}`},body:JSON.stringify({apiUrl:r,token:i})}),`POST /simulator`)},c=async e=>{try{return await i.iosInstances.delete(e),!0}catch{return!1}};return{async sync(e,i){let{cacheKey:a,basisCacheDir:s}=lt(e,i?.basisCacheDir),c=i?.additionalFiles&&i.additionalFiles.length>0?await o():void 0,l=i?.additionalFiles?.map(e=>({localPath:e.localPath,remotePath:c&&e.remotePath.startsWith(`~/`)?`${c.homeDir}/${e.remotePath.slice(2)}`:e.remotePath})),u={apiUrl:t,token:n,udid:a,install:i?.install??!0,ignoreFn:await b(e,{basisCacheDir:s,log:r,xcodeDefaults:!0,...i?.include?{include:i.include}:{},...i?.ignore?{additional:i.ignore}:{}}),basisCacheDir:s,watch:i?.watch??!0,launchMode:`ForegroundIfRunning`,log:r,syncSymlinks:!0,...l?{additionalFiles:l}:{},...i?.onSyncComplete?{onSyncComplete:i.onSyncComplete}:{}},d=await ee(e,u),f={};return d.bytesSent!==void 0&&(f.bytesSent=d.bytesSent),d.stopWatching&&(f.stopWatching=d.stopWatching),f},xcodebuild(e,a){if(a?.reactNative?.devServerURL&&e?.configuration===`Release`)throw Error(`reactNative.devServerURL is only supported for Debug builds`);if(e?.onlyTesting?.length&&e?.skipTesting?.length)throw Error(`onlyTesting and skipTesting are mutually exclusive; pass one`);if((e?.onlyTesting?.length||e?.skipTesting?.length)&&e?.action!==`build-for-testing`)throw Error(`onlyTesting/skipTesting require action: 'build-for-testing'`);if(e?.runTests===!1&&e?.action!==`build-for-testing`)throw Error(`runTests: false requires action: 'build-for-testing'`);if(e?.action===`build-for-testing`&&e.sdk!==void 0&&e.sdk!==`iphonesimulator`)throw Error(`action: 'build-for-testing' requires the iphonesimulator sdk`);a?.buildSettings&&ht(a.buildSettings);let o={command:`xcodebuild`,...e&&{xcodebuild:e},...a?.xcodegen&&{xcodegen:a.xcodegen},...a?.reactNative&&{reactNative:a.reactNative},...a?.signing&&{signing:a.signing},...a?.cloudSigning&&{cloudSigning:a.cloudSigning},...a?.appstore&&{testflight:a.appstore},...a?.buildSettings&&{buildSettings:a.buildSettings},...a?.env?.length&&{env:a.env},...a?.gitInit!==void 0&&{gitInit:a.gitInit},...a?.logProcessor&&{logProcessor:a.logProcessor},...a?.webhook&&{webhook:a.webhook}},s={apiUrl:t,token:n,log:r,...a?.onXctestEvent&&{onXctestEvent:a.onXctestEvent}};if(a?.upload&&`assetName`in a.upload){let e=G(i.assets,a.upload.assetName,a.upload.ttl,a.upload.uploadOptions).then(e=>(o.signedUploadUrl=e.signedUploadUrl,o.assetId=e.id,o.additionalMetadata={signedDownloadUrl:e.signedDownloadUrl},o));return f(e,s)}return a?.upload&&`signedUploadUrl`in a.upload&&(o.signedUploadUrl=a.upload.signedUploadUrl),f(o,s)},run(e,i){if(e.trim()===``)throw Error(`commandLine must not be empty`);if(i?.timeoutSeconds!==void 0&&(!Number.isInteger(i.timeoutSeconds)||i.timeoutSeconds<1||i.timeoutSeconds>21600))throw Error(`timeoutSeconds must be an integer between 1 and 21600`);let a={command:`run`,commandLine:e,cwd:i?.cwd??`.`,...i?.env&&{env:i.env},...i?.timeoutSeconds!==void 0&&{timeoutSeconds:i.timeoutSeconds}};return f(a,{apiUrl:t,token:n,log:r})},async getSimulator(){return J(await p.fetch(`${t}/simulator`,{method:`GET`,headers:{Authorization:`Bearer ${n}`}}),`GET /simulator`)},attachSimulator:s,attachNewSimulator:async()=>{let e=await i.iosInstances.create({wait:!0});try{await s(e)}catch(t){throw await c(e.metadata.id),t}return{iosInstanceId:e.metadata.id,simulator:e}},deleteSimulator:c,async getXcode(){return Tt(await p.fetch(`${t}/xcode`,{method:`GET`,headers:{Authorization:`Bearer ${n}`}}),`GET /xcode`)},async setXcode(e){return Tt(await p.fetch(`${t}/xcode`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${n}`},body:JSON.stringify({version:e})}),`POST /xcode`)},getInfo:()=>xt(t,n),async startRbe(e){return K(await p.fetch(`${t}/rbe`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${n}`},body:JSON.stringify(e??{})}),`POST /rbe`)},async getRbe(){return K(await p.fetch(`${t}/rbe`,{method:`GET`,headers:{Authorization:`Bearer ${n}`}}),`GET /rbe`)},async stopRbe(){return K(await p.fetch(`${t}/rbe`,{method:`DELETE`,headers:{Authorization:`Bearer ${n}`}}),`DELETE /rbe`)},async startRbeTunnel(r){return m(St(t),n,r?.host??`127.0.0.1`,r?.port??8980,{mode:`multiplexed`,logLevel:r?.logLevel??e.logLevel??`info`})},async uploadLatestRbeBuild(e){let r,a;if(e.assetName!==void 0){if(!e.assetName)throw Error(`assetName must not be empty`);let t=await G(i.assets,e.assetName,e.ttl);r=t.signedUploadUrl,a=t.signedDownloadUrl}else r=e.signedUploadUrl;return{...await yt(async()=>{let e=await p.fetchLongRequest(`${t}/rbe/upload`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${n}`},body:JSON.stringify({signedUploadUrl:r})});if(e.status===404)throw await e.text().catch(()=>void 0),Error(`POST /rbe/upload returned 404: the instance may no longer exist, or its limbuild predates RBE upload support. Recreate the instance and retry.`);return J(e,`POST /rbe/upload`)},{retryOn:e=>vt(e)||h(e,400)&&/no successful RBE app build/i.test(e.body)}),...a&&{signedDownloadUrl:a}}},async getActiveRbeBuilds(){return K(await p.fetch(`${t}/rbe/builds/active`,{method:`GET`,headers:{Authorization:`Bearer ${n}`}}),`GET /rbe/builds/active`)},async getRecentRbeBuilds(){return K(await p.fetch(`${t}/rbe/builds/recent`,{method:`GET`,headers:{Authorization:`Bearer ${n}`}}),`GET /rbe/builds/recent`)},waitForRbeBuildEnd(e,r){return new Promise((i,a)=>{if(r?.signal?.aborted){a(Error(`waiting for build ${e} was aborted`));return}let o=!1,s=()=>{d.close(),r?.signal?.removeEventListener(`abort`,u)},c=e=>{o||(o=!0,s(),i(e))},l=e=>{o||(o=!0,s(),a(e))},u=()=>l(Error(`waiting for build ${e} was aborted`)),d=re({url:`${t}/exec/${e}/events`,fetch:te(p.fetch,t=>l(Error(`build event stream for ${e} is unreachable: ${t instanceof Error?t.message:t}`))),headers:{Authorization:`Bearer ${n}`},onMessage:t=>{if(t.event!==`end`)return;let n;try{n=JSON.parse(t.data)}catch(t){l(Error(`invalid build end event for ${e}: ${t}`));return}c(n)},onDisconnect:()=>{l(Error(`build event stream for ${e} ended without a terminal event (the build may have finished and its live stream been removed)`))}});r?.signal?.addEventListener(`abort`,u,{once:!0})})}}}};function Dt(e){let t=e.endsWith(`/`)?e.slice(0,-1):e,n=t.split(`/`);return n[n.length-1]===`local.properties`||n.length===1&&(t===`.gradle`||t===`.kotlin`||t===`build`)}var Ot=class extends W{listBuildLogs(e,t){return this._client.get(U`/v1/gradle_instances/${e}/build_logs`,t)}async createClient(e){let t,n;if(`instance`in e){if(!e.instance.status.apiUrl)throw Error(`Instance not ready: apiUrl is not available`);t=e.instance.status.apiUrl,n=e.instance.status.token}else t=e.apiUrl,n=e.token;let r=dt(`[GradleInstance]`,e.logLevel??`info`),i=this._client;return{async sync(e,i){let{cacheKey:a,basisCacheDir:o}=lt(e,i?.basisCacheDir),s=i?.ignore,c={apiUrl:t,token:n,udid:a,install:!1,ignoreFn:await b(e,{basisCacheDir:o,log:r,xcodeDefaults:!1,nestedGitignore:!0,additional:s?e=>Dt(e)||s(e):Dt,...i?.include?{include:i.include}:{}}),basisCacheDir:o,watch:!1,launchMode:`ForegroundIfRunning`,log:r,syncSymlinks:!0},l=await ee(e,c),u={};return l.bytesSent!==void 0&&(u.bytesSent=l.bytesSent),u},gradlebuild(e){let a={command:`gradlebuild`,...e?.tasks?.length&&{tasks:e.tasks},...e?.projectPath&&{projectPath:e.projectPath},...e?.reactNative&&{reactNative:e.reactNative},...e?.signing&&{signing:e.signing},...e?.webhook&&{webhook:e.webhook},...e?.playstore&&{playstore:e.playstore}};if(e?.upload&&`assetName`in e.upload){let o=G(i.assets,e.upload.assetName,e.upload.ttl).then(e=>(a.signedUploadUrl=e.signedUploadUrl,a.additionalMetadata={signedDownloadUrl:e.signedDownloadUrl},a));return f(o,{apiUrl:t,token:n,log:r})}return e?.upload&&`signedUploadUrl`in e.upload&&(a.signedUploadUrl=e.upload.signedUploadUrl),f(a,{apiUrl:t,token:n,log:r})}}}};W.prototype.listBuildLogs=Ot.prototype.listBuildLogs,W.prototype.createClient=Ot.prototype.createClient;const Y=e=>{if(globalThis.process!==void 0)return globalThis.process.env?.[e]?.trim()||void 0;if(globalThis.Deno!==void 0)return globalThis.Deno.env?.get?.(e)?.trim()||void 0};var X,Z,Q,kt,$=class{constructor({baseURL:e=Y(`LIMRUN_BASE_URL`),apiKey:t=Y(`LIM_API_KEY`)??null,...n}={}){X.add(this),Q.set(this,void 0),this.androidInstances=new et(this),this.assets=new Xe(this),this.iosInstances=new Qe(this),this.xcodeInstances=new Et(this),this.gradleInstances=new W(this),this.analytics=new He(this),this.scopedTokens=new qe(this);let r={apiKey:t,...n,baseURL:e||`https://api.limrun.com`};this.baseURL=r.baseURL,this.timeout=r.timeout??Z.DEFAULT_TIMEOUT,this.logger=r.logger??console;let i=`warn`;this.logLevel=i,this.logLevel=O(r.logLevel,`ClientOptions.logLevel`,this)??O(Y(`LIMRUN_LOG`),`process.env['LIMRUN_LOG']`,this)??i,this.fetchOptions=r.fetchOptions,this.maxRetries=r.maxRetries??2,this.fetch=r.fetch??Te(),S(this,Q,ke,`f`);let a=Y(`LIMRUN_CUSTOM_HEADERS`);if(a){let e={};for(let t of a.split(`
|
|
3
|
-
`)){let n=t.indexOf(`:`);n>=0&&(e[t.substring(0,n).trim()]=t.substring(n+1).trim())}r.defaultHeaders={...e,...r.defaultHeaders}}this._options=r,this.apiKey=t}withOptions(e){return new this.constructor({...this._options,baseURL:this.baseURL,maxRetries:this.maxRetries,timeout:this.timeout,logger:this.logger,logLevel:this.logLevel,fetch:this.fetch,fetchOptions:this.fetchOptions,apiKey:this.apiKey,...e})}defaultQuery(){return this._options.defaultQuery}validateHeaders({values:e,nulls:t}){if(!(this.apiKey&&e.get(`authorization`))&&!t.has(`authorization`))throw Error(`Could not resolve authentication method. Expected the apiKey to be set. Or for the "Authorization" headers to be explicitly omitted`)}async authHeaders(e){if(this.apiKey!=null)return
|
|
1
|
+
import{P as e}from"./sdk-contracts.js";import{A as t,C as n,D as r,E as i,F as a,I as o,L as s,M as c,N as l,O as u,P as d,R as f,S as p,T as m,_ as h,b as g,g as _,j as v,k as ee,m as te,v as y,w as ne,x as re,y as ie}from"./log-stream.js";import{i as ae,r as oe}from"./ios-client.js";import"./instance-client.js";import{promises as se}from"fs";import"net";import ce from"os";import b,{basename as le}from"path";import ue,{createHash as de}from"crypto";import"child_process";function x(e,t,n,r,i){if(r===`m`)throw TypeError(`Private method is not writable`);if(r===`a`&&!i)throw TypeError(`Private accessor was defined without a setter`);if(typeof t==`function`?e!==t||!i:!t.has(e))throw TypeError(`Cannot write private member to an object whose class did not declare it`);return r===`a`?i.call(e,n):i?i.value=n:t.set(e,n),n}function S(e,t,n,r){if(n===`a`&&!r)throw TypeError(`Private accessor was defined without a getter`);if(typeof t==`function`?e!==t||!r:!t.has(e))throw TypeError(`Cannot read private member from an object whose class did not declare it`);return n===`m`?r:n===`a`?r.call(e):r?r.value:t.get(e)}let fe=function(){let{crypto:e}=globalThis;if(e?.randomUUID)return fe=e.randomUUID.bind(e),e.randomUUID();let t=new Uint8Array(1),n=e?()=>e.getRandomValues(t)[0]:()=>Math.random()*255&255;return`10000000-1000-4000-8000-100000000000`.replace(/[018]/g,e=>(e^n()&15>>e/4).toString(16))};const pe=/^[a-z][a-z0-9+.-]*:/i,me=e=>pe.test(e);let C=e=>(C=Array.isArray,C(e)),he=C;function ge(e){return typeof e==`object`?e??{}:{}}function _e(e){if(!e)return!0;for(let t in e)return!1;return!0}function ve(e,t){return Object.prototype.hasOwnProperty.call(e,t)}const ye=(e,t)=>{if(typeof t!=`number`||!Number.isInteger(t))throw new c(`${e} must be an integer`);if(t<0)throw new c(`${e} must be a positive integer`);return t},be=e=>{try{return JSON.parse(e)}catch{return}},w=`0.59.0`;function xe(){return typeof Deno<`u`&&Deno.build!=null?`deno`:typeof EdgeRuntime<`u`?`edge`:Object.prototype.toString.call(globalThis.process===void 0?0:globalThis.process)===`[object process]`?`node`:`unknown`}const Se=()=>{let e=xe();if(e===`deno`)return{"X-Stainless-Lang":`js`,"X-Stainless-Package-Version":w,"X-Stainless-OS":Te(Deno.build.os),"X-Stainless-Arch":we(Deno.build.arch),"X-Stainless-Runtime":`deno`,"X-Stainless-Runtime-Version":typeof Deno.version==`string`?Deno.version:Deno.version?.deno??`unknown`};if(typeof EdgeRuntime<`u`)return{"X-Stainless-Lang":`js`,"X-Stainless-Package-Version":w,"X-Stainless-OS":`Unknown`,"X-Stainless-Arch":`other:${EdgeRuntime}`,"X-Stainless-Runtime":`edge`,"X-Stainless-Runtime-Version":globalThis.process.version};if(e===`node`)return{"X-Stainless-Lang":`js`,"X-Stainless-Package-Version":w,"X-Stainless-OS":Te(globalThis.process.platform??`unknown`),"X-Stainless-Arch":we(globalThis.process.arch??`unknown`),"X-Stainless-Runtime":`node`,"X-Stainless-Runtime-Version":globalThis.process.version??`unknown`};let t=Ce();return t?{"X-Stainless-Lang":`js`,"X-Stainless-Package-Version":w,"X-Stainless-OS":`Unknown`,"X-Stainless-Arch":`unknown`,"X-Stainless-Runtime":`browser:${t.browser}`,"X-Stainless-Runtime-Version":t.version}:{"X-Stainless-Lang":`js`,"X-Stainless-Package-Version":w,"X-Stainless-OS":`Unknown`,"X-Stainless-Arch":`unknown`,"X-Stainless-Runtime":`unknown`,"X-Stainless-Runtime-Version":`unknown`}};function Ce(){if(typeof navigator>`u`||!navigator)return null;for(let{key:e,pattern:t}of[{key:`edge`,pattern:/Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:`ie`,pattern:/MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:`ie`,pattern:/Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:`chrome`,pattern:/Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:`firefox`,pattern:/Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:`safari`,pattern:/(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/}]){let n=t.exec(navigator.userAgent);if(n)return{browser:e,version:`${n[1]||0}.${n[2]||0}.${n[3]||0}`}}return null}const we=e=>e===`x32`?`x32`:e===`x86_64`||e===`x64`?`x64`:e===`arm`?`arm`:e===`aarch64`||e===`arm64`?`arm64`:e?`other:${e}`:`unknown`,Te=e=>(e=e.toLowerCase(),e.includes(`ios`)?`iOS`:e===`android`?`Android`:e===`darwin`?`MacOS`:e===`win32`?`Windows`:e===`freebsd`?`FreeBSD`:e===`openbsd`?`OpenBSD`:e===`linux`?`Linux`:e?`Other:${e}`:`Unknown`);let Ee;const De=()=>Ee??=Se();function Oe(){if(typeof fetch<`u`)return n.fetch;throw Error("`fetch` is not defined as a global; Either pass `fetch` to the client, `new Limrun({ fetch })` or polyfill the global, `globalThis.fetch = fetch`")}function ke(...e){let t=globalThis.ReadableStream;if(t===void 0)throw Error("`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`");return new t(...e)}function Ae(e){let t=Symbol.asyncIterator in e?e[Symbol.asyncIterator]():e[Symbol.iterator]();return ke({start(){},async pull(e){let{done:n,value:r}=await t.next();n?e.close():e.enqueue(r)},async cancel(){await t.return?.()}})}async function je(e){if(typeof e!=`object`||!e)return;if(e[Symbol.asyncIterator]){await e[Symbol.asyncIterator]().return?.();return}let t=e.getReader(),n=t.cancel();t.releaseLock(),await n}const Me=({headers:e,body:t})=>({bodyHeaders:{"content-type":`application/json`},body:JSON.stringify(t)});function Ne(e){return Object.entries(e).filter(([e,t])=>t!==void 0).map(([e,t])=>{if(typeof t==`string`||typeof t==`number`||typeof t==`boolean`)return`${encodeURIComponent(e)}=${encodeURIComponent(t)}`;if(t===null)return`${encodeURIComponent(e)}=`;throw new c(`Cannot stringify type ${typeof t}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`)}).join(`&`)}const T={off:0,error:200,warn:300,info:400,debug:500},E=(e,t,n)=>{if(e){if(ve(T,e))return e;A(n).warn(`${t} was set to ${JSON.stringify(e)}, expected one of ${JSON.stringify(Object.keys(T))}`)}};function D(){}function O(e,t,n){return!t||T[e]>T[n]?D:t[e].bind(t)}const Pe={error:D,warn:D,info:D,debug:D};let k=new WeakMap;function A(e){let t=e.logger,n=e.logLevel??`off`;if(!t)return Pe;let r=k.get(t);if(r&&r[0]===n)return r[1];let i={error:O(`error`,t,n),warn:O(`warn`,t,n),info:O(`info`,t,n),debug:O(`debug`,t,n)};return k.set(t,[n,i]),i}const j=e=>(e.options&&(e.options={...e.options},delete e.options.headers),e.headers&&=Object.fromEntries((e.headers instanceof Headers?[...e.headers]:Object.entries(e.headers)).map(([e,t])=>[e,e.toLowerCase()===`authorization`||e.toLowerCase()===`api-key`||e.toLowerCase()===`x-api-key`||e.toLowerCase()===`cookie`||e.toLowerCase()===`set-cookie`?`***`:t])),`retryOfRequestLogID`in e&&(e.retryOfRequestLogID&&(e.retryOf=e.retryOfRequestLogID),delete e.retryOfRequestLogID),e);async function Fe(e,t){let{response:n,requestLogID:r,retryOfRequestLogID:i,startTime:a}=t,o=await(async()=>{if(n.status===204)return null;if(t.options.__binaryResponse)return n;let e=n.headers.get(`content-type`)?.split(`;`)[0]?.trim();return e?.includes(`application/json`)||e?.endsWith(`+json`)?n.headers.get(`content-length`)===`0`?void 0:await n.json():await n.text()})();return A(e).debug(`[${r}] response parsed`,j({retryOfRequestLogID:i,url:n.url,status:n.status,body:o,durationMs:Date.now()-a})),o}var M,Ie=class e extends Promise{constructor(e,t,n=Fe){super(e=>{e(null)}),this.responsePromise=t,this.parseResponse=n,M.set(this,void 0),x(this,M,e,`f`)}_thenUnwrap(t){return new e(S(this,M,`f`),this.responsePromise,async(e,n)=>t(await this.parseResponse(e,n),n))}asResponse(){return this.responsePromise.then(e=>e.response)}async withResponse(){let[e,t]=await Promise.all([this.parse(),this.asResponse()]);return{data:e,response:t}}parse(){return this.parsedPromise||=this.responsePromise.then(e=>this.parseResponse(S(this,M,`f`),e)),this.parsedPromise}then(e,t){return this.parse().then(e,t)}catch(e){return this.parse().catch(e)}finally(e){return this.parse().finally(e)}};M=new WeakMap;var N,Le=class{constructor(e,t,n,r){N.set(this,void 0),x(this,N,e,`f`),this.options=r,this.response=t,this.body=n}hasNextPage(){return this.getPaginatedItems().length?this.nextPageRequestOptions()!=null:!1}async getNextPage(){let e=this.nextPageRequestOptions();if(!e)throw new c("No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`.");return await S(this,N,`f`).requestAPIList(this.constructor,e)}async*iterPages(){let e=this;for(yield e;e.hasNextPage();)e=await e.getNextPage(),yield e}async*[(N=new WeakMap,Symbol.asyncIterator)](){for await(let e of this.iterPages())for(let t of e.getPaginatedItems())yield t}},Re=class extends Ie{constructor(e,t,n){super(e,t,async(e,t)=>new n(e,t.response,await Fe(e,t),t.options))}async*[Symbol.asyncIterator](){let e=await this;for await(let t of e)yield t}},P=class extends Le{constructor(e,t,n,r){super(e,t,n,r),this.items=n||[]}getPaginatedItems(){return this.items??[]}nextPageRequestOptions(){let e=this.getPaginatedItems();if(!(typeof this.options.query==`object`&&`endingBefore`in(this.options.query||{}))){let t=e[e.length-1]?.metadata.id;return t?{...this.options,query:{...ge(this.options.query),startingAfter:t}}:null}let t=e[0]?.metadata.id;return t?{...this.options,query:{...ge(this.options.query),endingBefore:t}}:null}};const ze=()=>{if(typeof File>`u`){let{process:e}=globalThis,t=typeof e?.versions?.node==`string`&&parseInt(e.versions.node.split(`.`))<20;throw Error("`File` is not defined as a global, which is required for file uploads."+(t?" Update to Node 20 LTS or newer, or set `globalThis.File` to `import('node:buffer').File`.":``))}};function F(e,t,n){return ze(),new File(e,t??`unknown_file`,n)}function Be(e){return(typeof e==`object`&&!!e&&(`name`in e&&e.name&&String(e.name)||`url`in e&&e.url&&String(e.url)||`filename`in e&&e.filename&&String(e.filename)||`path`in e&&e.path&&String(e.path))||``).split(/[\\/]/).pop()||void 0}const Ve=e=>typeof e==`object`&&!!e&&typeof e[Symbol.asyncIterator]==`function`,He=e=>typeof e==`object`&&!!e&&typeof e.size==`number`&&typeof e.type==`string`&&typeof e.text==`function`&&typeof e.slice==`function`&&typeof e.arrayBuffer==`function`,Ue=e=>typeof e==`object`&&!!e&&typeof e.name==`string`&&typeof e.lastModified==`number`&&He(e),We=e=>typeof e==`object`&&!!e&&typeof e.url==`string`&&typeof e.blob==`function`;async function Ge(e,t,n){if(ze(),e=await e,Ue(e))return e instanceof File?e:F([await e.arrayBuffer()],e.name);if(We(e)){let r=await e.blob();return t||=new URL(e.url).pathname.split(/[\\/]/).pop(),F(await I(r),t,n)}let r=await I(e);if(t||=Be(e),!n?.type){let e=r.find(e=>typeof e==`object`&&`type`in e&&e.type);typeof e==`string`&&(n={...n,type:e})}return F(r,t,n)}async function I(e){let t=[];if(typeof e==`string`||ArrayBuffer.isView(e)||e instanceof ArrayBuffer)t.push(e);else if(He(e))t.push(e instanceof Blob?e:await e.arrayBuffer());else if(Ve(e))for await(let n of e)t.push(...await I(n));else{let t=e?.constructor?.name;throw Error(`Unexpected data type: ${typeof e}${t?`; constructor: ${t}`:``}${Ke(e)}`)}return t}function Ke(e){return typeof e!=`object`||!e?``:`; props: [${Object.getOwnPropertyNames(e).map(e=>`"${e}"`).join(`, `)}]`}var L=class{constructor(e){this._client=e}},qe=class extends L{get(e,t){return this._client.get(`/v1/analytics`,{query:Je(e),...t})}getInstances(e,t){return this._client.get(`/v1/analytics/instances`,{query:Je(e),...t})}};function Je(e){let{startedAt:t,stoppedAt:n,...r}=e,i={...r};for(let[e,r]of Object.entries({startedAt:t,stoppedAt:n}))if(r!==void 0)for(let[t,n]of Object.entries(r))n!==void 0&&(i[`${e}[${t}]`]=n);return i}const Ye=Symbol(`brand.privateNullableHeaders`);function*Xe(e){if(!e)return;if(Ye in e){let{values:t,nulls:n}=e;yield*t.entries();for(let e of n)yield[e,null];return}let t=!1,n;e instanceof Headers?n=e.entries():he(e)?n=e:(t=!0,n=Object.entries(e??{}));for(let e of n){let n=e[0];if(typeof n!=`string`)throw TypeError(`expected header name to be a string`);let r=he(e[1])?e[1]:[e[1]],i=!1;for(let e of r)e!==void 0&&(t&&!i&&(i=!0,yield[n,null]),yield[n,e])}}const R=e=>{let t=new Headers,n=new Set;for(let r of e){let e=new Set;for(let[i,a]of Xe(r)){let r=i.toLowerCase();e.has(r)||(t.delete(i),e.add(r)),a===null?(t.delete(i),n.add(r)):(t.append(i,a),n.delete(r))}}return{[Ye]:!0,values:t,nulls:n}};function Ze(e){return e.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g,encodeURIComponent)}const Qe=Object.freeze(Object.create(null)),z=((e=Ze)=>function(t,...n){if(t.length===1)return t[0];let r=!1,i=[],a=t.reduce((t,a,o)=>{/[?#]/.test(a)&&(r=!0);let s=n[o],c=(r?encodeURIComponent:e)(``+s);return o!==n.length&&(s==null||typeof s==`object`&&s.toString===Object.getPrototypeOf(Object.getPrototypeOf(s.hasOwnProperty??Qe)??Qe)?.toString)&&(c=s+``,i.push({start:t.length+a.length,length:c.length,error:`Value of type ${Object.prototype.toString.call(s).slice(8,-1)} is not a valid path parameter`})),t+a+(o===n.length?``:c)},``),o=a.split(/[?#]/,1)[0],s=/(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi,l;for(;(l=s.exec(o))!==null;)i.push({start:l.index,length:l[0].length,error:`Value "${l[0]}" can\'t be safely passed as a path parameter`});if(i.sort((e,t)=>e.start-t.start),i.length>0){let e=0,t=i.reduce((t,n)=>{let r=` `.repeat(n.start-e),i=`^`.repeat(n.length);return e=n.start+n.length,t+r+i},``);throw new c(`Path parameters result in path with invalid segments:\n${i.map(e=>e.error).join(`
|
|
2
|
+
`)}\n${a}\n${t}`)}return a})(Ze);var B=class extends L{create(e,t){let{reuseIfExists:n,wait:r,...i}=e;return this._client.post(`/v1/gradle_instances`,{query:{reuseIfExists:n,wait:r},body:i,...t})}list(e={},t){return this._client.getAPIList(`/v1/gradle_instances`,P,{query:e,...t})}delete(e,t){return this._client.delete(z`/v1/gradle_instances/${e}`,{...t,headers:R([{Accept:`*/*`},t?.headers])})}get(e,t){return this._client.get(z`/v1/gradle_instances/${e}`,t)}},V=class extends L{create(e,t){return this._client.post(`/v1/scoped_tokens`,{body:e,...t})}},$e=class extends L{list(e={},t){return this._client.get(`/v1/assets`,{query:e,...t})}delete(e,t){return this._client.delete(z`/v1/assets/${e}`,{...t,headers:R([{Accept:`*/*`},t?.headers])})}get(e,t={},n){return this._client.get(z`/v1/assets/${e}`,{query:t,...n})}getOrCreate(e,t){return this._client.put(`/v1/assets`,{body:e,...t})}};function et(e,t){if(!t)return{body:e};let n=0;return{body:new ReadableStream({pull(r){if(n>=e.length){r.close();return}let i=e.subarray(n,Math.min(n+262144,e.length));n+=i.length,r.enqueue(i),t(n,e.length)}}),duplex:`half`}}var tt=class extends $e{async getOrUpload(e,t){let r=await this.getOrCreate({name:e.name??le(e.path),kind:e.kind??`App`,...e.platform&&{platform:e.platform},...e.ttl&&{ttl:e.ttl},...e.uploadOptions},t),i=await se.readFile(e.path),a=de(`md5`).update(i).digest(`hex`);if(r.md5&&r.md5===a)return{id:r.id,name:r.name,signedDownloadUrl:r.signedDownloadUrl,kind:r.kind,...r.platform&&{platform:r.platform},md5:r.md5,...r.expiresAt&&{expiresAt:r.expiresAt}};let o=await n.fetch(r.signedUploadUrl,{headers:{...e.onUploadProgress&&{"Content-Length":i.length.toString()},"Content-Type":`application/octet-stream`},method:`PUT`,...et(i,e.onUploadProgress)});if(o.status!==200)throw Error(`Failed to upload asset: ${o.status} ${await o.text()}`);return{id:r.id,name:r.name,signedDownloadUrl:r.signedDownloadUrl,kind:r.kind,...r.platform&&{platform:r.platform},md5:a,...r.expiresAt&&{expiresAt:r.expiresAt}}}},nt=class extends L{create(e,t){let{reuseIfExists:n,wait:r,...i}=e;return this._client.post(`/v1/ios_instances`,{query:{reuseIfExists:n,wait:r},body:i,...t})}list(e={},t){return this._client.getAPIList(`/v1/ios_instances`,P,{query:e,...t})}delete(e,t){return this._client.delete(z`/v1/ios_instances/${e}`,{...t,headers:R([{Accept:`*/*`},t?.headers])})}get(e,t){return this._client.get(z`/v1/ios_instances/${e}`,t)}},rt=class extends nt{listSessionArtifacts(e,t,n){return this._client.get(z`/v1/ios_instances/${e}/session_artifacts`,{query:t?{kind:t}:void 0,...n})}listRecordings(e,t){return this.listSessionArtifacts(e,`recording`,t)}listAppLogs(e,t){return this.listSessionArtifacts(e,`appLog`,t)}listEvents(e,t){return this.listSessionArtifacts(e,`eventLog`,t)}},it=class extends L{create(e,t){let{reuseIfExists:n,wait:r,...i}=e;return this._client.post(`/v1/android_instances`,{query:{reuseIfExists:n,wait:r},body:i,...t})}list(e={},t){return this._client.getAPIList(`/v1/android_instances`,P,{query:e,...t})}delete(e,t){return this._client.delete(z`/v1/android_instances/${e}`,{...t,headers:R([{Accept:`*/*`},t?.headers])})}get(e,t){return this._client.get(z`/v1/android_instances/${e}`,t)}},at=class extends it{listSessionArtifacts(e,t,n){return this._client.get(z`/v1/android_instances/${e}/session_artifacts`,{query:t?{kind:t}:void 0,...n})}listRecordings(e,t){return this.listSessionArtifacts(e,`recording`,t)}listAppLogs(e,t){return this.listSessionArtifacts(e,`appLog`,t)}listEvents(e,t){return this.listSessionArtifacts(e,`eventLog`,t)}},ot=class extends L{create(e,t){let{reuseIfExists:n,wait:r,...i}=e;return this._client.post(`/v1/xcode_instances`,{query:{reuseIfExists:n,wait:r},body:i,...t})}list(e={},t){return this._client.getAPIList(`/v1/xcode_instances`,P,{query:e,...t})}delete(e,t){return this._client.delete(z`/v1/xcode_instances/${e}`,{...t,headers:R([{Accept:`*/*`},t?.headers])})}get(e,t){return this._client.get(z`/v1/xcode_instances/${e}`,t)}};function H(e){let t=e.status.token;if(!t)throw Error(`Instance ${e.metadata.id} came back without its token: the credential used can read it but not control it.`);return t}var U=class extends Error{constructor(e){super(`Instance ${e} was gone before it reported any cache status`),this.instanceId=e,this.name=`XcodeCacheGoneError`}},W=class extends Error{constructor(e,t,n){super(`Timed out after ${Math.round(t/1e3)}s waiting for the cache ${e} to finish`+(n?` (last phase: ${n[e].phase})`:``)),this.side=e,this.timeoutMs=t,this.cache=n,this.name=`XcodeCacheTimeoutError`}};const st={restore:12e5,save:72e4};function ct(e){return e===`disabled`||e===`unsupported`||e===`restored`||e===`skipped`||e===`failed`}function lt(e){return e===`disabled`||e===`published`||e===`skipped`||e===`failed`||e===`timed_out`}function ut(e,t){return t===`restore`?ct(e.restore.phase):lt(e.save.phase)}function dt(e,t={}){let r=t.side??`restore`,i=t.timeoutMs??st[r],a=e.baseURL;for(;a.endsWith(`/`);)a=a.slice(0,-1);let o=`${a}/v1/xcode_instances/${encodeURIComponent(e.instanceId)}/cache`;return new Promise((a,s)=>{let c,l=``,u=!1,d=e=>{if(!u){u=!0,clearTimeout(f),t.signal?.removeEventListener(`abort`,m);try{_.close()}catch{}e()}},f=setTimeout(()=>d(()=>s(new W(r,i,c))),i),m=()=>d(()=>s(t.signal?.reason??Error(`aborted`))),h=!1,g=()=>{h||u||(h=!0,n.fetch(o,{headers:{Authorization:`Bearer ${e.apiKey}`,Accept:`application/json`}}).then(async t=>{if(h=!1,t.status!==404){await t.text().catch(()=>void 0);return}d(()=>c?a({cache:c,gone:!0}):s(new U(e.instanceId)))}).catch(()=>{h=!1}))},_=p({url:o,fetch:async(t,r)=>{let i=await n.fetch(t,r);return i.status===404&&d(()=>c?a({cache:c,gone:!0}):s(new U(e.instanceId))),i},onConnect:()=>t.onOpen?.(),headers:{Authorization:`Bearer ${e.apiKey}`,Accept:`text/event-stream`},onMessage:e=>{if(e.event!==`cache`&&e.event!==`gone`)return;let n;try{n=JSON.parse(typeof e.data==`string`?e.data:String(e.data))}catch(e){d(()=>s(Error(`Cache stream sent unreadable data: ${e}`)));return}if(c=n,e.event===`gone`){g();return}let i=`${n.restore.phase}/${n.restore.reason??``}|${n.save.phase}/${n.save.reason??``}`;i!==l&&(l=i,t.onUpdate?.(n)),ut(n,r)&&d(()=>a({cache:n,gone:!1}))}});if(t.signal?.aborted){m();return}t.signal?.addEventListener(`abort`,m,{once:!0})})}var ft=class extends U{constructor(e){super(e),this.name=`XcodeSnapshotGoneError`,this.message=`Instance ${e} was gone before it reported any disk snapshot status`}},pt=class extends W{constructor(e){super(e.side,e.timeoutMs,e.cache),this.name=`XcodeSnapshotTimeoutError`,this.message=e.message.replace(`the cache `,`the disk snapshot `),this.snapshot=e.cache?G(e.cache):void 0}};function G(e){let{cacheKey:t,...n}=e.save;return{...e,save:{...n,...t===void 0?{}:{snapshotKey:t}}}}async function mt(e,t={}){let{onUpdate:n,...r}=t;try{let t=await dt(e,{...r,...n?{onUpdate:e=>n(G(e))}:{}});return{snapshot:G(t.cache),gone:t.gone}}catch(e){throw e instanceof U?new ft(e.instanceId):e instanceof W?new pt(e):e}}function ht(e,t){let n=b.resolve(e),r=`limsync-cache-${b.basename(n)}-${ue.createHash(`sha1`).update(n).digest(`hex`).slice(0,8)}`;return{cacheKey:r,basisCacheDir:t??b.join(ce.tmpdir(),r)}}function K(e,t,n,r){return e.getOrCreate({name:t,ttl:n||`336h`,...r}).catch(e=>{let n=`Failed to create upload URL for asset '${t}': ${e instanceof Error?e.message:e}`;throw Error(n,{cause:e})})}const gt=[`none`,`error`,`warn`,`info`,`debug`];function _t(e,t){let n=gt.indexOf(t),r=e=>n>=gt.indexOf(e);return(t,n)=>{r(t)&&(t===`error`||t===`warn`?console[t](e,n):console.log(e,n))}}function vt(e){return(t,n)=>{if(t.trim()===``)throw Error(`commandLine must not be empty`);if(n?.timeoutSeconds!==void 0&&(!Number.isInteger(n.timeoutSeconds)||n.timeoutSeconds<1||n.timeoutSeconds>21600))throw Error(`timeoutSeconds must be an integer between 1 and 21600`);let r={command:`run`,commandLine:t,cwd:n?.cwd??`.`,...n?.env?.length&&{env:n.env},...n?.timeoutSeconds!==void 0&&{timeoutSeconds:n.timeoutSeconds}};return h(r,e)}}const yt=/^[A-Z0-9_]+$/,bt=4096,xt=65536;function St(e){let t=Object.entries(e);if(t.length>32)throw Error(`too many build settings: got ${t.length}, max 32`);let n=0;for(let[e,r]of t){if(!yt.test(e))throw Error(`invalid build setting key "${e}": keys must match ^[A-Z0-9_]+$`);if(typeof r!=`string`)throw Error(`invalid build setting value for "${e}": value must be a string`);let t=Buffer.byteLength(r,`utf8`);if(t>bt)throw Error(`build setting value for "${e}" is too large: got ${t} bytes, max ${bt} bytes`);if(n+=Buffer.byteLength(e,`utf8`)+t,n>xt)throw Error(`build settings payload is too large: max ${xt} bytes`)}}const Ct=e=>new Promise(t=>setTimeout(t,e)),wt=/failed: (?:502|503|504)\b|\bEOF\b|ECONNRESET|ECONNREFUSED|socket hang up|fetch failed/i;function Tt(e){let t=e instanceof Error?e.message:String(e);return wt.test(t)}async function Et(e,t={}){let n=t.sleep??Ct,r=t.attempts??5,i=t.retryOn??Tt,a;for(let o=1;o<=r;o++)try{return await e()}catch(e){if(!i(e))throw e;if(a=e,o<r){let r=e instanceof Error?e.message:String(e);t.log?.(`Retrying after error (${r.trim()})...`),await n(2e3*o)}}throw a}function Dt(e){if(e===``||e.startsWith(`/`)||e.includes(`\\`)||e.includes(`\0`))throw Error(`invalid sandbox home path from server: ${e}`);let t=e.split(`/`);if(t.some(e=>e===``||e===`.`||e===`..`))throw Error(`invalid sandbox home path from server: ${e}`);return t.join(`/`)}async function Ot(e,t){let r=await J(await n.fetch(`${e}/info`,{method:`GET`,headers:{Authorization:`Bearer ${t}`}}),`GET /info`);if(!r.homeDir)throw Error(`GET /info response is missing homeDir`);return{homeDir:Dt(r.homeDir),...r.xcode?{xcode:r.xcode}:{}}}function kt(e){let t=new URL(e);if(t.protocol===`https:`)t.protocol=`wss:`;else if(t.protocol===`http:`)t.protocol=`ws:`;else throw Error(`Unsupported apiUrl protocol for rbe tunnel: ${t.protocol}`);return t.pathname=`${t.pathname.replace(/\/+$/,``)}/rbe/tunnel`,t.search=``,t.hash=``,t.toString()}var At=class extends c{constructor(e){super(`Remote build execution is not available on this Xcode instance (${e} returned 404). Its limbuild may predate RBE support, or you may be targeting the wrong environment (for example production instead of staging).`),this.name=`RbeUnsupportedError`}},jt=class extends c{constructor(e){super(`Xcode version selection is not available on this sandbox (${e} returned 404): its daemon predates Xcode selection. Create a new sandbox, or omit the Xcode version to build with its default.`),this.name=`XcodeSelectionUnsupportedError`}};function Mt(e,t){return Nt(e,t,e=>new jt(e))}function q(e,t){return Nt(e,t,e=>new At(e))}async function Nt(e,t,n){if(e.status===404)throw await e.text().catch(()=>void 0),n(t);return J(e,t)}async function J(e,t){let n=await e.text();if(!e.ok)throw ie(t,e.status,n,e.headers);if(!n.trim())throw Error(`${t} returned an empty response`);return JSON.parse(n)}var Pt=class extends ot{listBuildLogs(e,t){return this._client.get(z`/v1/xcode_instances/${e}/build_logs`,t)}listBazelBuildLogs(e,t){return this._client.get(z`/v1/xcode_instances/${e}/bazel_build_logs`,t)}create(e,t){if(e.spec?.snapshot!==void 0){let{snapshot:n,cache:r,...i}=e.spec;if(r!==void 0)throw Error(`Use either spec.snapshot or the legacy spec.cache, not both.`);return super.create({...e,spec:{...i,cache:n}},t)}return super.create(e,t)}getSnapshot(e,t){return this.getCache(e,t)._thenUnwrap(G)}bindSnapshotKey(e,t,n){return this.bindCacheKey(e,t,n)._thenUnwrap(G)}followSnapshot(e,t){let n=this._client.apiKey;if(!n)throw Error(`Following disk snapshot status needs an API key on the client`);return mt({baseURL:this._client.baseURL,apiKey:n,instanceId:e},t)}getCache(e,t){return this._client.get(z`/v1/xcode_instances/${e}/cache`,t)}bindCacheKey(e,t,n){return this._client.put(z`/v1/xcode_instances/${e}/cache`,{body:{key:t},...n})}followCache(e,t){let n=this._client.apiKey;if(!n)throw Error(`Following cache status needs an API key on the client`);return dt({baseURL:this._client.baseURL,apiKey:n,instanceId:e},t)}async createClient(e){let t,r;if(`instance`in e){if(!e.instance.status.apiUrl)throw Error(`Instance not ready: apiUrl is not available`);t=e.instance.status.apiUrl,r=H(e.instance)}else t=e.apiUrl,r=e.token;let i=_t(`[XcodeInstance]`,e.logLevel??`info`),a=this._client,o,s=()=>(o??=Ot(t,r),o),c=async e=>{let i,a;if(`status`in e){if(!e.status.apiUrl)throw Error(`Simulator instance not ready: apiUrl is not available`);i=e.status.apiUrl,a=H(e)}else i=e.apiUrl,a=e.token;return J(await n.fetch(`${t}/simulator`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${r}`},body:JSON.stringify({apiUrl:i,token:a})}),`POST /simulator`)},l=async e=>{try{return await a.iosInstances.delete(e),!0}catch{return!1}};return{async sync(e,n){let{cacheKey:a,basisCacheDir:o}=ht(e,n?.basisCacheDir),c=n?.additionalFiles&&n.additionalFiles.length>0?await s():void 0,l=n?.additionalFiles?.map(e=>({localPath:e.localPath,remotePath:c&&e.remotePath.startsWith(`~/`)?`${c.homeDir}/${e.remotePath.slice(2)}`:e.remotePath})),u={apiUrl:t,token:r,udid:a,install:n?.install??!0,ignoreFn:await oe(e,{basisCacheDir:o,log:i,xcodeDefaults:!0,...n?.include?{include:n.include}:{},...n?.ignore?{additional:n.ignore}:{}}),basisCacheDir:o,watch:n?.watch??!0,launchMode:`ForegroundIfRunning`,log:i,syncSymlinks:!0,...l?{additionalFiles:l}:{},...n?.onSyncComplete?{onSyncComplete:n.onSyncComplete}:{}},d=await _(e,u),f={};return d.bytesSent!==void 0&&(f.bytesSent=d.bytesSent),d.stopWatching&&(f.stopWatching=d.stopWatching),f},xcodebuild(e,n){if(n?.reactNative?.devServerURL&&e?.configuration===`Release`)throw Error(`reactNative.devServerURL is only supported for Debug builds`);if(e?.onlyTesting?.length&&e?.skipTesting?.length)throw Error(`onlyTesting and skipTesting are mutually exclusive; pass one`);if((e?.onlyTesting?.length||e?.skipTesting?.length)&&e?.action!==`build-for-testing`)throw Error(`onlyTesting/skipTesting require action: 'build-for-testing'`);if(e?.runTests===!1&&e?.action!==`build-for-testing`)throw Error(`runTests: false requires action: 'build-for-testing'`);if(e?.action===`build-for-testing`&&e.sdk!==void 0&&e.sdk!==`iphonesimulator`)throw Error(`action: 'build-for-testing' requires the iphonesimulator sdk`);n?.buildSettings&&St(n.buildSettings);let o={command:`xcodebuild`,...e&&{xcodebuild:e},...n?.xcodegen&&{xcodegen:n.xcodegen},...n?.reactNative&&{reactNative:n.reactNative},...n?.signing&&{signing:n.signing},...n?.cloudSigning&&{cloudSigning:n.cloudSigning},...n?.appstore&&{testflight:n.appstore},...n?.buildSettings&&{buildSettings:n.buildSettings},...n?.env?.length&&{env:n.env},...n?.gitInit!==void 0&&{gitInit:n.gitInit},...n?.logProcessor&&{logProcessor:n.logProcessor},...n?.webhook&&{webhook:n.webhook}},s={apiUrl:t,token:r,log:i,...n?.onXctestEvent&&{onXctestEvent:n.onXctestEvent}};if(n?.upload&&`assetName`in n.upload){let e=K(a.assets,n.upload.assetName,n.upload.ttl,n.upload.uploadOptions).then(e=>(o.signedUploadUrl=e.signedUploadUrl,o.assetId=e.id,o.additionalMetadata={signedDownloadUrl:e.signedDownloadUrl},o));return h(e,s)}return n?.upload&&`signedUploadUrl`in n.upload&&(o.signedUploadUrl=n.upload.signedUploadUrl),h(o,s)},run:vt({apiUrl:t,token:r,log:i}),observeBuildLogs(e,n){return y(e,{apiUrl:t,token:r,log:i,...n})},async getSimulator(){return J(await n.fetch(`${t}/simulator`,{method:`GET`,headers:{Authorization:`Bearer ${r}`}}),`GET /simulator`)},attachSimulator:c,attachNewSimulator:async()=>{let e=await a.iosInstances.create({wait:!0});try{await c(e)}catch(t){throw await l(e.metadata.id),t}return{iosInstanceId:e.metadata.id,simulator:e}},deleteSimulator:l,async getXcode(){return Mt(await n.fetch(`${t}/xcode`,{method:`GET`,headers:{Authorization:`Bearer ${r}`}}),`GET /xcode`)},async setXcode(e){return Mt(await n.fetch(`${t}/xcode`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${r}`},body:JSON.stringify({version:e})}),`POST /xcode`)},getInfo:()=>Ot(t,r),async startRbe(e){return q(await n.fetch(`${t}/rbe`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${r}`},body:JSON.stringify(e??{})}),`POST /rbe`)},async getRbe(){return q(await n.fetch(`${t}/rbe`,{method:`GET`,headers:{Authorization:`Bearer ${r}`}}),`GET /rbe`)},async stopRbe(){return q(await n.fetch(`${t}/rbe`,{method:`DELETE`,headers:{Authorization:`Bearer ${r}`}}),`DELETE /rbe`)},async startRbeTunnel(n){return te(kt(t),r,n?.host??`127.0.0.1`,n?.port??8980,{mode:`multiplexed`,logLevel:n?.logLevel??e.logLevel??`info`})},async uploadLatestRbeBuild(e){let i,o;if(e.assetName!==void 0){if(!e.assetName)throw Error(`assetName must not be empty`);let t=await K(a.assets,e.assetName,e.ttl);i=t.signedUploadUrl,o=t.signedDownloadUrl}else i=e.signedUploadUrl;return{...await Et(async()=>{let e=await n.fetchLongRequest(`${t}/rbe/upload`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${r}`},body:JSON.stringify({signedUploadUrl:i})});if(e.status===404)throw await e.text().catch(()=>void 0),Error(`POST /rbe/upload returned 404: the instance may no longer exist, or its limbuild predates RBE upload support. Recreate the instance and retry.`);return J(e,`POST /rbe/upload`)},{retryOn:e=>Tt(e)||g(e,400)&&/no successful RBE app build/i.test(e.body)}),...o&&{signedDownloadUrl:o}}},async getActiveRbeBuilds(){return q(await n.fetch(`${t}/rbe/builds/active`,{method:`GET`,headers:{Authorization:`Bearer ${r}`}}),`GET /rbe/builds/active`)},async getRecentRbeBuilds(){return q(await n.fetch(`${t}/rbe/builds/recent`,{method:`GET`,headers:{Authorization:`Bearer ${r}`}}),`GET /rbe/builds/recent`)},waitForRbeBuildEnd(e,i){return new Promise((a,o)=>{if(i?.signal?.aborted){o(Error(`waiting for build ${e} was aborted`));return}let s=!1,c=()=>{f.close(),i?.signal?.removeEventListener(`abort`,d)},l=e=>{s||(s=!0,c(),a(e))},u=e=>{s||(s=!0,c(),o(e))},d=()=>u(Error(`waiting for build ${e} was aborted`)),f=p({url:`${t}/exec/${e}/events`,fetch:re(n.fetch,t=>u(Error(`build event stream for ${e} is unreachable: ${t instanceof Error?t.message:t}`))),headers:{Authorization:`Bearer ${r}`},onMessage:t=>{if(t.event!==`end`)return;let n;try{n=JSON.parse(t.data)}catch(t){u(Error(`invalid build end event for ${e}: ${t}`));return}l(n)},onDisconnect:()=>{u(Error(`build event stream for ${e} ended without a terminal event (the build may have finished and its live stream been removed)`))}});i?.signal?.addEventListener(`abort`,d,{once:!0})})}}}};function Ft(e){let t=e.endsWith(`/`)?e.slice(0,-1):e,n=t.split(`/`);return n[n.length-1]===`local.properties`||n.length===1&&(t===`.gradle`||t===`.kotlin`||t===`build`)}var It=class extends B{listBuildLogs(e,t){return this._client.get(z`/v1/gradle_instances/${e}/build_logs`,t)}async createClient(e){let t,n;if(`instance`in e){if(!e.instance.status.apiUrl)throw Error(`Instance not ready: apiUrl is not available`);t=e.instance.status.apiUrl,n=H(e.instance)}else t=e.apiUrl,n=e.token;let r=_t(`[GradleInstance]`,e.logLevel??`info`),i=this._client;return{async sync(e,i){let{cacheKey:a,basisCacheDir:o}=ht(e,i?.basisCacheDir),s=i?.ignore,c={apiUrl:t,token:n,udid:a,install:!1,ignoreFn:await oe(e,{basisCacheDir:o,log:r,xcodeDefaults:!1,nestedGitignore:!0,additional:s?e=>Ft(e)||s(e):Ft,...i?.include?{include:i.include}:{}}),basisCacheDir:o,watch:i?.watch??!1,launchMode:`ForegroundIfRunning`,log:r,syncSymlinks:!0,...i?.additionalFiles&&{additionalFiles:i.additionalFiles},...i?.onSyncComplete&&{onSyncComplete:i.onSyncComplete}},l=await _(e,c),u={};return l.bytesSent!==void 0&&(u.bytesSent=l.bytesSent),l.stopWatching&&(u.stopWatching=l.stopWatching),u},run:vt({apiUrl:t,token:n,log:r}),gradlebuild(e){let a={command:`gradlebuild`,...e?.env?.length&&{env:e.env},...e?.tasks?.length&&{tasks:e.tasks},...e?.projectPath&&{projectPath:e.projectPath},...e?.reactNative&&{reactNative:e.reactNative},...e?.signing&&{signing:e.signing},...e?.webhook&&{webhook:e.webhook},...e?.playstore&&{playstore:e.playstore}};if(e?.upload&&`assetName`in e.upload){let o=K(i.assets,e.upload.assetName,e.upload.ttl).then(e=>(a.signedUploadUrl=e.signedUploadUrl,a.additionalMetadata={signedDownloadUrl:e.signedDownloadUrl},a));return h(o,{apiUrl:t,token:n,log:r})}return e?.upload&&`signedUploadUrl`in e.upload&&(a.signedUploadUrl=e.upload.signedUploadUrl),h(a,{apiUrl:t,token:n,log:r})},observeBuildLogs(e,i){return y(e,{apiUrl:t,token:n,log:r,...i})}}}};B.prototype.listBuildLogs=It.prototype.listBuildLogs,B.prototype.createClient=It.prototype.createClient;const Y=e=>{if(globalThis.process!==void 0)return globalThis.process.env?.[e]?.trim()||void 0;if(globalThis.Deno!==void 0)return globalThis.Deno.env?.get?.(e)?.trim()||void 0};var X,Z,Q,Lt,$=class{constructor({baseURL:e=Y(`LIMRUN_BASE_URL`),apiKey:t=Y(`LIM_API_KEY`)??null,...n}={}){X.add(this),Q.set(this,void 0),this.androidInstances=new at(this),this.assets=new tt(this),this.iosInstances=new rt(this),this.xcodeInstances=new Pt(this),this.gradleInstances=new B(this),this.analytics=new qe(this),this.scopedTokens=new V(this);let r={apiKey:t,...n,baseURL:e||`https://api.limrun.com`};this.baseURL=r.baseURL,this.timeout=r.timeout??Z.DEFAULT_TIMEOUT,this.logger=r.logger??console;let i=`warn`;this.logLevel=i,this.logLevel=E(r.logLevel,`ClientOptions.logLevel`,this)??E(Y(`LIMRUN_LOG`),`process.env['LIMRUN_LOG']`,this)??i,this.fetchOptions=r.fetchOptions,this.maxRetries=r.maxRetries??2,this.fetch=r.fetch??Oe(),x(this,Q,Me,`f`);let a=Y(`LIMRUN_CUSTOM_HEADERS`);if(a){let e={};for(let t of a.split(`
|
|
3
|
+
`)){let n=t.indexOf(`:`);n>=0&&(e[t.substring(0,n).trim()]=t.substring(n+1).trim())}r.defaultHeaders={...e,...r.defaultHeaders}}this._options=r,this.apiKey=t}withOptions(e){return new this.constructor({...this._options,baseURL:this.baseURL,maxRetries:this.maxRetries,timeout:this.timeout,logger:this.logger,logLevel:this.logLevel,fetch:this.fetch,fetchOptions:this.fetchOptions,apiKey:this.apiKey,...e})}defaultQuery(){return this._options.defaultQuery}validateHeaders({values:e,nulls:t}){if(!(this.apiKey&&e.get(`authorization`))&&!t.has(`authorization`))throw Error(`Could not resolve authentication method. Expected the apiKey to be set. Or for the "Authorization" headers to be explicitly omitted`)}async authHeaders(e){if(this.apiKey!=null)return R([{Authorization:`Bearer ${this.apiKey}`}])}stringifyQuery(e){return Ne(e)}getUserAgent(){return`${this.constructor.name}/JS ${w}`}defaultIdempotencyKey(){return`stainless-node-retry-${fe()}`}makeStatusError(e,t,n,r){return i.generate(e,t,n,r)}buildURL(e,t,n){let r=!S(this,X,`m`,Lt).call(this)&&n||this.baseURL,i=me(e)?new URL(e):new URL(r+(r.endsWith(`/`)&&e.startsWith(`/`)?e.slice(1):e)),a=this.defaultQuery(),o=Object.fromEntries(i.searchParams);return(!_e(a)||!_e(o))&&(t={...o,...a,...t}),typeof t==`object`&&t&&!Array.isArray(t)&&(i.search=this.stringifyQuery(t)),i.toString()}async prepareOptions(e){}async prepareRequest(e,{url:t,options:n}){}get(e,t){return this.methodRequest(`get`,e,t)}post(e,t){return this.methodRequest(`post`,e,t)}patch(e,t){return this.methodRequest(`patch`,e,t)}put(e,t){return this.methodRequest(`put`,e,t)}delete(e,t){return this.methodRequest(`delete`,e,t)}methodRequest(e,t,n){return this.request(Promise.resolve(n).then(n=>({method:e,path:t,...n})))}request(e,t=null){return new Ie(this,this.makeRequest(e,t,void 0))}async makeRequest(e,t,n){let i=await e,a=i.maxRetries??this.maxRetries;t??=a,await this.prepareOptions(i);let{req:o,url:c,timeout:l}=await this.buildRequest(i,{retryCount:a-t});await this.prepareRequest(o,{url:c,options:i});let u=`log_`+(Math.random()*(1<<24)|0).toString(16).padStart(6,`0`),d=n===void 0?``:`, retryOf: ${n}`,p=Date.now();if(A(this).debug(`[${u}] sending request`,j({retryOfRequestLogID:n,method:i.method,url:c,options:i,headers:o.headers})),i.signal?.aborted)throw new r;let h=new AbortController,g=await this.fetchWithTimeout(c,o,l,h).catch(s),_=Date.now();if(g instanceof globalThis.Error){let e=`retrying, ${t} attempts remaining`;if(i.signal?.aborted)throw new r;let a=f(g)||/timed? ?out/i.test(String(g)+(`cause`in g?String(g.cause):``));if(t)return A(this).info(`[${u}] connection ${a?`timed out`:`failed`} - ${e}`),A(this).debug(`[${u}] connection ${a?`timed out`:`failed`} (${e})`,j({retryOfRequestLogID:n,url:c,durationMs:_-p,message:g.message})),this.retryRequest(i,t,n??u);throw A(this).info(`[${u}] connection ${a?`timed out`:`failed`} - error; no more retries left`),A(this).debug(`[${u}] connection ${a?`timed out`:`failed`} (error; no more retries left)`,j({retryOfRequestLogID:n,url:c,durationMs:_-p,message:g.message})),a?new m:new ne({cause:g})}let v=`[${u}${d}] ${o.method} ${c} ${g.ok?`succeeded`:`failed`} with status ${g.status} in ${_-p}ms`;if(!g.ok){let e=await this.shouldRetry(g);if(t&&e){let e=`retrying, ${t} attempts remaining`;return await je(g.body),A(this).info(`${v} - ${e}`),A(this).debug(`[${u}] response error (${e})`,j({retryOfRequestLogID:n,url:g.url,status:g.status,headers:g.headers,durationMs:_-p})),this.retryRequest(i,t,n??u,g.headers)}let r=e?`error; no more retries left`:`error; not retryable`;A(this).info(`${v} - ${r}`);let a=await g.text().catch(e=>s(e).message),o=be(a),c=o?void 0:a;throw A(this).debug(`[${u}] response error (${r})`,j({retryOfRequestLogID:n,url:g.url,status:g.status,headers:g.headers,message:c,durationMs:Date.now()-p})),this.makeStatusError(g.status,o,c,g.headers)}return A(this).info(v),A(this).debug(`[${u}] response start`,j({retryOfRequestLogID:n,url:g.url,status:g.status,headers:g.headers,durationMs:_-p})),{response:g,options:i,controller:h,requestLogID:u,retryOfRequestLogID:n,startTime:p}}getAPIList(e,t,n){return this.requestAPIList(t,n&&`then`in n?n.then(t=>({method:`get`,path:e,...t})):{method:`get`,path:e,...n})}requestAPIList(e,t){let n=this.makeRequest(t,null,void 0);return new Re(this,n,e)}async fetchWithTimeout(e,t,n,r){let{signal:i,method:a,...o}=t||{},s=this._makeAbort(r);i&&i.addEventListener(`abort`,s,{once:!0});let c=setTimeout(s,n),l=globalThis.ReadableStream&&o.body instanceof globalThis.ReadableStream||typeof o.body==`object`&&o.body!==null&&Symbol.asyncIterator in o.body,u={signal:r.signal,...l?{duplex:`half`}:{},method:`GET`,...o};a&&(u.method=a.toUpperCase());try{return await this.fetch.call(void 0,e,u)}finally{clearTimeout(c)}}async shouldRetry(e){let t=e.headers.get(`x-should-retry`);return t===`true`?!0:t===`false`?!1:e.status===408||e.status===409||e.status===429||e.status>=500}async retryRequest(e,t,n,r){let i,a=r?.get(`retry-after-ms`);if(a){let e=parseFloat(a);Number.isNaN(e)||(i=e)}let o=r?.get(`retry-after`);if(o&&!i){let e=parseFloat(o);i=Number.isNaN(e)?Date.parse(o)-Date.now():e*1e3}if(i===void 0){let n=e.maxRetries??this.maxRetries;i=this.calculateDefaultRetryTimeoutMillis(t,n)}return await ae(i),this.makeRequest(e,t-1,n)}calculateDefaultRetryTimeoutMillis(e,t){let n=t-e;return Math.min(.5*2**n,8)*(1-Math.random()*.25)*1e3}async buildRequest(e,{retryCount:t=0}={}){let n={...e},{method:r,path:i,query:a,defaultBaseURL:o}=n,s=this.buildURL(i,a,o);`timeout`in n&&ye(`timeout`,n.timeout),n.timeout=n.timeout??this.timeout;let{bodyHeaders:c,body:l}=this.buildBody({options:n});return{req:{method:r,headers:await this.buildHeaders({options:e,method:r,bodyHeaders:c,retryCount:t}),...n.signal&&{signal:n.signal},...globalThis.ReadableStream&&l instanceof globalThis.ReadableStream&&{duplex:`half`},...l&&{body:l},...this.fetchOptions??{},...n.fetchOptions??{}},url:s,timeout:n.timeout}}async buildHeaders({options:e,method:t,bodyHeaders:n,retryCount:r}){let i={};this.idempotencyHeader&&t!==`get`&&(e.idempotencyKey||=this.defaultIdempotencyKey(),i[this.idempotencyHeader]=e.idempotencyKey);let a=R([i,{Accept:`application/json`,"User-Agent":this.getUserAgent(),"X-Stainless-Retry-Count":String(r),...e.timeout?{"X-Stainless-Timeout":String(Math.trunc(e.timeout/1e3))}:{},...De()},await this.authHeaders(e),this._options.defaultHeaders,n,e.headers]);return this.validateHeaders(a),a.values}_makeAbort(e){return()=>e.abort()}buildBody({options:e}){let{body:t,headers:n}=e;if(!t)return t==null&&`body`in e?S(this,Q,`f`).call(this,{body:t,headers:R([n])}):{bodyHeaders:void 0,body:void 0};let r=R([n]);return ArrayBuffer.isView(t)||t instanceof ArrayBuffer||t instanceof DataView||typeof t==`string`&&r.values.has(`content-type`)||globalThis.Blob&&t instanceof globalThis.Blob||t instanceof FormData||t instanceof URLSearchParams||globalThis.ReadableStream&&t instanceof globalThis.ReadableStream?{bodyHeaders:void 0,body:t}:typeof t==`object`&&(Symbol.asyncIterator in t||Symbol.iterator in t&&`next`in t&&typeof t.next==`function`)?{bodyHeaders:void 0,body:Ae(t)}:typeof t==`object`&&r.values.get(`content-type`)===`application/x-www-form-urlencoded`?{bodyHeaders:{"content-type":`application/x-www-form-urlencoded`},body:this.stringifyQuery(t)}:S(this,Q,`f`).call(this,{body:t,headers:r})}};Z=$,Q=new WeakMap,X=new WeakSet,Lt=function(){return this.baseURL!==`https://api.limrun.com`},$.Limrun=Z,$.DEFAULT_TIMEOUT=3e5,$.LimrunError=c,$.APIError=i,$.APIConnectionError=ne,$.APIConnectionTimeoutError=m,$.APIUserAbortError=r,$.NotFoundError=l,$.ConflictError=t,$.RateLimitError=a,$.BadRequestError=ee,$.AuthenticationError=u,$.InternalServerError=v,$.PermissionDeniedError=d,$.UnprocessableEntityError=o,$.toFile=Ge,$.AndroidInstances=at,$.Assets=tt,$.IosInstances=rt,$.XcodeInstances=Pt,$.GradleInstances=B,$.Analytics=qe,$.ScopedTokens=V,process.platform;const Rt=`agent-device-cli`;function zt(e){return{apiKey:e.apiKey,defaultHeaders:{"x-agent-device-client":Rt,"x-agent-device-version":e.clientVersion}}}function Bt(t,n,r=`This daemon drives an existing Limrun instance with its own token. Set LIMRUN_API_KEY, or ask the instance owner to do this.`){if(t)return t;throw new e(`UNSUPPORTED_OPERATION`,`${n} requires a Limrun API key.`,{hint:r})}export{$ as i,zt as n,Bt as r,Rt as t};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { B as
|
|
2
|
-
import {
|
|
3
|
-
import { A as
|
|
1
|
+
import { B as SnapshotUnchanged, D as IosSnapshotObservation, E as AppleApplicationState, F as SnapshotNode, H as SnapshotVisibility, N as SnapshotCommandOptionFields, O as IosTargetActivation, P as SnapshotKeyboardBandFact, R as SnapshotQualityVerdict, S as DeviceTarget, T as PublicPlatform, V as SnapshotViewportSize, X as NormalizedError, _ as SessionIsolationMode, a as DaemonRequest, f as LeaseBackend, g as ResponseLevel, i as DaemonLockPolicy, m as NetworkIncludeMode, o as DaemonResponse, q as DaemonError, r as DaemonInstallSource, s as DaemonResponseData, t as DaemonArtifact, v as SessionRuntimeHints, w as PlatformSelector, x as DeviceKind, y as AppleOS } from "./sdk-contracts.js";
|
|
2
|
+
import { t as AppsFilter } from "./app-inventory.js";
|
|
3
|
+
import { A as SetFoldPoseInput, C as ScrollInputDirection, D as DeviceRotation, E as TransformGestureParams, O as FoldPose, S as ScrollDirection, T as SwipePreset, a as AndroidSnapshotBackendMetadata, b as ScrollCommandResult, c as ScreenshotResultData, d as MACOS_PERMISSION_TARGETS, f as MOBILE_PERMISSION_TARGETS, i as CloudProviderSessionResult, j as BackMode, k as FoldScreenCoordinateSpace, l as SnapshotDiagnosticsSummary, m as PermissionMode, p as PermissionAction, s as FindLocator, t as AgentArtifactsResult, u as SessionSurface, v as TextSizeCategory, w as SwipePattern, y as TvRemoteButton } from "./cloud-artifacts.js";
|
|
4
4
|
import { _ as PressCommandResponseData, f as ClickCommandResponseData, g as LongPressCommandResponseData, h as HoverCommandResponseData, m as FindCommandResponseData, p as FillCommandResponseData, v as SettleObservation, y as ClickButton } from "./sdk-selectors.js";
|
|
5
|
+
import { n as GesturePointerCount } from "./gesture-plan-types.js";
|
|
5
6
|
import { a as RemoteConnectionProfileFields, c as MetroPrepareResult, i as CloudProviderProfileFields, l as MetroReloadOptions, s as MetroPrepareOptions, u as MetroReloadResult } from "./sdk-remote-config.js";
|
|
6
7
|
import { t as BatchRunResult } from "./sdk-batch-runner.js";
|
|
7
8
|
//#region packages/contracts/src/json.d.ts
|
|
@@ -57,7 +58,7 @@ type AgentDeviceClientConfig = RemoteConnectionProfileFields & CloudProviderProf
|
|
|
57
58
|
iosXctestDerivedDataPath?: string;
|
|
58
59
|
iosXctestEnvDir?: string;
|
|
59
60
|
};
|
|
60
|
-
type AgentDeviceRequestOverrides = Pick<AgentDeviceClientConfig, 'session' | 'lockPolicy' | 'lockPlatform' | 'requestId' | 'daemonBaseUrl' | 'daemonAuthToken' | 'daemonTransport' | 'daemonServerMode' | 'tenant' | 'sessionIsolation' | 'runId' | 'leaseId' | 'leaseBackend' | 'leaseProvider' | 'deviceKey' | 'clientId' | 'providerApp' | 'providerOsVersion' | 'providerProject' | 'providerBuild' | 'providerSessionName' | 'providerDeviceOrientation' | 'providerGeoLocation' | 'providerTimezone' | 'providerAppiumVersion' | 'providerLanguage' | 'providerLocale' | 'providerNetworkProfile' | 'providerCustomNetwork' | 'providerNoResignApp' | 'awsProjectArn' | 'awsDeviceArn' | 'awsAppArn' | 'awsRegion' | 'awsInteractionMode' | 'leaseTtlMs' | 'cwd' | 'debug' | 'cost' | 'responseLevel' | 'iosXctestrunFile' | 'iosXctestDerivedDataPath' | 'iosXctestEnvDir'> & {
|
|
61
|
+
type AgentDeviceRequestOverrides = Pick<AgentDeviceClientConfig, 'session' | 'lockPolicy' | 'lockPlatform' | 'requestId' | 'daemonBaseUrl' | 'daemonAuthToken' | 'daemonTransport' | 'daemonServerMode' | 'tenant' | 'sessionIsolation' | 'runId' | 'leaseId' | 'leaseBackend' | 'leaseProvider' | 'deviceKey' | 'clientId' | 'providerApp' | 'providerOsVersion' | 'providerDeviceType' | 'providerProject' | 'providerBuild' | 'providerSessionName' | 'providerDeviceOrientation' | 'providerGeoLocation' | 'providerTimezone' | 'providerAppiumVersion' | 'providerLanguage' | 'providerLocale' | 'providerNetworkProfile' | 'providerCustomNetwork' | 'providerNoResignApp' | 'awsProjectArn' | 'awsDeviceArn' | 'awsAppArn' | 'awsRegion' | 'awsInteractionMode' | 'leaseTtlMs' | 'cwd' | 'debug' | 'cost' | 'responseLevel' | 'iosXctestrunFile' | 'iosXctestDerivedDataPath' | 'iosXctestEnvDir'> & {
|
|
61
62
|
/**
|
|
62
63
|
* Cancels this one call. Already aborted: the call rejects without sending anything
|
|
63
64
|
* (`details.dispatched: 'no'`). Aborted in flight: the request's connection closes, the daemon
|
|
@@ -363,8 +364,9 @@ type SnapshotCaptureAnnotations = {
|
|
|
363
364
|
warnings?: string[];
|
|
364
365
|
/** The Apple runner re-activated the session app while serving this capture (#2682). */
|
|
365
366
|
targetActivation?: IosTargetActivation;
|
|
367
|
+
observation?: IosSnapshotObservation;
|
|
366
368
|
};
|
|
367
|
-
type PublicSnapshotCaptureAnnotations = Pick<SnapshotCaptureAnnotations, 'androidSnapshot' | 'warnings' | 'targetActivation'> & {
|
|
369
|
+
type PublicSnapshotCaptureAnnotations = Pick<SnapshotCaptureAnnotations, 'androidSnapshot' | 'warnings' | 'targetActivation' | 'observation'> & {
|
|
368
370
|
snapshotQuality?: SnapshotQualityVerdict;
|
|
369
371
|
};
|
|
370
372
|
//#endregion
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { D as IosSnapshotObservation, F as SnapshotNode, M as ScreenshotOverlayRef, R as SnapshotQualityVerdict, T as PublicPlatform, V as SnapshotViewportSize, n as DaemonArtifactType, z as SnapshotState } from "./sdk-contracts.js";
|
|
2
2
|
import { v as SettleObservation } from "./sdk-selectors.js";
|
|
3
3
|
//#region packages/contracts/src/back-mode.d.ts
|
|
4
4
|
declare const BACK_MODES: readonly ['in-app', 'system'];
|
|
@@ -295,6 +295,7 @@ type BackendSnapshotResult = {
|
|
|
295
295
|
};
|
|
296
296
|
quality?: SnapshotQualityVerdict;
|
|
297
297
|
warnings?: string[];
|
|
298
|
+
observation?: IosSnapshotObservation;
|
|
298
299
|
};
|
|
299
300
|
type AndroidSnapshotBackendMetadata = {
|
|
300
301
|
backend: 'android-helper';
|
|
@@ -319,6 +320,12 @@ type AndroidSnapshotBackendMetadata = {
|
|
|
319
320
|
captureMode?: string;
|
|
320
321
|
systemSurfaceOnly?: boolean;
|
|
321
322
|
windowCount?: number;
|
|
323
|
+
/**
|
|
324
|
+
* `AccessibilityWindowInfo` types of the listed windows the helper could not serialize because
|
|
325
|
+
* reading their root returned null or threw (`2` is an input method window); `windowCount` counts
|
|
326
|
+
* only the roots it serialized. Empty when every listed window was read. Absent on an older helper.
|
|
327
|
+
*/
|
|
328
|
+
missingRootWindowTypes?: number[];
|
|
322
329
|
nodeCount?: number;
|
|
323
330
|
helperTruncated?: boolean;
|
|
324
331
|
elapsedMs?: number;
|
|
@@ -393,4 +400,4 @@ type CloudArtifactProvider = {
|
|
|
393
400
|
listCloudArtifacts?: (query: CloudArtifactsQuery) => Promise<CloudArtifactsResult | undefined>;
|
|
394
401
|
};
|
|
395
402
|
//#endregion
|
|
396
|
-
export {
|
|
403
|
+
export { SetFoldPoseInput as A, ScrollInputDirection as C, DeviceRotation as D, TransformGestureParams as E, FoldPose as O, ScrollDirection as S, SwipePreset as T, SettingOptions as _, AndroidSnapshotBackendMetadata as a, ScrollCommandResult as b, ScreenshotResultData as c, MACOS_PERMISSION_TARGETS as d, MOBILE_PERMISSION_TARGETS as f, ReadableSetting as g, ReadSettingResult as h, CloudProviderSessionResult as i, BackMode as j, FoldScreenCoordinateSpace as k, SnapshotDiagnosticsSummary as l, PermissionMode as m, CloudArtifactProvider as n, BackendSnapshotResult as o, PermissionAction as p, CloudArtifactsResult as r, FindLocator as s, AgentArtifactsResult as t, SessionSurface as u, TextSizeCategory as v, SwipePattern as w, ScrollExecutionOptions as x, TvRemoteButton as y };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{j as e}from"./owner-identity.js";import"./file.js";import{a as t,r as n,s as r,t as i}from"./code-signature.js";import a from"node:crypto";import o from"node:fs";import s from"node:os";import c from"node:path";function l(e,a){let o=t(a),s=t(e),c=v(s,o),l=i(o,s),d=u(c,o,l);if(d)return n(d.files);let p;try{p=r(s,o)}catch{return`unknown`}return f(p.files,l)&&_(c,p),n(p.files)}function u(e,t,n){let r=p(e);if(!(!r||!f(r.files,n))){for(let[e,n,i]of r.files){let r=d(c.resolve(t,e));if(!r?.isFile()||r.size!==n||Math.trunc(r.mtimeMs)!==i)return}for(let e of r.absentPaths)if(d(c.resolve(t,e))?.isFile())return;return r}}function d(e){try{return o.statSync(e)}catch{return}}function f(e,t){return e.some(([e])=>e===t)}function p(e){let t=m(e);if(!t)return;let n=[];for(let e of t.files){let t=g(e);if(!t)return;n.push(t)}if(t.absent.every(e=>typeof e==`string`))return{files:n,absentPaths:t.absent}}function m(e){let t=h(e);if(t===void 0)return;let n;try{n=JSON.parse(t)}catch{return}if(!n||typeof n!=`object`)return;let r=n;if(r.version===2&&!(!Array.isArray(r.files)||!Array.isArray(r.absent)))return{files:r.files,absent:r.absent}}function h(e){let t;try{t=o.openSync(e,`r`)}catch{return}try{let e=process.getuid?.();return e!==void 0&&o.fstatSync(t).uid!==e?void 0:o.readFileSync(t,`utf8`)}catch{return}finally{o.closeSync(t)}}function g(e){if(!Array.isArray(e)||e.length!==3)return;let[t,n,r]=e;if(typeof t==`string`&&typeof n==`number`&&typeof r==`number`)return[t,n,r]}function _(t,n){let r={version:2,files:[...n.files],absent:[...n.absentPaths]};try{o.mkdirSync(c.dirname(t),{recursive:!0,mode:448}),e({destination:t,contents:JSON.stringify(r),mode:384})}catch{}}function v(e,t){let n=a.createHash(`sha1`).update(`${t} ${e}`).digest(`hex`),r=`agent-device-code-signature-${process.getuid?.()??`user`}`;return c.join(s.tmpdir(),r,`${n}.json`)}export{l as resolveCachedDaemonCodeSignature};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{o as e}from"./registry.js";import{v as t}from"./sdk-batch.js";const n=e(),r=new Map(n.map(e=>[e.name,e]));function i(){return[...n]}function a(){return t().map(e=>{let t=s(e);if(!t)throw Error(`Missing command metadata for MCP-exposed command: ${e}`);return t})}function o(e){return r.has(e)}function s(e){return r.get(e)}export{a as i,o as n,i as r,s as t};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{P as e}from"./sdk-contracts.js";import{
|
|
1
|
+
import{P as e}from"./sdk-contracts.js";import{C as t,E as n,r}from"./registry.js";import{r as i}from"./command-metadata.js";const a={plugins:{text:{summary:`Manage installed provider plugins`,description:`Install, list, update, or remove npm provider plugins in AGENT_DEVICE_HOME (default ~/.agent-device). Changes take effect after restarting the local daemon. Use --json for structured results.`},usageOverride:`plugins list|add <package[@version]>|update <package>|remove <package>`,listUsageOverride:`plugins`,positionalArgs:[`list|add|update|remove`,`package?`],supportedFlags:[]},cdp:{text:{summary:`Inspect CDP targets, JS heap, and leaks`,description:`Run CDP commands for React Native diagnostics, JS heap usage, heap snapshots, and leak analysis`},usageOverride:`cdp [...args]`,listUsageOverride:`cdp`,positionalArgs:[`args?`],allowsExtraPositionals:!0,supportedFlags:t},auth:{text:{summary:`Manage cloud login state`,description:`Manage cloud login state used by remote daemon and cloud device workflows.`},usageOverride:`auth status|login|logout`,listUsageOverride:`auth`,positionalArgs:[`status|login|logout`],supportedFlags:[`remoteConfig`,`stateDir`]},daemon:{text:{summary:`Stop a local daemon and clean up resources`,description:`Stop a local daemon after verifying its PID/start-time identity. Use --clean to remove retained Apple runner processes and leases owned by that daemon.`},usageOverride:`daemon stop [--state-dir <path>]`,listUsageOverride:`daemon stop`,positionalArgs:[`stop`],allowedFlags:[`clean`],supportedFlags:[`stateDir`]},device:{text:{summary:`Inspect and recover enforced local device ownership without a daemon`,description:`Inspect enforced host-local device ownership claims without starting or contacting a daemon; status --stale only inspects proven-stale claims. release --stale settles a provably dead owner through exact-owner resource reconciliation and clears its claim last — live and uncertain owners always fail closed. Automatic reclamation still occurs during open and daemon startup.`},usageOverride:`device status|release [--platform <platform>] [--udid <udid>] [--serial <serial>]`,listUsageOverride:`device status`,positionalArgs:[`status|release`],allowedFlags:[`stale`],supportedFlags:[`platform`,`device`,`udid`,`serial`]},connect:{text:{summary:`Configure remote or provider state`,description:`Configure remote access without allocating a device. Direct providers validate credentials/resources before saving state and print the exact device/app preparation needed before open. AGENT_DEVICE_CLOUD_BASE_URL is the bridge/control-plane API origin; use AGENT_DEVICE_DAEMON_AUTH_TOKEN=adc_live_... for CI/service-token automation.`},usageOverride:`connect [provider] [--remote-config <path>] [--daemon-base-url <url>] [--tenant <id>] [--run-id <id>] [--lease-id <id>] [--lease-backend <backend>] [--force] [--no-login]`,usageFlags:[],listUsageOverride:`connect`,positionalArgs:[`provider?`],allowedFlags:`remoteConfig.daemonBaseUrl.tenant.runId.leaseId.leaseBackend.providerApp.providerOsVersion.providerDeviceType.providerProject.providerBuild.providerSessionName.providerDeviceOrientation.providerGeoLocation.providerTimezone.providerAppiumVersion.providerLanguage.providerLocale.providerNetworkProfile.providerCustomNetwork.providerNoResignApp.awsProjectArn.awsDeviceArn.awsAppArn.awsRegion.awsInteractionMode.force.noLogin`.split(`.`),supportedFlags:[`stateDir`,`daemonAuthToken`,`session`,`platform`,`device`,...n,`launchUrl`]},connection:{text:{summary:`Inspect the saved remote connection`,description:`Inspect active remote connection state`},usageOverride:`connection status`,listUsageOverride:`connection`,positionalArgs:[`status`],supportedFlags:[`remoteConfig`,`stateDir`,`session`]},disconnect:{text:{summary:`Clear remote connection state and release leases`,description:`Disconnect remote daemon state, stop owned Metro companion, and release lease`},listUsageOverride:`disconnect`,allowedFlags:[`shutdown`],supportedFlags:[`remoteConfig`,`stateDir`,`session`]},mcp:{text:{summary:`Start MCP server`,description:`Start the official stdio MCP server. It exposes structured command tools backed by the agent-device client.`}},proxy:{text:{summary:`Expose a local daemon through an HTTP tunnel`,description:`Expose the local daemon HTTP contract through a tunnel-friendly reverse proxy.
|
|
2
2
|
|
|
3
3
|
Run this on the host that has access to simulators/devices, expose the printed local proxy URL through a tunnel, then point another machine at the tunnel URL with connect proxy.
|
|
4
4
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{J as e,P as t,X as n,Z as r,i}from"./sdk-contracts.js";import{g as a,v as o}from"./sdk-batch-runner.js";import{
|
|
2
|
-
`)}function De(e,t,n){let r=j({command:e,cwd:process.cwd(),cliFlags:t}),i={};for(let[t,a]of Object.entries(r))Object.hasOwn(n,t)&&k(t,e)&&(i[t]=a);return A(i,t)}const Oe={devices:async e=>({devices:e.map(M)}),apps:async e=>({apps:e})};async function ke(e,t){let n=Oe[e];return n?await n(t):t}function Ae(){let e=new Map;return{pinInput:(t,n,r)=>Ue(t,n,Pe(e,r,n.session)),mergeCommandResult:(t,n,r,i)=>Fe(e,t,n,r,i),mergeErrorDetails:(t,n,r)=>{let i=H(n,r);
|
|
1
|
+
import{J as e,P as t,X as n,Z as r,i}from"./sdk-contracts.js";import{g as a,v as o}from"./sdk-batch-runner.js";import{A as s,B as c,I as l,L as u,M as d,N as f,O as p,P as m,S as ee,_ as te,b as h,d as ne,f as re,g as ie,h as ae,j as g,k as _,l as oe,p as se,s as ce,v as le,z as v}from"./registry.js";import{a as y,n as ue,t as de}from"./sdk-device.js";import{C as fe,T as pe,c as me,f as he,m as b}from"./sdk-batch.js";import{n as ge}from"./success-text.js";import{t as _e}from"./output-common.js";import{i as ve,n as x,r as ye,t as S}from"./command-metadata.js";import{n as C,t as w}from"./cli-output.js";import{r as T,t as E}from"./recording-stop-observation.js";import{r as D}from"./replay-divergence.js";import{n as O}from"./error.js";import{i as k,r as A,t as j}from"./cli-config.js";import{n as M}from"./result-serialization.js";const N=f({field:m(),artifactType:m(),path:m(),localPath:m(),fileName:m()},[`field`]),P={record:{type:`object`,oneOf:[f({recording:_(`started`),outPath:m(),sessionStateDir:m(),recordingBackend:m(),recordingScope:m(),recordOnlySession:p(),activeSessionApp:g(),showTouches:p()},[`recording`,`outPath`,`sessionStateDir`,`showTouches`]),f({recording:_(`stopped`),outPath:m(),telemetryPath:m(),artifacts:{type:`array`,items:N},recordingBackend:m(),recordingScope:m(),recordOnlySession:p(),activeSessionApp:g(),durationMs:d(),capturedDurationMs:d(),recorder:s(E,`What the recorder was observed doing when the recording was stopped: confirmed, or lost when the session holding it died. ADR 0024 reserves unconfirmed for the step that gains the probe.`),nativePathDisposition:s(T,`What became of the artifact path the recorder writes to: retirable while it still owes a removal, retired once that removal was verified. ADR 0024 reserves pending.`),showTouches:p(),warning:m(),overlayWarning:m(),chunks:{type:`array`,items:g()}},[`recording`,`outPath`,`artifacts`,`durationMs`,`showTouches`])]},trace:{type:`object`,oneOf:[f({trace:_(`started`),outPath:m()},[`trace`,`outPath`]),f({trace:_(`stopped`),outPath:m(),artifacts:{type:`array`,items:N}},[`trace`,`outPath`,`artifacts`])]}},be=f({settled:p(`Whether the UI held the quiet window before the deadline. false is advisory, not failure.`),waitedMs:d(),captures:d(),quietMs:d(),timeoutMs:d(),refsGeneration:d(`Snapshot generation of the stored settled tree; refs on added diff lines were minted from it.`),refs:{type:`array`,items:f({ref:m(`Plain ref body (e12) minted from the stored settled tree.`)},[`ref`])},surfaceChange:le,diff:f({summary:f({additions:d(),removals:d(),unchanged:d()},[`additions`,`removals`,`unchanged`]),lines:{type:`array`,items:f({kind:s([`added`,`removed`]),text:m(),ref:m(`Plain ref body (e12) for added lines.`)},[`kind`,`text`])},truncated:p(`Lines were capped to the response bound.`)},[`summary`,`lines`],`Settled diff vs the pre-action tree (changed lines only).`),tail:{type:`array`,description:`Unchanged interactive refs tail: still-present, actionable elements from the settled tree, attached only when diff carries zero added-line refs (a modal-dismiss/toast-only diff).`,items:f({ref:m(`Plain ref body (e12) minted from the stored settled tree.`),role:m(),label:m()},[`ref`,`role`])},tailTruncated:p(`Present (true) when tail candidates exceeded the response cap.`),hint:m()},[`settled`,`waitedMs`,`captures`,`quietMs`,`timeoutMs`]);function F(e){return e.oneOf?{...e,oneOf:e.oneOf.map(F)}:{...e,properties:{...e.properties??{},settle:be}}}function xe(e){let t={...e};for(let e of Object.keys(t))b(e)&&(t[e]=F(t[e]));return t}const Se=xe({scroll:f({direction:s([`up`,`down`,`left`,`right`]),edge:s([`top`,`bottom`]),until:m(`Until scrolls only: the selector the passes stopped on.`),passes:d(`Edge and until scrolls only: how many scroll-and-check passes ran.`),amount:d(),pixels:d(),durationMs:d(),message:m(),keyboardAvoided:p(`Present only when an on-screen keyboard forced the swipe into the band above it; the reported pixels were planned against the shorter referenceHeight.`),keyboardMinY:d(`Where the keyboard began, in the same unit as the gesture coordinates. Clipped scrolls only.`),movement:s([`moved`,`at-edge`,`unchanged`,`unobserved`],"Directional scrolls only: what the owner observed after its gesture. `moved` means the content inside the scroller the swipe ran in differs from the tree the session stored immediately before the gesture; `at-edge` and `unchanged` mean it did not change, with no hidden content left to reveal and with no end-of-content signal to read, respectively; `unobserved` means the pair could not back a claim in either direction — nothing comparable was available (no stored tree, a capture from another lineage, a surface that never came to rest), or every difference sits outside the scroller that was swiped, which a changing status bar does on Android — so the reported distance rests on the gesture plan alone. The field is absent — which is never a claim that nothing moved — on the tiers that verify per pass (`scroll top`/`bottom`, `--until`), on a runtime bound without a capture, on a platform whose scroll dispatches no swipe (the Linux wheel), and where the caller already owns that observation (`--settle`, or a replay with `postGestureStabilization: false`).")},[`direction`]),...ee,...h,...se,...ae,...ie,...re,...ne,...te,...P,...oe,...ce}),Ce={devices:{type:`object`,properties:{devices:{type:`array`,items:{type:`object`,properties:{platform:{type:`string`,enum:y},target:{type:`string`,enum:ue},kind:{type:`string`,enum:de},id:{type:`string`},name:{type:`string`}},required:[`platform`,`target`,`kind`,`id`,`name`]}}},required:[`devices`]},apps:{type:`object`,properties:{apps:{type:`array`,items:{type:`string`}}},required:[`apps`]}},I={...Se,...Ce},we={stateDir:{schema:{type:`string`,description:`Agent-device state directory.`},audience:v({operatorConfig:!0})},mcpOutputFormat:{schema:{type:`string`,enum:[`optimized`,`json`],description:`MCP text content format. Defaults to optimized agent-friendly text; use json for JSON text. Structured content is always returned separately.`}},includeCost:{schema:{type:`boolean`,description:`Include per-command agent-cost (cost.wallClockMs, …) in structuredContent. Defaults to off; the default response shape is unchanged.`}},responseLevel:{schema:{type:`string`,enum:[`digest`,`default`,`full`],description:`Response verbosity: token-cheap digest / default (today) / full. Defaults to default; the default response shape is unchanged.`}}},L=Object.entries(we),R=new Set(L.map(([e])=>e)),Te=Object.fromEntries(L.flatMap(([e,t])=>t.audience?[[e,t.audience]]:[]));function Ee(){return Object.fromEntries(L.map(([e,t])=>[e,t.schema]))}function z(t){return e(t)}function B(e){let t=[`Error (${e.code}): ${e.message}`];if(e.cause){let n=e.cause.code?`${e.cause.code} `:``;t.push(`Cause: ${n}${e.cause.message}`)}e.hint&&t.push(`Hint: ${e.hint}`);for(let n of ge(e.details))t.push(`Warning: ${_e(n)}`);t.push(...O(r(e.details))),e.supportedOn&&t.push(`Supported on: ${e.supportedOn}`);let n=D(e.details);return n&&t.push(n),t.join(`
|
|
2
|
+
`)}function De(e,t,n){let r=j({command:e,cwd:process.cwd(),cliFlags:t}),i={};for(let[t,a]of Object.entries(r))Object.hasOwn(n,t)&&k(t,e)&&(i[t]=a);return A(i,t)}const Oe={devices:async e=>({devices:e.map(M)}),apps:async e=>({apps:e})};async function ke(e,t){let n=Oe[e];return n?await n(t):t}function Ae(){let e=new Map;return{pinInput:(t,n,r)=>Ue(t,n,Pe(e,r,n.session)),mergeCommandResult:(t,n,r,i)=>Fe(e,t,n,r,i),mergeErrorDetails:(t,n,r)=>{let i=H(n,r);V(e,i,t),Ve(e,i,t)}}}function V(e,t,r){let i=r?.refsGeneration;typeof i==`number`&&U(e,t,n(r),i)}const je=new Set([`snapshot`,`find`]),Me=new Set(he.map(e=>e.name).filter(x).filter(e=>b(e))),Ne=new Set([`press`,`click`,`fill`,`longpress`,`hover`,`get`]);function Pe(e,t,n){return e.get(H(t,n))}function H(e,t){let n=typeof t==`string`&&t.length>0?t:`default`;return`${e??``}\u0000${n}`}function Fe(e,t,n,r,i){let a=H(r,i);if(Me.has(t)){Re(e,a,ze(n));return}je.has(t)&&(t===`find`?Le(e,a,n):Ie(e,a,n))}function Ie(e,t,n){let r=n.refsGeneration;if(typeof r!=`number`){e.delete(t);return}let i=[];for(let{ref:e}of n.refs??[])i.push(e);for(let e of n.nodes??[])i.push(e.ref);U(e,t,i,r)}function Le(e,t,n){let r=n.refsGeneration;if(typeof r!=`number`)return;let i=[];typeof n.ref==`string`&&n.ref.startsWith(`@`)&&i.push(n.ref.slice(1));for(let e of n.matches??[])typeof e.ref==`string`&&e.ref.length>0&&i.push(e.ref.startsWith(`@`)?e.ref.slice(1):e.ref);U(e,t,i,r)}function Re(e,t,n){n?.refsGeneration!==void 0&&U(e,t,[...n.diff?.lines??[],...n.refs??[],...n.tail??[]].map(e=>e.ref).filter(e=>typeof e==`string`),n.refsGeneration)}function ze(e){let t=e.settle;return typeof t==`object`&&t?t:void 0}function U(e,t,n,r){if(n.length===0)return;let i=e.get(t)??new Map;e.set(t,i),Be(i,n,r)}function Be(e,t,n){for(let r of t)e.delete(r),e.set(r,n);for(;e.size>1e3;)e.delete(e.keys().next().value)}function Ve(e,t,n){let r=a(n?.divergence),i=a(r?.screen);if(i?.state!==`available`)return;let o=i.refsGeneration;if(typeof o!=`number`)return;let s=[];He(i.refs,s),U(e,t,s,o)}function He(e,t){if(Array.isArray(e))for(let n of e){let e=a(n)?.ref;typeof e==`string`&&e.length>0&&t.push(e)}}function Ue(e,t,n){return n===void 0||n.size===0?t:e===`wait`?We(t,n)??t:Ne.has(e)?Ge(t,n)??t:t}function We(e,t){if(typeof e.ref!=`string`)return;let n=W(e.ref,t);return n===e.ref?void 0:{...e,ref:n}}function Ge(e,t){let n=a(e.target);if(n?.kind!==`ref`||typeof n.ref!=`string`)return;let r=W(n.ref,t);return r===n.ref?void 0:{...e,target:{...n,ref:r}}}function W(e,t){if(!e.startsWith(`@`)||e.includes(`~`))return e;let n=t.get(e.slice(1));return n===void 0?e:`${e}~s${n}`}const Ke={config:v({operatorPath:`Point the process serving these tools at a config file with the AGENT_DEVICE_CONFIG environment variable.`}),remoteConfig:v({operatorPath:`Configure the remote profile on the process serving these tools, not per tool call.`})},qe=Object.fromEntries(ye().flatMap(e=>Object.entries(e.inputAudience).filter(([,e])=>e.kind===`operator`)));function G(e){return{...e.inputAudience,...u,...Te,...Ke,...qe}}function Je(){return ve().map(e=>{let t=e.name in I?I[e.name]:void 0,n=J(e.name,e);return{name:e.name,description:it(e.name,l(e)),inputSchema:n,...t?{outputSchema:t}:{}}})}function K(e={}){let n=Ae();return{execute:async(r,i)=>{if(!x(r))throw new t(`INVALID_ARGS`,`Unknown command tool: ${r}`);let a=S(r),o=Y(r,a,i)??X(a.inputSchema,i,r);if(o)return await q(new t(`INVALID_ARGS`,o),n,void 0,i.session);let s=Q(r,a.inputSchema).properties,c=De(r,i,s),l=Qe(c),u=nt(c),d=n.pinInput(r,u,l.client.stateDir),f=await Xe(e,l.client);try{let t=await(e.runCommand??Ze)(f,r,d);return n.mergeCommandResult(r,t,l.client.stateDir,u.session),{isError:!1,structuredContent:await ke(r,t),content:[{type:`text`,text:await at({name:r,input:u,result:t,outputFormat:l.outputFormat,responseLevel:l.client.responseLevel})}]}}catch(e){return await q(e,n,l.client.stateDir,u.session)}}}}async function q(e,t,n,r){let i=z(e);return t.mergeErrorDetails(i.details,n,r),{isError:!0,structuredContent:i,content:[{type:`text`,text:B(i)}]}}const Ye=K();async function Xe(e,t){if(e.createClient)return await e.createClient(t);let{createAgentDeviceClient:n}=await import(`./agent-device-client.js`).then(e=>e.t);return n(t)}async function Ze(e,t,n){return await(await import(`./command-surface.js`).then(e=>e.t)).runCommand(e,t,n)}function Qe(e){return{client:$e(e),outputFormat:tt(e.mcpOutputFormat)}}function $e(e){let n=e.stateDir,r=e.includeCost,i=e.responseLevel,a={};if(n!==void 0){if(typeof n!=`string`||n.length===0)throw new t(`INVALID_ARGS`,`Expected stateDir to be a non-empty string.`);a.stateDir=n}if(r!==void 0){if(typeof r!=`boolean`)throw new t(`INVALID_ARGS`,`Expected includeCost to be a boolean.`);r&&(a.cost=!0)}let o=et(i);return o!==void 0&&(a.responseLevel=o),a}function et(e){if(e===void 0)return;let n=i.find(t=>t===e);if(n===void 0)throw new t(`INVALID_ARGS`,`Expected responseLevel to be one of 'digest', 'default', or 'full'.`);return n}function tt(e){if(e===void 0)return`optimized`;if(e!==`optimized`&&e!==`json`)throw new t(`INVALID_ARGS`,`Expected mcpOutputFormat to be "optimized" or "json".`);return e}function nt(e){return Object.fromEntries(Object.entries(e).filter(([e])=>!R.has(e)))}function J(e,t){let n=G(t),r=Q(e,t.inputSchema);return{...r,properties:Object.fromEntries(Object.entries(r.properties).filter(([e])=>n[e]?.kind!==`operator`))}}function Y(e,t,n){let r=J(e,t).properties,i=G(t);for(let t of Object.keys(n)){if(Object.hasOwn(r,t))continue;let n=Object.hasOwn(i,t)?i[t]:void 0;if(n?.kind!==`retired`)return n?.kind===`operator`?c(t,n.source):`${t} is not an accepted argument for the ${e} tool.`}}function X(e,t,n){if(!(!e||t===void 0)){if(Array.isArray(t))return Z(t,(t,r)=>X(e.items,t,`${n}[${r}]`));if(o(t))return Z(e.oneOf??[],e=>X(e,t,n))??Z(Object.entries(e.properties??{}),([e,r])=>Object.hasOwn(t,e)?rt(r,t,e,`${n}.${e}`):void 0)}}function rt(e,t,n,r){let i=e.commandInputFor;if(i===void 0)return X(e,t[n],r);let a=t[n],s=me(t[i]);if(s===void 0||!o(a))return;let c=Y(s,S(s),a);return c===void 0?void 0:`${r}: ${c}`}function Z(e,t){for(let[n,r]of e.entries()){let e=t(r,n);if(e)return e}}function it(e,t){let n=pe(e);if(n.envelopeMs===`unbounded`)return`${t} Streams progress; no fixed client timeout.`;let r=Math.round(n.envelopeMs/1e3);return n.budget.source===`none`?`${t} Times out after ${r}s.`:`${t} Times out after ${r}s; a caller-supplied budget extends it.`}function Q(e,t){let n=fe(e);return{...t,properties:{...t.properties,...n&&!t.properties?.noRecord?{noRecord:{type:`boolean`,description:`Do not record this action.`}}:{},...Ee()}}}async function at(e){if(e.outputFormat===`json`||e.responseLevel!==void 0&&e.responseLevel!=="default")return $(e.result);let t=await w({name:e.name,input:e.input,result:e.result});return typeof t?.text==`string`?ot(e.name,t):$(t?.data??e.result)}function ot(e,t){let n=t.text??``;if(!C(e))return n;let r=t.stderr?.trimEnd()??``;return r===``?n:`${n}${n.endsWith(`
|
|
3
3
|
`)?``:`
|
|
4
4
|
`}${r}`}function $(e){return typeof e==`string`?e:JSON.stringify(e,null,2)}export{z as a,B as i,K as n,R as o,Je as r,Ye as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{P as e,d as t,l as n,p as r}from"./sdk-contracts.js";import{r as i}from"./diagnostics.js";import"./diagnostics2.js";import{C as a,D as o,o as s,s as c,w as l}from"./sdk-device.js";import{a as u,c as d,l as f,r as p}from"./lease-scope.js";import{n as m,t as h}from"./catalog.js";import{t as g}from"./sdk-remote-config.js";import{t as _}from"./prepare-kind.js";import{A as v}from"./owner-identity.js";import{p as y}from"./exec.js";import"./file.js";import"./command.js";import{t as ee}from"./daemon-resolution.js";import{_ as b}from"./base-url.js";import{i as te,r as ne}from"./client-metro-companion.js";import{n as re}from"./metro2.js";import{n as ie,r as x,t as ae}from"./remote-config2.js";import{a as S,n as C}from"./providers.js";import w from"node:crypto";import T from"node:fs";import E from"node:path";const D={slug:`react-devtools-companion`,runArg:b,displayName:`React DevTools companion`};async function oe(e){return await ne({...e,definition:D,localBaseUrl:e.localBaseUrl??`http://127.0.0.1:8097`,registerPath:`/api/react-devtools/companion/register`,unregisterPath:`/api/react-devtools/companion/unregister`,devicePort:e.devicePort??8097})}async function O(e){return await te({...e,definition:D})}function se(e){return e===`android-instance`||e===`ios-instance`}function ce(e){return[`exec`,`--yes`,`--package`,`agent-cdp@1.6.1`,`--`,`agent-cdp`,...e]}function le(e){return e.some(e=>e===`--url`||e.startsWith(`--url=`))}function ue(e){return e[0]===`target`&&(e[1]===`list`||e[1]===`select`)&&!le(e)}function de(e){let t=new URL(e);t.search=``,t.hash=``;let n=t.pathname.replace(/\/+$/,``);return t.pathname=n.endsWith(`/index.bundle`)?n.slice(0,-13)||`/`:n||`/`,t.toString().replace(/\/+$/,``)}function fe(e){let t=e?.metroPublicBaseUrl?.trim();return t?de(t):null}function pe(t,n={}){if(!ue(t)||!n.flags?.metroProxyBaseUrl||!se(n.flags.leaseBackend))return t;let r=fe(n.flags);if(!r)throw new e(`INVALID_ARGS`,`cdp remote bridge target discovery requires a React Native dev-server public base URL.`,{hint:`Include metroPublicBaseUrl in the remote config so cdp can reach the local or tunneled Metro/Re.Pack CDP endpoint without bridge proxy authentication.`});return[...t,`--url`,r]}async function me(e,t={}){let n=pe(e,t);return(await y(`npm`,ce(n),{cwd:t.cwd??process.cwd(),env:t.env??process.env,allowFailure:!0,onStdoutChunk:e=>{process.stdout.write(e)},onStderrChunk:e=>{process.stderr.write(e)}})).exitCode}function k(e){let n=l(e),r=t(n);return{platform:n,target:e.target,leaseBackend:r,identityFlag:r?c(n):void 0,id:e.id}}function he(e){return`${e.platform}:${e.target??`mobile`}:${e.id}`}function A(e){let t=[e.leaseBackend?r(e.leaseBackend):void 0,e.recordedPlatform].filter(e=>e!==void 0);if(t.some(e=>t.some(t=>a(e,t)))||a(e.requestedPlatform,t[0]??e.recordedPlatform))return{ok:!1,boundPlatform:t[0],requestedPlatform:e.requestedPlatform};let n=[...t,e.requestedPlatform].filter(e=>e!==void 0);return{ok:!0,platform:n.find(e=>e!==`apple`)??n[0]}}function ge(e,t){return t!==void 0&&e.platform===void 0?!1:A({leaseBackend:e.leaseBackend,recordedPlatform:e.platform,requestedPlatform:t}).ok}function j(e){let t=R(e);if(!T.existsSync(t))return null;let n;try{n=JSON.parse(T.readFileSync(t,`utf8`))}catch(t){return U(e,t),null}return Ce(n)?n:(U(e),null)}function M(e){let t=R({stateDir:e.stateDir,session:e.state.session});T.mkdirSync(E.dirname(t),{recursive:!0}),H(t,e.state),H(z(e.stateDir),{session:e.state.session})}function N(e){return{baseUrl:xe(e.daemonBaseUrl),transport:e.daemonTransport,serverMode:e.daemonServerMode}}function P(e){T.rmSync(R(e),{force:!0});let t=z(e.stateDir);V(e.stateDir)===e.session&&T.rmSync(t,{force:!0})}function _e(t){let n=t.validateRemoteConfigHash??!0,r=t.remoteConfig?ie({configPath:t.remoteConfig,cwd:t.cwd,env:t.env}):void 0,i=j(t)??(t.allowActiveFallback?B({stateDir:t.stateDir}):null);if(!i||r&&i.remoteConfigPath!==r)return null;if(n&&L(i.remoteConfigPath)!==i.remoteConfigHash)throw new e(`INVALID_ARGS`,`Active remote connection config changed. Run agent-device connect --force to refresh it.`,{remoteConfig:i.remoteConfigPath});let a=be(i,t),o=u(i);return{runtime:i.runtime,connection:f(o),flags:{...a,remoteConfig:i.remoteConfigPath,daemonBaseUrl:i.daemon?.baseUrl??a.daemonBaseUrl,daemonAuthToken:a.daemonAuthToken,daemonTransport:i.daemon?.transport??a.daemonTransport,daemonServerMode:i.daemon?.serverMode??a.daemonServerMode,...d(o),sessionIsolation:`tenant`,session:i.session,platform:i.platform??a.platform,target:i.target??a.target}}}function F(e){return f(u(e))}function I(e,t){return{leaseProvider:e.leaseProvider??t.leaseProvider,clientId:e.clientId??t.clientId,deviceKey:e.deviceKey??t.deviceKey}}function ve(e,t){return!t||(t.leaseProvider===void 0||e.leaseProvider===t.leaseProvider)&&(t.clientId===void 0||e.clientId===t.clientId)}function L(t){try{return w.createHash(`sha256`).update(T.readFileSync(t)).digest(`hex`)}catch(n){throw new e(`INVALID_ARGS`,`Remote config file not found: ${t}`,{cause:n instanceof Error?n.message:String(n)})}}function R(e){return E.join(e.stateDir,`remote-connections`,`${Se(e.session)}.json`)}function z(e){return E.join(e,`remote-connections`,`.active-session.json`)}function B(e){let t=V(e.stateDir);return t?j({stateDir:e.stateDir,session:t}):null}function V(e){let t=z(e);if(T.existsSync(t))try{let e=JSON.parse(T.readFileSync(t,`utf8`));return typeof e.session==`string`?e.session:void 0}catch{return}}function ye(e){if(e)return w.createHash(`sha256`).update(e).digest(`hex`).slice(0,12)}function be(e,t){try{return x({configPath:e.remoteConfigPath,cwd:t.cwd,env:t.env}).profile}catch(e){if(t.validateRemoteConfigHash===!1)return{};throw e}}function H(e,t){v({destination:e,contents:`${JSON.stringify(t,null,2)}\n`,mode:384})}function xe(e){if(!e)return;let t=new URL(e);t.username=``,t.password=``;for(let e of Array.from(t.searchParams.keys()))/(auth|key|password|secret|token)/i.test(e)&&t.searchParams.delete(e);return t.toString().replace(/\/+$/,``)}function U(e,t){i({level:`warn`,phase:`remote_connection_state_invalid`,data:{session:e.session,cause:t instanceof Error?t.message:t?String(t):void 0}}),P(e)}function Se(e){let t=e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`);return t?t===e?t:`${t}-${w.createHash(`sha256`).update(e).digest(`hex`).slice(0,8)}`:`default`}function Ce(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return t.version===1&&we(t,[`session`,`remoteConfigPath`,`remoteConfigHash`,`tenant`,`runId`,`connectedAt`,`updatedAt`])&&Te(t,[`leaseId`,`leaseBackend`,`leaseProvider`,`deviceKey`,`clientId`])&&Ee(t.daemon)}function we(e,t){return t.every(t=>typeof e[t]==`string`)}function Te(e,t){return t.every(t=>e[t]===void 0||typeof e[t]==`string`)}function Ee(e){return e===void 0?!0:!e||typeof e!=`object`||Array.isArray(e)?!1:De(e)}function De(e){let t=e;return(t.baseUrl===void 0||typeof t.baseUrl==`string`)&&(t.authToken===void 0||typeof t.authToken==`string`)&&(t.transport===void 0||typeof t.transport==`string`)&&(t.serverMode===void 0||typeof t.serverMode==`string`)}const Oe=g.map(e=>e.key);function W(e){let t={};for(let n of Oe){let r=e[n];r!==void 0&&(t[n]=r)}return t}function ke(e){return e.remoteConfig?{...W(x({configPath:e.remoteConfig,cwd:e.cwd,env:e.env}).profile),remoteConfig:e.remoteConfig}:{}}function Ae(e){return e===`cloud`||e===`proxy`||G(e)}function G(e){return e===`limrun`||S(e)}function je(){return[`cloud`,`proxy`,C.browserStack,C.awsDeviceFarm,`limrun`].join(`, `)}function K(e){let t=G(e),n=S(e);return{leaseKind:e===`proxy`?`proxy`:t?`direct-device-provider`:`remote-provider`,requiresAppAttachment:e===C.awsDeviceFarm,requiresRemoteDaemon:!t,supportsArtifacts:n,supportsDeferredAppSelection:e===`limrun`,supportsDirectPortReverse:e===`limrun`,usesCloudWebDriverLease:n}}function q(e){return{providerDeviceOrientation:e.providerDeviceOrientation,providerGeoLocation:e.providerGeoLocation,providerTimezone:e.providerTimezone,providerAppiumVersion:e.providerAppiumVersion,providerLanguage:e.providerLanguage,providerLocale:e.providerLocale,providerNetworkProfile:e.providerNetworkProfile,providerCustomNetwork:e.providerCustomNetwork,providerNoResignApp:e.providerNoResignApp}}function Me(e){return{metroProjectRoot:e.metroProjectRoot,metroKind:e.metroKind,metroPublicBaseUrl:e.metroPublicBaseUrl,metroProxyBaseUrl:e.metroProxyBaseUrl,metroPreparePort:e.metroPreparePort,metroListenHost:e.metroListenHost,metroStatusHost:e.metroStatusHost,metroStartupTimeoutMs:e.metroStartupTimeoutMs,metroProbeTimeoutMs:e.metroProbeTimeoutMs,metroRuntimeFile:e.metroRuntimeFile,metroNoReuseExisting:e.metroNoReuseExisting,metroNoInstallDeps:e.metroNoInstallDeps,launchUrl:e.launchUrl}}const J=new Set([`artifacts`,`connect`,`connection`,`close`,`disconnect`,`metro`,`session`]),Ne=new Set([`open`]),Pe=new Set([m.open,m.install,m.reinstall,h.installSource]);async function Fe(t){let{command:n,flags:r,client:i}=t;if(!r.remoteConfig)return{flags:r,runtime:t.runtime};let a=ee(r.stateDir).baseDir,o=x({configPath:r.remoteConfig,cwd:process.cwd(),env:process.env}),s={...W(o.profile),...r,remoteConfig:o.resolvedPath},c=j({stateDir:a,session:s.session??`default`});if(c&&c.remoteConfigPath!==o.resolvedPath)throw new e(`INVALID_ARGS`,`A different remote connection is already active for this session. Run connect --force or disconnect before using a different --remote-config.`,{session:c.session,activeRemoteConfig:c.remoteConfigPath,requestedRemoteConfig:o.resolvedPath});let l=c??lt(s,o.resolvedPath,o.profile),u={...s,session:l.session},d=K(l.leaseProvider).supportsDeferredAppSelection,f=d&&n===m.open?t.positionals?.[0]:void 0;d&&delete u.providerApp;let p=ct(l.runtime,u.platform)??t.runtime,h=l,g=!c,_,v=Ue(h);if(v.shouldAllocate(n)){let e=await Be({command:n,client:i,state:l,nextState:h,nextFlags:u,initialApp:f,policy:v});h=e.state,g||=e.changed,_=e.acquiredLeaseForCleanup}let y=A({leaseBackend:h.leaseBackend,recordedPlatform:h.platform,requestedPlatform:u.platform});if(!y.ok)throw $({session:l.session,leaseBackend:h.leaseBackend,boundPlatform:y.boundPlatform,requestedPlatform:y.requestedPlatform,detail:`bound-connection`});h={...h,platform:y.platform},u.platform=y.platform;let b=await Ie({command:n,flags:u,client:i,state:l,nextState:h,runtime:p,positionals:t.positionals,batchSteps:t.batchSteps,forceRuntimePrepare:t.forceRuntimePrepare});return h=b.state,p=b.runtime,g||=b.changed,await ze({changed:g,stateDir:a,state:h,client:i,acquiredLeaseForCleanup:_,preparedMetroCleanupOnFailure:b.preparedMetroCleanupOnFailure,metroCleanupToStop:b.metroCleanupToStop}),{flags:{...u,session:h.session,leaseId:h.leaseId,leaseBackend:h.leaseBackend,platform:h.platform??u.platform,target:h.target??u.target},runtime:p,connection:F(h)}}async function Ie(t){let{command:n,flags:r,state:i,client:a}=t,o=Le(t.nextState,r),s=t.runtime;if(!ot(n,r,t.batchSteps,t.positionals)||!Z(r)||!Re(t.forceRuntimePrepare,s,r.platform))return{state:o,runtime:s,changed:!1};if(!o.leaseId)throw new e(`INVALID_ARGS`,`${n} requires a resolved remote lease before Metro runtime can be prepared.`);let c=await Ye(r,a,i.remoteConfigPath,i.session,{tenantId:i.tenant,runId:i.runId,leaseId:o.leaseId}),l=!st(o.metro,c.cleanup);return o={...o,runtime:c.runtime,metro:c.cleanup,updatedAt:new Date().toISOString()},{state:o,runtime:c.runtime,changed:!0,metroCleanupToStop:l?t.nextState.metro:void 0,preparedMetroCleanupOnFailure:l?c.cleanup:void 0}}function Le(e,t){return e.leaseId||!t.leaseId?e:{...e,leaseId:t.leaseId,leaseBackend:t.leaseBackend}}function Re(e,t,n){return e===!0||!t||!Q(t,n)}async function ze(e){if(e.changed)try{M({stateDir:e.stateDir,state:e.state})}catch(t){throw await Y(e.preparedMetroCleanupOnFailure),await it(e.client,e.state,e.acquiredLeaseForCleanup),t}await Y(e.metroCleanupToStop)}async function Be(e){let{command:t,client:n,state:r,nextFlags:i,policy:a}=e,o=r.leaseBackend??X(i),s=e.nextState,c=await a.resolveLeaseState({command:t,client:n,state:s,flags:i,leaseBackend:o});s=c.state,c.device&&ft(i,c.device);let l=s.leaseBackend??o??at(i,t);mt(r,l);let u=A({leaseBackend:l,recordedPlatform:s.platform,requestedPlatform:i.platform});if(!u.ok)throw $({session:r.session,leaseBackend:l,boundPlatform:u.boundPlatform,requestedPlatform:u.requestedPlatform,detail:`bound-connection`});ht(r,i),s={...s,platform:u.platform},i.platform=u.platform;let d=await ut(n,s,l,a,i,e.initialApp),f=d.lease;return i.leaseId=f.leaseId,i.leaseBackend=l,i.target=s.target??i.target,Ve(s,f,l)?{state:s,changed:!1,acquiredLeaseForCleanup:d.acquired?f:void 0}:{state:He(s,f,l,i),changed:!0,acquiredLeaseForCleanup:d.acquired?f:void 0}}function Ve(e,t,n){return e.leaseId===t.leaseId&&e.leaseBackend===n&&e.deviceKey===(t.deviceKey??e.deviceKey)}function He(e,t,n,r){let i=I(t,e);return{...e,leaseId:t.leaseId,leaseBackend:n,...i,platform:e.platform??r.platform,target:e.target??r.target,updatedAt:new Date().toISOString()}}function Ue(e){if(e.leaseBackend===`macos-app`)return qe;let t=K(e.leaseProvider);return t.leaseKind===`proxy`?Ke:t.supportsDeferredAppSelection?We:t.usesCloudWebDriverLease?Je:Ge}const We={shouldAllocate:e=>e!==m.apps&&!J.has(e),ttlMs:()=>void 0,resolveLeaseState:async e=>({state:e.state})},Ge={shouldAllocate:e=>!J.has(e),ttlMs:()=>void 0,resolveLeaseState:async e=>({state:e.state})},Ke={shouldAllocate:e=>e!==`devices`&&!J.has(e),ttlMs:()=>3e5,resolveLeaseState:dt},qe={shouldAllocate:e=>e!==`devices`&&!J.has(e),ttlMs:()=>void 0,resolveLeaseState:async({state:t})=>{if(!t.leaseId||!t.deviceKey)throw new e(`INVALID_ARGS`,`A macos-app connection needs the leaseId and deviceKey the host allocated in its remote config.`);return{state:{...t,platform:`macos`}}}},Je={shouldAllocate:e=>!J.has(e),ttlMs:()=>6e5,resolveLeaseState:async e=>({state:e.state})};async function Ye(t,n,r,i,a){if(!t.metroProjectRoot&&!t.metroPublicBaseUrl&&!t.metroProxyBaseUrl)return{};if(t.platform!==`ios`&&t.platform!==`android`)throw new e(`INVALID_ARGS`,`Deferred Metro preparation requires platform "ios" or "android".`);if(!t.metroPublicBaseUrl&&!t.metroProxyBaseUrl)throw new e(`INVALID_ARGS`,`Deferred Metro preparation requires metroPublicBaseUrl or metroProxyBaseUrl when Metro settings are provided.`);let o=await n.metro.prepare({projectRoot:t.metroProjectRoot,kind:_(t.metroKind),publicBaseUrl:t.metroPublicBaseUrl,proxyBaseUrl:t.metroProxyBaseUrl,bearerToken:t.metroBearerToken,bridgeScope:a,launchUrl:t.launchUrl,companionProfileKey:r,companionConsumerKey:i,port:t.metroPreparePort,listenHost:t.metroListenHost,statusHost:t.metroStatusHost,startupTimeoutMs:t.metroStartupTimeoutMs,probeTimeoutMs:t.metroProbeTimeoutMs,reuseExisting:!t.metroNoReuseExisting&&void 0,installDependenciesIfNeeded:!t.metroNoInstallDeps&&void 0,runtimeFilePath:t.metroRuntimeFile});return{runtime:t.platform===`ios`?o.iosRuntime:o.androidRuntime,cleanup:t.metroProxyBaseUrl?{projectRoot:o.projectRoot,profileKey:r,consumerKey:i}:void 0}}async function Y(e){if(e)try{await re(e)}catch{}}async function Xe(e){try{await O({projectRoot:process.cwd(),stateDir:e.stateDir,profileKey:e.state.remoteConfigPath,consumerKey:e.state.session})}catch{}}function Ze(e){return e.leaseBackend===`macos-app`}async function Qe(e,t,n){return!t.leaseId||Ze(t)?{released:!1}:await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend,daemonBaseUrl:t.daemon?.baseUrl,daemonAuthToken:n,daemonTransport:t.daemon?.transport,daemonServerMode:t.daemon?.serverMode,...F(t)})}function $e(e){let t=et(e.previous,e.cwd,e.env);return t?{canAuthenticate:!0,daemonAuthToken:t}:e.previous.daemon?.baseUrl===e.nextDaemonBaseUrl?{canAuthenticate:!0,daemonAuthToken:e.ambientDaemonAuthToken}:{canAuthenticate:!1}}function et(e,t,n){try{let{profile:r}=ae({configPath:e.remoteConfigPath,cwd:t,env:n});return r.daemonAuthToken&&tt(e,r.daemonBaseUrl)?r.daemonAuthToken:void 0}catch{return}}function tt(e,t){let n=N({daemonBaseUrl:t})?.baseUrl;return n!==void 0&&n===e.daemon?.baseUrl}async function nt(e,t,n){if(!t.leaseId||Ze(t))return;let r=$e({previous:t,nextDaemonBaseUrl:n.nextDaemonBaseUrl,ambientDaemonAuthToken:n.ambientDaemonAuthToken,cwd:n.cwd,env:n.env});if(!r.canAuthenticate)return rt(t,`no credential known to belong to that endpoint was available`);try{await Qe(e,t,r.daemonAuthToken);return}catch{return rt(t,`the release request failed`)}}function rt(e,t){return{status:`unreleased`,message:`Could not release the previous lease ${e.leaseId} (tenant ${e.tenant}, run ${e.runId}) at ${e.daemon?.baseUrl??`its daemon`}: ${t}. It was left in place — release it manually if it is still active.`}}async function it(e,t,n){if(n)try{let r=I(t,n);await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:n.leaseId,leaseBackend:t.leaseBackend??n.backend,...r})}catch{}}function X(e){return e.leaseBackend??t(e.platform)}function at(t,n){let r=X(t);if(r)return r;throw new e(`INVALID_ARGS`,`${n} requires --platform ios|android|harmonyos or --lease-backend when the remote connection has not resolved a lease yet.`)}function ot(e,t,n,r=[]){return e===`cdp`?ue(r)&&!!t.metroPublicBaseUrl:Ne.has(e)?!0:e!==`batch`||!n?!1:n.some(e=>{let t=e.command.trim().toLowerCase();return Ne.has(t)&&e.runtime===void 0})}function Z(e){let t=e.metroKind;return!!(e.metroPublicBaseUrl||e.metroProxyBaseUrl||e.metroProjectRoot||t)}function Q(e,t){return!e.platform||!t||!n(t)||e.platform===t}function st(e,t){return e?.projectRoot===t?.projectRoot&&e?.profileKey===t?.profileKey&&e?.consumerKey===t?.consumerKey}function ct(e,t){if(e)return Q(e,t)?e:void 0}function lt(t,n,r={}){if(!t.tenant)throw new e(`INVALID_ARGS`,`remote command requires tenant in remote config or via --tenant <id>.`);if(!t.runId)throw new e(`INVALID_ARGS`,`remote command requires runId in remote config or via --run-id <id>.`);if(!t.daemonBaseUrl&&K(r.leaseProvider).requiresRemoteDaemon)throw new e(`INVALID_ARGS`,`remote command requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.`);let i=new Date().toISOString();return{version:1,session:t.session??`default`,remoteConfigPath:n,remoteConfigHash:L(n),daemon:N(t),tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend??X(t),leaseProvider:r.leaseProvider,clientId:r.clientId,deviceKey:r.deviceKey,platform:t.platform,target:t.target,connectedAt:i,updatedAt:i}}async function ut(t,n,r,i,a,o){let s=F(n);if(n.leaseId&&n.leaseBackend===r){let e=await gt(t,n.leaseId,{tenant:n.tenant,runId:n.runId,leaseBackend:r,...s,ttlMs:i.ttlMs(n)});if(e)return{lease:e,acquired:!1}}if(r===`macos-app`)throw new e(`UNAUTHORIZED`,`The host-allocated macos-app lease is no longer active.`,{reason:`LEASE_NOT_FOUND`,leaseId:n.leaseId,hint:`Ask the host for a new macos-app lease and update the remote config.`});return{lease:await t.leases.allocate({tenant:n.tenant,runId:n.runId,leaseBackend:r,...s,ttlMs:i.ttlMs(n),platform:n.platform??a.platform,target:n.target??a.target,device:a.device,udid:a.udid,serial:a.serial,providerApp:o??a.providerApp,providerOsVersion:a.providerOsVersion,providerProject:a.providerProject,providerBuild:a.providerBuild,providerSessionName:a.providerSessionName,...q(a),awsProjectArn:a.awsProjectArn,awsDeviceArn:a.awsDeviceArn,awsAppArn:a.awsAppArn,awsRegion:a.awsRegion,awsInteractionMode:a.awsInteractionMode}),acquired:!0}}async function dt(t){if(!Pe.has(t.command)){if(t.state.leaseId&&t.state.deviceKey)return{state:t.state};throw new e(`INVALID_ARGS`,`No active proxy device lease for this session; run open first.`)}let n=await pt(t.client,t.flags),r=k(n);return{state:{...t.state,deviceKey:he(r),leaseBackend:t.state.leaseBackend??t.leaseBackend??r.leaseBackend,platform:r.platform,target:t.state.target??r.target,updatedAt:new Date().toISOString()},device:n}}function ft(e,t){let n=k(t);e.platform=n.platform,e.target=n.target??e.target,n.identityFlag===`udid`&&(e.udid=n.id),n.identityFlag===`serial`&&(e.serial=n.id)}async function pt(e,t){let n=await e.devices.list({platform:t.platform,target:t.target,device:t.device,udid:t.udid,serial:t.serial,iosSimulatorDeviceSet:t.iosSimulatorDeviceSet,androidDeviceAllowlist:t.androidDeviceAllowlist});return await o(n.map(e=>({...s(e.platform),id:e.id,name:e.name,kind:e.kind,target:e.target,booted:e.booted})),{platform:t.platform,target:t.target,deviceName:t.device,udid:t.udid,serial:t.serial})}function $(t){return new e(`INVALID_ARGS`,t.detail===`bound-connection`?`Active remote connection is already bound to a different platform. Re-run connect --force to replace it.`:`The requested platform does not match the device this lease backend rents.`,{session:t.session,leaseBackend:t.leaseBackend,platform:t.boundPlatform,requestedPlatform:t.requestedPlatform,reason:`CONNECTION_PLATFORM_CONFLICT`})}function mt(t,n){if(t.leaseBackend&&t.leaseBackend!==n)throw new e(`INVALID_ARGS`,`Active remote connection is already bound to a different lease backend. Re-run connect --force to replace it.`,{session:t.session,leaseBackend:t.leaseBackend})}function ht(t,n){if(t.target&&n.target&&t.target!==n.target)throw new e(`INVALID_ARGS`,`Active remote connection is already bound to a different target. Re-run connect --force to replace it.`,{session:t.session,target:t.target})}async function gt(e,t,n){try{return await e.leases.heartbeat({...n,leaseId:t})}catch(e){if(p(e))return;throw e}}export{se as A,B as C,_e as D,P as E,O as M,M as O,A as S,ve as T,F as _,Qe as a,L as b,Xe as c,je as d,K as f,N as g,ke as h,nt as i,oe as j,me as k,q as l,W as m,Z as n,X as o,Ae as p,Fe as r,Y as s,$ as t,Me as u,ge as v,j as w,I as x,ye as y};
|
|
1
|
+
import{P as e,d as t,l as n}from"./sdk-contracts.js";import{u as r}from"./registry.js";import{k as i,o as a}from"./sdk-device.js";import{r as o}from"./lease-scope.js";import{n as s,t as c}from"./catalog.js";import{t as l}from"./daemon-resolution.js";import{n as u}from"./metro2.js";import{r as d,t as f}from"./remote-config-core.js";import"./remote-config2.js";import{c as p,g as m,h,n as g,o as _,p as v,r as y,s as b,t as x,u as S,y as C}from"./remote-connection-state.js";import{a as w,n as T}from"./provider-policy.js";function E(e){return{providerDeviceOrientation:e.providerDeviceOrientation,providerGeoLocation:e.providerGeoLocation,providerTimezone:e.providerTimezone,providerAppiumVersion:e.providerAppiumVersion,providerLanguage:e.providerLanguage,providerLocale:e.providerLocale,providerNetworkProfile:e.providerNetworkProfile,providerCustomNetwork:e.providerCustomNetwork,providerNoResignApp:e.providerNoResignApp}}function D(e){return{metroProjectRoot:e.metroProjectRoot,metroKind:e.metroKind,metroPublicBaseUrl:e.metroPublicBaseUrl,metroProxyBaseUrl:e.metroProxyBaseUrl,metroPreparePort:e.metroPreparePort,metroListenHost:e.metroListenHost,metroStatusHost:e.metroStatusHost,metroStartupTimeoutMs:e.metroStartupTimeoutMs,metroProbeTimeoutMs:e.metroProbeTimeoutMs,metroRuntimeFile:e.metroRuntimeFile,metroNoReuseExisting:e.metroNoReuseExisting,metroNoInstallDeps:e.metroNoInstallDeps,launchUrl:e.launchUrl}}const O=new Set([`artifacts`,`connect`,`connection`,`close`,`disconnect`,`metro`,`session`]),k=new Set([`open`]),A=new Set([s.open,s.install,s.reinstall,c.installSource]);async function j(t){let{command:n,flags:r,client:i}=t;if(!r.remoteConfig)return{flags:r,runtime:t.runtime};let a=l(r.stateDir).baseDir,o=d({configPath:r.remoteConfig,cwd:process.cwd(),env:process.env}),c={...m(o.profile),...r,remoteConfig:o.resolvedPath},u=S({stateDir:a,session:c.session??`default`});if(u&&u.remoteConfigPath!==o.resolvedPath)throw new e(`INVALID_ARGS`,`A different remote connection is already active for this session. Run connect --force or disconnect before using a different --remote-config.`,{session:u.session,activeRemoteConfig:u.remoteConfigPath,requestedRemoteConfig:o.resolvedPath});let f=u??de(c,o.resolvedPath,o.profile),h={...c,session:f.session},g=T(f.leaseProvider).supportsDeferredAppSelection,_=g&&n===s.open?t.positionals?.[0]:void 0;g&&delete h.providerApp;let v=ue(f.runtime,h.platform)??t.runtime,b=f,x=!u,C,w=P(b);if(w.shouldAllocate(n)){let e=await ie({command:n,client:i,state:f,nextState:b,nextFlags:h,initialApp:_,policy:w});b=e.state,x||=e.changed,C=e.acquiredLeaseForCleanup}let E=p({leaseBackend:b.leaseBackend,recordedPlatform:b.platform,requestedPlatform:h.platform});if(!E.ok)throw $({session:f.session,leaseBackend:b.leaseBackend,boundPlatform:E.boundPlatform,requestedPlatform:E.requestedPlatform,detail:`bound-connection`});b={...b,platform:E.platform},h.platform=E.platform;let D=await ee({command:n,flags:h,client:i,state:f,nextState:b,runtime:v,positionals:t.positionals,batchSteps:t.batchSteps,forceRuntimePrepare:t.forceRuntimePrepare});return b=D.state,v=D.runtime,x||=D.changed,await re({changed:x,stateDir:a,state:b,client:i,acquiredLeaseForCleanup:C,preparedMetroCleanupOnFailure:D.preparedMetroCleanupOnFailure,metroCleanupToStop:D.metroCleanupToStop}),{flags:{...h,session:b.session,leaseId:b.leaseId,leaseBackend:b.leaseBackend,platform:b.platform??h.platform,target:b.target??h.target},runtime:v,connection:y(b)}}async function ee(t){let{command:n,flags:r,state:i,client:a}=t,o=te(t.nextState,r),s=t.runtime;if(!ce(n,r,t.batchSteps,t.positionals)||!X(r)||!ne(t.forceRuntimePrepare,s,r.platform))return{state:o,runtime:s,changed:!1};if(!o.leaseId)throw new e(`INVALID_ARGS`,`${n} requires a resolved remote lease before Metro runtime can be prepared.`);let c=await B(r,a,i.remoteConfigPath,i.session,{tenantId:i.tenant,runId:i.runId,leaseId:o.leaseId}),l=!le(o.metro,c.cleanup);return o={...o,runtime:c.runtime,metro:c.cleanup,updatedAt:new Date().toISOString()},{state:o,runtime:c.runtime,changed:!0,metroCleanupToStop:l?t.nextState.metro:void 0,preparedMetroCleanupOnFailure:l?c.cleanup:void 0}}function te(e,t){return e.leaseId||!t.leaseId?e:{...e,leaseId:t.leaseId,leaseBackend:t.leaseBackend}}function ne(e,t,n){return e===!0||!t||!Z(t,n)}async function re(e){if(e.changed)try{h({stateDir:e.stateDir,state:e.state})}catch(t){throw await V(e.preparedMetroCleanupOnFailure),await oe(e.client,e.state,e.acquiredLeaseForCleanup),t}await V(e.metroCleanupToStop)}async function ie(e){let{command:t,client:n,state:r,nextFlags:i,policy:a}=e,o=r.leaseBackend??Y(i),s=e.nextState,c=await a.resolveLeaseState({command:t,client:n,state:s,flags:i,leaseBackend:o});s=c.state,c.device&&me(i,c.device);let l=s.leaseBackend??o??se(i,t);he(r,l);let u=p({leaseBackend:l,recordedPlatform:s.platform,requestedPlatform:i.platform});if(!u.ok)throw $({session:r.session,leaseBackend:l,boundPlatform:u.boundPlatform,requestedPlatform:u.requestedPlatform,detail:`bound-connection`});ge(r,i),s={...s,platform:u.platform},i.platform=u.platform;let d=await fe(n,s,l,a,i,e.initialApp),f=d.lease;return i.leaseId=f.leaseId,i.leaseBackend=l,i.target=s.target??i.target,M(s,f,l)?{state:s,changed:!1,acquiredLeaseForCleanup:d.acquired?f:void 0}:{state:N(s,f,l,i),changed:!0,acquiredLeaseForCleanup:d.acquired?f:void 0}}function M(e,t,n){return e.leaseId===t.leaseId&&e.leaseBackend===n&&e.deviceKey===(t.deviceKey??e.deviceKey)}function N(e,t,n,r){let i=b(t,e);return{...e,leaseId:t.leaseId,leaseBackend:n,...i,platform:e.platform??r.platform,target:e.target??r.target,updatedAt:new Date().toISOString()}}function P(e){if(e.leaseBackend===`macos-app`)return R;let t=T(e.leaseProvider);return t.leaseKind===`proxy`?L:t.supportsDeferredAppSelection?F:t.usesCloudWebDriverLease?z:I}const F={shouldAllocate:e=>e!==s.apps&&!O.has(e),ttlMs:()=>void 0,resolveLeaseState:async e=>({state:e.state})},I={shouldAllocate:e=>!O.has(e),ttlMs:()=>void 0,resolveLeaseState:async e=>({state:e.state})},L={shouldAllocate:e=>e!==`devices`&&!O.has(e),ttlMs:()=>3e5,resolveLeaseState:pe},R={shouldAllocate:e=>e!==`devices`&&!O.has(e),ttlMs:()=>void 0,resolveLeaseState:async({state:t})=>{if(!t.leaseId||!t.deviceKey)throw new e(`INVALID_ARGS`,`A macos-app connection needs the leaseId and deviceKey the host allocated in its remote config.`);return{state:{...t,platform:`macos`}}}},z={shouldAllocate:e=>!O.has(e),ttlMs:()=>6e5,resolveLeaseState:async e=>({state:e.state})};async function B(t,n,i,a,o){if(!t.metroProjectRoot&&!t.metroPublicBaseUrl&&!t.metroProxyBaseUrl)return{};if(t.platform!==`ios`&&t.platform!==`android`)throw new e(`INVALID_ARGS`,`Deferred Metro preparation requires platform "ios" or "android".`);if(!t.metroPublicBaseUrl&&!t.metroProxyBaseUrl)throw new e(`INVALID_ARGS`,`Deferred Metro preparation requires metroPublicBaseUrl or metroProxyBaseUrl when Metro settings are provided.`);let s=await n.metro.prepare({projectRoot:t.metroProjectRoot,kind:r(t.metroKind),publicBaseUrl:t.metroPublicBaseUrl,proxyBaseUrl:t.metroProxyBaseUrl,bearerToken:t.metroBearerToken,bridgeScope:o,launchUrl:t.launchUrl,companionProfileKey:i,companionConsumerKey:a,port:t.metroPreparePort,listenHost:t.metroListenHost,statusHost:t.metroStatusHost,startupTimeoutMs:t.metroStartupTimeoutMs,probeTimeoutMs:t.metroProbeTimeoutMs,reuseExisting:!t.metroNoReuseExisting&&void 0,installDependenciesIfNeeded:!t.metroNoInstallDeps&&void 0,runtimeFilePath:t.metroRuntimeFile});return{runtime:t.platform===`ios`?s.iosRuntime:s.androidRuntime,cleanup:t.metroProxyBaseUrl?{projectRoot:s.projectRoot,profileKey:i,consumerKey:a}:void 0}}async function V(e){if(e)try{await u(e)}catch{}}async function H(e){try{await w({projectRoot:process.cwd(),stateDir:e.stateDir,profileKey:e.state.remoteConfigPath,consumerKey:e.state.session})}catch{}}function U(e){return e.leaseBackend===`macos-app`}async function W(e,t,n){return!t.leaseId||U(t)?{released:!1}:await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend,daemonBaseUrl:t.daemon?.baseUrl,daemonAuthToken:n,daemonTransport:t.daemon?.transport,daemonServerMode:t.daemon?.serverMode,...y(t)})}function G(e){let t=K(e.previous,e.cwd,e.env);return t?{canAuthenticate:!0,daemonAuthToken:t}:e.previous.daemon?.baseUrl===e.nextDaemonBaseUrl?{canAuthenticate:!0,daemonAuthToken:e.ambientDaemonAuthToken}:{canAuthenticate:!1}}function K(e,t,n){try{let{profile:r}=f({configPath:e.remoteConfigPath,cwd:t,env:n});return r.daemonAuthToken&&q(e,r.daemonBaseUrl)?r.daemonAuthToken:void 0}catch{return}}function q(e,t){let n=g({daemonBaseUrl:t})?.baseUrl;return n!==void 0&&n===e.daemon?.baseUrl}async function ae(e,t,n){if(!t.leaseId||U(t))return;let r=G({previous:t,nextDaemonBaseUrl:n.nextDaemonBaseUrl,ambientDaemonAuthToken:n.ambientDaemonAuthToken,cwd:n.cwd,env:n.env});if(!r.canAuthenticate)return J(t,`no credential known to belong to that endpoint was available`);try{await W(e,t,r.daemonAuthToken);return}catch{return J(t,`the release request failed`)}}function J(e,t){return{status:`unreleased`,message:`Could not release the previous lease ${e.leaseId} (tenant ${e.tenant}, run ${e.runId}) at ${e.daemon?.baseUrl??`its daemon`}: ${t}. It was left in place — release it manually if it is still active.`}}async function oe(e,t,n){if(n)try{let r=b(t,n);await e.leases.release({tenant:t.tenant,runId:t.runId,leaseId:n.leaseId,leaseBackend:t.leaseBackend??n.backend,...r})}catch{}}function Y(e){return e.leaseBackend??t(e.platform)}function se(t,n){let r=Y(t);if(r)return r;throw new e(`INVALID_ARGS`,`${n} requires --platform ios|android|harmonyos or --lease-backend when the remote connection has not resolved a lease yet.`)}function ce(e,t,n,r=[]){return e===`cdp`?C(r)&&!!t.metroPublicBaseUrl:k.has(e)?!0:e!==`batch`||!n?!1:n.some(e=>{let t=e.command.trim().toLowerCase();return k.has(t)&&e.runtime===void 0})}function X(e){let t=e.metroKind;return!!(e.metroPublicBaseUrl||e.metroProxyBaseUrl||e.metroProjectRoot||t)}function Z(e,t){return!e.platform||!t||!n(t)||e.platform===t}function le(e,t){return e?.projectRoot===t?.projectRoot&&e?.profileKey===t?.profileKey&&e?.consumerKey===t?.consumerKey}function ue(e,t){if(e)return Z(e,t)?e:void 0}function de(t,n,r={}){if(!t.tenant)throw new e(`INVALID_ARGS`,`remote command requires tenant in remote config or via --tenant <id>.`);if(!t.runId)throw new e(`INVALID_ARGS`,`remote command requires runId in remote config or via --run-id <id>.`);if(!t.daemonBaseUrl&&T(r.leaseProvider).requiresRemoteDaemon)throw new e(`INVALID_ARGS`,`remote command requires daemonBaseUrl in remote config, config, env, or --daemon-base-url.`);let i=new Date().toISOString();return{version:1,session:t.session??`default`,remoteConfigPath:n,remoteConfigHash:_(n),daemon:g(t),tenant:t.tenant,runId:t.runId,leaseId:t.leaseId,leaseBackend:t.leaseBackend??Y(t),leaseProvider:r.leaseProvider,clientId:r.clientId,deviceKey:r.deviceKey,platform:t.platform,target:t.target,connectedAt:i,updatedAt:i}}async function fe(t,n,r,i,a,o){let s=y(n);if(n.leaseId&&n.leaseBackend===r){let e=await _e(t,n.leaseId,{tenant:n.tenant,runId:n.runId,leaseBackend:r,...s,ttlMs:i.ttlMs(n)});if(e)return{lease:e,acquired:!1}}if(r===`macos-app`)throw new e(`UNAUTHORIZED`,`The host-allocated macos-app lease is no longer active.`,{reason:`LEASE_NOT_FOUND`,leaseId:n.leaseId,hint:`Ask the host for a new macos-app lease and update the remote config.`});return{lease:await t.leases.allocate({tenant:n.tenant,runId:n.runId,leaseBackend:r,...s,ttlMs:i.ttlMs(n),platform:n.platform??a.platform,target:n.target??a.target,device:a.device,udid:a.udid,serial:a.serial,providerApp:o??a.providerApp,providerOsVersion:a.providerOsVersion,providerDeviceType:a.providerDeviceType,providerProject:a.providerProject,providerBuild:a.providerBuild,providerSessionName:a.providerSessionName,...E(a),awsProjectArn:a.awsProjectArn,awsDeviceArn:a.awsDeviceArn,awsAppArn:a.awsAppArn,awsRegion:a.awsRegion,awsInteractionMode:a.awsInteractionMode}),acquired:!0}}async function pe(t){if(!A.has(t.command)){if(t.state.leaseId&&t.state.deviceKey)return{state:t.state};throw new e(`INVALID_ARGS`,`No active proxy device lease for this session; run open first.`)}let n=await Q(t.client,t.flags),r=v(n);return{state:{...t.state,deviceKey:x(r),leaseBackend:t.state.leaseBackend??t.leaseBackend??r.leaseBackend,platform:r.platform,target:t.state.target??r.target,updatedAt:new Date().toISOString()},device:n}}function me(e,t){let n=v(t);e.platform=n.platform,e.target=n.target??e.target,n.identityFlag===`udid`&&(e.udid=n.id),n.identityFlag===`serial`&&(e.serial=n.id)}async function Q(e,t){let n=await e.devices.list({platform:t.platform,target:t.target,device:t.device,udid:t.udid,serial:t.serial,iosSimulatorDeviceSet:t.iosSimulatorDeviceSet,androidDeviceAllowlist:t.androidDeviceAllowlist});return await i(n.map(e=>({...a(e.platform),id:e.id,name:e.name,kind:e.kind,target:e.target,booted:e.booted})),{platform:t.platform,target:t.target,deviceName:t.device,udid:t.udid,serial:t.serial})}function $(t){return new e(`INVALID_ARGS`,t.detail===`bound-connection`?`Active remote connection is already bound to a different platform. Re-run connect --force to replace it.`:`The requested platform does not match the device this lease backend rents.`,{session:t.session,leaseBackend:t.leaseBackend,platform:t.boundPlatform,requestedPlatform:t.requestedPlatform,reason:`CONNECTION_PLATFORM_CONFLICT`})}function he(t,n){if(t.leaseBackend&&t.leaseBackend!==n)throw new e(`INVALID_ARGS`,`Active remote connection is already bound to a different lease backend. Re-run connect --force to replace it.`,{session:t.session,leaseBackend:t.leaseBackend})}function ge(t,n){if(t.target&&n.target&&t.target!==n.target)throw new e(`INVALID_ARGS`,`Active remote connection is already bound to a different target. Re-run connect --force to replace it.`,{session:t.session,target:t.target})}async function _e(e,t,n){try{return await e.leases.heartbeat({...n,leaseId:t})}catch(e){if(o(e))return;throw e}}export{$ as connectionPlatformConflict,X as hasDeferredMetroConfig,j as materializeRemoteConnectionForCommand,ae as releasePreviousLease,W as releaseRemoteConnectionLease,Y as resolveRequestedLeaseBackend,V as stopMetroCleanup,H as stopReactDevtoolsCleanup,D as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{P as e}from"./sdk-contracts.js";import{b as t,s as n}from"./runtime2.js";import{c as r,m as i}from"./browserstack.js";import{a}from"./providers.js";import o from"node:path";async function s(n,r){let i=c(n.app),a={username:n.username,accessKey:n.accessKey},o=d(await u(n.devicesEndpoint??`https://api-cloud.browserstack.com/app-automate/devices.json`,a,r)).find(e=>e.device===n.deviceName&&e.os.toLowerCase()===n.platform&&t(e.osVersion,n.osVersion));if(!o)throw new e(`INVALID_ARGS`,`BrowserStack device "${n.deviceName}" with ${n.platform} ${n.osVersion} is not available.`,{hint:`Choose an exact device and OS version from the BrowserStack App Automate device list.`});let s=await l(i,n,a,r);return{provider:`browserstack`,service:`BrowserStack`,verificationMessage:s.status===`verified`?`Credentials, device, and uploaded app verified.`:`Credentials and device access verified; app availability is checked when the session is created.`,device:{status:`verified`,name:o.device,platform:n.platform,osVersion:o.osVersion},app:s}}function c(e){return r(e)??e}async function l(e,t,n,r){if(a(e)){let i=f(await u(t.appsEndpoint??`https://api-cloud.browserstack.com/app-automate/recent_apps?limit=100`,n,r)).find(t=>t.reference===e);return i?{status:`verified`,...i}:{status:`configured`,reference:e,message:`App reference was not found in the 100 most recent uploads; BrowserStack validates it when creating the session.`}}return/^https?:\/\//i.test(e)?{status:`configured`,reference:e,message:`Public app URL configured; BrowserStack validates it when creating the session.`}:{status:`configured`,name:o.basename(e),reference:e,message:`Local app artifact is ready and will be uploaded when creating the session.`}}async function u(e,t,r){return await n(e,{clientVersion:r,auth:t,hints:{service:`BrowserStack`,unauthorizedHint:`Check BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY.`,networkHint:`Check network access to api-cloud.browserstack.com and retry connect.`}})}function d(t){if(!Array.isArray(t))throw new e(`COMMAND_FAILED`,`BrowserStack device verification response was not a list.`);return t.flatMap(e=>{let t=p(e),n=t?.os_version;return t&&typeof t.device==`string`&&typeof t.os==`string`&&(typeof n==`string`||typeof n==`number`)?[{device:t.device,os:t.os,osVersion:String(n)}]:[]})}function f(t){let n=p(t);if(n&&Object.keys(n).length===0)return[];if(!Array.isArray(t))throw new e(`COMMAND_FAILED`,`BrowserStack app verification response was not a list.`);return t.flatMap(e=>{let t=p(e);return!t||typeof t.app_url!=`string`?[]:[{reference:t.app_url,...typeof t.app_name==`string`?{name:t.app_name}:{},...typeof t.app_version==`string`?{version:t.app_version}:{}}]})}function p(e){return e&&typeof e==`object`&&!Array.isArray(e)?e:void 0}async function m(t,n){let r=i({runHostCommand:n,region:t.region}),[a,o,s]=await Promise.all([r(`get-project`,[`--arn`,t.projectArn]),r(`get-device`,[`--arn`,t.deviceArn]),t.appArn?r(`get-upload`,[`--arn`,t.appArn]):void 0]),c=g(a,`project`),l=g(o,`device`),u=_(l.platform);if(u!==t.platform)throw new e(`INVALID_ARGS`,`AWS Device Farm device "${v(l.name)??t.deviceArn}" is ${u}, not ${t.platform}.`);let d=t.appArn?h(g(s,`upload`),t):{status:`missing`,message:`No app upload is attached; AWS Device Farm does not support install after allocation. Reconnect with --aws-app-arn <arn>.`};return{provider:`aws-device-farm`,service:`AWS Device Farm`,verificationMessage:t.appArn?`Credentials, project, device, and app upload verified.`:`Credentials, project, and device verified.`,project:{name:v(c.name),reference:t.projectArn},device:{status:`verified`,name:v(l.name)??t.deviceArn,reference:t.deviceArn,platform:u,osVersion:v(l.os),availability:v(l.availability)},app:d}}function h(t,n){let r=v(t.status);if(r!==`SUCCEEDED`)throw new e(`COMMAND_FAILED`,`AWS Device Farm app upload is not ready (${r??`unknown status`}).`,{status:r,hint:`Wait for the upload to succeed or reconnect with a different --aws-app-arn.`});let i=n.platform===`android`?`ANDROID_APP`:`IOS_APP`,a=v(t.type);if(a!==i)throw new e(`INVALID_ARGS`,`AWS Device Farm app upload type is ${a??`unknown`}, expected ${i}.`);return{status:`verified`,name:v(t.name),reference:n.appArn}}function g(t,n){if(!t||typeof t!=`object`)throw new e(`COMMAND_FAILED`,`AWS Device Farm ${n} response was not an object.`);let r=t[n];if(!r||typeof r!=`object`||Array.isArray(r))throw new e(`COMMAND_FAILED`,`AWS Device Farm response missed ${n}.`);return r}function _(t){if(t===`ANDROID`)return`android`;if(t===`IOS`)return`ios`;throw new e(`UNSUPPORTED_PLATFORM`,`AWS Device Farm device platform is ${String(t)}.`)}function v(e){return typeof e==`string`&&e.length>0?e:void 0}export{s as n,m as t};
|