@object-ui/console 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +118 -0
- package/dist/assets/AdvancedChartImpl-DAS1mU9o.js +7 -0
- package/dist/assets/AdvancedChartImpl-DAS1mU9o.js.br +0 -0
- package/dist/assets/AdvancedChartImpl-DAS1mU9o.js.gz +0 -0
- package/dist/assets/AuditLogPage-BQW_Xbnm.js +1 -0
- package/dist/assets/AuditLogPage-BQW_Xbnm.js.br +0 -0
- package/dist/assets/AuditLogPage-BQW_Xbnm.js.gz +0 -0
- package/dist/assets/ChartImpl-2ivTljUi.js +1 -0
- package/dist/assets/ChartImpl-2ivTljUi.js.br +0 -0
- package/dist/assets/ChartImpl-2ivTljUi.js.gz +0 -0
- package/dist/assets/DashboardView-Dt-4VhH6.js +1 -0
- package/dist/assets/DashboardView-Dt-4VhH6.js.br +0 -0
- package/dist/assets/DashboardView-Dt-4VhH6.js.gz +0 -0
- package/dist/assets/ForgotPasswordPage-zr9S5vrE.js +1 -0
- package/dist/assets/KanbanEnhanced-BlGp--J7.js +1 -0
- package/dist/assets/KanbanEnhanced-BlGp--J7.js.br +0 -0
- package/dist/assets/KanbanEnhanced-BlGp--J7.js.gz +0 -0
- package/dist/assets/KanbanImpl-B5wWMXrJ.js +1 -0
- package/dist/assets/KanbanImpl-B5wWMXrJ.js.br +0 -0
- package/dist/assets/KanbanImpl-B5wWMXrJ.js.gz +0 -0
- package/dist/assets/LoginPage-H688gsah.js +1 -0
- package/dist/assets/MarkdownImpl-BshtTFK2.js +29 -0
- package/dist/assets/MarkdownImpl-BshtTFK2.js.br +0 -0
- package/dist/assets/MarkdownImpl-BshtTFK2.js.gz +0 -0
- package/dist/assets/OrgManagementPage-x3qIkxHL.js +1 -0
- package/dist/assets/OrgManagementPage-x3qIkxHL.js.br +0 -0
- package/dist/assets/OrgManagementPage-x3qIkxHL.js.gz +0 -0
- package/dist/assets/PageView-BRN1h8QD.js +1 -0
- package/dist/assets/PageView-BRN1h8QD.js.br +0 -0
- package/dist/assets/PageView-BRN1h8QD.js.gz +0 -0
- package/dist/assets/ProfilePage-DjAiGvFb.js +1 -0
- package/dist/assets/ProfilePage-DjAiGvFb.js.br +0 -0
- package/dist/assets/ProfilePage-DjAiGvFb.js.gz +0 -0
- package/dist/assets/RecordDetailView-Bfu7541n.js +1 -0
- package/dist/assets/RecordDetailView-Bfu7541n.js.br +0 -0
- package/dist/assets/RecordDetailView-Bfu7541n.js.gz +0 -0
- package/dist/assets/RegisterPage-CR91Lc7x.js +1 -0
- package/dist/assets/ReportView-CwWsv2yl.js +1 -0
- package/dist/assets/ReportView-CwWsv2yl.js.br +0 -0
- package/dist/assets/ReportView-CwWsv2yl.js.gz +0 -0
- package/dist/assets/RoleManagementPage-DnWuzxKJ.js +1 -0
- package/dist/assets/RoleManagementPage-DnWuzxKJ.js.br +0 -0
- package/dist/assets/RoleManagementPage-DnWuzxKJ.js.gz +0 -0
- package/dist/assets/SearchResultsPage-DBpjAlh2.js +1 -0
- package/dist/assets/SearchResultsPage-DBpjAlh2.js.br +0 -0
- package/dist/assets/SearchResultsPage-DBpjAlh2.js.gz +0 -0
- package/dist/assets/UserManagementPage-o0_K0dzR.js +1 -0
- package/dist/assets/UserManagementPage-o0_K0dzR.js.br +0 -0
- package/dist/assets/UserManagementPage-o0_K0dzR.js.gz +0 -0
- package/dist/assets/ViewDesignerPage-BbwrZa9D.js +1 -0
- package/dist/assets/ViewDesignerPage-BbwrZa9D.js.br +0 -0
- package/dist/assets/ViewDesignerPage-BbwrZa9D.js.gz +0 -0
- package/dist/assets/data-adapter-Cn800k4a.js +1 -0
- package/dist/assets/data-adapter-Cn800k4a.js.br +0 -0
- package/dist/assets/data-adapter-Cn800k4a.js.gz +0 -0
- package/dist/assets/framework-mHWN965c.js +10 -0
- package/dist/assets/framework-mHWN965c.js.br +0 -0
- package/dist/assets/framework-mHWN965c.js.gz +0 -0
- package/dist/assets/index-BjEGJcpx.js +56 -0
- package/dist/assets/index-BjEGJcpx.js.br +0 -0
- package/dist/assets/index-BjEGJcpx.js.gz +0 -0
- package/dist/assets/index-CUnVdETN.css +1 -0
- package/dist/assets/index-CUnVdETN.css.br +0 -0
- package/dist/assets/index-CUnVdETN.css.gz +0 -0
- package/dist/assets/infrastructure-aS2LF8OZ.js +1 -0
- package/dist/assets/infrastructure-aS2LF8OZ.js.br +0 -0
- package/dist/assets/infrastructure-aS2LF8OZ.js.gz +0 -0
- package/dist/assets/maplibre-gl-D2AsLM0J.js +811 -0
- package/dist/assets/maplibre-gl-D2AsLM0J.js.br +0 -0
- package/dist/assets/maplibre-gl-D2AsLM0J.js.gz +0 -0
- package/dist/assets/plugins-core-CcBSZCjG.js +4 -0
- package/dist/assets/plugins-core-CcBSZCjG.js.br +0 -0
- package/dist/assets/plugins-core-CcBSZCjG.js.gz +0 -0
- package/dist/assets/plugins-views-DQwkCaaO.js +60 -0
- package/dist/assets/plugins-views-DQwkCaaO.js.br +0 -0
- package/dist/assets/plugins-views-DQwkCaaO.js.gz +0 -0
- package/dist/assets/plugins-views-P3eB-els.css +1 -0
- package/dist/assets/plugins-views-P3eB-els.css.br +0 -0
- package/dist/assets/plugins-views-P3eB-els.css.gz +0 -0
- package/dist/assets/systemObjects-DSpePIIy.js +1 -0
- package/dist/assets/systemObjects-DSpePIIy.js.br +2 -0
- package/dist/assets/systemObjects-DSpePIIy.js.gz +0 -0
- package/dist/assets/ui-components-DVonQS7H.js +31 -0
- package/dist/assets/ui-components-DVonQS7H.js.br +0 -0
- package/dist/assets/ui-components-DVonQS7H.js.gz +0 -0
- package/dist/assets/ui-components-GrNdJOi1.css +1 -0
- package/dist/assets/ui-components-GrNdJOi1.css.br +0 -0
- package/dist/assets/ui-components-GrNdJOi1.css.gz +0 -0
- package/dist/assets/ui-layout-BENIRxAF.js +1 -0
- package/dist/assets/ui-layout-BENIRxAF.js.br +0 -0
- package/dist/assets/ui-layout-BENIRxAF.js.gz +0 -0
- package/dist/assets/vendor-charts-CSvoW-yB.js +65 -0
- package/dist/assets/vendor-charts-CSvoW-yB.js.br +0 -0
- package/dist/assets/vendor-charts-CSvoW-yB.js.gz +0 -0
- package/dist/assets/vendor-dndkit-DRGpK6sP.js +5 -0
- package/dist/assets/vendor-dndkit-DRGpK6sP.js.br +0 -0
- package/dist/assets/vendor-dndkit-DRGpK6sP.js.gz +0 -0
- package/dist/assets/vendor-i18n-D5KbMT7w.js +9 -0
- package/dist/assets/vendor-i18n-D5KbMT7w.js.br +0 -0
- package/dist/assets/vendor-i18n-D5KbMT7w.js.gz +0 -0
- package/dist/assets/vendor-icons-CQ8b-fGy.js +8671 -0
- package/dist/assets/vendor-icons-CQ8b-fGy.js.br +0 -0
- package/dist/assets/vendor-icons-CQ8b-fGy.js.gz +0 -0
- package/dist/assets/vendor-objectstack-DqojdwYW.js +37 -0
- package/dist/assets/vendor-objectstack-DqojdwYW.js.br +0 -0
- package/dist/assets/vendor-objectstack-DqojdwYW.js.gz +0 -0
- package/dist/assets/vendor-radix-BbeYj_o4.js +56 -0
- package/dist/assets/vendor-radix-BbeYj_o4.js.br +0 -0
- package/dist/assets/vendor-radix-BbeYj_o4.js.gz +0 -0
- package/dist/assets/vendor-react-Dy_xkBQQ.js +60 -0
- package/dist/assets/vendor-react-Dy_xkBQQ.js.br +0 -0
- package/dist/assets/vendor-react-Dy_xkBQQ.js.gz +0 -0
- package/dist/assets/vendor-ui-utils-h6yAcIi9.js +1 -0
- package/dist/assets/vendor-ui-utils-h6yAcIi9.js.br +0 -0
- package/dist/assets/vendor-ui-utils-h6yAcIi9.js.gz +0 -0
- package/dist/assets/vendor-zod-Dpl-cylz.js +39 -0
- package/dist/assets/vendor-zod-Dpl-cylz.js.br +0 -0
- package/dist/assets/vendor-zod-Dpl-cylz.js.gz +0 -0
- package/dist/index.html +49 -0
- package/dist/index.html.br +0 -0
- package/dist/index.html.gz +0 -0
- package/dist/manifest.json +19 -0
- package/dist/mockServiceWorker.js +349 -0
- package/dist/mockServiceWorker.js.br +0 -0
- package/dist/mockServiceWorker.js.gz +0 -0
- package/dist/stats.html +4949 -0
- package/package.json +98 -0
- package/plugin.ts +177 -0
package/package.json
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@object-ui/console",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "ObjectStack Console - The standard runtime UI for ObjectStack applications",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./plugin.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./plugin.ts",
|
|
10
|
+
"default": "./plugin.ts"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist",
|
|
15
|
+
"plugin.ts"
|
|
16
|
+
],
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@objectstack/client": "^3.0.2",
|
|
19
|
+
"@objectstack/driver-memory": "^3.0.2",
|
|
20
|
+
"@objectstack/objectql": "^3.0.2",
|
|
21
|
+
"@objectstack/plugin-msw": "^3.0.2",
|
|
22
|
+
"@objectstack/runtime": "^3.0.2",
|
|
23
|
+
"@objectstack/spec": "^3.0.2",
|
|
24
|
+
"lucide-react": "^0.563.0",
|
|
25
|
+
"react": "19.2.4",
|
|
26
|
+
"react-dom": "19.2.4",
|
|
27
|
+
"react-router-dom": "^7.13.0",
|
|
28
|
+
"sonner": "^2.0.7",
|
|
29
|
+
"@object-ui/auth": "2.0.0",
|
|
30
|
+
"@object-ui/components": "2.0.0",
|
|
31
|
+
"@object-ui/core": "2.0.0",
|
|
32
|
+
"@object-ui/collaboration": "2.0.0",
|
|
33
|
+
"@object-ui/example-crm": "1.0.0",
|
|
34
|
+
"@object-ui/data-objectstack": "2.0.0",
|
|
35
|
+
"@object-ui/example-todo": "1.0.0",
|
|
36
|
+
"@object-ui/example-kitchen-sink": "1.0.0",
|
|
37
|
+
"@object-ui/fields": "2.0.0",
|
|
38
|
+
"@object-ui/i18n": "2.0.0",
|
|
39
|
+
"@object-ui/layout": "2.0.0",
|
|
40
|
+
"@object-ui/plugin-calendar": "2.0.0",
|
|
41
|
+
"@object-ui/permissions": "2.0.0",
|
|
42
|
+
"@object-ui/plugin-charts": "2.0.0",
|
|
43
|
+
"@object-ui/mobile": "2.0.0",
|
|
44
|
+
"@object-ui/plugin-dashboard": "2.0.0",
|
|
45
|
+
"@object-ui/plugin-designer": "2.0.0",
|
|
46
|
+
"@object-ui/plugin-form": "2.0.0",
|
|
47
|
+
"@object-ui/plugin-detail": "2.0.0",
|
|
48
|
+
"@object-ui/plugin-gantt": "2.0.0",
|
|
49
|
+
"@object-ui/plugin-grid": "2.0.0",
|
|
50
|
+
"@object-ui/plugin-kanban": "2.0.0",
|
|
51
|
+
"@object-ui/plugin-list": "2.0.0",
|
|
52
|
+
"@object-ui/plugin-map": "2.0.0",
|
|
53
|
+
"@object-ui/plugin-markdown": "2.0.0",
|
|
54
|
+
"@object-ui/plugin-timeline": "2.0.0",
|
|
55
|
+
"@object-ui/plugin-view": "2.0.0",
|
|
56
|
+
"@object-ui/plugin-report": "2.0.0",
|
|
57
|
+
"@object-ui/react": "2.0.0",
|
|
58
|
+
"@object-ui/types": "2.0.0"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@objectstack/cli": "^3.0.2",
|
|
62
|
+
"@tailwindcss/postcss": "^4.1.18",
|
|
63
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
64
|
+
"@testing-library/react": "^16.3.2",
|
|
65
|
+
"@testing-library/user-event": "^14.6.1",
|
|
66
|
+
"@types/node": "^25.2.3",
|
|
67
|
+
"@types/react": "19.2.13",
|
|
68
|
+
"@types/react-dom": "19.2.3",
|
|
69
|
+
"@vitejs/plugin-react": "^5.1.4",
|
|
70
|
+
"@vitest/ui": "^4.0.18",
|
|
71
|
+
"autoprefixer": "^10.4.24",
|
|
72
|
+
"happy-dom": "^20.6.1",
|
|
73
|
+
"msw": "^2.12.10",
|
|
74
|
+
"postcss": "^8.5.6",
|
|
75
|
+
"tailwindcss": "^4.1.18",
|
|
76
|
+
"typescript": "^5.9.3",
|
|
77
|
+
"vite": "^6.4.1",
|
|
78
|
+
"vitest": "^4.0.18"
|
|
79
|
+
},
|
|
80
|
+
"msw": {
|
|
81
|
+
"workerDirectory": [
|
|
82
|
+
"public"
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
"scripts": {
|
|
86
|
+
"msw:init": "msw init -y public",
|
|
87
|
+
"dev": "pnpm msw:init && vite",
|
|
88
|
+
"start": "tsx ../../node_modules/@objectstack/cli/bin/objectstack.js serve objectstack.config.ts",
|
|
89
|
+
"start:mock": "pnpm msw:init && vite preview",
|
|
90
|
+
"build": "pnpm msw:init && tsc && VITE_USE_MOCK_SERVER=false vite build",
|
|
91
|
+
"build:vercel": "pnpm msw:init && tsc && VITE_USE_MOCK_SERVER=true vite build",
|
|
92
|
+
"build:analyze": "pnpm build && echo 'Bundle analysis available at dist/stats.html'",
|
|
93
|
+
"preview": "vite preview",
|
|
94
|
+
"test": "vitest run",
|
|
95
|
+
"test:watch": "vitest",
|
|
96
|
+
"test:ui": "vitest --ui"
|
|
97
|
+
}
|
|
98
|
+
}
|
package/plugin.ts
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectStack Console Plugin
|
|
3
|
+
*
|
|
4
|
+
* Serves the pre-built Console SPA as a static UI plugin.
|
|
5
|
+
* The mount path is auto-detected from the built assets (VITE_BASE_PATH
|
|
6
|
+
* at build time determines asset prefixes and React Router basename).
|
|
7
|
+
*
|
|
8
|
+
* Build commands:
|
|
9
|
+
* pnpm build → base '/' → mount at /
|
|
10
|
+
* VITE_BASE_PATH=/console/ pnpm build → base '/console' → mount at /console
|
|
11
|
+
*
|
|
12
|
+
* Usage in any ObjectStack application:
|
|
13
|
+
*
|
|
14
|
+
* import { ConsolePlugin } from '@object-ui/console';
|
|
15
|
+
*
|
|
16
|
+
* export default {
|
|
17
|
+
* plugins: [
|
|
18
|
+
* new HonoServerPlugin({ port: 3000 }),
|
|
19
|
+
* new ConsolePlugin(),
|
|
20
|
+
* ],
|
|
21
|
+
* };
|
|
22
|
+
*
|
|
23
|
+
* @see https://github.com/objectstack-ai/objectui
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { fileURLToPath } from 'url';
|
|
27
|
+
import { dirname, resolve } from 'path';
|
|
28
|
+
import { existsSync, readFileSync } from 'fs';
|
|
29
|
+
|
|
30
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
31
|
+
const __dirname = dirname(__filename);
|
|
32
|
+
|
|
33
|
+
/** Absolute path to the built SPA assets (dist/) */
|
|
34
|
+
export const staticPath = resolve(__dirname, 'dist');
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Detect the base path baked into dist/index.html at build time.
|
|
38
|
+
*
|
|
39
|
+
* Vite prefixes all asset URLs with the `base` config value.
|
|
40
|
+
* We parse `<script … src="/console/assets/…">` to recover it.
|
|
41
|
+
* Falls back to '/' when dist is missing or no prefix is found.
|
|
42
|
+
*/
|
|
43
|
+
function detectBasePath(distDir: string): string {
|
|
44
|
+
const indexPath = resolve(distDir, 'index.html');
|
|
45
|
+
if (!existsSync(indexPath)) return '/';
|
|
46
|
+
const html = readFileSync(indexPath, 'utf-8');
|
|
47
|
+
// Match src="/console/assets/..." or href="/console/assets/..."
|
|
48
|
+
const match = html.match(/(?:src|href)="(\/[^"]*?)\/assets\//);
|
|
49
|
+
if (match?.[1]) return match[1]; // e.g. '/console'
|
|
50
|
+
return '/';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export class ConsolePlugin {
|
|
54
|
+
readonly name = '@object-ui/console';
|
|
55
|
+
readonly version = '1.0.0';
|
|
56
|
+
readonly type = 'ui-plugin' as const;
|
|
57
|
+
readonly slug = 'console';
|
|
58
|
+
readonly staticPath = staticPath;
|
|
59
|
+
readonly default = true;
|
|
60
|
+
readonly description = 'ObjectStack Console - The standard runtime UI for ObjectStack applications';
|
|
61
|
+
|
|
62
|
+
readonly metadata = {
|
|
63
|
+
author: 'ObjectUI Team',
|
|
64
|
+
license: 'MIT',
|
|
65
|
+
homepage: 'https://www.objectui.org',
|
|
66
|
+
repository: 'https://github.com/objectstack-ai/objectui',
|
|
67
|
+
capabilities: [
|
|
68
|
+
'ui-rendering',
|
|
69
|
+
'crud-operations',
|
|
70
|
+
'multi-app-support',
|
|
71
|
+
'dynamic-navigation',
|
|
72
|
+
'theme-support',
|
|
73
|
+
],
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
init() {
|
|
77
|
+
// No initialization needed
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async start(ctx: any) {
|
|
81
|
+
const httpService = ctx.getService?.('http-server') || ctx.getService?.('http.server');
|
|
82
|
+
if (!httpService || typeof httpService.getRawApp !== 'function') {
|
|
83
|
+
const logger = ctx.logger || console;
|
|
84
|
+
logger.warn('[Console] HTTP server not available. SPA routes not registered.');
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const app = httpService.getRawApp();
|
|
89
|
+
const logger = ctx.logger || console;
|
|
90
|
+
const distDir = staticPath;
|
|
91
|
+
|
|
92
|
+
if (!existsSync(distDir)) {
|
|
93
|
+
logger.warn(`[Console] dist/ not found at ${distDir}. Run "pnpm build" first.`);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Auto-detect mount path from the build output
|
|
98
|
+
const basePath = detectBasePath(distDir);
|
|
99
|
+
const isRoot = basePath === '/';
|
|
100
|
+
|
|
101
|
+
// Try to use @hono/node-server/serve-static for efficient file serving
|
|
102
|
+
let serveStaticFn: any;
|
|
103
|
+
try {
|
|
104
|
+
const mod = await import('@hono/node-server/serve-static');
|
|
105
|
+
serveStaticFn = mod.serveStatic;
|
|
106
|
+
} catch {
|
|
107
|
+
// Fallback: manual file serving if @hono/node-server not available
|
|
108
|
+
serveStaticFn = null;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const routePattern = isRoot ? '/*' : `${basePath}/*`;
|
|
112
|
+
const stripPrefix = isRoot
|
|
113
|
+
? (p: string) => p
|
|
114
|
+
: (p: string) => p.replace(new RegExp(`^${basePath}`), '');
|
|
115
|
+
|
|
116
|
+
if (serveStaticFn) {
|
|
117
|
+
// Serve static assets
|
|
118
|
+
app.use(routePattern, serveStaticFn({
|
|
119
|
+
root: distDir,
|
|
120
|
+
rewriteRequestPath: stripPrefix,
|
|
121
|
+
}));
|
|
122
|
+
|
|
123
|
+
// SPA fallback: any non-file route → dist/index.html
|
|
124
|
+
app.get(routePattern, serveStaticFn({
|
|
125
|
+
root: distDir,
|
|
126
|
+
rewriteRequestPath: () => '/index.html',
|
|
127
|
+
}));
|
|
128
|
+
} else {
|
|
129
|
+
// Manual fallback when serveStatic is unavailable
|
|
130
|
+
const indexPath = resolve(distDir, 'index.html');
|
|
131
|
+
|
|
132
|
+
app.get(routePattern, async (c: any) => {
|
|
133
|
+
// Skip API routes
|
|
134
|
+
if (c.req.path.startsWith('/api')) return c.text('Not Found', 404);
|
|
135
|
+
|
|
136
|
+
const reqPath = stripPrefix(c.req.path);
|
|
137
|
+
const filePath = resolve(distDir, reqPath.replace(/^\//, ''));
|
|
138
|
+
|
|
139
|
+
// Try to serve the exact file first
|
|
140
|
+
if (existsSync(filePath) && !filePath.endsWith('/')) {
|
|
141
|
+
const ext = filePath.split('.').pop() || '';
|
|
142
|
+
const mimeTypes: Record<string, string> = {
|
|
143
|
+
js: 'application/javascript',
|
|
144
|
+
css: 'text/css',
|
|
145
|
+
json: 'application/json',
|
|
146
|
+
html: 'text/html',
|
|
147
|
+
svg: 'image/svg+xml',
|
|
148
|
+
png: 'image/png',
|
|
149
|
+
ico: 'image/x-icon',
|
|
150
|
+
woff2: 'font/woff2',
|
|
151
|
+
woff: 'font/woff',
|
|
152
|
+
gz: 'application/gzip',
|
|
153
|
+
br: 'application/x-brotli',
|
|
154
|
+
};
|
|
155
|
+
const contentType = mimeTypes[ext] || 'application/octet-stream';
|
|
156
|
+
const content = readFileSync(filePath);
|
|
157
|
+
return c.body(content, 200, { 'Content-Type': contentType });
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// SPA fallback: return index.html
|
|
161
|
+
if (existsSync(indexPath)) {
|
|
162
|
+
return c.html(readFileSync(indexPath, 'utf-8'));
|
|
163
|
+
}
|
|
164
|
+
return c.text('Console not built. Run: pnpm --filter @object-ui/console build', 404);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Only redirect / → basePath when NOT mounted at root
|
|
169
|
+
if (!isRoot) {
|
|
170
|
+
app.get('/', (c: any) => c.redirect(basePath));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
logger.info(`[Console] SPA mounted at ${isRoot ? '/' : basePath}`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export default ConsolePlugin;
|