@beforesemicolon/builder 1.8.1 → 1.8.13

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.
Files changed (58) hide show
  1. package/README.md +839 -142
  2. package/dist/cjs/docs/markdown-layout/index.js +1 -0
  3. package/dist/cjs/docs/markdown-layout/marked-extension.js +1 -0
  4. package/dist/cjs/docs/markdown-layout/parser.js +7 -0
  5. package/dist/cjs/docs/markdown-layout/renderer.js +1 -0
  6. package/dist/cjs/docs/markdown-layout/types.js +1 -0
  7. package/dist/cjs/docs/run.js +76 -1
  8. package/dist/cjs/docs/templates/fading-citrus/README.md +770 -0
  9. package/dist/cjs/docs/templates/fading-citrus/assets/logo.svg +8 -0
  10. package/dist/cjs/docs/templates/fading-citrus/layouts/_code-snippet.js +53 -0
  11. package/dist/cjs/docs/templates/fading-citrus/layouts/_footer.js +7 -4
  12. package/dist/cjs/docs/templates/fading-citrus/layouts/_header.js +4 -4
  13. package/dist/cjs/docs/templates/fading-citrus/layouts/_layout-utils.js +89 -0
  14. package/dist/cjs/docs/templates/fading-citrus/layouts/document.js +7 -4
  15. package/dist/cjs/docs/templates/fading-citrus/layouts/landing-cta.js +30 -0
  16. package/dist/cjs/docs/templates/fading-citrus/layouts/landing-ecosystem.js +43 -0
  17. package/dist/cjs/docs/templates/fading-citrus/layouts/landing-features.js +25 -0
  18. package/dist/cjs/docs/templates/fading-citrus/layouts/landing-hero.js +81 -0
  19. package/dist/cjs/docs/templates/fading-citrus/layouts/landing-install.js +116 -0
  20. package/dist/cjs/docs/templates/fading-citrus/layouts/landing-showcase.js +125 -0
  21. package/dist/cjs/docs/templates/fading-citrus/layouts/landing.js +8 -618
  22. package/dist/cjs/docs/templates/fading-citrus/stylesheets/common.css +6 -4
  23. package/dist/cjs/docs/templates/fading-citrus/template.config.js +100 -1
  24. package/dist/cjs/docs/types.js +1 -1
  25. package/dist/esm/docs/markdown-layout/index.js +1 -0
  26. package/dist/esm/docs/markdown-layout/marked-extension.js +1 -0
  27. package/dist/esm/docs/markdown-layout/parser.js +7 -0
  28. package/dist/esm/docs/markdown-layout/renderer.js +1 -0
  29. package/dist/esm/docs/markdown-layout/types.js +0 -0
  30. package/dist/esm/docs/run.js +76 -1
  31. package/dist/esm/docs/templates/fading-citrus/README.md +770 -0
  32. package/dist/esm/docs/templates/fading-citrus/assets/logo.svg +8 -0
  33. package/dist/esm/docs/templates/fading-citrus/layouts/_code-snippet.js +53 -0
  34. package/dist/esm/docs/templates/fading-citrus/layouts/_footer.js +7 -4
  35. package/dist/esm/docs/templates/fading-citrus/layouts/_header.js +4 -4
  36. package/dist/esm/docs/templates/fading-citrus/layouts/_layout-utils.js +89 -0
  37. package/dist/esm/docs/templates/fading-citrus/layouts/document.js +7 -4
  38. package/dist/esm/docs/templates/fading-citrus/layouts/landing-cta.js +30 -0
  39. package/dist/esm/docs/templates/fading-citrus/layouts/landing-ecosystem.js +43 -0
  40. package/dist/esm/docs/templates/fading-citrus/layouts/landing-features.js +25 -0
  41. package/dist/esm/docs/templates/fading-citrus/layouts/landing-hero.js +81 -0
  42. package/dist/esm/docs/templates/fading-citrus/layouts/landing-install.js +116 -0
  43. package/dist/esm/docs/templates/fading-citrus/layouts/landing-showcase.js +125 -0
  44. package/dist/esm/docs/templates/fading-citrus/layouts/landing.js +8 -618
  45. package/dist/esm/docs/templates/fading-citrus/stylesheets/common.css +6 -4
  46. package/dist/esm/docs/templates/fading-citrus/template.config.js +100 -1
  47. package/dist/types/docs/markdown-layout/index.d.ts +4 -0
  48. package/dist/types/docs/markdown-layout/marked-extension.d.ts +8 -0
  49. package/dist/types/docs/markdown-layout/parser.d.ts +12 -0
  50. package/dist/types/docs/markdown-layout/renderer.d.ts +3 -0
  51. package/dist/types/docs/markdown-layout/types.d.ts +35 -0
  52. package/dist/types/docs/run.d.ts +12 -1
  53. package/dist/types/docs/types.d.ts +23 -0
  54. package/package.json +3 -2
  55. package/dist/cjs/docs/templates/fading-citrus/layouts/_copy-code.js +0 -50
  56. package/dist/cjs/docs/templates/fading-citrus/layouts/_logo.js +0 -31
  57. package/dist/esm/docs/templates/fading-citrus/layouts/_copy-code.js +0 -50
  58. package/dist/esm/docs/templates/fading-citrus/layouts/_logo.js +0 -31
