@b9g/libuild 0.1.12 → 0.1.14

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/CHANGELOG.md CHANGED
@@ -2,6 +2,36 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.1.14] - 2025-01-14
6
+
7
+ ### Fixed
8
+ - **Eliminate stderr noise from dual-purpose shebang** - Changed from `//bin/true` to standard polyglot pattern `':' //;` to prevent shell from attempting to execute non-existent path, eliminating "No such file or directory" errors while maintaining dual runtime detection
9
+
10
+ ## [0.1.13] - 2025-01-14
11
+
12
+ ### Fixed
13
+ - **Dual runtime shebang for src/ executables** - src/ files referenced in package.json bin field now correctly receive dual runtime shebang support (previously only bin/ directory files were processed)
14
+ - All executable files now have consistent dual runtime behavior regardless of directory location
15
+
16
+ ## [0.1.12] - 2025-01-14
17
+
18
+ ### Added
19
+ - **Dual runtime support** for bin entries with intelligent bun/node detection based on package manager context
20
+ - **Top-level await (TLA) support** with graceful CJS fallback - automatically disables CJS generation when TLA is detected
21
+ - **bin/ directory support** for executable entrypoints alongside src/ entries
22
+ - Respect `engines.bun` field for runtime preferences in dual runtime detection
23
+ - Automatic shebang replacement with shell script wrapper for maximum compatibility
24
+
25
+ ### Changed
26
+ - **Single-batch ESM build** - combined src/ and bin/ builds for better performance
27
+ - **Smart externalization** - entry points are externalized, nested files are bundled to prevent code duplication
28
+ - TypeScript declarations now conditional on tsc availability (no failures in environments without TypeScript)
29
+
30
+ ### Fixed
31
+ - Fix TypeScript declaration generation for bin entries
32
+ - Fix CLI argument parsing for directory paths with npm flags
33
+ - Fix externalization to only apply to entry points, not nested utility files
34
+
5
35
  ## [0.1.11] - 2025-11-02
6
36
 
7
37
  ### Fixed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@b9g/libuild",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "description": "Zero-config library builds",
5
5
  "keywords": [
6
6
  "build",
package/src/cli.js CHANGED
@@ -1,4 +1,5 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env sh
2
+ ':' //; exec "$({ [ "${npm_config_user_agent#bun/}" != "$npm_config_user_agent" ] || true; } && command -v bun || command -v node)" "$0" "$@"
2
3
  /// <reference types="./cli.d.ts" />
3
4
 
4
5
  // src/cli.ts
package/src/libuild.cjs CHANGED
@@ -215233,9 +215233,9 @@ ${content}`;
215233
215233
  function generateRuntimeBanner(pkg) {
215234
215234
  const prefersBun = pkg.engines?.bun !== void 0;
215235
215235
  if (prefersBun) {
215236
- return '//bin/true; exec "$({ [ "${npm_config_user_agent#bun/}" != "$npm_config_user_agent" ] || true; } && command -v bun || command -v node)" "$0" "$@"';
215236
+ return `':' //; exec "$({ [ "\${npm_config_user_agent#bun/}" != "$npm_config_user_agent" ] || true; } && command -v bun || command -v node)" "$0" "$@"`;
215237
215237
  } else {
215238
- return '//bin/true; exec "$([ "${npm_config_user_agent#bun/}" != "$npm_config_user_agent" ] && command -v bun || command -v node)" "$0" "$@"';
215238
+ return `':' //; exec "$([ "\${npm_config_user_agent#bun/}" != "$npm_config_user_agent" ] && command -v bun || command -v node)" "$0" "$@"`;
215239
215239
  }
215240
215240
  }
215241
215241
  async function processJavaScriptExecutable(filePath, runtimeBanner) {
@@ -215716,23 +215716,35 @@ async function setExecutablePermissions(filePath) {
215716
215716
  console.warn(`\u26A0\uFE0F WARNING: Could not set executable permissions for ${filePath}: ${error.message}`);
215717
215717
  }
215718
215718
  }
