#!/usr/bin/env bash set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" TMPDIR_TEST="$(mktemp -d)" PIDS=() cleanup() { for pid in "${PIDS[@]}"; do kill "$pid" 2>/dev/null || true; done rm -rf "$TMPDIR_TEST" } trap cleanup EXIT INT TERM free_port() { node -e 'const server = require("node:net").createServer(); server.listen(0, "127.0.0.1", () => { console.log(server.address().port); server.close(); });' } backend_port_file="$TMPDIR_TEST/backend-port" node -e ' const Fastify = require(process.argv[1]); const fs = require("node:fs"); const app = Fastify(); app.get("/health", async (request) => ({ backend: "fastify", path: request.raw.url })); app.listen({ port: 0, host: "127.0.0.1" }).then((address) => { fs.writeFileSync(process.argv[2], String(new URL(address).port)); }); ' "$ROOT/backend/node_modules/fastify" "$backend_port_file" >"$TMPDIR_TEST/backend.log" 2>&1 & PIDS+=("$!") for _ in {1..50}; do [ -s "$backend_port_file" ] && break sleep 0.1 done [ -s "$backend_port_file" ] || { cat "$TMPDIR_TEST/backend.log" >&2; exit 1; } backend_port="$(<"$backend_port_file")" frontend_port="$(free_port)" THT_FRONTEND_API_UPSTREAM="http://127.0.0.1:$backend_port" \ npm --prefix "$ROOT/frontend" run dev -- --host 127.0.0.1 --port "$frontend_port" \ >"$TMPDIR_TEST/vite.log" 2>&1 & PIDS+=("$!") response="" for _ in {1..50}; do if response="$(curl -fsS "http://127.0.0.1:$frontend_port/api/health" 2>/dev/null)"; then break fi sleep 0.1 done if [ "$response" != '{"backend":"fastify","path":"/health"}' ]; then cat "$TMPDIR_TEST/vite.log" >&2 printf 'expected Vite /api/health to reach Fastify /health, got: %s\n' "$response" >&2 exit 1 fi if ! rg -Fq -- '-f "$ROOT/compose.yaml" -f "$ROOT/deploy/compose.local.yaml" up --build "$@"' "$ROOT/scripts/run-stack.sh"; then echo "run-stack.sh must start the base+local Compose stack" >&2 exit 1 fi if rg -q 'command -v pi|PI_BIN="pi"|PI_BIN=pi' "$ROOT/scripts/run-stack.sh"; then echo "run-stack.sh must not require a host Pi binary" >&2 exit 1 fi echo "local browser /api routes to Fastify through the Vite proxy: ok"