This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
Bun's bundler mis-compiles `import * as tmp from 'tmp'`.
|
||||
|
||||
tmp's entrypoint ends with `Object.defineProperty(module.exports, 'tmpdir', {...})`.
|
||||
When bun builds an ESM namespace object for that CJS module it emits a reference
|
||||
to `exports_tmp` without ever declaring the binding, so the compiled binary dies
|
||||
on startup with `ReferenceError: exports_tmp is not defined`.
|
||||
|
||||
Importing it as CJS instead keeps bun on its `__commonJS` path, which handles the
|
||||
`defineProperty` pattern correctly. Only the `tmp.file` value and the `Options`
|
||||
type are used here, so the switch is behaviour-preserving.
|
||||
|
||||
diff --git a/src/util/fs.ts b/src/util/fs.ts
|
||||
index 21c99ef..0d2224f 100644
|
||||
--- a/src/util/fs.ts
|
||||
+++ b/src/util/fs.ts
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
-import * as tmp from 'tmp';
|
||||
+import type { Options as TmpOptions } from 'tmp';
|
||||
+const tmp: typeof import('tmp') = require('tmp');
|
||||
import { lookpath } from 'lookpath';
|
||||
import { isErrorLike } from '@httptoolkit/util';
|
||||
|
||||
@@ -62,7 +63,7 @@ export const resolveCommandPath = (path: string): Promise<string | undefined> =>
|
||||
export const commandExists = (path: string): Promise<boolean> =>
|
||||
resolveCommandPath(path).then((result) => result !== undefined);
|
||||
|
||||
-export const createTmp = (options: tmp.Options = {}) => new Promise<{
|
||||
+export const createTmp = (options: TmpOptions = {}) => new Promise<{
|
||||
path: string,
|
||||
fd: number,
|
||||
cleanupCallback: () => void
|
||||
@@ -0,0 +1,33 @@
|
||||
Pin the CJS default-import interop for adbkit, which bun and tsc disagree on.
|
||||
|
||||
adbkit is a tsc-compiled CJS package: it sets `__esModule` and puts its real
|
||||
default export at `exports.default`. Upstream builds with tsc + esModuleInterop,
|
||||
where `import adb from '@devicefarmer/adbkit'` therefore resolves to
|
||||
`exports.default` - the Adb class.
|
||||
|
||||
Bun instead applies native ESM/Node semantics, where the default of a CJS module
|
||||
is `module.exports` *itself*. It emits `__toESM(require(...), 1)` and, because
|
||||
that `isNodeMode` flag is set, unconditionally does `default = mod` regardless of
|
||||
`__esModule`. So `adb` ends up as the whole exports object and the Adb class is
|
||||
one level deeper, giving `Adb.default.createClient is not a function` at startup
|
||||
(AndroidAdbInterceptor is constructed eagerly by buildInterceptors, so this kills
|
||||
the whole server, not just Android interception).
|
||||
|
||||
Requiring the module explicitly and reaching for `.default` ourselves makes the
|
||||
interop unambiguous under either toolchain. `Adb` is only ever used in type
|
||||
positions here, so it becomes a type-only import.
|
||||
|
||||
diff --git a/src/interceptors/android/adb-commands.ts b/src/interceptors/android/adb-commands.ts
|
||||
index 26307ce..2f74c4d 100644
|
||||
--- a/src/interceptors/android/adb-commands.ts
|
||||
+++ b/src/interceptors/android/adb-commands.ts
|
||||
@@ -1,7 +1,8 @@
|
||||
import * as stream from 'stream';
|
||||
import * as path from 'path';
|
||||
|
||||
-import adb, * as Adb from '@devicefarmer/adbkit';
|
||||
+import type * as Adb from '@devicefarmer/adbkit';
|
||||
+const adb = (require('@devicefarmer/adbkit') as typeof import('@devicefarmer/adbkit')).default;
|
||||
import { delay, isErrorLike } from '@httptoolkit/util';
|
||||
|
||||
import { logError } from '../../error-tracking';
|
||||
@@ -0,0 +1,24 @@
|
||||
diff --git a/src/index.ts b/src/index.ts
|
||||
index a13dcab..f2f3942 100644
|
||||
--- a/src/index.ts
|
||||
+++ b/src/index.ts
|
||||
@@ -15,7 +15,18 @@ import {
|
||||
MockRTCAdminPlugin
|
||||
} from 'mockrtc';
|
||||
|
||||
-import updateCommand from '@oclif/plugin-update/lib/commands/update';
|
||||
+// Self-update is meaningless in a single self-contained binary: oclif's updater
|
||||
+// rewrites files inside an oclif install directory that doesn't exist here. Worse,
|
||||
+// importing it drags @oclif/plugin-update into the bundle, and that reads
|
||||
+// @oclif/command/package.json from disk when it loads - a path that only exists on
|
||||
+// the build machine, so the compiled binary dies at startup everywhere else.
|
||||
+// Back off for 6 hours like the EEXIT branch below, so the UI stops re-asking.
|
||||
+const updateCommand = {
|
||||
+ run: (_channel: string[]): Promise<void> => {
|
||||
+ console.log('Self-update is not supported in this build - download a new binary to update.');
|
||||
+ return delay(1000 * 60 * 60 * 6, { unref: true });
|
||||
+ }
|
||||
+};
|
||||
|
||||
import { HttpToolkitServerApi } from './api/api-server';
|
||||
import { checkBrowserConfig } from './browsers';
|
||||
Reference in New Issue
Block a user