@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 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
@@ -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
+ }