@beforesemicolon/builder 1.6.2 → 1.6.4

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 CHANGED
@@ -1,3 +1,216 @@
1
1
  # @beforesemicolon/builder
2
2
 
3
- Before Semicolon utility to build npm packages and documentation website
3
+ Utilities to build npm packages and a documentation website for Before Semicolon projects.
4
+
5
+ This package provides small, focused helpers to:
6
+
7
+ - Build server-friendly CommonJS and ESM module bundles (dist/cjs and dist/esm).
8
+ - Produce a browser bundle (dist/client.js) for documentation or demos.
9
+ - Render a static documentation website from Markdown files (output defaults to `website/`).
10
+
11
+ Table of contents
12
+
13
+ - Features
14
+ - Requirements
15
+ - Installation
16
+ - Quick examples
17
+ - Library usage (Node)
18
+ - Building the browser bundle
19
+ - Generating the documentation website
20
+ - API
21
+ - buildModules(options?)
22
+ - buildBrowser(options?)
23
+ - buildDocs(options?)
24
+ - Documentation site layout and front-matter
25
+ - Scripts (in package.json)
26
+ - Development
27
+ - Contributing
28
+ - License
29
+
30
+
31
+ Features
32
+
33
+ - Builds all TypeScript sources into both ESM and CJS formats using esbuild.
34
+ - Produces a single browser bundle for client-side documentation UI.
35
+ - Static site generator for Markdown: supports layouts, assets, stylesheets, and scripts.
36
+ - Uses marked + highlight.js for Markdown rendering, DOMPurify for sanitization and minifies output CSS/JS/HTML.
37
+ - Simple, zero-config defaults plus options for common customization.
38
+
39
+ Requirements
40
+
41
+ - Node.js >= 18.16.0 (see `engines` in package.json)
42
+
43
+ Installation
44
+
45
+ Install from npm (package name: `@beforesemicolon/builder`) or use the repo directly.
46
+
47
+ ```
48
+ # npm
49
+ npm install @beforesemicolon/builder
50
+
51
+ # or using the repository
52
+ git clone https://github.com/beforesemicolon/builder.git
53
+ cd builder
54
+ npm install
55
+ ```
56
+
57
+ Quick examples
58
+
59
+ Library usage (Node / programmatic)
60
+
61
+ ```js
62
+ // ESM
63
+ import { buildModules, buildBrowser, buildDocs } from '@beforesemicolon/builder'
64
+
65
+ // Build server-side modules (dist/esm and dist/cjs)
66
+ await buildModules({ directoryPath: 'src' })
67
+
68
+ // Build single browser bundle (defaults to src/client -> dist/client.js)
69
+ await buildBrowser({ entry: 'src/client', out: 'dist/client.js' })
70
+
71
+ // Generate static docs (defaults: docs -> website)
72
+ await buildDocs({ srcDir: 'docs', publicDir: 'website' })
73
+ ```
74
+
75
+ CommonJS
76
+
77
+ ```js
78
+ const { buildModules, buildBrowser, buildDocs } = require('@beforesemicolon/builder')
79
+
80
+ ;(async () => {
81
+ await buildModules()
82
+ await buildBrowser()
83
+ await buildDocs()
84
+ })()
85
+ ```
86
+
87
+ CLI / npm scripts
88
+
89
+ The repo ships with a `build` script that will emit types and run the TypeScript build entry (`build.ts`).
90
+
91
+ ```
92
+ npm run build
93
+ ```
94
+
95
+ This runs TypeScript declaration emission and then executes `build.ts` which calls `buildModules()` to produce the `dist/` outputs.
96
+
97
+ API
98
+
99
+ - buildModules(options?: { directoryPath?: string }) => Promise
100
+ - Scans the given directory (default: `process.cwd()/src`) recursively for files and builds them into:
101
+ - `dist/esm` (ESM format)
102
+ - `dist/cjs` (CommonJS format)
103
+ - Files ending with `.spec.ts` or `/client.ts` are ignored from the module build set.
104
+ - Uses `esbuild` with minification and keeps symbol names for better stack traces.
105
+
106
+ - buildBrowser(options?: { entry?: string; out?: string }) => Promise
107
+ - Bundles a single browser file using `esbuild`.
108
+ - Defaults: `entry` -> `src/client`, `out` -> `dist/client.js`.
109
+ - Includes a small plugin to remove the `Doc` export from `@beforesemicolon/html-parser` during bundling (keeps bundle size smaller when that export isn't used).
110
+ - Generates sourcemaps and minifies the output.
111
+
112
+ - buildDocs(options?: { srcDir?: string; publicDir?: string }) => Promise
113
+ - Generates a static documentation website from a Markdown `docs` directory.
114
+ - Defaults: `srcDir` -> `docs`, `publicDir` -> `website`.
115
+ - Supported docs structure (defaults used by the generator):
116
+ - `_layouts/` — custom templates (each module should default-export a function matching `PageProps`)
117
+ - `assets/` — copied to the site output
118
+ - `stylesheets/` — CSS files are minified and copied
119
+ - `scripts/` — JS files are minified and copied
120
+ - `*.md` — Markdown pages with front-matter to control metadata
121
+ - Pages use `marked` with a custom renderer (heading IDs, code blocks, links) and `highlight.js` for syntax highlighting.
122
+ - HTML is sanitized with DOMPurify and minified with `html-minifier`.
123
+
124
+ Documentation site layout and front-matter
125
+
126
+ Markdown pages should contain front-matter (YAML) with properties compatible with the site's `PageProps`:
127
+
128
+ - title: string — page title (used in the HTML title)
129
+ - description: string — meta description
130
+ - order: number — numeric order used when building the site map and sorting pages
131
+ - layout: string — layout name; corresponds to a template in `_layouts` (default: `default`)
132
+
133
+ PageProps (shape used by layouts)
134
+
135
+ - name: string
136
+ - path: string (page path, e.g. `/guide/getting-started.html`)
137
+ - order: number
138
+ - title: string
139
+ - description: string
140
+ - content: string (HTML produced from Markdown)
141
+ - siteMap: Map representing the site structure
142
+ - tableOfContent: array of { path, label } entries generated from headings
143
+
144
+ A minimal docs layout example (the package ships a simple `default` template):
145
+
146
+ ```ts
147
+ export default ({ title, description, content }) => `
148
+ <!doctype html>
149
+ <html>
150
+ <head>
151
+ <meta charset="utf-8" />
152
+ <meta name="description" content="${description}" />
153
+ <title>${title}</title>
154
+ </head>
155
+ <body>
156
+ ${content}
157
+ </body>
158
+ </html>`
159
+ ```
160
+
161
+ Scripts (from package.json)
162
+
163
+ - `build` — removes `dist`, emits TypeScript declarations, then runs `build.ts` (which calls `buildModules`).
164
+ - `lint` — runs ESLint and Prettier check
165
+ - `format` — runs ESLint autofix and Prettier write
166
+
167
+ Development
168
+
169
+ - Ensure you use Node >= 18.16.0
170
+ - Install dependencies:
171
+
172
+ ```
173
+ npm install
174
+ ```
175
+
176
+ - Run the build pipeline locally:
177
+
178
+ ```
179
+ npm run build
180
+ ```
181
+
182
+ - Lint and format:
183
+
184
+ ```
185
+ npm run lint
186
+ npm run format
187
+ ```
188
+
189
+ - The source entry points are in `src/`. `src/build-modules.ts`, `src/build-browser.ts` and `src/docs/run.ts` provide the public functionality.
190
+
191
+ Testing and validation
192
+
193
+ This repository does not include automated tests by default. If you add tests, consider using the existing devDependencies (TypeScript + ts-jest + tinybench if you want benchmarks).
194
+
195
+ Contributing
196
+
197
+ Contributions are welcome. A good workflow is:
198
+
199
+ 1. Fork the repository and create a feature branch.
200
+ 2. Add or modify code in `src/`.
201
+ 3. Run `npm run build` to check the build output.
202
+ 4. Run `npm run lint` or `npm run format` to keep code style consistent.
203
+ 5. Open a pull request describing the change.
204
+
205
+ License
206
+
207
+ BSD-3-Clause — see `package.json` for author and license metadata.
208
+
209
+ Acknowledgements and internals
210
+
211
+ - Uses `esbuild` for fast bundling and minification.
212
+ - Markdown rendering powered by `marked` with a custom renderer and `marked-highlight` plugin using `highlight.js`.
213
+ - Front-matter parsing via `front-matter`.
214
+ - DOM sanitization by `isomorphic-dompurify` and HTML/CSS/JS minification using `html-minifier`, `clean-css`, and `@putout/minify` respectively.
215
+
216
+ If you'd like any sections expanded (examples, advanced options, or a CONTRIBUTING.md), tell me which parts to elaborate and I'll add them.
@@ -1 +1 @@
1
- "use strict";var a=Object.create;var n=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,y=Object.prototype.hasOwnProperty;var i=(e,r)=>n(e,"name",{value:r,configurable:!0});var g=(e,r)=>{for(var t in r)n(e,t,{get:r[t],enumerable:!0})},c=(e,r,t,s)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of d(r))!y.call(e,o)&&o!==t&&n(e,o,{get:()=>r[o],enumerable:!(s=m(r,o))||s.enumerable});return e};var p=(e,r,t)=>(t=e!=null?a(f(e)):{},c(r||!e||!e.__esModule?n(t,"default",{value:e,enumerable:!0}):t,e)),h=e=>c(n({},"__esModule",{value:!0}),e);var D={};g(D,{buildBrowser:()=>B});module.exports=h(D);var l=p(require("path"),1),u=p(require("esbuild"),1);const B=i(async({entry:e,out:r})=>{const t={name:"empty-parser-Doc-plugin",setup(s){s.onResolve({filter:/Doc$/},o=>{if(o.importer.includes("@beforesemicolon/html-parser"))return{path:o.path,namespace:"empty-Doc"}}),s.onLoad({filter:/.*/,namespace:"empty-Doc"},()=>({contents:""}))}};u.default.build({entryPoints:[e??l.default.resolve(process.cwd(),"src/client")],outfile:r??"dist/client.js",bundle:!0,keepNames:!0,sourcemap:!0,target:"esnext",minify:!0,plugins:[t]}).catch(console.error)},"buildBrowser");0&&(module.exports={buildBrowser});
1
+ "use strict";var a=Object.create;var n=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,y=Object.prototype.hasOwnProperty;var i=(e,r)=>n(e,"name",{value:r,configurable:!0});var g=(e,r)=>{for(var t in r)n(e,t,{get:r[t],enumerable:!0})},c=(e,r,t,s)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of d(r))!y.call(e,o)&&o!==t&&n(e,o,{get:()=>r[o],enumerable:!(s=m(r,o))||s.enumerable});return e};var p=(e,r,t)=>(t=e!=null?a(f(e)):{},c(r||!e||!e.__esModule?n(t,"default",{value:e,enumerable:!0}):t,e)),h=e=>c(n({},"__esModule",{value:!0}),e);var D={};g(D,{buildBrowser:()=>B});module.exports=h(D);var l=p(require("path"),1),u=p(require("esbuild"),1);const B=i(async({entry:e,out:r}={})=>{const t={name:"empty-parser-Doc-plugin",setup(s){s.onResolve({filter:/Doc$/},o=>{if(o.importer.includes("@beforesemicolon/html-parser"))return{path:o.path,namespace:"empty-Doc"}}),s.onLoad({filter:/.*/,namespace:"empty-Doc"},()=>({contents:""}))}};u.default.build({entryPoints:[e??l.default.resolve(process.cwd(),"src/client")],outfile:r??"dist/client.js",bundle:!0,keepNames:!0,sourcemap:!0,target:"esnext",minify:!0,plugins:[t]}).catch(console.error)},"buildBrowser");0&&(module.exports={buildBrowser});
@@ -1 +1 @@
1
- var i=Object.defineProperty;var s=(e,r)=>i(e,"name",{value:r,configurable:!0});import c from"path";import p from"esbuild";const d=s(async({entry:e,out:r})=>{const n={name:"empty-parser-Doc-plugin",setup(t){t.onResolve({filter:/Doc$/},o=>{if(o.importer.includes("@beforesemicolon/html-parser"))return{path:o.path,namespace:"empty-Doc"}}),t.onLoad({filter:/.*/,namespace:"empty-Doc"},()=>({contents:""}))}};p.build({entryPoints:[e??c.resolve(process.cwd(),"src/client")],outfile:r??"dist/client.js",bundle:!0,keepNames:!0,sourcemap:!0,target:"esnext",minify:!0,plugins:[n]}).catch(console.error)},"buildBrowser");export{d as buildBrowser};
1
+ var i=Object.defineProperty;var s=(e,r)=>i(e,"name",{value:r,configurable:!0});import c from"path";import p from"esbuild";const d=s(async({entry:e,out:r}={})=>{const n={name:"empty-parser-Doc-plugin",setup(t){t.onResolve({filter:/Doc$/},o=>{if(o.importer.includes("@beforesemicolon/html-parser"))return{path:o.path,namespace:"empty-Doc"}}),t.onLoad({filter:/.*/,namespace:"empty-Doc"},()=>({contents:""}))}};p.build({entryPoints:[e??c.resolve(process.cwd(),"src/client")],outfile:r??"dist/client.js",bundle:!0,keepNames:!0,sourcemap:!0,target:"esnext",minify:!0,plugins:[n]}).catch(console.error)},"buildBrowser");export{d as buildBrowser};
@@ -2,5 +2,5 @@ interface BuildBrowserOptions {
2
2
  entry?: string;
3
3
  out?: string;
4
4
  }
5
- export declare const buildBrowser: ({ entry, out }: BuildBrowserOptions) => Promise<void>;
5
+ export declare const buildBrowser: ({ entry, out }?: BuildBrowserOptions) => Promise<void>;
6
6
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beforesemicolon/builder",
3
- "version": "1.6.2",
3
+ "version": "1.6.4",
4
4
  "description": "Utilities to build npm packages and documentation website",
5
5
  "engines": {
6
6
  "node": ">=18.16.0"