UNPKG

vite-plugin-firebase-messaging-sw

Version:

Vite plugin to generate a Firebase Cloud Messaging service worker with env-aware configs and dev no-store preview.

1 lines 20.5 kB
{"version":3,"sources":["../src/helper.ts","../src/index.ts"],"names":["crypto","fs","path"],"mappings":"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","file":"index.cjs","sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport crypto from \"crypto\";\n\nexport type LogLevel = \"info\" | \"warn\" | \"error\" | \"debug\";\nexport type LogMeta = Record<string, unknown> | undefined;\n\nexport const NOW_ISO = () => new Date().toISOString();\n\nexport function sha256(input: string | Buffer) {\n return crypto.createHash(\"sha256\").update(input).digest(\"hex\");\n}\n\nexport function formatBytes(n: number) {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} kB`;\n return `${(n / (1024 * 1024)).toFixed(2)} MB`;\n}\n\nexport function createLogger(scope: string) {\n const pick = (lvl: LogLevel) => (lvl === \"error\" ? console.error : lvl === \"warn\" ? console.warn : console.log);\n const icon = (lvl: LogLevel) => (lvl === \"info\" ? \"🧩\" : lvl === \"warn\" ? \"⚠️\" : lvl === \"error\" ? \"🛑\" : \"🔎\");\n\n const log = (level: LogLevel) => (msg: string, meta?: LogMeta) => {\n const fn = pick(level);\n const head = `${icon(level)} [${scope}] ${msg}`;\n meta ? fn(head, meta) : fn(head);\n };\n\n return {\n info: log(\"info\"),\n warn: log(\"warn\"),\n error: log(\"error\"),\n debug: log(\"debug\"),\n };\n}\n\nexport function ensureDir(dir: string) {\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, {recursive: true});\n}\n\nexport function writeFileIfChanged(filePath: string, content: string, log = createLogger(\"write\")) {\n ensureDir(path.dirname(filePath));\n\n const existed = fs.existsSync(filePath);\n const oldHash = existed ? sha256(fs.readFileSync(filePath)) : null;\n const newHash = sha256(content);\n\n if (!existed || oldHash !== newHash) {\n fs.writeFileSync(filePath, content, \"utf-8\");\n const size = fs.statSync(filePath).size;\n log.info(\"File written\", {\n path: filePath,\n size: formatBytes(size),\n hash: newHash.slice(0, 12),\n replaced: existed && oldHash !== null,\n });\n return {changed: true, size, hash: newHash};\n }\n\n log.debug(\"No changes; kept existing file\", {\n path: filePath,\n hash: newHash.slice(0, 12),\n });\n return {changed: false, size: fs.statSync(filePath).size, hash: newHash};\n}\n\nexport function resolveOutputPath(outputDir: string, filename: string) {\n const abs = path.resolve(outputDir);\n ensureDir(abs);\n return path.join(abs, filename);\n}\n\nexport function readEnv(key: string, fallback?: string) {\n const v = process.env[key];\n return v === undefined || v === null || v === \"\" ? fallback : v;\n}","// vite/plugins/generate-firebase-messaging-sw.ts\nimport path from \"node:path\";\nimport type {Plugin, ResolvedConfig, ViteDevServer} from \"vite\";\nimport {\n createLogger,\n formatBytes,\n resolveOutputPath,\n sha256,\n writeFileIfChanged,\n NOW_ISO,\n} from \"./helper\";\n\n// ----------------- types -----------------\n\ntype FirebaseEnvCfg = Record<string, string | undefined>;\n\nexport type FirebaseConfig = {\n apiKey: string;\n authDomain: string;\n projectId: string;\n storageBucket: string;\n messagingSenderId: string;\n appId: string;\n measurementId?: string;\n};\n\nexport type FcmSwOptions = {\n outputDir?: string; // where to mirror file (default: \"static\")\n filename?: string; // default: \"firebase-messaging-sw.js\"\n firebaseCompatVersion?: string; // default: \"9.22.2\"\n firebase:\n | FirebaseConfig\n | ((\n ctx: {\n mode: \"development\" | \"production\";\n command: \"serve\" | \"build\";\n config: ResolvedConfig;\n },\n ) => FirebaseConfig);\n meta?: {\n appEnv?: string;\n target?: string;\n };\n analytics?: {\n impressionUrl?: string;\n openUrl?: string;\n srcParam?: string;\n cidParam?: string;\n srcValue?: string;\n };\n minify?: boolean;\n transform?: (code: string) => string;\n};\n\nconst DEFAULTS: Required<\n Pick<FcmSwOptions, \"outputDir\" | \"filename\" | \"firebaseCompatVersion\">\n> = {\n outputDir: \"static\",\n filename: \"firebase-messaging-sw.js\",\n firebaseCompatVersion: \"9.22.2\",\n};\n\n// ----------------- helpers -----------------\n\nfunction validateFirebaseConfig(cfg: FirebaseEnvCfg): asserts cfg is Record<string, string> {\n const required = [\n \"apiKey\",\n \"authDomain\",\n \"projectId\",\n \"storageBucket\",\n \"messagingSenderId\",\n \"appId\",\n ] as const;\n const missing = required.filter((k) => !cfg[k]);\n if (missing.length) {\n throw new Error(`Missing Firebase configs: ${missing.join(\", \")}`);\n }\n}\n\nconst esc = (s: string) => s.replace(/\\\\/g, \"\\\\\\\\\").replace(/`/g, \"\\\\`\");\n\nfunction jsMinifySimple(code: string) {\n return (\n code\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\")\n .replace(/[ \\t]+/g, \" \")\n .replace(/\\n\\s+/g, \"\\n\")\n .trim() + \"\\n\"\n );\n}\n\n// ----------------- template builder -----------------\n\nfunction buildSwTemplate(meta: {\n appEnv: string;\n target: string;\n swVersion: string;\n generatedAt: string;\n firebase: FirebaseConfig;\n analytics: Required<NonNullable<FcmSwOptions[\"analytics\"]>>;\n compatVersion: string;\n}) {\n const {appEnv, target, swVersion, generatedAt, firebase, analytics, compatVersion} =\n meta;\n\n return `/* Auto-generated at ${generatedAt} */\nimportScripts(\"https://www.gstatic.com/firebasejs/${compatVersion}/firebase-app-compat.js\");\nimportScripts(\"https://www.gstatic.com/firebasejs/${compatVersion}/firebase-messaging-compat.js\");\n\n(function(){\n const log = (...a)=>{ try{ console.log(\"[FIREBASE SW]\", ...a);}catch{} };\n const warn = (...a)=>{ try{ console.warn(\"[FIREBASE SW]\", ...a);}catch{} };\n const err = (...a)=>{ try{ console.error(\"[FIREBASE SW]\", ...a);}catch{} };\n\n const META = {\n appEnv: \"${esc(appEnv)}\",\n target: \"${esc(target)}\",\n swVersion: \"${esc(swVersion)}\",\n generatedAt: \"${esc(generatedAt)}\"\n };\n\n const ANALYTICS = {\n impressionUrl: \"${esc(analytics.impressionUrl)}\",\n openUrl: \"${esc(analytics.openUrl)}\",\n srcParam: \"${esc(analytics.srcParam)}\",\n cidParam: \"${esc(analytics.cidParam)}\",\n srcValue: \"${esc(analytics.srcValue)}\"\n };\n\n // ... trimmed for brevity (your full SW logic goes here) ...\n})();\n`;\n}\n\n// ----------------- plugin -----------------\n\nexport function generateFirebaseMessagingSw(options: FcmSwOptions): Plugin {\n const log = createLogger(\"fcm-sw\");\n\n const outputDir = options.outputDir ?? DEFAULTS.outputDir;\n const filename = options.filename ?? DEFAULTS.filename;\n const compatVersion = options.firebaseCompatVersion ?? DEFAULTS.firebaseCompatVersion;\n\n const analytics = {\n impressionUrl: options.analytics?.impressionUrl ?? \"\",\n openUrl: options.analytics?.openUrl ?? \"\",\n srcParam: options.analytics?.srcParam ?? \"src\",\n cidParam: options.analytics?.cidParam ?? \"cid\",\n srcValue: options.analytics?.srcValue ?? \"fcm\",\n };\n\n let resolvedConfig: ResolvedConfig;\n let mode: \"development\" | \"production\" = \"production\";\n let command: \"serve\" | \"build\" = \"build\";\n let root = process.cwd();\n let lastCode = \"\";\n let lastEtag = \"\";\n\n const resolveFirebaseConfig = (): FirebaseConfig => {\n const provided =\n typeof options.firebase === \"function\"\n ? options.firebase({mode, command, config: resolvedConfig})\n : options.firebase;\n\n const envFallback = {\n apiKey: process.env.FIREBASE_API_KEY,\n authDomain: process.env.FIREBASE_AUTH_DOMAIN,\n projectId: process.env.FIREBASE_PROJECT_ID,\n storageBucket: process.env.FIREBASE_STORAGE_BUCKET,\n messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,\n appId: process.env.FIREBASE_APP_ID,\n measurementId: process.env.FIREBASE_MEASUREMENT_ID,\n };\n\n const merged: FirebaseEnvCfg = {...envFallback, ...provided};\n validateFirebaseConfig(merged);\n\n return {\n apiKey: merged.apiKey!,\n authDomain: merged.authDomain!,\n projectId: merged.projectId!,\n storageBucket: merged.storageBucket!,\n messagingSenderId: merged.messagingSenderId!,\n appId: merged.appId!,\n ...(merged.measurementId ? {measurementId: merged.measurementId} : {}),\n };\n };\n\n const buildOnce = () => {\n const appEnv = options.meta?.appEnv ?? mode;\n const target = options.meta?.target ?? \"web\";\n const firebase = resolveFirebaseConfig();\n\n const generatedAt = NOW_ISO();\n const swVersion = sha256(`${appEnv}:${target}:${generatedAt}`).slice(0, 12);\n\n let code = buildSwTemplate({\n appEnv,\n target,\n swVersion,\n generatedAt,\n firebase,\n analytics,\n compatVersion,\n });\n\n if (options.minify ?? mode === \"production\") code = jsMinifySimple(code);\n if (options.transform) code = options.transform(code);\n\n lastCode = code;\n lastEtag = sha256(code).slice(0, 12);\n return {code, etag: lastEtag};\n };\n\n return {\n name: \"vite-plugin-firebase-messaging-sw\",\n apply: () => true,\n\n configResolved(config) {\n resolvedConfig = config;\n mode = (config.mode as \"development\" | \"production\") ?? \"production\";\n command = config.command as \"serve\" | \"build\";\n root = config.root ?? process.cwd();\n },\n\n buildStart() {\n try {\n const {code} = buildOnce();\n // Optionally mirror to disk\n const outPath = resolveOutputPath(path.resolve(root, outputDir), filename);\n writeFileIfChanged(outPath, code)\n } catch (e: any) {\n log.warn(\"Error generating Firebase SW\", {err: e?.message || String(e)});\n throw e;\n }\n },\n\n generateBundle() {\n const {code} = buildOnce();\n this.emitFile({\n type: \"asset\",\n fileName: filename,\n source: code,\n });\n log.info(\"FCM SW emitted\", {\n file: filename,\n size: formatBytes(Buffer.byteLength(code)),\n etag: lastEtag,\n });\n },\n\n configureServer(server: ViteDevServer) {\n const base = (resolvedConfig?.base ?? \"/\").replace(/\\/+$/, \"/\");\n const route = path.posix.join(base, filename);\n\n server.middlewares.use(route, (_req, res) => {\n try {\n const {code, etag} = buildOnce();\n res.setHeader(\"Content-Type\", \"application/javascript; charset=utf-8\");\n res.setHeader(\"Cache-Control\", \"no-store, no-cache, must-revalidate, max-age=0\");\n res.setHeader(\"Pragma\", \"no-cache\");\n res.setHeader(\"Expires\", \"0\");\n res.setHeader(\"ETag\", etag);\n res.end(code);\n } catch (e: any) {\n res.statusCode = 500;\n res.end(`/* ${String(e?.message || e || \"SW build error\")} */`);\n }\n });\n\n log.info(`dev route mounted → ${route} (no-store)`);\n },\n };\n}\n\nexport default generateFirebaseMessagingSw;\n"]}