From 7804a3495113a6276e1e703404c32cfc13314248 Mon Sep 17 00:00:00 2001 From: Benjamin Toby Date: Thu, 19 Mar 2026 06:33:47 +0100 Subject: [PATCH] Add url to server response --- dist/functions/server/server-params-gen.js | 46 ++++++++++++---- .../server/web-pages/grab-page-component.js | 26 +++++++-- package.json | 2 +- src/functions/server/server-params-gen.ts | 53 ++++++++++++++----- .../server/web-pages/grab-page-component.tsx | 27 ++++++++-- src/types/index.ts | 3 ++ 6 files changed, 126 insertions(+), 31 deletions(-) diff --git a/dist/functions/server/server-params-gen.js b/dist/functions/server/server-params-gen.js index f51eaf9..f1739ee 100644 --- a/dist/functions/server/server-params-gen.js +++ b/dist/functions/server/server-params-gen.js @@ -6,6 +6,7 @@ import handleRoutes from "./handle-routes"; import isDevelopment from "../../utils/is-development"; import grabConstants from "../../utils/grab-constants"; import { AppData } from "../../data/app-data"; +import { existsSync } from "fs"; export default async function (params) { const port = grabAppPort(); const { PUBLIC_DIR } = grabDirNames(); @@ -61,18 +62,43 @@ export default async function (params) { return await handleRoutes({ req, server }); } if (url.pathname.startsWith("/public/")) { - const file = Bun.file(path.join(PUBLIC_DIR, url.pathname.replace(/^\/public/, ""))); - let res_opts = {}; - if (!is_dev && url.pathname.match(/__bunext/)) { - res_opts.headers = { - "Cache-Control": `public, max-age=${AppData["BunextStaticFilesCacheExpiry"]}, must-revalidate`, - }; + try { + const file_path = path.join(PUBLIC_DIR, url.pathname.replace(/^\/public/, "")); + if (!existsSync(file_path)) { + return new Response(`Public File Doesn't Exist`, { + status: 404, + }); + } + const file = Bun.file(file_path); + let res_opts = {}; + if (!is_dev && url.pathname.match(/__bunext/)) { + res_opts.headers = { + "Cache-Control": `public, max-age=${AppData["BunextStaticFilesCacheExpiry"]}, must-revalidate`, + }; + } + return new Response(file, res_opts); + } + catch (error) { + return new Response(`Public File Not Found`, { + status: 404, + }); } - return new Response(file, res_opts); } - if (url.pathname.startsWith("/favicon.")) { - const file = Bun.file(path.join(PUBLIC_DIR, url.pathname)); - return new Response(file); + // if (url.pathname.startsWith("/favicon.") ) { + if (url.pathname.match(/\..*$/)) { + try { + const file_path = path.join(PUBLIC_DIR, url.pathname); + if (!existsSync(file_path)) { + return new Response(`File Doesn't Exist`, { + status: 404, + }); + } + const file = Bun.file(file_path); + return new Response(file); + } + catch (error) { + return new Response(`File Not Found`, { status: 404 }); + } } return await handleWebPages({ req }); } diff --git a/dist/functions/server/web-pages/grab-page-component.js b/dist/functions/server/web-pages/grab-page-component.js index 9a29a83..9cb54f6 100644 --- a/dist/functions/server/web-pages/grab-page-component.js +++ b/dist/functions/server/web-pages/grab-page-component.js @@ -5,6 +5,7 @@ import AppNames from "../../../utils/grab-app-names"; import { existsSync } from "fs"; import grabPageErrorComponent from "./grab-page-error-component"; import grabPageBundledReactComponent from "./grab-page-bundled-react-component"; +import _ from "lodash"; class NotFoundError extends Error { } export default async function grabPageComponent({ req, file_path: passed_file_path, }) { @@ -50,21 +51,40 @@ export default async function grabPageComponent({ req, file_path: passed_file_pa const now = Date.now(); const module = await import(file_path); const serverRes = await (async () => { + const default_props = { + url: { + ..._.pick(url, [ + "host", + "hostname", + "pathname", + "origin", + "port", + "search", + "searchParams", + "hash", + "href", + "password", + "protocol", + "username", + ]), + }, + query: match?.query, + }; try { if (routeParams) { const serverData = await module["server"]?.(routeParams); return { ...serverData, - query: match?.query, + ...default_props, }; } return { - query: match?.query, + ...default_props, }; } catch (error) { return { - query: match?.query, + ...default_props, }; } })(); diff --git a/package.json b/package.json index 38e28b2..98fda44 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@moduletrace/bunext", "module": "index.ts", "type": "module", - "version": "1.0.4", + "version": "1.0.5", "bin": { "bunext": "dist/index.js" }, diff --git a/src/functions/server/server-params-gen.ts b/src/functions/server/server-params-gen.ts index a24b34f..b4d68a5 100644 --- a/src/functions/server/server-params-gen.ts +++ b/src/functions/server/server-params-gen.ts @@ -7,6 +7,7 @@ import handleRoutes from "./handle-routes"; import isDevelopment from "../../utils/is-development"; import grabConstants from "../../utils/grab-constants"; import { AppData } from "../../data/app-data"; +import { existsSync } from "fs"; type Params = { dev?: boolean; @@ -91,28 +92,52 @@ export default async function (params?: Params): Promise { } if (url.pathname.startsWith("/public/")) { - const file = Bun.file( - path.join( + try { + const file_path = path.join( PUBLIC_DIR, url.pathname.replace(/^\/public/, ""), - ), - ); + ); - let res_opts: ResponseInit = {}; + if (!existsSync(file_path)) { + return new Response(`Public File Doesn't Exist`, { + status: 404, + }); + } - if (!is_dev && url.pathname.match(/__bunext/)) { - res_opts.headers = { - "Cache-Control": `public, max-age=${AppData["BunextStaticFilesCacheExpiry"]}, must-revalidate`, - }; + const file = Bun.file(file_path); + + let res_opts: ResponseInit = {}; + + if (!is_dev && url.pathname.match(/__bunext/)) { + res_opts.headers = { + "Cache-Control": `public, max-age=${AppData["BunextStaticFilesCacheExpiry"]}, must-revalidate`, + }; + } + + return new Response(file, res_opts); + } catch (error) { + return new Response(`Public File Not Found`, { + status: 404, + }); } - - return new Response(file, res_opts); } - if (url.pathname.startsWith("/favicon.")) { - const file = Bun.file(path.join(PUBLIC_DIR, url.pathname)); + // if (url.pathname.startsWith("/favicon.") ) { + if (url.pathname.match(/\..*$/)) { + try { + const file_path = path.join(PUBLIC_DIR, url.pathname); - return new Response(file); + if (!existsSync(file_path)) { + return new Response(`File Doesn't Exist`, { + status: 404, + }); + } + + const file = Bun.file(file_path); + return new Response(file); + } catch (error) { + return new Response(`File Not Found`, { status: 404 }); + } } return await handleWebPages({ req }); diff --git a/src/functions/server/web-pages/grab-page-component.tsx b/src/functions/server/web-pages/grab-page-component.tsx index f7ec857..48ba69b 100644 --- a/src/functions/server/web-pages/grab-page-component.tsx +++ b/src/functions/server/web-pages/grab-page-component.tsx @@ -12,6 +12,7 @@ import AppNames from "../../../utils/grab-app-names"; import { existsSync } from "fs"; import grabPageErrorComponent from "./grab-page-error-component"; import grabPageBundledReactComponent from "./grab-page-bundled-react-component"; +import _ from "lodash"; class NotFoundError extends Error {} @@ -84,20 +85,40 @@ export default async function grabPageComponent({ const module: BunextPageModule = await import(file_path); const serverRes: BunextPageModuleServerReturn = await (async () => { + const default_props: BunextPageModuleServerReturn = { + url: { + ...(_.pick(url!, [ + "host", + "hostname", + "pathname", + "origin", + "port", + "search", + "searchParams", + "hash", + "href", + "password", + "protocol", + "username", + ]) as any), + }, + query: match?.query, + }; + try { if (routeParams) { const serverData = await module["server"]?.(routeParams); return { ...serverData, - query: match?.query, + ...default_props, }; } return { - query: match?.query, + ...default_props, }; } catch (error) { return { - query: match?.query, + ...default_props, }; } })(); diff --git a/src/types/index.ts b/src/types/index.ts index 9fbee02..85c0807 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -220,8 +220,11 @@ export type BunextPageModuleServerReturn< * Expiry time of the cache in seconds */ cacheExpiry?: number; + url: BunextPageModuleServerReturnURLObject; }; +export type BunextPageModuleServerReturnURLObject = URL & {}; + export type BunextPageModuleServerRedirect = { destination: string; permanent?: boolean;