vite-plugin-html-pages 1.3.6 → 1.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +13 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/dev-server.ts +16 -11
- package/src/plugin.ts +4 -2
package/dist/index.js
CHANGED
|
@@ -287,17 +287,16 @@ async function closePageModuleLoader() {
|
|
|
287
287
|
function isStaticAssetRequest(url) {
|
|
288
288
|
return url.endsWith(".css") || url.endsWith(".js") || url.endsWith(".mjs") || url.endsWith(".ts") || url.endsWith(".png") || url.endsWith(".jpg") || url.endsWith(".jpeg") || url.endsWith(".gif") || url.endsWith(".svg") || url.endsWith(".webp") || url.endsWith(".ico") || url.endsWith(".woff") || url.endsWith(".woff2") || url.endsWith(".ttf") || url.endsWith(".otf");
|
|
289
289
|
}
|
|
290
|
-
function shouldSkipHtmlRouting(url) {
|
|
291
|
-
return url.startsWith("/@vite") || url.startsWith("/@fs/") || url.startsWith("/node_modules/") || url.startsWith(
|
|
290
|
+
function shouldSkipHtmlRouting(url, pagesDir) {
|
|
291
|
+
return url.startsWith("/@vite") || url.startsWith("/@fs/") || url.startsWith("/node_modules/") || url.startsWith(`/${pagesDir}/`) || url === "/favicon.ico" || isStaticAssetRequest(url);
|
|
292
292
|
}
|
|
293
|
-
function tryRewriteRootAssetToSrc(
|
|
293
|
+
function tryRewriteRootAssetToSrc(root, pagesDir, url) {
|
|
294
294
|
if (!url.startsWith("/")) return null;
|
|
295
295
|
if (!isStaticAssetRequest(url)) return null;
|
|
296
|
-
if (url.startsWith(
|
|
297
|
-
const
|
|
298
|
-
const candidate = path4.join(root, "src", url.slice(1));
|
|
296
|
+
if (url.startsWith(`/${pagesDir}/`)) return null;
|
|
297
|
+
const candidate = path4.join(root, pagesDir, url.slice(1));
|
|
299
298
|
if (fs.existsSync(candidate)) {
|
|
300
|
-
return
|
|
299
|
+
return `/${pagesDir}/${url.slice(1)}`;
|
|
301
300
|
}
|
|
302
301
|
return null;
|
|
303
302
|
}
|
|
@@ -305,17 +304,17 @@ function shouldUseDynamicRendering(mod) {
|
|
|
305
304
|
return mod.dynamic === true || mod.prerender === false;
|
|
306
305
|
}
|
|
307
306
|
function installDevServer(args) {
|
|
308
|
-
const { server, getPages } = args;
|
|
307
|
+
const { server, root, pagesDir, getPages } = args;
|
|
309
308
|
server.middlewares.use(async (req, res, next) => {
|
|
310
309
|
try {
|
|
311
310
|
const originalUrl = req.url ?? "/";
|
|
312
311
|
const url = originalUrl.split("?")[0];
|
|
313
|
-
const rewrittenAssetUrl = tryRewriteRootAssetToSrc(
|
|
312
|
+
const rewrittenAssetUrl = tryRewriteRootAssetToSrc(root, pagesDir, url);
|
|
314
313
|
if (rewrittenAssetUrl) {
|
|
315
314
|
req.url = rewrittenAssetUrl + originalUrl.slice(url.length);
|
|
316
315
|
return next();
|
|
317
316
|
}
|
|
318
|
-
if (shouldSkipHtmlRouting(url)) {
|
|
317
|
+
if (shouldSkipHtmlRouting(url, pagesDir)) {
|
|
319
318
|
return next();
|
|
320
319
|
}
|
|
321
320
|
const pages = await getPages();
|
|
@@ -325,7 +324,7 @@ function installDevServer(args) {
|
|
|
325
324
|
}
|
|
326
325
|
const loadModule = await createPageModuleLoader({
|
|
327
326
|
mode: "dev",
|
|
328
|
-
root
|
|
327
|
+
root,
|
|
329
328
|
server
|
|
330
329
|
});
|
|
331
330
|
const mod = await loadModule(page.entryPath, page.relativePath);
|
|
@@ -817,7 +816,7 @@ function htPages(options = {}) {
|
|
|
817
816
|
return null;
|
|
818
817
|
},
|
|
819
818
|
configResolved(resolved) {
|
|
820
|
-
root = resolved.root;
|
|
819
|
+
root = options.root ? path7.resolve(resolved.root, options.root) : resolved.root;
|
|
821
820
|
if (!hasWarnedESM) {
|
|
822
821
|
warnIfNotESM(root);
|
|
823
822
|
hasWarnedESM = true;
|
|
@@ -850,6 +849,8 @@ function htPages(options = {}) {
|
|
|
850
849
|
server = _server;
|
|
851
850
|
installDevServer({
|
|
852
851
|
server,
|
|
852
|
+
root,
|
|
853
|
+
pagesDir,
|
|
853
854
|
getPages: async () => {
|
|
854
855
|
if (devPages.length > 0) return devPages;
|
|
855
856
|
return loadDevPages();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/plugin.ts","../src/discover.ts","../src/path-utils.ts","../src/route-utils.ts","../src/route-params.ts","../src/constants.ts","../src/dev-server.ts","../src/errors.ts","../src/render-runtime.ts","../src/module-loader.ts","../src/page-index.ts","../src/static-assets.ts","../src/html-asset-validator.ts","../src/page-helper-generator.ts","../src/fetch-cache.ts"],"sourcesContent":["import pLimit from 'p-limit';\nimport type { Plugin, ViteDevServer } from 'vite';\n\nimport { discoverEntryPages } from './discover';\nimport { installDevServer } from './dev-server';\nimport { createPageModuleLoader, closePageModuleLoader } from './module-loader';\nimport { buildPageIndex } from './page-index';\nimport { renderPage } from './render-runtime';\nimport {\n buildProcessedStaticAssets,\n collectStaticAssets,\n copyStaticAssetSource,\n} from './static-assets';\nimport { validateHtmlAssetReferences } from './html-asset-validator';\nimport type { HtPageInfo, HtPageModule, HtPagesPluginOptions } from './types';\nimport {\n PLUGIN_NAME,\n VIRTUAL_BUILD_ENTRY_ID,\n VIRTUAL_PAGE_HELPER_ID,\n RESOLVED_VIRTUAL_PAGE_HELPER_PREFIX,\n} from './constants';\nimport { generateTypedPageHelper } from './page-helper-generator';\n\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nlet hasWarnedESM = false;\n\nfunction warnIfNotESM(root: string) {\n try {\n const pkgPath = path.join(root, 'package.json');\n\n if (!fs.existsSync(pkgPath)) return;\n\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));\n\n if (pkg.type !== 'module') {\n console.warn(\n `[${PLUGIN_NAME}] ⚠️ It is recommended to add \"type\": \"module\" to your package.json for optimal performance and to avoid Node ESM warnings.`,\n );\n }\n } catch {\n // silent — never break build\n }\n}\n\nfunction chunkArray<T>(items: T[], size: number): T[][] {\n const out: T[][] = [];\n for (let i = 0; i < items.length; i += size) {\n out.push(items.slice(i, i + size));\n }\n return out;\n}\n\nexport function htPages(options: HtPagesPluginOptions = {}): Plugin {\n let root = process.cwd();\n let server: ViteDevServer | null = null;\n let devPages: HtPageInfo[] = [];\n let watcherAttached = false;\n\n const cleanUrls = options.cleanUrls ?? true;\n const pagesDir = options.pagesDir ?? 'src';\n const pageExtensions = options.pageExtensions?.length\n ? options.pageExtensions\n : ['.ht.js', '.html.js', '.ht.ts', '.html.ts'];\n\n function logDebug(enabled: boolean | undefined, ...args: unknown[]) {\n if (!enabled) return;\n console.log(`[${PLUGIN_NAME}]`, ...args);\n }\n\n async function loadDevPages(): Promise<HtPageInfo[]> {\n const entries = await discoverEntryPages(root, options);\n const modulesByEntry = new Map<string, HtPageModule>();\n\n logDebug(\n options.debug,\n 'discovered entries',\n entries.map((e) => e.relativePath),\n );\n\n if (!server) return [];\n\n const loadModule = await createPageModuleLoader({\n mode: 'dev',\n root,\n server,\n });\n\n for (const entry of entries) {\n const mod = await loadModule(entry.entryPath, entry.relativePath);\n modulesByEntry.set(entry.entryPath, mod);\n }\n\n devPages = await buildPageIndex({\n entries,\n modulesByEntry,\n cleanUrls,\n });\n\n logDebug(\n options.debug,\n 'dev pages',\n devPages.map((p) => `${p.routePath} -> ${p.relativePath}`),\n );\n\n return devPages;\n }\n\n async function buildPagesPipeline() {\n const entries = await discoverEntryPages(root, options);\n const modulesByEntry = new Map<string, HtPageModule>();\n\n const loadModule = await createPageModuleLoader({\n mode: 'build',\n root,\n });\n\n for (const entry of entries) {\n const mod = await loadModule(entry.entryPath, entry.relativePath);\n modulesByEntry.set(entry.entryPath, mod);\n }\n\n const pages = await buildPageIndex({\n entries,\n modulesByEntry,\n cleanUrls,\n });\n\n return { entries, modulesByEntry, pages };\n }\n\n return {\n name: PLUGIN_NAME,\n\n config(userConfig, env) {\n if (env.command !== 'build') return;\n\n const hasExplicitInput = userConfig.build?.rollupOptions?.input != null;\n if (hasExplicitInput) return;\n\n return {\n build: {\n rollupOptions: {\n input: VIRTUAL_BUILD_ENTRY_ID,\n },\n },\n };\n },\n\n resolveId(id, importer) {\n if (id === VIRTUAL_BUILD_ENTRY_ID) return id;\n \n if (id === VIRTUAL_PAGE_HELPER_ID && importer) {\n return `${RESOLVED_VIRTUAL_PAGE_HELPER_PREFIX}${importer}`;\n }\n \n return null;\n },\n\n async load(id) {\n if (id === VIRTUAL_BUILD_ENTRY_ID) {\n return 'export default {};';\n }\n \n if (id.startsWith(RESOLVED_VIRTUAL_PAGE_HELPER_PREFIX)) {\n const importer = id.slice(RESOLVED_VIRTUAL_PAGE_HELPER_PREFIX.length);\n const { pages } = await buildPagesPipeline();\n \n const normalizedImporter = path.resolve(importer);\n \n const page = pages.find(\n (candidate) => path.resolve(candidate.absolutePath) === normalizedImporter,\n );\n \n return generateTypedPageHelper(page);\n }\n \n return null;\n },\n\n configResolved(resolved) {\n root = resolved.root;\n\n if (!hasWarnedESM) {\n warnIfNotESM(root);\n hasWarnedESM = true;\n }\n },\n\n async buildStart() {\n const entries = await discoverEntryPages(root, options);\n\n for (const entry of entries) {\n this.addWatchFile(entry.entryPath);\n }\n\n const staticAssets = await collectStaticAssets({\n root,\n pagesDir,\n pageExtensions,\n });\n\n for (const asset of staticAssets) {\n this.addWatchFile(asset.absolutePath);\n }\n\n logDebug(\n options.debug,\n 'static assets',\n staticAssets.map((asset) => ({\n kind: asset.kind,\n input: asset.relativePathFromSrc,\n output: asset.outputFileName,\n })),\n );\n },\n\n configureServer(_server) {\n server = _server;\n \n installDevServer({\n server,\n getPages: async () => {\n if (devPages.length > 0) return devPages;\n return loadDevPages();\n },\n getEntries: async () => discoverEntryPages(root, options),\n });\n \n if (!watcherAttached) {\n watcherAttached = true;\n \n const reload = async (file: string) => {\n if (!file.includes(`${path.sep}src${path.sep}`) && !file.includes('/src/')) {\n return;\n }\n \n logDebug(options.debug, 'file changed', file);\n \n await loadDevPages();\n \n server?.ws.send({ type: 'full-reload' });\n\n };\n \n server.watcher.on('add', reload);\n server.watcher.on('change', reload);\n server.watcher.on('unlink', reload);\n }\n \n loadDevPages().catch((error) => {\n server?.config.logger.error(\n `[${PLUGIN_NAME}] loadDevPages failed: ${\n error instanceof Error ? error.stack ?? error.message : String(error)\n }`,\n );\n });\n },\n\n // async handleHotUpdate(ctx) {\n // if (!server) return;\n \n // logDebug(options.debug, 'file changed', ctx.file);\n \n // await loadDevPages();\n \n // server.ws.send({\n // type: 'full-reload',\n // });\n \n // return [];\n // },\n\n async generateBundle(_, bundle) {\n try {\n const { modulesByEntry, pages } = await buildPagesPipeline();\n\n const staticAssets = await collectStaticAssets({\n root,\n pagesDir,\n pageExtensions,\n });\n\n logDebug(\n options.debug,\n 'emitting pages',\n pages.map((p) => p.fileName),\n );\n\n logDebug(\n options.debug,\n 'emitting static assets',\n staticAssets.map((asset) => ({\n kind: asset.kind,\n input: asset.relativePathFromSrc,\n output: asset.outputFileName,\n })),\n );\n\n const limit = pLimit(options.renderConcurrency ?? 8);\n const batchSize =\n options.renderBatchSize ??\n Math.max(options.renderConcurrency ?? 8, 32);\n\n const processedOutputs = await buildProcessedStaticAssets({\n root,\n pagesDir,\n assets: staticAssets,\n minify: true,\n sourcemap: false,\n });\n\n for (const [fileName, source] of processedOutputs) {\n this.emitFile({\n type: 'asset',\n fileName,\n source,\n });\n }\n\n for (const asset of staticAssets) {\n if (asset.kind !== 'copy') continue;\n\n const source = await copyStaticAssetSource(asset);\n\n this.emitFile({\n type: 'asset',\n fileName: asset.outputFileName,\n source,\n });\n }\n\n for (const batch of chunkArray(pages, batchSize)) {\n await Promise.all(\n batch.map((page) =>\n limit(async () => {\n const mod = modulesByEntry.get(page.entryPath);\n\n if (!mod) {\n throw new Error(\n `[${PLUGIN_NAME}] Missing module for page entry: ${page.entryPath}`,\n );\n }\n\n const html = await renderPage(page, mod, false);\n\n validateHtmlAssetReferences({\n root,\n pagesDir,\n html,\n pluginName: PLUGIN_NAME,\n pageLabel: page.relativePath,\n missingAssets: options.missingAssets ?? 'error',\n });\n \n this.emitFile({\n type: 'asset',\n fileName: options.mapOutputPath?.(page) ?? page.fileName,\n source: html,\n });\n }),\n ),\n );\n }\n\n const notFoundPage = pages.find((p) => p.routePath === '/404');\n\n if (notFoundPage) {\n const mod = modulesByEntry.get(notFoundPage.entryPath);\n\n if (!mod) {\n throw new Error(\n `[${PLUGIN_NAME}] Missing module for 404 page entry: ${notFoundPage.entryPath}`,\n );\n }\n\n const html = await renderPage(notFoundPage, mod, false);\n\n validateHtmlAssetReferences({\n root,\n pagesDir,\n html,\n pluginName: PLUGIN_NAME,\n pageLabel: notFoundPage.relativePath,\n missingAssets: options.missingAssets ?? 'error',\n });\n \n this.emitFile({\n type: 'asset',\n fileName: '404.html',\n source: html,\n });\n\n logDebug(options.debug, 'generated 404.html from user page');\n } else {\n const default404 = `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>404 - Page Not Found</title>\n <style>\n :root {\n color-scheme: light dark;\n }\n body {\n margin: 0;\n font-family: system-ui, sans-serif;\n min-height: 100vh;\n display: grid;\n place-items: center;\n padding: 2rem;\n }\n main {\n max-width: 40rem;\n text-align: center;\n }\n h1 {\n font-size: 3rem;\n margin: 0 0 1rem;\n }\n p {\n margin: 0.5rem 0;\n line-height: 1.5;\n }\n a {\n color: inherit;\n }\n </style>\n </head>\n <body>\n <main>\n <h1>404</h1>\n <p>Page not found.</p>\n <p><a href=\"/\">Go back home</a></p>\n </main>\n </body>\n</html>\n`;\n\n this.emitFile({\n type: 'asset',\n fileName: '404.html',\n source: default404,\n });\n\n logDebug(options.debug, 'generated default 404.html');\n }\n\n const sitemapBase = options.site ?? '';\n\n const sitemapRoutes = [...new Set(pages.map((p) => p.routePath))].filter(\n (route) => !route.includes(':') && !route.includes('*'),\n );\n\n if (sitemapBase && sitemapRoutes.length > 0) {\n const sitemap = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\\n${sitemapRoutes\n .map((route) => ` <url><loc>${sitemapBase}${route}</loc></url>`)\n .join('\\n')}\\n</urlset>\\n`;\n\n this.emitFile({\n type: 'asset',\n fileName: 'sitemap.xml',\n source: sitemap,\n });\n\n logDebug(options.debug, 'generated sitemap.xml');\n }\n\n const rss = options.rss;\n\n if (rss?.site) {\n const routePrefix = rss.routePrefix ?? '/blog';\n \n const rssItems = pages\n .filter((page) => page.routePath.startsWith(routePrefix))\n .map((page) => {\n const url = `${rss.site}${page.routePath}`;\n \n return ` <item>\\n <title>${page.routePath}</title>\\n <link>${url}</link>\\n <guid>${url}</guid>\\n </item>`;\n })\n .join('\\n');\n \n const rssXml = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<rss version=\"2.0\">\\n<channel>\\n <title>${rss.title ?? PLUGIN_NAME}</title>\\n <link>${rss.site}</link>\\n <description>${rss.description ?? 'RSS feed'}</description>\\n${rssItems}\\n</channel>\\n</rss>\\n`;\n \n this.emitFile({\n type: 'asset',\n fileName: 'rss.xml',\n source: rssXml,\n });\n \n logDebug(options.debug, 'generated rss.xml');\n }\n\n for (const [fileName, output] of Object.entries(bundle)) {\n if (\n output.type === 'chunk' &&\n output.facadeModuleId === VIRTUAL_BUILD_ENTRY_ID\n ) {\n delete bundle[fileName];\n }\n }\n } finally {\n await closePageModuleLoader();\n }\n }\n };\n}\n\nexport default htPages;\n","import path from 'node:path';\nimport { normalizeFsPath, toPosix } from './path-utils';\nimport { isDynamicPage, toRoutePattern } from './route-utils';\nimport { extractRouteParamDefinitions } from './route-params';\nimport type { HtPageInfo, HtPagesPluginOptions } from './types';\nimport { PLUGIN_NAME } from './constants';\n\nfunction buildDefaultIncludeGlobs(\n pagesDir: string,\n pageExtensions: string[],\n): string[] {\n return pageExtensions.map((ext) => {\n const cleanExt = ext.startsWith('.') ? ext.slice(1) : ext;\n return `${pagesDir}/**/*.${cleanExt}`;\n });\n}\n\nexport async function discoverEntryPages(\n root: string,\n options: HtPagesPluginOptions,\n): Promise<HtPageInfo[]> {\n const fgModule = await import('fast-glob');\n const fg = (fgModule.default ?? fgModule) as typeof import('fast-glob');\n\n const pagesDir = options.pagesDir ?? 'src';\n const pageExtensions = options.pageExtensions?.length\n ? options.pageExtensions\n : ['.ht.js', '.html.js', '.ht.ts', '.html.ts'];\n\n const include = Array.isArray(options.include)\n ? options.include\n : options.include\n ? [options.include]\n : buildDefaultIncludeGlobs(pagesDir, pageExtensions);\n\n const exclude = Array.isArray(options.exclude)\n ? options.exclude\n : options.exclude\n ? [options.exclude]\n : [];\n\n const pagesRoot = normalizeFsPath(path.join(root, pagesDir));\n\n const files = await fg.glob(include, {\n cwd: root,\n ignore: exclude,\n absolute: true,\n });\n\n return files\n .sort()\n .map((absolutePath) => {\n const entryPath = normalizeFsPath(absolutePath);\n const relativePath = toPosix(path.relative(root, entryPath));\n const relativeFromPagesDir = toPosix(path.relative(pagesRoot, entryPath));\n\n if (\n relativeFromPagesDir.startsWith('../') ||\n relativeFromPagesDir === '..'\n ) {\n throw new Error(\n `[${PLUGIN_NAME}] Page is outside pagesDir: ${entryPath} (pagesDir: ${pagesDir})`,\n );\n }\n\n const dynamic = isDynamicPage(relativeFromPagesDir);\n const routePattern = toRoutePattern(relativeFromPagesDir, pageExtensions);\n const paramDefinitions = extractRouteParamDefinitions(routePattern);\n\n return {\n id: entryPath,\n entryPath,\n absolutePath: entryPath,\n relativePath,\n routePattern,\n routePath: routePattern,\n fileName: '',\n dynamic,\n paramNames: paramDefinitions.map((p) => p.name),\n paramDefinitions,\n params: {},\n } satisfies HtPageInfo;\n });\n}","import path from 'node:path';\n\nexport function toPosix(value: string): string {\n return value.replace(/\\\\/g, '/');\n}\n\nexport function normalizeFsPath(value: string): string {\n return path.normalize(value);\n}\n\nexport function normalizeRoutePath(value: string): string {\n const normalized = toPosix(value).replace(/\\/+/g, '/');\n if (!normalized || normalized === '/') return '/';\n return normalized.startsWith('/') ? normalized : `/${normalized}`;\n}\n\nexport function stripPageSuffix(\n filePath: string,\n extensions: string[],\n): string {\n const normalized = toPosix(filePath);\n\n const match = [...extensions]\n .sort((a, b) => b.length - a.length)\n .find((ext) => normalized.endsWith(ext));\n\n if (!match) return normalized;\n\n return normalized.slice(0, -match.length);\n}","import { normalizeRoutePath, stripPageSuffix, toPosix } from './path-utils';\nimport type { HtPageInfo, StaticParamRecord } from './types';\n\nconst DYNAMIC_SEGMENT_RE = /\\[([A-Za-z0-9_]+)\\]/g;\nconst CATCH_ALL_SEGMENT_RE = /\\[\\.\\.\\.([A-Za-z0-9_]+)\\]/g;\nconst OPTIONAL_CATCH_ALL_SEGMENT_RE = /\\[\\.\\.\\.([A-Za-z0-9_]+)\\]\\?/g;\nconst ANY_PARAM_RE = /\\[(?:\\.\\.\\.)?([A-Za-z0-9_]+)\\]\\??/g;\nconst ROUTE_GROUP_RE = /(^|\\/)\\(([^)]+)\\)(?=\\/|$)/g;\n\nexport function getParamNames(relativeFromPagesDir: string): string[] {\n return [...relativeFromPagesDir.matchAll(ANY_PARAM_RE)].map((m) => m[1]);\n}\n\nexport function isDynamicPage(relativeFromPagesDir: string): boolean {\n return /\\[(?:\\.\\.\\.)?[A-Za-z0-9_]+\\]\\??/.test(relativeFromPagesDir);\n}\n\nexport function toRoutePattern(\n relativeFromPagesDir: string,\n extensions: string[],\n): string {\n const noExt = stripPageSuffix(toPosix(relativeFromPagesDir), extensions);\n\n const withoutGroups = noExt.replace(ROUTE_GROUP_RE, '$1');\n const withoutIndex = withoutGroups.replace(/\\/index$/i, '').replace(/^index$/i, '');\n\n const raw = withoutIndex\n .replace(OPTIONAL_CATCH_ALL_SEGMENT_RE, '*?:$1')\n .replace(CATCH_ALL_SEGMENT_RE, '*:$1')\n .replace(DYNAMIC_SEGMENT_RE, ':$1');\n\n return normalizeRoutePath(raw || '/');\n}\n\nexport function fillParams(\n pattern: string,\n params: Record<string, string>,\n): string {\n const result = pattern\n .replace(/\\*\\?:([A-Za-z0-9_]+)/g, (_, key) => {\n const value = params[key];\n if (value == null || value === '') {\n return '';\n }\n\n return String(value)\n .split('/')\n .map((part) => encodeURIComponent(part))\n .join('/');\n })\n .replace(/\\*:([A-Za-z0-9_]+)/g, (_, key) => {\n if (!(key in params)) {\n throw new Error(`Missing catch-all route param \"${key}\"`);\n }\n\n return String(params[key])\n .split('/')\n .map((part) => encodeURIComponent(part))\n .join('/');\n })\n .replace(/:([A-Za-z0-9_]+)/g, (_, key) => {\n if (!(key in params)) {\n throw new Error(`Missing route param \"${key}\"`);\n }\n\n return encodeURIComponent(params[key]);\n });\n\n return normalizeRoutePath(result || '/');\n}\n\nexport function fileNameFromRoute(\n routePath: string,\n cleanUrls: boolean,\n): string {\n const normalized = normalizeRoutePath(routePath);\n\n if (normalized === '/') return 'index.html';\n\n const base = normalized.slice(1);\n return cleanUrls ? `${base}/index.html` : `${base}.html`;\n}\n\nexport function expandStaticPaths(\n basePage: Omit<HtPageInfo, 'routePath' | 'fileName' | 'params'>,\n rows: StaticParamRecord[],\n cleanUrls: boolean,\n): HtPageInfo[] {\n return rows.map((row) => {\n const params = Object.fromEntries(\n Object.entries(row).map(([k, v]) => [k, String(v)]),\n );\n\n const routePath = fillParams(basePage.routePattern, params);\n\n return {\n ...basePage,\n routePath,\n fileName: fileNameFromRoute(routePath, cleanUrls),\n params,\n };\n });\n}\n\nexport function routeMatch(\n pattern: string,\n urlPath: string,\n): Record<string, string> | null {\n const a = normalizeRoutePath(pattern).split('/').filter(Boolean);\n const b = normalizeRoutePath(urlPath).split('/').filter(Boolean);\n const params: Record<string, string> = {};\n\n for (let i = 0; i < a.length; i++) {\n const patternSeg = a[i];\n const urlSeg = b[i];\n\n if (patternSeg.startsWith('*?:')) {\n params[patternSeg.slice(3)] =\n i < b.length ? b.slice(i).map(decodeURIComponent).join('/') : '';\n return params;\n }\n\n if (patternSeg.startsWith('*:')) {\n const rest = b.slice(i);\n if (rest.length === 0) return null;\n\n params[patternSeg.slice(2)] = rest.map(decodeURIComponent).join('/');\n return params;\n }\n\n if (!urlSeg) return null;\n\n if (patternSeg.startsWith(':')) {\n params[patternSeg.slice(1)] = decodeURIComponent(urlSeg);\n continue;\n }\n\n if (patternSeg !== urlSeg) return null;\n }\n\n return a.length === b.length ? params : null;\n}\n\nexport function compareRoutePriority(a: string, b: string): number {\n const aSegs = normalizeRoutePath(a).split('/').filter(Boolean);\n const bSegs = normalizeRoutePath(b).split('/').filter(Boolean);\n const len = Math.max(aSegs.length, bSegs.length);\n\n for (let i = 0; i < len; i++) {\n const aa = aSegs[i];\n const bb = bSegs[i];\n\n if (aa == null) return 1;\n if (bb == null) return -1;\n\n const aOptionalCatchAll = aa.startsWith('*?:');\n const bOptionalCatchAll = bb.startsWith('*?:');\n if (aOptionalCatchAll !== bOptionalCatchAll) {\n return aOptionalCatchAll ? 1 : -1;\n }\n\n const aCatchAll = aa.startsWith('*:');\n const bCatchAll = bb.startsWith('*:');\n if (aCatchAll !== bCatchAll) {\n return aCatchAll ? 1 : -1;\n }\n\n const aDynamic = aa.startsWith(':');\n const bDynamic = bb.startsWith(':');\n if (aDynamic !== bDynamic) {\n return aDynamic ? 1 : -1;\n }\n }\n\n return bSegs.length - aSegs.length;\n}","import type { RouteParamDefinition } from './types';\n\nexport function parseRouteParamSegment(\n segment: string,\n): RouteParamDefinition | null {\n if (segment.startsWith('[...') && segment.endsWith(']?')) {\n return {\n name: segment.slice(4, -2),\n type: 'optional-catch-all',\n };\n }\n\n if (segment.startsWith('[...') && segment.endsWith(']')) {\n return {\n name: segment.slice(4, -1),\n type: 'catch-all',\n };\n }\n\n if (segment.startsWith('[') && segment.endsWith(']')) {\n return {\n name: segment.slice(1, -1),\n type: 'single',\n };\n }\n\n return null;\n}\n\nexport function extractRouteParamDefinitions(\n routePattern: string,\n): RouteParamDefinition[] {\n return routePattern\n .split('/')\n .filter(Boolean)\n .map((segment) => parseRouteParamSegment(segment))\n .filter((value): value is RouteParamDefinition => value != null);\n}","export const PLUGIN_NAME = 'vite-plugin-html-pages';\nexport const VIRTUAL_BUILD_ENTRY_ID = `\\0${PLUGIN_NAME}:build-entry`;\nexport const VIRTUAL_PAGE_HELPER_ID = `${PLUGIN_NAME}/page`;\nexport const RESOLVED_VIRTUAL_PAGE_HELPER_PREFIX =`\\0${PLUGIN_NAME}/page:`;\nexport const VIRTUAL_MANIFEST_ID = `\\0virtual:${PLUGIN_NAME}-manifest`;\nexport const CACHE_DIR_NAME = `node_modules/.cache/${PLUGIN_NAME}`;","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { ViteDevServer } from 'vite';\n\nimport { renderPage } from './render-runtime';\nimport type { HtPageInfo, HtPageModule } from './types';\nimport { PLUGIN_NAME } from './constants';\nimport { createPageModuleLoader } from './module-loader';\n\nfunction isStaticAssetRequest(url: string): boolean {\n return (\n url.endsWith('.css') ||\n url.endsWith('.js') ||\n url.endsWith('.mjs') ||\n url.endsWith('.ts') ||\n url.endsWith('.png') ||\n url.endsWith('.jpg') ||\n url.endsWith('.jpeg') ||\n url.endsWith('.gif') ||\n url.endsWith('.svg') ||\n url.endsWith('.webp') ||\n url.endsWith('.ico') ||\n url.endsWith('.woff') ||\n url.endsWith('.woff2') ||\n url.endsWith('.ttf') ||\n url.endsWith('.otf')\n );\n}\n\nfunction shouldSkipHtmlRouting(url: string): boolean {\n return (\n url.startsWith('/@vite') ||\n url.startsWith('/@fs/') ||\n url.startsWith('/node_modules/') ||\n url.startsWith('/src/') ||\n url === '/favicon.ico' ||\n isStaticAssetRequest(url)\n );\n}\n\nfunction tryRewriteRootAssetToSrc(server: ViteDevServer, url: string): string | null {\n if (!url.startsWith('/')) return null;\n if (!isStaticAssetRequest(url)) return null;\n if (url.startsWith('/src/')) return null;\n\n const root = server.config.root;\n const candidate = path.join(root, 'src', url.slice(1));\n\n if (fs.existsSync(candidate)) {\n return `/src/${url.slice(1)}`;\n }\n\n return null;\n}\n\nfunction shouldUseDynamicRendering(mod: HtPageModule): boolean {\n return mod.dynamic === true || mod.prerender === false;\n}\n\nexport function installDevServer(args: {\n server: ViteDevServer;\n getPages: () => Promise<HtPageInfo[]>;\n getEntries?: () => Promise<HtPageInfo[]>;\n}) {\n const { server, getPages } = args;\n\n server.middlewares.use(async (req, res, next) => {\n try {\n const originalUrl = req.url ?? '/';\n const url = originalUrl.split('?')[0];\n\n const rewrittenAssetUrl = tryRewriteRootAssetToSrc(server, url);\n if (rewrittenAssetUrl) {\n req.url = rewrittenAssetUrl + originalUrl.slice(url.length);\n return next();\n }\n\n if (shouldSkipHtmlRouting(url)) {\n return next();\n }\n\n const pages = await getPages();\n\n const page = pages.find((p) => p.routePath === url);\n\n if (!page) {\n return next();\n }\n\n const loadModule = await createPageModuleLoader({\n mode: 'dev',\n root: server.config.root,\n server,\n });\n\n const mod = await loadModule(page.entryPath, page.relativePath);\n\n if (!mod) {\n return next();\n }\n\n if (!shouldUseDynamicRendering(mod) && page.dynamic) {\n return next();\n }\n\n const html = await renderPage(page, mod, true);\n const transformedHtml = await server.transformIndexHtml(\n url,\n html,\n req.originalUrl,\n );\n \n res.statusCode = 200;\n res.setHeader('Content-Type', 'text/html; charset=utf-8');\n res.end(transformedHtml);\n } catch (error) {\n server.config.logger.error(\n `[${PLUGIN_NAME}] dev server render failed: ${\n error instanceof Error ? error.stack ?? error.message : String(error)\n }`,\n );\n\n next(error as Error);\n }\n });\n}","import type { HtPageInfo } from './types';\nimport { PLUGIN_NAME } from './constants';\nexport function invalidHtmlReturn(\n page: HtPageInfo,\n value: unknown,\n): Error {\n return new Error(\n `[${PLUGIN_NAME}] Page \"${page.relativePath}\" must resolve to an HTML string, got ${typeof value}`,\n );\n}\n\nexport function missingDefaultExport(page: HtPageInfo): Error {\n return new Error(\n `[${PLUGIN_NAME}] Page \"${page.relativePath}\" does not export a default renderer`,\n );\n}\n\nexport function pageError(page: HtPageInfo, cause: unknown): Error {\n const message = `[${PLUGIN_NAME}] Failed to render \"${page.relativePath}\" at route \"${page.routePath}\"`;\n\n if (cause instanceof Error) {\n const err = new Error(`${message}: ${cause.message}`);\n\n if (cause.stack) {\n err.stack = `${err.stack}\\nCaused by:\\n${cause.stack}`;\n }\n\n return err;\n }\n\n return new Error(`${message}: ${String(cause)}`);\n}","import { invalidHtmlReturn, pageError, missingDefaultExport } from './errors';\nimport type { HtPageInfo, HtPageModule, HtPageRenderContext } from './types';\n\nexport async function renderPage(\n page: HtPageInfo,\n mod: HtPageModule,\n dev = false,\n): Promise<string> {\n const ctx: HtPageRenderContext = {\n page,\n params: page.params,\n dev,\n };\n\n try {\n if (typeof mod.data === 'function') {\n ctx.data = await mod.data(ctx);\n }\n\n const entry = mod.default;\n\n if (entry == null) {\n throw missingDefaultExport(page);\n }\n\n const html = typeof entry === 'function' ? await entry(ctx) : entry;\n\n if (typeof html !== 'string') {\n throw invalidHtmlReturn(page, html);\n }\n\n return html;\n } catch (error) {\n throw pageError(page, error);\n }\n}","import path from 'node:path';\nimport { createServer, type InlineConfig, type ViteDevServer } from 'vite';\nimport type { HtPageModule } from './types';\n\nexport type PageModuleLoader = (\n entryPath: string,\n relativePath: string,\n) => Promise<HtPageModule>;\n\nlet buildServer: ViteDevServer | null = null;\n\nexport async function createPageModuleLoader(args: {\n mode: 'dev' | 'build';\n root: string;\n server?: ViteDevServer | null;\n}): Promise<PageModuleLoader> {\n const { mode, root, server } = args;\n\n if (mode === 'dev') {\n if (!server) {\n throw new Error('[vite-plugin-html-pages] dev server not available');\n }\n\n return async (_entryPath, relativePath) => {\n const mod = await server.ssrLoadModule(`/${relativePath}`);\n return mod as HtPageModule;\n };\n }\n\n if (!buildServer) {\n const config: InlineConfig = {\n root,\n configFile: false,\n logLevel: 'error',\n appType: 'custom',\n server: {\n middlewareMode: true,\n },\n };\n\n buildServer = await createServer(config);\n }\n\n return async (entryPath) => {\n const relativePath =\n '/' + path.relative(root, entryPath).replace(/\\\\/g, '/');\n\n const mod = await buildServer!.ssrLoadModule(relativePath);\n return mod as HtPageModule;\n };\n}\n\nexport async function closePageModuleLoader(): Promise<void> {\n if (buildServer) {\n await buildServer.close();\n buildServer = null;\n }\n}","import {\n compareRoutePriority,\n expandStaticPaths,\n fileNameFromRoute,\n} from './route-utils';\nimport type { HtPageInfo, HtPageModule, StaticParamRecord } from './types';\nimport { PLUGIN_NAME } from './constants';\nexport async function buildPageIndex(args: {\n entries: HtPageInfo[];\n modulesByEntry: Map<string, HtPageModule>;\n cleanUrls: boolean;\n}): Promise<HtPageInfo[]> {\n const { entries, modulesByEntry, cleanUrls } = args;\n const pages: HtPageInfo[] = [];\n\n for (const entry of entries) {\n const mod = modulesByEntry.get(entry.entryPath) ?? {};\n\n if (entry.dynamic) {\n const rows =\n (mod.generateStaticParams\n ? await mod.generateStaticParams()\n : []) ?? [];\n\n pages.push(\n ...expandStaticPaths(\n {\n id: entry.id,\n entryPath: entry.entryPath,\n absolutePath: entry.absolutePath,\n relativePath: entry.relativePath,\n routePattern: entry.routePattern,\n dynamic: entry.dynamic,\n paramNames: entry.paramNames,\n } as Omit<HtPageInfo, 'routePath' | 'fileName' | 'params'>,\n Array.isArray(rows) ? rows : [],\n cleanUrls,\n ),\n );\n } else {\n pages.push({\n ...entry,\n routePath: entry.routePattern,\n fileName: fileNameFromRoute(entry.routePattern, cleanUrls),\n params: {},\n });\n }\n }\n\n pages.sort((a, b) => compareRoutePriority(a.routePattern, b.routePattern));\n\n const seenRoutes = new Map<string, HtPageInfo>();\n\n for (const page of pages) {\n const existing = seenRoutes.get(page.routePath);\n\n if (existing) {\n throw new Error(\n `[${PLUGIN_NAME}] Duplicate route generated: \"${page.routePath}\" from \"${existing.relativePath}\" and \"${page.relativePath}\"`,\n );\n }\n\n seenRoutes.set(page.routePath, page);\n }\n\n return pages;\n}","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport fg from 'fast-glob';\nimport * as esbuild from 'esbuild';\nimport fsSync from 'node:fs';\n\nexport interface StaticAssetFile {\n absolutePath: string;\n relativePathFromSrc: string;\n outputFileName: string;\n kind: 'copy' | 'process';\n}\n\nexport interface CollectStaticAssetsArgs {\n root: string;\n pagesDir: string;\n pageExtensions: string[];\n}\n\nfunction normalizeSlashes(value: string): string {\n return value.replace(/\\\\/g, '/');\n}\n\nfunction hasAnySuffix(value: string, suffixes: string[]): boolean {\n return suffixes.some((suffix) => value.endsWith(suffix));\n}\n\nfunction shouldIgnoreFile(rel: string): boolean {\n return (\n rel.endsWith('.d.ts') ||\n rel.endsWith('.map') ||\n rel.endsWith('.tsbuildinfo') ||\n rel.startsWith('.') ||\n rel.includes('/.')\n );\n}\n\nfunction isProcessableAsset(rel: string): boolean {\n return (\n rel.endsWith('.js') ||\n rel.endsWith('.mjs') ||\n rel.endsWith('.ts') ||\n rel.endsWith('.css')\n );\n}\n\nfunction toOutputFileName(relativePathFromSrc: string): string {\n if (relativePathFromSrc.endsWith('.ts')) {\n return relativePathFromSrc.slice(0, -3) + '.js';\n }\n return relativePathFromSrc;\n}\n\nexport async function collectStaticAssets(\n args: CollectStaticAssetsArgs,\n): Promise<StaticAssetFile[]> {\n const { root, pagesDir, pageExtensions } = args;\n const srcDir = path.join(root, pagesDir);\n\n const entries = await fg('**/*', {\n cwd: srcDir,\n onlyFiles: true,\n dot: false,\n absolute: false,\n });\n\n const assets: StaticAssetFile[] = [];\n\n for (const entry of entries) {\n const rel = normalizeSlashes(entry);\n\n if (shouldIgnoreFile(rel)) continue;\n if (hasAnySuffix(rel, pageExtensions)) continue;\n\n const absolutePath = path.join(srcDir, rel);\n\n assets.push({\n absolutePath,\n relativePathFromSrc: rel,\n outputFileName: normalizeSlashes(toOutputFileName(rel)),\n kind: isProcessableAsset(rel) ? 'process' : 'copy',\n });\n }\n\n return assets;\n}\n\nexport async function copyStaticAssetSource(\n asset: StaticAssetFile,\n): Promise<Uint8Array> {\n return fs.readFile(asset.absolutePath);\n}\n\nexport async function buildProcessedStaticAssets(args: {\n root: string;\n pagesDir: string;\n assets: StaticAssetFile[];\n minify?: boolean;\n sourcemap?: boolean;\n }): Promise<Map<string, string | Uint8Array>> {\n const { root, pagesDir, assets, minify = true, sourcemap = false } = args;\n \n const processable = assets.filter((a) => a.kind === 'process');\n const out = new Map<string, string | Uint8Array>();\n \n if (processable.length === 0) {\n return out;\n }\n \n const srcDir = path.join(root, pagesDir);\n const distDir = path.join(root, 'dist');\n const warnedMissingAssets = new Set<string>();\n const result = await esbuild.build({\n entryPoints: processable.map((a) => a.absolutePath),\n absWorkingDir: root,\n outbase: srcDir,\n outdir: distDir,\n bundle: true,\n splitting: true,\n treeShaking: true,\n minify,\n sourcemap,\n format: 'esm',\n target: 'es2020',\n platform: 'browser',\n write: false,\n entryNames: '[dir]/[name]',\n assetNames: '[dir]/[name]',\n loader: {\n '.css': 'css',\n '.png': 'file',\n '.jpg': 'file',\n '.jpeg': 'file',\n '.gif': 'file',\n '.svg': 'file',\n '.webp': 'file',\n '.woff': 'file',\n '.woff2': 'file',\n '.ttf': 'file',\n '.otf': 'file',\n },\n plugins: [\n {\n name: 'html-pages-root-url-resolver',\n setup(build) {\n build.onResolve({ filter: /^\\// }, (resolveArgs) => {\n // Leave real filesystem absolute paths alone\n if (\n path.isAbsolute(resolveArgs.path) &&\n fsSync.existsSync(resolveArgs.path)\n ) {\n return { path: resolveArgs.path };\n }\n \n const cleanPath = resolveArgs.path.slice(1);\n \n const fromSrc = path.join(srcDir, cleanPath);\n if (fsSync.existsSync(fromSrc)) {\n return { path: fromSrc };\n }\n \n const fromPublic = path.join(root, 'public', cleanPath);\n if (fsSync.existsSync(fromPublic)) {\n return {\n path: resolveArgs.path,\n external: true,\n };\n }\n \n const isCssUrlToken = resolveArgs.kind === 'url-token';\n \n if (isCssUrlToken) {\n if (!warnedMissingAssets.has(resolveArgs.path)) {\n warnedMissingAssets.add(resolveArgs.path);\n console.warn(\n `[vite-plugin-html-pages] ⚠️ Missing CSS asset: ${resolveArgs.path}\\n` +\n ` Looked in:\\n` +\n ` - ${fromSrc}\\n` +\n ` - ${fromPublic}`\n );\n }\n \n // Keep the original root-relative URL in output CSS\n return {\n path: resolveArgs.path,\n external: true,\n };\n }\n \n // JS/CSS entry imports remain strict\n return {\n path: fromSrc,\n };\n });\n },\n },\n ],\n });\n \n for (const file of result.outputFiles) {\n const rel = normalizeSlashes(path.relative(distDir, file.path));\n out.set(rel, file.text ?? file.contents);\n }\n \n return out;\n }\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nexport interface HtmlAssetValidationOptions {\n root: string;\n pagesDir: string;\n html: string;\n pluginName: string;\n pageLabel?: string;\n missingAssets?: 'error' | 'warn';\n}\n\nfunction stripQueryAndHash(url: string): string {\n return url.split('#')[0].split('?')[0];\n}\n\nfunction isLocalRootUrl(url: string): boolean {\n return !!url && url.startsWith('/') && !url.startsWith('//');\n}\n\nfunction fileExistsForPublicUrl(root: string, pagesDir: string, url: string): boolean {\n const clean = stripQueryAndHash(url).slice(1);\n\n const fromSrc = path.join(root, pagesDir, clean);\n if (fs.existsSync(fromSrc)) return true;\n\n const fromPublic = path.join(root, 'public', clean);\n if (fs.existsSync(fromPublic)) return true;\n\n return false;\n}\n\nfunction collectScriptSrcs(html: string): string[] {\n const out: string[] = [];\n\n for (const match of html.matchAll(\n /<script\\b[^>]*\\bsrc=[\"']([^\"']+)[\"'][^>]*>/gi,\n )) {\n out.push(match[1]);\n }\n\n return out;\n}\n\nfunction collectStylesheetHrefs(html: string): string[] {\n const out: string[] = [];\n\n for (const match of html.matchAll(\n /<link\\b[^>]*\\brel=[\"']stylesheet[\"'][^>]*\\bhref=[\"']([^\"']+)[\"'][^>]*>/gi,\n )) {\n out.push(match[1]);\n }\n\n return out;\n}\n\nfunction collectLiteralDynamicImports(html: string): string[] {\n const out: string[] = [];\n\n for (const match of html.matchAll(\n /import\\s*\\(\\s*[\"']([^\"'`]+)[\"']\\s*\\)/gi,\n )) {\n out.push(match[1]);\n }\n\n return out;\n}\n\nfunction unique(values: string[]): string[] {\n return [...new Set(values)];\n}\n\nfunction formatPageLabel(pageLabel?: string): string {\n return pageLabel ? ` (${pageLabel})` : '';\n}\n\nfunction missingAssetMessage(args: {\n pluginName: string;\n kind: string;\n url: string;\n root: string;\n pagesDir: string;\n pageLabel?: string;\n}): string {\n const { pluginName, kind, url, root, pagesDir, pageLabel } = args;\n const clean = stripQueryAndHash(url).slice(1);\n const pageSuffix = formatPageLabel(pageLabel);\n\n return (\n `[${pluginName}] Missing ${kind}${pageSuffix}: ${url}\\n` +\n `Expected one of:\\n` +\n `- ${path.join(root, pagesDir, clean)}\\n` +\n `- ${path.join(root, 'public', clean)}`\n );\n}\n\nfunction reportMissing(args: {\n mode: 'error' | 'warn';\n pluginName: string;\n kind: string;\n url: string;\n root: string;\n pagesDir: string;\n pageLabel?: string;\n}) {\n const message = missingAssetMessage(args);\n\n if (args.mode === 'warn') {\n console.warn(`⚠️ ${message}`);\n return;\n }\n\n throw new Error(message);\n}\n\nexport function validateHtmlAssetReferences(\n options: HtmlAssetValidationOptions,\n): void {\n const {\n root,\n pagesDir,\n html,\n pluginName,\n pageLabel,\n missingAssets = 'error',\n } = options;\n\n const scriptSrcs = unique(collectScriptSrcs(html)).filter(isLocalRootUrl);\n const stylesheetHrefs = unique(collectStylesheetHrefs(html)).filter(isLocalRootUrl);\n const literalDynamicImports = unique(collectLiteralDynamicImports(html)).filter(\n isLocalRootUrl,\n );\n\n for (const url of scriptSrcs) {\n if (!fileExistsForPublicUrl(root, pagesDir, url)) {\n reportMissing({\n mode: missingAssets,\n pluginName,\n kind: 'JavaScript asset',\n url,\n root,\n pagesDir,\n pageLabel,\n });\n }\n }\n\n for (const url of stylesheetHrefs) {\n if (!fileExistsForPublicUrl(root, pagesDir, url)) {\n reportMissing({\n mode: missingAssets,\n pluginName,\n kind: 'stylesheet asset',\n url,\n root,\n pagesDir,\n pageLabel,\n });\n }\n }\n\n for (const url of literalDynamicImports) {\n if (!fileExistsForPublicUrl(root, pagesDir, url)) {\n console.warn(\n `⚠️ ${missingAssetMessage({\n pluginName,\n kind: 'literal dynamic import',\n url,\n root,\n pagesDir,\n pageLabel,\n })}`,\n );\n }\n }\n}","import type { HtPageInfo, RouteParamDefinition } from './types';\n\nfunction paramsTypeFromDefinitions(\n paramDefinitions: RouteParamDefinition[],\n): string {\n if (paramDefinitions.length === 0) {\n return '{}';\n }\n\n const fields = paramDefinitions.map((param) => {\n if (param.type === 'single') {\n return `${JSON.stringify(param.name)}: string`;\n }\n\n if (param.type === 'catch-all') {\n return `${JSON.stringify(param.name)}: string[]`;\n }\n\n return `${JSON.stringify(param.name)}?: string[]`;\n });\n\n return `{ ${fields.join('; ')} }`;\n}\n\nexport function generateTypedPageHelper(page: HtPageInfo | undefined): string {\n const paramsType = page\n ? paramsTypeFromDefinitions(page.paramDefinitions ?? [])\n : '{}';\n\n return `\nexport type PageParams = ${paramsType};\n\nexport type PageContext = {\n params: PageParams;\n data?: unknown;\n dev: boolean;\n};\n\nexport function definePage<T extends (ctx: PageContext) => any>(fn: T): T {\n return fn;\n}\n`;\n}","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { createHash } from 'node:crypto';\nimport { CACHE_DIR_NAME } from './constants';\n\nexport type FetchCacheMode = 'auto' | 'memory' | 'fs' | 'none';\nexport interface FetchWithCacheOptions {\n maxAge?: number;\n cacheKey?: string;\n forceRefresh?: boolean;\n cache?: FetchCacheMode;\n}\n\ntype CachedResponseRecord = {\n timestamp: number;\n status: number;\n statusText: string;\n headers: [string, string][];\n body: string;\n};\n\nconst memoryCache = new Map<string, CachedResponseRecord>();\n\nfunction createDefaultCacheKey(\n input: RequestInfo | URL,\n init?: RequestInit,\n): string {\n const raw = JSON.stringify({\n url: String(input),\n method: init?.method ?? 'GET',\n headers: init?.headers ?? {},\n body: init?.body ?? null,\n });\n\n return createHash('sha256').update(raw).digest('hex');\n}\n\nfunction getCacheFilePath(cacheKey: string): string {\n return path.join(process.cwd(), CACHE_DIR_NAME, 'fetch', `${cacheKey}.json`);\n}\n\nfunction getEffectiveCacheMode(\n mode: FetchCacheMode | undefined,\n): Exclude<FetchCacheMode, 'auto'> {\n if (mode === 'memory' || mode === 'fs' || mode === 'none') {\n return mode;\n }\n\n return process.env.NODE_ENV === 'production' ? 'fs' : 'memory';\n}\n\nfunction toResponse(cached: CachedResponseRecord): Response {\n return new Response(cached.body, {\n status: cached.status,\n statusText: cached.statusText,\n headers: cached.headers,\n });\n}\n\nfunction isFresh(cached: CachedResponseRecord, maxAgeSeconds: number): boolean {\n const ageSeconds = (Date.now() - cached.timestamp) / 1000;\n return ageSeconds <= maxAgeSeconds;\n}\n\nexport function clearMemoryFetchCache(): void {\n memoryCache.clear();\n}\n\nexport function deleteMemoryFetchCache(cacheKey: string): void {\n memoryCache.delete(cacheKey);\n}\n\nexport async function fetchWithCache(\n input: RequestInfo | URL,\n init?: RequestInit,\n options: FetchWithCacheOptions = {},\n): Promise<Response> {\n const maxAge = options.maxAge ?? 60 * 60;\n const method = (init?.method ?? 'GET').toUpperCase();\n\n if (method !== 'GET' && !options.cacheKey) {\n return fetch(input, init);\n }\n\n const cacheMode = getEffectiveCacheMode(options.cache);\n const cacheKey = options.cacheKey ?? createDefaultCacheKey(input, init);\n\n if (cacheMode === 'none') {\n return fetch(input, init);\n }\n\n if (cacheMode === 'memory' && !options.forceRefresh) {\n const cached = memoryCache.get(cacheKey);\n\n if (cached && isFresh(cached, maxAge)) {\n return toResponse(cached);\n }\n }\n\n const filePath = getCacheFilePath(cacheKey);\n\n if (cacheMode === 'fs') {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n\n if (!options.forceRefresh) {\n try {\n const raw = await fs.readFile(filePath, 'utf8');\n const cached = JSON.parse(raw) as CachedResponseRecord;\n\n if (isFresh(cached, maxAge)) {\n return toResponse(cached);\n }\n } catch {\n // cache miss or invalid cache; fetch fresh\n }\n }\n }\n\n const res = await fetch(input, init);\n const body = await res.text();\n\n const record: CachedResponseRecord = {\n timestamp: Date.now(),\n status: res.status,\n statusText: res.statusText,\n headers: [...res.headers.entries()],\n body,\n };\n\n if (cacheMode === 'memory') {\n memoryCache.set(cacheKey, record);\n } else if (cacheMode === 'fs') {\n await fs.writeFile(filePath, JSON.stringify(record), 'utf8');\n }\n\n return new Response(body, {\n status: res.status,\n statusText: res.statusText,\n headers: res.headers,\n });\n}\n"],"mappings":"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","names":["path","fg","path","path","path","path","fs","path","build","fs","path","fs","path","fs","path","path","fs","path"]}
|
|
1
|
+
{"version":3,"sources":["../src/plugin.ts","../src/discover.ts","../src/path-utils.ts","../src/route-utils.ts","../src/route-params.ts","../src/constants.ts","../src/dev-server.ts","../src/errors.ts","../src/render-runtime.ts","../src/module-loader.ts","../src/page-index.ts","../src/static-assets.ts","../src/html-asset-validator.ts","../src/page-helper-generator.ts","../src/fetch-cache.ts"],"sourcesContent":["import pLimit from 'p-limit';\nimport type { Plugin, ViteDevServer } from 'vite';\n\nimport { discoverEntryPages } from './discover';\nimport { installDevServer } from './dev-server';\nimport { createPageModuleLoader, closePageModuleLoader } from './module-loader';\nimport { buildPageIndex } from './page-index';\nimport { renderPage } from './render-runtime';\nimport {\n buildProcessedStaticAssets,\n collectStaticAssets,\n copyStaticAssetSource,\n} from './static-assets';\nimport { validateHtmlAssetReferences } from './html-asset-validator';\nimport type { HtPageInfo, HtPageModule, HtPagesPluginOptions } from './types';\nimport {\n PLUGIN_NAME,\n VIRTUAL_BUILD_ENTRY_ID,\n VIRTUAL_PAGE_HELPER_ID,\n RESOLVED_VIRTUAL_PAGE_HELPER_PREFIX,\n} from './constants';\nimport { generateTypedPageHelper } from './page-helper-generator';\n\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nlet hasWarnedESM = false;\n\nfunction warnIfNotESM(root: string) {\n try {\n const pkgPath = path.join(root, 'package.json');\n\n if (!fs.existsSync(pkgPath)) return;\n\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));\n\n if (pkg.type !== 'module') {\n console.warn(\n `[${PLUGIN_NAME}] ⚠️ It is recommended to add \"type\": \"module\" to your package.json for optimal performance and to avoid Node ESM warnings.`,\n );\n }\n } catch {\n // silent — never break build\n }\n}\n\nfunction chunkArray<T>(items: T[], size: number): T[][] {\n const out: T[][] = [];\n for (let i = 0; i < items.length; i += size) {\n out.push(items.slice(i, i + size));\n }\n return out;\n}\n\nexport function htPages(options: HtPagesPluginOptions = {}): Plugin {\n let root = process.cwd();\n let server: ViteDevServer | null = null;\n let devPages: HtPageInfo[] = [];\n let watcherAttached = false;\n\n const cleanUrls = options.cleanUrls ?? true;\n const pagesDir = options.pagesDir ?? 'src';\n const pageExtensions = options.pageExtensions?.length\n ? options.pageExtensions\n : ['.ht.js', '.html.js', '.ht.ts', '.html.ts'];\n\n function logDebug(enabled: boolean | undefined, ...args: unknown[]) {\n if (!enabled) return;\n console.log(`[${PLUGIN_NAME}]`, ...args);\n }\n\n async function loadDevPages(): Promise<HtPageInfo[]> {\n const entries = await discoverEntryPages(root, options);\n const modulesByEntry = new Map<string, HtPageModule>();\n\n logDebug(\n options.debug,\n 'discovered entries',\n entries.map((e) => e.relativePath),\n );\n\n if (!server) return [];\n\n const loadModule = await createPageModuleLoader({\n mode: 'dev',\n root,\n server,\n });\n\n for (const entry of entries) {\n const mod = await loadModule(entry.entryPath, entry.relativePath);\n modulesByEntry.set(entry.entryPath, mod);\n }\n\n devPages = await buildPageIndex({\n entries,\n modulesByEntry,\n cleanUrls,\n });\n\n logDebug(\n options.debug,\n 'dev pages',\n devPages.map((p) => `${p.routePath} -> ${p.relativePath}`),\n );\n\n return devPages;\n }\n\n async function buildPagesPipeline() {\n const entries = await discoverEntryPages(root, options);\n const modulesByEntry = new Map<string, HtPageModule>();\n\n const loadModule = await createPageModuleLoader({\n mode: 'build',\n root,\n });\n\n for (const entry of entries) {\n const mod = await loadModule(entry.entryPath, entry.relativePath);\n modulesByEntry.set(entry.entryPath, mod);\n }\n\n const pages = await buildPageIndex({\n entries,\n modulesByEntry,\n cleanUrls,\n });\n\n return { entries, modulesByEntry, pages };\n }\n\n return {\n name: PLUGIN_NAME,\n\n config(userConfig, env) {\n if (env.command !== 'build') return;\n\n const hasExplicitInput = userConfig.build?.rollupOptions?.input != null;\n if (hasExplicitInput) return;\n\n return {\n build: {\n rollupOptions: {\n input: VIRTUAL_BUILD_ENTRY_ID,\n },\n },\n };\n },\n\n resolveId(id, importer) {\n if (id === VIRTUAL_BUILD_ENTRY_ID) return id;\n \n if (id === VIRTUAL_PAGE_HELPER_ID && importer) {\n return `${RESOLVED_VIRTUAL_PAGE_HELPER_PREFIX}${importer}`;\n }\n \n return null;\n },\n\n async load(id) {\n if (id === VIRTUAL_BUILD_ENTRY_ID) {\n return 'export default {};';\n }\n \n if (id.startsWith(RESOLVED_VIRTUAL_PAGE_HELPER_PREFIX)) {\n const importer = id.slice(RESOLVED_VIRTUAL_PAGE_HELPER_PREFIX.length);\n const { pages } = await buildPagesPipeline();\n \n const normalizedImporter = path.resolve(importer);\n \n const page = pages.find(\n (candidate) => path.resolve(candidate.absolutePath) === normalizedImporter,\n );\n \n return generateTypedPageHelper(page);\n }\n \n return null;\n },\n\n configResolved(resolved) {\n root = options.root ? path.resolve(resolved.root, options.root) : resolved.root;\n \n if (!hasWarnedESM) {\n warnIfNotESM(root);\n hasWarnedESM = true;\n }\n },\n\n async buildStart() {\n const entries = await discoverEntryPages(root, options);\n\n for (const entry of entries) {\n this.addWatchFile(entry.entryPath);\n }\n\n const staticAssets = await collectStaticAssets({\n root,\n pagesDir,\n pageExtensions,\n });\n\n for (const asset of staticAssets) {\n this.addWatchFile(asset.absolutePath);\n }\n\n logDebug(\n options.debug,\n 'static assets',\n staticAssets.map((asset) => ({\n kind: asset.kind,\n input: asset.relativePathFromSrc,\n output: asset.outputFileName,\n })),\n );\n },\n\n configureServer(_server) {\n server = _server;\n \n installDevServer({\n server,\n root,\n pagesDir,\n getPages: async () => {\n if (devPages.length > 0) return devPages;\n return loadDevPages();\n },\n getEntries: async () => discoverEntryPages(root, options),\n });\n \n if (!watcherAttached) {\n watcherAttached = true;\n \n const reload = async (file: string) => {\n if (!file.includes(`${path.sep}src${path.sep}`) && !file.includes('/src/')) {\n return;\n }\n \n logDebug(options.debug, 'file changed', file);\n \n await loadDevPages();\n \n server?.ws.send({ type: 'full-reload' });\n\n };\n \n server.watcher.on('add', reload);\n server.watcher.on('change', reload);\n server.watcher.on('unlink', reload);\n }\n \n loadDevPages().catch((error) => {\n server?.config.logger.error(\n `[${PLUGIN_NAME}] loadDevPages failed: ${\n error instanceof Error ? error.stack ?? error.message : String(error)\n }`,\n );\n });\n },\n\n // async handleHotUpdate(ctx) {\n // if (!server) return;\n \n // logDebug(options.debug, 'file changed', ctx.file);\n \n // await loadDevPages();\n \n // server.ws.send({\n // type: 'full-reload',\n // });\n \n // return [];\n // },\n\n async generateBundle(_, bundle) {\n try {\n const { modulesByEntry, pages } = await buildPagesPipeline();\n\n const staticAssets = await collectStaticAssets({\n root,\n pagesDir,\n pageExtensions,\n });\n\n logDebug(\n options.debug,\n 'emitting pages',\n pages.map((p) => p.fileName),\n );\n\n logDebug(\n options.debug,\n 'emitting static assets',\n staticAssets.map((asset) => ({\n kind: asset.kind,\n input: asset.relativePathFromSrc,\n output: asset.outputFileName,\n })),\n );\n\n const limit = pLimit(options.renderConcurrency ?? 8);\n const batchSize =\n options.renderBatchSize ??\n Math.max(options.renderConcurrency ?? 8, 32);\n\n const processedOutputs = await buildProcessedStaticAssets({\n root,\n pagesDir,\n assets: staticAssets,\n minify: true,\n sourcemap: false,\n });\n\n for (const [fileName, source] of processedOutputs) {\n this.emitFile({\n type: 'asset',\n fileName,\n source,\n });\n }\n\n for (const asset of staticAssets) {\n if (asset.kind !== 'copy') continue;\n\n const source = await copyStaticAssetSource(asset);\n\n this.emitFile({\n type: 'asset',\n fileName: asset.outputFileName,\n source,\n });\n }\n\n for (const batch of chunkArray(pages, batchSize)) {\n await Promise.all(\n batch.map((page) =>\n limit(async () => {\n const mod = modulesByEntry.get(page.entryPath);\n\n if (!mod) {\n throw new Error(\n `[${PLUGIN_NAME}] Missing module for page entry: ${page.entryPath}`,\n );\n }\n\n const html = await renderPage(page, mod, false);\n\n validateHtmlAssetReferences({\n root,\n pagesDir,\n html,\n pluginName: PLUGIN_NAME,\n pageLabel: page.relativePath,\n missingAssets: options.missingAssets ?? 'error',\n });\n \n this.emitFile({\n type: 'asset',\n fileName: options.mapOutputPath?.(page) ?? page.fileName,\n source: html,\n });\n }),\n ),\n );\n }\n\n const notFoundPage = pages.find((p) => p.routePath === '/404');\n\n if (notFoundPage) {\n const mod = modulesByEntry.get(notFoundPage.entryPath);\n\n if (!mod) {\n throw new Error(\n `[${PLUGIN_NAME}] Missing module for 404 page entry: ${notFoundPage.entryPath}`,\n );\n }\n\n const html = await renderPage(notFoundPage, mod, false);\n\n validateHtmlAssetReferences({\n root,\n pagesDir,\n html,\n pluginName: PLUGIN_NAME,\n pageLabel: notFoundPage.relativePath,\n missingAssets: options.missingAssets ?? 'error',\n });\n \n this.emitFile({\n type: 'asset',\n fileName: '404.html',\n source: html,\n });\n\n logDebug(options.debug, 'generated 404.html from user page');\n } else {\n const default404 = `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>404 - Page Not Found</title>\n <style>\n :root {\n color-scheme: light dark;\n }\n body {\n margin: 0;\n font-family: system-ui, sans-serif;\n min-height: 100vh;\n display: grid;\n place-items: center;\n padding: 2rem;\n }\n main {\n max-width: 40rem;\n text-align: center;\n }\n h1 {\n font-size: 3rem;\n margin: 0 0 1rem;\n }\n p {\n margin: 0.5rem 0;\n line-height: 1.5;\n }\n a {\n color: inherit;\n }\n </style>\n </head>\n <body>\n <main>\n <h1>404</h1>\n <p>Page not found.</p>\n <p><a href=\"/\">Go back home</a></p>\n </main>\n </body>\n</html>\n`;\n\n this.emitFile({\n type: 'asset',\n fileName: '404.html',\n source: default404,\n });\n\n logDebug(options.debug, 'generated default 404.html');\n }\n\n const sitemapBase = options.site ?? '';\n\n const sitemapRoutes = [...new Set(pages.map((p) => p.routePath))].filter(\n (route) => !route.includes(':') && !route.includes('*'),\n );\n\n if (sitemapBase && sitemapRoutes.length > 0) {\n const sitemap = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\\n${sitemapRoutes\n .map((route) => ` <url><loc>${sitemapBase}${route}</loc></url>`)\n .join('\\n')}\\n</urlset>\\n`;\n\n this.emitFile({\n type: 'asset',\n fileName: 'sitemap.xml',\n source: sitemap,\n });\n\n logDebug(options.debug, 'generated sitemap.xml');\n }\n\n const rss = options.rss;\n\n if (rss?.site) {\n const routePrefix = rss.routePrefix ?? '/blog';\n \n const rssItems = pages\n .filter((page) => page.routePath.startsWith(routePrefix))\n .map((page) => {\n const url = `${rss.site}${page.routePath}`;\n \n return ` <item>\\n <title>${page.routePath}</title>\\n <link>${url}</link>\\n <guid>${url}</guid>\\n </item>`;\n })\n .join('\\n');\n \n const rssXml = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<rss version=\"2.0\">\\n<channel>\\n <title>${rss.title ?? PLUGIN_NAME}</title>\\n <link>${rss.site}</link>\\n <description>${rss.description ?? 'RSS feed'}</description>\\n${rssItems}\\n</channel>\\n</rss>\\n`;\n \n this.emitFile({\n type: 'asset',\n fileName: 'rss.xml',\n source: rssXml,\n });\n \n logDebug(options.debug, 'generated rss.xml');\n }\n\n for (const [fileName, output] of Object.entries(bundle)) {\n if (\n output.type === 'chunk' &&\n output.facadeModuleId === VIRTUAL_BUILD_ENTRY_ID\n ) {\n delete bundle[fileName];\n }\n }\n } finally {\n await closePageModuleLoader();\n }\n }\n };\n}\n\nexport default htPages;\n","import path from 'node:path';\nimport { normalizeFsPath, toPosix } from './path-utils';\nimport { isDynamicPage, toRoutePattern } from './route-utils';\nimport { extractRouteParamDefinitions } from './route-params';\nimport type { HtPageInfo, HtPagesPluginOptions } from './types';\nimport { PLUGIN_NAME } from './constants';\n\nfunction buildDefaultIncludeGlobs(\n pagesDir: string,\n pageExtensions: string[],\n): string[] {\n return pageExtensions.map((ext) => {\n const cleanExt = ext.startsWith('.') ? ext.slice(1) : ext;\n return `${pagesDir}/**/*.${cleanExt}`;\n });\n}\n\nexport async function discoverEntryPages(\n root: string,\n options: HtPagesPluginOptions,\n): Promise<HtPageInfo[]> {\n const fgModule = await import('fast-glob');\n const fg = (fgModule.default ?? fgModule) as typeof import('fast-glob');\n\n const pagesDir = options.pagesDir ?? 'src';\n const pageExtensions = options.pageExtensions?.length\n ? options.pageExtensions\n : ['.ht.js', '.html.js', '.ht.ts', '.html.ts'];\n\n const include = Array.isArray(options.include)\n ? options.include\n : options.include\n ? [options.include]\n : buildDefaultIncludeGlobs(pagesDir, pageExtensions);\n\n const exclude = Array.isArray(options.exclude)\n ? options.exclude\n : options.exclude\n ? [options.exclude]\n : [];\n\n const pagesRoot = normalizeFsPath(path.join(root, pagesDir));\n\n const files = await fg.glob(include, {\n cwd: root,\n ignore: exclude,\n absolute: true,\n });\n\n return files\n .sort()\n .map((absolutePath) => {\n const entryPath = normalizeFsPath(absolutePath);\n const relativePath = toPosix(path.relative(root, entryPath));\n const relativeFromPagesDir = toPosix(path.relative(pagesRoot, entryPath));\n\n if (\n relativeFromPagesDir.startsWith('../') ||\n relativeFromPagesDir === '..'\n ) {\n throw new Error(\n `[${PLUGIN_NAME}] Page is outside pagesDir: ${entryPath} (pagesDir: ${pagesDir})`,\n );\n }\n\n const dynamic = isDynamicPage(relativeFromPagesDir);\n const routePattern = toRoutePattern(relativeFromPagesDir, pageExtensions);\n const paramDefinitions = extractRouteParamDefinitions(routePattern);\n\n return {\n id: entryPath,\n entryPath,\n absolutePath: entryPath,\n relativePath,\n routePattern,\n routePath: routePattern,\n fileName: '',\n dynamic,\n paramNames: paramDefinitions.map((p) => p.name),\n paramDefinitions,\n params: {},\n } satisfies HtPageInfo;\n });\n}","import path from 'node:path';\n\nexport function toPosix(value: string): string {\n return value.replace(/\\\\/g, '/');\n}\n\nexport function normalizeFsPath(value: string): string {\n return path.normalize(value);\n}\n\nexport function normalizeRoutePath(value: string): string {\n const normalized = toPosix(value).replace(/\\/+/g, '/');\n if (!normalized || normalized === '/') return '/';\n return normalized.startsWith('/') ? normalized : `/${normalized}`;\n}\n\nexport function stripPageSuffix(\n filePath: string,\n extensions: string[],\n): string {\n const normalized = toPosix(filePath);\n\n const match = [...extensions]\n .sort((a, b) => b.length - a.length)\n .find((ext) => normalized.endsWith(ext));\n\n if (!match) return normalized;\n\n return normalized.slice(0, -match.length);\n}","import { normalizeRoutePath, stripPageSuffix, toPosix } from './path-utils';\nimport type { HtPageInfo, StaticParamRecord } from './types';\n\nconst DYNAMIC_SEGMENT_RE = /\\[([A-Za-z0-9_]+)\\]/g;\nconst CATCH_ALL_SEGMENT_RE = /\\[\\.\\.\\.([A-Za-z0-9_]+)\\]/g;\nconst OPTIONAL_CATCH_ALL_SEGMENT_RE = /\\[\\.\\.\\.([A-Za-z0-9_]+)\\]\\?/g;\nconst ANY_PARAM_RE = /\\[(?:\\.\\.\\.)?([A-Za-z0-9_]+)\\]\\??/g;\nconst ROUTE_GROUP_RE = /(^|\\/)\\(([^)]+)\\)(?=\\/|$)/g;\n\nexport function getParamNames(relativeFromPagesDir: string): string[] {\n return [...relativeFromPagesDir.matchAll(ANY_PARAM_RE)].map((m) => m[1]);\n}\n\nexport function isDynamicPage(relativeFromPagesDir: string): boolean {\n return /\\[(?:\\.\\.\\.)?[A-Za-z0-9_]+\\]\\??/.test(relativeFromPagesDir);\n}\n\nexport function toRoutePattern(\n relativeFromPagesDir: string,\n extensions: string[],\n): string {\n const noExt = stripPageSuffix(toPosix(relativeFromPagesDir), extensions);\n\n const withoutGroups = noExt.replace(ROUTE_GROUP_RE, '$1');\n const withoutIndex = withoutGroups.replace(/\\/index$/i, '').replace(/^index$/i, '');\n\n const raw = withoutIndex\n .replace(OPTIONAL_CATCH_ALL_SEGMENT_RE, '*?:$1')\n .replace(CATCH_ALL_SEGMENT_RE, '*:$1')\n .replace(DYNAMIC_SEGMENT_RE, ':$1');\n\n return normalizeRoutePath(raw || '/');\n}\n\nexport function fillParams(\n pattern: string,\n params: Record<string, string>,\n): string {\n const result = pattern\n .replace(/\\*\\?:([A-Za-z0-9_]+)/g, (_, key) => {\n const value = params[key];\n if (value == null || value === '') {\n return '';\n }\n\n return String(value)\n .split('/')\n .map((part) => encodeURIComponent(part))\n .join('/');\n })\n .replace(/\\*:([A-Za-z0-9_]+)/g, (_, key) => {\n if (!(key in params)) {\n throw new Error(`Missing catch-all route param \"${key}\"`);\n }\n\n return String(params[key])\n .split('/')\n .map((part) => encodeURIComponent(part))\n .join('/');\n })\n .replace(/:([A-Za-z0-9_]+)/g, (_, key) => {\n if (!(key in params)) {\n throw new Error(`Missing route param \"${key}\"`);\n }\n\n return encodeURIComponent(params[key]);\n });\n\n return normalizeRoutePath(result || '/');\n}\n\nexport function fileNameFromRoute(\n routePath: string,\n cleanUrls: boolean,\n): string {\n const normalized = normalizeRoutePath(routePath);\n\n if (normalized === '/') return 'index.html';\n\n const base = normalized.slice(1);\n return cleanUrls ? `${base}/index.html` : `${base}.html`;\n}\n\nexport function expandStaticPaths(\n basePage: Omit<HtPageInfo, 'routePath' | 'fileName' | 'params'>,\n rows: StaticParamRecord[],\n cleanUrls: boolean,\n): HtPageInfo[] {\n return rows.map((row) => {\n const params = Object.fromEntries(\n Object.entries(row).map(([k, v]) => [k, String(v)]),\n );\n\n const routePath = fillParams(basePage.routePattern, params);\n\n return {\n ...basePage,\n routePath,\n fileName: fileNameFromRoute(routePath, cleanUrls),\n params,\n };\n });\n}\n\nexport function routeMatch(\n pattern: string,\n urlPath: string,\n): Record<string, string> | null {\n const a = normalizeRoutePath(pattern).split('/').filter(Boolean);\n const b = normalizeRoutePath(urlPath).split('/').filter(Boolean);\n const params: Record<string, string> = {};\n\n for (let i = 0; i < a.length; i++) {\n const patternSeg = a[i];\n const urlSeg = b[i];\n\n if (patternSeg.startsWith('*?:')) {\n params[patternSeg.slice(3)] =\n i < b.length ? b.slice(i).map(decodeURIComponent).join('/') : '';\n return params;\n }\n\n if (patternSeg.startsWith('*:')) {\n const rest = b.slice(i);\n if (rest.length === 0) return null;\n\n params[patternSeg.slice(2)] = rest.map(decodeURIComponent).join('/');\n return params;\n }\n\n if (!urlSeg) return null;\n\n if (patternSeg.startsWith(':')) {\n params[patternSeg.slice(1)] = decodeURIComponent(urlSeg);\n continue;\n }\n\n if (patternSeg !== urlSeg) return null;\n }\n\n return a.length === b.length ? params : null;\n}\n\nexport function compareRoutePriority(a: string, b: string): number {\n const aSegs = normalizeRoutePath(a).split('/').filter(Boolean);\n const bSegs = normalizeRoutePath(b).split('/').filter(Boolean);\n const len = Math.max(aSegs.length, bSegs.length);\n\n for (let i = 0; i < len; i++) {\n const aa = aSegs[i];\n const bb = bSegs[i];\n\n if (aa == null) return 1;\n if (bb == null) return -1;\n\n const aOptionalCatchAll = aa.startsWith('*?:');\n const bOptionalCatchAll = bb.startsWith('*?:');\n if (aOptionalCatchAll !== bOptionalCatchAll) {\n return aOptionalCatchAll ? 1 : -1;\n }\n\n const aCatchAll = aa.startsWith('*:');\n const bCatchAll = bb.startsWith('*:');\n if (aCatchAll !== bCatchAll) {\n return aCatchAll ? 1 : -1;\n }\n\n const aDynamic = aa.startsWith(':');\n const bDynamic = bb.startsWith(':');\n if (aDynamic !== bDynamic) {\n return aDynamic ? 1 : -1;\n }\n }\n\n return bSegs.length - aSegs.length;\n}","import type { RouteParamDefinition } from './types';\n\nexport function parseRouteParamSegment(\n segment: string,\n): RouteParamDefinition | null {\n if (segment.startsWith('[...') && segment.endsWith(']?')) {\n return {\n name: segment.slice(4, -2),\n type: 'optional-catch-all',\n };\n }\n\n if (segment.startsWith('[...') && segment.endsWith(']')) {\n return {\n name: segment.slice(4, -1),\n type: 'catch-all',\n };\n }\n\n if (segment.startsWith('[') && segment.endsWith(']')) {\n return {\n name: segment.slice(1, -1),\n type: 'single',\n };\n }\n\n return null;\n}\n\nexport function extractRouteParamDefinitions(\n routePattern: string,\n): RouteParamDefinition[] {\n return routePattern\n .split('/')\n .filter(Boolean)\n .map((segment) => parseRouteParamSegment(segment))\n .filter((value): value is RouteParamDefinition => value != null);\n}","export const PLUGIN_NAME = 'vite-plugin-html-pages';\nexport const VIRTUAL_BUILD_ENTRY_ID = `\\0${PLUGIN_NAME}:build-entry`;\nexport const VIRTUAL_PAGE_HELPER_ID = `${PLUGIN_NAME}/page`;\nexport const RESOLVED_VIRTUAL_PAGE_HELPER_PREFIX =`\\0${PLUGIN_NAME}/page:`;\nexport const VIRTUAL_MANIFEST_ID = `\\0virtual:${PLUGIN_NAME}-manifest`;\nexport const CACHE_DIR_NAME = `node_modules/.cache/${PLUGIN_NAME}`;","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { ViteDevServer } from 'vite';\n\nimport { renderPage } from './render-runtime';\nimport type { HtPageInfo, HtPageModule } from './types';\nimport { PLUGIN_NAME } from './constants';\nimport { createPageModuleLoader } from './module-loader';\n\nfunction isStaticAssetRequest(url: string): boolean {\n return (\n url.endsWith('.css') ||\n url.endsWith('.js') ||\n url.endsWith('.mjs') ||\n url.endsWith('.ts') ||\n url.endsWith('.png') ||\n url.endsWith('.jpg') ||\n url.endsWith('.jpeg') ||\n url.endsWith('.gif') ||\n url.endsWith('.svg') ||\n url.endsWith('.webp') ||\n url.endsWith('.ico') ||\n url.endsWith('.woff') ||\n url.endsWith('.woff2') ||\n url.endsWith('.ttf') ||\n url.endsWith('.otf')\n );\n}\n\nfunction shouldSkipHtmlRouting(url: string, pagesDir: string): boolean {\n return (\n url.startsWith('/@vite') ||\n url.startsWith('/@fs/') ||\n url.startsWith('/node_modules/') ||\n url.startsWith(`/${pagesDir}/`) ||\n url === '/favicon.ico' ||\n isStaticAssetRequest(url)\n );\n}\n\nfunction tryRewriteRootAssetToSrc(\n root: string,\n pagesDir: string,\n url: string,\n): string | null {\n if (!url.startsWith('/')) return null;\n if (!isStaticAssetRequest(url)) return null;\n if (url.startsWith(`/${pagesDir}/`)) return null;\n\n const candidate = path.join(root, pagesDir, url.slice(1));\n\n if (fs.existsSync(candidate)) {\n return `/${pagesDir}/${url.slice(1)}`;\n }\n\n return null;\n}\n\nfunction shouldUseDynamicRendering(mod: HtPageModule): boolean {\n return mod.dynamic === true || mod.prerender === false;\n}\n\nexport function installDevServer(args: {\n server: ViteDevServer;\n root: string;\n pagesDir: string;\n getPages: () => Promise<HtPageInfo[]>;\n getEntries?: () => Promise<HtPageInfo[]>;\n}) {\n const { server, root, pagesDir, getPages } = args;\n\n server.middlewares.use(async (req, res, next) => {\n try {\n const originalUrl = req.url ?? '/';\n const url = originalUrl.split('?')[0];\n\n const rewrittenAssetUrl = tryRewriteRootAssetToSrc(root, pagesDir, url);\n if (rewrittenAssetUrl) {\n req.url = rewrittenAssetUrl + originalUrl.slice(url.length);\n return next();\n }\n\n if (shouldSkipHtmlRouting(url, pagesDir)) {\n return next();\n }\n\n const pages = await getPages();\n\n const page = pages.find((p) => p.routePath === url);\n\n if (!page) {\n return next();\n }\n\n const loadModule = await createPageModuleLoader({\n mode: 'dev',\n root,\n server,\n });\n\n const mod = await loadModule(page.entryPath, page.relativePath);\n\n if (!mod) {\n return next();\n }\n\n if (!shouldUseDynamicRendering(mod) && page.dynamic) {\n return next();\n }\n\n const html = await renderPage(page, mod, true);\n const transformedHtml = await server.transformIndexHtml(\n url,\n html,\n req.originalUrl,\n );\n \n res.statusCode = 200;\n res.setHeader('Content-Type', 'text/html; charset=utf-8');\n res.end(transformedHtml);\n } catch (error) {\n server.config.logger.error(\n `[${PLUGIN_NAME}] dev server render failed: ${\n error instanceof Error ? error.stack ?? error.message : String(error)\n }`,\n );\n\n next(error as Error);\n }\n });\n}","import type { HtPageInfo } from './types';\nimport { PLUGIN_NAME } from './constants';\nexport function invalidHtmlReturn(\n page: HtPageInfo,\n value: unknown,\n): Error {\n return new Error(\n `[${PLUGIN_NAME}] Page \"${page.relativePath}\" must resolve to an HTML string, got ${typeof value}`,\n );\n}\n\nexport function missingDefaultExport(page: HtPageInfo): Error {\n return new Error(\n `[${PLUGIN_NAME}] Page \"${page.relativePath}\" does not export a default renderer`,\n );\n}\n\nexport function pageError(page: HtPageInfo, cause: unknown): Error {\n const message = `[${PLUGIN_NAME}] Failed to render \"${page.relativePath}\" at route \"${page.routePath}\"`;\n\n if (cause instanceof Error) {\n const err = new Error(`${message}: ${cause.message}`);\n\n if (cause.stack) {\n err.stack = `${err.stack}\\nCaused by:\\n${cause.stack}`;\n }\n\n return err;\n }\n\n return new Error(`${message}: ${String(cause)}`);\n}","import { invalidHtmlReturn, pageError, missingDefaultExport } from './errors';\nimport type { HtPageInfo, HtPageModule, HtPageRenderContext } from './types';\n\nexport async function renderPage(\n page: HtPageInfo,\n mod: HtPageModule,\n dev = false,\n): Promise<string> {\n const ctx: HtPageRenderContext = {\n page,\n params: page.params,\n dev,\n };\n\n try {\n if (typeof mod.data === 'function') {\n ctx.data = await mod.data(ctx);\n }\n\n const entry = mod.default;\n\n if (entry == null) {\n throw missingDefaultExport(page);\n }\n\n const html = typeof entry === 'function' ? await entry(ctx) : entry;\n\n if (typeof html !== 'string') {\n throw invalidHtmlReturn(page, html);\n }\n\n return html;\n } catch (error) {\n throw pageError(page, error);\n }\n}","import path from 'node:path';\nimport { createServer, type InlineConfig, type ViteDevServer } from 'vite';\nimport type { HtPageModule } from './types';\n\nexport type PageModuleLoader = (\n entryPath: string,\n relativePath: string,\n) => Promise<HtPageModule>;\n\nlet buildServer: ViteDevServer | null = null;\n\nexport async function createPageModuleLoader(args: {\n mode: 'dev' | 'build';\n root: string;\n server?: ViteDevServer | null;\n}): Promise<PageModuleLoader> {\n const { mode, root, server } = args;\n\n if (mode === 'dev') {\n if (!server) {\n throw new Error('[vite-plugin-html-pages] dev server not available');\n }\n\n return async (_entryPath, relativePath) => {\n const mod = await server.ssrLoadModule(`/${relativePath}`);\n return mod as HtPageModule;\n };\n }\n\n if (!buildServer) {\n const config: InlineConfig = {\n root,\n configFile: false,\n logLevel: 'error',\n appType: 'custom',\n server: {\n middlewareMode: true,\n },\n };\n\n buildServer = await createServer(config);\n }\n\n return async (entryPath) => {\n const relativePath =\n '/' + path.relative(root, entryPath).replace(/\\\\/g, '/');\n\n const mod = await buildServer!.ssrLoadModule(relativePath);\n return mod as HtPageModule;\n };\n}\n\nexport async function closePageModuleLoader(): Promise<void> {\n if (buildServer) {\n await buildServer.close();\n buildServer = null;\n }\n}","import {\n compareRoutePriority,\n expandStaticPaths,\n fileNameFromRoute,\n} from './route-utils';\nimport type { HtPageInfo, HtPageModule, StaticParamRecord } from './types';\nimport { PLUGIN_NAME } from './constants';\nexport async function buildPageIndex(args: {\n entries: HtPageInfo[];\n modulesByEntry: Map<string, HtPageModule>;\n cleanUrls: boolean;\n}): Promise<HtPageInfo[]> {\n const { entries, modulesByEntry, cleanUrls } = args;\n const pages: HtPageInfo[] = [];\n\n for (const entry of entries) {\n const mod = modulesByEntry.get(entry.entryPath) ?? {};\n\n if (entry.dynamic) {\n const rows =\n (mod.generateStaticParams\n ? await mod.generateStaticParams()\n : []) ?? [];\n\n pages.push(\n ...expandStaticPaths(\n {\n id: entry.id,\n entryPath: entry.entryPath,\n absolutePath: entry.absolutePath,\n relativePath: entry.relativePath,\n routePattern: entry.routePattern,\n dynamic: entry.dynamic,\n paramNames: entry.paramNames,\n } as Omit<HtPageInfo, 'routePath' | 'fileName' | 'params'>,\n Array.isArray(rows) ? rows : [],\n cleanUrls,\n ),\n );\n } else {\n pages.push({\n ...entry,\n routePath: entry.routePattern,\n fileName: fileNameFromRoute(entry.routePattern, cleanUrls),\n params: {},\n });\n }\n }\n\n pages.sort((a, b) => compareRoutePriority(a.routePattern, b.routePattern));\n\n const seenRoutes = new Map<string, HtPageInfo>();\n\n for (const page of pages) {\n const existing = seenRoutes.get(page.routePath);\n\n if (existing) {\n throw new Error(\n `[${PLUGIN_NAME}] Duplicate route generated: \"${page.routePath}\" from \"${existing.relativePath}\" and \"${page.relativePath}\"`,\n );\n }\n\n seenRoutes.set(page.routePath, page);\n }\n\n return pages;\n}","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport fg from 'fast-glob';\nimport * as esbuild from 'esbuild';\nimport fsSync from 'node:fs';\n\nexport interface StaticAssetFile {\n absolutePath: string;\n relativePathFromSrc: string;\n outputFileName: string;\n kind: 'copy' | 'process';\n}\n\nexport interface CollectStaticAssetsArgs {\n root: string;\n pagesDir: string;\n pageExtensions: string[];\n}\n\nfunction normalizeSlashes(value: string): string {\n return value.replace(/\\\\/g, '/');\n}\n\nfunction hasAnySuffix(value: string, suffixes: string[]): boolean {\n return suffixes.some((suffix) => value.endsWith(suffix));\n}\n\nfunction shouldIgnoreFile(rel: string): boolean {\n return (\n rel.endsWith('.d.ts') ||\n rel.endsWith('.map') ||\n rel.endsWith('.tsbuildinfo') ||\n rel.startsWith('.') ||\n rel.includes('/.')\n );\n}\n\nfunction isProcessableAsset(rel: string): boolean {\n return (\n rel.endsWith('.js') ||\n rel.endsWith('.mjs') ||\n rel.endsWith('.ts') ||\n rel.endsWith('.css')\n );\n}\n\nfunction toOutputFileName(relativePathFromSrc: string): string {\n if (relativePathFromSrc.endsWith('.ts')) {\n return relativePathFromSrc.slice(0, -3) + '.js';\n }\n return relativePathFromSrc;\n}\n\nexport async function collectStaticAssets(\n args: CollectStaticAssetsArgs,\n): Promise<StaticAssetFile[]> {\n const { root, pagesDir, pageExtensions } = args;\n const srcDir = path.join(root, pagesDir);\n\n const entries = await fg('**/*', {\n cwd: srcDir,\n onlyFiles: true,\n dot: false,\n absolute: false,\n });\n\n const assets: StaticAssetFile[] = [];\n\n for (const entry of entries) {\n const rel = normalizeSlashes(entry);\n\n if (shouldIgnoreFile(rel)) continue;\n if (hasAnySuffix(rel, pageExtensions)) continue;\n\n const absolutePath = path.join(srcDir, rel);\n\n assets.push({\n absolutePath,\n relativePathFromSrc: rel,\n outputFileName: normalizeSlashes(toOutputFileName(rel)),\n kind: isProcessableAsset(rel) ? 'process' : 'copy',\n });\n }\n\n return assets;\n}\n\nexport async function copyStaticAssetSource(\n asset: StaticAssetFile,\n): Promise<Uint8Array> {\n return fs.readFile(asset.absolutePath);\n}\n\nexport async function buildProcessedStaticAssets(args: {\n root: string;\n pagesDir: string;\n assets: StaticAssetFile[];\n minify?: boolean;\n sourcemap?: boolean;\n }): Promise<Map<string, string | Uint8Array>> {\n const { root, pagesDir, assets, minify = true, sourcemap = false } = args;\n \n const processable = assets.filter((a) => a.kind === 'process');\n const out = new Map<string, string | Uint8Array>();\n \n if (processable.length === 0) {\n return out;\n }\n \n const srcDir = path.join(root, pagesDir);\n const distDir = path.join(root, 'dist');\n const warnedMissingAssets = new Set<string>();\n const result = await esbuild.build({\n entryPoints: processable.map((a) => a.absolutePath),\n absWorkingDir: root,\n outbase: srcDir,\n outdir: distDir,\n bundle: true,\n splitting: true,\n treeShaking: true,\n minify,\n sourcemap,\n format: 'esm',\n target: 'es2020',\n platform: 'browser',\n write: false,\n entryNames: '[dir]/[name]',\n assetNames: '[dir]/[name]',\n loader: {\n '.css': 'css',\n '.png': 'file',\n '.jpg': 'file',\n '.jpeg': 'file',\n '.gif': 'file',\n '.svg': 'file',\n '.webp': 'file',\n '.woff': 'file',\n '.woff2': 'file',\n '.ttf': 'file',\n '.otf': 'file',\n },\n plugins: [\n {\n name: 'html-pages-root-url-resolver',\n setup(build) {\n build.onResolve({ filter: /^\\// }, (resolveArgs) => {\n // Leave real filesystem absolute paths alone\n if (\n path.isAbsolute(resolveArgs.path) &&\n fsSync.existsSync(resolveArgs.path)\n ) {\n return { path: resolveArgs.path };\n }\n \n const cleanPath = resolveArgs.path.slice(1);\n \n const fromSrc = path.join(srcDir, cleanPath);\n if (fsSync.existsSync(fromSrc)) {\n return { path: fromSrc };\n }\n \n const fromPublic = path.join(root, 'public', cleanPath);\n if (fsSync.existsSync(fromPublic)) {\n return {\n path: resolveArgs.path,\n external: true,\n };\n }\n \n const isCssUrlToken = resolveArgs.kind === 'url-token';\n \n if (isCssUrlToken) {\n if (!warnedMissingAssets.has(resolveArgs.path)) {\n warnedMissingAssets.add(resolveArgs.path);\n console.warn(\n `[vite-plugin-html-pages] ⚠️ Missing CSS asset: ${resolveArgs.path}\\n` +\n ` Looked in:\\n` +\n ` - ${fromSrc}\\n` +\n ` - ${fromPublic}`\n );\n }\n \n // Keep the original root-relative URL in output CSS\n return {\n path: resolveArgs.path,\n external: true,\n };\n }\n \n // JS/CSS entry imports remain strict\n return {\n path: fromSrc,\n };\n });\n },\n },\n ],\n });\n \n for (const file of result.outputFiles) {\n const rel = normalizeSlashes(path.relative(distDir, file.path));\n out.set(rel, file.text ?? file.contents);\n }\n \n return out;\n }\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nexport interface HtmlAssetValidationOptions {\n root: string;\n pagesDir: string;\n html: string;\n pluginName: string;\n pageLabel?: string;\n missingAssets?: 'error' | 'warn';\n}\n\nfunction stripQueryAndHash(url: string): string {\n return url.split('#')[0].split('?')[0];\n}\n\nfunction isLocalRootUrl(url: string): boolean {\n return !!url && url.startsWith('/') && !url.startsWith('//');\n}\n\nfunction fileExistsForPublicUrl(root: string, pagesDir: string, url: string): boolean {\n const clean = stripQueryAndHash(url).slice(1);\n\n const fromSrc = path.join(root, pagesDir, clean);\n if (fs.existsSync(fromSrc)) return true;\n\n const fromPublic = path.join(root, 'public', clean);\n if (fs.existsSync(fromPublic)) return true;\n\n return false;\n}\n\nfunction collectScriptSrcs(html: string): string[] {\n const out: string[] = [];\n\n for (const match of html.matchAll(\n /<script\\b[^>]*\\bsrc=[\"']([^\"']+)[\"'][^>]*>/gi,\n )) {\n out.push(match[1]);\n }\n\n return out;\n}\n\nfunction collectStylesheetHrefs(html: string): string[] {\n const out: string[] = [];\n\n for (const match of html.matchAll(\n /<link\\b[^>]*\\brel=[\"']stylesheet[\"'][^>]*\\bhref=[\"']([^\"']+)[\"'][^>]*>/gi,\n )) {\n out.push(match[1]);\n }\n\n return out;\n}\n\nfunction collectLiteralDynamicImports(html: string): string[] {\n const out: string[] = [];\n\n for (const match of html.matchAll(\n /import\\s*\\(\\s*[\"']([^\"'`]+)[\"']\\s*\\)/gi,\n )) {\n out.push(match[1]);\n }\n\n return out;\n}\n\nfunction unique(values: string[]): string[] {\n return [...new Set(values)];\n}\n\nfunction formatPageLabel(pageLabel?: string): string {\n return pageLabel ? ` (${pageLabel})` : '';\n}\n\nfunction missingAssetMessage(args: {\n pluginName: string;\n kind: string;\n url: string;\n root: string;\n pagesDir: string;\n pageLabel?: string;\n}): string {\n const { pluginName, kind, url, root, pagesDir, pageLabel } = args;\n const clean = stripQueryAndHash(url).slice(1);\n const pageSuffix = formatPageLabel(pageLabel);\n\n return (\n `[${pluginName}] Missing ${kind}${pageSuffix}: ${url}\\n` +\n `Expected one of:\\n` +\n `- ${path.join(root, pagesDir, clean)}\\n` +\n `- ${path.join(root, 'public', clean)}`\n );\n}\n\nfunction reportMissing(args: {\n mode: 'error' | 'warn';\n pluginName: string;\n kind: string;\n url: string;\n root: string;\n pagesDir: string;\n pageLabel?: string;\n}) {\n const message = missingAssetMessage(args);\n\n if (args.mode === 'warn') {\n console.warn(`⚠️ ${message}`);\n return;\n }\n\n throw new Error(message);\n}\n\nexport function validateHtmlAssetReferences(\n options: HtmlAssetValidationOptions,\n): void {\n const {\n root,\n pagesDir,\n html,\n pluginName,\n pageLabel,\n missingAssets = 'error',\n } = options;\n\n const scriptSrcs = unique(collectScriptSrcs(html)).filter(isLocalRootUrl);\n const stylesheetHrefs = unique(collectStylesheetHrefs(html)).filter(isLocalRootUrl);\n const literalDynamicImports = unique(collectLiteralDynamicImports(html)).filter(\n isLocalRootUrl,\n );\n\n for (const url of scriptSrcs) {\n if (!fileExistsForPublicUrl(root, pagesDir, url)) {\n reportMissing({\n mode: missingAssets,\n pluginName,\n kind: 'JavaScript asset',\n url,\n root,\n pagesDir,\n pageLabel,\n });\n }\n }\n\n for (const url of stylesheetHrefs) {\n if (!fileExistsForPublicUrl(root, pagesDir, url)) {\n reportMissing({\n mode: missingAssets,\n pluginName,\n kind: 'stylesheet asset',\n url,\n root,\n pagesDir,\n pageLabel,\n });\n }\n }\n\n for (const url of literalDynamicImports) {\n if (!fileExistsForPublicUrl(root, pagesDir, url)) {\n console.warn(\n `⚠️ ${missingAssetMessage({\n pluginName,\n kind: 'literal dynamic import',\n url,\n root,\n pagesDir,\n pageLabel,\n })}`,\n );\n }\n }\n}","import type { HtPageInfo, RouteParamDefinition } from './types';\n\nfunction paramsTypeFromDefinitions(\n paramDefinitions: RouteParamDefinition[],\n): string {\n if (paramDefinitions.length === 0) {\n return '{}';\n }\n\n const fields = paramDefinitions.map((param) => {\n if (param.type === 'single') {\n return `${JSON.stringify(param.name)}: string`;\n }\n\n if (param.type === 'catch-all') {\n return `${JSON.stringify(param.name)}: string[]`;\n }\n\n return `${JSON.stringify(param.name)}?: string[]`;\n });\n\n return `{ ${fields.join('; ')} }`;\n}\n\nexport function generateTypedPageHelper(page: HtPageInfo | undefined): string {\n const paramsType = page\n ? paramsTypeFromDefinitions(page.paramDefinitions ?? [])\n : '{}';\n\n return `\nexport type PageParams = ${paramsType};\n\nexport type PageContext = {\n params: PageParams;\n data?: unknown;\n dev: boolean;\n};\n\nexport function definePage<T extends (ctx: PageContext) => any>(fn: T): T {\n return fn;\n}\n`;\n}","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { createHash } from 'node:crypto';\nimport { CACHE_DIR_NAME } from './constants';\n\nexport type FetchCacheMode = 'auto' | 'memory' | 'fs' | 'none';\nexport interface FetchWithCacheOptions {\n maxAge?: number;\n cacheKey?: string;\n forceRefresh?: boolean;\n cache?: FetchCacheMode;\n}\n\ntype CachedResponseRecord = {\n timestamp: number;\n status: number;\n statusText: string;\n headers: [string, string][];\n body: string;\n};\n\nconst memoryCache = new Map<string, CachedResponseRecord>();\n\nfunction createDefaultCacheKey(\n input: RequestInfo | URL,\n init?: RequestInit,\n): string {\n const raw = JSON.stringify({\n url: String(input),\n method: init?.method ?? 'GET',\n headers: init?.headers ?? {},\n body: init?.body ?? null,\n });\n\n return createHash('sha256').update(raw).digest('hex');\n}\n\nfunction getCacheFilePath(cacheKey: string): string {\n return path.join(process.cwd(), CACHE_DIR_NAME, 'fetch', `${cacheKey}.json`);\n}\n\nfunction getEffectiveCacheMode(\n mode: FetchCacheMode | undefined,\n): Exclude<FetchCacheMode, 'auto'> {\n if (mode === 'memory' || mode === 'fs' || mode === 'none') {\n return mode;\n }\n\n return process.env.NODE_ENV === 'production' ? 'fs' : 'memory';\n}\n\nfunction toResponse(cached: CachedResponseRecord): Response {\n return new Response(cached.body, {\n status: cached.status,\n statusText: cached.statusText,\n headers: cached.headers,\n });\n}\n\nfunction isFresh(cached: CachedResponseRecord, maxAgeSeconds: number): boolean {\n const ageSeconds = (Date.now() - cached.timestamp) / 1000;\n return ageSeconds <= maxAgeSeconds;\n}\n\nexport function clearMemoryFetchCache(): void {\n memoryCache.clear();\n}\n\nexport function deleteMemoryFetchCache(cacheKey: string): void {\n memoryCache.delete(cacheKey);\n}\n\nexport async function fetchWithCache(\n input: RequestInfo | URL,\n init?: RequestInit,\n options: FetchWithCacheOptions = {},\n): Promise<Response> {\n const maxAge = options.maxAge ?? 60 * 60;\n const method = (init?.method ?? 'GET').toUpperCase();\n\n if (method !== 'GET' && !options.cacheKey) {\n return fetch(input, init);\n }\n\n const cacheMode = getEffectiveCacheMode(options.cache);\n const cacheKey = options.cacheKey ?? createDefaultCacheKey(input, init);\n\n if (cacheMode === 'none') {\n return fetch(input, init);\n }\n\n if (cacheMode === 'memory' && !options.forceRefresh) {\n const cached = memoryCache.get(cacheKey);\n\n if (cached && isFresh(cached, maxAge)) {\n return toResponse(cached);\n }\n }\n\n const filePath = getCacheFilePath(cacheKey);\n\n if (cacheMode === 'fs') {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n\n if (!options.forceRefresh) {\n try {\n const raw = await fs.readFile(filePath, 'utf8');\n const cached = JSON.parse(raw) as CachedResponseRecord;\n\n if (isFresh(cached, maxAge)) {\n return toResponse(cached);\n }\n } catch {\n // cache miss or invalid cache; fetch fresh\n }\n }\n }\n\n const res = await fetch(input, init);\n const body = await res.text();\n\n const record: CachedResponseRecord = {\n timestamp: Date.now(),\n status: res.status,\n statusText: res.statusText,\n headers: [...res.headers.entries()],\n body,\n };\n\n if (cacheMode === 'memory') {\n memoryCache.set(cacheKey, record);\n } else if (cacheMode === 'fs') {\n await fs.writeFile(filePath, JSON.stringify(record), 'utf8');\n }\n\n return new Response(body, {\n status: res.status,\n statusText: res.statusText,\n headers: res.headers,\n });\n}\n"],"mappings":"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","names":["path","fg","path","path","path","path","fs","path","build","fs","path","fs","path","fs","path","path","fs","path"]}
|
package/package.json
CHANGED
package/src/dev-server.ts
CHANGED
|
@@ -27,27 +27,30 @@ function isStaticAssetRequest(url: string): boolean {
|
|
|
27
27
|
);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
function shouldSkipHtmlRouting(url: string): boolean {
|
|
30
|
+
function shouldSkipHtmlRouting(url: string, pagesDir: string): boolean {
|
|
31
31
|
return (
|
|
32
32
|
url.startsWith('/@vite') ||
|
|
33
33
|
url.startsWith('/@fs/') ||
|
|
34
34
|
url.startsWith('/node_modules/') ||
|
|
35
|
-
url.startsWith(
|
|
35
|
+
url.startsWith(`/${pagesDir}/`) ||
|
|
36
36
|
url === '/favicon.ico' ||
|
|
37
37
|
isStaticAssetRequest(url)
|
|
38
38
|
);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
function tryRewriteRootAssetToSrc(
|
|
41
|
+
function tryRewriteRootAssetToSrc(
|
|
42
|
+
root: string,
|
|
43
|
+
pagesDir: string,
|
|
44
|
+
url: string,
|
|
45
|
+
): string | null {
|
|
42
46
|
if (!url.startsWith('/')) return null;
|
|
43
47
|
if (!isStaticAssetRequest(url)) return null;
|
|
44
|
-
if (url.startsWith(
|
|
48
|
+
if (url.startsWith(`/${pagesDir}/`)) return null;
|
|
45
49
|
|
|
46
|
-
const
|
|
47
|
-
const candidate = path.join(root, 'src', url.slice(1));
|
|
50
|
+
const candidate = path.join(root, pagesDir, url.slice(1));
|
|
48
51
|
|
|
49
52
|
if (fs.existsSync(candidate)) {
|
|
50
|
-
return
|
|
53
|
+
return `/${pagesDir}/${url.slice(1)}`;
|
|
51
54
|
}
|
|
52
55
|
|
|
53
56
|
return null;
|
|
@@ -59,23 +62,25 @@ function shouldUseDynamicRendering(mod: HtPageModule): boolean {
|
|
|
59
62
|
|
|
60
63
|
export function installDevServer(args: {
|
|
61
64
|
server: ViteDevServer;
|
|
65
|
+
root: string;
|
|
66
|
+
pagesDir: string;
|
|
62
67
|
getPages: () => Promise<HtPageInfo[]>;
|
|
63
68
|
getEntries?: () => Promise<HtPageInfo[]>;
|
|
64
69
|
}) {
|
|
65
|
-
const { server, getPages } = args;
|
|
70
|
+
const { server, root, pagesDir, getPages } = args;
|
|
66
71
|
|
|
67
72
|
server.middlewares.use(async (req, res, next) => {
|
|
68
73
|
try {
|
|
69
74
|
const originalUrl = req.url ?? '/';
|
|
70
75
|
const url = originalUrl.split('?')[0];
|
|
71
76
|
|
|
72
|
-
const rewrittenAssetUrl = tryRewriteRootAssetToSrc(
|
|
77
|
+
const rewrittenAssetUrl = tryRewriteRootAssetToSrc(root, pagesDir, url);
|
|
73
78
|
if (rewrittenAssetUrl) {
|
|
74
79
|
req.url = rewrittenAssetUrl + originalUrl.slice(url.length);
|
|
75
80
|
return next();
|
|
76
81
|
}
|
|
77
82
|
|
|
78
|
-
if (shouldSkipHtmlRouting(url)) {
|
|
83
|
+
if (shouldSkipHtmlRouting(url, pagesDir)) {
|
|
79
84
|
return next();
|
|
80
85
|
}
|
|
81
86
|
|
|
@@ -89,7 +94,7 @@ export function installDevServer(args: {
|
|
|
89
94
|
|
|
90
95
|
const loadModule = await createPageModuleLoader({
|
|
91
96
|
mode: 'dev',
|
|
92
|
-
root
|
|
97
|
+
root,
|
|
93
98
|
server,
|
|
94
99
|
});
|
|
95
100
|
|
package/src/plugin.ts
CHANGED
|
@@ -180,8 +180,8 @@ export function htPages(options: HtPagesPluginOptions = {}): Plugin {
|
|
|
180
180
|
},
|
|
181
181
|
|
|
182
182
|
configResolved(resolved) {
|
|
183
|
-
root = resolved.root;
|
|
184
|
-
|
|
183
|
+
root = options.root ? path.resolve(resolved.root, options.root) : resolved.root;
|
|
184
|
+
|
|
185
185
|
if (!hasWarnedESM) {
|
|
186
186
|
warnIfNotESM(root);
|
|
187
187
|
hasWarnedESM = true;
|
|
@@ -221,6 +221,8 @@ export function htPages(options: HtPagesPluginOptions = {}): Plugin {
|
|
|
221
221
|
|
|
222
222
|
installDevServer({
|
|
223
223
|
server,
|
|
224
|
+
root,
|
|
225
|
+
pagesDir,
|
|
224
226
|
getPages: async () => {
|
|
225
227
|
if (devPages.length > 0) return devPages;
|
|
226
228
|
return loadDevPages();
|