@beforesemicolon/builder 1.8.22 → 1.8.23
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 +13 -3
- package/dist/cjs/docs/run.js +5 -5
- package/dist/cjs/docs/templates/fading-citrus/README.md +1 -1
- package/dist/cjs/docs/templates/fading-citrus/layouts/_head-meta.js +0 -16
- package/dist/cjs/docs/templates/fading-citrus/layouts/document.js +1 -0
- package/dist/cjs/docs/templates/fading-citrus/layouts/landing.js +1 -0
- package/dist/esm/docs/run.js +5 -5
- package/dist/esm/docs/templates/fading-citrus/README.md +1 -1
- package/dist/esm/docs/templates/fading-citrus/layouts/_head-meta.js +0 -16
- package/dist/esm/docs/templates/fading-citrus/layouts/document.js +1 -0
- package/dist/esm/docs/templates/fading-citrus/layouts/landing.js +1 -0
- package/dist/types/docs/types.d.ts +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -306,6 +306,7 @@ export default {
|
|
|
306
306
|
meta: {},
|
|
307
307
|
markedOptions: {},
|
|
308
308
|
markdownLayouts: {},
|
|
309
|
+
headScripts: {},
|
|
309
310
|
scripts: {},
|
|
310
311
|
theme: {
|
|
311
312
|
light: {},
|
|
@@ -319,7 +320,7 @@ Config from `docs/_template/template.config.js` is merged into the selected temp
|
|
|
319
320
|
Merge behavior:
|
|
320
321
|
|
|
321
322
|
- `markdownLayouts` are shallow-merged by layout name.
|
|
322
|
-
- `scripts` are shallow-merged by script name.
|
|
323
|
+
- `headScripts` and `scripts` are shallow-merged by script name.
|
|
323
324
|
- `meta` is shallow-merged by metadata field.
|
|
324
325
|
- `theme.light` and `theme.dark` are shallow-merged by CSS variable name.
|
|
325
326
|
- Other top-level config values use the docs source config value when provided.
|
|
@@ -602,6 +603,8 @@ export default {
|
|
|
602
603
|
}
|
|
603
604
|
```
|
|
604
605
|
|
|
606
|
+
Use `headScripts` for scripts that must render in `<head>`, such as analytics bootstrap tags. Use `scripts` for scripts that can render near `</body>`, such as interaction handlers.
|
|
607
|
+
|
|
605
608
|
Script definitions:
|
|
606
609
|
|
|
607
610
|
```ts
|
|
@@ -632,12 +635,15 @@ Behavior:
|
|
|
632
635
|
- A function matcher receives the rendered page HTML and returns a boolean.
|
|
633
636
|
- A script can be disabled by setting its registry value to `false` in an extending config.
|
|
634
637
|
|
|
635
|
-
Layouts receive scripts through `props.
|
|
638
|
+
Layouts receive scripts through `props.headScripts` and `props.scripts`. Template layouts must insert them where appropriate.
|
|
636
639
|
|
|
637
640
|
```js
|
|
638
641
|
export default (props) => `
|
|
639
642
|
<!doctype html>
|
|
640
643
|
<html>
|
|
644
|
+
<head>
|
|
645
|
+
${props.headScripts?.join('') || ''}
|
|
646
|
+
</head>
|
|
641
647
|
<body>
|
|
642
648
|
${props.content}
|
|
643
649
|
${props.scripts?.join('') || ''}
|
|
@@ -802,8 +808,12 @@ export default {
|
|
|
802
808
|
markdownLayouts: {
|
|
803
809
|
'pricing-cards': pricingCards,
|
|
804
810
|
},
|
|
811
|
+
headScripts: {
|
|
812
|
+
analytics: () =>
|
|
813
|
+
`<script async src="https://example.com/analytics.js"></script>`,
|
|
814
|
+
},
|
|
805
815
|
scripts: {
|
|
806
|
-
|
|
816
|
+
pageView: {
|
|
807
817
|
match: '<main',
|
|
808
818
|
render: () => `<script>console.log('page viewed')</script>`,
|
|
809
819
|
},
|
package/dist/cjs/docs/run.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var ge=Object.create;var C=Object.defineProperty;var ye=Object.getOwnPropertyDescriptor;var we=Object.getOwnPropertyNames;var ve=Object.getPrototypeOf,Se=Object.prototype.hasOwnProperty;var m=(e,t)=>C(e,"name",{value:t,configurable:!0});var De=(e,t)=>{for(var r in t)C(e,r,{get:t[r],enumerable:!0})},Q=(e,t,r,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of we(t))!Se.call(e,n)&&n!==r&&C(e,n,{get:()=>t[n],enumerable:!(a=ye(t,n))||a.enumerable});return e};var v=(e,t,r)=>(r=e!=null?ge(ve(e)):{},Q(t||!e||!e.__esModule?C(r,"default",{value:e,enumerable:!0}):r,e)),be=e=>Q(C({},"__esModule",{value:!0}),e);var Ue={};De(Ue,{buildDocs:()=>Ne});module.exports=be(Ue);const ze={};var re=require("marked"),c=require("fs/promises"),o=v(require("path"),1),oe=v(require("front-matter"),1),ae=v(require("isomorphic-dompurify"),1),ne=require("marked-highlight"),_=v(require("highlight.js"),1),ie=v(require("./templates/default.template.js"),1),le=v(require("./renderer/index.js"),1),ce=require("./markdown-layout/index.js"),me=v(require("clean-css"),1),ue=v(require("html-minifier"),1),X=v(require("@putout/minify"),1),P=require("url"),f=v(require("fs"),1);let V,A="";const Y=new me.default({inline:["none"]}),R=new Map;R.set("default",ie.default);let W;const Z=m((e,t)=>t===!1?!1:t===void 0?e:e===!1||e===void 0?t:{...e,...t},"mergeThemeMode"),xe=m((e,t)=>{if(!(!e&&!t))return{light:Z(e?.light,t?.light),dark:Z(e?.dark,t?.dark)}},"mergeTheme"),$e=m((e,t)=>({...e,...t,markdownLayouts:{...e.markdownLayouts,...t.markdownLayouts},headScripts:{...e.headScripts,...t.headScripts},scripts:{...e.scripts,...t.scripts},theme:xe(e.theme,t.theme),meta:{...e.meta,...t.meta}}),"mergeTemplateConfig"),Pe=m((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(a=>t.includes(a)):r instanceof RegExp?r.test(t):r(t):!0},"scriptMatches"),ee=m((e,t)=>e?Object.values(e).filter(r=>r!==!1).filter(r=>Pe(r,t)).map(r=>typeof r=="function"?r():r.render()):[],"renderPageScripts"),G=m((e,t)=>{const r=Object.entries(t).filter(([a])=>a.startsWith("--")).map(([a,n])=>` ${a}: ${n};`).join(`
|
|
2
2
|
`);return r?`${e} {
|
|
3
3
|
${r}
|
|
4
4
|
}`:""},"renderThemeBlock"),ke=m(e=>{if(!e)return"";const t=e.light===!1,r=e.dark===!1,a=e.light===!1?void 0:e.light,n=r?void 0:e.dark,u=a||n;return u?[G(":root",u),n&&!t?`@media (prefers-color-scheme: dark) {
|
|
@@ -7,10 +7,10 @@ ${G(" :root",n)}
|
|
|
7
7
|
.site-logo-dark { display: block; }`:"",r&&a?`.site-logo-light { display: block; }
|
|
8
8
|
.site-logo-dark { display: none; }`:""].filter(Boolean).join(`
|
|
9
9
|
|
|
10
|
-
`):""},"renderThemeStylesheet"),Te=m((e="")=>String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"),"escapeXML"),Me=m((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"),je=m(e=>e==="/index.html"?"/":e.replace(/\/index\.html$/,"/").replace(/\.html$/,"").replace(/\/+/g,"/"),"pagePathToUrlPath"),
|
|
10
|
+
`):""},"renderThemeStylesheet"),Te=m((e="")=>String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"),"escapeXML"),Me=m((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"),je=m(e=>e==="/index.html"?"/":e.replace(/\/index\.html$/,"/").replace(/\.html$/,"").replace(/\/+/g,"/"),"pagePathToUrlPath"),te=m((e,t)=>e?`${e.replace(/\/$/,"")}${t==="/"?"/":t}`:t,"canonicalUrl"),Ce=m(async(e,t)=>f.default.existsSync(e)?(await(0,c.mkdir)(o.default.dirname(t),{recursive:!0}),await(0,c.cp)(e,t),!0):!1,"copyIfExists"),Fe=m(async e=>{const t=o.default.resolve(e,"logo.svg");f.default.existsSync(t)&&await Promise.all(["logo.light.svg","logo.dark.svg"].map(async r=>{const a=o.default.resolve(e,r);f.default.existsSync(a)||await(0,c.cp)(t,a)}))},"ensureLogoModeAssets"),Ge=m(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"),Le=m((e,t)=>{if(!t)return"";const r=new Date().toISOString().slice(0,10);return`<?xml version="1.0" encoding="UTF-8"?>
|
|
11
11
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
12
12
|
${e.map(n=>{const u=n.urlPath==="/"?"1.0":"0.8";return` <url>
|
|
13
|
-
<loc>${Te(
|
|
13
|
+
<loc>${Te(te(t,n.urlPath))}</loc>
|
|
14
14
|
<lastmod>${r}</lastmod>
|
|
15
15
|
<changefreq>weekly</changefreq>
|
|
16
16
|
<priority>${u}</priority>
|
|
@@ -35,7 +35,7 @@ This file is generated at build time from the Markdown documentation. Use it to
|
|
|
35
35
|
|
|
36
36
|
${e.map(r=>`## ${r.title}
|
|
37
37
|
|
|
38
|
-
URL: ${
|
|
38
|
+
URL: ${te(t,r.urlPath)}
|
|
39
39
|
Source: docs/${r.sourcePath}
|
|
40
40
|
Description: ${r.description}
|
|
41
41
|
|
|
@@ -75,4 +75,4 @@ for = "/robots.txt"
|
|
|
75
75
|
[headers.values]
|
|
76
76
|
Content-Type = "text/plain; charset=utf-8"
|
|
77
77
|
Cache-Control = "public, max-age=0, must-revalidate"
|
|
78
|
-
`,"generateNetlifyToml"),$=m(async(e,t,r,a)=>{if(await Ce(e,t))return;const n=r();if(!n){a&&console.warn(a);return}await(0,c.mkdir)(o.default.dirname(t),{recursive:!0}),await(0,c.writeFile)(t,n)},"writeGeneratedFile"),_e=m(async({docsDir:e,docsSiteDir:t,pages:r,siteUrl:a,publicDir:n,generatedFiles:u})=>{u.sitemap&&await $(o.default.resolve(e,"sitemap.xml"),o.default.resolve(t,"sitemap.xml"),()=>Le(r,a),"Skipping generated sitemap.xml because buildDocs({ siteUrl }) is not set."),u.robots&&await $(o.default.resolve(e,"robots.txt"),o.default.resolve(t,"robots.txt"),()=>Ee(a)),u.llms&&await $(o.default.resolve(e,"llms.txt"),o.default.resolve(t,"llms.txt"),()=>Oe(r)),u.llmsFull&&await $(o.default.resolve(e,"llms-full.txt"),o.default.resolve(t,"llms-full.txt"),()=>Ae(r,a)),u.netlify&&(await $(o.default.resolve(e,"_redirects"),o.default.resolve(t,"_redirects"),()=>Re(r,u)),await $(o.default.resolve(e,"netlify.toml"),o.default.resolve(t,"netlify.toml"),()=>We(n&&o.default.basename(n))))},"writeGeneratedDocsFiles"),
|
|
78
|
+
`,"generateNetlifyToml"),$=m(async(e,t,r,a)=>{if(await Ce(e,t))return;const n=r();if(!n){a&&console.warn(a);return}await(0,c.mkdir)(o.default.dirname(t),{recursive:!0}),await(0,c.writeFile)(t,n)},"writeGeneratedFile"),_e=m(async({docsDir:e,docsSiteDir:t,pages:r,siteUrl:a,publicDir:n,generatedFiles:u})=>{u.sitemap&&await $(o.default.resolve(e,"sitemap.xml"),o.default.resolve(t,"sitemap.xml"),()=>Le(r,a),"Skipping generated sitemap.xml because buildDocs({ siteUrl }) is not set."),u.robots&&await $(o.default.resolve(e,"robots.txt"),o.default.resolve(t,"robots.txt"),()=>Ee(a)),u.llms&&await $(o.default.resolve(e,"llms.txt"),o.default.resolve(t,"llms.txt"),()=>Oe(r)),u.llmsFull&&await $(o.default.resolve(e,"llms-full.txt"),o.default.resolve(t,"llms-full.txt"),()=>Ae(r,a)),u.netlify&&(await $(o.default.resolve(e,"_redirects"),o.default.resolve(t,"_redirects"),()=>Re(r,u)),await $(o.default.resolve(e,"netlify.toml"),o.default.resolve(t,"netlify.toml"),()=>We(n&&o.default.basename(n))))},"writeGeneratedDocsFiles"),se=m((e={},t,r)=>{const a=new re.Marked((0,ne.markedHighlight)({langPrefix:"hljs language-",highlight(n,u){const h=_.default.getLanguage(u)?u:"plaintext";return _.default.highlight(n,{language:h}).value}}));return a.use({renderer:le.default}),a.use((0,ce.createMarkdownLayoutExtension)({marked:a,handlers:e.markdownLayouts,renderMarkdown:r})),e.markedOptions&&a.use(e.markedOptions),t&&a.use(t),a},"createBaseMarked"),Be=m((e={},t,r)=>{const a=se(e,t),n=m(h=>a.parse(h),"renderMarkdown"),u=se(e,t,n);return u.use({hooks:{postprocess(h){const{layout:w="default",...k}=W.attributes,T=ee(e.headScripts,h),M=ee(e.scripts,h);h=ae.default.sanitize(h);const b=[...h.matchAll(/<h([0-6])\sid="[^"]+".*?>.*?<a\s+href="([^"]+)".*?>([\s\S]*?)<\/a><\/h\1>/gm)].map(p=>({path:p[2],label:p[3].replace(/<[^>]+>/g,"").replace(/\s+/g," ").trim(),level:p[1]}));return R.get(w)?.({...k,content:h,siteMap:W.siteMap,tableOfContent:b,projectMeta:V,renderMarkdown:n,headScripts:T,scripts:M,themeStylesheet:e.theme?`/stylesheets/theme.css?v=${A}`:void 0,cacheKey:A,siteUrl:r,templateConfig:e})||h}}}),u},"createMarked"),S=m(async e=>{const t=await(0,c.readdir)(e),r=[];for(const a of t){const n=o.default.extname(a);/^[._]/.test(a)||(n?r.push(o.default.join(e,a)):/(stylesheets|assets|scripts)/.test(a)||r.push(...await S(o.default.join(e,a))))}return r},"traverseDirectory"),Ne=m(async({srcDir:e,publicDir:t,markedOptions:r,template:a,siteUrl:n,generatedFiles:u}={})=>{A=Date.now().toString(36);try{const s=o.default.resolve(process.cwd(),"package.json");f.default.existsSync(s)&&(V=JSON.parse(await(0,c.readFile)(s,"utf-8")))}catch(s){console.warn("Failed to load project package.json metadata",s)}const h=m(()=>{try{return __dirname}catch{return o.default.dirname((0,P.fileURLToPath)(ze.url))}},"getDirname"),w=a?o.default.resolve(h(),"templates",a):null,k=w?o.default.resolve(w,"assets"):null,T=w?o.default.resolve(w,"stylesheets"):null,M=w?o.default.resolve(w,"layouts"):null;let b={};if(w)try{let s=o.default.resolve(w,"template.config.js");if(f.default.existsSync(s)||(s=s.replace(/\.js$/,".ts")),f.default.existsSync(s)){const i=await import((0,P.pathToFileURL)(s).href);b=i.default||i}}catch(s){console.error(`Failed to load template config for ${a}`,s)}const p=e??o.default.resolve(process.cwd(),"docs"),d=t??o.default.resolve(process.cwd(),"website"),pe=Ge(u),D=o.default.resolve(p,"_template"),B=o.default.resolve(D,"assets"),N=o.default.resolve(D,"stylesheets"),U=o.default.resolve(D,"scripts"),z=o.default.resolve(D,"layouts"),q=o.default.resolve(p,"_layouts"),F=o.default.resolve(p,"assets"),H=o.default.resolve(p,"stylesheets"),L=o.default.resolve(p,"scripts");try{let s=o.default.resolve(D,"template.config.js");if(f.default.existsSync(s)||(s=s.replace(/\.js$/,".ts")),f.default.existsSync(s)){const i=await import((0,P.pathToFileURL)(s).href),l=i.default||i;b=$e(b,l)}}catch(s){console.error("Failed to load docs _template config",s)}const fe=Be(b,r,n);if(await(0,c.mkdir)(d,{recursive:!0}),k&&f.default.existsSync(k))try{await(0,c.cp)(k,F.replace(p,d),{recursive:!0})}catch(s){console.warn(s)}if(f.default.existsSync(F))try{await(0,c.cp)(F,F.replace(p,d),{recursive:!0})}catch(s){console.warn(s)}if(f.default.existsSync(B))try{await(0,c.cp)(B,o.default.resolve(d,"assets"),{recursive:!0})}catch(s){console.warn(s)}await Fe(o.default.resolve(d,"assets"));try{const s=new Set;if(T&&f.default.existsSync(T)&&(await S(T)).forEach(l=>s.add(l)),f.default.existsSync(H)&&(await S(H)).forEach(l=>s.add(l)),f.default.existsSync(N)&&(await S(N)).forEach(l=>s.add(l)),s.size){await(0,c.mkdir)(o.default.join(d,"stylesheets"),{recursive:!0});for(const l of s){const g=await(0,c.readFile)(l,"utf-8"),y=Y.minify(g);y.errors.length&&y.errors.forEach(console.error);const j=l.startsWith(D)?l.replace(D,d):l.startsWith(p)?l.replace(p,d):o.default.join(d,"stylesheets",o.default.basename(l));await(0,c.writeFile)(j,y.styles??g)}}const i=ke(b.theme);if(i){const l=Y.minify(i);l.errors.length&&l.errors.forEach(console.error),await(0,c.mkdir)(o.default.join(d,"stylesheets"),{recursive:!0}),await(0,c.writeFile)(o.default.join(d,"stylesheets","theme.css"),l.styles??i)}}catch(s){console.error(s)}if(f.default.existsSync(L))try{const s=await S(L);s.length&&await(0,c.mkdir)(L.replace(p,d),{recursive:!0});for(const i of s)try{const l=await(0,c.readFile)(i,"utf-8");await(0,c.writeFile)(i.replace(p,d),X.minify(l))}catch(l){console.error(l)}}catch(s){console.warn(s)}if(f.default.existsSync(U))try{const s=await S(U);s.length&&await(0,c.mkdir)(o.default.join(d,"scripts"),{recursive:!0});for(const i of s)try{const l=await(0,c.readFile)(i,"utf-8");await(0,c.writeFile)(i.replace(D,d),X.minify(l))}catch(l){console.error(l)}}catch(s){console.warn(s)}try{const s=new Map;M&&f.default.existsSync(M)&&(await S(M)).forEach(i=>{/\.(j|t)s$/.test(i)&&s.set(o.default.basename(i).replace(/\.(j|t)s$/,""),i)}),f.default.existsSync(q)&&(await S(q)).forEach(i=>{/\.(j|t)s$/.test(i)&&s.set(o.default.basename(i).replace(/\.(j|t)s$/,""),i)}),f.default.existsSync(z)&&(await S(z)).forEach(i=>{/\.(j|t)s$/.test(i)&&s.set(o.default.basename(i).replace(/\.(j|t)s$/,""),i)});for(const[i,l]of s.entries()){const g=await import((0,P.pathToFileURL)(l).href);R.set(i,g.default)}}catch(s){console.error("Template import failed",s)}const de=await S(p),I=new Map,J=(await Promise.all(de.filter(s=>s.endsWith(".md")).map(async s=>{const i=await(0,c.readFile)(s,"utf-8");return{filePath:s,...(0,oe.default)(i)}}))).sort((s,i)=>(s.attributes.order??0)-(i.attributes.order??0)).map(({attributes:s,body:i,filePath:l})=>{const g=l.replace(p,"").replace(/\.md/,".html"),y=l.replace(p,d).replace(".md",".html"),j=y.replace(o.default.basename(y),""),E=o.default.basename(g)||"/",he=g.replace(E,"").replace(/\/$/,"");let x=I;he.split("/").filter(Boolean).forEach(O=>{x.has(O)||x.set(O,new Map),x=x.get(O)});const K={...s,path:g};return x.has(E)||x.set(E,K),{attributes:K,fileWebsitePath:y,fileDirWebsitePath:j,body:i,sourcePath:o.default.relative(p,l),siteMap:I}});for(const{attributes:s,body:i,fileDirWebsitePath:l,fileWebsitePath:g,siteMap:y}of J){W={attributes:s,siteMap:y};const j=await fe.parse(i);await(0,c.mkdir)(l,{recursive:!0}),await(0,c.writeFile)(g,ue.default.minify(j,{includeAutoGeneratedTags:!0,removeAttributeQuotes:!0,removeComments:!0,removeRedundantAttributes:!0,removeScriptTypeAttributes:!0,removeStyleLinkTypeAttributes:!0,sortClassName:!0,useShortDoctype:!0,collapseWhitespace:!0,minifyJS:!0,minifyCSS:!0}))}await _e({docsDir:p,docsSiteDir:d,pages:J.map(({attributes:s,body:i,sourcePath:l})=>{const g=je(String(s.path)),y=Me(i);return{sourcePath:l,urlPath:g,title:String(s.title||s.name||"").trim()||"Documentation",name:String(s.name||s.title||"").trim()||"Documentation",description:String(s.description||"").trim()||y.slice(0,156)||"Documentation page.",order:Number(s.order??999),summary:y.slice(0,320)}}),siteUrl:n,publicDir:d,generatedFiles:pe})},"buildDocs");0&&(module.exports={buildDocs});
|
|
@@ -637,7 +637,7 @@ The landing and documentation stylesheets import or rely on the shared styles as
|
|
|
637
637
|
|
|
638
638
|
## Scripts
|
|
639
639
|
|
|
640
|
-
Template scripts are registered by marker
|
|
640
|
+
Template scripts are registered by marker. The template renders `headScripts` inside `<head>` and `scripts` before `</body>`.
|
|
641
641
|
|
|
642
642
|
```js
|
|
643
643
|
scripts: {
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/* global process */
|
|
2
|
-
const isDev = process.env.NODE_ENV === 'development'
|
|
3
|
-
|
|
4
1
|
const fallbackSiteUrl = 'https://beforesemicolon.com'
|
|
5
2
|
const fallbackSiteName = 'Before Semicolon'
|
|
6
3
|
const fallbackTitle = 'Before Semicolon Documentation'
|
|
@@ -234,18 +231,5 @@ export default (props = {}) => {
|
|
|
234
231
|
<link rel="stylesheet" href="/stylesheets/github-dark.hightlighter.css${cacheKey}">
|
|
235
232
|
${jsonScript(pageJson({ ...props, siteUrl, siteName, defaultImage, title, description }))}
|
|
236
233
|
${jsonScript(breadcrumbJson({ siteUrl, title, path: props.path }))}
|
|
237
|
-
${
|
|
238
|
-
isDev
|
|
239
|
-
? ''
|
|
240
|
-
: `<!-- Google tag (gtag.js) -->
|
|
241
|
-
<script async src="https://www.googletagmanager.com/gtag/js?id=G-N3MXGDP5PS"></script>
|
|
242
|
-
<script>
|
|
243
|
-
window.dataLayer = window.dataLayer || [];
|
|
244
|
-
function gtag(){dataLayer.push(arguments);}
|
|
245
|
-
gtag('js', new Date());
|
|
246
|
-
|
|
247
|
-
gtag('config', 'G-N3MXGDP5PS');
|
|
248
|
-
</script>`
|
|
249
|
-
}
|
|
250
234
|
`
|
|
251
235
|
}
|
package/dist/esm/docs/run.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
1
|
+
var ie=Object.defineProperty;var c=(e,t)=>ie(e,"name",{value:t,configurable:!0});import{Marked as le}from"marked";import{cp as j,mkdir as S,readdir as ce,readFile as C,writeFile as x}from"fs/promises";import o from"path";import me from"front-matter";import ue from"isomorphic-dompurify";import{markedHighlight as pe}from"marked-highlight";import Q from"highlight.js";import fe from"./templates/default.template.js";import de from"./renderer/index.js";import{createMarkdownLayoutExtension as he}from"./markdown-layout/index.js";import ge from"clean-css";import ye from"html-minifier";import*as X from"@putout/minify";import{fileURLToPath as we,pathToFileURL as A}from"url";import p from"fs";let V,R="";const Y=new ge({inline:["none"]}),W=new Map;W.set("default",fe);let _;const Z=c((e,t)=>t===!1?!1:t===void 0?e:e===!1||e===void 0?t:{...e,...t},"mergeThemeMode"),ve=c((e,t)=>{if(!(!e&&!t))return{light:Z(e?.light,t?.light),dark:Z(e?.dark,t?.dark)}},"mergeTheme"),Se=c((e,t)=>({...e,...t,markdownLayouts:{...e.markdownLayouts,...t.markdownLayouts},headScripts:{...e.headScripts,...t.headScripts},scripts:{...e.scripts,...t.scripts},theme:ve(e.theme,t.theme),meta:{...e.meta,...t.meta}}),"mergeTemplateConfig"),De=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(a=>t.includes(a)):r instanceof RegExp?r.test(t):r(t):!0},"scriptMatches"),ee=c((e,t)=>e?Object.values(e).filter(r=>r!==!1).filter(r=>De(r,t)).map(r=>typeof r=="function"?r():r.render()):[],"renderPageScripts"),G=c((e,t)=>{const r=Object.entries(t).filter(([a])=>a.startsWith("--")).map(([a,i])=>` ${a}: ${i};`).join(`
|
|
2
2
|
`);return r?`${e} {
|
|
3
3
|
${r}
|
|
4
4
|
}`:""},"renderThemeBlock"),be=c(e=>{if(!e)return"";const t=e.light===!1,r=e.dark===!1,a=e.light===!1?void 0:e.light,i=r?void 0:e.dark,m=a||i;return m?[G(":root",m),i&&!t?`@media (prefers-color-scheme: dark) {
|
|
@@ -7,10 +7,10 @@ ${G(" :root",i)}
|
|
|
7
7
|
.site-logo-dark { display: block; }`:"",r&&a?`.site-logo-light { display: block; }
|
|
8
8
|
.site-logo-dark { display: none; }`:""].filter(Boolean).join(`
|
|
9
9
|
|
|
10
|
-
`):""},"renderThemeStylesheet"),xe=c((e="")=>String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"),"escapeXML"),$e=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"),Pe=c(e=>e==="/index.html"?"/":e.replace(/\/index\.html$/,"/").replace(/\.html$/,"").replace(/\/+/g,"/"),"pagePathToUrlPath"),
|
|
10
|
+
`):""},"renderThemeStylesheet"),xe=c((e="")=>String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"),"escapeXML"),$e=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"),Pe=c(e=>e==="/index.html"?"/":e.replace(/\/index\.html$/,"/").replace(/\.html$/,"").replace(/\/+/g,"/"),"pagePathToUrlPath"),te=c((e,t)=>e?`${e.replace(/\/$/,"")}${t==="/"?"/":t}`:t,"canonicalUrl"),ke=c(async(e,t)=>p.existsSync(e)?(await S(o.dirname(t),{recursive:!0}),await j(e,t),!0):!1,"copyIfExists"),Te=c(async e=>{const t=o.resolve(e,"logo.svg");p.existsSync(t)&&await Promise.all(["logo.light.svg","logo.dark.svg"].map(async r=>{const a=o.resolve(e,r);p.existsSync(a)||await j(t,a)}))},"ensureLogoModeAssets"),Me=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"),je=c((e,t)=>{if(!t)return"";const r=new Date().toISOString().slice(0,10);return`<?xml version="1.0" encoding="UTF-8"?>
|
|
11
11
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
12
12
|
${e.map(i=>{const m=i.urlPath==="/"?"1.0":"0.8";return` <url>
|
|
13
|
-
<loc>${xe(
|
|
13
|
+
<loc>${xe(te(t,i.urlPath))}</loc>
|
|
14
14
|
<lastmod>${r}</lastmod>
|
|
15
15
|
<changefreq>weekly</changefreq>
|
|
16
16
|
<priority>${m}</priority>
|
|
@@ -35,7 +35,7 @@ This file is generated at build time from the Markdown documentation. Use it to
|
|
|
35
35
|
|
|
36
36
|
${e.map(r=>`## ${r.title}
|
|
37
37
|
|
|
38
|
-
URL: ${
|
|
38
|
+
URL: ${te(t,r.urlPath)}
|
|
39
39
|
Source: docs/${r.sourcePath}
|
|
40
40
|
Description: ${r.description}
|
|
41
41
|
|
|
@@ -75,4 +75,4 @@ for = "/robots.txt"
|
|
|
75
75
|
[headers.values]
|
|
76
76
|
Content-Type = "text/plain; charset=utf-8"
|
|
77
77
|
Cache-Control = "public, max-age=0, must-revalidate"
|
|
78
|
-
`,"generateNetlifyToml"),$=c(async(e,t,r,a)=>{if(await ke(e,t))return;const i=r();if(!i){a&&console.warn(a);return}await
|
|
78
|
+
`,"generateNetlifyToml"),$=c(async(e,t,r,a)=>{if(await ke(e,t))return;const i=r();if(!i){a&&console.warn(a);return}await S(o.dirname(t),{recursive:!0}),await x(t,i)},"writeGeneratedFile"),Oe=c(async({docsDir:e,docsSiteDir:t,pages:r,siteUrl:a,publicDir:i,generatedFiles:m})=>{m.sitemap&&await $(o.resolve(e,"sitemap.xml"),o.resolve(t,"sitemap.xml"),()=>je(r,a),"Skipping generated sitemap.xml because buildDocs({ siteUrl }) is not set."),m.robots&&await $(o.resolve(e,"robots.txt"),o.resolve(t,"robots.txt"),()=>Ce(a)),m.llms&&await $(o.resolve(e,"llms.txt"),o.resolve(t,"llms.txt"),()=>Fe(r)),m.llmsFull&&await $(o.resolve(e,"llms-full.txt"),o.resolve(t,"llms-full.txt"),()=>Ge(r,a)),m.netlify&&(await $(o.resolve(e,"_redirects"),o.resolve(t,"_redirects"),()=>Le(r,m)),await $(o.resolve(e,"netlify.toml"),o.resolve(t,"netlify.toml"),()=>Ee(i&&o.basename(i))))},"writeGeneratedDocsFiles"),se=c((e={},t,r)=>{const a=new le(pe({langPrefix:"hljs language-",highlight(i,m){const d=Q.getLanguage(m)?m:"plaintext";return Q.highlight(i,{language:d}).value}}));return a.use({renderer:de}),a.use(he({marked:a,handlers:e.markdownLayouts,renderMarkdown:r})),e.markedOptions&&a.use(e.markedOptions),t&&a.use(t),a},"createBaseMarked"),Ae=c((e={},t,r)=>{const a=se(e,t),i=c(d=>a.parse(d),"renderMarkdown"),m=se(e,t,i);return m.use({hooks:{postprocess(d){const{layout:y="default",...P}=_.attributes,k=ee(e.headScripts,d),T=ee(e.scripts,d);d=ue.sanitize(d);const D=[...d.matchAll(/<h([0-6])\sid="[^"]+".*?>.*?<a\s+href="([^"]+)".*?>([\s\S]*?)<\/a><\/h\1>/gm)].map(u=>({path:u[2],label:u[3].replace(/<[^>]+>/g,"").replace(/\s+/g," ").trim(),level:u[1]}));return W.get(y)?.({...P,content:d,siteMap:_.siteMap,tableOfContent:D,projectMeta:V,renderMarkdown:i,headScripts:k,scripts:T,themeStylesheet:e.theme?`/stylesheets/theme.css?v=${R}`:void 0,cacheKey:R,siteUrl:r,templateConfig:e})||d}}}),m},"createMarked"),w=c(async e=>{const t=await ce(e),r=[];for(const a of t){const i=o.extname(a);/^[._]/.test(a)||(i?r.push(o.join(e,a)):/(stylesheets|assets|scripts)/.test(a)||r.push(...await w(o.join(e,a))))}return r},"traverseDirectory"),lt=c(async({srcDir:e,publicDir:t,markedOptions:r,template:a,siteUrl:i,generatedFiles:m}={})=>{R=Date.now().toString(36);try{const s=o.resolve(process.cwd(),"package.json");p.existsSync(s)&&(V=JSON.parse(await C(s,"utf-8")))}catch(s){console.warn("Failed to load project package.json metadata",s)}const d=c(()=>{try{return __dirname}catch{return o.dirname(we(import.meta.url))}},"getDirname"),y=a?o.resolve(d(),"templates",a):null,P=y?o.resolve(y,"assets"):null,k=y?o.resolve(y,"stylesheets"):null,T=y?o.resolve(y,"layouts"):null;let D={};if(y)try{let s=o.resolve(y,"template.config.js");if(p.existsSync(s)||(s=s.replace(/\.js$/,".ts")),p.existsSync(s)){const n=await import(A(s).href);D=n.default||n}}catch(s){console.error(`Failed to load template config for ${a}`,s)}const u=e??o.resolve(process.cwd(),"docs"),f=t??o.resolve(process.cwd(),"website"),re=Me(m),v=o.resolve(u,"_template"),B=o.resolve(v,"assets"),N=o.resolve(v,"stylesheets"),U=o.resolve(v,"scripts"),z=o.resolve(v,"layouts"),q=o.resolve(u,"_layouts"),F=o.resolve(u,"assets"),H=o.resolve(u,"stylesheets"),L=o.resolve(u,"scripts");try{let s=o.resolve(v,"template.config.js");if(p.existsSync(s)||(s=s.replace(/\.js$/,".ts")),p.existsSync(s)){const n=await import(A(s).href),l=n.default||n;D=Se(D,l)}}catch(s){console.error("Failed to load docs _template config",s)}const oe=Ae(D,r,i);if(await S(f,{recursive:!0}),P&&p.existsSync(P))try{await j(P,F.replace(u,f),{recursive:!0})}catch(s){console.warn(s)}if(p.existsSync(F))try{await j(F,F.replace(u,f),{recursive:!0})}catch(s){console.warn(s)}if(p.existsSync(B))try{await j(B,o.resolve(f,"assets"),{recursive:!0})}catch(s){console.warn(s)}await Te(o.resolve(f,"assets"));try{const s=new Set;if(k&&p.existsSync(k)&&(await w(k)).forEach(l=>s.add(l)),p.existsSync(H)&&(await w(H)).forEach(l=>s.add(l)),p.existsSync(N)&&(await w(N)).forEach(l=>s.add(l)),s.size){await S(o.join(f,"stylesheets"),{recursive:!0});for(const l of s){const h=await C(l,"utf-8"),g=Y.minify(h);g.errors.length&&g.errors.forEach(console.error);const M=l.startsWith(v)?l.replace(v,f):l.startsWith(u)?l.replace(u,f):o.join(f,"stylesheets",o.basename(l));await x(M,g.styles??h)}}const n=be(D.theme);if(n){const l=Y.minify(n);l.errors.length&&l.errors.forEach(console.error),await S(o.join(f,"stylesheets"),{recursive:!0}),await x(o.join(f,"stylesheets","theme.css"),l.styles??n)}}catch(s){console.error(s)}if(p.existsSync(L))try{const s=await w(L);s.length&&await S(L.replace(u,f),{recursive:!0});for(const n of s)try{const l=await C(n,"utf-8");await x(n.replace(u,f),X.minify(l))}catch(l){console.error(l)}}catch(s){console.warn(s)}if(p.existsSync(U))try{const s=await w(U);s.length&&await S(o.join(f,"scripts"),{recursive:!0});for(const n of s)try{const l=await C(n,"utf-8");await x(n.replace(v,f),X.minify(l))}catch(l){console.error(l)}}catch(s){console.warn(s)}try{const s=new Map;T&&p.existsSync(T)&&(await w(T)).forEach(n=>{/\.(j|t)s$/.test(n)&&s.set(o.basename(n).replace(/\.(j|t)s$/,""),n)}),p.existsSync(q)&&(await w(q)).forEach(n=>{/\.(j|t)s$/.test(n)&&s.set(o.basename(n).replace(/\.(j|t)s$/,""),n)}),p.existsSync(z)&&(await w(z)).forEach(n=>{/\.(j|t)s$/.test(n)&&s.set(o.basename(n).replace(/\.(j|t)s$/,""),n)});for(const[n,l]of s.entries()){const h=await import(A(l).href);W.set(n,h.default)}}catch(s){console.error("Template import failed",s)}const ae=await w(u),I=new Map,J=(await Promise.all(ae.filter(s=>s.endsWith(".md")).map(async s=>{const n=await C(s,"utf-8");return{filePath:s,...me(n)}}))).sort((s,n)=>(s.attributes.order??0)-(n.attributes.order??0)).map(({attributes:s,body:n,filePath:l})=>{const h=l.replace(u,"").replace(/\.md/,".html"),g=l.replace(u,f).replace(".md",".html"),M=g.replace(o.basename(g),""),E=o.basename(h)||"/",ne=h.replace(E,"").replace(/\/$/,"");let b=I;ne.split("/").filter(Boolean).forEach(O=>{b.has(O)||b.set(O,new Map),b=b.get(O)});const K={...s,path:h};return b.has(E)||b.set(E,K),{attributes:K,fileWebsitePath:g,fileDirWebsitePath:M,body:n,sourcePath:o.relative(u,l),siteMap:I}});for(const{attributes:s,body:n,fileDirWebsitePath:l,fileWebsitePath:h,siteMap:g}of J){_={attributes:s,siteMap:g};const M=await oe.parse(n);await S(l,{recursive:!0}),await x(h,ye.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 Oe({docsDir:u,docsSiteDir:f,pages:J.map(({attributes:s,body:n,sourcePath:l})=>{const h=Pe(String(s.path)),g=$e(n);return{sourcePath:l,urlPath:h,title:String(s.title||s.name||"").trim()||"Documentation",name:String(s.name||s.title||"").trim()||"Documentation",description:String(s.description||"").trim()||g.slice(0,156)||"Documentation page.",order:Number(s.order??999),summary:g.slice(0,320)}}),siteUrl:i,publicDir:f,generatedFiles:re})},"buildDocs");export{lt as buildDocs};
|
|
@@ -637,7 +637,7 @@ The landing and documentation stylesheets import or rely on the shared styles as
|
|
|
637
637
|
|
|
638
638
|
## Scripts
|
|
639
639
|
|
|
640
|
-
Template scripts are registered by marker
|
|
640
|
+
Template scripts are registered by marker. The template renders `headScripts` inside `<head>` and `scripts` before `</body>`.
|
|
641
641
|
|
|
642
642
|
```js
|
|
643
643
|
scripts: {
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/* global process */
|
|
2
|
-
const isDev = process.env.NODE_ENV === 'development'
|
|
3
|
-
|
|
4
1
|
const fallbackSiteUrl = 'https://beforesemicolon.com'
|
|
5
2
|
const fallbackSiteName = 'Before Semicolon'
|
|
6
3
|
const fallbackTitle = 'Before Semicolon Documentation'
|
|
@@ -234,18 +231,5 @@ export default (props = {}) => {
|
|
|
234
231
|
<link rel="stylesheet" href="/stylesheets/github-dark.hightlighter.css${cacheKey}">
|
|
235
232
|
${jsonScript(pageJson({ ...props, siteUrl, siteName, defaultImage, title, description }))}
|
|
236
233
|
${jsonScript(breadcrumbJson({ siteUrl, title, path: props.path }))}
|
|
237
|
-
${
|
|
238
|
-
isDev
|
|
239
|
-
? ''
|
|
240
|
-
: `<!-- Google tag (gtag.js) -->
|
|
241
|
-
<script async src="https://www.googletagmanager.com/gtag/js?id=G-N3MXGDP5PS"></script>
|
|
242
|
-
<script>
|
|
243
|
-
window.dataLayer = window.dataLayer || [];
|
|
244
|
-
function gtag(){dataLayer.push(arguments);}
|
|
245
|
-
gtag('js', new Date());
|
|
246
|
-
|
|
247
|
-
gtag('config', 'G-N3MXGDP5PS');
|
|
248
|
-
</script>`
|
|
249
|
-
}
|
|
250
234
|
`
|
|
251
235
|
}
|
|
@@ -38,6 +38,7 @@ export interface PageProps {
|
|
|
38
38
|
[key: string]: unknown;
|
|
39
39
|
};
|
|
40
40
|
renderMarkdown?: (markdown: string) => string;
|
|
41
|
+
headScripts?: string[];
|
|
41
42
|
scripts?: string[];
|
|
42
43
|
themeStylesheet?: string;
|
|
43
44
|
cacheKey?: string;
|
|
@@ -67,6 +68,7 @@ export type SiteMap = Map<string, CustomOptions | SiteMap>;
|
|
|
67
68
|
export interface DocsTemplateConfig {
|
|
68
69
|
markedOptions?: MarkedExtension;
|
|
69
70
|
markdownLayouts?: Record<string, MarkdownLayoutHandler>;
|
|
71
|
+
headScripts?: DocsScriptRegistry;
|
|
70
72
|
scripts?: DocsScriptRegistry;
|
|
71
73
|
theme?: DocsTheme;
|
|
72
74
|
meta?: DocsMetaConfig;
|