@choonkeat/md-serve 0.1.0
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 +71 -0
- package/bin/md-serve.js +92 -0
- package/package.json +29 -0
package/README.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# md-serve
|
|
2
|
+
|
|
3
|
+
Tiny static file server that renders Markdown (`.md`, `.markdown`) as
|
|
4
|
+
GitHub-styled HTML. Single Go binary, distributed via npm with native
|
|
5
|
+
binaries for Linux / macOS / Windows on x64 and arm64.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install -g @choonkeat/md-serve
|
|
11
|
+
# or one-shot:
|
|
12
|
+
npx @choonkeat/md-serve
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
(The published name is scoped — npm rejected the unscoped `md-serve`
|
|
16
|
+
as too similar to an existing package. The installed binary is still
|
|
17
|
+
called `md-serve`.)
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
md-serve # serve $PWD on :$PORT (or :8080), live-reload on
|
|
23
|
+
md-serve -dir ./docs # serve a specific directory
|
|
24
|
+
md-serve -addr :3000 # bind to a specific address
|
|
25
|
+
md-serve -no-live # disable the live-reload poller
|
|
26
|
+
md-serve -version
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Behavior
|
|
30
|
+
|
|
31
|
+
- `.md` / `.markdown` files render as HTML using
|
|
32
|
+
[goldmark](https://github.com/yuin/goldmark) with GFM, styled with
|
|
33
|
+
[github-markdown-css](https://github.com/sindresorhus/github-markdown-css).
|
|
34
|
+
Fenced code blocks are syntax-highlighted via
|
|
35
|
+
[chroma](https://github.com/alecthomas/chroma) (200+ languages).
|
|
36
|
+
- Directories show a generated listing with **Name / Size / Modified**
|
|
37
|
+
columns. If `index.md` / `README.md` / `readme.md` / `index.markdown`
|
|
38
|
+
is present, it's rendered below the listing GitHub-style. If only
|
|
39
|
+
`index.html` is present, it's served raw.
|
|
40
|
+
- Source files (`.go`, `.py`, `.json`, `.yaml`, `.toml`, `Dockerfile`,
|
|
41
|
+
`Makefile`, ...) render as syntax-highlighted HTML with linkable line
|
|
42
|
+
numbers (`/main.go#L42`). Append `?raw=1` to any URL to bypass and
|
|
43
|
+
fetch the byte-for-byte original. Files larger than 1 MiB or that
|
|
44
|
+
look binary skip highlighting and stream raw.
|
|
45
|
+
- Everything else is served byte-for-byte.
|
|
46
|
+
- Dotfiles are hidden from listings.
|
|
47
|
+
- Path traversal is blocked: requests are rejected if they resolve
|
|
48
|
+
outside the served root.
|
|
49
|
+
- Live-reload is on by default: rendered pages poll a tiny endpoint
|
|
50
|
+
once a second and reload themselves when the underlying file's mtime
|
|
51
|
+
changes. Pass `-no-live` to disable (e.g. for production-style
|
|
52
|
+
serving where you don't want the extra requests).
|
|
53
|
+
|
|
54
|
+
## Develop
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
make build # cross-compile all 6 platform binaries → npm-platforms/
|
|
58
|
+
make test # go vet
|
|
59
|
+
make publish-dry # rehearse the npm publish
|
|
60
|
+
make publish # ship to npm
|
|
61
|
+
make bump VERSION=x.y.z # sync version across package.json + optionalDependencies
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The npm package layout: a thin shim (`bin/md-serve.js`) selects the
|
|
65
|
+
right `@choonkeat/md-serve-<platform>-<arch>` optionalDependency at
|
|
66
|
+
runtime, falling back to a locally built binary in `npm-platforms/`
|
|
67
|
+
during development.
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
MIT
|
package/bin/md-serve.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawnSync } from "child_process";
|
|
4
|
+
import { createRequire } from "module";
|
|
5
|
+
import { existsSync, chmodSync } from "fs";
|
|
6
|
+
import { dirname, join } from "path";
|
|
7
|
+
import { fileURLToPath } from "url";
|
|
8
|
+
|
|
9
|
+
const require = createRequire(import.meta.url);
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
|
|
12
|
+
const PLATFORM_MAP = {
|
|
13
|
+
linux: "linux",
|
|
14
|
+
darwin: "darwin",
|
|
15
|
+
win32: "win32",
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const ARCH_MAP = {
|
|
19
|
+
x64: "x64",
|
|
20
|
+
arm64: "arm64",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const platform = PLATFORM_MAP[process.platform];
|
|
24
|
+
const arch = ARCH_MAP[process.arch];
|
|
25
|
+
|
|
26
|
+
if (!platform || !arch) {
|
|
27
|
+
console.error(
|
|
28
|
+
`Unsupported platform: ${process.platform}-${process.arch}\n` +
|
|
29
|
+
`md-serve supports: linux-x64, linux-arm64, darwin-x64, darwin-arm64, win32-x64, win32-arm64`
|
|
30
|
+
);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const pkgName = `@choonkeat/md-serve-${platform}-${arch}`;
|
|
35
|
+
const binName = process.platform === "win32" ? "md-serve.exe" : "md-serve";
|
|
36
|
+
|
|
37
|
+
// Prefer local build in npm-platforms/ (development) over npm-installed package.
|
|
38
|
+
// npm-platforms/ is not published to npm, so this only takes effect during local dev.
|
|
39
|
+
const localPath = join(__dirname, "..", "npm-platforms", `${platform}-${arch}`, "bin", binName);
|
|
40
|
+
|
|
41
|
+
let binPath;
|
|
42
|
+
if (existsSync(localPath)) {
|
|
43
|
+
binPath = localPath;
|
|
44
|
+
} else {
|
|
45
|
+
try {
|
|
46
|
+
const pkgDir = dirname(require.resolve(`${pkgName}/package.json`));
|
|
47
|
+
binPath = join(pkgDir, "bin", binName);
|
|
48
|
+
} catch {
|
|
49
|
+
console.error(
|
|
50
|
+
`Could not find package ${pkgName}.\n` +
|
|
51
|
+
`Make sure it is installed — this usually means your platform is supported\n` +
|
|
52
|
+
`but the optional dependency was not installed.\n\n` +
|
|
53
|
+
`Try: npm install ${pkgName}\n` +
|
|
54
|
+
`Or run: npx @choonkeat/md-serve`
|
|
55
|
+
);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!existsSync(binPath)) {
|
|
61
|
+
console.error(`Binary not found at ${binPath}`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function run() {
|
|
66
|
+
const result = spawnSync(binPath, process.argv.slice(2), {
|
|
67
|
+
stdio: "inherit",
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (result.error) {
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
process.exit(result.status ?? 1);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
let result = run();
|
|
77
|
+
|
|
78
|
+
// Handle EACCES by chmod +x and retrying
|
|
79
|
+
if (result.error && result.error.code === "EACCES") {
|
|
80
|
+
try {
|
|
81
|
+
chmodSync(binPath, 0o755);
|
|
82
|
+
} catch (e) {
|
|
83
|
+
console.error(`Failed to chmod +x ${binPath}: ${e.message}`);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
result = run();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (result.error) {
|
|
90
|
+
console.error(`Failed to start md-serve: ${result.error.message}`);
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@choonkeat/md-serve",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Tiny static file server that renders Markdown as GitHub-styled HTML",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"md-serve": "bin/md-serve.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"postinstall": "node -e \"try{require('fs').chmodSync(require('path').join(__dirname,'bin','md-serve.js'),0o755)}catch(e){}\"",
|
|
14
|
+
"prepare": "node scripts/prepare-local-build.js"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/choonkeat/md-serve.git"
|
|
19
|
+
},
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"optionalDependencies": {
|
|
22
|
+
"@choonkeat/md-serve-darwin-arm64": "0.1.0",
|
|
23
|
+
"@choonkeat/md-serve-darwin-x64": "0.1.0",
|
|
24
|
+
"@choonkeat/md-serve-linux-arm64": "0.1.0",
|
|
25
|
+
"@choonkeat/md-serve-linux-x64": "0.1.0",
|
|
26
|
+
"@choonkeat/md-serve-win32-arm64": "0.1.0",
|
|
27
|
+
"@choonkeat/md-serve-win32-x64": "0.1.0"
|
|
28
|
+
}
|
|
29
|
+
}
|