import { Readable, Writable } from "node:stream"; import { StdioOptions, spawn } from "node:child_process"; //#region src/utils/exec.d.ts type ExecResult = { stdout: string; stderr: string; exitCode: number; stdoutBuffer?: Buffer; }; type ExecOptions = { cwd?: string; env?: NodeJS.ProcessEnv; allowFailure?: boolean; binaryStdout?: boolean; stdin?: string | Buffer; timeoutMs?: number; detached?: boolean; signal?: AbortSignal; /** Max stdout/stderr bytes for synchronous runs (default Node ~1MB). */ maxBuffer?: number; }; type ExecBackgroundOptions = ExecOptions & { /** * Capture stdout/stderr into the wait result when the child has piped stdio. * Set false when the caller owns, ignores, or forwards the streams. */ captureOutput?: boolean; stdio?: StdioOptions; }; //#endregion //#region src/platforms/android/adb-executor.d.ts type AndroidAdbExecutorOptions = Pick; type AndroidAdbExecutorResult = Pick; type AndroidAdbProcess = { pid?: number; stdin: Writable | null; stdout: Readable | null; stderr: Readable | null; killed: boolean; kill(signal?: NodeJS.Signals | number): boolean; once(event: 'exit' | 'close', listener: (code: number | null, signal: NodeJS.Signals | null) => void): unknown; on(event: 'error', listener: (error: Error) => void): unknown; on(event: 'exit' | 'close', listener: (code: number | null, signal: NodeJS.Signals | null) => void): unknown; }; /** * Runs device-scoped adb arguments after the device serial has already been selected. * Implementations must be safe to call concurrently for one request. */ type AndroidAdbExecutor = (args: string[], options?: AndroidAdbExecutorOptions) => Promise; type AndroidAdbSpawner = (args: string[], options?: ExecBackgroundOptions) => AndroidAdbProcess; type AndroidPortReverseEndpoint = `tcp:${number}` | `localabstract:${string}`; type AndroidPortReverseMapping = { local: AndroidPortReverseEndpoint; remote: AndroidPortReverseEndpoint; ownerId?: string; }; type AndroidPortReverseOptions = { signal?: AbortSignal; timeoutMs?: number; }; type AndroidPortReverseProvider = { ensure(mapping: AndroidPortReverseMapping, options?: AndroidPortReverseOptions): Promise; remove(local: AndroidPortReverseEndpoint, options?: AndroidPortReverseOptions): Promise; removeAllOwned(ownerId: string, options?: AndroidPortReverseOptions): Promise; list?(options?: AndroidPortReverseOptions): Promise; }; type AndroidAdbTransferOptions = AndroidAdbExecutorOptions; type AndroidAdbInstallOptions = AndroidAdbTransferOptions & { replace?: boolean; allowTestPackages?: boolean; allowDowngrade?: boolean; grantPermissions?: boolean; }; type AndroidAdbPuller = (remotePath: string, localPath: string, options?: AndroidAdbTransferOptions) => Promise; /** * Installs an APK path. Implementations are responsible for honoring semantic * install options such as replace/test/downgrade/grant-permissions. */ type AndroidAdbInstaller = (apkPath: string, options?: AndroidAdbInstallOptions) => Promise; type AndroidBundleInstaller = (bundlePath: string, options: { mode: string; }) => Promise; type AndroidTextInputAction = 'type' | 'fill'; type AndroidTextInjectionRequest = { action: AndroidTextInputAction; text: string; delayMs?: number; /** * Present only for fill. Providers must make this target the focused/replaced * input for the request, not inject into an unrelated currently focused field. */ target?: { x: number; y: number; }; }; type AndroidTextInjector = (request: AndroidTextInjectionRequest) => Promise; type AndroidTouchGestureRequest = { kind: 'swipe'; x1: number; y1: number; x2: number; y2: number; durationMs?: number; } | { kind: 'pinch'; x: number; y: number; scale: number; durationMs?: number; } | { kind: 'rotate'; x: number; y: number; degrees: number; durationMs?: number; } | { kind: 'transform'; x: number; y: number; dx: number; dy: number; scale: number; degrees: number; durationMs?: number; }; type AndroidTouchInjector = (request: AndroidTouchGestureRequest) => Promise | void>; type AndroidAdbProvider = { /** * Fallback executor for device-scoped adb arguments. Providers may omit explicit * methods to keep the legacy exec-shaped pull/install fallback. */ exec: AndroidAdbExecutor; spawn?: AndroidAdbSpawner; reverse?: AndroidPortReverseProvider; pull?: AndroidAdbPuller; install?: AndroidAdbInstaller; installBundle?: AndroidBundleInstaller; text?: AndroidTextInjector; touch?: AndroidTouchInjector; }; declare function createAndroidPortReverseManager(provider: AndroidAdbProvider | AndroidAdbExecutor): AndroidPortReverseProvider; //#endregion export { createAndroidPortReverseManager as i, AndroidAdbExecutorOptions as n, AndroidPortReverseEndpoint as r, AndroidAdbExecutor as t };