@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.
Files changed (50) hide show
  1. package/package.json +8 -5
  2. package/CHANGELOG.md +0 -82
  3. package/src/Studio.ts +0 -367
  4. package/src/__tests__/Studio.spec.ts +0 -447
  5. package/src/data/DataBrowser.ts +0 -170
  6. package/src/data/__tests__/DataBrowser.integration.spec.ts +0 -418
  7. package/src/data/__tests__/filtering.integration.spec.ts +0 -741
  8. package/src/data/__tests__/introspection.integration.spec.ts +0 -352
  9. package/src/data/__tests__/pagination.spec.ts +0 -123
  10. package/src/data/filtering.ts +0 -191
  11. package/src/data/index.ts +0 -1
  12. package/src/data/introspection.ts +0 -220
  13. package/src/data/pagination.ts +0 -33
  14. package/src/index.ts +0 -29
  15. package/src/server/__tests__/hono.integration.spec.ts +0 -619
  16. package/src/server/hono.ts +0 -427
  17. package/src/types.ts +0 -278
  18. package/src/ui-assets.ts +0 -37
  19. package/tsconfig.json +0 -9
  20. package/tsdown.config.ts +0 -13
  21. package/ui/CHANGELOG.md +0 -26
  22. package/ui/index.html +0 -12
  23. package/ui/node_modules/.bin/tsc +0 -21
  24. package/ui/node_modules/.bin/tsserver +0 -21
  25. package/ui/node_modules/.bin/vite +0 -21
  26. package/ui/package.json +0 -30
  27. package/ui/src/App.tsx +0 -100
  28. package/ui/src/api.ts +0 -213
  29. package/ui/src/components/FilterPanel.tsx +0 -213
  30. package/ui/src/components/NavRail.tsx +0 -183
  31. package/ui/src/components/RowDetail.tsx +0 -119
  32. package/ui/src/components/StudioHeader.tsx +0 -109
  33. package/ui/src/components/TableList.tsx +0 -58
  34. package/ui/src/components/TableView.tsx +0 -564
  35. package/ui/src/main.tsx +0 -10
  36. package/ui/src/pages/DashboardPage.tsx +0 -500
  37. package/ui/src/pages/DatabasePage.tsx +0 -226
  38. package/ui/src/pages/EndpointDetailsPage.tsx +0 -288
  39. package/ui/src/pages/ExceptionsPage.tsx +0 -268
  40. package/ui/src/pages/LogsPage.tsx +0 -228
  41. package/ui/src/pages/MonitoringPage.tsx +0 -46
  42. package/ui/src/pages/PerformancePage.tsx +0 -307
  43. package/ui/src/pages/RequestsPage.tsx +0 -379
  44. package/ui/src/providers/StudioProvider.tsx +0 -194
  45. package/ui/src/styles.css +0 -105
  46. package/ui/src/types.ts +0 -174
  47. package/ui/src/vite-env.d.ts +0 -1
  48. package/ui/tsconfig.json +0 -21
  49. package/ui/tsconfig.tsbuildinfo +0 -1
  50. package/ui/vite.config.ts +0 -12
package/tsconfig.json DELETED
@@ -1,9 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "outDir": "./dist",
5
- "rootDir": "./src",
6
- "composite": true
7
- },
8
- "include": ["src/**/*"]
9
- }
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>
@@ -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
- }