Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/plugin-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ jobs:
- PKGPATH: ./plugins/bao
RUNNER: ubuntu-24.04
- PKGPATH: ./plugins/docs
- PKGPATH: ./plugins/web
- PKGPATH: ./plugins/runtime

runs-on: ${{ matrix.RUNNER || needs.pick_runner.outputs.random_runner }}
Expand Down
20 changes: 1 addition & 19 deletions core/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -545,26 +545,8 @@ try {
console.log("Serving Shinylive assets from shinylive/");
} catch { /* shinylive assets not present — skip */ }

try {
const schemaDir = Deno.env.get("SCHEMA_DIR");
const coreRoot = schemaDir ? join(schemaDir, "..") : join(Deno.cwd(), "core");
const webDistPath = join(coreRoot, "web", "dist");
await Deno.stat(webDistPath);
const serveStatic = (await import("express")).default.static;
app.use(BASE_PATH, serveStatic(webDistPath));
app.get(`${BASE_PATH}/*`, (_req, res, next) => {
if (_req.path.startsWith(`${BASE_PATH}/api/`) || _req.path.startsWith(`${BASE_PATH}/graphql`) || _req.path.startsWith(`${BASE_PATH}/graphiql`) || _req.path.startsWith(`${BASE_PATH}/_internal`)) {
return next();
}
res.sendFile(join(webDistPath, "index.html"));
});
console.log("Serving static files from core/web/dist/");
} catch (e) {
console.warn("Static file serving disabled:", e);
}

app.get("/", (_req, res) => {
res.redirect(`${BASE_PATH}/`);
res.redirect("/plugins/trex/web/");
});

await initAuthFromDB();
Expand Down
18 changes: 16 additions & 2 deletions core/server/plugin/ui.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Express } from "express";
import { join } from "jsr:@std/path@^1.0";
import { PLUGINS_BASE_PATH } from "../config.ts";
import { scopeUrlPrefix } from "./utils.ts";

Expand All @@ -14,21 +15,34 @@
return pluginsJson;
}

export function addPlugin(_app: Express, value: any, dir: string, fullName: string = "") {
export function addPlugin(app: Express, value: any, dir: string, fullName: string = "") {
const scopePrefix = scopeUrlPrefix(fullName);
if (value.routes) {
for (const r of value.routes) {
const urlPrefix = r.path || r.source;
const fsPath = `${dir}/${r.dir || r.target}`;
const fullPrefix = `${PLUGINS_BASE_PATH}${scopePrefix}${urlPrefix}`;
console.log(`Registering static route: ${fullPrefix} -> ${fsPath}`);
REGISTERED_UI_ROUTES.push({ pluginName: name, urlPrefix: fullPrefix, fsPath });
REGISTERED_UI_ROUTES.push({ pluginName: fullName, urlPrefix: fullPrefix, fsPath });
try {
// deno-lint-ignore no-explicit-any
(Deno as any).core.ops.op_register_static_route(fullPrefix, fsPath);
} catch (e) {
console.error(`Failed to register static route ${fullPrefix}: ${e}`);
}

// SPA fallback: serve index.html for non-file paths
if (r.spa) {
const indexPath = join(fsPath, "index.html");
app.use(fullPrefix, (_req, res, next) => {
try {
res.sendFile(indexPath);
} catch {
next();
}
});
console.log(`Registered SPA fallback: ${fullPrefix}/* -> ${indexPath}`);
}
}
}

Expand Down
2 changes: 0 additions & 2 deletions core/web/src/lib/config.ts

This file was deleted.

1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ services:
- ./functions:/usr/src/functions
- ./plugins-dev:/usr/src/plugins-dev
- ./plugins/docs:/usr/src/plugins/@trex/docs
- ./plugins/web/dist:/usr/src/plugins/@trex/web/dist
depends_on:
postgres:
condition: service_healthy
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@trex/pgwire": "latest",
"@trex/tpm": "latest",
"@trex/docs": "latest",
"@trex/transform": "latest"
"@trex/transform": "latest",
"@trex/web": "latest"
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
15 changes: 12 additions & 3 deletions core/web/package.json → plugins/web/package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
{
"name": "web",
"private": true,
"version": "0.0.0",
"name": "@trex/web",
"version": "1.0.0",
"description": "trex admin web UI",
"type": "module",
"files": ["dist/"],
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"prepack": "npm run build",
"lint": "eslint .",
"preview": "vite preview"
},
"trex": {
"ui": {
"routes": [
{ "path": "/web", "dir": "dist", "spa": true }
]
}
},
"dependencies": {
"@tanstack/react-query": "^5.90.21",
"better-auth": "^1.4.18",
Expand Down
4 changes: 2 additions & 2 deletions core/web/src/App.tsx → plugins/web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom";
import { Toaster } from "@/components/ui/sonner";
import { useSession } from "@/lib/auth-client";
import { GraphQLProvider } from "@/lib/graphql-client";
import { BASE_PATH } from "@/lib/config";
import { UI_BASE_PATH } from "@/lib/config";
import { Layout } from "@/components/Layout";
import { AdminLayout } from "@/components/AdminLayout";
import { Login } from "@/pages/Login";
Expand Down Expand Up @@ -49,7 +49,7 @@ function HomeRedirect() {
export default function App() {
return (
<GraphQLProvider>
<BrowserRouter basename={BASE_PATH}>
<BrowserRouter basename={UI_BASE_PATH}>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
Expand Down
File renamed without changes.
File renamed without changes.
5 changes: 5 additions & 0 deletions plugins/web/src/lib/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const raw = import.meta.env.VITE_BASE_PATH || "/trex";
export const BASE_PATH = raw.endsWith("/") ? raw.slice(0, -1) : raw;

// Vite's `base` config sets import.meta.env.BASE_URL automatically
export const UI_BASE_PATH = import.meta.env.BASE_URL.replace(/\/$/, "");
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 3 additions & 1 deletion core/web/vite.config.ts → plugins/web/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'

const basePath = process.env.VITE_BASE_PATH || "/trex"
const uiBasePath = process.env.VITE_UI_BASE_PATH || "/plugins/trex/web"

export default defineConfig({
base: `${basePath}/`,
base: `${uiBasePath}/`,
plugins: [react(), tailwindcss()],
resolve: {
alias: {
Expand All @@ -19,6 +20,7 @@ export default defineConfig({
[`${basePath}/graphql`]: { target: "http://localhost:8000", ws: true },
[`${basePath}/graphiql`]: "http://localhost:8000",
[`${basePath}/docs`]: "http://localhost:8000",
"/plugins": "http://localhost:8000",
},
},
})
Loading