@pagesmith/core 0.4.0 → 0.4.2
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/README.md +19 -0
- package/REFERENCE.md +160 -94
- package/dist/{content-config-DJXUOcNG.d.mts → content-config-Bu2HH0Yx.d.mts} +2 -2
- package/dist/{content-config-DJXUOcNG.d.mts.map → content-config-Bu2HH0Yx.d.mts.map} +1 -1
- package/dist/{content-layer-B5enqWeJ.mjs → content-layer-CJRrNpZ_.mjs} +71 -10
- package/dist/content-layer-CJRrNpZ_.mjs.map +1 -0
- package/dist/{content-layer-CpHYUYNN.d.mts → content-layer-Ckt08g2i.d.mts} +4 -3
- package/dist/content-layer-Ckt08g2i.d.mts.map +1 -0
- package/dist/create/index.d.mts.map +1 -1
- package/dist/create/index.mjs +5 -2
- package/dist/create/index.mjs.map +1 -1
- package/dist/css/index.mjs +1 -1
- package/dist/css-CO3CBqxx.mjs +24 -0
- package/dist/css-CO3CBqxx.mjs.map +1 -0
- package/dist/heading-D4X2L4vd.d.mts +12 -0
- package/dist/heading-D4X2L4vd.d.mts.map +1 -0
- package/dist/{index-C0QFHYwb.d.mts → index-B4YZRIzb.d.mts} +1 -1
- package/dist/{index-C0QFHYwb.d.mts.map → index-B4YZRIzb.d.mts.map} +1 -1
- package/dist/{index-DCznbvaV.d.mts → index-CryArLlX.d.mts} +1 -1
- package/dist/{index-DCznbvaV.d.mts.map → index-CryArLlX.d.mts.map} +1 -1
- package/dist/{index-CJkBs8YQ.d.mts → index-D44syBt-.d.mts} +3 -2
- package/dist/index-D44syBt-.d.mts.map +1 -0
- package/dist/index.d.mts +7 -6
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +4 -4
- package/dist/loaders/index.d.mts +1 -1
- package/dist/loaders/index.mjs +1 -1
- package/dist/{loaders-Cf-BXf2L.mjs → loaders-DnyWfANR.mjs} +3 -3
- package/dist/loaders-DnyWfANR.mjs.map +1 -0
- package/dist/markdown/index.d.mts +2 -2
- package/dist/markdown/index.mjs +1 -1
- package/dist/{markdown-BmDJgYeB.mjs → markdown-DMHd400a.mjs} +7 -2
- package/dist/{markdown-BmDJgYeB.mjs.map → markdown-DMHd400a.mjs.map} +1 -1
- package/dist/{heading-Dhvzlay-.d.mts → markdown-config-CDvh5aJ-.d.mts} +2 -10
- package/dist/markdown-config-CDvh5aJ-.d.mts.map +1 -0
- package/dist/mcp/index.d.mts.map +1 -1
- package/dist/mcp/index.mjs +1 -1
- package/dist/mcp/server.d.mts +1 -1
- package/dist/mcp/server.d.mts.map +1 -1
- package/dist/mcp/server.mjs +1 -1
- package/dist/runtime/index.d.mts.map +1 -1
- package/dist/runtime/index.mjs +4 -9
- package/dist/runtime/index.mjs.map +1 -1
- package/dist/schemas/index.d.mts +4 -3
- package/dist/{server-D3DHoh5f.mjs → server-BZA_iSen.mjs} +2 -1
- package/dist/server-BZA_iSen.mjs.map +1 -0
- package/dist/ssg-utils/index.d.mts +3 -13
- package/dist/ssg-utils/index.d.mts.map +1 -1
- package/dist/ssg-utils/index.mjs +2 -1
- package/dist/ssg-utils/index.mjs.map +1 -1
- package/dist/vite/index.d.mts +2 -2
- package/dist/vite/index.d.mts.map +1 -1
- package/dist/vite/index.mjs +5 -5
- package/dist/vite/index.mjs.map +1 -1
- package/docs/agents/AGENTS.md.template +24 -4
- package/docs/agents/changelog-notes.md +1 -1
- package/docs/agents/errors.md +61 -7
- package/docs/agents/migration.md +7 -7
- package/docs/agents/recipes.md +26 -2
- package/docs/agents/usage.md +66 -5
- package/docs/llms-full.txt +73 -15
- package/docs/llms.txt +46 -7
- package/package.json +2 -27
- package/dist/content-layer-B5enqWeJ.mjs.map +0 -1
- package/dist/content-layer-CpHYUYNN.d.mts.map +0 -1
- package/dist/css-BneO430t.mjs +0 -20
- package/dist/css-BneO430t.mjs.map +0 -1
- package/dist/heading-Dhvzlay-.d.mts.map +0 -1
- package/dist/index-CJkBs8YQ.d.mts.map +0 -1
- package/dist/loaders-Cf-BXf2L.mjs.map +0 -1
- package/dist/server-D3DHoh5f.mjs.map +0 -1
package/dist/vite/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import "../markdown-
|
|
2
|
-
import { l as toSlug, t as createContentLayer } from "../content-layer-
|
|
3
|
-
import { r as resolveLoader } from "../loaders-
|
|
1
|
+
import "../markdown-DMHd400a.mjs";
|
|
2
|
+
import { l as toSlug, t as createContentLayer } from "../content-layer-CJRrNpZ_.mjs";
|
|
3
|
+
import { r as resolveLoader } from "../loaders-DnyWfANR.mjs";
|
|
4
4
|
import { i as copyPublicFiles, n as collectContentAssets, t as CONTENT_ASSET_EXTS } from "../assets-CAPOqQ_P.mjs";
|
|
5
5
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "fs";
|
|
6
6
|
import { basename, dirname, extname, join, relative, resolve } from "path";
|
|
@@ -87,7 +87,7 @@ function sharedAssetsPlugin() {
|
|
|
87
87
|
}
|
|
88
88
|
if (url.includes("/assets/fonts/") && url.endsWith(".woff2")) {
|
|
89
89
|
const fileName = url.split("/assets/fonts/").pop();
|
|
90
|
-
if (fileName) {
|
|
90
|
+
if (fileName && !fileName.includes("..") && !fileName.includes("/")) {
|
|
91
91
|
const filePath = join(assetsDir, "fonts", fileName);
|
|
92
92
|
if (existsSync(filePath)) {
|
|
93
93
|
res.writeHead(200, {
|
|
@@ -340,7 +340,7 @@ function configureSsgDevServer(server, context) {
|
|
|
340
340
|
res.writeHead(status, { "Content-Type": "text/html; charset=utf-8" });
|
|
341
341
|
res.end(html);
|
|
342
342
|
} catch (err) {
|
|
343
|
-
server.ssrFixStacktrace(err);
|
|
343
|
+
if (err instanceof Error) server.ssrFixStacktrace(err);
|
|
344
344
|
console.error(`SSR error for ${url}:`, err instanceof Error ? err.message : String(err));
|
|
345
345
|
next(err);
|
|
346
346
|
}
|
package/dist/vite/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["normalizePath"],"sources":["../../src/vite/ssg.ts","../../src/vite/shared-assets.ts","../../src/vite/ssg-render.ts","../../src/vite/ssg-hmr.ts","../../src/vite/ssg-pagefind.ts","../../src/vite/ssg-plugin.ts","../../src/vite/dts.ts","../../src/vite/content-plugin.ts"],"sourcesContent":["/**\n * Pre-rendering utility for Vite-based SSG sites.\n *\n * Call after running both the client and SSR Vite builds.\n * Loads the SSR module, renders each route, injects into the\n * client HTML template, and writes static files.\n */\n\nimport { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'fs'\nimport { dirname, resolve } from 'path'\nimport { pathToFileURL } from 'url'\n\nexport type PrerenderOptions = {\n /** Absolute path to the client build output directory (e.g., `dist/`) */\n outDir: string\n /** Absolute path to the built SSR entry module (e.g., `dist/.server/entry-server.js`) */\n serverEntry: string\n /** Routes to pre-render (e.g., `['/', '/about', '/posts/hello-world']`) */\n routes: string[]\n /** HTML placeholder to replace with rendered content (default: `'<!--ssr-outlet-->'`) */\n placeholder?: string\n /** Remove the server build directory after pre-rendering (default: true) */\n cleanup?: boolean\n}\n\n/**\n * Pre-render routes to static HTML files.\n *\n * Expects the SSR entry to export a `render(url: string): string` function.\n *\n * @example\n * ```ts\n * import { build } from 'vite'\n * import { prerenderRoutes } from '@pagesmith/core/vite'\n *\n * // 1. Client build\n * await build({ build: { outDir: 'dist' } })\n *\n * // 2. SSR build\n * await build({ build: { ssr: 'src/entry-server.tsx', outDir: 'dist/.server' } })\n *\n * // 3. Pre-render\n * await prerenderRoutes({\n * outDir: resolve('dist'),\n * serverEntry: resolve('dist/.server/entry-server.js'),\n * routes: ['/', '/about', '/posts/hello-world'],\n * })\n * ```\n */\nexport async function prerenderRoutes(options: PrerenderOptions): Promise<{ pages: number }> {\n const placeholder = options.placeholder ?? '<!--ssr-outlet-->'\n const cleanup = options.cleanup ?? true\n\n // Load SSR module\n if (!existsSync(options.serverEntry)) {\n throw new Error(`SSR entry not found: ${options.serverEntry}`)\n }\n\n const mod = await import(pathToFileURL(options.serverEntry).href)\n const render: (url: string) => string | Promise<string> = mod.render ?? mod.default?.render\n\n if (typeof render !== 'function') {\n throw new Error(\n `SSR entry must export a 'render(url: string)' function. ` +\n `Found exports: ${Object.keys(mod).join(', ')}`,\n )\n }\n\n // Read client HTML template\n const templatePath = resolve(options.outDir, 'index.html')\n const template = readFileSync(templatePath, 'utf-8')\n\n if (!template.includes(placeholder)) {\n throw new Error(\n `HTML template does not contain placeholder \"${placeholder}\". ` +\n `Add it to your index.html where SSR content should be injected.`,\n )\n }\n\n // Pre-render each route\n for (const route of options.routes) {\n const rendered = await render(route)\n const html = template.replace(placeholder, rendered)\n\n const routePath = route === '/' ? '' : route.replace(/^\\//, '')\n const outPath = resolve(options.outDir, routePath, 'index.html')\n mkdirSync(dirname(outPath), { recursive: true })\n writeFileSync(outPath, html)\n }\n\n // Clean up server build\n if (cleanup) {\n const serverDir = dirname(options.serverEntry)\n rmSync(serverDir, { recursive: true, force: true })\n }\n\n return { pages: options.routes.length }\n}\n","import { existsSync, readFileSync } from 'fs'\nimport { dirname, join } from 'path'\nimport { fileURLToPath } from 'url'\nimport type { Plugin } from 'vite'\n\n/**\n * Vite plugin that serves shared font assets during development.\n * In production, fonts are copied to the output directory by the build script.\n */\nexport function sharedAssetsPlugin(): Plugin {\n const pkgDir = join(dirname(fileURLToPath(import.meta.url)), '..', '..')\n const assetsDir = join(pkgDir, 'assets')\n\n return {\n name: 'pagesmith:shared-assets',\n configureServer(server) {\n server.middlewares.use((req, res, next) => {\n const url = req.url ?? ''\n\n // Serve fonts.css\n if (url === '/assets/fonts.css' || url.endsWith('/assets/fonts.css')) {\n const filePath = join(assetsDir, 'fonts.css')\n if (existsSync(filePath)) {\n res.writeHead(200, { 'Content-Type': 'text/css', 'Cache-Control': 'no-cache' })\n res.end(readFileSync(filePath, 'utf-8'))\n return\n }\n }\n\n // Serve font files\n if (url.includes('/assets/fonts/') && url.endsWith('.woff2')) {\n const fileName = url.split('/assets/fonts/').pop()\n if (fileName) {\n const filePath = join(assetsDir, 'fonts', fileName)\n if (existsSync(filePath)) {\n res.writeHead(200, {\n 'Content-Type': 'font/woff2',\n 'Cache-Control': 'public, max-age=31536000',\n })\n res.end(readFileSync(filePath))\n return\n }\n }\n }\n\n next()\n })\n },\n }\n}\n","/**\n * Route collection, pre-rendering, and content asset handling for the SSG plugin.\n *\n * Provides:\n * - Content companion asset discovery and copying\n * - HTML asset reference rewriting\n * - SSR bundle building via child process\n * - Route pre-rendering to static HTML files\n * - Font and public file copying\n */\n\nimport {\n copyFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from 'fs'\nimport { basename, dirname, extname, join, resolve } from 'path'\nimport { fileURLToPath, pathToFileURL } from 'url'\nimport type { ResolvedConfig } from 'vite'\nimport { collectContentAssets, CONTENT_ASSET_EXTS, copyPublicFiles } from '../assets'\nimport type { SsgRenderConfig } from './ssg-plugin'\n\nexport const MIME: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n '.avif': 'image/avif',\n '.ico': 'image/x-icon',\n '.woff2': 'font/woff2',\n '.woff': 'font/woff',\n '.ttf': 'font/ttf',\n '.txt': 'text/plain; charset=utf-8',\n '.xml': 'application/xml; charset=utf-8',\n}\n\n// ── Content directory helpers ──\n\nexport function resolveContentDirs(projectRoot: string, contentDirs: string[] = []): string[] {\n return contentDirs.map((dir) => resolve(projectRoot, dir))\n}\n\nfunction isAssetReference(ref: string): boolean {\n if (!ref.startsWith('./')) return false\n const path = ref.split(/[?#]/u, 1)[0] ?? ref\n return CONTENT_ASSET_EXTS.has(extname(path).toLowerCase())\n}\n\nexport function rewriteContentAssetRefs(html: string, base: string): string {\n const basePrefix = base.replace(/\\/+$/u, '')\n\n return html.replace(\n /(src|href|srcset)=(?:\"([^\"]+)\"|'([^']+)')/g,\n (match, attr: string, doubleRef: string | undefined, singleRef: string | undefined) => {\n const ref = doubleRef ?? singleRef ?? ''\n if (!isAssetReference(ref)) return match\n const pathname = ref.split(/[?#]/u, 1)[0] ?? ref\n const suffix = ref.slice(pathname.length)\n const quote = doubleRef !== undefined ? '\"' : \"'\"\n return `${attr}=${quote}${basePrefix}/assets/${pathname.split('/').pop() ?? pathname}${suffix}${quote}`\n },\n )\n}\n\nfunction copyContentAssetsToOutDir(outDir: string, assets: Map<string, string>): void {\n if (assets.size === 0) return\n\n const assetsDir = join(outDir, 'assets')\n mkdirSync(assetsDir, { recursive: true })\n\n for (const [fileName, sourcePath] of assets) {\n copyFileSync(sourcePath, join(assetsDir, fileName))\n }\n}\n\n// ── Build-time rendering ──\n\nexport type SsgBuildContext = {\n /** Vite resolved config */\n config: ResolvedConfig\n /** Absolute path to the project root */\n projectRoot: string\n /** Base path without trailing slash (e.g., '/my-site') */\n base: string\n /** Absolute path to the build output directory */\n outDir: string\n /** Resolved content directories (absolute paths) */\n contentDirs: string[]\n /** Path to the SSR entry module */\n entry: string\n}\n\n/**\n * Run the full SSG build: SSR bundle, route pre-rendering, asset copying.\n *\n * Returns the number of pages rendered.\n */\nexport async function renderStaticSite(context: SsgBuildContext): Promise<number> {\n const { config, projectRoot, base, outDir, contentDirs, entry } = context\n\n console.log('\\nSSG: Starting static site generation...')\n\n const contentAssets = collectContentAssets(contentDirs)\n\n // Copy font assets from @pagesmith/core\n copyFontAssets(outDir)\n\n // Copy public/ files (favicon etc.)\n const publicDir = join(projectRoot, 'public')\n copyPublicFiles(publicDir, outDir)\n\n // Discover built asset paths from the client build output\n const { cssPath, jsPath } = discoverBuiltAssets(outDir, base)\n\n // SSR build — use child process to avoid nested Vite resolution issues\n console.log('SSG: Building SSR bundle...')\n await buildSsrBundle(config, projectRoot, outDir, entry)\n\n // Load SSR module — derive output filename from the configured entry path\n const entryBaseName = basename(entry).replace(/\\.(c|m)?[jt]sx?$/u, '.js')\n const serverDir = join(outDir, '.server')\n const serverEntry = join(serverDir, entryBaseName)\n const ssrMod = await import(pathToFileURL(serverEntry).href)\n\n const renderConfig: SsgRenderConfig = {\n base,\n root: projectRoot,\n cssPath,\n jsPath,\n searchEnabled: true,\n isDev: false,\n }\n\n // Get routes and render with bounded concurrency\n const routes: string[] = await ssrMod.getRoutes(renderConfig)\n console.log(`SSG: Rendering ${routes.length} pages...`)\n\n const concurrency = Math.min(routes.length, 8)\n let routeIndex = 0\n\n async function renderWorker(): Promise<void> {\n while (routeIndex < routes.length) {\n const i = routeIndex++\n const route = routes[i]\n const html = rewriteContentAssetRefs(await ssrMod.render(route, renderConfig), base)\n const routePath = route === '/' ? '' : route.replace(/^\\//, '')\n const outputPath = join(outDir, routePath, 'index.html')\n mkdirSync(dirname(outputPath), { recursive: true })\n writeFileSync(outputPath, `<!DOCTYPE html>\\n${html}`)\n\n if (route === '/404') {\n writeFileSync(join(outDir, '404.html'), `<!DOCTYPE html>\\n${html}`)\n }\n }\n }\n\n const workers = Array.from({ length: concurrency }, () => renderWorker())\n await Promise.all(workers)\n\n copyContentAssetsToOutDir(outDir, contentAssets)\n\n // Cleanup SSR build\n rmSync(serverDir, { recursive: true, force: true })\n\n return routes.length\n}\n\nfunction copyFontAssets(outDir: string): void {\n const corePkgDir = dirname(fileURLToPath(import.meta.resolve('@pagesmith/core/package.json')))\n const coreFontsDir = join(corePkgDir, 'assets', 'fonts')\n const outFontsDir = join(outDir, 'assets', 'fonts')\n mkdirSync(outFontsDir, { recursive: true })\n for (const file of readdirSync(coreFontsDir)) {\n if (file.endsWith('.woff2')) {\n copyFileSync(join(coreFontsDir, file), join(outFontsDir, file))\n }\n }\n copyFileSync(join(corePkgDir, 'assets', 'fonts.css'), join(outDir, 'assets', 'fonts.css'))\n}\n\nfunction discoverBuiltAssets(\n outDir: string,\n base: string,\n): { cssPath: string; jsPath: string | undefined } {\n const builtIndex = join(outDir, 'index.html')\n let cssPath = `${base}/assets/style.css`\n let jsPath: string | undefined\n if (existsSync(builtIndex)) {\n const html = readFileSync(builtIndex, 'utf-8')\n const cssMatch = html.match(/href=\"([^\"]*\\.css)\"/)\n const jsMatch = html.match(/src=\"([^\"]*\\.js)\"/)\n if (cssMatch) cssPath = cssMatch[1]\n if (jsMatch) jsPath = jsMatch[1]\n }\n return { cssPath, jsPath }\n}\n\nasync function buildSsrBundle(\n config: ResolvedConfig,\n projectRoot: string,\n outDir: string,\n entry: string,\n): Promise<void> {\n const { execFileSync } = await import('child_process')\n const serverDir = join(outDir, '.server')\n const ssrEntry = resolve(projectRoot, entry)\n // Write a temp build script that externalizes node_modules and skips the SSG plugin\n const buildScript = `\n import { build } from 'vite';\n await build({\n root: ${JSON.stringify(projectRoot)},\n logLevel: 'warn',\n mode: ${JSON.stringify(config.mode)},\n build: {\n ssr: ${JSON.stringify(ssrEntry)},\n outDir: ${JSON.stringify(serverDir)},\n emptyOutDir: true,\n },\n });\n `\n execFileSync(process.execPath, ['--input-type=module', '-e', buildScript], {\n stdio: 'inherit',\n cwd: projectRoot,\n })\n}\n","/**\n * Dev-server middleware for the SSG plugin.\n *\n * Handles on-the-fly SSR rendering during development, including:\n * - Content companion asset serving from content directories\n * - HTML navigation request handling via server-side rendering\n * - Vite HMR client injection for live reload\n */\n\nimport { extname, resolve } from 'path'\nimport { readFileSync } from 'fs'\nimport type { ViteDevServer } from 'vite'\nimport type { SsgRenderConfig } from './ssg-plugin'\nimport { collectContentAssets } from '../assets'\nimport { MIME, rewriteContentAssetRefs } from './ssg-render'\n\nconst WS_RELOAD_SCRIPT = `<script type=\"module\">\nimport 'vite/modulepreload-polyfill'\nif (import.meta.hot) {\n import.meta.hot.on('full-reload', () => location.reload())\n}\n</script>`\n\nexport type SsgDevContext = {\n /** Absolute path to the project root */\n projectRoot: string\n /** Base path without trailing slash (e.g., '/my-site') */\n base: string\n /** Resolved content directories (absolute paths) */\n contentDirs: string[]\n /** Path to the SSR entry module */\n entry: string\n}\n\n/**\n * Configure the Vite dev server with SSR middleware for on-the-fly rendering.\n *\n * Sets up:\n * - File watcher for content companion assets\n * - Middleware for serving companion assets from `/assets/` paths\n * - Middleware for SSR-rendering HTML navigation requests\n */\nexport function configureSsgDevServer(server: ViteDevServer, context: SsgDevContext): void {\n const { projectRoot, base, contentDirs, entry } = context\n let contentAssets = new Map<string, string>()\n\n async function refreshContentArtifacts(): Promise<void> {\n contentAssets = collectContentAssets(contentDirs)\n }\n\n void refreshContentArtifacts().catch((error) => {\n console.warn(\n `pagesmith:ssg failed to prepare companion assets: ${error instanceof Error ? error.message : String(error)}`,\n )\n })\n\n if (contentDirs.length > 0) {\n server.watcher.add(contentDirs)\n\n const refresh = () => {\n void refreshContentArtifacts().catch((error) => {\n console.warn(\n `pagesmith:ssg failed to refresh companion assets: ${error instanceof Error ? error.message : String(error)}`,\n )\n })\n }\n\n server.watcher.on('add', refresh)\n server.watcher.on('change', refresh)\n server.watcher.on('unlink', refresh)\n }\n\n // Register middleware directly — appType: 'custom' disables Vite's\n // built-in HTML serving, so we handle all HTML requests via SSR.\n server.middlewares.use(async (req, res, next) => {\n const url = req.url ?? '/'\n const pathname = url.split(/[?#]/u, 1)[0] ?? url\n\n if (pathname.includes('/assets/')) {\n const assetName = pathname.split('/assets/').pop()\n const assetPath = assetName ? contentAssets.get(assetName) : undefined\n\n if (assetPath) {\n const ext = extname(assetPath).toLowerCase()\n res.writeHead(200, {\n 'Content-Type': MIME[ext] ?? 'application/octet-stream',\n 'Cache-Control': 'no-cache',\n })\n res.end(readFileSync(assetPath))\n return\n }\n }\n\n // Only handle HTML navigation requests (not assets, not files with extensions)\n const accept = req.headers.accept ?? ''\n const pathExt = extname(pathname)\n if (pathExt && pathExt !== '.html') return next()\n if (!pathExt && !accept.includes('text/html')) return next()\n\n // Redirect root to base\n if (base && (url === '/' || url === '')) {\n res.writeHead(302, { Location: `${base}/` })\n res.end()\n return\n }\n\n // Must start with base path\n if (base && !url.startsWith(base)) return next()\n\n try {\n // Load SSR module on-the-fly (Vite transforms TSX etc.)\n const ssrMod = await server.ssrLoadModule(resolve(projectRoot, entry))\n const renderFn: (url: string, cfg: SsgRenderConfig) => Promise<string> | string =\n ssrMod.render\n\n if (typeof renderFn !== 'function') {\n return next()\n }\n\n const renderConfig: SsgRenderConfig = {\n base,\n root: projectRoot,\n cssPath: `${base}/src/theme.css`, // Vite transforms this in dev\n jsPath: undefined,\n searchEnabled: false,\n isDev: true,\n }\n\n let html = await renderFn(url, renderConfig)\n html = rewriteContentAssetRefs(html, base)\n\n // Inject Vite's client + HMR script for live reload\n html = html.replace(\n '</head>',\n `<script type=\"module\" src=\"/@vite/client\"></script>\\n` +\n `<link rel=\"stylesheet\" href=\"${base}/src/theme.css\">\\n` +\n `</head>`,\n )\n\n // Let Vite transform the HTML (resolves module URLs, etc.)\n html = await server.transformIndexHtml(url, html)\n\n const status = html.includes('doc-not-found') ? 404 : 200\n res.writeHead(status, { 'Content-Type': 'text/html; charset=utf-8' })\n res.end(html)\n } catch (err: unknown) {\n server.ssrFixStacktrace(err as Error)\n console.error(`SSR error for ${url}:`, err instanceof Error ? err.message : String(err))\n next(err)\n }\n })\n}\n","/**\n * Pagefind search indexing for the SSG plugin.\n *\n * Runs the Pagefind CLI to index the generated static site output,\n * producing the search index used by the docs theme.\n */\n\nimport { dirname, join } from 'path'\nimport { fileURLToPath } from 'url'\n\n/**\n * Run Pagefind indexing on the built site output directory.\n *\n * Resolves the Pagefind binary from the installed package and invokes it\n * via a child process. Logs a warning and continues if Pagefind is not\n * installed.\n */\nexport async function runPagefindIndexing(outDir: string): Promise<void> {\n console.log('SSG: Indexing with Pagefind...')\n try {\n const pagefindMain = fileURLToPath(import.meta.resolve('pagefind'))\n const pagefindBin = join(dirname(pagefindMain), '..', 'lib', 'runner', 'bin.cjs')\n const { execFileSync } = await import('child_process')\n execFileSync(process.execPath, [pagefindBin, '--site', outDir], { stdio: 'inherit' })\n } catch {\n console.warn('SSG: Pagefind not found, skipping search indexing')\n }\n}\n","/**\n * Vite plugin for static site generation with @pagesmith/core.\n *\n * Handles both development (on-the-fly SSR via middleware) and\n * production (post-build SSG + pagefind indexing).\n *\n * The SSR entry module must export:\n * - `getRoutes(config)` — returns route paths to pre-render\n * - `render(url, config)` — renders a route to an HTML string\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { pagesmithSsg } from '@pagesmith/core/vite'\n *\n * export default defineConfig({\n * base: '/my-site/',\n * plugins: [pagesmithSsg({ entry: './src/entry-server.tsx' })],\n * })\n * ```\n */\n\nimport { resolve } from 'path'\nimport type { Plugin, ResolvedConfig } from 'vite'\nimport { configureSsgDevServer } from './ssg-hmr'\nimport { resolveContentDirs, renderStaticSite } from './ssg-render'\nimport { runPagefindIndexing } from './ssg-pagefind'\n\nexport type SsgPluginOptions = {\n /** Path to the SSR entry module (e.g., './src/entry-server.tsx') */\n entry: string\n /** Run pagefind after build (default: true) */\n pagefind?: boolean\n /** Content roots used for copying companion assets. */\n contentDirs?: string[]\n}\n\nexport type SsgRenderConfig = {\n /** Base path without trailing slash (e.g., '/my-site') */\n base: string\n /** Absolute path to the project root */\n root: string\n /** Path to the built CSS asset */\n cssPath: string\n /** Path to the built JS asset (undefined in dev for inline-script examples) */\n jsPath?: string\n /** Whether search is enabled (false in dev) */\n searchEnabled: boolean\n /** Whether running in dev mode */\n isDev: boolean\n}\n\nexport function pagesmithSsg(options: SsgPluginOptions): Plugin[] {\n const enablePagefind = options.pagefind !== false\n let config: ResolvedConfig\n let projectRoot: string\n let base: string // e.g., '/my-site'\n let outDir: string\n let contentDirs: string[] = []\n\n // ── Dev plugin: SSR middleware ──\n const devPlugin: Plugin = {\n name: 'pagesmith:ssg-dev',\n apply: 'serve',\n\n config() {\n // Disable Vite's built-in SPA HTML serving so the SSG middleware\n // can handle all HTML requests via server-side rendering.\n return { appType: 'custom' }\n },\n\n configResolved(resolved) {\n config = resolved\n projectRoot = resolved.root\n base = resolved.base.replace(/\\/+$/, '')\n outDir = resolve(projectRoot, resolved.build.outDir)\n contentDirs = resolveContentDirs(projectRoot, options.contentDirs)\n },\n\n configureServer(server) {\n configureSsgDevServer(server, {\n projectRoot,\n base,\n contentDirs,\n entry: options.entry,\n })\n },\n }\n\n // ── Build plugin: SSG post-build ──\n const buildPlugin: Plugin = {\n name: 'pagesmith:ssg-build',\n apply: 'build',\n\n configResolved(resolved) {\n config = resolved\n projectRoot = resolved.root\n base = resolved.base.replace(/\\/+$/, '')\n outDir = resolve(projectRoot, resolved.build.outDir)\n contentDirs = resolveContentDirs(projectRoot, options.contentDirs)\n },\n\n async closeBundle() {\n // Skip SSG during the SSR build itself (detected by ssr option)\n if (config.build.ssr) return\n\n const pageCount = await renderStaticSite({\n config,\n projectRoot,\n base,\n outDir,\n contentDirs,\n entry: options.entry,\n })\n\n if (enablePagefind) {\n await runPagefindIndexing(outDir)\n }\n\n console.log(`SSG: Done — ${pageCount} pages generated`)\n },\n }\n\n return [devPlugin, buildPlugin]\n}\n","import { existsSync } from 'fs'\nimport { dirname, relative, resolve } from 'path'\nimport type { PagesmithContentPluginOptions } from './content-plugin'\n\nfunction stripExtension(filePath: string): string {\n return filePath.replace(/\\.(c|m)?[jt]sx?$/u, '')\n}\n\nfunction normalizePath(value: string): string {\n return value.replace(/\\\\/g, '/')\n}\n\nexport function resolveDtsPath(\n projectRoot: string,\n dts: PagesmithContentPluginOptions<any>['dts'],\n): string {\n if (dts === false) {\n return ''\n }\n\n if (typeof dts === 'string') {\n return resolve(projectRoot, dts)\n }\n\n if (typeof dts === 'object' && dts?.path) {\n return resolve(projectRoot, dts.path)\n }\n\n const srcPath = resolve(projectRoot, 'src')\n if (existsSync(srcPath)) {\n return resolve(srcPath, 'pagesmith-content.d.ts')\n }\n\n return resolve(projectRoot, 'pagesmith-content.d.ts')\n}\n\nexport function createDtsSource(\n moduleId: string,\n collectionNames: string[],\n dtsPath: string,\n configPath: string,\n): string {\n const configImportPath = normalizePath(\n stripExtension(relative(dirname(dtsPath), configPath)).replace(/^[^.]/u, './$&'),\n )\n\n const moduleLines = collectionNames\n .map(\n (name) => `declare module '${moduleId}/${name}' {\n const collection: import('@pagesmith/core/vite').ContentCollectionModule<\n __PagesmithCollections['${name.replaceAll('\\\\', '\\\\\\\\').replaceAll(\"'\", \"\\\\'\")}']\n >\n export default collection\n}`,\n )\n .join('\\n\\n')\n\n return `// Generated by @pagesmith/core/vite. Do not edit manually.\ntype __PagesmithCollections = typeof import('${configImportPath}').default\n\ndeclare module '${moduleId}' {\n const content: import('@pagesmith/core/vite').ContentModuleMap<__PagesmithCollections>\n export default content\n}\n\n${moduleLines}\n`\n}\n","import { mkdirSync, writeFileSync } from 'fs'\nimport { dirname, relative, resolve } from 'path'\nimport { uneval } from 'devalue'\nimport { createContentLayer } from '../content-layer'\nimport { resolveLoader } from '../loaders'\nimport type { Heading } from '../schemas/heading'\nimport type { CollectionDef, CollectionMap, InferCollectionData } from '../schemas/collection'\nimport type { ContentLayerConfig } from '../schemas/content-config'\nimport { toSlug } from '../utils/slug'\nimport { createDtsSource, resolveDtsPath } from './dts'\n\ntype Simplify<T> = { [K in keyof T]: T[K] } & {}\n\ntype PagesmithResolvedConfig = {\n root: string\n}\n\ntype PagesmithModuleGraph = {\n getModuleById(id: string): unknown\n invalidateModule(module: unknown): void\n}\n\ntype PagesmithDevServer = {\n moduleGraph: PagesmithModuleGraph\n ws: {\n send(payload: { type: string }): void\n }\n}\n\nexport type PagesmithVitePlugin = {\n name: string\n enforce?: 'pre' | 'post'\n configResolved?: (config: PagesmithResolvedConfig) => void\n buildStart?: () => void\n resolveId?: (id: string) => string | void\n load?: (id: string) => Promise<string | void> | string | void\n handleHotUpdate?: (context: { file: string; server: PagesmithDevServer }) => void\n}\n\nexport type BaseContentModuleEntry = {\n id: string\n contentSlug: string\n}\n\nexport type MarkdownContentModuleEntry<TCollection extends CollectionDef<any, any, any>> = Simplify<\n BaseContentModuleEntry & {\n html: string\n headings: Heading[]\n frontmatter: InferCollectionData<TCollection>\n }\n>\n\nexport type DataContentModuleEntry<TCollection extends CollectionDef<any, any, any>> = Simplify<\n BaseContentModuleEntry & {\n data: InferCollectionData<TCollection>\n }\n>\n\ntype LoaderKindFromCollection<TCollection extends CollectionDef<any, any, any>> =\n TCollection['loader'] extends 'markdown'\n ? 'markdown'\n : TCollection['loader'] extends { kind: infer TKind }\n ? TKind\n : 'data'\n\nexport type ContentCollectionModule<TCollection extends CollectionDef<any, any, any>> =\n LoaderKindFromCollection<TCollection> extends 'markdown'\n ? MarkdownContentModuleEntry<TCollection>[]\n : DataContentModuleEntry<TCollection>[]\n\nexport type ContentModuleMap<TCollections extends CollectionMap> = {\n [TName in keyof TCollections]: ContentCollectionModule<TCollections[TName]>\n}\n\nexport type PagesmithContentPluginOptions<TCollections extends CollectionMap> = Omit<\n ContentLayerConfig,\n 'collections'\n> & {\n collections: TCollections\n /**\n * Shared content root used to compute `id` and `contentSlug`.\n * Defaults to the deepest common parent directory across all collection directories.\n */\n contentRoot?: string\n /**\n * Root virtual module id.\n * Per-collection modules are exposed as `${moduleId}/<collection-name>`.\n */\n moduleId?: string\n /**\n * Path to the content config module used for generated typings.\n * Defaults to `./content.config.ts`.\n */\n configPath?: string\n /**\n * Generate module declarations for the virtual modules.\n * Defaults to `src/pagesmith-content.d.ts` when `src/` exists, otherwise `pagesmith-content.d.ts`.\n */\n dts?: boolean | string | { path?: string }\n}\n\nconst DEFAULT_MODULE_ID = 'virtual:content'\n\nfunction normalizePath(value: string): string {\n return value.replace(/\\\\/g, '/')\n}\n\nfunction isPathWithin(parent: string, candidate: string): boolean {\n const rel = normalizePath(relative(parent, candidate))\n return rel === '' || (!rel.startsWith('..') && !rel.startsWith('/'))\n}\n\nfunction commonDirectory(paths: string[]): string {\n const normalized = paths.map((path) => normalizePath(resolve(path)))\n if (normalized.length === 0) return process.cwd()\n if (normalized.length === 1) return normalized[0]\n\n const segments = normalized.map((path) => path.split('/').filter(Boolean))\n const shared: string[] = []\n const first = segments[0]!\n\n for (let index = 0; index < first.length; index += 1) {\n const segment = first[index]\n if (segments.every((parts) => parts[index] === segment)) {\n shared.push(segment)\n continue\n }\n break\n }\n\n if (shared.length === 0) {\n return resolve('/')\n }\n\n return resolve(`/${shared.join('/')}`)\n}\n\nasync function serializeCollection(\n layer: ReturnType<typeof createContentLayer>,\n collectionName: string,\n collectionDef: CollectionDef<any, any, any>,\n contentRoot: string,\n): Promise<string> {\n const entries = await layer.getCollection(collectionName)\n const loader = resolveLoader(collectionDef.loader)\n const sortedEntries = [...entries].sort((left, right) =>\n left.filePath.localeCompare(right.filePath),\n )\n\n const payload = await Promise.all(\n sortedEntries.map(async (entry) => {\n const contentSlug = toSlug(entry.filePath, contentRoot)\n const base = {\n id: contentSlug,\n contentSlug,\n }\n\n if (loader.kind === 'markdown') {\n const rendered = await entry.render()\n return {\n ...base,\n html: rendered.html,\n headings: rendered.headings,\n frontmatter: entry.data,\n }\n }\n\n return {\n ...base,\n data: entry.data,\n }\n }),\n )\n\n return `const collection = ${uneval(payload)};\\nexport default collection;\\n`\n}\n\nfunction createRootModuleSource(moduleId: string, collectionNames: string[]): string {\n const imports = collectionNames\n .map((name, index) => `import collection${index} from '${moduleId}/${name}'`)\n .join('\\n')\n const contentMap = collectionNames\n .map((name, index) => `${JSON.stringify(name)}: collection${index}`)\n .join(', ')\n\n return `${imports}\\n\\nexport default { ${contentMap} };\\n`\n}\n\nfunction resolvePluginOptions<TCollections extends CollectionMap>(\n collectionsOrOptions: TCollections | PagesmithContentPluginOptions<TCollections>,\n maybeOptions: Omit<PagesmithContentPluginOptions<TCollections>, 'collections'> = {},\n): PagesmithContentPluginOptions<TCollections> {\n if ('collections' in collectionsOrOptions) {\n return collectionsOrOptions as PagesmithContentPluginOptions<TCollections>\n }\n\n return {\n ...maybeOptions,\n collections: collectionsOrOptions,\n }\n}\n\nexport function pagesmithContent<TCollections extends CollectionMap>(\n collections: TCollections,\n options?: Omit<PagesmithContentPluginOptions<TCollections>, 'collections'>,\n): PagesmithVitePlugin\nexport function pagesmithContent<TCollections extends CollectionMap>(\n options: PagesmithContentPluginOptions<TCollections>,\n): PagesmithVitePlugin\nexport function pagesmithContent<TCollections extends CollectionMap>(\n collectionsOrOptions: TCollections | PagesmithContentPluginOptions<TCollections>,\n maybeOptions: Omit<PagesmithContentPluginOptions<TCollections>, 'collections'> = {},\n): PagesmithVitePlugin {\n const options = resolvePluginOptions(collectionsOrOptions, maybeOptions)\n const collectionNames = Object.keys(options.collections)\n const moduleId = options.moduleId ?? DEFAULT_MODULE_ID\n const resolvedPrefix = `\\0${moduleId}/`\n const resolvedRootId = `\\0${moduleId}`\n\n let projectRoot = process.cwd()\n let layerRoot = projectRoot\n let contentRoot = projectRoot\n let configPath = resolve(projectRoot, options.configPath ?? 'content.config.ts')\n let dtsPath = resolveDtsPath(projectRoot, options.dts)\n let layer: ReturnType<typeof createContentLayer> | null = null\n\n function getLayer(): ReturnType<typeof createContentLayer> {\n if (!layer) {\n throw new Error(\n 'pagesmith-content: ContentLayer not initialized. configResolved has not run yet.',\n )\n }\n return layer\n }\n\n const ensureDeclarations = (): void => {\n if (options.dts === false) return\n\n const source = createDtsSource(moduleId, collectionNames, dtsPath, configPath)\n mkdirSync(dirname(dtsPath), { recursive: true })\n writeFileSync(dtsPath, source)\n }\n\n return {\n name: 'pagesmith-content',\n enforce: 'pre',\n\n configResolved(config) {\n projectRoot = resolve(config.root)\n layerRoot = resolve(projectRoot, options.root ?? '.')\n configPath = resolve(projectRoot, options.configPath ?? 'content.config.ts')\n dtsPath = resolveDtsPath(projectRoot, options.dts)\n\n const collectionDirectories = collectionNames.map((name) =>\n resolve(layerRoot, options.collections[name]!.directory),\n )\n contentRoot = options.contentRoot\n ? resolve(layerRoot, options.contentRoot)\n : commonDirectory(collectionDirectories)\n\n layer = createContentLayer({\n ...options,\n root: layerRoot,\n })\n\n ensureDeclarations()\n },\n\n buildStart() {\n ensureDeclarations()\n },\n\n resolveId(id) {\n if (id === moduleId) {\n return resolvedRootId\n }\n\n for (const name of collectionNames) {\n if (id === `${moduleId}/${name}`) {\n return `${resolvedPrefix}${name}`\n }\n }\n },\n\n async load(id) {\n if (id === resolvedRootId) {\n return createRootModuleSource(moduleId, collectionNames)\n }\n\n if (!id.startsWith(resolvedPrefix)) return\n\n const collectionName = id.slice(resolvedPrefix.length)\n const collectionDef = options.collections[collectionName]\n if (!collectionDef) return\n\n return serializeCollection(getLayer(), collectionName, collectionDef, contentRoot)\n },\n\n handleHotUpdate({ file, server }) {\n const resolvedFile = resolve(file)\n const touchesConfig = resolvedFile === configPath\n\n const affectedCollections = collectionNames.filter((name) =>\n isPathWithin(resolve(layerRoot, options.collections[name]!.directory), resolvedFile),\n )\n\n const touchesContent = affectedCollections.length > 0\n\n if (!touchesConfig && !touchesContent) return\n\n if (touchesConfig) {\n ensureDeclarations()\n }\n\n const rootModule = server.moduleGraph.getModuleById(resolvedRootId)\n if (rootModule) {\n server.moduleGraph.invalidateModule(rootModule)\n }\n\n if (touchesContent) {\n for (const name of affectedCollections) {\n const moduleNode = server.moduleGraph.getModuleById(`${resolvedPrefix}${name}`)\n if (moduleNode) {\n server.moduleGraph.invalidateModule(moduleNode)\n }\n getLayer()\n .invalidateCollection(name)\n .catch((err) => {\n console.warn(`[pagesmith] Failed to invalidate collection \"${name}\":`, err)\n })\n }\n } else {\n for (const name of collectionNames) {\n const moduleNode = server.moduleGraph.getModuleById(`${resolvedPrefix}${name}`)\n if (moduleNode) {\n server.moduleGraph.invalidateModule(moduleNode)\n }\n }\n getLayer().invalidateAll()\n }\n\n server.ws.send({ type: 'full-reload' })\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA,eAAsB,gBAAgB,SAAuD;CAC3F,MAAM,cAAc,QAAQ,eAAe;CAC3C,MAAM,UAAU,QAAQ,WAAW;AAGnC,KAAI,CAAC,WAAW,QAAQ,YAAY,CAClC,OAAM,IAAI,MAAM,wBAAwB,QAAQ,cAAc;CAGhE,MAAM,MAAM,MAAM,OAAO,cAAc,QAAQ,YAAY,CAAC;CAC5D,MAAM,SAAoD,IAAI,UAAU,IAAI,SAAS;AAErF,KAAI,OAAO,WAAW,WACpB,OAAM,IAAI,MACR,0EACoB,OAAO,KAAK,IAAI,CAAC,KAAK,KAAK,GAChD;CAKH,MAAM,WAAW,aADI,QAAQ,QAAQ,QAAQ,aAAa,EACd,QAAQ;AAEpD,KAAI,CAAC,SAAS,SAAS,YAAY,CACjC,OAAM,IAAI,MACR,+CAA+C,YAAY,oEAE5D;AAIH,MAAK,MAAM,SAAS,QAAQ,QAAQ;EAClC,MAAM,WAAW,MAAM,OAAO,MAAM;EACpC,MAAM,OAAO,SAAS,QAAQ,aAAa,SAAS;EAEpD,MAAM,YAAY,UAAU,MAAM,KAAK,MAAM,QAAQ,OAAO,GAAG;EAC/D,MAAM,UAAU,QAAQ,QAAQ,QAAQ,WAAW,aAAa;AAChE,YAAU,QAAQ,QAAQ,EAAE,EAAE,WAAW,MAAM,CAAC;AAChD,gBAAc,SAAS,KAAK;;AAI9B,KAAI,QAEF,QADkB,QAAQ,QAAQ,YAAY,EAC5B;EAAE,WAAW;EAAM,OAAO;EAAM,CAAC;AAGrD,QAAO,EAAE,OAAO,QAAQ,OAAO,QAAQ;;;;;;;;ACvFzC,SAAgB,qBAA6B;CAE3C,MAAM,YAAY,KADH,KAAK,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC,EAAE,MAAM,KAAK,EACzC,SAAS;AAExC,QAAO;EACL,MAAM;EACN,gBAAgB,QAAQ;AACtB,UAAO,YAAY,KAAK,KAAK,KAAK,SAAS;IACzC,MAAM,MAAM,IAAI,OAAO;AAGvB,QAAI,QAAQ,uBAAuB,IAAI,SAAS,oBAAoB,EAAE;KACpE,MAAM,WAAW,KAAK,WAAW,YAAY;AAC7C,SAAI,WAAW,SAAS,EAAE;AACxB,UAAI,UAAU,KAAK;OAAE,gBAAgB;OAAY,iBAAiB;OAAY,CAAC;AAC/E,UAAI,IAAI,aAAa,UAAU,QAAQ,CAAC;AACxC;;;AAKJ,QAAI,IAAI,SAAS,iBAAiB,IAAI,IAAI,SAAS,SAAS,EAAE;KAC5D,MAAM,WAAW,IAAI,MAAM,iBAAiB,CAAC,KAAK;AAClD,SAAI,UAAU;MACZ,MAAM,WAAW,KAAK,WAAW,SAAS,SAAS;AACnD,UAAI,WAAW,SAAS,EAAE;AACxB,WAAI,UAAU,KAAK;QACjB,gBAAgB;QAChB,iBAAiB;QAClB,CAAC;AACF,WAAI,IAAI,aAAa,SAAS,CAAC;AAC/B;;;;AAKN,UAAM;KACN;;EAEL;;;;;;;;;;;;;;ACtBH,MAAa,OAA+B;CAC1C,SAAS;CACT,QAAQ;CACR,OAAO;CACP,SAAS;CACT,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,SAAS;CACT,SAAS;CACT,QAAQ;CACR,UAAU;CACV,SAAS;CACT,QAAQ;CACR,QAAQ;CACR,QAAQ;CACT;AAID,SAAgB,mBAAmB,aAAqB,cAAwB,EAAE,EAAY;AAC5F,QAAO,YAAY,KAAK,QAAQ,QAAQ,aAAa,IAAI,CAAC;;AAG5D,SAAS,iBAAiB,KAAsB;AAC9C,KAAI,CAAC,IAAI,WAAW,KAAK,CAAE,QAAO;CAClC,MAAM,OAAO,IAAI,MAAM,SAAS,EAAE,CAAC,MAAM;AACzC,QAAO,mBAAmB,IAAI,QAAQ,KAAK,CAAC,aAAa,CAAC;;AAG5D,SAAgB,wBAAwB,MAAc,MAAsB;CAC1E,MAAM,aAAa,KAAK,QAAQ,SAAS,GAAG;AAE5C,QAAO,KAAK,QACV,+CACC,OAAO,MAAc,WAA+B,cAAkC;EACrF,MAAM,MAAM,aAAa,aAAa;AACtC,MAAI,CAAC,iBAAiB,IAAI,CAAE,QAAO;EACnC,MAAM,WAAW,IAAI,MAAM,SAAS,EAAE,CAAC,MAAM;EAC7C,MAAM,SAAS,IAAI,MAAM,SAAS,OAAO;EACzC,MAAM,QAAQ,cAAc,KAAA,IAAY,OAAM;AAC9C,SAAO,GAAG,KAAK,GAAG,QAAQ,WAAW,UAAU,SAAS,MAAM,IAAI,CAAC,KAAK,IAAI,WAAW,SAAS;GAEnG;;AAGH,SAAS,0BAA0B,QAAgB,QAAmC;AACpF,KAAI,OAAO,SAAS,EAAG;CAEvB,MAAM,YAAY,KAAK,QAAQ,SAAS;AACxC,WAAU,WAAW,EAAE,WAAW,MAAM,CAAC;AAEzC,MAAK,MAAM,CAAC,UAAU,eAAe,OACnC,cAAa,YAAY,KAAK,WAAW,SAAS,CAAC;;;;;;;AA0BvD,eAAsB,iBAAiB,SAA2C;CAChF,MAAM,EAAE,QAAQ,aAAa,MAAM,QAAQ,aAAa,UAAU;AAElE,SAAQ,IAAI,4CAA4C;CAExD,MAAM,gBAAgB,qBAAqB,YAAY;AAGvD,gBAAe,OAAO;AAItB,iBADkB,KAAK,aAAa,SAAS,EAClB,OAAO;CAGlC,MAAM,EAAE,SAAS,WAAW,oBAAoB,QAAQ,KAAK;AAG7D,SAAQ,IAAI,8BAA8B;AAC1C,OAAM,eAAe,QAAQ,aAAa,QAAQ,MAAM;CAGxD,MAAM,gBAAgB,SAAS,MAAM,CAAC,QAAQ,qBAAqB,MAAM;CACzE,MAAM,YAAY,KAAK,QAAQ,UAAU;CAEzC,MAAM,SAAS,MAAM,OAAO,cADR,KAAK,WAAW,cAAc,CACI,CAAC;CAEvD,MAAM,eAAgC;EACpC;EACA,MAAM;EACN;EACA;EACA,eAAe;EACf,OAAO;EACR;CAGD,MAAM,SAAmB,MAAM,OAAO,UAAU,aAAa;AAC7D,SAAQ,IAAI,kBAAkB,OAAO,OAAO,WAAW;CAEvD,MAAM,cAAc,KAAK,IAAI,OAAO,QAAQ,EAAE;CAC9C,IAAI,aAAa;CAEjB,eAAe,eAA8B;AAC3C,SAAO,aAAa,OAAO,QAAQ;GAEjC,MAAM,QAAQ,OADJ;GAEV,MAAM,OAAO,wBAAwB,MAAM,OAAO,OAAO,OAAO,aAAa,EAAE,KAAK;GAEpF,MAAM,aAAa,KAAK,QADN,UAAU,MAAM,KAAK,MAAM,QAAQ,OAAO,GAAG,EACpB,aAAa;AACxD,aAAU,QAAQ,WAAW,EAAE,EAAE,WAAW,MAAM,CAAC;AACnD,iBAAc,YAAY,oBAAoB,OAAO;AAErD,OAAI,UAAU,OACZ,eAAc,KAAK,QAAQ,WAAW,EAAE,oBAAoB,OAAO;;;CAKzE,MAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,aAAa,QAAQ,cAAc,CAAC;AACzE,OAAM,QAAQ,IAAI,QAAQ;AAE1B,2BAA0B,QAAQ,cAAc;AAGhD,QAAO,WAAW;EAAE,WAAW;EAAM,OAAO;EAAM,CAAC;AAEnD,QAAO,OAAO;;AAGhB,SAAS,eAAe,QAAsB;CAC5C,MAAM,aAAa,QAAQ,cAAc,OAAO,KAAK,QAAQ,+BAA+B,CAAC,CAAC;CAC9F,MAAM,eAAe,KAAK,YAAY,UAAU,QAAQ;CACxD,MAAM,cAAc,KAAK,QAAQ,UAAU,QAAQ;AACnD,WAAU,aAAa,EAAE,WAAW,MAAM,CAAC;AAC3C,MAAK,MAAM,QAAQ,YAAY,aAAa,CAC1C,KAAI,KAAK,SAAS,SAAS,CACzB,cAAa,KAAK,cAAc,KAAK,EAAE,KAAK,aAAa,KAAK,CAAC;AAGnE,cAAa,KAAK,YAAY,UAAU,YAAY,EAAE,KAAK,QAAQ,UAAU,YAAY,CAAC;;AAG5F,SAAS,oBACP,QACA,MACiD;CACjD,MAAM,aAAa,KAAK,QAAQ,aAAa;CAC7C,IAAI,UAAU,GAAG,KAAK;CACtB,IAAI;AACJ,KAAI,WAAW,WAAW,EAAE;EAC1B,MAAM,OAAO,aAAa,YAAY,QAAQ;EAC9C,MAAM,WAAW,KAAK,MAAM,sBAAsB;EAClD,MAAM,UAAU,KAAK,MAAM,oBAAoB;AAC/C,MAAI,SAAU,WAAU,SAAS;AACjC,MAAI,QAAS,UAAS,QAAQ;;AAEhC,QAAO;EAAE;EAAS;EAAQ;;AAG5B,eAAe,eACb,QACA,aACA,QACA,OACe;CACf,MAAM,EAAE,iBAAiB,MAAM,OAAO;CACtC,MAAM,YAAY,KAAK,QAAQ,UAAU;CACzC,MAAM,WAAW,QAAQ,aAAa,MAAM;CAE5C,MAAM,cAAc;;;cAGR,KAAK,UAAU,YAAY,CAAC;;cAE5B,KAAK,UAAU,OAAO,KAAK,CAAC;;eAE3B,KAAK,UAAU,SAAS,CAAC;kBACtB,KAAK,UAAU,UAAU,CAAC;;;;;AAK1C,cAAa,QAAQ,UAAU;EAAC;EAAuB;EAAM;EAAY,EAAE;EACzE,OAAO;EACP,KAAK;EACN,CAAC;;;;;;;;;;;;;;;;;;;;AC/LJ,SAAgB,sBAAsB,QAAuB,SAA8B;CACzF,MAAM,EAAE,aAAa,MAAM,aAAa,UAAU;CAClD,IAAI,gCAAgB,IAAI,KAAqB;CAE7C,eAAe,0BAAyC;AACtD,kBAAgB,qBAAqB,YAAY;;AAG9C,0BAAyB,CAAC,OAAO,UAAU;AAC9C,UAAQ,KACN,qDAAqD,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,GAC5G;GACD;AAEF,KAAI,YAAY,SAAS,GAAG;AAC1B,SAAO,QAAQ,IAAI,YAAY;EAE/B,MAAM,gBAAgB;AACf,4BAAyB,CAAC,OAAO,UAAU;AAC9C,YAAQ,KACN,qDAAqD,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,GAC5G;KACD;;AAGJ,SAAO,QAAQ,GAAG,OAAO,QAAQ;AACjC,SAAO,QAAQ,GAAG,UAAU,QAAQ;AACpC,SAAO,QAAQ,GAAG,UAAU,QAAQ;;AAKtC,QAAO,YAAY,IAAI,OAAO,KAAK,KAAK,SAAS;EAC/C,MAAM,MAAM,IAAI,OAAO;EACvB,MAAM,WAAW,IAAI,MAAM,SAAS,EAAE,CAAC,MAAM;AAE7C,MAAI,SAAS,SAAS,WAAW,EAAE;GACjC,MAAM,YAAY,SAAS,MAAM,WAAW,CAAC,KAAK;GAClD,MAAM,YAAY,YAAY,cAAc,IAAI,UAAU,GAAG,KAAA;AAE7D,OAAI,WAAW;IACb,MAAM,MAAM,QAAQ,UAAU,CAAC,aAAa;AAC5C,QAAI,UAAU,KAAK;KACjB,gBAAgB,KAAK,QAAQ;KAC7B,iBAAiB;KAClB,CAAC;AACF,QAAI,IAAI,aAAa,UAAU,CAAC;AAChC;;;EAKJ,MAAM,SAAS,IAAI,QAAQ,UAAU;EACrC,MAAM,UAAU,QAAQ,SAAS;AACjC,MAAI,WAAW,YAAY,QAAS,QAAO,MAAM;AACjD,MAAI,CAAC,WAAW,CAAC,OAAO,SAAS,YAAY,CAAE,QAAO,MAAM;AAG5D,MAAI,SAAS,QAAQ,OAAO,QAAQ,KAAK;AACvC,OAAI,UAAU,KAAK,EAAE,UAAU,GAAG,KAAK,IAAI,CAAC;AAC5C,OAAI,KAAK;AACT;;AAIF,MAAI,QAAQ,CAAC,IAAI,WAAW,KAAK,CAAE,QAAO,MAAM;AAEhD,MAAI;GAGF,MAAM,YADS,MAAM,OAAO,cAAc,QAAQ,aAAa,MAAM,CAAC,EAE7D;AAET,OAAI,OAAO,aAAa,WACtB,QAAO,MAAM;GAYf,IAAI,OAAO,MAAM,SAAS,KATY;IACpC;IACA,MAAM;IACN,SAAS,GAAG,KAAK;IACjB,QAAQ,KAAA;IACR,eAAe;IACf,OAAO;IACR,CAE2C;AAC5C,UAAO,wBAAwB,MAAM,KAAK;AAG1C,UAAO,KAAK,QACV,WACA,sFACkC,KAAK,2BAExC;AAGD,UAAO,MAAM,OAAO,mBAAmB,KAAK,KAAK;GAEjD,MAAM,SAAS,KAAK,SAAS,gBAAgB,GAAG,MAAM;AACtD,OAAI,UAAU,QAAQ,EAAE,gBAAgB,4BAA4B,CAAC;AACrE,OAAI,IAAI,KAAK;WACN,KAAc;AACrB,UAAO,iBAAiB,IAAa;AACrC,WAAQ,MAAM,iBAAiB,IAAI,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAAC;AACxF,QAAK,IAAI;;GAEX;;;;;;;;;;;;;;;;;ACrIJ,eAAsB,oBAAoB,QAA+B;AACvE,SAAQ,IAAI,iCAAiC;AAC7C,KAAI;EAEF,MAAM,cAAc,KAAK,QADJ,cAAc,OAAO,KAAK,QAAQ,WAAW,CAAC,CACrB,EAAE,MAAM,OAAO,UAAU,UAAU;EACjF,MAAM,EAAE,iBAAiB,MAAM,OAAO;AACtC,eAAa,QAAQ,UAAU;GAAC;GAAa;GAAU;GAAO,EAAE,EAAE,OAAO,WAAW,CAAC;SAC/E;AACN,UAAQ,KAAK,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;;AC2BrE,SAAgB,aAAa,SAAqC;CAChE,MAAM,iBAAiB,QAAQ,aAAa;CAC5C,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI,cAAwB,EAAE;AAiE9B,QAAO,CA9DmB;EACxB,MAAM;EACN,OAAO;EAEP,SAAS;AAGP,UAAO,EAAE,SAAS,UAAU;;EAG9B,eAAe,UAAU;AACvB,YAAS;AACT,iBAAc,SAAS;AACvB,UAAO,SAAS,KAAK,QAAQ,QAAQ,GAAG;AACxC,YAAS,QAAQ,aAAa,SAAS,MAAM,OAAO;AACpD,iBAAc,mBAAmB,aAAa,QAAQ,YAAY;;EAGpE,gBAAgB,QAAQ;AACtB,yBAAsB,QAAQ;IAC5B;IACA;IACA;IACA,OAAO,QAAQ;IAChB,CAAC;;EAEL,EAG2B;EAC1B,MAAM;EACN,OAAO;EAEP,eAAe,UAAU;AACvB,YAAS;AACT,iBAAc,SAAS;AACvB,UAAO,SAAS,KAAK,QAAQ,QAAQ,GAAG;AACxC,YAAS,QAAQ,aAAa,SAAS,MAAM,OAAO;AACpD,iBAAc,mBAAmB,aAAa,QAAQ,YAAY;;EAGpE,MAAM,cAAc;AAElB,OAAI,OAAO,MAAM,IAAK;GAEtB,MAAM,YAAY,MAAM,iBAAiB;IACvC;IACA;IACA;IACA;IACA;IACA,OAAO,QAAQ;IAChB,CAAC;AAEF,OAAI,eACF,OAAM,oBAAoB,OAAO;AAGnC,WAAQ,IAAI,eAAe,UAAU,kBAAkB;;EAE1D,CAE8B;;;;ACvHjC,SAAS,eAAe,UAA0B;AAChD,QAAO,SAAS,QAAQ,qBAAqB,GAAG;;AAGlD,SAASA,gBAAc,OAAuB;AAC5C,QAAO,MAAM,QAAQ,OAAO,IAAI;;AAGlC,SAAgB,eACd,aACA,KACQ;AACR,KAAI,QAAQ,MACV,QAAO;AAGT,KAAI,OAAO,QAAQ,SACjB,QAAO,QAAQ,aAAa,IAAI;AAGlC,KAAI,OAAO,QAAQ,YAAY,KAAK,KAClC,QAAO,QAAQ,aAAa,IAAI,KAAK;CAGvC,MAAM,UAAU,QAAQ,aAAa,MAAM;AAC3C,KAAI,WAAW,QAAQ,CACrB,QAAO,QAAQ,SAAS,yBAAyB;AAGnD,QAAO,QAAQ,aAAa,yBAAyB;;AAGvD,SAAgB,gBACd,UACA,iBACA,SACA,YACQ;AAgBR,QAAO;+CAfkBA,gBACvB,eAAe,SAAS,QAAQ,QAAQ,EAAE,WAAW,CAAC,CAAC,QAAQ,UAAU,OAAO,CACjF,CAc6D;;kBAE9C,SAAS;;;;;EAdL,gBACjB,KACE,SAAS,mBAAmB,SAAS,GAAG,KAAK;;8BAEtB,KAAK,WAAW,MAAM,OAAO,CAAC,WAAW,KAAK,MAAM,CAAC;;;GAI9E,CACA,KAAK,OAAO,CAUH;;;;;ACoCd,MAAM,oBAAoB;AAE1B,SAAS,cAAc,OAAuB;AAC5C,QAAO,MAAM,QAAQ,OAAO,IAAI;;AAGlC,SAAS,aAAa,QAAgB,WAA4B;CAChE,MAAM,MAAM,cAAc,SAAS,QAAQ,UAAU,CAAC;AACtD,QAAO,QAAQ,MAAO,CAAC,IAAI,WAAW,KAAK,IAAI,CAAC,IAAI,WAAW,IAAI;;AAGrE,SAAS,gBAAgB,OAAyB;CAChD,MAAM,aAAa,MAAM,KAAK,SAAS,cAAc,QAAQ,KAAK,CAAC,CAAC;AACpE,KAAI,WAAW,WAAW,EAAG,QAAO,QAAQ,KAAK;AACjD,KAAI,WAAW,WAAW,EAAG,QAAO,WAAW;CAE/C,MAAM,WAAW,WAAW,KAAK,SAAS,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ,CAAC;CAC1E,MAAM,SAAmB,EAAE;CAC3B,MAAM,QAAQ,SAAS;AAEvB,MAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GAAG;EACpD,MAAM,UAAU,MAAM;AACtB,MAAI,SAAS,OAAO,UAAU,MAAM,WAAW,QAAQ,EAAE;AACvD,UAAO,KAAK,QAAQ;AACpB;;AAEF;;AAGF,KAAI,OAAO,WAAW,EACpB,QAAO,QAAQ,IAAI;AAGrB,QAAO,QAAQ,IAAI,OAAO,KAAK,IAAI,GAAG;;AAGxC,eAAe,oBACb,OACA,gBACA,eACA,aACiB;CACjB,MAAM,UAAU,MAAM,MAAM,cAAc,eAAe;CACzD,MAAM,SAAS,cAAc,cAAc,OAAO;CAClD,MAAM,gBAAgB,CAAC,GAAG,QAAQ,CAAC,MAAM,MAAM,UAC7C,KAAK,SAAS,cAAc,MAAM,SAAS,CAC5C;AA2BD,QAAO,sBAAsB,OAzBb,MAAM,QAAQ,IAC5B,cAAc,IAAI,OAAO,UAAU;EACjC,MAAM,cAAc,OAAO,MAAM,UAAU,YAAY;EACvD,MAAM,OAAO;GACX,IAAI;GACJ;GACD;AAED,MAAI,OAAO,SAAS,YAAY;GAC9B,MAAM,WAAW,MAAM,MAAM,QAAQ;AACrC,UAAO;IACL,GAAG;IACH,MAAM,SAAS;IACf,UAAU,SAAS;IACnB,aAAa,MAAM;IACpB;;AAGH,SAAO;GACL,GAAG;GACH,MAAM,MAAM;GACb;GACD,CACH,CAE2C,CAAC;;AAG/C,SAAS,uBAAuB,UAAkB,iBAAmC;AAQnF,QAAO,GAPS,gBACb,KAAK,MAAM,UAAU,oBAAoB,MAAM,SAAS,SAAS,GAAG,KAAK,GAAG,CAC5E,KAAK,KAAK,CAKK,uBAJC,gBAChB,KAAK,MAAM,UAAU,GAAG,KAAK,UAAU,KAAK,CAAC,cAAc,QAAQ,CACnE,KAAK,KAAK,CAEuC;;AAGtD,SAAS,qBACP,sBACA,eAAiF,EAAE,EACtC;AAC7C,KAAI,iBAAiB,qBACnB,QAAO;AAGT,QAAO;EACL,GAAG;EACH,aAAa;EACd;;AAUH,SAAgB,iBACd,sBACA,eAAiF,EAAE,EAC9D;CACrB,MAAM,UAAU,qBAAqB,sBAAsB,aAAa;CACxE,MAAM,kBAAkB,OAAO,KAAK,QAAQ,YAAY;CACxD,MAAM,WAAW,QAAQ,YAAY;CACrC,MAAM,iBAAiB,KAAK,SAAS;CACrC,MAAM,iBAAiB,KAAK;CAE5B,IAAI,cAAc,QAAQ,KAAK;CAC/B,IAAI,YAAY;CAChB,IAAI,cAAc;CAClB,IAAI,aAAa,QAAQ,aAAa,QAAQ,cAAc,oBAAoB;CAChF,IAAI,UAAU,eAAe,aAAa,QAAQ,IAAI;CACtD,IAAI,QAAsD;CAE1D,SAAS,WAAkD;AACzD,MAAI,CAAC,MACH,OAAM,IAAI,MACR,mFACD;AAEH,SAAO;;CAGT,MAAM,2BAAiC;AACrC,MAAI,QAAQ,QAAQ,MAAO;EAE3B,MAAM,SAAS,gBAAgB,UAAU,iBAAiB,SAAS,WAAW;AAC9E,YAAU,QAAQ,QAAQ,EAAE,EAAE,WAAW,MAAM,CAAC;AAChD,gBAAc,SAAS,OAAO;;AAGhC,QAAO;EACL,MAAM;EACN,SAAS;EAET,eAAe,QAAQ;AACrB,iBAAc,QAAQ,OAAO,KAAK;AAClC,eAAY,QAAQ,aAAa,QAAQ,QAAQ,IAAI;AACrD,gBAAa,QAAQ,aAAa,QAAQ,cAAc,oBAAoB;AAC5E,aAAU,eAAe,aAAa,QAAQ,IAAI;GAElD,MAAM,wBAAwB,gBAAgB,KAAK,SACjD,QAAQ,WAAW,QAAQ,YAAY,MAAO,UAAU,CACzD;AACD,iBAAc,QAAQ,cAClB,QAAQ,WAAW,QAAQ,YAAY,GACvC,gBAAgB,sBAAsB;AAE1C,WAAQ,mBAAmB;IACzB,GAAG;IACH,MAAM;IACP,CAAC;AAEF,uBAAoB;;EAGtB,aAAa;AACX,uBAAoB;;EAGtB,UAAU,IAAI;AACZ,OAAI,OAAO,SACT,QAAO;AAGT,QAAK,MAAM,QAAQ,gBACjB,KAAI,OAAO,GAAG,SAAS,GAAG,OACxB,QAAO,GAAG,iBAAiB;;EAKjC,MAAM,KAAK,IAAI;AACb,OAAI,OAAO,eACT,QAAO,uBAAuB,UAAU,gBAAgB;AAG1D,OAAI,CAAC,GAAG,WAAW,eAAe,CAAE;GAEpC,MAAM,iBAAiB,GAAG,MAAM,eAAe,OAAO;GACtD,MAAM,gBAAgB,QAAQ,YAAY;AAC1C,OAAI,CAAC,cAAe;AAEpB,UAAO,oBAAoB,UAAU,EAAE,gBAAgB,eAAe,YAAY;;EAGpF,gBAAgB,EAAE,MAAM,UAAU;GAChC,MAAM,eAAe,QAAQ,KAAK;GAClC,MAAM,gBAAgB,iBAAiB;GAEvC,MAAM,sBAAsB,gBAAgB,QAAQ,SAClD,aAAa,QAAQ,WAAW,QAAQ,YAAY,MAAO,UAAU,EAAE,aAAa,CACrF;GAED,MAAM,iBAAiB,oBAAoB,SAAS;AAEpD,OAAI,CAAC,iBAAiB,CAAC,eAAgB;AAEvC,OAAI,cACF,qBAAoB;GAGtB,MAAM,aAAa,OAAO,YAAY,cAAc,eAAe;AACnE,OAAI,WACF,QAAO,YAAY,iBAAiB,WAAW;AAGjD,OAAI,eACF,MAAK,MAAM,QAAQ,qBAAqB;IACtC,MAAM,aAAa,OAAO,YAAY,cAAc,GAAG,iBAAiB,OAAO;AAC/E,QAAI,WACF,QAAO,YAAY,iBAAiB,WAAW;AAEjD,cAAU,CACP,qBAAqB,KAAK,CAC1B,OAAO,QAAQ;AACd,aAAQ,KAAK,gDAAgD,KAAK,KAAK,IAAI;MAC3E;;QAED;AACL,SAAK,MAAM,QAAQ,iBAAiB;KAClC,MAAM,aAAa,OAAO,YAAY,cAAc,GAAG,iBAAiB,OAAO;AAC/E,SAAI,WACF,QAAO,YAAY,iBAAiB,WAAW;;AAGnD,cAAU,CAAC,eAAe;;AAG5B,UAAO,GAAG,KAAK,EAAE,MAAM,eAAe,CAAC;;EAE1C"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["normalizePath"],"sources":["../../src/vite/ssg.ts","../../src/vite/shared-assets.ts","../../src/vite/ssg-render.ts","../../src/vite/ssg-hmr.ts","../../src/vite/ssg-pagefind.ts","../../src/vite/ssg-plugin.ts","../../src/vite/dts.ts","../../src/vite/content-plugin.ts"],"sourcesContent":["/**\n * Pre-rendering utility for Vite-based SSG sites.\n *\n * Call after running both the client and SSR Vite builds.\n * Loads the SSR module, renders each route, injects into the\n * client HTML template, and writes static files.\n */\n\nimport { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'fs'\nimport { dirname, resolve } from 'path'\nimport { pathToFileURL } from 'url'\n\nexport type PrerenderOptions = {\n /** Absolute path to the client build output directory (e.g., `dist/`) */\n outDir: string\n /** Absolute path to the built SSR entry module (e.g., `dist/.server/entry-server.js`) */\n serverEntry: string\n /** Routes to pre-render (e.g., `['/', '/about', '/posts/hello-world']`) */\n routes: string[]\n /** HTML placeholder to replace with rendered content (default: `'<!--ssr-outlet-->'`) */\n placeholder?: string\n /** Remove the server build directory after pre-rendering (default: true) */\n cleanup?: boolean\n}\n\n/**\n * Pre-render routes to static HTML files.\n *\n * Expects the SSR entry to export a `render(url: string): string` function.\n *\n * @example\n * ```ts\n * import { build } from 'vite'\n * import { prerenderRoutes } from '@pagesmith/core/vite'\n *\n * // 1. Client build\n * await build({ build: { outDir: 'dist' } })\n *\n * // 2. SSR build\n * await build({ build: { ssr: 'src/entry-server.tsx', outDir: 'dist/.server' } })\n *\n * // 3. Pre-render\n * await prerenderRoutes({\n * outDir: resolve('dist'),\n * serverEntry: resolve('dist/.server/entry-server.js'),\n * routes: ['/', '/about', '/posts/hello-world'],\n * })\n * ```\n */\nexport async function prerenderRoutes(options: PrerenderOptions): Promise<{ pages: number }> {\n const placeholder = options.placeholder ?? '<!--ssr-outlet-->'\n const cleanup = options.cleanup ?? true\n\n // Load SSR module\n if (!existsSync(options.serverEntry)) {\n throw new Error(`SSR entry not found: ${options.serverEntry}`)\n }\n\n const mod = await import(pathToFileURL(options.serverEntry).href)\n const render: (url: string) => string | Promise<string> = mod.render ?? mod.default?.render\n\n if (typeof render !== 'function') {\n throw new Error(\n `SSR entry must export a 'render(url: string)' function. ` +\n `Found exports: ${Object.keys(mod).join(', ')}`,\n )\n }\n\n // Read client HTML template\n const templatePath = resolve(options.outDir, 'index.html')\n const template = readFileSync(templatePath, 'utf-8')\n\n if (!template.includes(placeholder)) {\n throw new Error(\n `HTML template does not contain placeholder \"${placeholder}\". ` +\n `Add it to your index.html where SSR content should be injected.`,\n )\n }\n\n // Pre-render each route\n for (const route of options.routes) {\n const rendered = await render(route)\n const html = template.replace(placeholder, rendered)\n\n const routePath = route === '/' ? '' : route.replace(/^\\//, '')\n const outPath = resolve(options.outDir, routePath, 'index.html')\n mkdirSync(dirname(outPath), { recursive: true })\n writeFileSync(outPath, html)\n }\n\n // Clean up server build\n if (cleanup) {\n const serverDir = dirname(options.serverEntry)\n rmSync(serverDir, { recursive: true, force: true })\n }\n\n return { pages: options.routes.length }\n}\n","import { existsSync, readFileSync } from 'fs'\nimport { dirname, join } from 'path'\nimport { fileURLToPath } from 'url'\nimport type { Plugin } from 'vite'\n\n/**\n * Vite plugin that serves shared font assets during development.\n * In production, fonts are copied to the output directory by the build script.\n */\nexport function sharedAssetsPlugin(): Plugin {\n const pkgDir = join(dirname(fileURLToPath(import.meta.url)), '..', '..')\n const assetsDir = join(pkgDir, 'assets')\n\n return {\n name: 'pagesmith:shared-assets',\n configureServer(server) {\n server.middlewares.use((req, res, next) => {\n const url = req.url ?? ''\n\n // Serve fonts.css\n if (url === '/assets/fonts.css' || url.endsWith('/assets/fonts.css')) {\n const filePath = join(assetsDir, 'fonts.css')\n if (existsSync(filePath)) {\n res.writeHead(200, { 'Content-Type': 'text/css', 'Cache-Control': 'no-cache' })\n res.end(readFileSync(filePath, 'utf-8'))\n return\n }\n }\n\n // Serve font files\n if (url.includes('/assets/fonts/') && url.endsWith('.woff2')) {\n const fileName = url.split('/assets/fonts/').pop()\n if (fileName && !fileName.includes('..') && !fileName.includes('/')) {\n const filePath = join(assetsDir, 'fonts', fileName)\n if (existsSync(filePath)) {\n res.writeHead(200, {\n 'Content-Type': 'font/woff2',\n 'Cache-Control': 'public, max-age=31536000',\n })\n res.end(readFileSync(filePath))\n return\n }\n }\n }\n\n next()\n })\n },\n }\n}\n","/**\n * Route collection, pre-rendering, and content asset handling for the SSG plugin.\n *\n * Provides:\n * - Content companion asset discovery and copying\n * - HTML asset reference rewriting\n * - SSR bundle building via child process\n * - Route pre-rendering to static HTML files\n * - Font and public file copying\n */\n\nimport {\n copyFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from 'fs'\nimport { basename, dirname, extname, join, resolve } from 'path'\nimport { fileURLToPath, pathToFileURL } from 'url'\nimport type { ResolvedConfig } from 'vite'\nimport { collectContentAssets, CONTENT_ASSET_EXTS, copyPublicFiles } from '../assets'\nimport type { SsgRenderConfig } from './ssg-plugin'\n\nexport const MIME: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n '.avif': 'image/avif',\n '.ico': 'image/x-icon',\n '.woff2': 'font/woff2',\n '.woff': 'font/woff',\n '.ttf': 'font/ttf',\n '.txt': 'text/plain; charset=utf-8',\n '.xml': 'application/xml; charset=utf-8',\n}\n\n// ── Content directory helpers ──\n\nexport function resolveContentDirs(projectRoot: string, contentDirs: string[] = []): string[] {\n return contentDirs.map((dir) => resolve(projectRoot, dir))\n}\n\nfunction isAssetReference(ref: string): boolean {\n if (!ref.startsWith('./')) return false\n const path = ref.split(/[?#]/u, 1)[0] ?? ref\n return CONTENT_ASSET_EXTS.has(extname(path).toLowerCase())\n}\n\nexport function rewriteContentAssetRefs(html: string, base: string): string {\n const basePrefix = base.replace(/\\/+$/u, '')\n\n return html.replace(\n /(src|href|srcset)=(?:\"([^\"]+)\"|'([^']+)')/g,\n (match, attr: string, doubleRef: string | undefined, singleRef: string | undefined) => {\n const ref = doubleRef ?? singleRef ?? ''\n if (!isAssetReference(ref)) return match\n const pathname = ref.split(/[?#]/u, 1)[0] ?? ref\n const suffix = ref.slice(pathname.length)\n const quote = doubleRef !== undefined ? '\"' : \"'\"\n return `${attr}=${quote}${basePrefix}/assets/${pathname.split('/').pop() ?? pathname}${suffix}${quote}`\n },\n )\n}\n\nfunction copyContentAssetsToOutDir(outDir: string, assets: Map<string, string>): void {\n if (assets.size === 0) return\n\n const assetsDir = join(outDir, 'assets')\n mkdirSync(assetsDir, { recursive: true })\n\n for (const [fileName, sourcePath] of assets) {\n copyFileSync(sourcePath, join(assetsDir, fileName))\n }\n}\n\n// ── Build-time rendering ──\n\nexport type SsgBuildContext = {\n /** Vite resolved config */\n config: ResolvedConfig\n /** Absolute path to the project root */\n projectRoot: string\n /** Base path without trailing slash (e.g., '/my-site') */\n base: string\n /** Absolute path to the build output directory */\n outDir: string\n /** Resolved content directories (absolute paths) */\n contentDirs: string[]\n /** Path to the SSR entry module */\n entry: string\n}\n\n/**\n * Run the full SSG build: SSR bundle, route pre-rendering, asset copying.\n *\n * Returns the number of pages rendered.\n */\nexport async function renderStaticSite(context: SsgBuildContext): Promise<number> {\n const { config, projectRoot, base, outDir, contentDirs, entry } = context\n\n console.log('\\nSSG: Starting static site generation...')\n\n const contentAssets = collectContentAssets(contentDirs)\n\n // Copy font assets from @pagesmith/core\n copyFontAssets(outDir)\n\n // Copy public/ files (favicon etc.)\n const publicDir = join(projectRoot, 'public')\n copyPublicFiles(publicDir, outDir)\n\n // Discover built asset paths from the client build output\n const { cssPath, jsPath } = discoverBuiltAssets(outDir, base)\n\n // SSR build — use child process to avoid nested Vite resolution issues\n console.log('SSG: Building SSR bundle...')\n await buildSsrBundle(config, projectRoot, outDir, entry)\n\n // Load SSR module — derive output filename from the configured entry path\n const entryBaseName = basename(entry).replace(/\\.(c|m)?[jt]sx?$/u, '.js')\n const serverDir = join(outDir, '.server')\n const serverEntry = join(serverDir, entryBaseName)\n const ssrMod = await import(pathToFileURL(serverEntry).href)\n\n const renderConfig: SsgRenderConfig = {\n base,\n root: projectRoot,\n cssPath,\n jsPath,\n searchEnabled: true,\n isDev: false,\n }\n\n // Get routes and render with bounded concurrency\n const routes: string[] = await ssrMod.getRoutes(renderConfig)\n console.log(`SSG: Rendering ${routes.length} pages...`)\n\n const concurrency = Math.min(routes.length, 8)\n let routeIndex = 0\n\n async function renderWorker(): Promise<void> {\n while (routeIndex < routes.length) {\n const i = routeIndex++\n const route = routes[i]\n const html = rewriteContentAssetRefs(await ssrMod.render(route, renderConfig), base)\n const routePath = route === '/' ? '' : route.replace(/^\\//, '')\n const outputPath = join(outDir, routePath, 'index.html')\n mkdirSync(dirname(outputPath), { recursive: true })\n writeFileSync(outputPath, `<!DOCTYPE html>\\n${html}`)\n\n if (route === '/404') {\n writeFileSync(join(outDir, '404.html'), `<!DOCTYPE html>\\n${html}`)\n }\n }\n }\n\n const workers = Array.from({ length: concurrency }, () => renderWorker())\n await Promise.all(workers)\n\n copyContentAssetsToOutDir(outDir, contentAssets)\n\n // Cleanup SSR build\n rmSync(serverDir, { recursive: true, force: true })\n\n return routes.length\n}\n\nfunction copyFontAssets(outDir: string): void {\n const corePkgDir = dirname(fileURLToPath(import.meta.resolve('@pagesmith/core/package.json')))\n const coreFontsDir = join(corePkgDir, 'assets', 'fonts')\n const outFontsDir = join(outDir, 'assets', 'fonts')\n mkdirSync(outFontsDir, { recursive: true })\n for (const file of readdirSync(coreFontsDir)) {\n if (file.endsWith('.woff2')) {\n copyFileSync(join(coreFontsDir, file), join(outFontsDir, file))\n }\n }\n copyFileSync(join(corePkgDir, 'assets', 'fonts.css'), join(outDir, 'assets', 'fonts.css'))\n}\n\nfunction discoverBuiltAssets(\n outDir: string,\n base: string,\n): { cssPath: string; jsPath: string | undefined } {\n const builtIndex = join(outDir, 'index.html')\n let cssPath = `${base}/assets/style.css`\n let jsPath: string | undefined\n if (existsSync(builtIndex)) {\n const html = readFileSync(builtIndex, 'utf-8')\n const cssMatch = html.match(/href=\"([^\"]*\\.css)\"/)\n const jsMatch = html.match(/src=\"([^\"]*\\.js)\"/)\n if (cssMatch) cssPath = cssMatch[1]\n if (jsMatch) jsPath = jsMatch[1]\n }\n return { cssPath, jsPath }\n}\n\nasync function buildSsrBundle(\n config: ResolvedConfig,\n projectRoot: string,\n outDir: string,\n entry: string,\n): Promise<void> {\n const { execFileSync } = await import('child_process')\n const serverDir = join(outDir, '.server')\n const ssrEntry = resolve(projectRoot, entry)\n // Write a temp build script that externalizes node_modules and skips the SSG plugin\n const buildScript = `\n import { build } from 'vite';\n await build({\n root: ${JSON.stringify(projectRoot)},\n logLevel: 'warn',\n mode: ${JSON.stringify(config.mode)},\n build: {\n ssr: ${JSON.stringify(ssrEntry)},\n outDir: ${JSON.stringify(serverDir)},\n emptyOutDir: true,\n },\n });\n `\n execFileSync(process.execPath, ['--input-type=module', '-e', buildScript], {\n stdio: 'inherit',\n cwd: projectRoot,\n })\n}\n","/**\n * Dev-server middleware for the SSG plugin.\n *\n * Handles on-the-fly SSR rendering during development, including:\n * - Content companion asset serving from content directories\n * - HTML navigation request handling via server-side rendering\n * - Vite HMR client injection for live reload\n */\n\nimport { extname, resolve } from 'path'\nimport { readFileSync } from 'fs'\nimport type { ViteDevServer } from 'vite'\nimport type { SsgRenderConfig } from './ssg-plugin'\nimport { collectContentAssets } from '../assets'\nimport { MIME, rewriteContentAssetRefs } from './ssg-render'\n\nexport type SsgDevContext = {\n /** Absolute path to the project root */\n projectRoot: string\n /** Base path without trailing slash (e.g., '/my-site') */\n base: string\n /** Resolved content directories (absolute paths) */\n contentDirs: string[]\n /** Path to the SSR entry module */\n entry: string\n}\n\n/**\n * Configure the Vite dev server with SSR middleware for on-the-fly rendering.\n *\n * Sets up:\n * - File watcher for content companion assets\n * - Middleware for serving companion assets from `/assets/` paths\n * - Middleware for SSR-rendering HTML navigation requests\n */\nexport function configureSsgDevServer(server: ViteDevServer, context: SsgDevContext): void {\n const { projectRoot, base, contentDirs, entry } = context\n let contentAssets = new Map<string, string>()\n\n async function refreshContentArtifacts(): Promise<void> {\n contentAssets = collectContentAssets(contentDirs)\n }\n\n void refreshContentArtifacts().catch((error) => {\n console.warn(\n `pagesmith:ssg failed to prepare companion assets: ${error instanceof Error ? error.message : String(error)}`,\n )\n })\n\n if (contentDirs.length > 0) {\n server.watcher.add(contentDirs)\n\n const refresh = () => {\n void refreshContentArtifacts().catch((error) => {\n console.warn(\n `pagesmith:ssg failed to refresh companion assets: ${error instanceof Error ? error.message : String(error)}`,\n )\n })\n }\n\n server.watcher.on('add', refresh)\n server.watcher.on('change', refresh)\n server.watcher.on('unlink', refresh)\n }\n\n // Register middleware directly — appType: 'custom' disables Vite's\n // built-in HTML serving, so we handle all HTML requests via SSR.\n server.middlewares.use(async (req, res, next) => {\n const url = req.url ?? '/'\n const pathname = url.split(/[?#]/u, 1)[0] ?? url\n\n if (pathname.includes('/assets/')) {\n const assetName = pathname.split('/assets/').pop()\n const assetPath = assetName ? contentAssets.get(assetName) : undefined\n\n if (assetPath) {\n const ext = extname(assetPath).toLowerCase()\n res.writeHead(200, {\n 'Content-Type': MIME[ext] ?? 'application/octet-stream',\n 'Cache-Control': 'no-cache',\n })\n res.end(readFileSync(assetPath))\n return\n }\n }\n\n // Only handle HTML navigation requests (not assets, not files with extensions)\n const accept = req.headers.accept ?? ''\n const pathExt = extname(pathname)\n if (pathExt && pathExt !== '.html') return next()\n if (!pathExt && !accept.includes('text/html')) return next()\n\n // Redirect root to base\n if (base && (url === '/' || url === '')) {\n res.writeHead(302, { Location: `${base}/` })\n res.end()\n return\n }\n\n // Must start with base path\n if (base && !url.startsWith(base)) return next()\n\n try {\n // Load SSR module on-the-fly (Vite transforms TSX etc.)\n const ssrMod = await server.ssrLoadModule(resolve(projectRoot, entry))\n const renderFn: (url: string, cfg: SsgRenderConfig) => Promise<string> | string =\n ssrMod.render\n\n if (typeof renderFn !== 'function') {\n return next()\n }\n\n const renderConfig: SsgRenderConfig = {\n base,\n root: projectRoot,\n cssPath: `${base}/src/theme.css`, // Vite transforms this in dev\n jsPath: undefined,\n searchEnabled: false,\n isDev: true,\n }\n\n let html = await renderFn(url, renderConfig)\n html = rewriteContentAssetRefs(html, base)\n\n // Inject Vite's client + HMR script for live reload\n html = html.replace(\n '</head>',\n `<script type=\"module\" src=\"/@vite/client\"></script>\\n` +\n `<link rel=\"stylesheet\" href=\"${base}/src/theme.css\">\\n` +\n `</head>`,\n )\n\n // Let Vite transform the HTML (resolves module URLs, etc.)\n html = await server.transformIndexHtml(url, html)\n\n const status = html.includes('doc-not-found') ? 404 : 200\n res.writeHead(status, { 'Content-Type': 'text/html; charset=utf-8' })\n res.end(html)\n } catch (err: unknown) {\n if (err instanceof Error) {\n server.ssrFixStacktrace(err)\n }\n console.error(`SSR error for ${url}:`, err instanceof Error ? err.message : String(err))\n next(err)\n }\n })\n}\n","/**\n * Pagefind search indexing for the SSG plugin.\n *\n * Runs the Pagefind CLI to index the generated static site output,\n * producing the search index used by the docs theme.\n */\n\nimport { dirname, join } from 'path'\nimport { fileURLToPath } from 'url'\n\n/**\n * Run Pagefind indexing on the built site output directory.\n *\n * Resolves the Pagefind binary from the installed package and invokes it\n * via a child process. Logs a warning and continues if Pagefind is not\n * installed.\n */\nexport async function runPagefindIndexing(outDir: string): Promise<void> {\n console.log('SSG: Indexing with Pagefind...')\n try {\n const pagefindMain = fileURLToPath(import.meta.resolve('pagefind'))\n const pagefindBin = join(dirname(pagefindMain), '..', 'lib', 'runner', 'bin.cjs')\n const { execFileSync } = await import('child_process')\n execFileSync(process.execPath, [pagefindBin, '--site', outDir], { stdio: 'inherit' })\n } catch {\n console.warn('SSG: Pagefind not found, skipping search indexing')\n }\n}\n","/**\n * Vite plugin for static site generation with @pagesmith/core.\n *\n * Handles both development (on-the-fly SSR via middleware) and\n * production (post-build SSG + pagefind indexing).\n *\n * The SSR entry module must export:\n * - `getRoutes(config)` — returns route paths to pre-render\n * - `render(url, config)` — renders a route to an HTML string\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { pagesmithSsg } from '@pagesmith/core/vite'\n *\n * export default defineConfig({\n * base: '/my-site/',\n * plugins: [pagesmithSsg({ entry: './src/entry-server.tsx' })],\n * })\n * ```\n */\n\nimport { resolve } from 'path'\nimport type { Plugin, ResolvedConfig } from 'vite'\nimport { configureSsgDevServer } from './ssg-hmr'\nimport { resolveContentDirs, renderStaticSite } from './ssg-render'\nimport { runPagefindIndexing } from './ssg-pagefind'\n\nexport type SsgPluginOptions = {\n /** Path to the SSR entry module (e.g., './src/entry-server.tsx') */\n entry: string\n /** Run pagefind after build (default: true) */\n pagefind?: boolean\n /** Content roots used for copying companion assets. */\n contentDirs?: string[]\n}\n\nexport type SsgRenderConfig = {\n /** Base path without trailing slash (e.g., '/my-site') */\n base: string\n /** Absolute path to the project root */\n root: string\n /** Path to the built CSS asset */\n cssPath: string\n /** Path to the built JS asset (undefined in dev for inline-script examples) */\n jsPath?: string\n /** Whether search is enabled (false in dev) */\n searchEnabled: boolean\n /** Whether running in dev mode */\n isDev: boolean\n}\n\nexport function pagesmithSsg(options: SsgPluginOptions): Plugin[] {\n const enablePagefind = options.pagefind !== false\n let config: ResolvedConfig\n let projectRoot: string\n let base: string // e.g., '/my-site'\n let outDir: string\n let contentDirs: string[] = []\n\n // ── Dev plugin: SSR middleware ──\n const devPlugin: Plugin = {\n name: 'pagesmith:ssg-dev',\n apply: 'serve',\n\n config() {\n // Disable Vite's built-in SPA HTML serving so the SSG middleware\n // can handle all HTML requests via server-side rendering.\n return { appType: 'custom' }\n },\n\n configResolved(resolved) {\n config = resolved\n projectRoot = resolved.root\n base = resolved.base.replace(/\\/+$/, '')\n outDir = resolve(projectRoot, resolved.build.outDir)\n contentDirs = resolveContentDirs(projectRoot, options.contentDirs)\n },\n\n configureServer(server) {\n configureSsgDevServer(server, {\n projectRoot,\n base,\n contentDirs,\n entry: options.entry,\n })\n },\n }\n\n // ── Build plugin: SSG post-build ──\n const buildPlugin: Plugin = {\n name: 'pagesmith:ssg-build',\n apply: 'build',\n\n configResolved(resolved) {\n config = resolved\n projectRoot = resolved.root\n base = resolved.base.replace(/\\/+$/, '')\n outDir = resolve(projectRoot, resolved.build.outDir)\n contentDirs = resolveContentDirs(projectRoot, options.contentDirs)\n },\n\n async closeBundle() {\n // Skip SSG during the SSR build itself (detected by ssr option)\n if (config.build.ssr) return\n\n const pageCount = await renderStaticSite({\n config,\n projectRoot,\n base,\n outDir,\n contentDirs,\n entry: options.entry,\n })\n\n if (enablePagefind) {\n await runPagefindIndexing(outDir)\n }\n\n console.log(`SSG: Done — ${pageCount} pages generated`)\n },\n }\n\n return [devPlugin, buildPlugin]\n}\n","import { existsSync } from 'fs'\nimport { dirname, relative, resolve } from 'path'\nimport type { PagesmithContentPluginOptions } from './content-plugin'\n\nfunction stripExtension(filePath: string): string {\n return filePath.replace(/\\.(c|m)?[jt]sx?$/u, '')\n}\n\nfunction normalizePath(value: string): string {\n return value.replace(/\\\\/g, '/')\n}\n\nexport function resolveDtsPath(\n projectRoot: string,\n dts: PagesmithContentPluginOptions<any>['dts'],\n): string {\n if (dts === false) {\n return ''\n }\n\n if (typeof dts === 'string') {\n return resolve(projectRoot, dts)\n }\n\n if (typeof dts === 'object' && dts?.path) {\n return resolve(projectRoot, dts.path)\n }\n\n const srcPath = resolve(projectRoot, 'src')\n if (existsSync(srcPath)) {\n return resolve(srcPath, 'pagesmith-content.d.ts')\n }\n\n return resolve(projectRoot, 'pagesmith-content.d.ts')\n}\n\nexport function createDtsSource(\n moduleId: string,\n collectionNames: string[],\n dtsPath: string,\n configPath: string,\n): string {\n const configImportPath = normalizePath(\n stripExtension(relative(dirname(dtsPath), configPath)).replace(/^[^.]/u, './$&'),\n )\n\n const moduleLines = collectionNames\n .map(\n (name) => `declare module '${moduleId}/${name}' {\n const collection: import('@pagesmith/core/vite').ContentCollectionModule<\n __PagesmithCollections['${name.replaceAll('\\\\', '\\\\\\\\').replaceAll(\"'\", \"\\\\'\")}']\n >\n export default collection\n}`,\n )\n .join('\\n\\n')\n\n return `// Generated by @pagesmith/core/vite. Do not edit manually.\ntype __PagesmithCollections = typeof import('${configImportPath}').default\n\ndeclare module '${moduleId}' {\n const content: import('@pagesmith/core/vite').ContentModuleMap<__PagesmithCollections>\n export default content\n}\n\n${moduleLines}\n`\n}\n","import { mkdirSync, writeFileSync } from 'fs'\nimport { dirname, relative, resolve } from 'path'\nimport { uneval } from 'devalue'\nimport { createContentLayer } from '../content-layer'\nimport { resolveLoader } from '../loaders'\nimport type { Heading } from '../schemas/heading'\nimport type { CollectionDef, CollectionMap, InferCollectionData } from '../schemas/collection'\nimport type { ContentLayerConfig } from '../schemas/content-config'\nimport { toSlug } from '../utils/slug'\nimport { createDtsSource, resolveDtsPath } from './dts'\n\ntype Simplify<T> = { [K in keyof T]: T[K] } & {}\n\ntype PagesmithResolvedConfig = {\n root: string\n}\n\ntype PagesmithModuleGraph = {\n getModuleById(id: string): unknown\n invalidateModule(module: unknown): void\n}\n\ntype PagesmithDevServer = {\n moduleGraph: PagesmithModuleGraph\n ws: {\n send(payload: { type: string }): void\n }\n}\n\nexport type PagesmithVitePlugin = {\n name: string\n enforce?: 'pre' | 'post'\n configResolved?: (config: PagesmithResolvedConfig) => void\n buildStart?: () => void\n resolveId?: (id: string) => string | void\n load?: (id: string) => Promise<string | void> | string | void\n handleHotUpdate?: (context: { file: string; server: PagesmithDevServer }) => void\n}\n\nexport type BaseContentModuleEntry = {\n id: string\n contentSlug: string\n}\n\nexport type MarkdownContentModuleEntry<TCollection extends CollectionDef<any, any, any>> = Simplify<\n BaseContentModuleEntry & {\n html: string\n headings: Heading[]\n frontmatter: InferCollectionData<TCollection>\n }\n>\n\nexport type DataContentModuleEntry<TCollection extends CollectionDef<any, any, any>> = Simplify<\n BaseContentModuleEntry & {\n data: InferCollectionData<TCollection>\n }\n>\n\ntype LoaderKindFromCollection<TCollection extends CollectionDef<any, any, any>> =\n TCollection['loader'] extends 'markdown'\n ? 'markdown'\n : TCollection['loader'] extends { kind: infer TKind }\n ? TKind\n : 'data'\n\nexport type ContentCollectionModule<TCollection extends CollectionDef<any, any, any>> =\n LoaderKindFromCollection<TCollection> extends 'markdown'\n ? MarkdownContentModuleEntry<TCollection>[]\n : DataContentModuleEntry<TCollection>[]\n\nexport type ContentModuleMap<TCollections extends CollectionMap> = {\n [TName in keyof TCollections]: ContentCollectionModule<TCollections[TName]>\n}\n\nexport type PagesmithContentPluginOptions<TCollections extends CollectionMap> = Omit<\n ContentLayerConfig,\n 'collections'\n> & {\n collections: TCollections\n /**\n * Shared content root used to compute `id` and `contentSlug`.\n * Defaults to the deepest common parent directory across all collection directories.\n */\n contentRoot?: string\n /**\n * Root virtual module id.\n * Per-collection modules are exposed as `${moduleId}/<collection-name>`.\n */\n moduleId?: string\n /**\n * Path to the content config module used for generated typings.\n * Defaults to `./content.config.ts`.\n */\n configPath?: string\n /**\n * Generate module declarations for the virtual modules.\n * Defaults to `src/pagesmith-content.d.ts` when `src/` exists, otherwise `pagesmith-content.d.ts`.\n */\n dts?: boolean | string | { path?: string }\n}\n\nconst DEFAULT_MODULE_ID = 'virtual:content'\n\nfunction normalizePath(value: string): string {\n return value.replace(/\\\\/g, '/')\n}\n\nfunction isPathWithin(parent: string, candidate: string): boolean {\n const rel = normalizePath(relative(parent, candidate))\n return rel === '' || (!rel.startsWith('..') && !rel.startsWith('/'))\n}\n\nfunction commonDirectory(paths: string[]): string {\n const normalized = paths.map((path) => normalizePath(resolve(path)))\n if (normalized.length === 0) return process.cwd()\n if (normalized.length === 1) return normalized[0]\n\n const segments = normalized.map((path) => path.split('/').filter(Boolean))\n const shared: string[] = []\n const first = segments[0]!\n\n for (let index = 0; index < first.length; index += 1) {\n const segment = first[index]\n if (segments.every((parts) => parts[index] === segment)) {\n shared.push(segment)\n continue\n }\n break\n }\n\n if (shared.length === 0) {\n return resolve('/')\n }\n\n return resolve(`/${shared.join('/')}`)\n}\n\nasync function serializeCollection(\n layer: ReturnType<typeof createContentLayer>,\n collectionName: string,\n collectionDef: CollectionDef<any, any, any>,\n contentRoot: string,\n): Promise<string> {\n const entries = await layer.getCollection(collectionName)\n const loader = resolveLoader(collectionDef.loader)\n const sortedEntries = [...entries].sort((left, right) =>\n left.filePath.localeCompare(right.filePath),\n )\n\n const payload = await Promise.all(\n sortedEntries.map(async (entry) => {\n const contentSlug = toSlug(entry.filePath, contentRoot)\n const base = {\n id: contentSlug,\n contentSlug,\n }\n\n if (loader.kind === 'markdown') {\n const rendered = await entry.render()\n return {\n ...base,\n html: rendered.html,\n headings: rendered.headings,\n frontmatter: entry.data,\n }\n }\n\n return {\n ...base,\n data: entry.data,\n }\n }),\n )\n\n return `const collection = ${uneval(payload)};\\nexport default collection;\\n`\n}\n\nfunction createRootModuleSource(moduleId: string, collectionNames: string[]): string {\n const imports = collectionNames\n .map((name, index) => `import collection${index} from '${moduleId}/${name}'`)\n .join('\\n')\n const contentMap = collectionNames\n .map((name, index) => `${JSON.stringify(name)}: collection${index}`)\n .join(', ')\n\n return `${imports}\\n\\nexport default { ${contentMap} };\\n`\n}\n\nfunction resolvePluginOptions<TCollections extends CollectionMap>(\n collectionsOrOptions: TCollections | PagesmithContentPluginOptions<TCollections>,\n maybeOptions: Omit<PagesmithContentPluginOptions<TCollections>, 'collections'> = {},\n): PagesmithContentPluginOptions<TCollections> {\n if ('collections' in collectionsOrOptions) {\n return collectionsOrOptions as PagesmithContentPluginOptions<TCollections>\n }\n\n return {\n ...maybeOptions,\n collections: collectionsOrOptions,\n }\n}\n\nexport function pagesmithContent<TCollections extends CollectionMap>(\n collections: TCollections,\n options?: Omit<PagesmithContentPluginOptions<TCollections>, 'collections'>,\n): PagesmithVitePlugin\nexport function pagesmithContent<TCollections extends CollectionMap>(\n options: PagesmithContentPluginOptions<TCollections>,\n): PagesmithVitePlugin\nexport function pagesmithContent<TCollections extends CollectionMap>(\n collectionsOrOptions: TCollections | PagesmithContentPluginOptions<TCollections>,\n maybeOptions: Omit<PagesmithContentPluginOptions<TCollections>, 'collections'> = {},\n): PagesmithVitePlugin {\n const options = resolvePluginOptions(collectionsOrOptions, maybeOptions)\n const collectionNames = Object.keys(options.collections)\n const moduleId = options.moduleId ?? DEFAULT_MODULE_ID\n const resolvedPrefix = `\\0${moduleId}/`\n const resolvedRootId = `\\0${moduleId}`\n\n let projectRoot = process.cwd()\n let layerRoot = projectRoot\n let contentRoot = projectRoot\n let configPath = resolve(projectRoot, options.configPath ?? 'content.config.ts')\n let dtsPath = resolveDtsPath(projectRoot, options.dts)\n let layer: ReturnType<typeof createContentLayer> | null = null\n\n function getLayer(): ReturnType<typeof createContentLayer> {\n if (!layer) {\n throw new Error(\n 'pagesmith-content: ContentLayer not initialized. configResolved has not run yet.',\n )\n }\n return layer\n }\n\n const ensureDeclarations = (): void => {\n if (options.dts === false) return\n\n const source = createDtsSource(moduleId, collectionNames, dtsPath, configPath)\n mkdirSync(dirname(dtsPath), { recursive: true })\n writeFileSync(dtsPath, source)\n }\n\n return {\n name: 'pagesmith-content',\n enforce: 'pre',\n\n configResolved(config) {\n projectRoot = resolve(config.root)\n layerRoot = resolve(projectRoot, options.root ?? '.')\n configPath = resolve(projectRoot, options.configPath ?? 'content.config.ts')\n dtsPath = resolveDtsPath(projectRoot, options.dts)\n\n const collectionDirectories = collectionNames.map((name) =>\n resolve(layerRoot, options.collections[name]!.directory),\n )\n contentRoot = options.contentRoot\n ? resolve(layerRoot, options.contentRoot)\n : commonDirectory(collectionDirectories)\n\n layer = createContentLayer({\n ...options,\n root: layerRoot,\n })\n\n ensureDeclarations()\n },\n\n buildStart() {\n ensureDeclarations()\n },\n\n resolveId(id) {\n if (id === moduleId) {\n return resolvedRootId\n }\n\n for (const name of collectionNames) {\n if (id === `${moduleId}/${name}`) {\n return `${resolvedPrefix}${name}`\n }\n }\n },\n\n async load(id) {\n if (id === resolvedRootId) {\n return createRootModuleSource(moduleId, collectionNames)\n }\n\n if (!id.startsWith(resolvedPrefix)) return\n\n const collectionName = id.slice(resolvedPrefix.length)\n const collectionDef = options.collections[collectionName]\n if (!collectionDef) return\n\n return serializeCollection(getLayer(), collectionName, collectionDef, contentRoot)\n },\n\n handleHotUpdate({ file, server }) {\n const resolvedFile = resolve(file)\n const touchesConfig = resolvedFile === configPath\n\n const affectedCollections = collectionNames.filter((name) =>\n isPathWithin(resolve(layerRoot, options.collections[name]!.directory), resolvedFile),\n )\n\n const touchesContent = affectedCollections.length > 0\n\n if (!touchesConfig && !touchesContent) return\n\n if (touchesConfig) {\n ensureDeclarations()\n }\n\n const rootModule = server.moduleGraph.getModuleById(resolvedRootId)\n if (rootModule) {\n server.moduleGraph.invalidateModule(rootModule)\n }\n\n if (touchesContent) {\n for (const name of affectedCollections) {\n const moduleNode = server.moduleGraph.getModuleById(`${resolvedPrefix}${name}`)\n if (moduleNode) {\n server.moduleGraph.invalidateModule(moduleNode)\n }\n getLayer()\n .invalidateCollection(name)\n .catch((err) => {\n console.warn(`[pagesmith] Failed to invalidate collection \"${name}\":`, err)\n })\n }\n } else {\n for (const name of collectionNames) {\n const moduleNode = server.moduleGraph.getModuleById(`${resolvedPrefix}${name}`)\n if (moduleNode) {\n server.moduleGraph.invalidateModule(moduleNode)\n }\n }\n getLayer().invalidateAll()\n }\n\n server.ws.send({ type: 'full-reload' })\n },\n }\n}\n"],"mappings":"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"}
|
|
@@ -2,8 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
## @pagesmith/core
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Install: `npm add @pagesmith/core`
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
Use the installed package guidance — these files are version-matched to what you have installed:
|
|
8
|
+
|
|
9
|
+
### Primary references
|
|
10
|
+
|
|
11
|
+
- `node_modules/@pagesmith/core/REFERENCE.md` — complete API reference: content layer, collections, loaders, markdown, JSX, CSS, Vite plugins
|
|
12
|
+
- `node_modules/@pagesmith/core/docs/agents/usage.md` — agent rules, integration shape, and copy-paste prompts for common workflows
|
|
13
|
+
- `node_modules/@pagesmith/core/docs/agents/errors.md` — error catalog with patterns and fixes
|
|
14
|
+
|
|
15
|
+
### Task-specific files
|
|
16
|
+
|
|
17
|
+
| Task | Read |
|
|
18
|
+
|---|---|
|
|
19
|
+
| Initial Vite setup | `node_modules/@pagesmith/core/REFERENCE.md`, `node_modules/@pagesmith/core/docs/agents/recipes.md` |
|
|
20
|
+
| Defining collections and schemas | `node_modules/@pagesmith/core/REFERENCE.md` |
|
|
21
|
+
| Writing markdown content (code blocks, mermaid, frontmatter) | `node_modules/@pagesmith/core/REFERENCE.md` |
|
|
22
|
+
| Customizing the markdown pipeline | `node_modules/@pagesmith/core/REFERENCE.md`, `node_modules/@pagesmith/core/docs/agents/recipes.md` |
|
|
23
|
+
| Troubleshooting validation errors | `node_modules/@pagesmith/core/docs/agents/errors.md` |
|
|
24
|
+
| Migration and upgrades | `node_modules/@pagesmith/core/docs/agents/migration.md`, `node_modules/@pagesmith/core/docs/agents/changelog-notes.md` |
|
|
25
|
+
|
|
26
|
+
### Docs package (if also using @pagesmith/docs)
|
|
27
|
+
|
|
28
|
+
- `node_modules/@pagesmith/docs/REFERENCE.md`
|
|
29
|
+
- `node_modules/@pagesmith/docs/docs/agents/usage.md`
|
|
@@ -12,4 +12,4 @@
|
|
|
12
12
|
- Added `docs/agents/migration.md` with pre-1.0 upgrade guidance
|
|
13
13
|
- AI installer split into focused modules for maintainability
|
|
14
14
|
- AI exports removed from main barrel — use `@pagesmith/core/ai` subpath or CLI `npx pagesmith init --ai`
|
|
15
|
-
- Scripts converted from JavaScript to TypeScript (using `node --strip-types`)
|
|
15
|
+
- Scripts converted from JavaScript to TypeScript (using `node --strip-types`)
|
package/docs/agents/errors.md
CHANGED
|
@@ -5,9 +5,11 @@ Machine-readable error solutions for AI agents. Each section maps a common error
|
|
|
5
5
|
## Schema Validation Errors
|
|
6
6
|
|
|
7
7
|
### Required field missing
|
|
8
|
+
|
|
8
9
|
**Pattern:** `Required at "<field>"`
|
|
9
10
|
**Fix:** Add the missing field to your frontmatter. Check the collection schema for required fields.
|
|
10
11
|
**Example:**
|
|
12
|
+
|
|
11
13
|
```yaml
|
|
12
14
|
---
|
|
13
15
|
title: My Page # ← required by BaseFrontmatterSchema
|
|
@@ -16,17 +18,21 @@ description: A summary # ← required by BaseFrontmatterSchema
|
|
|
16
18
|
```
|
|
17
19
|
|
|
18
20
|
### Invalid date format
|
|
21
|
+
|
|
19
22
|
**Pattern:** `Expected date, received string` or `Invalid date`
|
|
20
23
|
**Fix:** Use ISO 8601 format: `YYYY-MM-DD` or `YYYY-MM-DDTHH:mm:ss`.
|
|
21
24
|
**Example:** `publishedDate: 2024-01-15`
|
|
22
25
|
|
|
23
26
|
### Unknown field
|
|
27
|
+
|
|
24
28
|
**Pattern:** `Unrecognized key(s) in object: "<field>"`
|
|
25
29
|
**Fix:** The schema uses `.strict()`. Remove the unrecognized field or update the schema to include it.
|
|
26
30
|
|
|
27
31
|
### Type mismatch
|
|
32
|
+
|
|
28
33
|
**Pattern:** `Expected <type>, received <type>`
|
|
29
34
|
**Fix:** Ensure the frontmatter value matches the schema type. Common mismatches:
|
|
35
|
+
|
|
30
36
|
- `tags` must be an array: `tags: [a, b]` not `tags: a, b`
|
|
31
37
|
- `draft` must be boolean: `draft: true` not `draft: "true"`
|
|
32
38
|
- `order` must be number: `order: 1` not `order: "1"`
|
|
@@ -34,63 +40,111 @@ description: A summary # ← required by BaseFrontmatterSchema
|
|
|
34
40
|
## Content Validation Errors
|
|
35
41
|
|
|
36
42
|
### Missing heading
|
|
37
|
-
|
|
43
|
+
|
|
44
|
+
**Pattern:** `Document has content but no headings`
|
|
38
45
|
**Fix:** Add a top-level `# Heading` to your markdown content, or set `title` in frontmatter (some setups auto-generate h1 from title).
|
|
39
46
|
|
|
40
47
|
### Heading level skip
|
|
41
|
-
|
|
48
|
+
|
|
49
|
+
**Pattern:** `Heading level skip: h<n> -> h<m> ("<text>")`
|
|
42
50
|
**Fix:** Don't skip heading levels. After `## Section`, use `### Subsection`, not `#### Deep`.
|
|
43
51
|
|
|
44
52
|
### Bare URL
|
|
53
|
+
|
|
45
54
|
**Pattern:** `Bare URL found`
|
|
46
55
|
**Fix:** Wrap URLs in markdown links: `[Link text](https://example.com)` instead of bare `https://example.com`.
|
|
47
56
|
|
|
48
57
|
### Missing code language
|
|
49
|
-
|
|
50
|
-
**
|
|
58
|
+
|
|
59
|
+
**Pattern:** `Code block has meta properties but no language identifier`
|
|
60
|
+
**Fix:** Add a language identifier to code blocks that use meta properties like `title`, `mark`, etc.
|
|
61
|
+
|
|
62
|
+
### Unknown meta property
|
|
63
|
+
|
|
64
|
+
**Pattern:** `Unknown code block meta property: "<prop>"`
|
|
65
|
+
**Fix:** Use only supported Expressive Code meta properties: `title`, `showLineNumbers`, `startLineNumber`, `wrap`, `frame`, `collapse`, `mark`, `ins`, `del`.
|
|
51
66
|
|
|
52
67
|
### Unknown code language
|
|
68
|
+
|
|
53
69
|
**Pattern:** `Unknown language "<lang>"`
|
|
54
70
|
**Fix:** Use a supported language identifier. Common mappings: `ts` for TypeScript, `js` for JavaScript, `sh`/`bash` for Shell. See Expressive Code language list.
|
|
55
71
|
|
|
56
72
|
## Plugin Validation Errors
|
|
57
73
|
|
|
58
74
|
### Plugin threw
|
|
59
|
-
|
|
75
|
+
|
|
76
|
+
**Pattern:** `[<name>] Validator threw: <message>`
|
|
60
77
|
**Fix:** A custom or plugin validator encountered an unexpected error. Check the plugin's documentation for the specific error message. The validator name identifies which plugin failed.
|
|
61
78
|
|
|
62
79
|
## Load Errors
|
|
63
80
|
|
|
64
81
|
### File not found
|
|
82
|
+
|
|
65
83
|
**Pattern:** `Failed to load <path>: ENOENT`
|
|
66
84
|
**Fix:** The file was deleted or moved. Update your content directory or remove the reference.
|
|
67
85
|
|
|
68
86
|
### Invalid YAML frontmatter
|
|
87
|
+
|
|
69
88
|
**Pattern:** `Failed to load <path>: YAMLException`
|
|
70
89
|
**Fix:** Check frontmatter YAML syntax. Common issues:
|
|
90
|
+
|
|
71
91
|
- Missing `---` delimiters
|
|
72
92
|
- Unquoted special characters (`:`, `#`, `[`, `{`)
|
|
73
93
|
- Incorrect indentation
|
|
74
94
|
|
|
75
95
|
### Invalid JSON
|
|
96
|
+
|
|
76
97
|
**Pattern:** `Failed to load <path>: JSON` or `Unexpected token`
|
|
77
98
|
**Fix:** Validate your JSON/JSON5 file syntax. Use a JSON linter.
|
|
78
99
|
|
|
79
100
|
## MCP Server Errors
|
|
80
101
|
|
|
81
102
|
### Config not found
|
|
82
|
-
|
|
103
|
+
|
|
104
|
+
**Pattern:** `No pagesmith.config.json5 file found at <path>`
|
|
83
105
|
**Fix:** Run `npx pagesmith init` to create a config file, or pass `--config <path>` to specify the location.
|
|
84
106
|
|
|
85
107
|
### Entry not found
|
|
108
|
+
|
|
86
109
|
**Pattern:** `Entry not found: <collection>/<slug>`
|
|
87
110
|
**Fix:** Verify the collection name and slug. Use `core_list_entries` to see available entries.
|
|
88
111
|
|
|
112
|
+
## Content Layer Errors
|
|
113
|
+
|
|
114
|
+
### Collection not found
|
|
115
|
+
|
|
116
|
+
**Pattern:** `Collection "<name>" not found. Available: <list>`
|
|
117
|
+
**Fix:** Check the collection name passed to `getCollection()` or `getEntry()`. The error lists all configured collection names — use one of those.
|
|
118
|
+
|
|
119
|
+
### Markdown processing failed
|
|
120
|
+
|
|
121
|
+
**Pattern:** `Markdown processing failed: <message>`
|
|
122
|
+
**Fix:** The unified markdown pipeline threw an error. Common causes:
|
|
123
|
+
|
|
124
|
+
- Invalid remark/rehype plugin configuration
|
|
125
|
+
- Malformed markdown that breaks a parser plugin
|
|
126
|
+
- Shiki theme or language loading failure
|
|
127
|
+
|
|
128
|
+
Check the inner error message for details. If caused by a custom plugin, verify the plugin implementation.
|
|
129
|
+
|
|
130
|
+
### Unknown loader type
|
|
131
|
+
|
|
132
|
+
**Pattern:** `Unknown loader type: <type>`
|
|
133
|
+
**Fix:** The `loader` field in your collection definition uses an unrecognized type string. Supported built-in types: `markdown`, `json`, `json5`, `jsonc`, `yaml`, `toml`. For custom loaders, pass a `Loader` object instead of a string.
|
|
134
|
+
|
|
135
|
+
## Vite Plugin Errors
|
|
136
|
+
|
|
137
|
+
### ContentLayer not initialized
|
|
138
|
+
|
|
139
|
+
**Pattern:** `pagesmith-content: ContentLayer not initialized. configResolved has not run yet.`
|
|
140
|
+
**Fix:** The `pagesmithContent` Vite plugin tried to load content before Vite called `configResolved`. This usually means the plugin was misconfigured or a module tried to import content at config time. Ensure the plugin is registered in `vite.config.ts` and content is only imported from application code (not config files).
|
|
141
|
+
|
|
89
142
|
## Quick Diagnostic Workflow
|
|
90
143
|
|
|
91
144
|
When encountering an error:
|
|
92
145
|
|
|
93
|
-
1. **Identify the source** —
|
|
146
|
+
1. **Identify the source** — each `ValidationIssue` has a `source` field indicating where it originated: `schema` (Zod safeParse), `content` (MDAST-based validators), `plugin` (plugin validators), or `custom` (collection `validate` function)
|
|
94
147
|
2. **Match the pattern** — find the error pattern above
|
|
95
148
|
3. **Apply the fix** — follow the specific fix instructions
|
|
96
149
|
4. **Re-validate** — use `core_validate` MCP tool or rebuild to confirm the fix
|
|
150
|
+
|
package/docs/agents/migration.md
CHANGED
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
## Upgrade checklist
|
|
6
6
|
|
|
7
7
|
1. Prefer subpath imports from the package export map:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
- `@pagesmith/core/vite`
|
|
9
|
+
- `@pagesmith/core/mcp`
|
|
10
|
+
- `@pagesmith/core/ssg-utils`
|
|
11
11
|
2. Keep Vite integration scripts aligned with current examples (`vite dev`, `vite build`) in downstream projects.
|
|
12
12
|
3. Re-run validation and tests after upgrade:
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
- `vp check`
|
|
14
|
+
- `vp test`
|
|
15
15
|
|
|
16
16
|
## Behavior updates to note
|
|
17
17
|
|
|
@@ -21,5 +21,5 @@
|
|
|
21
21
|
|
|
22
22
|
## Related docs
|
|
23
23
|
|
|
24
|
-
- `docs/agents/changelog-notes.md`
|
|
25
|
-
- `REFERENCE.md`
|
|
24
|
+
- `node_modules/@pagesmith/core/docs/agents/changelog-notes.md`
|
|
25
|
+
- `node_modules/@pagesmith/core/REFERENCE.md`
|
package/docs/agents/recipes.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @pagesmith/core Agent Recipes
|
|
2
2
|
|
|
3
|
+
Short procedural recipes for common content layer workflows. For the full reference, see `node_modules/@pagesmith/core/REFERENCE.md`.
|
|
4
|
+
|
|
3
5
|
## Create a collection
|
|
4
6
|
|
|
5
7
|
1. Add a directory under `content/`.
|
|
@@ -7,20 +9,42 @@
|
|
|
7
9
|
3. Register with `defineCollection`.
|
|
8
10
|
4. Expose via `defineCollections` or `defineConfig`.
|
|
9
11
|
|
|
12
|
+
**Read:** `node_modules/@pagesmith/core/REFERENCE.md` (Content Layer API, Collections)
|
|
13
|
+
|
|
10
14
|
## Add Vite integration
|
|
11
15
|
|
|
12
16
|
1. Import `pagesmithContent` and `pagesmithSsg` from `@pagesmith/core/vite`.
|
|
13
17
|
2. Register content plugin before SSG output steps.
|
|
14
18
|
3. Ensure SSR entry exports `getRoutes` and `render`.
|
|
15
19
|
|
|
20
|
+
**Read:** `node_modules/@pagesmith/core/REFERENCE.md` (Vite Plugins)
|
|
21
|
+
|
|
22
|
+
## Write markdown content
|
|
23
|
+
|
|
24
|
+
1. Create markdown files with frontmatter (`title`, `description`, etc.).
|
|
25
|
+
2. Use fenced code blocks with language identifiers.
|
|
26
|
+
3. Use Expressive Code meta for titles, line numbers, and line highlighting.
|
|
27
|
+
4. Use mermaid code blocks for diagrams (` ```mermaid `).
|
|
28
|
+
5. Use GitHub Alerts for callouts (`> [!NOTE]`, `> [!TIP]`, `> [!WARNING]`).
|
|
29
|
+
6. Validate with built-in content validators.
|
|
30
|
+
|
|
31
|
+
**Read:** `node_modules/@pagesmith/core/REFERENCE.md` (Markdown Pipeline, Expressive Code, Validators)
|
|
32
|
+
|
|
16
33
|
## Update markdown behavior
|
|
17
34
|
|
|
18
35
|
1. Update config through markdown options (`remarkPlugins`, `rehypePlugins`, `shiki`).
|
|
19
36
|
2. Keep plugin order consistent with pipeline expectations.
|
|
20
37
|
3. Validate with rendered output and built-in validators.
|
|
21
38
|
|
|
39
|
+
**Read:** `node_modules/@pagesmith/core/REFERENCE.md` (Markdown Pipeline, Custom Plugins)
|
|
40
|
+
|
|
22
41
|
## Update AI pointers in consuming project
|
|
23
42
|
|
|
24
|
-
Add
|
|
43
|
+
Add pointer lines to root `CLAUDE.md` or `AGENTS.md`:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
For @pagesmith/core usage and prompts, read node_modules/@pagesmith/core/docs/agents/usage.md
|
|
47
|
+
For the full @pagesmith/core API reference, see node_modules/@pagesmith/core/REFERENCE.md
|
|
48
|
+
```
|
|
25
49
|
|
|
26
|
-
`
|
|
50
|
+
Or copy `node_modules/@pagesmith/core/docs/agents/AGENTS.md.template` as a starting point.
|