@takazudo/zfb 0.1.0-next.75 → 0.1.0-next.76
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/bin/detect-musl.mjs +55 -0
- package/bin/zfb.mjs +13 -0
- package/package.json +6 -6
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Extracted from zfb.mjs so the detection decision can be unit-tested
|
|
2
|
+
// without triggering zfb.mjs's top-level exec/spawn side effects. Pure and
|
|
3
|
+
// dependency-injectable: production callers can omit every option.
|
|
4
|
+
import { readdirSync } from "node:fs";
|
|
5
|
+
|
|
6
|
+
const MUSL_LOADER_DIR = "/lib";
|
|
7
|
+
const MUSL_LOADER_PREFIX = "ld-musl-";
|
|
8
|
+
|
|
9
|
+
// True if a musl dynamic loader file is present (e.g. Alpine's
|
|
10
|
+
// /lib/ld-musl-x86_64.so.1). Reading the directory and matching the prefix
|
|
11
|
+
// covers every arch's loader filename with one probe instead of hardcoding
|
|
12
|
+
// an existsSync path per arch. Mirrors the loader-file probe used by the
|
|
13
|
+
// widely-adopted `detect-libc` npm package.
|
|
14
|
+
function hasMuslLoaderFile(readdirSyncFn) {
|
|
15
|
+
try {
|
|
16
|
+
return readdirSyncFn(MUSL_LOADER_DIR).some((name) => name.startsWith(MUSL_LOADER_PREFIX));
|
|
17
|
+
} catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function defaultGetReport() {
|
|
23
|
+
return process.report?.getReport?.();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// True if Node's process.report exposes a glibc runtime version. glibc-built
|
|
27
|
+
// Node populates header.glibcVersionRuntime; musl-built Node does not. Used
|
|
28
|
+
// only as a fallback signal when the loader-file probe above is inconclusive.
|
|
29
|
+
function hasGlibcVersionRuntime(getReportFn) {
|
|
30
|
+
try {
|
|
31
|
+
return Boolean(getReportFn()?.header?.glibcVersionRuntime);
|
|
32
|
+
} catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Detects musl libc (e.g. Alpine) on Linux, where the gnu-built platform
|
|
39
|
+
* binary would otherwise fail with an opaque dynamic-loader exec error
|
|
40
|
+
* instead of a clear "not supported" message. Always returns false on
|
|
41
|
+
* non-linux platforms (darwin, win32) — zero behavior change there.
|
|
42
|
+
*/
|
|
43
|
+
export function detectMuslLinux({
|
|
44
|
+
platform = process.platform,
|
|
45
|
+
readdirSyncFn = readdirSync,
|
|
46
|
+
getReportFn = defaultGetReport,
|
|
47
|
+
} = {}) {
|
|
48
|
+
if (platform !== "linux") return false;
|
|
49
|
+
// The glibc runtime report is authoritative when present: a Node process
|
|
50
|
+
// that reports a glibc version is definitely glibc-linked and will work,
|
|
51
|
+
// regardless of an unrelated musl loader file sitting on the filesystem
|
|
52
|
+
// (e.g. a `musl` package installed on Debian/Ubuntu for other reasons).
|
|
53
|
+
if (hasGlibcVersionRuntime(getReportFn)) return false;
|
|
54
|
+
return hasMuslLoaderFile(readdirSyncFn);
|
|
55
|
+
}
|
package/bin/zfb.mjs
CHANGED
|
@@ -10,6 +10,7 @@ import { spawn } from "node:child_process";
|
|
|
10
10
|
import { createRequire } from "node:module";
|
|
11
11
|
import { constants as osConstants } from "node:os";
|
|
12
12
|
import { join } from "node:path";
|
|
13
|
+
import { detectMuslLinux } from "./detect-musl.mjs";
|
|
13
14
|
|
|
14
15
|
const require = createRequire(import.meta.url);
|
|
15
16
|
|
|
@@ -32,6 +33,18 @@ if (!pkg) {
|
|
|
32
33
|
process.exit(1);
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
// The gnu-built binary above matches on os/cpu but not on libc: an
|
|
37
|
+
// Alpine/musl-libc Linux install passes the os/cpu check yet would still
|
|
38
|
+
// fail to exec, with a raw, confusing dynamic-loader error. Detect and fail
|
|
39
|
+
// with a clear message before attempting to resolve/spawn the binary.
|
|
40
|
+
if (detectMuslLinux()) {
|
|
41
|
+
console.error(
|
|
42
|
+
"[zfb] musl/Alpine is not supported yet — no @takazudo/zfb-linux-*-musl package exists.\n" +
|
|
43
|
+
" Use a glibc-based Linux image (e.g. Debian/Ubuntu) instead of Alpine.",
|
|
44
|
+
);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
35
48
|
let binPath;
|
|
36
49
|
try {
|
|
37
50
|
// Resolve the platform package's package.json to get the install directory.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@takazudo/zfb",
|
|
3
|
-
"version": "0.1.0-next.
|
|
3
|
+
"version": "0.1.0-next.76",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Rust-built static-site engine for Astro and Next.js users — millisecond rebuilds, single binary. SDK with islands, content collections, pagination, and config helpers.",
|
|
@@ -74,11 +74,11 @@
|
|
|
74
74
|
"LICENSE"
|
|
75
75
|
],
|
|
76
76
|
"optionalDependencies": {
|
|
77
|
-
"@takazudo/zfb-darwin-arm64": "0.1.0-next.
|
|
78
|
-
"@takazudo/zfb-darwin-x64": "0.1.0-next.
|
|
79
|
-
"@takazudo/zfb-linux-arm64-gnu": "0.1.0-next.
|
|
80
|
-
"@takazudo/zfb-linux-x64-gnu": "0.1.0-next.
|
|
81
|
-
"@takazudo/zfb-win32-x64-msvc": "0.1.0-next.
|
|
77
|
+
"@takazudo/zfb-darwin-arm64": "0.1.0-next.76",
|
|
78
|
+
"@takazudo/zfb-darwin-x64": "0.1.0-next.76",
|
|
79
|
+
"@takazudo/zfb-linux-arm64-gnu": "0.1.0-next.76",
|
|
80
|
+
"@takazudo/zfb-linux-x64-gnu": "0.1.0-next.76",
|
|
81
|
+
"@takazudo/zfb-win32-x64-msvc": "0.1.0-next.76"
|
|
82
82
|
},
|
|
83
83
|
"publishConfig": {
|
|
84
84
|
"access": "public"
|