diff --git a/packages/core/src/common/vars.ts b/packages/core/src/common/vars.ts index f4c19c16e6..1cb0271ab2 100644 --- a/packages/core/src/common/vars.ts +++ b/packages/core/src/common/vars.ts @@ -6,7 +6,6 @@ // App's common configuration for any process (main, renderer, build pipeline, etc.) import type { ThemeId } from "../renderer/themes/lens-theme"; -export const publicPath = "/build/" as string; export const defaultThemeId: ThemeId = "lens-dark"; export const defaultFontSize = 12; export const defaultTerminalFontFamily = "RobotoMono"; diff --git a/packages/core/src/main/router/router-content-types.ts b/packages/core/src/main/router/router-content-types.ts index 4106e6b750..1bc00380b1 100644 --- a/packages/core/src/main/router/router-content-types.ts +++ b/packages/core/src/main/router/router-content-types.ts @@ -5,9 +5,9 @@ import type { LensApiResult } from "./route"; export interface LensApiResultContentType { - resultMapper: (result: LensApiResult) => ({ + resultMapper: (result: LensApiResult) => ({ statusCode: number; - content: any; + content: unknown; headers: Record; }); } @@ -22,9 +22,13 @@ const resultMapperFor = export type SupportedFileExtension = "json" | "txt" | "html" | "css" | "gif" | "jpg" | "png" | "svg" | "js" | "woff2" | "ttf"; -export const contentTypes: Record = { +export interface ContentTypes extends Record { + [key: string]: LensApiResultContentType | undefined; +} + +export const contentTypes: ContentTypes = { json: { - resultMapper: (result) => { + resultMapper: (result: LensApiResult) => { const resultMapper = resultMapperFor("application/json"); const mappedResult = resultMapper(result); diff --git a/packages/core/src/main/routes/files/development.injectable.ts b/packages/core/src/main/routes/files/development.injectable.ts index 3251a9937b..98c95c7928 100644 --- a/packages/core/src/main/routes/files/development.injectable.ts +++ b/packages/core/src/main/routes/files/development.injectable.ts @@ -4,8 +4,8 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import httpProxy from "http-proxy"; +import path from "path"; import { webpackDevServerPort } from "../../../../webpack/vars"; -import { publicPath } from "../../../common/vars"; import type { LensApiRequest, RouteResponse } from "../../router/route"; const devStaticFileRouteHandlerInjectable = getInjectable({ @@ -14,10 +14,14 @@ const devStaticFileRouteHandlerInjectable = getInjectable({ const proxy = httpProxy.createProxy(); const proxyTarget = `http://127.0.0.1:${webpackDevServerPort}`; - return async ({ raw: { req, res }}: LensApiRequest<"/{path*}">): Promise> => { - if (req.url === "/" || !req.url || !req.url.startsWith(publicPath)) { - req.url = `${publicPath}/index.html`; - } + return async ({ raw: { req, res }, params }: LensApiRequest<"/{path*}">): Promise> => { + const filePath = (!params.path || params.path === "/") + ? "/build/index.html" + : path.posix.extname(params.path) + ? params.path + : "/build/index.html"; + + req.url = filePath; proxy.web(req, res, { target: proxyTarget }); diff --git a/packages/core/src/main/routes/files/production.injectable.ts b/packages/core/src/main/routes/files/production.injectable.ts index 1b9376215a..408f3e98ea 100644 --- a/packages/core/src/main/routes/files/production.injectable.ts +++ b/packages/core/src/main/routes/files/production.injectable.ts @@ -8,10 +8,8 @@ import joinPathsInjectable from "../../../common/path/join-paths.injectable"; import staticFilesDirectoryInjectable from "../../../common/vars/static-files-directory.injectable"; import type { LensApiRequest } from "../../router/route"; import path from "path"; -import type { SupportedFileExtension } from "../../router/router-content-types"; import { contentTypes } from "../../router/router-content-types"; -import { loggerInjectionToken } from "@k8slens/logger"; -import { publicPath } from "../../../common/vars"; +import { prefixedLoggerInjectable } from "@k8slens/logger"; const prodStaticFileRouteHandlerInjectable = getInjectable({ id: "prod-static-file-route-handler", @@ -19,39 +17,31 @@ const prodStaticFileRouteHandlerInjectable = getInjectable({ const readFileBuffer = di.inject(readFileBufferInjectable); const joinPaths = di.inject(joinPathsInjectable); const staticFilesDirectory = di.inject(staticFilesDirectoryInjectable); - const logger = di.inject(loggerInjectionToken); + const logger = di.inject(prefixedLoggerInjectable, "FILE-ROUTE"); return async ({ params }: LensApiRequest<"/{path*}">) => { - let filePath = params.path; + const filePath = (!params.path || params.path === "/") + ? "/build/index.html" + : path.posix.extname(params.path) + ? params.path + : "/build/index.html"; + const assetFilePath = joinPaths(staticFilesDirectory, filePath); - for (let retryCount = 0; retryCount < 5; retryCount += 1) { - const assetFilePath = joinPaths(staticFilesDirectory, filePath); - - if (!assetFilePath.startsWith(staticFilesDirectory)) { - return { statusCode: 404 }; - } - - try { - const fileExtension = path - .extname(assetFilePath) - .slice(1) as SupportedFileExtension; - - const contentType = contentTypes[fileExtension] || contentTypes.txt; - - return { response: await readFileBuffer(assetFilePath), contentType }; - } catch (err) { - if (retryCount > 5) { - logger.error("handleStaticFile:", String(err)); - - return { statusCode: 404 }; - } - - filePath = `${publicPath}/index.html`; - } + if (!assetFilePath.startsWith(staticFilesDirectory)) { + return { statusCode: 404 }; } - return { statusCode: 404 }; + const fileExtension = path.extname(assetFilePath).slice(1); + const contentType = contentTypes[fileExtension] || contentTypes.txt; + + try { + return { response: await readFileBuffer(assetFilePath), contentType }; + } catch (err) { + logger.error(`failed to find file "${filePath}"`, err); + + return { statusCode: 404 }; + } }; }, }); diff --git a/packages/core/webpack/vars.ts b/packages/core/webpack/vars.ts index b0245dedae..2119137400 100644 --- a/packages/core/webpack/vars.ts +++ b/packages/core/webpack/vars.ts @@ -12,13 +12,11 @@ export const mainDir = path.join(process.cwd(), "src", "main"); export const buildDir = path.join(process.cwd(), "static", "build"); export const extensionEntry = path.join(process.cwd(), "src", "extensions", "extension-api.ts"); export const extensionOutDir = path.join(process.cwd(), "packages", "extensions", "dist"); -export const assetsFolderName = "assets"; export const rendererDir = path.join(process.cwd(), "src", "renderer"); export const appName = isDevelopment ? `${packageInfo.productName}Dev` : packageInfo.productName; export const htmlTemplate = path.resolve(rendererDir, "template.html"); -export const publicPath = "/build/"; export const sassCommonVars = path.resolve(rendererDir, "components/vars.scss"); export const webpackDevServerPort = Number(process.env.WEBPACK_DEV_SERVER_PORT) || 9191;