@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.
@@ -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.75",
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.75",
78
- "@takazudo/zfb-darwin-x64": "0.1.0-next.75",
79
- "@takazudo/zfb-linux-arm64-gnu": "0.1.0-next.75",
80
- "@takazudo/zfb-linux-x64-gnu": "0.1.0-next.75",
81
- "@takazudo/zfb-win32-x64-msvc": "0.1.0-next.75"
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"