UNPKG

vite-plugin-cogs-sdk

Version:

A Vite plugin to easily setup your project to be a COGS plugin or custom content

143 lines (142 loc) 4.77 kB
// src/index.ts import { existsSync } from "fs"; import { cp, mkdir, readFile, rm, writeFile } from "fs/promises"; import { basename, join, resolve } from "path"; var PLUGIN_NAME = "cogs-sdk"; var devModeIndexHtmlContent = (serverUrl) => { const serverUrlNoTrailingSlash = serverUrl.endsWith("/") ? serverUrl.slice(0, -1) : serverUrl; return `<html> <head> <title>Redirecting...</title> <script> document.addEventListener('DOMContentLoaded', () => { const parsedUrl = new URL(document.location.href); const pathParams = new URLSearchParams(parsedUrl.searchParams); document.location.href = \`${serverUrlNoTrailingSlash}\${parsedUrl.pathname}?\${pathParams.toString()}\`; }); </script> </head> <body></body> </html>`; }; var INDEX_HTML_POLYFILL = ` <!-- COGS SDK Polyfill for global --> <script> if (global === undefined) { var global = window; } if (module === undefined) { var module = {}; } </script> </head>`; var cogsSdkPlugin = (options = {}) => { let config; let serverUrl; let manifestFilename, manifestFilePath; const basePath = process.cwd(); if (options.manifestFilePath) { manifestFilename = basename(options.manifestFilePath); manifestFilePath = resolve(basePath, options.manifestFilePath); } else { manifestFilename = "cogs-plugin-manifest.js"; manifestFilePath = join(basePath, "src", manifestFilename); } if (!existsSync(manifestFilePath)) { throw new Error(`COGS Manifest file not found at ${manifestFilePath}`); } const generateDevModeOutput = async () => { const outDirPath = join(basePath, config.build.outDir); await rm(outDirPath, { force: true, recursive: true }); await mkdir(outDirPath); await cp(manifestFilePath, join(outDirPath, manifestFilename)); const publicPath = join(basePath, "public"); if (existsSync(publicPath)) { await cp(publicPath, outDirPath, { recursive: true }); } const indexHtmlContent = devModeIndexHtmlContent(serverUrl); await writeFile(join(outDirPath, "index.html"), indexHtmlContent); }; return { name: PLUGIN_NAME, /** * Make sure the server is exposed to all the network so it "just works" in dev mode */ config() { if (options.noServerExpose) { return {}; } else { return { server: { host: "0.0.0.0" } }; } }, /** * Store the resolved config so we can access it elsewhere in the plugin code */ configResolved(resolvedConfig) { config = resolvedConfig; }, /** * When the server is configured we add a listener to get the real port value. This is because it might not match the one in the config if * that one was not available */ configureServer(server) { server.httpServer?.on("listening", () => { setImmediate(() => { if (server.resolvedUrls?.network && server.resolvedUrls.network.length > 0) { serverUrl = server.resolvedUrls.network[0]; } else if (server.resolvedUrls?.local && server.resolvedUrls.local.length > 0) { serverUrl = server.resolvedUrls.local[0]; } else { const address = server.httpServer?.address(); if (address && typeof address === "object") { serverUrl = `http://localhost:${address.port}/`; } } generateDevModeOutput(); }); }); }, /** * When the build starts we detect if we're in "serve" mode (dev mode) and start a dev build output */ async buildStart() { if (config.command === "serve") { serverUrl = `http://localhost:${config.server.port}/`; this.addWatchFile(manifestFilePath); await generateDevModeOutput(); } }, /** * When the manifest file changes in dev mode, we need to rebuild the output. * This is only used in build mode. */ async watchChange(path) { if (path === manifestFilePath) { await generateDevModeOutput(); } }, /** * We tell Vite to include the manifest file in the build output as an asset. * This is only called in "build" mode when we're bundling for production */ async generateBundle() { const source = await readFile(manifestFilePath); this.emitFile({ fileName: manifestFilename, source, type: "asset" }); }, /** * We need to add a polyfill for `global` and `module` in the HTML file for the COGS SDK to correctly load * It is used in both build and serve mode */ transformIndexHtml(html) { return html.replace(/<\/head>/, INDEX_HTML_POLYFILL); } }; }; var index_default = cogsSdkPlugin; export { cogsSdkPlugin, index_default as default };