Files
httptoolkit/scripts/patch.sh
T
shihaam 6768b0a5b2
Build & Release binary / build (push) Successful in 26m20s
build works now
2026-08-22 16:14:56 +05:00

80 lines
3.8 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Apply our patches + overlay onto the cloned upstream repos.
# Fails loudly if a patch no longer applies (upstream moved).
#
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT"
apply_patches() {
local name="$1" dir="$2"
[ -d "patches/$name" ] || return 0
echo "==> [$name] applying patches"
for patch in patches/"$name"/*.patch; do
[ -e "$patch" ] || continue
echo " - $(basename "$patch")"
git -C "$dir" apply --3way "$ROOT/$patch"
done
}
apply_patches ui httptoolkit-ui
apply_patches server httptoolkit-server
# `src/config.d.ts` is a types-only module: tsc erases `import { HtkConfig } from
# './config'` entirely, but bun's bundler resolves imports for real and fails
# ("Could not resolve: ./config") because a .d.ts isn't a bundleable source file.
# Promote it to a real .ts module so bun can resolve it - it holds only exported
# interfaces, so it compiles down to nothing. Derived from upstream rather than
# vendored, so it can't drift out of sync with the real type.
promote_dts_to_ts() {
local dts="$1" ts="${1%.d.ts}.ts"
[ -f "$dts" ] || { echo "!! expected $dts to exist (upstream moved?)"; exit 1; }
# Anything other than exported type declarations would need real runtime code:
if grep -qE '^\s*(declare|import|export\s+(const|let|var|function|class|default))' "$dts"; then
echo "!! $dts is no longer types-only - it needs a real runtime module now"
exit 1
fi
echo " - $dts -> $ts"
mv "$dts" "$ts"
}
echo "==> [server] promoting types-only modules to real modules (for bun)"
promote_dts_to_ts httptoolkit-server/src/config.d.ts
# Upstream targets es2020 and never sets useDefineForClassFields, so tsc defaults
# it to false: class field initialisers are emitted *inside* the constructor,
# after parameter properties are assigned. Bun ignores that inferred default and
# emits native ES class fields, which run BEFORE the constructor body - so any
# class doing `constructor(private config: X)` plus a field initialiser that
# reads `this.config` (e.g. ElectronInterceptor.certData) crashes with
# "undefined is not an object". Set the flag explicitly to restore tsc semantics.
# APP_ROOT is derived from __dirname, which in a compiled binary is a build-machine
# path that doesn't exist for users. Everything hanging off it then breaks at
# runtime - OVERRIDES_DIR most visibly ("Unable to access jarfile
# .../overrides/java-agent.jar", "lstat .../overrides/webextension"), which takes
# out JVM/terminal interception and the WebRTC webextension. Make it overridable so
# htk-entry.ts can point it at the directory it extracts the embedded overrides to.
echo "==> [server] making APP_ROOT overridable via HTK_APP_ROOT"
APP_ROOT_LINE="export const APP_ROOT = path.join(__dirname, '..');"
if grep -qF "$APP_ROOT_LINE" httptoolkit-server/src/constants.ts; then
sed -i "s|$APP_ROOT_LINE|export const APP_ROOT = process.env.HTK_APP_ROOT \|\| path.join(__dirname, '..');|" \
httptoolkit-server/src/constants.ts
elif grep -q 'HTK_APP_ROOT' httptoolkit-server/src/constants.ts; then
echo " - already applied"
else
echo "!! APP_ROOT definition not found in constants.ts (upstream moved?)"; exit 1
fi
echo "==> [server] pinning useDefineForClassFields=false (tsc semantics for bun)"
jq '.compilerOptions.useDefineForClassFields = false' \
httptoolkit-server/tsconfig.json > httptoolkit-server/tsconfig.json.tmp
mv httptoolkit-server/tsconfig.json.tmp httptoolkit-server/tsconfig.json
echo "==> Copying overlay into httptoolkit-server"
cp -v overlay/server/htk-entry.ts httptoolkit-server/htk-entry.ts
cp -v overlay/server/src/htk-app.ts httptoolkit-server/src/htk-app.ts
cp -v overlay/server/src/commands/app.ts httptoolkit-server/src/commands/app.ts
echo "==> patch.sh complete."