fix: use bun native hashing

This commit is contained in:
nate 2026-04-10 04:09:20 +04:00
parent 6aa5795683
commit bfffb4a719
5 changed files with 19 additions and 15 deletions

View File

@ -4,15 +4,20 @@ import { resolve } from "path";
import { resolveKey } from "./auth"; import { resolveKey } from "./auth";
import sql from "../db"; import sql from "../db";
import { sparklineFromPings, pickBestRegion } from "../utils/sparkline"; import { sparklineFromPings, pickBestRegion } from "../utils/sparkline";
import { createHash } from "crypto";
import { PLAN_LABELS, REGION_COLORS, REGION_LABELS, REGIONS } from "../../../shared/plans"; import { PLAN_LABELS, REGION_COLORS, REGION_LABELS, REGIONS } from "../../../shared/plans";
const cssFile = Bun.file(resolve(import.meta.dir, "../dashboard/tailwind.css")); async function hashFile(path: string): Promise<string> {
const cssHash = createHash("md5").update(await cssFile.bytes()).digest("hex").slice(0, 8); const bytes = await Bun.file(path).bytes();
const jsFile = Bun.file(resolve(import.meta.dir, "../dashboard/app.js")); return Bun.hash(bytes).toString(36);
const jsHash = createHash("md5").update(await jsFile.bytes()).digest("hex").slice(0, 8); }
const qbFile = Bun.file(resolve(import.meta.dir, "../dashboard/query-builder.js"));
const qbHash = createHash("md5").update(await qbFile.bytes()).digest("hex").slice(0, 8); const dashDir = resolve(import.meta.dir, "../dashboard");
const assetHash = {
css: await hashFile(`${dashDir}/tailwind.css`),
appCss: await hashFile(`${dashDir}/app.css`),
js: await hashFile(`${dashDir}/app.js`),
qb: await hashFile(`${dashDir}/query-builder.js`),
};
const eta = new Eta({ views: resolve(import.meta.dir, "../views"), cache: true, defaultExtension: ".ejs" }); const eta = new Eta({ views: resolve(import.meta.dir, "../views"), cache: true, defaultExtension: ".ejs" });
@ -133,7 +138,7 @@ function redirect(to: string) {
export function html(template: string, data: Record<string, unknown> = {}) { export function html(template: string, data: Record<string, unknown> = {}) {
return new Response(eta.render(template, { return new Response(eta.render(template, {
...data, timeAgoSSR, sparklineSSR, pickBestRegion, latencyChartSSR, escapeHtmlSSR, cssHash, jsHash, qbHash, ...data, timeAgoSSR, sparklineSSR, pickBestRegion, latencyChartSSR, escapeHtmlSSR, h: assetHash,
regionColors: REGION_COLORS, regionLabels: REGION_LABELS, regions: REGIONS, planLabels: PLAN_LABELS, regionColors: REGION_COLORS, regionLabels: REGION_LABELS, regions: REGIONS, planLabels: PLAN_LABELS,
}), { }), {
headers: { "content-type": "text/html; charset=utf-8" }, headers: { "content-type": "text/html; charset=utf-8" },
@ -207,8 +212,6 @@ function parseStatusPageForm(b: any): {
return { groupsForApi, monitorsForApi }; return { groupsForApi, monitorsForApi };
} }
const dashDir = resolve(import.meta.dir, "../dashboard");
export const dashboard = new Elysia() export const dashboard = new Elysia()
.get("/", () => html("landing", {})) .get("/", () => html("landing", {}))

View File

@ -90,3 +90,4 @@
border-color: #1e1e24; border-color: #1e1e24;
} }
} }
/* cache bust */

View File

@ -1,4 +1,4 @@
<%~ include('./partials/head', { title: 'Monitor', scripts: ['/dashboard/query-builder.js?v=' + it.qbHash] }) %> <%~ include('./partials/head', { title: 'Monitor', scripts: ['/dashboard/query-builder.js?v=' + it.h.qb] }) %>
<%~ include('./partials/nav', { nav: 'monitors' }) %> <%~ include('./partials/nav', { nav: 'monitors' }) %>
<% <%

View File

@ -1,4 +1,4 @@
<%~ include('./partials/head', { title: 'New Monitor', scripts: ['/dashboard/query-builder.js?v=' + it.qbHash] }) %> <%~ include('./partials/head', { title: 'New Monitor', scripts: ['/dashboard/query-builder.js?v=' + it.h.qb] }) %>
<%~ include('./partials/nav', { nav: 'monitors' }) %> <%~ include('./partials/nav', { nav: 'monitors' }) %>
<main class="max-w-2xl mx-auto px-6 py-8"> <main class="max-w-2xl mx-auto px-6 py-8">

View File

@ -5,9 +5,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PingQL<%= it.title ? ` - ${it.title}` : '' %></title> <title>PingQL<%= it.title ? ` - ${it.title}` : '' %></title>
<link rel="icon" href="/favicon.svg" type="image/svg+xml"> <link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="stylesheet" href="/assets/tailwind.css?v=<%= it.cssHash %>"> <link rel="stylesheet" href="/assets/tailwind.css?v=<%= it.h.css %>">
<link rel="stylesheet" href="/assets/app.css?v=<%= it.cssHash %>"> <link rel="stylesheet" href="/assets/app.css?v=<%= it.h.appCss %>">
<script src="/assets/app.js?v=<%= it.jsHash %>"></script> <script src="/assets/app.js?v=<%= it.h.js %>"></script>
<% if (it.scripts) { it.scripts.forEach(function(s) { %> <% if (it.scripts) { it.scripts.forEach(function(s) { %>
<script src="<%= s %>"></script> <script src="<%= s %>"></script>
<% }) } %> <% }) } %>