@@ -341,7 +341,7 @@ footer .footer-brand {
341
341
  min-width: 280px;
342
342
  }
343
343
 
344
- footer .footer-brand svg {
344
+ footer .footer-brand .site-logo {
345
345
  margin-bottom: 16px;
346
346
  display: block;
347
347
  }
@@ -663,8 +663,10 @@ header.site-header .header-inner {
663
663
  justify-content: space-between;
664
664
  }
665
665
 
666
- header.site-header h1 a svg {
666
+ header.site-header h1 a .site-logo {
667
667
  height: 28px;
668
+ width: auto;
669
+ display: block;
668
670
  }
669
671
 
670
672
  header.site-header nav a {
@@ -704,10 +706,10 @@ header.site-header nav a.docs-github-link {
704
706
  gap: 40px;
705
707
  }
706
708
 
707
- .site-footer .footer-brand svg {
709
+ .site-footer .footer-brand .site-logo {
708
710
  height: 28px;
709
711
  width: auto;
710
- color: var(--foreground);
712
+ display: block;
711
713
  }
712
714
 
713
715
  .site-footer .footer-brand p {
@@ -1,6 +1,27 @@
1
- import { renderCodeBlock } from './layouts/_code-snippet.js'
1
+ import {
2
+ renderCodeBlock,
3
+ renderCodeCopyScript,
4
+ } from './layouts/_code-snippet.js'
5
+ import landingHero from './layouts/landing-hero.js'
6
+ import landingEcosystem from './layouts/landing-ecosystem.js'
7
+ import landingFeatures from './layouts/landing-features.js'
8
+ import landingShowcase, {
9
+ renderShowcaseScript,
10
+ } from './layouts/landing-showcase.js'
11
+ import landingInstall, {
12
+ renderInstallScript,
13
+ } from './layouts/landing-install.js'
14
+ import landingCta from './layouts/landing-cta.js'
2
15
 
3
16
  export default {
17
+ markdownLayouts: {
18
+ 'landing-hero': landingHero,
19
+ 'landing-ecosystem': landingEcosystem,
20
+ 'landing-features': landingFeatures,
21
+ 'landing-showcase': landingShowcase,
22
+ 'landing-install': landingInstall,
23
+ 'landing-cta': landingCta,
24
+ },
4
25
  markedOptions: {
5
26
  renderer: {
6
27
  code({ lang, raw }) {
@@ -11,4 +32,82 @@ export default {
11
32
  },
12
33
  },
13
34
  },
35
+ scripts: {
36
+ 'code-copy': {
37
+ match: 'code-copy-btn',
38
+ render: renderCodeCopyScript,
39
+ },
40
+ showcase: {
41
+ match: 'data-fading-citrus-showcase',
42
+ render: renderShowcaseScript,
43
+ },
44
+ install: {
45
+ match: 'data-fading-citrus-install',
46
+ render: renderInstallScript,
47
+ },
48
+ },
49
+ theme: {
50
+ light: {
51
+ '--background': 'oklch(0.98 0.006 250)',
52
+ '--foreground': 'oklch(0.18 0.015 250)',
53
+ '--card': 'oklch(1 0 0)',
54
+ '--primary': 'oklch(0.66 0.18 45)',
55
+ '--primary-glow': 'oklch(0.72 0.19 50)',
56
+ '--primary-foreground': 'oklch(0.98 0.006 250)',
57
+ '--secondary': 'oklch(0.93 0.01 250)',
58
+ '--muted': 'oklch(0.94 0.01 250)',
59
+ '--muted-foreground': 'oklch(0.42 0.02 250)',
60
+ '--accent': 'oklch(0.58 0.16 200)',
61
+ '--border': 'oklch(0.86 0.018 250)',
62
+ '--ring': 'oklch(0.66 0.18 45)',
63
+ '--code-bg': 'oklch(0.16 0.015 250)',
64
+ '--syntax-comment': 'oklch(0.55 0.02 250)',
65
+ '--syntax-keyword': 'oklch(0.78 0.19 50)',
66
+ '--syntax-string': 'oklch(0.78 0.15 145)',
67
+ '--syntax-tag': 'oklch(0.72 0.16 200)',
68
+ '--syntax-attr': 'oklch(0.82 0.14 90)',
69
+ '--gradient-hero':
70
+ 'radial-gradient(ellipse at top, oklch(0.86 0.08 45 / 0.35), transparent 60%)',
71
+ '--gradient-primary':
72
+ 'linear-gradient(135deg, var(--primary), var(--primary-glow))',
73
+ '--gradient-text':
74
+ 'linear-gradient(135deg, oklch(0.18 0.015 250), oklch(0.35 0.03 250))',
75
+ '--gradient-border':
76
+ 'linear-gradient(135deg, oklch(0.66 0.18 45 / 0.45), oklch(0.58 0.16 200 / 0.25))',
77
+ '--shadow-glow': '0 0 60px -15px oklch(0.66 0.18 45 / 0.35)',
78
+ '--shadow-card':
79
+ '0 1px 0 0 oklch(1 0 0 / 0.75) inset, 0 20px 40px -20px oklch(0.18 0.015 250 / 0.18)',
80
+ },
81
+ dark: {
82
+ '--background': 'oklch(0.18 0.015 250)',
83
+ '--foreground': 'oklch(0.96 0.005 250)',
84
+ '--card': 'oklch(0.22 0.018 250)',
85
+ '--primary': 'oklch(0.74 0.18 45)',
86
+ '--primary-glow': 'oklch(0.78 0.19 50)',
87
+ '--primary-foreground': 'oklch(0.18 0.02 250)',
88
+ '--secondary': 'oklch(0.27 0.02 250)',
89
+ '--muted': 'oklch(0.25 0.018 250)',
90
+ '--muted-foreground': 'oklch(0.68 0.02 250)',
91
+ '--accent': 'oklch(0.7 0.16 200)',
92
+ '--border': 'oklch(0.3 0.02 250)',
93
+ '--ring': 'oklch(0.74 0.18 45)',
94
+ '--code-bg': 'oklch(0.16 0.015 250)',
95
+ '--syntax-comment': 'oklch(0.55 0.02 250)',
96
+ '--syntax-keyword': 'oklch(0.78 0.19 50)',
97
+ '--syntax-string': 'oklch(0.78 0.15 145)',
98
+ '--syntax-tag': 'oklch(0.72 0.16 200)',
99
+ '--syntax-attr': 'oklch(0.82 0.14 90)',
100
+ '--gradient-hero':
101
+ 'radial-gradient(ellipse at top, oklch(0.28 0.08 45 / 0.35), transparent 60%)',
102
+ '--gradient-primary':
103
+ 'linear-gradient(135deg, var(--primary), var(--primary-glow))',
104
+ '--gradient-text':
105
+ 'linear-gradient(135deg, oklch(0.98 0.005 250), oklch(0.78 0.05 250))',
106
+ '--gradient-border':
107
+ 'linear-gradient(135deg, oklch(0.74 0.18 45 / 0.5), oklch(0.7 0.16 200 / 0.3))',
108
+ '--shadow-glow': '0 0 60px -15px oklch(0.74 0.18 45 / 0.5)',
109
+ '--shadow-card':
110
+ '0 1px 0 0 oklch(1 0 0 / 0.05) inset, 0 20px 40px -20px oklch(0 0 0 / 0.5)',
111
+ },
112
+ },
14
113
  }
@@ -1 +1 @@
1
- "use strict";var r=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var o=Object.prototype.hasOwnProperty;var p=(n,t,s,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of g(t))!o.call(n,e)&&e!==s&&r(n,e,{get:()=>t[e],enumerable:!(i=a(t,e))||i.enumerable});return n};var l=n=>p(r({},"__esModule",{value:!0}),n);var u={};module.exports=l(u);
1
+ "use strict";var i=Object.defineProperty;var s=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var g=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of a(t))!p.call(e,r)&&r!==o&&i(e,r,{get:()=>t[r],enumerable:!(n=s(t,r))||n.enumerable});return e};var c=e=>g(i({},"__esModule",{value:!0}),e);var m={};module.exports=c(m);
@@ -0,0 +1 @@
1
+ export*from"./marked-extension.js";export*from"./parser.js";export*from"./renderer.js";export*from"./types.js";
@@ -0,0 +1 @@
1
+ var s=Object.defineProperty;var u=(t,e)=>s(t,"name",{value:e,configurable:!0});import{parseLayoutBlock as i,readLayoutBlock as y}from"./parser.js";import{renderDefaultMarkdownLayout as M,renderMarkdownLayout as w}from"./renderer.js";const N=u(({marked:t,handlers:e={},renderMarkdown:d})=>({extensions:[{name:"markdownLayout",level:"block",start(o){return o.match(/^::: layout /m)?.index},tokenizer(o){const n=y(o);if(n)return{...i(n),type:"markdownLayout",raw:n}},renderer(o){const n=o,a={marked:t,renderMarkdown(r){return d?d(r):t.parse(r)},renderDefault(r){return M(r,a)},renderParts(r){return r.items.map(k=>({...k,html:a.renderMarkdown(k.body)}))}};return w(n,a,e)}}]}),"createMarkdownLayoutExtension");export{N as createMarkdownLayoutExtension};
@@ -0,0 +1,7 @@
1
+ var m=Object.defineProperty;var i=(n,t)=>m(n,"name",{value:t,configurable:!0});const a=/^::: layout(?:\s+.*)?$/,l=/^:::\s*$/,y=/^===(?:\s+.*)?$/,f=i(n=>{const t=n.replace(/^(['"])(.*)\1$/,"$2");return/^-?\d+(\.\d+)?$/.test(t)?Number(t):t==="true"?!0:t==="false"?!1:t},"coerceOptionValue"),c=i((n="")=>{const t=[],e=/\S+=("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|\S*)|"[^"]*"|'[^']*'|\S+/g;let r;for(;r=e.exec(n);)t.push(r[0]);return t},"tokenizeOptions"),d=i((n="")=>c(n).reduce((t,e)=>{const r=e.indexOf("=");if(r===-1)return t[e]=!0,t;const o=e.slice(0,r).trim(),s=e.slice(r+1).trim();return o&&(t[o]=f(s)),t},{}),"parseOptions"),h=i(n=>{const t=n.replace(/^:::\s*layout\s*/,"").trim(),[e="",...r]=c(t);if(!e)throw new Error(`Invalid layout header: ${n}`);return{layoutType:e,options:d(r.join(" "))}},"parseLayoutHeader"),w=i(n=>{const t=n.replace(/^===\s*/,"").trim();if(!t)return{name:null,options:{}};const[e=null,...r]=c(t);return{name:e,options:d(r.join(" "))}},"parseItemHeader"),L=i(n=>{const t=n.split(`
2
+ `),e=[];let r=0,o=null,s=[];const p=i(()=>{o&&(e.push({...o,body:s.join(`
3
+ `).trim()}),s=[])},"pushCurrent");for(const u of t){if(a.test(u.trim())){o&&s.push(u),r+=1;continue}if(l.test(u.trim())&&r>0){r-=1,o&&s.push(u);continue}if(r===0&&y.test(u.trim())){p(),o=w(u.trim());continue}o&&s.push(u)}return p(),e.length?e:[{name:null,options:{},body:n.trim()}]},"splitLayoutItems"),$=i(n=>{const t=n.replace(/\s+$/,"").split(`
4
+ `),e=t.shift();if(!e||!a.test(e.trim()))throw new Error("Layout block must start with `::: layout`.");return t.length&&l.test(t[t.length-1].trim())&&t.pop(),{...h(e.trim()),items:L(t.join(`
5
+ `)),raw:n}},"parseLayoutBlock"),N=i(n=>{if(!n.startsWith("::: layout"))return null;const t=n.split(`
6
+ `);let e=0;const r=[];for(const o of t){const s=o.trim();if(r.push(o),a.test(s))e+=1;else if(l.test(s)&&(e-=1,e===0))return r.join(`
7
+ `)}return null},"readLayoutBlock");export{w as parseItemHeader,$ as parseLayoutBlock,h as parseLayoutHeader,d as parseOptions,N as readLayoutBlock};
@@ -0,0 +1 @@
1
+ var u=Object.defineProperty;var r=(t,o)=>u(t,"name",{value:o,configurable:!0});const s=r(t=>String(t).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;"),"escapeAttribute"),l=r(t=>`--${t.replace(/[A-Z]/g,o=>`-${o.toLowerCase()}`)}`,"optionToStyleName"),y=r(t=>{const o=Object.entries(t).filter(([,a])=>typeof a!="boolean").map(([a,e])=>`${l(a)}: ${e};`);return o.length?` style="${s(o.join(" "))}"`:""},"optionsToStyle"),M=r((t,o)=>{const a=s(t.layoutType),e=t.items.map(n=>`<section class="bfs-layout-item"${n.name?` data-name="${s(n.name)}"`:""}${y(n.options)}>${o.renderMarkdown(n.body)}</section>`).join("");return`<div class="bfs-layout bfs-layout-${a}" data-layout="${a}"${y(t.options)}>${e}</div>`},"renderDefaultMarkdownLayout"),$=r((t,o,a={})=>{const e=a[t.layoutType];return e?e({type:t.layoutType,options:t.options,parts:o.renderParts(t),raw:t.raw},o):o.renderDefault(t)},"renderMarkdownLayout");export{M as renderDefaultMarkdownLayout,$ as renderMarkdownLayout};
File without changes
@@ -1 +1,76 @@
1
- var J=Object.defineProperty;var S=(a,c)=>J(a,"name",{value:c,configurable:!0});import{Marked as U}from"marked";import{cp as W,mkdir as v,readdir as G,readFile as b,writeFile as C}from"fs/promises";import s from"path";import H from"front-matter";import Q from"isomorphic-dompurify";import{markedHighlight as q}from"marked-highlight";import N from"highlight.js";import I from"./templates/default.template.js";import K from"./renderer/index.js";import V from"clean-css";import X from"html-minifier";import*as Y from"@putout/minify";import{fileURLToPath as Z,pathToFileURL as R}from"url";import p from"fs";let _;const tt=new V({inline:["none"]}),F=new Map;F.set("default",I);let E;const g=new U(q({langPrefix:"hljs language-",highlight(a,c){const l=N.getLanguage(c)?c:"plaintext";return N.highlight(a,{language:l}).value}}));g.use({renderer:K});const d=S(async a=>{const c=await G(a),l=[];for(const i of c){const f=s.extname(i);/^[._]/.test(i)||(f?l.push(s.join(a,i)):/(stylesheets|assets|scripts)/.test(i)||l.push(...await d(s.join(a,i))))}return l},"traverseDirectory");g.use({hooks:{postprocess(a){const{layout:c="default",...l}=E.attributes;a=Q.sanitize(a);const i=[...a.matchAll(/<h([0-6])\sid="[^"]+".*?>.*?<a\s+href="([^"]+)".*?>([^<]+)<\/a>/gm)].map(f=>({path:f[2],label:f[3],level:f[1]}));return F.get(c)?.({...l,content:a,siteMap:E.siteMap,tableOfContent:i,projectMeta:_})||a}}});const vt=S(async({srcDir:a,publicDir:c,markedOptions:l,template:i}={})=>{try{const t=s.resolve(process.cwd(),"package.json");p.existsSync(t)&&(_=JSON.parse(await b(t,"utf-8")))}catch(t){console.warn("Failed to load project package.json metadata",t)}const f=S(()=>{try{return __dirname}catch{return s.dirname(Z(import.meta.url))}},"getDirname"),m=i?s.resolve(f(),"templates",i):null,M=m?s.resolve(m,"assets"):null,D=m?s.resolve(m,"stylesheets"):null,j=m?s.resolve(m,"layouts"):null;if(m)try{let t=s.resolve(m,"template.config.js");if(p.existsSync(t)||(t=t.replace(/\.js$/,".ts")),p.existsSync(t)){const e=await import(R(t).href),r=e.default||e;r.markedOptions&&g.use(r.markedOptions)}}catch(t){console.error(`Failed to load template config for ${i}`,t)}l&&g.use(l);const o=a??s.resolve(process.cwd(),"docs"),u=c??s.resolve(process.cwd(),"website"),A=s.resolve(o,"_layouts"),w=s.resolve(o,"assets"),L=s.resolve(o,"stylesheets"),x=s.resolve(o,"scripts");if(await v(u,{recursive:!0}),M&&p.existsSync(M))try{await W(M,w.replace(o,u),{recursive:!0})}catch(t){console.warn(t)}if(p.existsSync(w))try{await W(w,w.replace(o,u),{recursive:!0})}catch(t){console.warn(t)}try{const t=new Set;if(D&&p.existsSync(D)&&(await d(D)).forEach(e=>t.add(e)),p.existsSync(L)&&(await d(L)).forEach(e=>t.add(e)),t.size){await v(s.join(u,"stylesheets"),{recursive:!0});for(const e of t){const r=await b(e,"utf-8"),n=tt.minify(r);n.errors.length&&n.errors.forEach(console.error);const h=e.startsWith(o)?e.replace(o,u):s.join(u,"stylesheets",s.basename(e));await C(h,n.styles??r)}}}catch(t){console.error(t)}if(p.existsSync(x))try{const t=await d(x);t.length&&await v(x.replace(o,u),{recursive:!0});for(const e of t)try{const r=await b(e,"utf-8");await C(e.replace(o,u),Y.minify(r))}catch(r){console.error(r)}}catch(t){console.warn(t)}try{const t=new Map;j&&p.existsSync(j)&&(await d(j)).forEach(e=>{/\.(j|t)s$/.test(e)&&t.set(s.basename(e).replace(/\.(j|t)s$/,""),e)}),p.existsSync(A)&&(await d(A)).forEach(e=>{/\.(j|t)s$/.test(e)&&t.set(s.basename(e).replace(/\.(j|t)s$/,""),e)});for(const[e,r]of t.entries()){const n=await import(R(r).href);F.set(e,n.default)}}catch(t){console.error("Template import failed",t)}const B=await d(o),T=new Map;(await Promise.all(B.filter(t=>t.endsWith(".md")).map(async t=>{const e=await b(t,"utf-8");return{filePath:t,...H(e)}}))).sort((t,e)=>(t.attributes.order??0)-(e.attributes.order??0)).map(({attributes:t,body:e,filePath:r})=>{const n=r.replace(o,"").replace(/\.md/,".html"),h=r.replace(o,u).replace(".md",".html"),P=h.replace(s.basename(h),""),k=s.basename(n)||"/",z=n.replace(k,"").replace(/\/$/,"");let y=T;z.split("/").filter(Boolean).forEach(O=>{y.has(O)||y.set(O,new Map),y=y.get(O)});const $={...t,path:n};return y.has(k)||y.set(k,$),{attributes:$,fileWebsitePath:h,fileDirWebsitePath:P,body:e,siteMap:T}}).forEach(async({attributes:t,body:e,fileDirWebsitePath:r,fileWebsitePath:n,siteMap:h})=>{E={attributes:t,siteMap:h};const P=await g.parse(e);await v(r,{recursive:!0}),await C(n,X.minify(P,{includeAutoGeneratedTags:!0,removeAttributeQuotes:!0,removeComments:!0,removeRedundantAttributes:!0,removeScriptTypeAttributes:!0,removeStyleLinkTypeAttributes:!0,sortClassName:!0,useShortDoctype:!0,collapseWhitespace:!0,minifyJS:!0,minifyCSS:!0}))})},"buildDocs");export{vt as buildDocs};
1
+ var ne=Object.defineProperty;var c=(e,t)=>ne(e,"name",{value:t,configurable:!0});import{Marked as ae}from"marked";import{cp as F,mkdir as v,readdir as ie,readFile as j,writeFile as x}from"fs/promises";import o from"path";import le from"front-matter";import ce from"isomorphic-dompurify";import{markedHighlight as me}from"marked-highlight";import Q from"highlight.js";import ue from"./templates/default.template.js";import fe from"./renderer/index.js";import{createMarkdownLayoutExtension as pe}from"./markdown-layout/index.js";import de from"clean-css";import he from"html-minifier";import*as X from"@putout/minify";import{fileURLToPath as ge,pathToFileURL as A}from"url";import f from"fs";let K;const V=new de({inline:["none"]}),R=new Map;R.set("default",ue);let W;const Y=c((e,t)=>t===!1?!1:t===void 0?e:e===!1||e===void 0?t:{...e,...t},"mergeThemeMode"),ye=c((e,t)=>{if(!(!e&&!t))return{light:Y(e?.light,t?.light),dark:Y(e?.dark,t?.dark)}},"mergeTheme"),we=c((e,t)=>({...e,...t,markdownLayouts:{...e.markdownLayouts,...t.markdownLayouts},scripts:{...e.scripts,...t.scripts},theme:ye(e.theme,t.theme)}),"mergeTemplateConfig"),ve=c((e,t)=>{if(typeof e=="function")return!0;const{match:r}=e;return r?typeof r=="string"?t.includes(r):Array.isArray(r)?r.some(n=>t.includes(n)):r instanceof RegExp?r.test(t):r(t):!0},"scriptMatches"),De=c((e,t)=>e?Object.values(e).filter(r=>r!==!1).filter(r=>ve(r,t)).map(r=>typeof r=="function"?r():r.render()):[],"renderPageScripts"),G=c((e,t)=>{const r=Object.entries(t).filter(([n])=>n.startsWith("--")).map(([n,l])=>` ${n}: ${l};`).join(`
2
+ `);return r?`${e} {
3
+ ${r}
4
+ }`:""},"renderThemeBlock"),Se=c(e=>{if(!e)return"";const t=e.light===!1,r=e.light===!1?void 0:e.light,n=e.dark===!1?void 0:e.dark,l=r||n;return l?[G(":root",l),n&&!t?`@media (prefers-color-scheme: dark) {
5
+ ${G(" :root",n)}
6
+ }`:"",r?G('[data-theme="light"]',r):"",n?G('[data-theme="dark"]',n):""].filter(Boolean).join(`
7
+
8
+ `):""},"renderThemeStylesheet"),xe=c((e="")=>String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;"),"escapeXML"),be=c((e="")=>e.replace(/```[\s\S]*?```/g," ").replace(/`([^`]+)`/g,"$1").replace(/!\[[^\]]*]\([^)]*\)/g," ").replace(/\[([^\]]+)]\([^)]*\)/g,"$1").replace(/^#{1,6}\s+/gm,"").replace(/^---+$/gm," ").replace(/[>*_~]/g,"").replace(/\s+/g," ").trim(),"stripMarkdown"),$e=c(e=>e==="/index.html"?"/":e.replace(/\/index\.html$/,"/").replace(/\.html$/,"").replace(/\/+/g,"/"),"pagePathToUrlPath"),Z=c((e,t)=>e?`${e.replace(/\/$/,"")}${t==="/"?"/":t}`:t,"canonicalUrl"),Pe=c(async(e,t)=>f.existsSync(e)?(await v(o.dirname(t),{recursive:!0}),await F(e,t),!0):!1,"copyIfExists"),Te=c(e=>{const t={sitemap:!0,robots:!0,llms:!0,llmsFull:!0,netlify:!1};return e===!1?{sitemap:!1,robots:!1,llms:!1,llmsFull:!1,netlify:!1}:e===!0||e===void 0?t:{...t,...e}},"normalizeGeneratedFilesConfig"),ke=c((e,t)=>{if(!t)return"";const r=new Date().toISOString().slice(0,10);return`<?xml version="1.0" encoding="UTF-8"?>
9
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
10
+ ${e.map(l=>{const m=l.urlPath==="/"?"1.0":"0.8";return` <url>
11
+ <loc>${xe(Z(t,l.urlPath))}</loc>
12
+ <lastmod>${r}</lastmod>
13
+ <changefreq>weekly</changefreq>
14
+ <priority>${m}</priority>
15
+ </url>`}).join(`
16
+ `)}
17
+ </urlset>
18
+ `},"generateSitemap"),Me=c(e=>`User-agent: *
19
+ Allow: /
20
+ ${e?`
21
+ Sitemap: ${e.replace(/\/$/,"")}/sitemap.xml
22
+ Host: ${e.replace(/\/$/,"")}
23
+ `:""}
24
+ `,"generateRobots"),je=c(e=>`# Documentation
25
+
26
+ ## Page index
27
+
28
+ ${e.map(t=>`- ${t.name}: ${t.urlPath} - ${t.description}`).join(`
29
+ `)}
30
+ `,"generateLlms"),Ce=c((e,t)=>`# Documentation for AI agents
31
+
32
+ This file is generated at build time from the Markdown documentation. Use it to choose the most relevant page before reading the canonical HTML documentation.
33
+
34
+ ${e.map(r=>`## ${r.title}
35
+
36
+ URL: ${Z(t,r.urlPath)}
37
+ Source: docs/${r.sourcePath}
38
+ Description: ${r.description}
39
+
40
+ ${r.summary||r.description}
41
+ `).join(`
42
+ `)}
43
+ `,"generateLlmsFull"),Fe=c((e,t)=>{const r=["# Generated by @beforesemicolon/builder"];return[t.llms?"llms.txt":"",t.llmsFull?"llms-full.txt":"",t.sitemap?"sitemap.xml":"",t.robots?"robots.txt":""].filter(Boolean).forEach(l=>r.push(`/${l} /${l} 200`)),e.forEach(l=>{if(l.urlPath==="/")return;const m=l.urlPath.endsWith("/")?`${l.urlPath}index.html`:`${l.urlPath}.html`;r.push(`${l.urlPath} ${m} 200`),l.urlPath.endsWith("/")&&r.push(`${l.urlPath.replace(/\/$/,"")} ${m} 200`)}),`${[...new Set(r)].join(`
44
+ `)}
45
+ `},"generateNetlifyRedirects"),Ge=c(e=>`[build]
46
+ command = "node build-docs.js"
47
+ publish = "${e||"website"}"
48
+
49
+ [[headers]]
50
+ for = "/llms.txt"
51
+
52
+ [headers.values]
53
+ Content-Type = "text/plain; charset=utf-8"
54
+ Cache-Control = "public, max-age=0, must-revalidate"
55
+
56
+ [[headers]]
57
+ for = "/llms-full.txt"
58
+
59
+ [headers.values]
60
+ Content-Type = "text/plain; charset=utf-8"
61
+ Cache-Control = "public, max-age=0, must-revalidate"
62
+
63
+ [[headers]]
64
+ for = "/sitemap.xml"
65
+
66
+ [headers.values]
67
+ Content-Type = "application/xml; charset=utf-8"
68
+ Cache-Control = "public, max-age=0, must-revalidate"
69
+
70
+ [[headers]]
71
+ for = "/robots.txt"
72
+
73
+ [headers.values]
74
+ Content-Type = "text/plain; charset=utf-8"
75
+ Cache-Control = "public, max-age=0, must-revalidate"
76
+ `,"generateNetlifyToml"),b=c(async(e,t,r,n)=>{if(await Pe(e,t))return;const l=r();if(!l){n&&console.warn(n);return}await v(o.dirname(t),{recursive:!0}),await x(t,l)},"writeGeneratedFile"),Ee=c(async({docsDir:e,docsSiteDir:t,pages:r,siteUrl:n,publicDir:l,generatedFiles:m})=>{m.sitemap&&await b(o.resolve(e,"sitemap.xml"),o.resolve(t,"sitemap.xml"),()=>ke(r,n),"Skipping generated sitemap.xml because buildDocs({ siteUrl }) is not set."),m.robots&&await b(o.resolve(e,"robots.txt"),o.resolve(t,"robots.txt"),()=>Me(n)),m.llms&&await b(o.resolve(e,"llms.txt"),o.resolve(t,"llms.txt"),()=>je(r)),m.llmsFull&&await b(o.resolve(e,"llms-full.txt"),o.resolve(t,"llms-full.txt"),()=>Ce(r,n)),m.netlify&&(await b(o.resolve(e,"_redirects"),o.resolve(t,"_redirects"),()=>Fe(r,m)),await b(o.resolve(e,"netlify.toml"),o.resolve(t,"netlify.toml"),()=>Ge(l&&o.basename(l))))},"writeGeneratedDocsFiles"),ee=c((e={},t,r)=>{const n=new ae(me({langPrefix:"hljs language-",highlight(l,m){const $=Q.getLanguage(m)?m:"plaintext";return Q.highlight(l,{language:$}).value}}));return n.use({renderer:fe}),n.use(pe({marked:n,handlers:e.markdownLayouts,renderMarkdown:r})),e.markedOptions&&n.use(e.markedOptions),t&&n.use(t),n},"createBaseMarked"),Le=c((e={},t)=>{const r=ee(e,t),n=c(m=>r.parse(m),"renderMarkdown"),l=ee(e,t,n);return l.use({hooks:{postprocess(m){const{layout:$="default",...g}=W.attributes,P=De(e.scripts,m);m=ce.sanitize(m);const T=[...m.matchAll(/<h([0-6])\sid="[^"]+".*?>.*?<a\s+href="([^"]+)".*?>([^<]+)<\/a>/gm)].map(D=>({path:D[2],label:D[3],level:D[1]}));return R.get($)?.({...g,content:m,siteMap:W.siteMap,tableOfContent:T,projectMeta:K,renderMarkdown:n,scripts:P,themeStylesheet:e.theme?"/stylesheets/theme.css":void 0})||m}}}),l},"createMarked"),y=c(async e=>{const t=await ie(e),r=[];for(const n of t){const l=o.extname(n);/^[._]/.test(n)||(l?r.push(o.join(e,n)):/(stylesheets|assets|scripts)/.test(n)||r.push(...await y(o.join(e,n))))}return r},"traverseDirectory"),at=c(async({srcDir:e,publicDir:t,markedOptions:r,template:n,siteUrl:l,generatedFiles:m}={})=>{try{const s=o.resolve(process.cwd(),"package.json");f.existsSync(s)&&(K=JSON.parse(await j(s,"utf-8")))}catch(s){console.warn("Failed to load project package.json metadata",s)}const $=c(()=>{try{return __dirname}catch{return o.dirname(ge(import.meta.url))}},"getDirname"),g=n?o.resolve($(),"templates",n):null,P=g?o.resolve(g,"assets"):null,T=g?o.resolve(g,"stylesheets"):null,D=g?o.resolve(g,"layouts"):null;let k={};if(g)try{let s=o.resolve(g,"template.config.js");if(f.existsSync(s)||(s=s.replace(/\.js$/,".ts")),f.existsSync(s)){const a=await import(A(s).href);k=a.default||a}}catch(s){console.error(`Failed to load template config for ${n}`,s)}const p=e??o.resolve(process.cwd(),"docs"),u=t??o.resolve(process.cwd(),"website"),te=Te(m),w=o.resolve(p,"_template"),_=o.resolve(w,"assets"),B=o.resolve(w,"stylesheets"),N=o.resolve(w,"scripts"),U=o.resolve(w,"layouts"),z=o.resolve(p,"_layouts"),C=o.resolve(p,"assets"),q=o.resolve(p,"stylesheets"),E=o.resolve(p,"scripts");try{let s=o.resolve(w,"template.config.js");if(f.existsSync(s)||(s=s.replace(/\.js$/,".ts")),f.existsSync(s)){const a=await import(A(s).href),i=a.default||a;k=we(k,i)}}catch(s){console.error("Failed to load docs _template config",s)}const se=Le(k,r);if(await v(u,{recursive:!0}),P&&f.existsSync(P))try{await F(P,C.replace(p,u),{recursive:!0})}catch(s){console.warn(s)}if(f.existsSync(C))try{await F(C,C.replace(p,u),{recursive:!0})}catch(s){console.warn(s)}if(f.existsSync(_))try{await F(_,o.resolve(u,"assets"),{recursive:!0})}catch(s){console.warn(s)}try{const s=new Set;if(T&&f.existsSync(T)&&(await y(T)).forEach(i=>s.add(i)),f.existsSync(q)&&(await y(q)).forEach(i=>s.add(i)),f.existsSync(B)&&(await y(B)).forEach(i=>s.add(i)),s.size){await v(o.join(u,"stylesheets"),{recursive:!0});for(const i of s){const d=await j(i,"utf-8"),h=V.minify(d);h.errors.length&&h.errors.forEach(console.error);const M=i.startsWith(w)?i.replace(w,u):i.startsWith(p)?i.replace(p,u):o.join(u,"stylesheets",o.basename(i));await x(M,h.styles??d)}}const a=Se(k.theme);if(a){const i=V.minify(a);i.errors.length&&i.errors.forEach(console.error),await v(o.join(u,"stylesheets"),{recursive:!0}),await x(o.join(u,"stylesheets","theme.css"),i.styles??a)}}catch(s){console.error(s)}if(f.existsSync(E))try{const s=await y(E);s.length&&await v(E.replace(p,u),{recursive:!0});for(const a of s)try{const i=await j(a,"utf-8");await x(a.replace(p,u),X.minify(i))}catch(i){console.error(i)}}catch(s){console.warn(s)}if(f.existsSync(N))try{const s=await y(N);s.length&&await v(o.join(u,"scripts"),{recursive:!0});for(const a of s)try{const i=await j(a,"utf-8");await x(a.replace(w,u),X.minify(i))}catch(i){console.error(i)}}catch(s){console.warn(s)}try{const s=new Map;D&&f.existsSync(D)&&(await y(D)).forEach(a=>{/\.(j|t)s$/.test(a)&&s.set(o.basename(a).replace(/\.(j|t)s$/,""),a)}),f.existsSync(z)&&(await y(z)).forEach(a=>{/\.(j|t)s$/.test(a)&&s.set(o.basename(a).replace(/\.(j|t)s$/,""),a)}),f.existsSync(U)&&(await y(U)).forEach(a=>{/\.(j|t)s$/.test(a)&&s.set(o.basename(a).replace(/\.(j|t)s$/,""),a)});for(const[a,i]of s.entries()){const d=await import(A(i).href);R.set(a,d.default)}}catch(s){console.error("Template import failed",s)}const re=await y(p),H=new Map,I=(await Promise.all(re.filter(s=>s.endsWith(".md")).map(async s=>{const a=await j(s,"utf-8");return{filePath:s,...le(a)}}))).sort((s,a)=>(s.attributes.order??0)-(a.attributes.order??0)).map(({attributes:s,body:a,filePath:i})=>{const d=i.replace(p,"").replace(/\.md/,".html"),h=i.replace(p,u).replace(".md",".html"),M=h.replace(o.basename(h),""),L=o.basename(d)||"/",oe=d.replace(L,"").replace(/\/$/,"");let S=H;oe.split("/").filter(Boolean).forEach(O=>{S.has(O)||S.set(O,new Map),S=S.get(O)});const J={...s,path:d};return S.has(L)||S.set(L,J),{attributes:J,fileWebsitePath:h,fileDirWebsitePath:M,body:a,sourcePath:o.relative(p,i),siteMap:H}});for(const{attributes:s,body:a,fileDirWebsitePath:i,fileWebsitePath:d,siteMap:h}of I){W={attributes:s,siteMap:h};const M=await se.parse(a);await v(i,{recursive:!0}),await x(d,he.minify(M,{includeAutoGeneratedTags:!0,removeAttributeQuotes:!0,removeComments:!0,removeRedundantAttributes:!0,removeScriptTypeAttributes:!0,removeStyleLinkTypeAttributes:!0,sortClassName:!0,useShortDoctype:!0,collapseWhitespace:!0,minifyJS:!0,minifyCSS:!0}))}await Ee({docsDir:p,docsSiteDir:u,pages:I.map(({attributes:s,body:a,sourcePath:i})=>{const d=$e(String(s.path)),h=be(a);return{sourcePath:i,urlPath:d,title:String(s.title||s.name||"").trim()||"Documentation",name:String(s.name||s.title||"").trim()||"Documentation",description:String(s.description||"").trim()||h.slice(0,156)||"Documentation page.",order:Number(s.order??999),summary:h.slice(0,320)}}),siteUrl:l,publicDir:u,generatedFiles:te})},"buildDocs");export{at as buildDocs};