@geekmidas/studio 9.0.2 → 10.0.0-alpha.1
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/package.json +8 -5
- package/CHANGELOG.md +0 -82
- package/src/Studio.ts +0 -367
- package/src/__tests__/Studio.spec.ts +0 -447
- package/src/data/DataBrowser.ts +0 -170
- package/src/data/__tests__/DataBrowser.integration.spec.ts +0 -418
- package/src/data/__tests__/filtering.integration.spec.ts +0 -741
- package/src/data/__tests__/introspection.integration.spec.ts +0 -352
- package/src/data/__tests__/pagination.spec.ts +0 -123
- package/src/data/filtering.ts +0 -191
- package/src/data/index.ts +0 -1
- package/src/data/introspection.ts +0 -220
- package/src/data/pagination.ts +0 -33
- package/src/index.ts +0 -29
- package/src/server/__tests__/hono.integration.spec.ts +0 -619
- package/src/server/hono.ts +0 -427
- package/src/types.ts +0 -278
- package/src/ui-assets.ts +0 -37
- package/tsconfig.json +0 -9
- package/tsdown.config.ts +0 -13
- package/ui/CHANGELOG.md +0 -26
- package/ui/index.html +0 -12
- package/ui/node_modules/.bin/tsc +0 -21
- package/ui/node_modules/.bin/tsserver +0 -21
- package/ui/node_modules/.bin/vite +0 -21
- package/ui/package.json +0 -30
- package/ui/src/App.tsx +0 -100
- package/ui/src/api.ts +0 -213
- package/ui/src/components/FilterPanel.tsx +0 -213
- package/ui/src/components/NavRail.tsx +0 -183
- package/ui/src/components/RowDetail.tsx +0 -119
- package/ui/src/components/StudioHeader.tsx +0 -109
- package/ui/src/components/TableList.tsx +0 -58
- package/ui/src/components/TableView.tsx +0 -564
- package/ui/src/main.tsx +0 -10
- package/ui/src/pages/DashboardPage.tsx +0 -500
- package/ui/src/pages/DatabasePage.tsx +0 -226
- package/ui/src/pages/EndpointDetailsPage.tsx +0 -288
- package/ui/src/pages/ExceptionsPage.tsx +0 -268
- package/ui/src/pages/LogsPage.tsx +0 -228
- package/ui/src/pages/MonitoringPage.tsx +0 -46
- package/ui/src/pages/PerformancePage.tsx +0 -307
- package/ui/src/pages/RequestsPage.tsx +0 -379
- package/ui/src/providers/StudioProvider.tsx +0 -194
- package/ui/src/styles.css +0 -105
- package/ui/src/types.ts +0 -174
- package/ui/src/vite-env.d.ts +0 -1
- package/ui/tsconfig.json +0 -21
- package/ui/tsconfig.tsbuildinfo +0 -1
- package/ui/vite.config.ts +0 -12
package/tsconfig.json
DELETED
package/tsdown.config.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'tsdown';
|
|
2
|
-
|
|
3
|
-
export default defineConfig({
|
|
4
|
-
entry: ['src/index.ts', 'src/data/index.ts', 'src/server/hono.ts'],
|
|
5
|
-
clean: true,
|
|
6
|
-
outDir: 'dist',
|
|
7
|
-
format: ['cjs', 'esm'],
|
|
8
|
-
sourcemap: true,
|
|
9
|
-
dts: true,
|
|
10
|
-
outExtensions: (ctx) => ({
|
|
11
|
-
js: ctx.format === 'es' ? '.mjs' : '.cjs',
|
|
12
|
-
}),
|
|
13
|
-
});
|
package/ui/CHANGELOG.md
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# @geekmidas/studio-ui
|
|
2
|
-
|
|
3
|
-
## 1.0.2
|
|
4
|
-
|
|
5
|
-
### Patch Changes
|
|
6
|
-
|
|
7
|
-
- Updated dependencies [[`40f4dc0`](https://github.com/geekmidas/toolbox/commit/40f4dc095911b2223a255029d8f776caf7781309)]:
|
|
8
|
-
- @geekmidas/ui@1.0.2
|
|
9
|
-
|
|
10
|
-
## 1.0.1
|
|
11
|
-
|
|
12
|
-
### Patch Changes
|
|
13
|
-
|
|
14
|
-
- Updated dependencies [[`d70c6c0`](https://github.com/geekmidas/toolbox/commit/d70c6c0aeb8a79da2473ac77dbd8255a4a2f5651)]:
|
|
15
|
-
- @geekmidas/ui@1.0.1
|
|
16
|
-
|
|
17
|
-
## 1.0.0
|
|
18
|
-
|
|
19
|
-
### Major Changes
|
|
20
|
-
|
|
21
|
-
- [`ff7b115`](https://github.com/geekmidas/toolbox/commit/ff7b11599f60f84ac6cdc73714c853ecf786b2e8) Thanks [@geekmidas](https://github.com/geekmidas)! - Version 1 Stable release
|
|
22
|
-
|
|
23
|
-
### Patch Changes
|
|
24
|
-
|
|
25
|
-
- Updated dependencies [[`ff7b115`](https://github.com/geekmidas/toolbox/commit/ff7b11599f60f84ac6cdc73714c853ecf786b2e8)]:
|
|
26
|
-
- @geekmidas/ui@1.0.0
|
package/ui/index.html
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Studio - Database Browser</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<div id="root"></div>
|
|
10
|
-
<script type="module" src="/src/main.tsx"></script>
|
|
11
|
-
</body>
|
|
12
|
-
</html>
|
package/ui/node_modules/.bin/tsc
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
|
-
|
|
4
|
-
case `uname` in
|
|
5
|
-
*CYGWIN*|*MINGW*|*MSYS*)
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
10
|
-
esac
|
|
11
|
-
|
|
12
|
-
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/home/runner/work/toolbox/toolbox/node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/bin/node_modules:/home/runner/work/toolbox/toolbox/node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/node_modules:/home/runner/work/toolbox/toolbox/node_modules/.pnpm/typescript@5.8.2/node_modules:/home/runner/work/toolbox/toolbox/node_modules/.pnpm/node_modules"
|
|
14
|
-
else
|
|
15
|
-
export NODE_PATH="/home/runner/work/toolbox/toolbox/node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/bin/node_modules:/home/runner/work/toolbox/toolbox/node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/node_modules:/home/runner/work/toolbox/toolbox/node_modules/.pnpm/typescript@5.8.2/node_modules:/home/runner/work/toolbox/toolbox/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
|
-
fi
|
|
17
|
-
if [ -x "$basedir/node" ]; then
|
|
18
|
-
exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@"
|
|
19
|
-
else
|
|
20
|
-
exec node "$basedir/../typescript/bin/tsc" "$@"
|
|
21
|
-
fi
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
|
-
|
|
4
|
-
case `uname` in
|
|
5
|
-
*CYGWIN*|*MINGW*|*MSYS*)
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
10
|
-
esac
|
|
11
|
-
|
|
12
|
-
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/home/runner/work/toolbox/toolbox/node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/bin/node_modules:/home/runner/work/toolbox/toolbox/node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/node_modules:/home/runner/work/toolbox/toolbox/node_modules/.pnpm/typescript@5.8.2/node_modules:/home/runner/work/toolbox/toolbox/node_modules/.pnpm/node_modules"
|
|
14
|
-
else
|
|
15
|
-
export NODE_PATH="/home/runner/work/toolbox/toolbox/node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/bin/node_modules:/home/runner/work/toolbox/toolbox/node_modules/.pnpm/typescript@5.8.2/node_modules/typescript/node_modules:/home/runner/work/toolbox/toolbox/node_modules/.pnpm/typescript@5.8.2/node_modules:/home/runner/work/toolbox/toolbox/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
|
-
fi
|
|
17
|
-
if [ -x "$basedir/node" ]; then
|
|
18
|
-
exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@"
|
|
19
|
-
else
|
|
20
|
-
exec node "$basedir/../typescript/bin/tsserver" "$@"
|
|
21
|
-
fi
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
|
-
|
|
4
|
-
case `uname` in
|
|
5
|
-
*CYGWIN*|*MINGW*|*MSYS*)
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
10
|
-
esac
|
|
11
|
-
|
|
12
|
-
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/home/runner/work/toolbox/toolbox/node_modules/.pnpm/vite@6.3.5_@types+node@24.9.1_jiti@2.6.1_lightningcss@1.30.2_terser@5.43.1_tsx@4.20.6_yaml@2.8.2/node_modules/vite/bin/node_modules:/home/runner/work/toolbox/toolbox/node_modules/.pnpm/vite@6.3.5_@types+node@24.9.1_jiti@2.6.1_lightningcss@1.30.2_terser@5.43.1_tsx@4.20.6_yaml@2.8.2/node_modules/vite/node_modules:/home/runner/work/toolbox/toolbox/node_modules/.pnpm/vite@6.3.5_@types+node@24.9.1_jiti@2.6.1_lightningcss@1.30.2_terser@5.43.1_tsx@4.20.6_yaml@2.8.2/node_modules:/home/runner/work/toolbox/toolbox/node_modules/.pnpm/node_modules"
|
|
14
|
-
else
|
|
15
|
-
export NODE_PATH="/home/runner/work/toolbox/toolbox/node_modules/.pnpm/vite@6.3.5_@types+node@24.9.1_jiti@2.6.1_lightningcss@1.30.2_terser@5.43.1_tsx@4.20.6_yaml@2.8.2/node_modules/vite/bin/node_modules:/home/runner/work/toolbox/toolbox/node_modules/.pnpm/vite@6.3.5_@types+node@24.9.1_jiti@2.6.1_lightningcss@1.30.2_terser@5.43.1_tsx@4.20.6_yaml@2.8.2/node_modules/vite/node_modules:/home/runner/work/toolbox/toolbox/node_modules/.pnpm/vite@6.3.5_@types+node@24.9.1_jiti@2.6.1_lightningcss@1.30.2_terser@5.43.1_tsx@4.20.6_yaml@2.8.2/node_modules:/home/runner/work/toolbox/toolbox/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
|
-
fi
|
|
17
|
-
if [ -x "$basedir/node" ]; then
|
|
18
|
-
exec "$basedir/node" "$basedir/../vite/bin/vite.js" "$@"
|
|
19
|
-
else
|
|
20
|
-
exec node "$basedir/../vite/bin/vite.js" "$@"
|
|
21
|
-
fi
|
package/ui/package.json
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@geekmidas/studio-ui",
|
|
3
|
-
"private": true,
|
|
4
|
-
"version": "1.0.2",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"dev": "vite",
|
|
8
|
-
"build": "tsc -b && vite build",
|
|
9
|
-
"preview": "vite preview"
|
|
10
|
-
},
|
|
11
|
-
"dependencies": {
|
|
12
|
-
"@geekmidas/ui": "workspace:*",
|
|
13
|
-
"class-variance-authority": "^0.7.1",
|
|
14
|
-
"clsx": "^2.1.1",
|
|
15
|
-
"lucide-react": "^0.511.0",
|
|
16
|
-
"react": "^19.0.0",
|
|
17
|
-
"react-dom": "^19.0.0",
|
|
18
|
-
"react-router-dom": "^7.1.1",
|
|
19
|
-
"tailwind-merge": "^3.0.0"
|
|
20
|
-
},
|
|
21
|
-
"devDependencies": {
|
|
22
|
-
"@tailwindcss/vite": "^4.0.0",
|
|
23
|
-
"@types/react": "^19.0.0",
|
|
24
|
-
"@types/react-dom": "^19.0.0",
|
|
25
|
-
"@vitejs/plugin-react": "^4.3.4",
|
|
26
|
-
"tailwindcss": "^4.0.0",
|
|
27
|
-
"typescript": "~5.8.2",
|
|
28
|
-
"vite": "^6.0.0"
|
|
29
|
-
}
|
|
30
|
-
}
|
package/ui/src/App.tsx
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { Activity, Database, Gauge, Home } from 'lucide-react';
|
|
2
|
-
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';
|
|
3
|
-
import { NavRail, NavRailItem, NavRailSection } from './components/NavRail';
|
|
4
|
-
import { StudioHeader } from './components/StudioHeader';
|
|
5
|
-
import { DashboardPage } from './pages/DashboardPage';
|
|
6
|
-
import { DatabasePage } from './pages/DatabasePage';
|
|
7
|
-
import { EndpointDetailsPage } from './pages/EndpointDetailsPage';
|
|
8
|
-
import { ExceptionsPage } from './pages/ExceptionsPage';
|
|
9
|
-
import { LogsPage } from './pages/LogsPage';
|
|
10
|
-
import { MonitoringPage } from './pages/MonitoringPage';
|
|
11
|
-
import { PerformancePage } from './pages/PerformancePage';
|
|
12
|
-
import { RequestsPage } from './pages/RequestsPage';
|
|
13
|
-
import { StudioProvider } from './providers/StudioProvider';
|
|
14
|
-
|
|
15
|
-
function AppLayout() {
|
|
16
|
-
return (
|
|
17
|
-
<div className="flex h-screen w-full bg-[#0a0a0a]">
|
|
18
|
-
{/* Navigation Rail */}
|
|
19
|
-
<NavRail>
|
|
20
|
-
<NavRailSection>
|
|
21
|
-
<NavRailItem to="/" icon={Home}>
|
|
22
|
-
Dashboard
|
|
23
|
-
</NavRailItem>
|
|
24
|
-
<NavRailItem to="/database" icon={Database}>
|
|
25
|
-
Database
|
|
26
|
-
</NavRailItem>
|
|
27
|
-
<NavRailItem
|
|
28
|
-
to="/monitoring/requests"
|
|
29
|
-
icon={Activity}
|
|
30
|
-
matchPath="/monitoring"
|
|
31
|
-
>
|
|
32
|
-
Monitoring
|
|
33
|
-
</NavRailItem>
|
|
34
|
-
<NavRailItem to="/performance" icon={Gauge}>
|
|
35
|
-
Performance
|
|
36
|
-
</NavRailItem>
|
|
37
|
-
</NavRailSection>
|
|
38
|
-
</NavRail>
|
|
39
|
-
|
|
40
|
-
{/* Main Content */}
|
|
41
|
-
<div className="flex-1 flex flex-col overflow-hidden">
|
|
42
|
-
{/* Header */}
|
|
43
|
-
<StudioHeader />
|
|
44
|
-
|
|
45
|
-
{/* Content */}
|
|
46
|
-
<main className="flex-1 overflow-auto">
|
|
47
|
-
<Routes>
|
|
48
|
-
<Route path="/" element={<DashboardPage />} />
|
|
49
|
-
<Route path="/database" element={<DatabasePage />} />
|
|
50
|
-
<Route path="/database/:table" element={<DatabasePage />} />
|
|
51
|
-
<Route path="/monitoring" element={<MonitoringPage />}>
|
|
52
|
-
<Route
|
|
53
|
-
index
|
|
54
|
-
element={<Navigate to="/monitoring/requests" replace />}
|
|
55
|
-
/>
|
|
56
|
-
<Route path="requests" element={<RequestsPage />} />
|
|
57
|
-
<Route path="requests/:id" element={<RequestsPage />} />
|
|
58
|
-
<Route path="logs" element={<LogsPage />} />
|
|
59
|
-
<Route path="exceptions" element={<ExceptionsPage />} />
|
|
60
|
-
<Route path="exceptions/:id" element={<ExceptionsPage />} />
|
|
61
|
-
</Route>
|
|
62
|
-
<Route path="/performance" element={<PerformancePage />} />
|
|
63
|
-
<Route
|
|
64
|
-
path="/performance/endpoint"
|
|
65
|
-
element={<EndpointDetailsPage />}
|
|
66
|
-
/>
|
|
67
|
-
{/* Redirects for old routes */}
|
|
68
|
-
<Route
|
|
69
|
-
path="/requests/*"
|
|
70
|
-
element={<Navigate to="/monitoring/requests" replace />}
|
|
71
|
-
/>
|
|
72
|
-
<Route
|
|
73
|
-
path="/logs"
|
|
74
|
-
element={<Navigate to="/monitoring/logs" replace />}
|
|
75
|
-
/>
|
|
76
|
-
<Route
|
|
77
|
-
path="/exceptions/*"
|
|
78
|
-
element={<Navigate to="/monitoring/exceptions" replace />}
|
|
79
|
-
/>
|
|
80
|
-
<Route
|
|
81
|
-
path="/analytics/*"
|
|
82
|
-
element={<Navigate to="/performance" replace />}
|
|
83
|
-
/>
|
|
84
|
-
<Route path="*" element={<Navigate to="/" replace />} />
|
|
85
|
-
</Routes>
|
|
86
|
-
</main>
|
|
87
|
-
</div>
|
|
88
|
-
</div>
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export function App() {
|
|
93
|
-
return (
|
|
94
|
-
<BrowserRouter>
|
|
95
|
-
<StudioProvider>
|
|
96
|
-
<AppLayout />
|
|
97
|
-
</StudioProvider>
|
|
98
|
-
</BrowserRouter>
|
|
99
|
-
);
|
|
100
|
-
}
|
package/ui/src/api.ts
DELETED
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
EndpointDetails,
|
|
3
|
-
EndpointMetrics,
|
|
4
|
-
ExceptionEntry,
|
|
5
|
-
FilterConfig,
|
|
6
|
-
LogEntry,
|
|
7
|
-
QueryResult,
|
|
8
|
-
RequestEntry,
|
|
9
|
-
RequestMetrics,
|
|
10
|
-
SchemaInfo,
|
|
11
|
-
SortConfig,
|
|
12
|
-
StatusDistribution,
|
|
13
|
-
StudioStats,
|
|
14
|
-
TableInfo,
|
|
15
|
-
TableSummary,
|
|
16
|
-
} from './types';
|
|
17
|
-
|
|
18
|
-
const BASE_URL = '/__studio';
|
|
19
|
-
|
|
20
|
-
async function fetchJson<T>(url: string): Promise<T> {
|
|
21
|
-
const res = await fetch(`${BASE_URL}${url}`);
|
|
22
|
-
if (!res.ok) {
|
|
23
|
-
throw new Error(`HTTP ${res.status}: ${res.statusText}`);
|
|
24
|
-
}
|
|
25
|
-
return res.json();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// ============================================================================
|
|
29
|
-
// Database API
|
|
30
|
-
// ============================================================================
|
|
31
|
-
|
|
32
|
-
export async function getSchema(refresh = false): Promise<SchemaInfo> {
|
|
33
|
-
const url = refresh ? '/api/schema?refresh=true' : '/api/schema';
|
|
34
|
-
return fetchJson(url);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export async function getTables(): Promise<{ tables: TableSummary[] }> {
|
|
38
|
-
return fetchJson('/api/tables');
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export async function getTableInfo(tableName: string): Promise<TableInfo> {
|
|
42
|
-
return fetchJson(`/api/tables/${encodeURIComponent(tableName)}`);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export interface QueryOptions {
|
|
46
|
-
pageSize?: number;
|
|
47
|
-
cursor?: string;
|
|
48
|
-
filters?: FilterConfig[];
|
|
49
|
-
sort?: SortConfig[];
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export async function queryTable(
|
|
53
|
-
tableName: string,
|
|
54
|
-
options: QueryOptions = {},
|
|
55
|
-
): Promise<QueryResult> {
|
|
56
|
-
const params = new URLSearchParams();
|
|
57
|
-
|
|
58
|
-
if (options.pageSize) {
|
|
59
|
-
params.set('pageSize', String(options.pageSize));
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (options.cursor) {
|
|
63
|
-
params.set('cursor', options.cursor);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (options.filters) {
|
|
67
|
-
for (const filter of options.filters) {
|
|
68
|
-
params.set(`filter[${filter.column}][${filter.operator}]`, filter.value);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (options.sort && options.sort.length > 0) {
|
|
73
|
-
const sortStr = options.sort
|
|
74
|
-
.map((s) => `${s.column}:${s.direction}`)
|
|
75
|
-
.join(',');
|
|
76
|
-
params.set('sort', sortStr);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const queryStr = params.toString();
|
|
80
|
-
const url = `/api/tables/${encodeURIComponent(tableName)}/rows${queryStr ? `?${queryStr}` : ''}`;
|
|
81
|
-
|
|
82
|
-
return fetchJson(url);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// ============================================================================
|
|
86
|
-
// Monitoring API (from Telescope)
|
|
87
|
-
// ============================================================================
|
|
88
|
-
|
|
89
|
-
export async function getStats(): Promise<StudioStats> {
|
|
90
|
-
return fetchJson('/api/stats');
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export interface MonitoringQueryOptions {
|
|
94
|
-
limit?: number;
|
|
95
|
-
search?: string;
|
|
96
|
-
method?: string;
|
|
97
|
-
status?: string;
|
|
98
|
-
level?: string;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export async function getRequests(
|
|
102
|
-
options: MonitoringQueryOptions = {},
|
|
103
|
-
): Promise<RequestEntry[]> {
|
|
104
|
-
const params = new URLSearchParams();
|
|
105
|
-
if (options.limit) params.set('limit', String(options.limit));
|
|
106
|
-
if (options.search) params.set('search', options.search);
|
|
107
|
-
if (options.method) params.set('method', options.method);
|
|
108
|
-
if (options.status) params.set('status', options.status);
|
|
109
|
-
|
|
110
|
-
const queryStr = params.toString();
|
|
111
|
-
return fetchJson(`/api/requests${queryStr ? `?${queryStr}` : ''}`);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
export async function getRequest(id: string): Promise<RequestEntry> {
|
|
115
|
-
return fetchJson(`/api/requests/${encodeURIComponent(id)}`);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export async function getExceptions(
|
|
119
|
-
options: MonitoringQueryOptions = {},
|
|
120
|
-
): Promise<ExceptionEntry[]> {
|
|
121
|
-
const params = new URLSearchParams();
|
|
122
|
-
if (options.limit) params.set('limit', String(options.limit));
|
|
123
|
-
if (options.search) params.set('search', options.search);
|
|
124
|
-
|
|
125
|
-
const queryStr = params.toString();
|
|
126
|
-
return fetchJson(`/api/exceptions${queryStr ? `?${queryStr}` : ''}`);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export async function getException(id: string): Promise<ExceptionEntry> {
|
|
130
|
-
return fetchJson(`/api/exceptions/${encodeURIComponent(id)}`);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export async function getLogs(
|
|
134
|
-
options: MonitoringQueryOptions = {},
|
|
135
|
-
): Promise<LogEntry[]> {
|
|
136
|
-
const params = new URLSearchParams();
|
|
137
|
-
if (options.limit) params.set('limit', String(options.limit));
|
|
138
|
-
if (options.search) params.set('search', options.search);
|
|
139
|
-
if (options.level) params.set('level', options.level);
|
|
140
|
-
|
|
141
|
-
const queryStr = params.toString();
|
|
142
|
-
return fetchJson(`/api/logs${queryStr ? `?${queryStr}` : ''}`);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// ============================================================================
|
|
146
|
-
// Metrics API
|
|
147
|
-
// ============================================================================
|
|
148
|
-
|
|
149
|
-
export interface MetricsQueryOptions {
|
|
150
|
-
start?: string;
|
|
151
|
-
end?: string;
|
|
152
|
-
bucketSize?: number;
|
|
153
|
-
limit?: number;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
export async function getMetrics(
|
|
157
|
-
options: MetricsQueryOptions = {},
|
|
158
|
-
): Promise<RequestMetrics> {
|
|
159
|
-
const params = new URLSearchParams();
|
|
160
|
-
if (options.start) params.set('start', options.start);
|
|
161
|
-
if (options.end) params.set('end', options.end);
|
|
162
|
-
if (options.bucketSize) params.set('bucketSize', String(options.bucketSize));
|
|
163
|
-
|
|
164
|
-
const queryStr = params.toString();
|
|
165
|
-
return fetchJson(`/api/metrics${queryStr ? `?${queryStr}` : ''}`);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
export async function getEndpointMetrics(
|
|
169
|
-
options: MetricsQueryOptions = {},
|
|
170
|
-
): Promise<EndpointMetrics[]> {
|
|
171
|
-
const params = new URLSearchParams();
|
|
172
|
-
if (options.start) params.set('start', options.start);
|
|
173
|
-
if (options.end) params.set('end', options.end);
|
|
174
|
-
if (options.limit) params.set('limit', String(options.limit));
|
|
175
|
-
|
|
176
|
-
const queryStr = params.toString();
|
|
177
|
-
return fetchJson(`/api/metrics/endpoints${queryStr ? `?${queryStr}` : ''}`);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
export async function getEndpointDetails(
|
|
181
|
-
method: string,
|
|
182
|
-
path: string,
|
|
183
|
-
options: MetricsQueryOptions = {},
|
|
184
|
-
): Promise<EndpointDetails> {
|
|
185
|
-
const params = new URLSearchParams();
|
|
186
|
-
params.set('method', method);
|
|
187
|
-
params.set('path', path);
|
|
188
|
-
if (options.start) params.set('start', options.start);
|
|
189
|
-
if (options.end) params.set('end', options.end);
|
|
190
|
-
|
|
191
|
-
return fetchJson(`/api/metrics/endpoint?${params.toString()}`);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
export async function getStatusDistribution(
|
|
195
|
-
options: MetricsQueryOptions = {},
|
|
196
|
-
): Promise<StatusDistribution> {
|
|
197
|
-
const params = new URLSearchParams();
|
|
198
|
-
if (options.start) params.set('start', options.start);
|
|
199
|
-
if (options.end) params.set('end', options.end);
|
|
200
|
-
|
|
201
|
-
const queryStr = params.toString();
|
|
202
|
-
return fetchJson(`/api/metrics/status${queryStr ? `?${queryStr}` : ''}`);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// ============================================================================
|
|
206
|
-
// WebSocket
|
|
207
|
-
// ============================================================================
|
|
208
|
-
|
|
209
|
-
export function createWebSocket(): WebSocket {
|
|
210
|
-
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
211
|
-
const wsUrl = `${protocol}//${window.location.host}${BASE_URL}/ws`;
|
|
212
|
-
return new WebSocket(wsUrl);
|
|
213
|
-
}
|