-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvite.config.ts
More file actions
98 lines (89 loc) · 2.87 KB
/
Copy pathvite.config.ts
File metadata and controls
98 lines (89 loc) · 2.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { VitePWA } from "vite-plugin-pwa";
import fs from "node:fs";
import path from "node:path";
const appBuildId = new Date().toISOString();
const basePath = normalizeBasePath(process.env.VITE_BASE_PATH ?? "/");
export default defineConfig({
base: basePath,
define: {
__APP_BUILD_ID__: JSON.stringify(appBuildId),
},
plugins: [
react(),
emitVersionSnapshotPlugin(appBuildId),
VitePWA({
injectRegister: false,
registerType: "autoUpdate",
includeAssets: ["logo.svg"],
workbox: {
clientsClaim: true,
skipWaiting: true,
cleanupOutdatedCaches: true,
globIgnores: ["**/version.json"],
navigateFallback: `${basePath}index.html`,
},
manifest: {
name: "!bangs.fast",
short_name: "!bangs.fast",
description: "Fast local bang redirects and search",
display: "standalone",
background_color: "#f3efe7",
theme_color: "#1e5d4f",
start_url: basePath,
scope: basePath,
},
}),
],
build: {
sourcemap: false,
},
});
function normalizeBasePath(value: string): string {
const trimmed = value.trim();
if (!trimmed || trimmed === "/") return "/";
const withLeadingSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
return withLeadingSlash.endsWith("/") ? withLeadingSlash : `${withLeadingSlash}/`;
}
function emitVersionSnapshotPlugin(appBuild: string): import("vite").Plugin {
const DATASET_IDS = ["kagi-community", "kagi-internal", "duckduckgo"] as const;
const sanitizeDatasetHash = (value: unknown): string | null => {
if (typeof value !== "string") return null;
const trimmed = value.trim();
if (!trimmed) return null;
return trimmed;
};
return {
name: "emit-version-snapshot",
apply: "build",
generateBundle() {
const datasetHashes: Record<string, { hash: string }> = {};
for (const sourceId of DATASET_IDS) {
const datasetPath = path.resolve(process.cwd(), `public/datasets/${sourceId}.json`);
try {
const raw = fs.readFileSync(datasetPath, "utf8");
const parsed = JSON.parse(raw) as { hash?: unknown };
const hash = sanitizeDatasetHash(parsed.hash);
if (hash) {
datasetHashes[sourceId] = { hash };
} else {
this.warn(`[emit-version-snapshot] Missing dataset hash in ${datasetPath}`);
}
} catch (_error) {
// Keep version emission resilient even if one dataset file cannot be parsed.
}
}
const payload = {
appBuildId: appBuild,
generatedAt: new Date().toISOString(),
datasets: datasetHashes,
};
this.emitFile({
type: "asset",
fileName: "version.json",
source: `${JSON.stringify(payload)}\n`,
});
},
};
}