Files
2026-07-17 15:53:31 -05:00

99 lines
2.7 KiB
TypeScript

import { existsSync, readFileSync } from "node:fs";
import { resolve } from "node:path";
import { parse as parseDotenv } from "dotenv";
import { defineConfig, type Plugin } from "vite";
function loadExtensionEnv(mode: string): NodeJS.ProcessEnv {
const fileEnv: Record<string, string> = {};
for (const fileName of [".env", ".env.local", `.env.${mode}`, `.env.${mode}.local`]) {
const path = resolve(process.cwd(), fileName);
if (existsSync(path)) {
Object.assign(fileEnv, parseDotenv(readFileSync(path)));
}
}
return { ...fileEnv, ...process.env };
}
function getGiteaHostPermissions(baseUrl?: string): string[] {
const permissions = ["<all_urls>"];
if (!baseUrl?.trim()) {
return permissions;
}
try {
const url = new URL(baseUrl);
return Array.from(new Set([...permissions, `${url.protocol}//${url.host}/*`]));
} catch {
console.warn(`VITE_GITEA_BASE_URL is not a valid URL: ${baseUrl}`);
return permissions;
}
}
function chromeExtensionManifest(mode: string): Plugin {
return {
name: "chrome-extension-manifest",
generateBundle() {
const env = loadExtensionEnv(mode);
const manifest = {
manifest_version: 3,
name: "Silma AI Aide",
version: "0.1.0",
description: "A Vite-powered side panel for Gitea-backed Silma AI aide workflows.",
icons: {
16: "icons/icon-16.png",
32: "icons/icon-32.png",
48: "icons/icon-48.png",
128: "icons/icon-128.png"
},
action: {
default_title: "Silma AI Aide",
default_icon: {
16: "icons/icon-16.png",
32: "icons/icon-32.png",
48: "icons/icon-48.png",
128: "icons/icon-128.png"
}
},
background: {
service_worker: "assets/background.js",
type: "module"
},
side_panel: {
default_path: "index.html"
},
permissions: ["activeTab", "sidePanel", "storage", "tabs"],
host_permissions: getGiteaHostPermissions(env.VITE_GITEA_BASE_URL)
};
this.emitFile({
type: "asset",
fileName: "manifest.json",
source: `${JSON.stringify(manifest, null, 2)}\n`
});
}
};
}
export default defineConfig(({ mode }) => ({
plugins: [chromeExtensionManifest(mode)],
build: {
outDir: "dist",
emptyOutDir: true,
rollupOptions: {
output: {
entryFileNames: "assets/[name].js",
chunkFileNames: "assets/[name]-[hash].js",
assetFileNames: "assets/[name]-[hash][extname]"
},
input: {
background: resolve(__dirname, "src/background.ts"),
sidePanel: resolve(__dirname, "index.html")
}
}
}
}));