2026-02-19 00:11:31 +00:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
2026-06-18 16:25:54 +01:00
|
|
|
PROXY_PORT=${PROXY_PORT:-8080}
|
|
|
|
|
METRO_HOST=${METRO_HOST:-localhost}
|
|
|
|
|
METRO_PORT=${METRO_PORT:-8081}
|
2026-06-12 16:31:28 +01:00
|
|
|
TS_IP=$(tailscale ip -4)
|
2026-02-19 00:11:31 +00:00
|
|
|
|
2026-06-18 16:25:54 +01:00
|
|
|
port_is_open() {
|
|
|
|
|
(: >"/dev/tcp/$1/$2") >/dev/null 2>&1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ensure_port_available() {
|
|
|
|
|
local port=$1
|
|
|
|
|
local name=$2
|
|
|
|
|
|
|
|
|
|
if port_is_open localhost "$port"; then
|
|
|
|
|
echo "$name port $port is already in use." >&2
|
|
|
|
|
echo "Stop the existing process or set ${name}_PORT to another value." >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wait_for_metro() {
|
|
|
|
|
for _ in {1..120}; do
|
|
|
|
|
if port_is_open "$METRO_HOST" "$METRO_PORT"; then
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
sleep 0.5
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
echo "Metro did not start on ${METRO_HOST}:${METRO_PORT}." >&2
|
|
|
|
|
return 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ensure_port_available "$PROXY_PORT" PROXY
|
|
|
|
|
ensure_port_available "$METRO_PORT" METRO
|
|
|
|
|
|
|
|
|
|
# Start the proxy only after Metro is listening. Otherwise an iOS client can hit
|
|
|
|
|
# the proxy during Expo startup and get a misleading upstream connection error.
|
|
|
|
|
(
|
|
|
|
|
wait_for_metro
|
|
|
|
|
exec env PROXY_PORT=$PROXY_PORT METRO_HOST=$METRO_HOST METRO_PORT=$METRO_PORT bun run scripts/dev-proxy.ts
|
|
|
|
|
) &
|
2026-02-19 00:11:31 +00:00
|
|
|
PROXY_PID=$!
|
|
|
|
|
trap "kill $PROXY_PID 2>/dev/null" EXIT
|
|
|
|
|
|
2026-06-12 16:31:28 +01:00
|
|
|
echo "Expo proxy: http://${TS_IP}:${PROXY_PORT}"
|
|
|
|
|
EXPO_PACKAGER_PROXY_URL=http://${TS_IP}:$PROXY_PORT bunx expo start --localhost -p $METRO_PORT
|