mirror of https://github.com/buster-so/buster.git
create basic hello world screenshot
This commit is contained in:
parent
1c76851c2e
commit
0b265b6a9d
|
@ -0,0 +1,5 @@
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
export const GetScreenshotRequestSharedSchema = z.object({});
|
||||||
|
|
||||||
|
export type GetScreenshotRequestShared = z.infer<typeof GetScreenshotRequestSharedSchema>;
|
|
@ -18,6 +18,7 @@ import { Route as AuthRouteImport } from './routes/auth'
|
||||||
import { Route as AppRouteImport } from './routes/app'
|
import { Route as AppRouteImport } from './routes/app'
|
||||||
import { Route as IndexRouteImport } from './routes/index'
|
import { Route as IndexRouteImport } from './routes/index'
|
||||||
import { Route as AppIndexRouteImport } from './routes/app/index'
|
import { Route as AppIndexRouteImport } from './routes/app/index'
|
||||||
|
import { Route as ScreenshotsHelloWorldRouteImport } from './routes/screenshots/hello-world'
|
||||||
import { Route as InfoGettingStartedRouteImport } from './routes/info/getting-started'
|
import { Route as InfoGettingStartedRouteImport } from './routes/info/getting-started'
|
||||||
import { Route as AuthResetPasswordRouteImport } from './routes/auth.reset-password'
|
import { Route as AuthResetPasswordRouteImport } from './routes/auth.reset-password'
|
||||||
import { Route as AuthLogoutRouteImport } from './routes/auth.logout'
|
import { Route as AuthLogoutRouteImport } from './routes/auth.logout'
|
||||||
|
@ -154,6 +155,7 @@ import { Route as AppAppAssetChatsChatIdDashboardsDashboardIdMetricsMetricIdCont
|
||||||
import { Route as AppAppAssetChatsChatIdDashboardsDashboardIdMetricsMetricIdContentChartRouteImport } from './routes/app/_app/_asset/chats.$chatId/dashboards.$dashboardId/metrics.$metricId/_content/chart'
|
import { Route as AppAppAssetChatsChatIdDashboardsDashboardIdMetricsMetricIdContentChartRouteImport } from './routes/app/_app/_asset/chats.$chatId/dashboards.$dashboardId/metrics.$metricId/_content/chart'
|
||||||
import { ServerRoute as AuthConfirmServerRouteImport } from './routes/auth.confirm'
|
import { ServerRoute as AuthConfirmServerRouteImport } from './routes/auth.confirm'
|
||||||
import { ServerRoute as AuthCallbackServerRouteImport } from './routes/auth.callback'
|
import { ServerRoute as AuthCallbackServerRouteImport } from './routes/auth.callback'
|
||||||
|
import { ServerRoute as ScreenshotsMetricsMetricIdServerRouteImport } from './routes/screenshots/metrics.$metricId'
|
||||||
|
|
||||||
const EmbedChatChatIdReportsReportIdRouteImport = createFileRoute(
|
const EmbedChatChatIdReportsReportIdRouteImport = createFileRoute(
|
||||||
'/embed/chat/$chatId/reports/$reportId',
|
'/embed/chat/$chatId/reports/$reportId',
|
||||||
|
@ -235,6 +237,11 @@ const AppIndexRoute = AppIndexRouteImport.update({
|
||||||
path: '/',
|
path: '/',
|
||||||
getParentRoute: () => AppRoute,
|
getParentRoute: () => AppRoute,
|
||||||
} as any)
|
} as any)
|
||||||
|
const ScreenshotsHelloWorldRoute = ScreenshotsHelloWorldRouteImport.update({
|
||||||
|
id: '/screenshots/hello-world',
|
||||||
|
path: '/screenshots/hello-world',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
const InfoGettingStartedRoute = InfoGettingStartedRouteImport.update({
|
const InfoGettingStartedRoute = InfoGettingStartedRouteImport.update({
|
||||||
id: '/info/getting-started',
|
id: '/info/getting-started',
|
||||||
path: '/info/getting-started',
|
path: '/info/getting-started',
|
||||||
|
@ -1180,6 +1187,12 @@ const AuthCallbackServerRoute = AuthCallbackServerRouteImport.update({
|
||||||
path: '/auth/callback',
|
path: '/auth/callback',
|
||||||
getParentRoute: () => rootServerRouteImport,
|
getParentRoute: () => rootServerRouteImport,
|
||||||
} as any)
|
} as any)
|
||||||
|
const ScreenshotsMetricsMetricIdServerRoute =
|
||||||
|
ScreenshotsMetricsMetricIdServerRouteImport.update({
|
||||||
|
id: '/screenshots/metrics/$metricId',
|
||||||
|
path: '/screenshots/metrics/$metricId',
|
||||||
|
getParentRoute: () => rootServerRouteImport,
|
||||||
|
} as any)
|
||||||
|
|
||||||
export interface FileRoutesByFullPath {
|
export interface FileRoutesByFullPath {
|
||||||
'/': typeof IndexRoute
|
'/': typeof IndexRoute
|
||||||
|
@ -1191,6 +1204,7 @@ export interface FileRoutesByFullPath {
|
||||||
'/auth/logout': typeof AuthLogoutRoute
|
'/auth/logout': typeof AuthLogoutRoute
|
||||||
'/auth/reset-password': typeof AuthResetPasswordRoute
|
'/auth/reset-password': typeof AuthResetPasswordRoute
|
||||||
'/info/getting-started': typeof InfoGettingStartedRoute
|
'/info/getting-started': typeof InfoGettingStartedRoute
|
||||||
|
'/screenshots/hello-world': typeof ScreenshotsHelloWorldRoute
|
||||||
'/app/': typeof AppIndexRoute
|
'/app/': typeof AppIndexRoute
|
||||||
'/app/home': typeof AppAppHomeRouteWithChildren
|
'/app/home': typeof AppAppHomeRouteWithChildren
|
||||||
'/app/new-user': typeof AppAppNewUserRouteWithChildren
|
'/app/new-user': typeof AppAppNewUserRouteWithChildren
|
||||||
|
@ -1327,6 +1341,7 @@ export interface FileRoutesByTo {
|
||||||
'/auth/logout': typeof AuthLogoutRoute
|
'/auth/logout': typeof AuthLogoutRoute
|
||||||
'/auth/reset-password': typeof AuthResetPasswordRoute
|
'/auth/reset-password': typeof AuthResetPasswordRoute
|
||||||
'/info/getting-started': typeof InfoGettingStartedRoute
|
'/info/getting-started': typeof InfoGettingStartedRoute
|
||||||
|
'/screenshots/hello-world': typeof ScreenshotsHelloWorldRoute
|
||||||
'/app/test-pagination': typeof AppAppTestPaginationRoute
|
'/app/test-pagination': typeof AppAppTestPaginationRoute
|
||||||
'/embed/dashboard/$dashboardId': typeof EmbedDashboardDashboardIdRoute
|
'/embed/dashboard/$dashboardId': typeof EmbedDashboardDashboardIdRoute
|
||||||
'/embed/metric/$metricId': typeof EmbedMetricMetricIdRoute
|
'/embed/metric/$metricId': typeof EmbedMetricMetricIdRoute
|
||||||
|
@ -1440,6 +1455,7 @@ export interface FileRoutesById {
|
||||||
'/auth/logout': typeof AuthLogoutRoute
|
'/auth/logout': typeof AuthLogoutRoute
|
||||||
'/auth/reset-password': typeof AuthResetPasswordRoute
|
'/auth/reset-password': typeof AuthResetPasswordRoute
|
||||||
'/info/getting-started': typeof InfoGettingStartedRoute
|
'/info/getting-started': typeof InfoGettingStartedRoute
|
||||||
|
'/screenshots/hello-world': typeof ScreenshotsHelloWorldRoute
|
||||||
'/app/': typeof AppIndexRoute
|
'/app/': typeof AppIndexRoute
|
||||||
'/app/_app/_asset': typeof AppAppAssetRouteWithChildren
|
'/app/_app/_asset': typeof AppAppAssetRouteWithChildren
|
||||||
'/app/_app/home': typeof AppAppHomeRouteWithChildren
|
'/app/_app/home': typeof AppAppHomeRouteWithChildren
|
||||||
|
@ -1597,6 +1613,7 @@ export interface FileRouteTypes {
|
||||||
| '/auth/logout'
|
| '/auth/logout'
|
||||||
| '/auth/reset-password'
|
| '/auth/reset-password'
|
||||||
| '/info/getting-started'
|
| '/info/getting-started'
|
||||||
|
| '/screenshots/hello-world'
|
||||||
| '/app/'
|
| '/app/'
|
||||||
| '/app/home'
|
| '/app/home'
|
||||||
| '/app/new-user'
|
| '/app/new-user'
|
||||||
|
@ -1733,6 +1750,7 @@ export interface FileRouteTypes {
|
||||||
| '/auth/logout'
|
| '/auth/logout'
|
||||||
| '/auth/reset-password'
|
| '/auth/reset-password'
|
||||||
| '/info/getting-started'
|
| '/info/getting-started'
|
||||||
|
| '/screenshots/hello-world'
|
||||||
| '/app/test-pagination'
|
| '/app/test-pagination'
|
||||||
| '/embed/dashboard/$dashboardId'
|
| '/embed/dashboard/$dashboardId'
|
||||||
| '/embed/metric/$metricId'
|
| '/embed/metric/$metricId'
|
||||||
|
@ -1845,6 +1863,7 @@ export interface FileRouteTypes {
|
||||||
| '/auth/logout'
|
| '/auth/logout'
|
||||||
| '/auth/reset-password'
|
| '/auth/reset-password'
|
||||||
| '/info/getting-started'
|
| '/info/getting-started'
|
||||||
|
| '/screenshots/hello-world'
|
||||||
| '/app/'
|
| '/app/'
|
||||||
| '/app/_app/_asset'
|
| '/app/_app/_asset'
|
||||||
| '/app/_app/home'
|
| '/app/_app/home'
|
||||||
|
@ -1998,31 +2017,43 @@ export interface RootRouteChildren {
|
||||||
EmbedRoute: typeof EmbedRouteWithChildren
|
EmbedRoute: typeof EmbedRouteWithChildren
|
||||||
HealthcheckRoute: typeof HealthcheckRoute
|
HealthcheckRoute: typeof HealthcheckRoute
|
||||||
InfoGettingStartedRoute: typeof InfoGettingStartedRoute
|
InfoGettingStartedRoute: typeof InfoGettingStartedRoute
|
||||||
|
ScreenshotsHelloWorldRoute: typeof ScreenshotsHelloWorldRoute
|
||||||
}
|
}
|
||||||
export interface FileServerRoutesByFullPath {
|
export interface FileServerRoutesByFullPath {
|
||||||
'/auth/callback': typeof AuthCallbackServerRoute
|
'/auth/callback': typeof AuthCallbackServerRoute
|
||||||
'/auth/confirm': typeof AuthConfirmServerRoute
|
'/auth/confirm': typeof AuthConfirmServerRoute
|
||||||
|
'/screenshots/metrics/$metricId': typeof ScreenshotsMetricsMetricIdServerRoute
|
||||||
}
|
}
|
||||||
export interface FileServerRoutesByTo {
|
export interface FileServerRoutesByTo {
|
||||||
'/auth/callback': typeof AuthCallbackServerRoute
|
'/auth/callback': typeof AuthCallbackServerRoute
|
||||||
'/auth/confirm': typeof AuthConfirmServerRoute
|
'/auth/confirm': typeof AuthConfirmServerRoute
|
||||||
|
'/screenshots/metrics/$metricId': typeof ScreenshotsMetricsMetricIdServerRoute
|
||||||
}
|
}
|
||||||
export interface FileServerRoutesById {
|
export interface FileServerRoutesById {
|
||||||
__root__: typeof rootServerRouteImport
|
__root__: typeof rootServerRouteImport
|
||||||
'/auth/callback': typeof AuthCallbackServerRoute
|
'/auth/callback': typeof AuthCallbackServerRoute
|
||||||
'/auth/confirm': typeof AuthConfirmServerRoute
|
'/auth/confirm': typeof AuthConfirmServerRoute
|
||||||
|
'/screenshots/metrics/$metricId': typeof ScreenshotsMetricsMetricIdServerRoute
|
||||||
}
|
}
|
||||||
export interface FileServerRouteTypes {
|
export interface FileServerRouteTypes {
|
||||||
fileServerRoutesByFullPath: FileServerRoutesByFullPath
|
fileServerRoutesByFullPath: FileServerRoutesByFullPath
|
||||||
fullPaths: '/auth/callback' | '/auth/confirm'
|
fullPaths:
|
||||||
|
| '/auth/callback'
|
||||||
|
| '/auth/confirm'
|
||||||
|
| '/screenshots/metrics/$metricId'
|
||||||
fileServerRoutesByTo: FileServerRoutesByTo
|
fileServerRoutesByTo: FileServerRoutesByTo
|
||||||
to: '/auth/callback' | '/auth/confirm'
|
to: '/auth/callback' | '/auth/confirm' | '/screenshots/metrics/$metricId'
|
||||||
id: '__root__' | '/auth/callback' | '/auth/confirm'
|
id:
|
||||||
|
| '__root__'
|
||||||
|
| '/auth/callback'
|
||||||
|
| '/auth/confirm'
|
||||||
|
| '/screenshots/metrics/$metricId'
|
||||||
fileServerRoutesById: FileServerRoutesById
|
fileServerRoutesById: FileServerRoutesById
|
||||||
}
|
}
|
||||||
export interface RootServerRouteChildren {
|
export interface RootServerRouteChildren {
|
||||||
AuthCallbackServerRoute: typeof AuthCallbackServerRoute
|
AuthCallbackServerRoute: typeof AuthCallbackServerRoute
|
||||||
AuthConfirmServerRoute: typeof AuthConfirmServerRoute
|
AuthConfirmServerRoute: typeof AuthConfirmServerRoute
|
||||||
|
ScreenshotsMetricsMetricIdServerRoute: typeof ScreenshotsMetricsMetricIdServerRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module '@tanstack/react-router' {
|
declare module '@tanstack/react-router' {
|
||||||
|
@ -2069,6 +2100,13 @@ declare module '@tanstack/react-router' {
|
||||||
preLoaderRoute: typeof AppIndexRouteImport
|
preLoaderRoute: typeof AppIndexRouteImport
|
||||||
parentRoute: typeof AppRoute
|
parentRoute: typeof AppRoute
|
||||||
}
|
}
|
||||||
|
'/screenshots/hello-world': {
|
||||||
|
id: '/screenshots/hello-world'
|
||||||
|
path: '/screenshots/hello-world'
|
||||||
|
fullPath: '/screenshots/hello-world'
|
||||||
|
preLoaderRoute: typeof ScreenshotsHelloWorldRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
'/info/getting-started': {
|
'/info/getting-started': {
|
||||||
id: '/info/getting-started'
|
id: '/info/getting-started'
|
||||||
path: '/info/getting-started'
|
path: '/info/getting-started'
|
||||||
|
@ -3130,6 +3168,13 @@ declare module '@tanstack/react-start/server' {
|
||||||
preLoaderRoute: typeof AuthCallbackServerRouteImport
|
preLoaderRoute: typeof AuthCallbackServerRouteImport
|
||||||
parentRoute: typeof rootServerRouteImport
|
parentRoute: typeof rootServerRouteImport
|
||||||
}
|
}
|
||||||
|
'/screenshots/metrics/$metricId': {
|
||||||
|
id: '/screenshots/metrics/$metricId'
|
||||||
|
path: '/screenshots/metrics/$metricId'
|
||||||
|
fullPath: '/screenshots/metrics/$metricId'
|
||||||
|
preLoaderRoute: typeof ScreenshotsMetricsMetricIdServerRouteImport
|
||||||
|
parentRoute: typeof rootServerRouteImport
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4140,6 +4185,7 @@ const rootRouteChildren: RootRouteChildren = {
|
||||||
EmbedRoute: EmbedRouteWithChildren,
|
EmbedRoute: EmbedRouteWithChildren,
|
||||||
HealthcheckRoute: HealthcheckRoute,
|
HealthcheckRoute: HealthcheckRoute,
|
||||||
InfoGettingStartedRoute: InfoGettingStartedRoute,
|
InfoGettingStartedRoute: InfoGettingStartedRoute,
|
||||||
|
ScreenshotsHelloWorldRoute: ScreenshotsHelloWorldRoute,
|
||||||
}
|
}
|
||||||
export const routeTree = rootRouteImport
|
export const routeTree = rootRouteImport
|
||||||
._addFileChildren(rootRouteChildren)
|
._addFileChildren(rootRouteChildren)
|
||||||
|
@ -4147,6 +4193,7 @@ export const routeTree = rootRouteImport
|
||||||
const rootServerRouteChildren: RootServerRouteChildren = {
|
const rootServerRouteChildren: RootServerRouteChildren = {
|
||||||
AuthCallbackServerRoute: AuthCallbackServerRoute,
|
AuthCallbackServerRoute: AuthCallbackServerRoute,
|
||||||
AuthConfirmServerRoute: AuthConfirmServerRoute,
|
AuthConfirmServerRoute: AuthConfirmServerRoute,
|
||||||
|
ScreenshotsMetricsMetricIdServerRoute: ScreenshotsMetricsMetricIdServerRoute,
|
||||||
}
|
}
|
||||||
export const serverRouteTree = rootServerRouteImport
|
export const serverRouteTree = rootServerRouteImport
|
||||||
._addFileChildren(rootServerRouteChildren)
|
._addFileChildren(rootServerRouteChildren)
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { createFileRoute } from '@tanstack/react-router';
|
||||||
|
import { useMount } from '@/hooks/useMount';
|
||||||
|
|
||||||
|
export const Route = createFileRoute('/screenshots/hello-world')({
|
||||||
|
component: RouteComponent,
|
||||||
|
});
|
||||||
|
|
||||||
|
function RouteComponent() {
|
||||||
|
useMount(() => {
|
||||||
|
// getMetricScreenshot({
|
||||||
|
// data: {
|
||||||
|
// metricId: '123',
|
||||||
|
// },
|
||||||
|
// }).then((res) => {
|
||||||
|
// console.log(res);
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-10 flex flex-col h-full border-red-500 border-10 items-center justify-center bg-blue-100 text-2xl text-blue-500">
|
||||||
|
Hello "/screenshot/hello-world"!
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
import { createServerFileRoute } from '@tanstack/react-start/server';
|
||||||
|
import { chromium } from 'playwright';
|
||||||
|
import { z } from 'zod';
|
||||||
|
import { Route as HelloWorldRoute } from './hello-world';
|
||||||
|
|
||||||
|
const GetMetricScreenshotParamsSchema = z.object({
|
||||||
|
metricId: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const GetMetricScreenshotQuerySchema = z.object({
|
||||||
|
version_number: z.coerce.number().min(1).optional(),
|
||||||
|
width: z.coerce.number().min(100).max(3840).default(800),
|
||||||
|
height: z.coerce.number().min(100).max(2160).default(450),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ServerRoute = createServerFileRoute('/screenshots/metrics/$metricId').methods({
|
||||||
|
GET: async ({ request, params }) => {
|
||||||
|
console.time('capture screenshot');
|
||||||
|
const { metricId } = GetMetricScreenshotParamsSchema.parse(params);
|
||||||
|
const { version_number, width, height } = GetMetricScreenshotQuerySchema.parse(
|
||||||
|
Object.fromEntries(new URL(request.url).searchParams)
|
||||||
|
);
|
||||||
|
const origin = new URL(request.url).origin;
|
||||||
|
console.timeLog('capture screenshot', 'params parsed');
|
||||||
|
const browser = await chromium.launch();
|
||||||
|
console.timeLog('capture screenshot', 'browser launched');
|
||||||
|
try {
|
||||||
|
const page = await browser.newPage({
|
||||||
|
viewport: { width, height },
|
||||||
|
});
|
||||||
|
console.timeLog('capture screenshot', 'page created');
|
||||||
|
|
||||||
|
const fullPath = `${origin}${HelloWorldRoute.fullPath}`;
|
||||||
|
await page.goto(fullPath, { waitUntil: 'networkidle' });
|
||||||
|
console.timeLog('capture screenshot', 'page navigated');
|
||||||
|
const screenshotBuffer = await page.screenshot({
|
||||||
|
type: 'png',
|
||||||
|
});
|
||||||
|
console.timeLog('capture screenshot', 'screenshot taken');
|
||||||
|
console.timeEnd('capture screenshot');
|
||||||
|
return new Response(new Uint8Array(screenshotBuffer), {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'image/png',
|
||||||
|
'Content-Length': screenshotBuffer.length.toString(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
// console.error('Error capturing metric screenshot', error);
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
message: 'Failed to capture screenshot',
|
||||||
|
}),
|
||||||
|
{ status: 500, headers: { 'Content-Type': 'application/json' } }
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
await browser.close();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
Loading…
Reference in New Issue