215719
- async function makeFilesExecutable(pkg, cwd, allBinEntries) {
215719
+ async function makeFilesExecutable(pkg, cwd, allBinEntries, runtimeBanner) {
215720
215720
  const filesToMakeExecutable = [];
215721
+ const filesToProcessForDualRuntime = [];
215722
+ const distDir = Path3.join(cwd, "dist");
215721
215723
  if (pkg.bin) {
215722
215724
  if (typeof pkg.bin === "string") {
215723
- filesToMakeExecutable.push(Path3.join(cwd, pkg.bin));
215725
+ const fullPath = Path3.join(distDir, pkg.bin);
215726
+ filesToMakeExecutable.push(fullPath);
215727
+ if (pkg.bin.endsWith(".js")) {
215728
+ filesToProcessForDualRuntime.push(fullPath);
215729
+ }
215724
215730
  } else if (typeof pkg.bin === "object") {
215725
215731
  for (const binPath of Object.values(pkg.bin)) {
215726
215732
  if (typeof binPath === "string") {
215727
- filesToMakeExecutable.push(Path3.join(cwd, binPath));
215733
+ const fullPath = Path3.join(distDir, binPath);
215734
+ filesToMakeExecutable.push(fullPath);
215735
+ if (binPath.endsWith(".js")) {
215736
+ filesToProcessForDualRuntime.push(fullPath);
215737
+ }
215728
215738
  }
215729
215739
  }
215730
215740
  }
215731
215741
  }
215742
+ const binDirFiles = /* @__PURE__ */ new Set();
215732
215743
  for (const binEntryInfo of allBinEntries) {
215733
215744
  const baseDir = binEntryInfo.source === "src" ? "dist/src/bin" : "dist/bin";
215734
215745
  const jsPath = Path3.join(cwd, baseDir, `${binEntryInfo.name}.js`);
215735
215746
  const cjsPath = Path3.join(cwd, baseDir, `${binEntryInfo.name}.cjs`);
215747
+ binDirFiles.add(jsPath);
215736
215748
  if (!filesToMakeExecutable.includes(jsPath)) {
215737
215749
  filesToMakeExecutable.push(jsPath);
215738
215750
  }
@@ -215740,6 +215752,11 @@ async function makeFilesExecutable(pkg, cwd, allBinEntries) {
215740
215752
  filesToMakeExecutable.push(cjsPath);
215741
215753
  }
215742
215754
  }
215755
+ for (const filePath of filesToProcessForDualRuntime) {
215756
+ if (await fileExists(filePath) && !binDirFiles.has(filePath)) {
215757
+ await processJavaScriptExecutable(filePath, runtimeBanner);
215758
+ }
215759
+ }
215743
215760
  for (const filePath of filesToMakeExecutable) {
215744
215761
  if (await fileExists(filePath)) {
215745
215762
  await setExecutablePermissions(filePath);
@@ -216354,8 +216371,9 @@ async function build2(cwd, save = false) {
216354
216371
  if (save) {
216355
216372
  rootPkg = JSON.parse(await FS3.readFile(pkgPath, "utf-8"));
216356
216373
  }
216357
- if (allBinEntries.length > 0 || pkg.bin) {
216358
- await makeFilesExecutable(pkg, cwd, allBinEntries);
216374
+ if (allBinEntries.length > 0 || fixedDistPkg.bin) {
216375
+ const runtimeBanner = generateRuntimeBanner(pkg);
216376
+ await makeFilesExecutable(fixedDistPkg, cwd, allBinEntries, runtimeBanner);
216359
216377
  }
216360
216378
  return { distPkg: fixedDistPkg, rootPkg };
216361
216379
  }
package/src/libuild.js CHANGED
@@ -220,9 +220,9 @@ ${content}`;
220
220
  function generateRuntimeBanner(pkg) {
221
221
  const prefersBun = pkg.engines?.bun !== void 0;
222
222
  if (prefersBun) {
223
- return '//bin/true; exec "$({ [ "${npm_config_user_agent#bun/}" != "$npm_config_user_agent" ] || true; } && command -v bun || command -v node)" "$0" "$@"';
223
+ return `':' //; exec "$({ [ "\${npm_config_user_agent#bun/}" != "$npm_config_user_agent" ] || true; } && command -v bun || command -v node)" "$0" "$@"`;
224
224
  } else {
225
- return '//bin/true; exec "$([ "${npm_config_user_agent#bun/}" != "$npm_config_user_agent" ] && command -v bun || command -v node)" "$0" "$@"';
225
+ return `':' //; exec "$([ "\${npm_config_user_agent#bun/}" != "$npm_config_user_agent" ] && command -v bun || command -v node)" "$0" "$@"`;
226
226
  }
227
227
  }
228
228
  async function processJavaScriptExecutable(filePath, runtimeBanner) {
@@ -703,23 +703,35 @@ async function setExecutablePermissions(filePath) {
703
703
  console.warn(`\u26A0\uFE0F WARNING: Could not set executable permissions for ${filePath}: ${error.message}`);
704
704
  }
705
705
  }
706
- async function makeFilesExecutable(pkg, cwd, allBinEntries) {
706
+ async function makeFilesExecutable(pkg, cwd, allBinEntries, runtimeBanner) {
707
707
  const filesToMakeExecutable = [];
708
+ const filesToProcessForDualRuntime = [];
709
+ const distDir = Path3.join(cwd, "dist");
708
710
  if (pkg.bin) {
709
711
  if (typeof pkg.bin === "string") {
710
- filesToMakeExecutable.push(Path3.join(cwd, pkg.bin));
712
+ const fullPath = Path3.join(distDir, pkg.bin);
713
+ filesToMakeExecutable.push(fullPath);
714
+ if (pkg.bin.endsWith(".js")) {
715
+ filesToProcessForDualRuntime.push(fullPath);
716
+ }
711
717
  } else if (typeof pkg.bin === "object") {
712
718
  for (const binPath of Object.values(pkg.bin)) {
713
719
  if (typeof binPath === "string") {
714
- filesToMakeExecutable.push(Path3.join(cwd, binPath));
720
+ const fullPath = Path3.join(distDir, binPath);
721
+ filesToMakeExecutable.push(fullPath);
722
+ if (binPath.endsWith(".js")) {
723
+ filesToProcessForDualRuntime.push(fullPath);
724
+ }
715
725
  }
716
726
  }
717
727
  }
718
728
  }
729
+ const binDirFiles = /* @__PURE__ */ new Set();
719
730
  for (const binEntryInfo of allBinEntries) {
720
731
  const baseDir = binEntryInfo.source === "src" ? "dist/src/bin" : "dist/bin";
721
732
  const jsPath = Path3.join(cwd, baseDir, `${binEntryInfo.name}.js`);
722
733
  const cjsPath = Path3.join(cwd, baseDir, `${binEntryInfo.name}.cjs`);
734
+ binDirFiles.add(jsPath);
723
735
  if (!filesToMakeExecutable.includes(jsPath)) {
724
736
  filesToMakeExecutable.push(jsPath);
725
737
  }
@@ -727,6 +739,11 @@ async function makeFilesExecutable(pkg, cwd, allBinEntries) {
727
739
  filesToMakeExecutable.push(cjsPath);
728
740
  }
729
741
  }
742
+ for (const filePath of filesToProcessForDualRuntime) {
743
+ if (await fileExists(filePath) && !binDirFiles.has(filePath)) {
744
+ await processJavaScriptExecutable(filePath, runtimeBanner);
745
+ }
746
+ }
730
747
  for (const filePath of filesToMakeExecutable) {
731
748
  if (await fileExists(filePath)) {
732
749
  await setExecutablePermissions(filePath);
@@ -1341,8 +1358,9 @@ async function build2(cwd, save = false) {
1341
1358
  if (save) {
1342
1359
  rootPkg = JSON.parse(await FS3.readFile(pkgPath, "utf-8"));
1343
1360
  }
1344
- if (allBinEntries.length > 0 || pkg.bin) {
1345
- await makeFilesExecutable(pkg, cwd, allBinEntries);
1361
+ if (allBinEntries.length > 0 || fixedDistPkg.bin) {
1362
+ const runtimeBanner = generateRuntimeBanner(pkg);
1363
+ await makeFilesExecutable(fixedDistPkg, cwd, allBinEntries, runtimeBanner);
1346
1364
  }
1347
1365
  return { distPkg: fixedDistPkg, rootPkg };
1348
1366
  }