@helping-ai-workflow/md2doc 1.0.2 → 1.0.3
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 +29 -1
- package/package.json +3 -1
- package/scripts/preinstall.js +70 -0
package/README.md
CHANGED
|
@@ -6,11 +6,39 @@ Two global CLIs (`md2html`, `md2pdf`) you can call from any directory.
|
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
|
+
Requires Node.js 18 or higher. The first install pulls puppeteer (≈ 170 MB Chromium download); subsequent installs reuse it.
|
|
10
|
+
|
|
11
|
+
### Recommended: install via nvm
|
|
12
|
+
|
|
13
|
+
If you do not yet have Node.js — or your system Node lives under `/usr/local` and `npm install -g` fails with `EACCES` — install Node through [nvm](https://github.com/nvm-sh/nvm) first. nvm puts Node under `~/.nvm`, so global packages never need `sudo`.
|
|
14
|
+
|
|
9
15
|
```bash
|
|
16
|
+
sudo apt install -y curl # Debian / Ubuntu only; skip if curl is already installed
|
|
17
|
+
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
|
|
18
|
+
source ~/.zshrc # or: source ~/.bashrc
|
|
19
|
+
nvm install --lts
|
|
20
|
+
nvm use --lts
|
|
10
21
|
npm install -g @helping-ai-workflow/md2doc
|
|
11
22
|
```
|
|
12
23
|
|
|
13
|
-
|
|
24
|
+
### Already have Node.js
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install -g @helping-ai-workflow/md2doc
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Troubleshooting
|
|
31
|
+
|
|
32
|
+
**`EACCES: permission denied, mkdir '/usr/local/lib/node_modules'`**
|
|
33
|
+
Your system Node is owned by root. Do **not** run `sudo npm install -g` — puppeteer's postinstall would download Chromium as root and break later runs. Instead, switch to nvm using the steps above.
|
|
34
|
+
|
|
35
|
+
**`Failed to set up chrome ...! Set "PUPPETEER_SKIP_DOWNLOAD" env variable to skip download.`**
|
|
36
|
+
An earlier install left a half-finished Chromium download in `~/.cache/puppeteer`. md2doc ≥ 1.0.3 cleans this automatically; on older versions, clear the cache and retry:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
rm -rf ~/.cache/puppeteer
|
|
40
|
+
npm install -g @helping-ai-workflow/md2doc
|
|
41
|
+
```
|
|
14
42
|
|
|
15
43
|
## Usage
|
|
16
44
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helping-ai-workflow/md2doc",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Markdown → HTML / PDF renderer with WaveDrom, Mermaid, and Graphviz support",
|
|
5
5
|
"keywords": ["markdown", "html", "pdf", "renderer", "wavedrom", "mermaid", "graphviz"],
|
|
6
6
|
"main": "lib/md2doc.js",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"lib/",
|
|
13
13
|
"bin/",
|
|
14
|
+
"scripts/",
|
|
14
15
|
"README.md",
|
|
15
16
|
"LICENSE"
|
|
16
17
|
],
|
|
@@ -22,6 +23,7 @@
|
|
|
22
23
|
"puppeteer": "^24.15.0"
|
|
23
24
|
},
|
|
24
25
|
"scripts": {
|
|
26
|
+
"preinstall": "node scripts/preinstall.js",
|
|
25
27
|
"test": "node test/md2doc.test.js"
|
|
26
28
|
},
|
|
27
29
|
"repository": {
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// Remove stale puppeteer browser-cache folders that exist but are missing
|
|
5
|
+
// the actual binary. An interrupted prior download leaves @puppeteer/browsers
|
|
6
|
+
// in a state where it sees the version folder and refuses to redownload,
|
|
7
|
+
// failing puppeteer's postinstall with:
|
|
8
|
+
// The browser folder (.../chrome/<platform>-<ver>) exists but the
|
|
9
|
+
// executable (.../chrome-<platform>/chrome) is missing
|
|
10
|
+
// We run before puppeteer's postinstall and clean those husks so the
|
|
11
|
+
// download proceeds fresh.
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const os = require('os');
|
|
16
|
+
|
|
17
|
+
const BINARY_NAMES = new Set([
|
|
18
|
+
'chrome',
|
|
19
|
+
'chrome.exe',
|
|
20
|
+
'chrome-headless-shell',
|
|
21
|
+
'chrome-headless-shell.exe',
|
|
22
|
+
'Google Chrome for Testing',
|
|
23
|
+
]);
|
|
24
|
+
const MIN_BINARY_BYTES = 1_000_000;
|
|
25
|
+
const MAX_DEPTH = 4;
|
|
26
|
+
|
|
27
|
+
function hasBinary(rootDir) {
|
|
28
|
+
const stack = [[rootDir, 0]];
|
|
29
|
+
while (stack.length) {
|
|
30
|
+
const [dir, depth] = stack.pop();
|
|
31
|
+
if (depth > MAX_DEPTH) continue;
|
|
32
|
+
let entries;
|
|
33
|
+
try { entries = fs.readdirSync(dir, { withFileTypes: true }); }
|
|
34
|
+
catch { continue; }
|
|
35
|
+
for (const ent of entries) {
|
|
36
|
+
const full = path.join(dir, ent.name);
|
|
37
|
+
if (ent.isFile() && BINARY_NAMES.has(ent.name)) {
|
|
38
|
+
try {
|
|
39
|
+
if (fs.statSync(full).size >= MIN_BINARY_BYTES) return true;
|
|
40
|
+
} catch { /* ignore */ }
|
|
41
|
+
} else if (ent.isDirectory()) {
|
|
42
|
+
stack.push([full, depth + 1]);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function cleanStaleVersionDirs(parentDir) {
|
|
50
|
+
if (!fs.existsSync(parentDir)) return;
|
|
51
|
+
let entries;
|
|
52
|
+
try { entries = fs.readdirSync(parentDir, { withFileTypes: true }); }
|
|
53
|
+
catch { return; }
|
|
54
|
+
for (const ent of entries) {
|
|
55
|
+
if (!ent.isDirectory()) continue;
|
|
56
|
+
const versionDir = path.join(parentDir, ent.name);
|
|
57
|
+
if (hasBinary(versionDir)) continue;
|
|
58
|
+
console.log(`[md2doc preinstall] removing stale puppeteer cache: ${versionDir}`);
|
|
59
|
+
try { fs.rmSync(versionDir, { recursive: true, force: true }); }
|
|
60
|
+
catch (e) {
|
|
61
|
+
console.log(`[md2doc preinstall] failed to remove ${versionDir}: ${e.message}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const cacheRoot = process.env.PUPPETEER_CACHE_DIR
|
|
67
|
+
|| path.join(os.homedir(), '.cache', 'puppeteer');
|
|
68
|
+
|
|
69
|
+
cleanStaleVersionDirs(path.join(cacheRoot, 'chrome'));
|
|
70
|
+
cleanStaleVersionDirs(path.join(cacheRoot, 'chrome-headless-shell'));
|