markopress 0.0.6 → 0.0.8

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.
@@ -1 +1 @@
1
- import{promises as e}from"node:fs";import o from"node:path";import{spawn as t}from"node:child_process";import{fileURLToPath as n}from"node:url";import s from"gray-matter";import{loadConfig as a}from"../config/loader.js";import{getDesignSystem as i,getDarkModeOverride as r}from"../theme/default/design-systems/index.js";import{globalTagValidator as c,formatValidationError as l}from"../markdown/index.js";import{PluginManager as d}from"../plugin/manager.js";import{loadMarkdownModule as u,registerMarkdownContent as m,escapeMarkoText as g}from"./vite-markdown-plugin.js";import{renderMarkdown as f}from"../markdown/renderer.js";import{buildSearchIndex as p}from"../search/index.js";const h=o.dirname(n(import.meta.url)),w=o.resolve(h,"..",".."),k=o.join(w,"src","theme","default"),y=new Set(["@markopress/theme-default","theme-default","default"]);function j(e){return y.has(e)}export async function build(n={}){const{outDir:i,debug:r=!1,useCatchAllRoutes:u,root:m}=n,h=m||process.cwd(),w=[],k=new Map,y=new Map,j=e=>({start:()=>{y.set(e,performance.now())},end:()=>{const o=y.get(e)||0,t=performance.now()-o;k.set(e,t)}});try{console.log("šŸš€ Building MarkoPress site...\n");const n=j("Config loading");n.start();const m=await a(h,{mode:"production",command:"build"});let y;if(n.end(),m.plugins&&m.plugins.length>0){console.log("šŸ”Œ Loading plugins...");const e=j("Plugin loading");e.start(),y=new d(m),await y.loadPlugins(m.plugins),e.end(),console.log("")}if(y){console.log("šŸ“¦ Loading plugin content...");const e=j("Plugin loadContent hooks");e.start(),await y.execLoadContentHooks(),e.end(),console.log(" Plugin content loaded\n")}const $={},T=[];for(const[t,n]of Object.entries(m.content)){const a="string"==typeof n?{dir:n}:n;if(!a?.dir)continue;const i=new Map,r={id:t,dir:a.dir,config:a,enhance(e,o){i.set(e,o)},getEnhancement:e=>i.get(e),files:[],_enhancements:i},c=o.resolve(h,a.dir);try{const n=await e.readdir(c,{withFileTypes:!0});for(const a of n)if(a.isFile()&&a.name.endsWith(".md")){const n=o.join(c,a.name),i=await e.readFile(n,"utf-8");let l={};try{l=s(i).data}catch{}r.files.push({id:a.name.replace(".md",""),slug:a.name.replace(".md",""),filePath:n,urlPath:"index"===a.name.replace(".md","")?"/"+t:`/${t}/${a.name.replace(".md","")}`,processed:{frontmatter:l}})}}catch{}T.push(r)}if(y&&T.length>0){console.log("šŸ”Œ Enhancing modules with plugin metadata...");const t=j("Module enhancement");t.start();for(const e of T)console.log(` Module: ${e.id} (${e.files.length} files)`),e.files.length>0&&console.log(" First file has processed: "+!!e.files[0].processed);await y.execEnhanceModulesHooks(T),t.end(),console.log(` Enhanced ${T.length} module(s)\n`);const n=o.join(h,"src",".generated");await e.mkdir(n,{recursive:!0});const s=(m.site?.base||"/").replace(/\/$/,""),a={};for(const e of T){const o={},t=e._enhancements.entries();for(const[e,n]of t)o[e]=n;Object.keys(o).length>0&&(s&&b(o,s),a[e.id]=o)}const i=o.join(n,"module-enhancements.js"),r=`// Auto-generated by MarkoPress - Do not edit\nexport default ${JSON.stringify(a,null,2)};\n`;await e.writeFile(i,r,"utf-8"),console.log(" Wrote module enhancements to src/.generated/module-enhancements.js\n")}if(!1!==m.search?.enabled){console.log("šŸ” Building search index...");const t=j("Search index");t.start();const n=[];for(const o of T)for(const t of o.files)try{const o=await e.readFile(t.filePath,"utf-8"),s=await f(o,m.markdown);n.push({url:t.urlPath,html:s.html,title:s.frontmatter?.title||t.id,frontmatter:s.frontmatter})}catch(e){console.warn(` Warning: Could not index ${t.filePath}:`,e)}try{const t=await p(n,m.search),s=o.join(h,"public","search-index.json");await e.mkdir(o.dirname(s),{recursive:!0}),await e.writeFile(s,t),console.log(` Search index built (${n.length} pages)\n`)}catch(e){console.warn(" Warning: Failed to build search index:",e)}t.end()}if(m.markdown.markoTags?.enabled){const e=o.join(h,m.markdown.markoTags.tagsDir||"src/.markopress/tags");console.log("šŸ” Scanning tags directory...");const t=j("Tag validation setup");t.start(),await c.loadAvailableTags(e),t.end(),console.log(` Found ${c.getAvailableTagsCount()} tags\n`)}else c.reset();const v=o.join(h,"src","routes");await e.mkdir(v,{recursive:!0});let C={};if(y){const e=j("Extend routes hooks");e.start(),C=await y.execExtendRoutesHooks(C),e.end(),console.log("šŸ”Œ Extended routes manifest:",Object.keys(C).length)}console.log("šŸ“ Generating routes from content...");const P=j("Route generation");P.start();const F=u??m.build.useCatchAllRoutes;console.log("šŸ“„ Pre-rendering markdown to .marko files...");const x=j("Pre-render markdown");x.start();const E=o.join(h,"src",".generated","markdown");await e.mkdir(E,{recursive:!0});const S={};let A=0;for(const t of T){const n=o.join(E,t.id);await e.mkdir(n,{recursive:!0});for(const s of t.files)try{const a=await e.readFile(s.filePath,"utf-8"),i=(m.site?.base||"/").replace(/\/$/,""),r=await f(a,{base:i});let c=r.html.replace(/<span class="line"><\/span>(\s*<\/code>)/g,"$1");const l=`<div class="markdown-content">\n${g(c)}\n</div>`,d=o.join(n,s.slug+".marko");await e.writeFile(d,l),S[`${t.id}/${s.slug}`]={frontmatter:r.frontmatter,headers:r.headers||[]},A++}catch(e){console.warn(` Warning: Failed to pre-render ${t.id}/${s.slug}:`,e)}}const _=o.join(h,"src",".generated","content-metadata.js"),D=`// Auto-generated by MarkoPress - Do not edit\nexport default ${JSON.stringify(S,null,2)};\n`;await e.writeFile(_,D),x.end(),console.log(` Pre-rendered ${A} markdown files\n`),F?(await generateCatchAllRoutes($,v,m,T,r,!0),console.log(" Using catch-all dynamic routes")):(await generateRoutes($,v,m,T,r),console.log(" Using static routes")),P.end(),console.log(" Routes generated\n");const O=[];for(const[e,o]of Object.entries(C))(o.handler||o.component)&&(O.push({path:e,...o}),console.log(" Found plugin route: "+e));if(console.log(`šŸ”Œ Total manifest routes: ${Object.keys(C).length}, Plugin routes: ${O.length}`),y){const t=[...y.getPluginRoutes(),...O];if(t.length>0){console.log(`šŸ”Œ Generating ${t.length} plugin routes...`);const n=j("Plugin route generation");n.start(),await async function(t,n,s,a){for(const s of t){const t=s.path.slice(1),i=o.join(n,t,"+page");if(await e.mkdir(o.dirname(i),{recursive:!0}),s.handler){const t=o.join(o.dirname(i),"+handler.js");await e.writeFile(t,s.handler)}if(s.component){const o=i+".marko";await e.writeFile(o,s.component)}a&&console.log(" Generated plugin route: "+s.path)}}(t,v,0,r),n.end(),console.log(" Plugin routes generated\n")}}console.log("āš™ļø Generating Vite config...");const M=j("Vite config generation");if(M.start(),await generateViteConfig(h,r),M.end(),console.log(" Vite config generated\n"),y){console.log("šŸ”Œ Processing plugin allContentLoaded hooks...");const e=j("AllContentLoaded hooks");e.start(),await y.execAllContentLoadedHooks(C),e.end(),console.log(" All content processed\n")}if(m.markdown.markoTags?.enabled){console.log("šŸ” Validating Marko tags...");const e=j("Tag validation");e.start();const o=c.validate();if(e.end(),!o.success){const e=l(o.missingTags);return console.error(`\n${e}\n`),w.push(e),{success:!1,outDir:"",pages:0,errors:w}}console.log(" All tags validated āœ“\n")}console.log("šŸŽØ Copying theme CSS...");const N=j("Theme CSS copy");N.start(),await copyThemeCSS(h,m,r),N.end(),console.log(" Theme CSS copied\n"),console.log("šŸŽØ Extracting styles from Marko components...");const W=j("Marko component styles extraction");W.start(),await extractStylesFromMarkoTags(h,m,r),W.end(),console.log(" Component styles extracted\n");const G=[];for(const e of T)for(const o of e.files)"pages"===e.id?G.push("index"===o.id?"/":"/"+o.id):G.push(o.urlPath);for(const e of Object.keys(C))G.includes(e)||G.push(e);const L=o.join(h,"src",".generated","static-urls.json");await e.mkdir(o.dirname(L),{recursive:!0}),await e.writeFile(L,JSON.stringify(G,null,2)),r&&console.log(` Generated static URL manifest: ${G.length} URLs`),console.log("šŸ”Ø Building with @marko/run...");const R=j("@marko/run build");R.start();const I=i||m.build.outDir,B=await async function(e,n,s){return new Promise(a=>{const i=["build"];e&&i.push("--output",e),n&&i.push("--debug");const r=t("npx",["marko-run",...i],{stdio:"inherit",cwd:s});r.on("close",t=>{if(0===t){const t=e||"dist";a({success:!0,outDir:o.join(s,t),errors:[]})}else a({success:!1,outDir:"",errors:["Build process exited with code "+t]})}),r.on("error",e=>{a({success:!1,outDir:"",errors:["Failed to start build process: "+e.message]})})})}(I,r,h);if(R.end(),!B.success)return w.push(...B.errors),{success:!1,outDir:"",pages:0,errors:w};const H=j("Collect build assets");H.start();const U=await async function(o){const t=[];try{const n=await e.readdir(o,{recursive:!0});for(const e of n)"string"==typeof e&&(e.endsWith(".js")||e.endsWith(".css")||e.endsWith(".json"))&&t.push(e)}catch(e){console.warn("Warning: Could not collect build assets:",e)}return t}(B.outDir);if(H.end(),y){console.log("šŸ”Œ Processing plugin postBuild hooks...");const e=j("Post-build hooks");e.start(),await y.execPostBuildHooks(B.outDir,C,U),e.end(),console.log(" Post-build hooks completed\n")}console.log("šŸ“¦ Copying Marko tags directory...");const V=j("Copy tags directory");V.start(),await copyTagsDirectory(h,B.outDir,m,r),V.end(),console.log(" Tags directory copied\n"),console.log("\nāœ… Build completed successfully!"),console.log(" Output: "+B.outDir),console.log(" Pages: Generated dynamically at request time"),console.log("\nā±ļø Build timing:");const Y=Array.from(k.entries()).sort((e,o)=>o[1]-e[1]);for(const[e,o]of Y){const t=(o/1e3).toFixed(2);console.log(` ${"ā–ˆ".repeat(Math.min(Math.floor(o/100),20))} ${e}: ${t}s`)}return{success:!0,outDir:B.outDir,pages:0,errors:w}}catch(e){const o=e instanceof Error?e.message:e+"";return w.push(o),console.error("\nāŒ Build failed:",o),{success:!1,outDir:"",pages:0,errors:w}}}function b(e,o){Array.isArray(e.sidebar)&&(e.sidebar=e.sidebar.map(e=>({...e,items:Array.isArray(e.items)?e.items.map(e=>({...e,link:e.link&&!e.link.startsWith(o)?o+e.link:e.link})):e.items}))),Array.isArray(e.blogPosts)&&(e.blogPosts=e.blogPosts.map(e=>({...e,link:e.link&&!e.link.startsWith(o)?o+e.link:e.link})))}export async function generateRoutes(e,o,t,n,s){await cleanupGeneratedRoutes(o,e,s);const a=[];let i=0,r=0,c=0;for(const[o,t]of Object.entries(e)){if(!Array.isArray(t))continue;a.push(o);const e=t;if("pages"===o)for(const o of e)await T(0,0,0,0,s),i++;else if("blog"===o)for(const o of e)await C(0,0,0,0,s),c++;else for(const o of e)await v(0,0,0,0,s),r++}await P(o,t,s),await generateViteConfig(t.root,s),await F(o,t,s),s&&(console.log(` Generated ${i} page routes`),console.log(` Generated ${r} doc routes`),console.log(` Generated ${c} blog routes`))}export async function cleanupGeneratedRoutes(t,n,s){const a=[],i=["+layout.marko","+middleware.js","components/**/*","api/**/*","lib/**/*"],r=Object.keys(n).filter(e=>"pages"!==e).map(e=>e+"/");try{const n=await e.readdir(t,{recursive:!0,withFileTypes:!0});for(const c of n){if(!c.isFile())continue;const n=o.join(c.path||c.parentPath||t,c.name),l=o.relative(t,n);if(r.some(e=>l.startsWith(e)))if(i.some(e=>e.includes("**")?RegExp(e.replace(/\*\*/g,".*").replace(/\*/g,"[^/]*")).test(l):c.name===e))s&&console.log(" Preserving: "+l);else try{await e.unlink(n),s&&console.log(" Deleted: "+l)}catch(e){if("ENOENT"!==e.code){const o=e instanceof Error?e.message:e+"";a.push(`Failed to delete ${l}: ${o}`)}}}for(const e of r){const n=o.join(t,e);try{await $(n)}catch{}}a.length>0&&(console.warn("āš ļø Cleanup warnings:"),a.forEach(e=>console.warn(" "+e)))}catch(e){if("ENOENT"!==e.code)throw e}}async function $(t){try{const n=await e.readdir(t,{withFileTypes:!0});for(const e of n)if(e.isDirectory()){const n=o.join(t,e.name);await $(n)}0===(await e.readdir(t)).length&&await e.rmdir(t)}catch{}}async function T(e,o,t,n,s){s&&console.log(" Warning: Static routes deprecated, use catch-all routes")}async function v(e,o,t,n,s){s&&console.log(" Warning: Static routes deprecated, use catch-all routes")}async function C(e,o,t,n,s){s&&console.log(" Warning: Static routes deprecated, use catch-all routes")}async function P(t,n,s){const a=o.join(t,"_config.js"),i={root:n.root,site:{title:n.site?.title||"MarkoPress",description:n.site?.description||"",lang:n.site?.lang||"en-US",head:n.site?.head||[],base:n.site?.base||"/"},content:n.content,theme:{name:n.theme?.name||"@markopress/theme-default",options:n.theme?.options||{}},markdown:n.markdown||{},build:n.build||{}},r=(n.site?.base||"/").replace(/\/$/,"");r&&i.theme.options?.navbar&&(i.theme.options.navbar=i.theme.options.navbar.map(e=>({...e,link:e.link&&!e.link.startsWith(r)?r+e.link:e.link})));const c=`// Auto-generated by MarkoPress - Do not edit\nexport const config = ${JSON.stringify(i,null,2)};\n`;await e.writeFile(a,c),s&&console.log(" Generated: "+a)}async function F(t,n,s){const a=o.join(t,"+layout.marko"),i=(n.theme,n.site?.title||"MarkoPress"),r=n.theme?.options?.style||"default",c=await x("layout.marko.template",{SITE_TITLE:i,THEME_STYLE:r,BASE_PATH:n.site?.base?.replace(/\/$/,"")||""});await e.writeFile(a,c),s&&console.log(" Generated: "+a)}async function x(t,n){const s=o.dirname(new URL(import.meta.url).pathname),a=o.join(s,"..",".."),i=o.join(a,"templates",t);let r=await e.readFile(i,"utf-8");for(const[e,o]of Object.entries(n))r=r.replace(RegExp(`\\{\\{${e}\\}\\}`,"g"),o);return r}export function validateThemeName(e){if(!/^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(e))throw Error(`Invalid theme name: "${e}". Must be a valid npm package name (e.g., "my-theme" or "@org/my-theme")`);if(e.includes(".."))throw Error(`Theme name cannot contain traversal sequences (..): "${e}"`);if(e.includes("\\"))throw Error(`Theme name cannot contain backslashes: "${e}"`);if((e.match(/\//g)||[]).length>1)throw Error(`Theme name can only contain one forward slash (for scoped packages): "${e}"`);if(o.isAbsolute(e))throw Error(`Theme name cannot be an absolute path: "${e}"`)}export async function generateViteConfig(t,n){const s=o.join(t,"vite.config.js");try{if((await e.readFile(s,"utf-8")).includes("markdownContentPlugin"))return void(n&&console.log(" Vite config already has markdownContentPlugin"))}catch{}await e.writeFile(s,"import { defineConfig } from 'vite';\nimport marko from '@marko/run/vite';\nimport { markdownContentPlugin } from 'markopress/build';\n\nexport default defineConfig({\n plugins: [\n marko(),\n markdownContentPlugin(),\n ],\n resolve: {\n // Preserve symlinks for pnpm workspace compatibility\n // This allows Marko to properly discover tags from symlinked packages\n preserveSymlinks: true,\n },\n build: {\n outDir: 'dist',\n },\n});\n"),n&&console.log(" Created vite.config.js with markdownContentPlugin")}export async function copyThemeCSS(t,n,s){const a=o.join(t,"public","_markopress","theme");await e.mkdir(a,{recursive:!0});const i=n.theme?.name||"@markopress/theme-default";try{validateThemeName(i)}catch(e){const o=e instanceof Error?e.message:e+"";throw Error("Security: "+o)}const r=n.theme?.options?.style||"default",c=`theme-${r}.css`,l=[...j(i)?[o.join(k,"public",c)]:[],o.join(t,"..","node_modules",i,"public",c),o.join(t,"node_modules",i,"public",c)];let d=null,u=null;for(const o of l)try{await e.access(o),d=await e.readFile(o,"utf-8"),u=o;break}catch{}if(!d){console.warn(` Warning: Could not find ${c}, using minimal fallback`);const t=`/* Minimal fallback CSS for style: ${r} */\nbody { font-family: system-ui, sans-serif; margin: 0; padding: 0; }`,n=o.join(a,c);return void await e.writeFile(n,t)}const m=o.join(a,c);await e.writeFile(m,d),s&&(console.log(` Copied ${c} from: ${u}`),console.log(" Output: "+m));const g="styles.css",f=[...j(i)?[o.join(k,g)]:[],o.join(t,"..","node_modules",i,"src",g),o.join(t,"node_modules",i,"src",g)];for(const t of f)try{await e.access(t);const n=await e.readFile(t,"utf-8"),i=o.join(a,g);await e.writeFile(i,n),s&&(console.log(` Copied ${g} from: ${t}`),console.log(" Output: "+i));break}catch{}}export async function extractStylesFromMarkoTags(t,n,s){const a=n.markdown?.markoTags?.tagsDir||"src/.markopress/tags",i=o.join(t,a);try{await e.access(i)}catch{return void(s&&console.log(" No tags directory found at: "+i))}const r=[];if(await async function t(n){const s=await e.readdir(n,{withFileTypes:!0});for(const e of s){const s=o.join(n,e.name);e.isDirectory()?await t(s):e.isFile()&&e.name.endsWith(".marko")&&r.push(s)}}(i),0===r.length)return void(s&&console.log(" No .marko files found in: "+i));const c=[];c.push("/* Custom markdown tag styles"),c.push(" * Loaded globally because request-time virtual markdown modules"),c.push(" * do not emit tag-local CSS assets reliably. */"),c.push("");for(const t of r){const n=o.relative(i,t),s=""===o.dirname(n)?o.basename(n,".marko"):o.join(o.dirname(n),o.basename(n,".marko"));try{const o=await e.readFile(t,"utf-8"),n=/<style\b[^>]*>([\s\S]*?)<\/style>/gi,a=Array.from(o.matchAll(n));if(a.length>0){c.push(`/* ${s}.marko */`);for(const e of a){const o=e[1]||"";if(o){const e=o.split("\n");let t=0;for(;t<e.length&&""===e[t].trim();)t++;let n=e.length-1;for(;n>=t&&""===e[n].trim();)n--;for(let o=t;o<=n;o++){const t=e[o];if(""===t.trim()){c.push("");continue}const n=t.match(/^(\s*)/),s=n?n[1].length:0,a=" ".repeat(Math.floor(s/2)),i=t.trim().replace(/:global\(([^)]+)\)/g,"$1");c.push(a+i)}}}c.push("")}}catch(e){console.warn(` Warning: Could not read file ${t}:`,e)}}const l=o.join(t,"public");await e.mkdir(l,{recursive:!0});const d=o.join(l,"markopress-components.css"),u=c.join("\n");await e.writeFile(d,u),s&&(console.log(` Extracted styles from ${r.length} Marko component(s)`),console.log(" Output: "+d))}async function E(t){const n=await e.readdir(t,{withFileTypes:!0}),s=await Promise.all(n.map(e=>{const n=o.resolve(t,e.name);return e.isDirectory()?E(n):n}));return Array.prototype.concat(...s).filter(e=>e.endsWith(".marko"))}export async function copyThemeComponents(t,n,s){const a=n.theme?.name||"@markopress/theme-default",i=o.join(t,"src"),r=o.join(i,"tags");await e.mkdir(r,{recursive:!0});const c=[...j(a)?[o.join(k,"tags")]:[],o.join(t,"..","node_modules",a,"dist","tags"),o.join(t,"node_modules",a,"dist","tags"),o.join(t,"..","node_modules",a,"src","components"),o.join(t,"node_modules",a,"src","components")];let l=null;for(const o of c)try{await e.access(o),l=o;break}catch{}if(!l)return void(s&&console.warn(" Warning: Could not find theme components, skipping"));const d=await E(l);let u=0;for(const t of d){const n=o.relative(l,t),a=o.join(r,n);let i=!1;try{await e.access(a),i=!0}catch{}i?s&&console.log(" Skipped component (user override exists): "+n):(await e.mkdir(o.dirname(a),{recursive:!0}),await e.copyFile(t,a),u++)}s&&(console.log(` Copied ${u} theme components from: ${l}`),console.log(" Output: "+r))}export async function copyTagsDirectory(t,n,s,a){const i=s.markdown?.markoTags?.tagsDir||"src/.markopress/tags",r=o.join(t,i),c=o.join(n,"tags");try{await e.access(r)}catch{return void(a&&console.log(" No tags directory found at: "+r))}await e.mkdir(c,{recursive:!0});const l=await e.readdir(r,{withFileTypes:!0});let d=0;for(const t of l){const n=o.join(r,t.name),s=o.join(c,t.name);if(t.isDirectory()){await e.mkdir(s,{recursive:!0});const t=await e.readdir(n,{withFileTypes:!0});for(const a of t){const t=o.join(n,a.name),i=o.join(s,a.name);a.isDirectory()||(await e.copyFile(t,i),d++)}}else t.isFile()&&(await e.copyFile(n,s),d++)}a&&(console.log(` Copied ${d} tag files from: ${r}`),console.log(" Output: "+c))}export async function generateCatchAllRoutes(t,n,s,a,i,r=!0){console.log(" Using catch-all dynamic routes..."),console.log(" Mode: "+(r?"build (pre-compiled)":"dev (request-time rendering)"));const c=s.content||{};for(const[t,s]of Object.entries(c))if(s&&("object"!=typeof s||null===s||"dir"in s))if("pages"===t){const t=o.join(n,"$$slug");await e.mkdir(t,{recursive:!0});const s=await x("catch-all-handler.js.template",{CONTENT_TYPE:"pages",CONFIG_PATH:"../_config.js",VITE_PLUGIN_PATH:"markopress/build",IS_BUILD:r?"true":"false"});await e.writeFile(o.join(t,"+handler.js"),s);const a=await x("catch-all-page.marko.template",{CONTENT_TYPE_CLASS:"page"});await e.writeFile(o.join(t,"+page.marko"),a),i&&console.log(" Generated pages catch-all route")}else{const s=o.join(n,t,"$$slug");await e.mkdir(s,{recursive:!0});const a=await x("catch-all-handler.js.template",{CONTENT_TYPE:t,CONFIG_PATH:"../../_config.js",VITE_PLUGIN_PATH:"markopress/build",IS_BUILD:r?"true":"false"});await e.writeFile(o.join(s,"+handler.js"),a);const c=await x("catch-all-page.marko.template",{CONTENT_TYPE_CLASS:t});await e.writeFile(o.join(s,"+page.marko"),c),i&&console.log(` Generated ${t} catch-all route`)}await P(n,s,i),await generateViteConfig(s.root,i),await F(n,s,i)}export{u as loadMarkdownModule,m as registerMarkdownContent};export{markdownContentPlugin}from"./vite-markdown-plugin.js";
1
+ import{promises as e}from"node:fs";import o from"node:path";import{spawn as t}from"node:child_process";import{fileURLToPath as n}from"node:url";import s from"gray-matter";import{loadConfig as a}from"../config/loader.js";import{getDesignSystem as i,getDarkModeOverride as r}from"../theme/default/design-systems/index.js";import{globalTagValidator as c,formatValidationError as l}from"../markdown/index.js";import{PluginManager as d}from"../plugin/manager.js";import{loadMarkdownModule as u,registerMarkdownContent as m,escapeMarkoText as g}from"./vite-markdown-plugin.js";import{renderMarkdown as f}from"../markdown/renderer.js";import{buildSearchIndex as p}from"../search/index.js";const h=o.dirname(n(import.meta.url)),w=o.resolve(h,"..",".."),k=o.join(w,"src","theme","default"),y=new Set(["@markopress/theme-default","theme-default","default"]);function j(e){return y.has(e)}export async function build(n={}){const{outDir:i,debug:r=!1,useCatchAllRoutes:u,root:m}=n,h=m||process.cwd(),w=[],k=new Map,y=new Map,j=e=>({start:()=>{y.set(e,performance.now())},end:()=>{const o=y.get(e)||0,t=performance.now()-o;k.set(e,t)}});try{console.log("šŸš€ Building MarkoPress site...\n");const n=j("Config loading");n.start();const m=await a(h,{mode:"production",command:"build"});let y;if(n.end(),m.plugins&&m.plugins.length>0){console.log("šŸ”Œ Loading plugins...");const e=j("Plugin loading");e.start(),y=new d(m),await y.loadPlugins(m.plugins),e.end(),console.log("")}if(y){console.log("šŸ“¦ Loading plugin content...");const e=j("Plugin loadContent hooks");e.start(),await y.execLoadContentHooks(),e.end(),console.log(" Plugin content loaded\n")}const T={},$=[];for(const[t,n]of Object.entries(m.content)){const a="string"==typeof n?{dir:n}:n;if(!a?.dir)continue;const i=new Map,r={id:t,dir:a.dir,config:a,enhance(e,o){i.set(e,o)},getEnhancement:e=>i.get(e),files:[],_enhancements:i},c=o.resolve(h,a.dir);try{const n=await e.readdir(c,{withFileTypes:!0});for(const a of n)if(a.isFile()&&a.name.endsWith(".md")){const n=o.join(c,a.name),i=await e.readFile(n,"utf-8");let l={};try{l=s(i).data}catch{}r.files.push({id:a.name.replace(".md",""),slug:a.name.replace(".md",""),filePath:n,urlPath:"index"===a.name.replace(".md","")?"/"+t:`/${t}/${a.name.replace(".md","")}`,processed:{frontmatter:l}})}}catch{}$.push(r)}if(y&&$.length>0){console.log("šŸ”Œ Enhancing modules with plugin metadata...");const t=j("Module enhancement");t.start();for(const e of $)console.log(` Module: ${e.id} (${e.files.length} files)`),e.files.length>0&&console.log(" First file has processed: "+!!e.files[0].processed);await y.execEnhanceModulesHooks($),t.end(),console.log(` Enhanced ${$.length} module(s)\n`);const n=o.join(h,"src",".generated");await e.mkdir(n,{recursive:!0});const s=(m.site?.base||"/").replace(/\/$/,""),a={};for(const e of $){const o={},t=e._enhancements.entries();for(const[e,n]of t)o[e]=n;Object.keys(o).length>0&&(s&&b(o,s),a[e.id]=o)}const i=o.join(n,"module-enhancements.js"),r=`// Auto-generated by MarkoPress - Do not edit\nexport default ${JSON.stringify(a,null,2)};\n`;await e.writeFile(i,r,"utf-8"),console.log(" Wrote module enhancements to src/.generated/module-enhancements.js\n")}if(!1!==m.search?.enabled){console.log("šŸ” Building search index...");const t=j("Search index");t.start();const n=[];for(const o of $)for(const t of o.files)try{const o=await e.readFile(t.filePath,"utf-8"),s=await f(o,m.markdown);n.push({url:t.urlPath,html:s.html,title:s.frontmatter?.title||t.id,frontmatter:s.frontmatter})}catch(e){console.warn(` Warning: Could not index ${t.filePath}:`,e)}try{const t=await p(n,m.search),s=o.join(h,"public","search-index.json");await e.mkdir(o.dirname(s),{recursive:!0}),await e.writeFile(s,t),console.log(` Search index built (${n.length} pages)\n`)}catch(e){console.warn(" Warning: Failed to build search index:",e)}t.end()}if(m.markdown.markoTags?.enabled){const e=o.join(h,m.markdown.markoTags.tagsDir||"src/tags");console.log("šŸ” Scanning tags directory...");const t=j("Tag validation setup");t.start(),await c.loadAvailableTags(e),t.end(),console.log(` Found ${c.getAvailableTagsCount()} tags\n`)}else c.reset();const v=o.join(h,"src","routes");await e.mkdir(v,{recursive:!0});let C={};if(y){const e=j("Extend routes hooks");e.start(),C=await y.execExtendRoutesHooks(C),e.end(),console.log("šŸ”Œ Extended routes manifest:",Object.keys(C).length)}console.log("šŸ“ Generating routes from content...");const P=j("Route generation");P.start();const F=u??m.build.useCatchAllRoutes;console.log("šŸ“„ Pre-rendering markdown to .marko files...");const x=j("Pre-render markdown");x.start();const E=o.join(h,"src",".generated","markdown");await e.mkdir(E,{recursive:!0});const S={};let _=0;for(const t of $){const n=o.join(E,t.id);await e.mkdir(n,{recursive:!0});for(const s of t.files)try{const a=await e.readFile(s.filePath,"utf-8"),i=(m.site?.base||"/").replace(/\/$/,""),r=await f(a,{base:i});let c=r.html.replace(/<span class="line"><\/span>(\s*<\/code>)/g,"$1");const l=`<div class="markdown-content">\n${g(c)}\n</div>`,d=o.join(n,s.slug+".marko");await e.writeFile(d,l),S[`${t.id}/${s.slug}`]={frontmatter:r.frontmatter,headers:r.headers||[]},_++}catch(e){console.warn(` Warning: Failed to pre-render ${t.id}/${s.slug}:`,e)}}const A=o.join(h,"src",".generated","content-metadata.js"),D=`// Auto-generated by MarkoPress - Do not edit\nexport default ${JSON.stringify(S,null,2)};\n`;await e.writeFile(A,D),x.end(),console.log(` Pre-rendered ${_} markdown files\n`),F?(await generateCatchAllRoutes(T,v,m,$,r,!0),console.log(" Using catch-all dynamic routes")):(await generateRoutes(T,v,m,$,r),console.log(" Using static routes")),P.end(),console.log(" Routes generated\n");const O=[];for(const[e,o]of Object.entries(C))(o.handler||o.component)&&(O.push({path:e,...o}),console.log(" Found plugin route: "+e));if(console.log(`šŸ”Œ Total manifest routes: ${Object.keys(C).length}, Plugin routes: ${O.length}`),y){const t=[...y.getPluginRoutes(),...O];if(t.length>0){console.log(`šŸ”Œ Generating ${t.length} plugin routes...`);const n=j("Plugin route generation");n.start(),await async function(t,n,s,a){for(const s of t){const t=s.path.slice(1),i=o.join(n,t,"+page");if(await e.mkdir(o.dirname(i),{recursive:!0}),s.handler){const t=o.join(o.dirname(i),"+handler.js");await e.writeFile(t,s.handler)}if(s.component){const o=i+".marko";await e.writeFile(o,s.component)}a&&console.log(" Generated plugin route: "+s.path)}}(t,v,0,r),n.end(),console.log(" Plugin routes generated\n")}}console.log("āš™ļø Generating Vite config...");const M=j("Vite config generation");if(M.start(),await generateViteConfig(h,r),M.end(),console.log(" Vite config generated\n"),y){console.log("šŸ”Œ Processing plugin allContentLoaded hooks...");const e=j("AllContentLoaded hooks");e.start(),await y.execAllContentLoadedHooks(C),e.end(),console.log(" All content processed\n")}if(m.markdown.markoTags?.enabled){console.log("šŸ” Validating Marko tags...");const e=j("Tag validation");e.start();const o=c.validate();if(e.end(),!o.success){const e=l(o.missingTags);return console.error(`\n${e}\n`),w.push(e),{success:!1,outDir:"",pages:0,errors:w}}console.log(" All tags validated āœ“\n")}console.log("šŸŽØ Copying theme CSS...");const N=j("Theme CSS copy");N.start(),await copyThemeCSS(h,m,r),N.end(),console.log(" Theme CSS copied\n"),console.log("šŸŽØ Extracting styles from Marko components...");const W=j("Marko component styles extraction");W.start(),await extractStylesFromMarkoTags(h,m,r),W.end(),console.log(" Component styles extracted\n");const L=[];for(const e of $)for(const o of e.files)"pages"===e.id?L.push("index"===o.id?"/":"/"+o.id):L.push(o.urlPath);for(const e of Object.keys(C))L.includes(e)||L.push(e);const G=o.join(h,"src",".generated","static-urls.json");await e.mkdir(o.dirname(G),{recursive:!0}),await e.writeFile(G,JSON.stringify(L,null,2)),r&&console.log(` Generated static URL manifest: ${L.length} URLs`),console.log("šŸ”Ø Building with @marko/run...");const R=j("@marko/run build");R.start();const I=i||m.build.outDir,B=await async function(e,n,s){return new Promise(a=>{const i=["build"];e&&i.push("--output",e),n&&i.push("--debug");const r=t("npx",["marko-run",...i],{stdio:"inherit",cwd:s});r.on("close",t=>{if(0===t){const t=e||"dist";a({success:!0,outDir:o.join(s,t),errors:[]})}else a({success:!1,outDir:"",errors:["Build process exited with code "+t]})}),r.on("error",e=>{a({success:!1,outDir:"",errors:["Failed to start build process: "+e.message]})})})}(I,r,h);if(R.end(),!B.success)return w.push(...B.errors),{success:!1,outDir:"",pages:0,errors:w};const H=j("Collect build assets");H.start();const U=await async function(o){const t=[];try{const n=await e.readdir(o,{recursive:!0});for(const e of n)"string"==typeof e&&(e.endsWith(".js")||e.endsWith(".css")||e.endsWith(".json"))&&t.push(e)}catch(e){console.warn("Warning: Could not collect build assets:",e)}return t}(B.outDir);if(H.end(),y){console.log("šŸ”Œ Processing plugin postBuild hooks...");const e=j("Post-build hooks");e.start(),await y.execPostBuildHooks(B.outDir,C,U),e.end(),console.log(" Post-build hooks completed\n")}console.log("šŸ“¦ Copying Marko tags directory...");const V=j("Copy tags directory");V.start(),await copyTagsDirectory(h,B.outDir,m,r),V.end(),console.log(" Tags directory copied\n"),console.log("\nāœ… Build completed successfully!"),console.log(" Output: "+B.outDir),console.log(" Pages: Generated dynamically at request time"),console.log("\nā±ļø Build timing:");const Y=Array.from(k.entries()).sort((e,o)=>o[1]-e[1]);for(const[e,o]of Y){const t=(o/1e3).toFixed(2);console.log(` ${"ā–ˆ".repeat(Math.min(Math.floor(o/100),20))} ${e}: ${t}s`)}return{success:!0,outDir:B.outDir,pages:0,errors:w}}catch(e){const o=e instanceof Error?e.message:e+"";return w.push(o),console.error("\nāŒ Build failed:",o),{success:!1,outDir:"",pages:0,errors:w}}}function b(e,o){Array.isArray(e.sidebar)&&(e.sidebar=e.sidebar.map(e=>({...e,items:Array.isArray(e.items)?e.items.map(e=>({...e,link:e.link&&!e.link.startsWith(o)?o+e.link:e.link})):e.items}))),Array.isArray(e.blogPosts)&&(e.blogPosts=e.blogPosts.map(e=>({...e,link:e.link&&!e.link.startsWith(o)?o+e.link:e.link})))}export async function generateRoutes(e,o,t,n,s){await cleanupGeneratedRoutes(o,e,s);const a=[];let i=0,r=0,c=0;for(const[o,t]of Object.entries(e)){if(!Array.isArray(t))continue;a.push(o);const e=t;if("pages"===o)for(const o of e)await $(0,0,0,0,s),i++;else if("blog"===o)for(const o of e)await C(0,0,0,0,s),c++;else for(const o of e)await v(0,0,0,0,s),r++}await P(o,t,s),await generateViteConfig(t.root,s),await F(o,t,s),s&&(console.log(` Generated ${i} page routes`),console.log(` Generated ${r} doc routes`),console.log(` Generated ${c} blog routes`))}export async function cleanupGeneratedRoutes(t,n,s){const a=[],i=["+layout.marko","+middleware.js","components/**/*","api/**/*","lib/**/*"],r=Object.keys(n).filter(e=>"pages"!==e).map(e=>e+"/");try{const n=await e.readdir(t,{recursive:!0,withFileTypes:!0});for(const c of n){if(!c.isFile())continue;const n=o.join(c.path||c.parentPath||t,c.name),l=o.relative(t,n);if(r.some(e=>l.startsWith(e)))if(i.some(e=>e.includes("**")?RegExp(e.replace(/\*\*/g,".*").replace(/\*/g,"[^/]*")).test(l):c.name===e))s&&console.log(" Preserving: "+l);else try{await e.unlink(n),s&&console.log(" Deleted: "+l)}catch(e){if("ENOENT"!==e.code){const o=e instanceof Error?e.message:e+"";a.push(`Failed to delete ${l}: ${o}`)}}}for(const e of r){const n=o.join(t,e);try{await T(n)}catch{}}a.length>0&&(console.warn("āš ļø Cleanup warnings:"),a.forEach(e=>console.warn(" "+e)))}catch(e){if("ENOENT"!==e.code)throw e}}async function T(t){try{const n=await e.readdir(t,{withFileTypes:!0});for(const e of n)if(e.isDirectory()){const n=o.join(t,e.name);await T(n)}0===(await e.readdir(t)).length&&await e.rmdir(t)}catch{}}async function $(e,o,t,n,s){s&&console.log(" Warning: Static routes deprecated, use catch-all routes")}async function v(e,o,t,n,s){s&&console.log(" Warning: Static routes deprecated, use catch-all routes")}async function C(e,o,t,n,s){s&&console.log(" Warning: Static routes deprecated, use catch-all routes")}async function P(t,n,s){const a=o.join(t,"_config.js"),i={root:n.root,site:{title:n.site?.title||"MarkoPress",description:n.site?.description||"",lang:n.site?.lang||"en-US",head:n.site?.head||[],base:n.site?.base||"/"},content:n.content,theme:{name:n.theme?.name||"@markopress/theme-default",options:n.theme?.options||{}},markdown:n.markdown||{},build:n.build||{}},r=(n.site?.base||"/").replace(/\/$/,"");r&&i.theme.options?.navbar&&(i.theme.options.navbar=i.theme.options.navbar.map(e=>({...e,link:e.link&&!e.link.startsWith(r)?r+e.link:e.link})));const c=`// Auto-generated by MarkoPress - Do not edit\nexport const config = ${JSON.stringify(i,null,2)};\n`;await e.writeFile(a,c),s&&console.log(" Generated: "+a)}async function F(t,n,s){const a=o.join(t,"+layout.marko"),i=(n.theme,n.site?.title||"MarkoPress"),r=n.theme?.options?.style||"default",c=n.site?.base?.replace(/\/$/,"")||"",l=n.markdown?.markoTags?.enabled?`<link rel="stylesheet" href="${c}/markopress-components.css">`:"",d=await x("layout.marko.template",{SITE_TITLE:i,THEME_STYLE:r,BASE_PATH:c,COMPONENT_STYLES_LINK:l});await e.writeFile(a,d),s&&console.log(" Generated: "+a)}async function x(t,n){const s=o.dirname(new URL(import.meta.url).pathname),a=o.join(s,"..",".."),i=o.join(a,"templates",t);let r=await e.readFile(i,"utf-8");for(const[e,o]of Object.entries(n))r=r.replace(RegExp(`\\{\\{${e}\\}\\}`,"g"),o);return r}export function validateThemeName(e){if(!/^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(e))throw Error(`Invalid theme name: "${e}". Must be a valid npm package name (e.g., "my-theme" or "@org/my-theme")`);if(e.includes(".."))throw Error(`Theme name cannot contain traversal sequences (..): "${e}"`);if(e.includes("\\"))throw Error(`Theme name cannot contain backslashes: "${e}"`);if((e.match(/\//g)||[]).length>1)throw Error(`Theme name can only contain one forward slash (for scoped packages): "${e}"`);if(o.isAbsolute(e))throw Error(`Theme name cannot be an absolute path: "${e}"`)}export async function generateViteConfig(t,n){const s=o.join(t,"vite.config.js");try{if((await e.readFile(s,"utf-8")).includes("markdownContentPlugin"))return void(n&&console.log(" Vite config already has markdownContentPlugin"))}catch{}await e.writeFile(s,"import { defineConfig } from 'vite';\nimport marko from '@marko/run/vite';\nimport { markdownContentPlugin } from 'markopress/build';\n\nexport default defineConfig({\n plugins: [\n marko(),\n markdownContentPlugin(),\n ],\n resolve: {\n // Preserve symlinks for pnpm workspace compatibility\n // This allows Marko to properly discover tags from symlinked packages\n preserveSymlinks: true,\n },\n build: {\n outDir: 'dist',\n },\n});\n"),n&&console.log(" Created vite.config.js with markdownContentPlugin")}export async function copyThemeCSS(t,n,s){const a=o.join(t,"public","_markopress","theme");await e.mkdir(a,{recursive:!0});const i=n.theme?.name||"@markopress/theme-default";try{validateThemeName(i)}catch(e){const o=e instanceof Error?e.message:e+"";throw Error("Security: "+o)}const r=n.theme?.options?.style||"default",c=`theme-${r}.css`,l=[...j(i)?[o.join(k,"public",c)]:[],o.join(t,"..","node_modules",i,"public",c),o.join(t,"node_modules",i,"public",c)];let d=null,u=null;for(const o of l)try{await e.access(o),d=await e.readFile(o,"utf-8"),u=o;break}catch{}if(!d){console.warn(` Warning: Could not find ${c}, using minimal fallback`);const t=`/* Minimal fallback CSS for style: ${r} */\nbody { font-family: system-ui, sans-serif; margin: 0; padding: 0; }`,n=o.join(a,c);return void await e.writeFile(n,t)}const m=o.join(a,c);await e.writeFile(m,d),s&&(console.log(` Copied ${c} from: ${u}`),console.log(" Output: "+m));const g="styles.css",f=[...j(i)?[o.join(k,g)]:[],o.join(t,"..","node_modules",i,"src",g),o.join(t,"node_modules",i,"src",g)];for(const t of f)try{await e.access(t);const n=await e.readFile(t,"utf-8"),i=o.join(a,g);await e.writeFile(i,n),s&&(console.log(` Copied ${g} from: ${t}`),console.log(" Output: "+i));break}catch{}}export async function extractStylesFromMarkoTags(t,n,s){const a=n.markdown?.markoTags?.tagsDir||"src/tags",i=o.join(t,a),r=o.join(t,"public");await e.mkdir(r,{recursive:!0});const c=o.join(r,"markopress-components.css");if(!n.markdown?.markoTags?.enabled){s&&console.log(" Marko tags not enabled, skipping style extraction");try{await e.unlink(c)}catch{}return}try{await e.access(i)}catch{return void(s&&console.log(" No tags directory found at: "+i))}const l=[];if(await async function t(n){const s=await e.readdir(n,{withFileTypes:!0});for(const e of s){const s=o.join(n,e.name);e.isDirectory()?await t(s):e.isFile()&&e.name.endsWith(".marko")&&l.push(s)}}(i),0===l.length)return void(s&&console.log(" No .marko files found in: "+i));const d=[];d.push("/* Custom markdown tag styles"),d.push(" * Loaded globally because request-time virtual markdown modules"),d.push(" * do not emit tag-local CSS assets reliably. */"),d.push("");for(const t of l){const n=o.relative(i,t),s=""===o.dirname(n)?o.basename(n,".marko"):o.join(o.dirname(n),o.basename(n,".marko"));try{const o=await e.readFile(t,"utf-8"),n=/<style\b[^>]*>([\s\S]*?)<\/style>/gi,a=Array.from(o.matchAll(n));if(a.length>0){d.push(`/* ${s}.marko */`);for(const e of a){const o=e[1]||"";if(o){const e=o.split("\n");let t=0;for(;t<e.length&&""===e[t].trim();)t++;let n=e.length-1;for(;n>=t&&""===e[n].trim();)n--;for(let o=t;o<=n;o++){const t=e[o];if(""===t.trim()){d.push("");continue}const n=t.match(/^(\s*)/),s=n?n[1].length:0,a=" ".repeat(Math.floor(s/2)),i=t.trim().replace(/:global\(([^)]+)\)/g,"$1");d.push(a+i)}}}d.push("")}}catch(e){console.warn(` Warning: Could not read file ${t}:`,e)}}const u=d.join("\n");await e.writeFile(c,u),s&&(console.log(` Extracted styles from ${l.length} Marko component(s)`),console.log(" Output: "+c))}async function E(t){const n=await e.readdir(t,{withFileTypes:!0}),s=await Promise.all(n.map(e=>{const n=o.resolve(t,e.name);return e.isDirectory()?E(n):n}));return Array.prototype.concat(...s).filter(e=>e.endsWith(".marko"))}export async function copyThemeComponents(t,n,s){const a=n.theme?.name||"@markopress/theme-default",i=o.join(t,"src"),r=o.join(i,"tags");await e.mkdir(r,{recursive:!0});const c=[...j(a)?[o.join(k,"tags")]:[],o.join(t,"..","node_modules",a,"dist","tags"),o.join(t,"node_modules",a,"dist","tags"),o.join(t,"..","node_modules",a,"src","components"),o.join(t,"node_modules",a,"src","components")];let l=null;for(const o of c)try{await e.access(o),l=o;break}catch{}if(!l)return void(s&&console.warn(" Warning: Could not find theme components, skipping"));const d=await E(l);let u=0;for(const t of d){const n=o.relative(l,t),a=o.join(r,n);let i=!1;try{await e.access(a),i=!0}catch{}i?s&&console.log(" Skipped component (user override exists): "+n):(await e.mkdir(o.dirname(a),{recursive:!0}),await e.copyFile(t,a),u++)}s&&(console.log(` Copied ${u} theme components from: ${l}`),console.log(" Output: "+r))}export async function copyTagsDirectory(t,n,s,a){const i=s.markdown?.markoTags?.tagsDir||"src/tags",r=o.join(t,i),c=o.join(n,"tags");try{await e.access(r)}catch{return void(a&&console.log(" No tags directory found at: "+r))}await e.mkdir(c,{recursive:!0});const l=await e.readdir(r,{withFileTypes:!0});let d=0;for(const t of l){const n=o.join(r,t.name),s=o.join(c,t.name);if(t.isDirectory()){await e.mkdir(s,{recursive:!0});const t=await e.readdir(n,{withFileTypes:!0});for(const a of t){const t=o.join(n,a.name),i=o.join(s,a.name);a.isDirectory()||(await e.copyFile(t,i),d++)}}else t.isFile()&&(await e.copyFile(n,s),d++)}a&&(console.log(` Copied ${d} tag files from: ${r}`),console.log(" Output: "+c))}export async function generateCatchAllRoutes(t,n,s,a,i,r=!0){console.log(" Using catch-all dynamic routes..."),console.log(" Mode: "+(r?"build (pre-compiled)":"dev (request-time rendering)"));const c=s.content||{};for(const[t,s]of Object.entries(c))if(s&&("object"!=typeof s||null===s||"dir"in s))if("pages"===t){const t=o.join(n,"$$slug");await e.mkdir(t,{recursive:!0});const s=await x("catch-all-handler.js.template",{CONTENT_TYPE:"pages",CONFIG_PATH:"../_config.js",VITE_PLUGIN_PATH:"markopress/build",IS_BUILD:r?"true":"false"});await e.writeFile(o.join(t,"+handler.js"),s);const a=await x("catch-all-page.marko.template",{CONTENT_TYPE_CLASS:"page"});await e.writeFile(o.join(t,"+page.marko"),a),i&&console.log(" Generated pages catch-all route")}else{const s=o.join(n,t,"$$slug");await e.mkdir(s,{recursive:!0});const a=await x("catch-all-handler.js.template",{CONTENT_TYPE:t,CONFIG_PATH:"../../_config.js",VITE_PLUGIN_PATH:"markopress/build",IS_BUILD:r?"true":"false"});await e.writeFile(o.join(s,"+handler.js"),a);const c=await x("catch-all-page.marko.template",{CONTENT_TYPE_CLASS:t});await e.writeFile(o.join(s,"+page.marko"),c),i&&console.log(` Generated ${t} catch-all route`)}await P(n,s,i),await generateViteConfig(s.root,i),await F(n,s,i)}export{u as loadMarkdownModule,m as registerMarkdownContent};export{markdownContentPlugin}from"./vite-markdown-plugin.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "markopress",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "A fast, modern static site generator built on Marko.js v6 - drop-in alternative to VitePress and Docusaurus with full content compatibility",
5
5
  "keywords": [
6
6
  "static-site-generator",
@@ -2,14 +2,8 @@
2
2
  * Blog listing layout
3
3
  */
4
4
 
5
- class {
6
- onCreate() {
7
- this.state = {
8
- title: input.frontmatter?.title || 'Blog',
9
- posts: input.posts || [],
10
- };
11
- }
12
- }
5
+ <const/title=input.frontmatter?.title || 'Blog'/>
6
+ <const/posts=input.posts || []/>
13
7
 
14
8
  <!DOCTYPE html>
15
9
  <html lang="en">
@@ -17,7 +11,7 @@ class {
17
11
  <theme-head-top/>
18
12
  <meta charset="UTF-8">
19
13
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
20
- <title>${state.title}</title>
14
+ <title>${title}</title>
21
15
  <theme-head-bottom/>
22
16
  </head>
23
17
  <body>
@@ -33,9 +27,9 @@ class {
33
27
 
34
28
  <main class="blog-content">
35
29
  <theme-page-top/>
36
- <h1>${state.title}</h1>
30
+ <h1>${title}</h1>
37
31
  <div class="posts-list">
38
- <for|post| in=(state.posts)>
32
+ <for|post| of=posts>
39
33
  <article class="post-summary">
40
34
  <h2>
41
35
  <a href="${post.urlPath}">${post.frontmatter.title}</a>
@@ -3,50 +3,32 @@
3
3
  * Main layout wrapper with theme support, navigation, and SEO
4
4
  */
5
5
 
6
- class {
7
- onCreate() {
8
- this.state = {
9
- darkMode: false,
10
- mobileMenuOpen: false,
11
- sidebarOpen: true,
12
- };
13
- }
6
+ <let/darkMode=false/>
7
+ <let/mobileMenuOpen=false/>
8
+ <let/sidebarOpen=true/>
9
+ <const/basePath=($global.base === '/' ? '' : $global.base) || ''/>
14
10
 
11
+ <lifecycle
15
12
  onMount() {
16
13
  // Check for saved theme preference or system preference
17
14
  const savedTheme = localStorage.getItem('theme');
18
15
  const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
19
16
 
20
17
  if (savedTheme === 'dark' || (!savedTheme && prefersDark)) {
21
- this.state.darkMode = true;
18
+ darkMode = true;
22
19
  document.documentElement.classList.add('dark');
23
20
  }
24
21
 
25
22
  // Check for saved sidebar state
26
23
  const sidebarState = localStorage.getItem('sidebar');
27
24
  if (sidebarState === 'closed') {
28
- this.state.sidebarOpen = false;
25
+ sidebarOpen = false;
29
26
  }
30
27
  }
31
-
32
- toggleDarkMode() {
33
- this.state.darkMode = !this.state.darkMode;
34
- document.documentElement.classList.toggle('dark', this.state.darkMode);
35
- localStorage.setItem('theme', this.state.darkMode ? 'dark' : 'light');
36
- }
37
-
38
- toggleMobileMenu() {
39
- this.state.mobileMenuOpen = !this.state.mobileMenuOpen;
40
- }
41
-
42
- toggleSidebar() {
43
- this.state.sidebarOpen = !this.state.sidebarOpen;
44
- localStorage.setItem('sidebar', this.state.sidebarOpen ? 'open' : 'closed');
45
- }
46
- }
28
+ />
47
29
 
48
30
  <!DOCTYPE html>
49
- <html lang=$input.lang||"en">
31
+ <html lang=input.lang||"en">
50
32
  <head>
51
33
  <theme-head-top/>
52
34
 
@@ -96,15 +78,17 @@ class {
96
78
  <include('../styles.css')/>
97
79
  </style>
98
80
 
99
- <!-- Component Styles -->
100
- <link rel="stylesheet" href="/markopress-components.css">
81
+ <!-- Component Styles (only when marko tags are enabled) -->
82
+ <if=$global.hasComponentStyles>
83
+ <link rel="stylesheet" href=(basePath + '/markopress-components.css')>
84
+ </if>
101
85
 
102
86
  <theme-head-bottom/>
103
87
  </head>
104
88
  <body class=${[
105
89
  'theme-default',
106
- state.darkMode ? 'dark' : 'light',
107
- !state.sidebarOpen ? 'sidebar-closed' : ''
90
+ darkMode ? 'dark' : 'light',
91
+ !sidebarOpen ? 'sidebar-closed' : ''
108
92
  ].filter(Boolean).join(' ')}>
109
93
  <theme-body-top/>
110
94
 
@@ -125,11 +109,11 @@ class {
125
109
  <theme-navbar-center/>
126
110
 
127
111
  <!-- Header Actions -->
128
- <theme-navbar-end darkMode=state.darkMode mobileMenuOpen=state.mobileMenuOpen />
112
+ <theme-navbar-end darkMode=darkMode mobileMenuOpen=mobileMenuOpen />
129
113
  </div>
130
114
 
131
115
  <!-- Mobile Menu -->
132
- <if=state.mobileMenuOpen>
116
+ <if=mobileMenuOpen>
133
117
  <div class="navbar-mobile-menu">
134
118
  <nav-bar/>
135
119
  </div>
@@ -138,10 +122,13 @@ class {
138
122
 
139
123
  <div class="layout-container">
140
124
  <!-- Sidebar (if provided) -->
141
- <aside class="sidebar" class-list={collapsed: !state.sidebarOpen}>
125
+ <aside class="sidebar" class-list={collapsed: !sidebarOpen}>
142
126
  <div class="sidebar-container">
143
127
  <!-- Collapse Button -->
144
- <button class="sidebar-toggle-btn" on-click('toggleSidebar') aria-label="Toggle sidebar">
128
+ <button class="sidebar-toggle-btn" onClick() {
129
+ sidebarOpen = !sidebarOpen;
130
+ localStorage.setItem('sidebar', sidebarOpen ? 'open' : 'closed');
131
+ } aria-label="Toggle sidebar">
145
132
  <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
146
133
  <polyline points="15 18 9 12 15 6"></polyline>
147
134
  </svg>
@@ -2,19 +2,13 @@
2
2
  * Documentation layout with sidebar and table of contents
3
3
  */
4
4
 
5
- class {
6
- onCreate() {
7
- this.state = {
8
- title: input.frontmatter?.title || 'Documentation',
9
- description: input.frontmatter?.description || '',
10
- headers: input.headers || [],
11
- editUrl: input.editUrl,
12
- lastUpdated: input.lastUpdated,
13
- prevPage: input.prevPage,
14
- nextPage: input.nextPage,
15
- };
16
- }
17
- }
5
+ <const/title=input.frontmatter?.title || 'Documentation'/>
6
+ <const/description=input.frontmatter?.description || ''/>
7
+ <const/headers=input.headers || []/>
8
+ <const/editUrl=input.editUrl/>
9
+ <const/lastUpdated=input.lastUpdated/>
10
+ <const/prevPage=input.prevPage/>
11
+ <const/nextPage=input.nextPage/>
18
12
 
19
13
  <!DOCTYPE html>
20
14
  <html lang="en">
@@ -22,9 +16,9 @@ class {
22
16
  <theme-head-top/>
23
17
  <meta charset="UTF-8">
24
18
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
25
- <title>${state.title}</title>
26
- <if=state.description>
27
- <meta name="description" content="${state.description}">
19
+ <title>${title}</title>
20
+ <if=description>
21
+ <meta name="description" content=description>
28
22
  </if>
29
23
  <theme-head-bottom/>
30
24
  </head>
@@ -54,22 +48,22 @@ class {
54
48
  <main id="main-content" class="docs-content">
55
49
  <theme-doc-top/>
56
50
  <article class="docs-article main-content">
57
- <h1>${state.title}</h1>
51
+ <h1>${title}</h1>
58
52
  <${input.renderBody()} />
59
53
  </article>
60
54
 
61
55
  <!-- Documentation Footer -->
62
56
  <doc-footer
63
- editUrl=state.editUrl
64
- lastUpdated=state.lastUpdated
65
- prev=state.prevPage
66
- next=state.nextPage/>
57
+ editUrl=editUrl
58
+ lastUpdated=lastUpdated
59
+ prev=prevPage
60
+ next=nextPage/>
67
61
 
68
62
  <theme-doc-bottom/>
69
63
  </main>
70
64
  <aside class="toc">
71
65
  <theme-aside-top/>
72
- <toc headers=state.headers/>
66
+ <toc headers=headers/>
73
67
  <theme-aside-bottom/>
74
68
  </aside>
75
69
  </div>
@@ -2,14 +2,8 @@
2
2
  * Default page layout
3
3
  */
4
4
 
5
- class {
6
- onCreate() {
7
- this.state = {
8
- title: input.frontmatter?.title || 'Page',
9
- description: input.frontmatter?.description || '',
10
- };
11
- }
12
- }
5
+ <const/title=input.frontmatter?.title || 'Page'/>
6
+ <const/description=input.frontmatter?.description || ''/>
13
7
 
14
8
  <!DOCTYPE html>
15
9
  <html lang="en">
@@ -17,9 +11,9 @@ class {
17
11
  <theme-head-top/>
18
12
  <meta charset="UTF-8">
19
13
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
20
- <title>${state.title}</title>
21
- <if=state.description>
22
- <meta name="description" content="${state.description}">
14
+ <title>${title}</title>
15
+ <if=description>
16
+ <meta name="description" content=description>
23
17
  </if>
24
18
  <theme-head-bottom/>
25
19
  </head>
@@ -37,7 +31,7 @@ class {
37
31
  <main class="content">
38
32
  <theme-page-top/>
39
33
  <article>
40
- <h1>${state.title}</h1>
34
+ <h1>${title}</h1>
41
35
  <${input.renderBody()} />
42
36
  </article>
43
37
  <theme-page-bottom/>
@@ -959,7 +959,6 @@ a.header-anchor {
959
959
  color: var(--color-primary-3);
960
960
  opacity: 0;
961
961
  transition: opacity var(--transition-fast);
962
-
963
962
  }
964
963
 
965
964
  h1:hover .header-anchor,
@@ -959,7 +959,6 @@ a.header-anchor {
959
959
  color: var(--color-primary-3);
960
960
  opacity: 0;
961
961
  transition: opacity var(--transition-fast);
962
-
963
962
  }
964
963
 
965
964
  h1:hover .header-anchor,
@@ -959,7 +959,6 @@ a.header-anchor {
959
959
  color: var(--color-primary-3);
960
960
  opacity: 0;
961
961
  transition: opacity var(--transition-fast);
962
-
963
962
  }
964
963
 
965
964
  h1:hover .header-anchor,
@@ -111,6 +111,7 @@ export async function GET(context, next) {
111
111
  context.lang = config.site.lang || 'en-US';
112
112
  context.siteHead = config.site.head || [];
113
113
  context.footer = config.theme.options.footer || null;
114
+ context.hasComponentStyles = !!(config.markdown?.markoTags?.enabled);
114
115
 
115
116
  context.title = frontmatter.title || slug;
116
117
  context.description = frontmatter.description || '';
@@ -11,7 +11,7 @@
11
11
  <meta name="theme-color" content="#3c8772">
12
12
  <link rel="stylesheet" href="{{BASE_PATH}}/_markopress/theme/theme-{{THEME_STYLE}}.css">
13
13
  <link rel="stylesheet" href="{{BASE_PATH}}/_markopress/theme/styles.css">
14
- <link rel="stylesheet" href="{{BASE_PATH}}/markopress-components.css">
14
+ {{COMPONENT_STYLES_LINK}}
15
15
  <theme-head-bottom/>
16
16
  </head>
17
17
  <body>
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-builder.d.ts","sourceRoot":"","sources":["../../../src/search/build/index-builder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAoB,YAAY,EAAE,MAAM,aAAa,CAAC;AAKlE,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,KAAK,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC,CAAC,EACF,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,MAAM,CAAC,CAyBjB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-builder.js","sourceRoot":"","sources":["../../../src/search/build/index-builder.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/search/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/search/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"search-client.d.ts","sourceRoot":"","sources":["../../../src/search/runtime/search-client.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhF,wBAAsB,UAAU,CAAC,QAAQ,SAAK,GAAG,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAoBrF;AAED,wBAAsB,MAAM,CAC1B,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,YAAY,EACrB,KAAK,SAAK,GACT,OAAO,CAAC,YAAY,EAAE,CAAC,CAuBzB;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAGvC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"search-client.js","sourceRoot":"","sources":["../../../src/search/runtime/search-client.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AAGpC,IAAI,WAAW,GAAwC,IAAI,CAAC;AAC5D,IAAI,WAAW,GAAiD,IAAI,CAAC;AAErE,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAQ,GAAG,EAAE;IAC5C,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IACpC,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IAEpC,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,oBAAoB,CAAC,CAAC,CAAC,oBAAoB,CAAC;IAEpF,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC;SAC3B,IAAI,CAAC,CAAC,CAAC,EAAE;QACR,IAAI,CAAC,CAAC,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QACvE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAClB,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,EAAE;QACX,WAAW,GAAG,UAAU,CAAC,QAAQ,CAAmB,IAAI,EAAE;YACxD,MAAM,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC;YACnC,WAAW,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC;SACxC,CAAC,CAAC;QACH,OAAO,WAAW,CAAC;IACrB,CAAC,CAAC,CAAC;IAEL,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,KAAa,EACb,MAAqB,EACrB,KAAK,GAAG,EAAE;IAEV,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,CAAC;IAE7B,MAAM,KAAK,GAAG,MAAM,UAAU,EAAE,CAAC;IAEjC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE;QAClC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,IAAI,GAAG;QACvC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,IAAI,IAAI;QAC1C,KAAK,EAAE;YACL,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;YAC5C,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC;YAC9C,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC;SAC3C;KACF,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC9C,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,KAAK,EAAE,MAAM,CAAC,KAAe;QAC7B,MAAM,EAAE,MAAM,CAAC,MAAkB;QACjC,IAAI,EAAG,MAAuC,CAAC,IAAI,IAAI,EAAE;QACzD,GAAG,EAAE,MAAM,CAAC,GAAa;QACzB,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC,CAAmB,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,WAAW,GAAG,IAAI,CAAC;IACnB,WAAW,GAAG,IAAI,CAAC;AACrB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/search/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/search/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAqB,MAAM,oBAAoB,CAAC"}