fix(ui): sub-path routing and API proxy for /magpie/ base URL
- spa_server.py: strip /magpie prefix before API check and file lookup; all HTTP methods call _normalise_path() first so /magpie/api/v1/* proxies correctly and /magpie/assets/* resolve against the dist root - manage.sh: pass --base /magpie to spa_server.py so the handler knows the deployment prefix - main.ts: pass import.meta.env.BASE_URL to createWebHistory so Vue Router strips the /magpie prefix before matching routes Without these fixes, assets returned index.html (MIME type error), API calls returned HTML instead of JSON (stats.posts undefined), and router routes never matched (matched: []). Closes: #12
This commit is contained in:
parent
35c6e5f7bc
commit
8ea4baa915
3 changed files with 26 additions and 3 deletions
|
|
@ -12,7 +12,7 @@ import OpportunitiesView from './components/OpportunitiesView.vue'
|
|||
import SignalsView from './components/SignalsView.vue'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes: [
|
||||
{ path: '/', redirect: '/signals' },
|
||||
{ path: '/signals', component: SignalsView },
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ _start_web() {
|
|||
if [[ -f "frontend/dist/index.html" ]]; then
|
||||
info "Starting web on :${WEB_PORT} (static dist — production mode)..."
|
||||
conda run --no-capture-output -n "$CONDA_ENV" \
|
||||
python scripts/spa_server.py --port "$WEB_PORT" --directory frontend/dist >> "$LOG_WEB" 2>&1 &
|
||||
python scripts/spa_server.py --port "$WEB_PORT" --directory frontend/dist --base /magpie >> "$LOG_WEB" 2>&1 &
|
||||
else
|
||||
info "Starting web on :${WEB_PORT} (Vite dev server — no dist found)..."
|
||||
cd frontend
|
||||
|
|
@ -266,7 +266,7 @@ case "$cmd" in
|
|||
# In production, Caddy proxies menagerie.circuitforge.tech/magpie* → this port.
|
||||
info "Serving pre-built frontend on :${WEB_PORT} (SPA fallback enabled)..."
|
||||
conda run --no-capture-output -n "$CONDA_ENV" \
|
||||
python scripts/spa_server.py --port "$WEB_PORT" --directory frontend/dist >> "$LOG_WEB" 2>&1 &
|
||||
python scripts/spa_server.py --port "$WEB_PORT" --directory frontend/dist --base /magpie >> "$LOG_WEB" 2>&1 &
|
||||
echo $! > "$PID_WEB"
|
||||
ok "Static server up → http://localhost:${WEB_PORT}"
|
||||
;;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,18 @@ from http.server import HTTPServer, SimpleHTTPRequestHandler
|
|||
|
||||
class SPAHandler(SimpleHTTPRequestHandler):
|
||||
api_port: int = 8532
|
||||
base_prefix: str = "" # e.g. "/magpie" — stripped before file lookup
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Path helpers
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
def _strip_base(self, path: str) -> str:
|
||||
"""Remove the base prefix so file lookup works against the dist root."""
|
||||
p = path.split("?", 1)[0].split("#", 1)[0]
|
||||
if self.base_prefix and p.startswith(self.base_prefix):
|
||||
path = path[len(self.base_prefix):]
|
||||
return path or "/"
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# API proxy
|
||||
|
|
@ -51,11 +63,16 @@ class SPAHandler(SimpleHTTPRequestHandler):
|
|||
# Request dispatch
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
def _normalise_path(self) -> None:
|
||||
"""Strip base prefix so all subsequent checks work on bare /api/ or /asset paths."""
|
||||
self.path = self._strip_base(self.path)
|
||||
|
||||
def _is_api(self) -> bool:
|
||||
path = self.path.split("?", 1)[0]
|
||||
return path.startswith("/api/")
|
||||
|
||||
def do_GET(self) -> None:
|
||||
self._normalise_path()
|
||||
if self._is_api():
|
||||
self._proxy_api()
|
||||
return
|
||||
|
|
@ -65,24 +82,28 @@ class SPAHandler(SimpleHTTPRequestHandler):
|
|||
super().do_GET()
|
||||
|
||||
def do_POST(self) -> None:
|
||||
self._normalise_path()
|
||||
if self._is_api():
|
||||
self._proxy_api()
|
||||
return
|
||||
self.send_error(405, "Method Not Allowed")
|
||||
|
||||
def do_PUT(self) -> None:
|
||||
self._normalise_path()
|
||||
if self._is_api():
|
||||
self._proxy_api()
|
||||
return
|
||||
self.send_error(405, "Method Not Allowed")
|
||||
|
||||
def do_PATCH(self) -> None:
|
||||
self._normalise_path()
|
||||
if self._is_api():
|
||||
self._proxy_api()
|
||||
return
|
||||
self.send_error(405, "Method Not Allowed")
|
||||
|
||||
def do_DELETE(self) -> None:
|
||||
self._normalise_path()
|
||||
if self._is_api():
|
||||
self._proxy_api()
|
||||
return
|
||||
|
|
@ -98,9 +119,11 @@ def main() -> None:
|
|||
parser.add_argument("--port", type=int, default=8531)
|
||||
parser.add_argument("--directory", default="frontend/dist")
|
||||
parser.add_argument("--api-port", type=int, default=8532)
|
||||
parser.add_argument("--base", default="", help="URL base prefix to strip (e.g. /magpie)")
|
||||
args = parser.parse_args()
|
||||
|
||||
SPAHandler.api_port = args.api_port
|
||||
SPAHandler.base_prefix = args.base.rstrip("/")
|
||||
os.chdir(args.directory)
|
||||
server = HTTPServer(("", args.port), SPAHandler)
|
||||
print(
|
||||
|
|
|
|||
Loading…
Reference in a new issue