@b9g/libuild 0.1.11 → 0.1.12
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/package.json +1 -1
- package/src/cli.cjs +38 -2
- package/src/cli.js +38 -2
- package/src/libuild.cjs +339 -67
- package/src/libuild.js +347 -67
package/package.json
CHANGED
package/src/cli.cjs
CHANGED
|
@@ -83,7 +83,42 @@ async function main() {
|
|
|
83
83
|
process.exit(0);
|
|
84
84
|
}
|
|
85
85
|
const command = positionals[0] || "build";
|
|
86
|
-
|
|
86
|
+
let targetDir;
|
|
87
|
+
for (let i = 1; i < positionals.length; i++) {
|
|
88
|
+
const arg = positionals[i];
|
|
89
|
+
const flagValueFlags = ["--tag", "--access", "--registry", "--otp", "--workspace"];
|
|
90
|
+
const isValueForFlag = flagValueFlags.some((flag) => {
|
|
91
|
+
const flagIndex = process.argv.indexOf(flag);
|
|
92
|
+
const argIndex = process.argv.indexOf(arg);
|
|
93
|
+
return flagIndex !== -1 && argIndex === flagIndex + 1;
|
|
94
|
+
});
|
|
95
|
+
if (isValueForFlag) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (!arg.startsWith("--")) {
|
|
99
|
+
try {
|
|
100
|
+
const isSystemPath = Path.isAbsolute(arg) && (arg.startsWith("/bin/") || arg.startsWith("/usr/") || arg.startsWith("/etc/") || arg.startsWith("/var/") || arg.startsWith("/opt/") || arg.startsWith("/tmp/") || arg.startsWith("/System/") || arg.startsWith("/Applications/"));
|
|
101
|
+
if (isSystemPath) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
const resolvedPath = Path.resolve(arg);
|
|
105
|
+
if (arg.includes("/") || arg.includes("\\") || arg === "." || arg === ".." || arg.startsWith("./") || arg.startsWith("../")) {
|
|
106
|
+
targetDir = arg;
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
const fs = await import("fs/promises");
|
|
110
|
+
try {
|
|
111
|
+
const stat = await fs.stat(resolvedPath);
|
|
112
|
+
if (stat.isDirectory() && !Path.isAbsolute(arg)) {
|
|
113
|
+
targetDir = arg;
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
} catch {
|
|
117
|
+
}
|
|
118
|
+
} catch {
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
87
122
|
const cwd = targetDir ? Path.resolve(targetDir) : process.cwd();
|
|
88
123
|
const shouldSave = values.save || command === "publish" && !values["no-save"];
|
|
89
124
|
const allowedNpmFlags = [
|
|
@@ -98,7 +133,8 @@ async function main() {
|
|
|
98
133
|
"--include-workspace-root"
|
|
99
134
|
];
|
|
100
135
|
const rawExtraArgs = process.argv.slice(2).filter(
|
|
101
|
-
(arg) => !["build", "publish"].includes(arg) && !["--save", "--no-save", "--help", "-h", "--version", "-v"].includes(arg)
|
|
136
|
+
(arg) => !["build", "publish"].includes(arg) && !["--save", "--no-save", "--help", "-h", "--version", "-v"].includes(arg) && arg !== targetDir
|
|
137
|
+
// Don't filter out the target directory
|
|
102
138
|
);
|
|
103
139
|
const extraArgs = [];
|
|
104
140
|
for (let i = 0; i < rawExtraArgs.length; i++) {
|
package/src/cli.js
CHANGED
|
@@ -61,7 +61,42 @@ async function main() {
|
|
|
61
61
|
process.exit(0);
|
|
62
62
|
}
|
|
63
63
|
const command = positionals[0] || "build";
|
|
64
|
-
|
|
64
|
+
let targetDir;
|
|
65
|
+
for (let i = 1; i < positionals.length; i++) {
|
|
66
|
+
const arg = positionals[i];
|
|
67
|
+
const flagValueFlags = ["--tag", "--access", "--registry", "--otp", "--workspace"];
|
|
68
|
+
const isValueForFlag = flagValueFlags.some((flag) => {
|
|
69
|
+
const flagIndex = process.argv.indexOf(flag);
|
|
70
|
+
const argIndex = process.argv.indexOf(arg);
|
|
71
|
+
return flagIndex !== -1 && argIndex === flagIndex + 1;
|
|
72
|
+
});
|
|
73
|
+
if (isValueForFlag) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (!arg.startsWith("--")) {
|
|
77
|
+
try {
|
|
78
|
+
const isSystemPath = Path.isAbsolute(arg) && (arg.startsWith("/bin/") || arg.startsWith("/usr/") || arg.startsWith("/etc/") || arg.startsWith("/var/") || arg.startsWith("/opt/") || arg.startsWith("/tmp/") || arg.startsWith("/System/") || arg.startsWith("/Applications/"));
|
|
79
|
+
if (isSystemPath) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const resolvedPath = Path.resolve(arg);
|
|
83
|
+
if (arg.includes("/") || arg.includes("\\") || arg === "." || arg === ".." || arg.startsWith("./") || arg.startsWith("../")) {
|
|
84
|
+
targetDir = arg;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
const fs = await import("fs/promises");
|
|
88
|
+
try {
|
|
89
|
+
const stat = await fs.stat(resolvedPath);
|
|
90
|
+
if (stat.isDirectory() && !Path.isAbsolute(arg)) {
|
|
91
|
+
targetDir = arg;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
} catch {
|
|
95
|
+
}
|
|
96
|
+
} catch {
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
65
100
|
const cwd = targetDir ? Path.resolve(targetDir) : process.cwd();
|
|
66
101
|
const shouldSave = values.save || command === "publish" && !values["no-save"];
|
|
67
102
|
const allowedNpmFlags = [
|
|
@@ -76,7 +111,8 @@ async function main() {
|
|
|
76
111
|
"--include-workspace-root"
|
|
77
112
|
];
|
|
78
113
|
const rawExtraArgs = process.argv.slice(2).filter(
|
|
79
|
-
(arg) => !["build", "publish"].includes(arg) && !["--save", "--no-save", "--help", "-h", "--version", "-v"].includes(arg)
|
|
114
|
+
(arg) => !["build", "publish"].includes(arg) && !["--save", "--no-save", "--help", "-h", "--version", "-v"].includes(arg) && arg !== targetDir
|
|
115
|
+
// Don't filter out the target directory
|
|
80
116
|
);
|
|
81
117
|
const extraArgs = [];
|
|
82
118
|
for (let i = 0; i < rawExtraArgs.length; i++) {
|
package/src/libuild.cjs
CHANGED
|
@@ -215088,6 +215088,21 @@ function externalEntrypointsPlugin(options) {
|
|
|
215088
215088
|
};
|
|
215089
215089
|
}
|
|
215090
215090
|
});
|
|
215091
|
+
build3.onResolve({ filter: /^\.\.\/(?:src|bin)\// }, (args) => {
|
|
215092
|
+
const withoutExt = args.path.replace(/\.(ts|js)$/, "");
|
|
215093
|
+
const match = withoutExt.match(/^\.\.\/(?:src|bin)\/(.+)$/);
|
|
215094
|
+
if (match) {
|
|
215095
|
+
const entryName = match[1];
|
|
215096
|
+
if (externalEntries.includes(entryName)) {
|
|
215097
|
+
const dir = withoutExt.match(/^(\.\.\/(?:src|bin))\//)?.[1];
|
|
215098
|
+
return {
|
|
215099
|
+
path: `${dir}/${entryName}${outputExtension}`,
|
|
215100
|
+
external: true
|
|
215101
|
+
};
|
|
215102
|
+
}
|
|
215103
|
+
}
|
|
215104
|
+
return void 0;
|
|
215105
|
+
});
|
|
215091
215106
|
}
|
|
215092
215107
|
};
|
|
215093
215108
|
}
|
|
@@ -215113,27 +215128,34 @@ function dtsPlugin(options) {
|
|
|
215113
215128
|
let TS;
|
|
215114
215129
|
try {
|
|
215115
215130
|
TS = await Promise.resolve().then(() => __toESM(require_typescript(), 1));
|
|
215116
|
-
} catch {
|
|
215131
|
+
} catch (error) {
|
|
215117
215132
|
return;
|
|
215118
215133
|
}
|
|
215119
215134
|
const tsFiles = entryFiles.filter((file) => {
|
|
215120
215135
|
if (!file.endsWith(".ts"))
|
|
215121
215136
|
return false;
|
|
215122
215137
|
return options.entryPoints.some((entryPoint) => {
|
|
215123
|
-
|
|
215124
|
-
|
|
215125
|
-
|
|
215138
|
+
try {
|
|
215139
|
+
const fs = require("fs");
|
|
215140
|
+
const normalizedEntry = fs.realpathSync(Path2.resolve(entryPoint));
|
|
215141
|
+
const normalizedFile = fs.realpathSync(Path2.resolve(file));
|
|
215142
|
+
return normalizedEntry === normalizedFile;
|
|
215143
|
+
} catch {
|
|
215144
|
+
const normalizedEntry = Path2.resolve(entryPoint);
|
|
215145
|
+
const normalizedFile = Path2.resolve(file);
|
|
215146
|
+
return normalizedEntry === normalizedFile;
|
|
215147
|
+
}
|
|
215126
215148
|
});
|
|
215127
215149
|
});
|
|
215128
215150
|
if (tsFiles.length === 0) {
|
|
215129
215151
|
return;
|
|
215130
215152
|
}
|
|
215131
215153
|
try {
|
|
215154
|
+
await FS2.mkdir(options.outDir, { recursive: true });
|
|
215132
215155
|
const compilerOptions = {
|
|
215133
215156
|
declaration: true,
|
|
215134
215157
|
emitDeclarationOnly: true,
|
|
215135
215158
|
outDir: options.outDir,
|
|
215136
|
-
rootDir: options.rootDir,
|
|
215137
215159
|
skipLibCheck: true,
|
|
215138
215160
|
esModuleInterop: true,
|
|
215139
215161
|
target: TS.ScriptTarget.ES2020,
|
|
@@ -215208,6 +215230,38 @@ ${content}`;
|
|
|
215208
215230
|
}
|
|
215209
215231
|
|
|
215210
215232
|
// src/libuild.ts
|
|
215233
|
+
function generateRuntimeBanner(pkg) {
|
|
215234
|
+
const prefersBun = pkg.engines?.bun !== void 0;
|
|
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" "$@"';
|
|
215237
|
+
} else {
|
|
215238
|
+
return '//bin/true; exec "$([ "${npm_config_user_agent#bun/}" != "$npm_config_user_agent" ] && command -v bun || command -v node)" "$0" "$@"';
|
|
215239
|
+
}
|
|
215240
|
+
}
|
|
215241
|
+
async function processJavaScriptExecutable(filePath, runtimeBanner) {
|
|
215242
|
+
try {
|
|
215243
|
+
const contents = await FS3.readFile(filePath, "utf8");
|
|
215244
|
+
const lines = contents.split("\n");
|
|
215245
|
+
let modified = false;
|
|
215246
|
+
if (lines[0]?.startsWith("#!")) {
|
|
215247
|
+
const existingShebang = lines[0];
|
|
215248
|
+
if (existingShebang.includes("python") || existingShebang.includes("bash") || !existingShebang.includes("node") && !existingShebang.includes("bun") && !existingShebang.includes("sh")) {
|
|
215249
|
+
console.warn(`\u26A0\uFE0F WARNING: ${filePath} has non-JavaScript shebang but is a JS file. Adding dual runtime support.`);
|
|
215250
|
+
}
|
|
215251
|
+
lines[0] = "#!/usr/bin/env sh";
|
|
215252
|
+
lines.splice(1, 0, runtimeBanner);
|
|
215253
|
+
modified = true;
|
|
215254
|
+
} else {
|
|
215255
|
+
lines.unshift("#!/usr/bin/env sh", runtimeBanner);
|
|
215256
|
+
modified = true;
|
|
215257
|
+
}
|
|
215258
|
+
if (modified) {
|
|
215259
|
+
await FS3.writeFile(filePath, lines.join("\n"));
|
|
215260
|
+
}
|
|
215261
|
+
} catch (error) {
|
|
215262
|
+
console.warn(`\u26A0\uFE0F WARNING: Could not process executable ${filePath}: ${error.message}`);
|
|
215263
|
+
}
|
|
215264
|
+
}
|
|
215211
215265
|
function isValidEntrypoint(filename) {
|
|
215212
215266
|
if (!filename.endsWith(".ts") && !filename.endsWith(".js"))
|
|
215213
215267
|
return false;
|
|
@@ -215234,6 +215288,22 @@ async function findEntrypoints(srcDir) {
|
|
|
215234
215288
|
return isValidEntrypoint(dirent.name);
|
|
215235
215289
|
}).map((dirent) => Path3.basename(dirent.name, Path3.extname(dirent.name))).sort();
|
|
215236
215290
|
}
|
|
215291
|
+
async function findBinEntrypoints(binDir) {
|
|
215292
|
+
try {
|
|
215293
|
+
const files = await FS3.readdir(binDir, { withFileTypes: true });
|
|
215294
|
+
return files.filter((dirent) => {
|
|
215295
|
+
if (dirent.isDirectory()) {
|
|
215296
|
+
return false;
|
|
215297
|
+
}
|
|
215298
|
+
return isValidEntrypoint(dirent.name);
|
|
215299
|
+
}).map((dirent) => Path3.basename(dirent.name, Path3.extname(dirent.name))).sort();
|
|
215300
|
+
} catch (error) {
|
|
215301
|
+
if (error.code === "ENOENT") {
|
|
215302
|
+
return [];
|
|
215303
|
+
}
|
|
215304
|
+
throw error;
|
|
215305
|
+
}
|
|
215306
|
+
}
|
|
215237
215307
|
function detectMainEntry(pkg, entries) {
|
|
215238
215308
|
function extractEntryFromPath(path) {
|
|
215239
215309
|
const match = path.match(/\.\/src\/([^.]+)/);
|
|
@@ -215331,18 +215401,38 @@ function checkIfExportIsStale(exportKey, exportValue, entries) {
|
|
|
215331
215401
|
}
|
|
215332
215402
|
return entryName ? !entries.includes(entryName) : false;
|
|
215333
215403
|
}
|
|
215334
|
-
function generateExports(entries, mainEntry, options, existingExports = {}) {
|
|
215404
|
+
async function generateExports(entries, mainEntry, options, existingExports = {}, distDir, allBinEntries = []) {
|
|
215335
215405
|
const exports2 = {};
|
|
215336
215406
|
const staleExports = [];
|
|
215337
|
-
function createExportEntry(entry) {
|
|
215338
|
-
|
|
215339
|
-
|
|
215340
|
-
|
|
215341
|
-
|
|
215342
|
-
|
|
215343
|
-
|
|
215407
|
+
async function createExportEntry(entry) {
|
|
215408
|
+
if (entry.startsWith("bin/")) {
|
|
215409
|
+
const binEntry = entry.replace("bin/", "");
|
|
215410
|
+
const exportEntry = {
|
|
215411
|
+
import: `./bin/${binEntry}.js`
|
|
215412
|
+
};
|
|
215413
|
+
if (distDir) {
|
|
215414
|
+
const dtsPath = Path3.join(distDir, "bin", `${binEntry}.d.ts`);
|
|
215415
|
+
if (await fileExists(dtsPath)) {
|
|
215416
|
+
exportEntry.types = `./bin/${binEntry}.d.ts`;
|
|
215417
|
+
}
|
|
215418
|
+
}
|
|
215419
|
+
return exportEntry;
|
|
215420
|
+
} else {
|
|
215421
|
+
const exportEntry = {
|
|
215422
|
+
import: `./src/${entry}.js`
|
|
215423
|
+
};
|
|
215424
|
+
if (distDir) {
|
|
215425
|
+
const dtsPath = Path3.join(distDir, "src", `${entry}.d.ts`);
|
|
215426
|
+
const exists = await fileExists(dtsPath);
|
|
215427
|
+
if (exists) {
|
|
215428
|
+
exportEntry.types = `./src/${entry}.d.ts`;
|
|
215429
|
+
}
|
|
215430
|
+
}
|
|
215431
|
+
if (options.formats.cjs) {
|
|
215432
|
+
exportEntry.require = `./src/${entry}.cjs`;
|
|
215433
|
+
}
|
|
215434
|
+
return exportEntry;
|
|
215344
215435
|
}
|
|
215345
|
-
return exportEntry;
|
|
215346
215436
|
}
|
|
215347
215437
|
function expandExistingExport(existing, entryFromPath) {
|
|
215348
215438
|
if (typeof existing === "string") {
|
|
@@ -215416,7 +215506,7 @@ function generateExports(entries, mainEntry, options, existingExports = {}) {
|
|
|
215416
215506
|
}
|
|
215417
215507
|
}
|
|
215418
215508
|
if (!exports2["."]) {
|
|
215419
|
-
exports2["."] = createExportEntry(mainEntry);
|
|
215509
|
+
exports2["."] = await createExportEntry(mainEntry);
|
|
215420
215510
|
} else {
|
|
215421
215511
|
exports2["."] = expandExistingExport(exports2["."], mainEntry);
|
|
215422
215512
|
}
|
|
@@ -215425,7 +215515,7 @@ function generateExports(entries, mainEntry, options, existingExports = {}) {
|
|
|
215425
215515
|
continue;
|
|
215426
215516
|
const key = `./${entry}`;
|
|
215427
215517
|
if (!exports2[key]) {
|
|
215428
|
-
exports2[key] = createExportEntry(entry);
|
|
215518
|
+
exports2[key] = await createExportEntry(entry);
|
|
215429
215519
|
} else {
|
|
215430
215520
|
exports2[key] = expandExistingExport(exports2[key], entry);
|
|
215431
215521
|
}
|
|
@@ -215478,13 +215568,30 @@ async function validateSingleBinPath(binPath, fieldName, cwd, save) {
|
|
|
215478
215568
|
if (save) {
|
|
215479
215569
|
return;
|
|
215480
215570
|
}
|
|
215481
|
-
if (binPath.startsWith("dist/src/") || binPath.startsWith("./dist/src/")) {
|
|
215571
|
+
if (binPath.startsWith("dist/src/") || binPath.startsWith("./dist/src/") || binPath.startsWith("dist/bin/") || binPath.startsWith("./dist/bin/")) {
|
|
215482
215572
|
const fullPath2 = Path3.join(cwd, binPath);
|
|
215483
215573
|
const distExists = await fileExists(fullPath2);
|
|
215484
215574
|
if (distExists) {
|
|
215485
215575
|
return;
|
|
215486
215576
|
}
|
|
215487
|
-
|
|
215577
|
+
let srcPath;
|
|
215578
|
+
let sourceDir;
|
|
215579
|
+
if (binPath.startsWith("./dist/src/")) {
|
|
215580
|
+
srcPath = binPath.replace("./dist/src/", "src/");
|
|
215581
|
+
sourceDir = "src";
|
|
215582
|
+
} else if (binPath.startsWith("dist/src/")) {
|
|
215583
|
+
srcPath = binPath.replace("dist/src/", "src/");
|
|
215584
|
+
sourceDir = "src";
|
|
215585
|
+
} else if (binPath.startsWith("./dist/bin/")) {
|
|
215586
|
+
srcPath = binPath.replace("./dist/bin/", "bin/");
|
|
215587
|
+
sourceDir = "bin";
|
|
215588
|
+
} else if (binPath.startsWith("dist/bin/")) {
|
|
215589
|
+
srcPath = binPath.replace("dist/bin/", "bin/");
|
|
215590
|
+
sourceDir = "bin";
|
|
215591
|
+
} else {
|
|
215592
|
+
srcPath = binPath;
|
|
215593
|
+
sourceDir = "src";
|
|
215594
|
+
}
|
|
215488
215595
|
const basePath = srcPath.replace(/\.(js|cjs|mjs)$/, "");
|
|
215489
215596
|
const tsPath = Path3.join(cwd, basePath + ".ts");
|
|
215490
215597
|
const jsPath = Path3.join(cwd, basePath + ".js");
|
|
@@ -215511,7 +215618,16 @@ async function validateSingleBinPath(binPath, fieldName, cwd, save) {
|
|
|
215511
215618
|
if (pathExists) {
|
|
215512
215619
|
return;
|
|
215513
215620
|
}
|
|
215514
|
-
if (binPath.startsWith("src/") || binPath.startsWith("./src/")) {
|
|
215621
|
+
if (binPath.startsWith("src/") || binPath.startsWith("./src/") || binPath.startsWith("bin/") || binPath.startsWith("./bin/")) {
|
|
215622
|
+
let normalizedPath = binPath.startsWith("./") ? binPath.slice(2) : binPath;
|
|
215623
|
+
if (normalizedPath.startsWith("src/")) {
|
|
215624
|
+
const srcRelativePath = normalizedPath.replace("src/", "");
|
|
215625
|
+
if (srcRelativePath.includes("/")) {
|
|
215626
|
+
console.warn(`\u26A0\uFE0F WARNING: ${fieldName} field points to "${binPath}" which is in a subdirectory of src/.`);
|
|
215627
|
+
console.warn(` libuild only auto-detects top-level src/ files as entrypoints.`);
|
|
215628
|
+
console.warn(` Consider moving the file to the top-level src/ directory or use the bin/ directory for executables.`);
|
|
215629
|
+
}
|
|
215630
|
+
}
|
|
215515
215631
|
const basePath = fullPath.replace(/\.(js|cjs|mjs)$/, "");
|
|
215516
215632
|
const tsPath = basePath + ".ts";
|
|
215517
215633
|
const jsPath = basePath + ".js";
|
|
@@ -215536,10 +215652,19 @@ function transformBinPaths(value) {
|
|
|
215536
215652
|
if (value.startsWith("dist/src/")) {
|
|
215537
215653
|
return value.replace("dist/", "");
|
|
215538
215654
|
}
|
|
215655
|
+
if (value.startsWith("./dist/bin/")) {
|
|
215656
|
+
return value.replace("./dist/", "");
|
|
215657
|
+
}
|
|
215658
|
+
if (value.startsWith("dist/bin/")) {
|
|
215659
|
+
return value.replace("dist/", "");
|
|
215660
|
+
}
|
|
215539
215661
|
if (value.startsWith("./src/")) {
|
|
215540
215662
|
return value.replace("./", "");
|
|
215541
215663
|
}
|
|
215542
|
-
if (value.startsWith("
|
|
215664
|
+
if (value.startsWith("./bin/")) {
|
|
215665
|
+
return value.replace("./", "");
|
|
215666
|
+
}
|
|
215667
|
+
if (value.startsWith("src/") || value === "src" || value.startsWith("bin/") || value === "bin") {
|
|
215543
215668
|
return value;
|
|
215544
215669
|
}
|
|
215545
215670
|
return value;
|
|
@@ -215584,6 +215709,43 @@ function fixExportsForDist(obj) {
|
|
|
215584
215709
|
}
|
|
215585
215710
|
return obj;
|
|
215586
215711
|
}
|
|
215712
|
+
async function setExecutablePermissions(filePath) {
|
|
215713
|
+
try {
|
|
215714
|
+
await FS3.chmod(filePath, 493);
|
|
215715
|
+
} catch (error) {
|
|
215716
|
+
console.warn(`\u26A0\uFE0F WARNING: Could not set executable permissions for ${filePath}: ${error.message}`);
|
|
215717
|
+
}
|
|
215718
|
+
}
|
|
215719
|
+
async function makeFilesExecutable(pkg, cwd, allBinEntries) {
|
|
215720
|
+
const filesToMakeExecutable = [];
|
|
215721
|
+
if (pkg.bin) {
|
|
215722
|
+
if (typeof pkg.bin === "string") {
|
|
215723
|
+
filesToMakeExecutable.push(Path3.join(cwd, pkg.bin));
|
|
215724
|
+
} else if (typeof pkg.bin === "object") {
|
|
215725
|
+
for (const binPath of Object.values(pkg.bin)) {
|
|
215726
|
+
if (typeof binPath === "string") {
|
|
215727
|
+
filesToMakeExecutable.push(Path3.join(cwd, binPath));
|
|
215728
|
+
}
|
|
215729
|
+
}
|
|
215730
|
+
}
|
|
215731
|
+
}
|
|
215732
|
+
for (const binEntryInfo of allBinEntries) {
|
|
215733
|
+
const baseDir = binEntryInfo.source === "src" ? "dist/src/bin" : "dist/bin";
|
|
215734
|
+
const jsPath = Path3.join(cwd, baseDir, `${binEntryInfo.name}.js`);
|
|
215735
|
+
const cjsPath = Path3.join(cwd, baseDir, `${binEntryInfo.name}.cjs`);
|
|
215736
|
+
if (!filesToMakeExecutable.includes(jsPath)) {
|
|
215737
|
+
filesToMakeExecutable.push(jsPath);
|
|
215738
|
+
}
|
|
215739
|
+
if (!filesToMakeExecutable.includes(cjsPath)) {
|
|
215740
|
+
filesToMakeExecutable.push(cjsPath);
|
|
215741
|
+
}
|
|
215742
|
+
}
|
|
215743
|
+
for (const filePath of filesToMakeExecutable) {
|
|
215744
|
+
if (await fileExists(filePath)) {
|
|
215745
|
+
await setExecutablePermissions(filePath);
|
|
215746
|
+
}
|
|
215747
|
+
}
|
|
215748
|
+
}
|
|
215587
215749
|
async function resolveWorkspaceDependencies(dependencies, cwd) {
|
|
215588
215750
|
if (!dependencies)
|
|
215589
215751
|
return void 0;
|
|
@@ -215643,7 +215805,7 @@ async function resolveWorkspaceVersion(packageName, workspaceSpec, cwd) {
|
|
|
215643
215805
|
return workspaceSpec;
|
|
215644
215806
|
}
|
|
215645
215807
|
}
|
|
215646
|
-
async function cleanPackageJSON(pkg, mainEntry, options, cwd) {
|
|
215808
|
+
async function cleanPackageJSON(pkg, mainEntry, options, cwd, distDir) {
|
|
215647
215809
|
const cleaned = {
|
|
215648
215810
|
name: pkg.name,
|
|
215649
215811
|
version: pkg.version
|
|
@@ -215708,7 +215870,13 @@ async function cleanPackageJSON(pkg, mainEntry, options, cwd) {
|
|
|
215708
215870
|
cleaned.main = `src/${mainEntry}.cjs`;
|
|
215709
215871
|
}
|
|
215710
215872
|
cleaned.module = `src/${mainEntry}.js`;
|
|
215711
|
-
|
|
215873
|
+
if (distDir) {
|
|
215874
|
+
const dtsPath = Path3.join(distDir, "src", `${mainEntry}.d.ts`);
|
|
215875
|
+
const exists = await fileExists(dtsPath);
|
|
215876
|
+
if (exists) {
|
|
215877
|
+
cleaned.types = `src/${mainEntry}.d.ts`;
|
|
215878
|
+
}
|
|
215879
|
+
}
|
|
215712
215880
|
return cleaned;
|
|
215713
215881
|
}
|
|
215714
215882
|
async function fileExists(filePath) {
|
|
@@ -215760,9 +215928,19 @@ async function build2(cwd, save = false) {
|
|
|
215760
215928
|
console.warn(" Add 'dist/' to your .gitignore file");
|
|
215761
215929
|
}
|
|
215762
215930
|
}
|
|
215763
|
-
const
|
|
215764
|
-
|
|
215765
|
-
|
|
215931
|
+
const binDir = Path3.join(cwd, "bin");
|
|
215932
|
+
const srcEntries = await findEntrypoints(srcDir);
|
|
215933
|
+
const binEntries = await findBinEntrypoints(binDir);
|
|
215934
|
+
const allBinEntries = binEntries.map((entry) => ({ name: entry, source: "top-level" }));
|
|
215935
|
+
const entries = [
|
|
215936
|
+
...srcEntries,
|
|
215937
|
+
...allBinEntries.map((entry) => `bin/${entry.name}`)
|
|
215938
|
+
];
|
|
215939
|
+
if (srcEntries.length === 0 && allBinEntries.length === 0) {
|
|
215940
|
+
throw new Error("No entry points found in src/ or bin/");
|
|
215941
|
+
}
|
|
215942
|
+
if (allBinEntries.length > 0) {
|
|
215943
|
+
console.info(` Found bin entries: ${allBinEntries.map((entry) => entry.name).join(", ")}`);
|
|
215766
215944
|
}
|
|
215767
215945
|
const options = {
|
|
215768
215946
|
formats: {
|
|
@@ -215773,7 +215951,7 @@ async function build2(cwd, save = false) {
|
|
|
215773
215951
|
umd: entries.includes("umd")
|
|
215774
215952
|
}
|
|
215775
215953
|
};
|
|
215776
|
-
const mainEntry = detectMainEntry(pkg,
|
|
215954
|
+
const mainEntry = detectMainEntry(pkg, srcEntries);
|
|
215777
215955
|
console.info(" Found entries:", entries.join(", "));
|
|
215778
215956
|
console.info(" Main entry:", mainEntry);
|
|
215779
215957
|
if (options.formats.cjs) {
|
|
@@ -215804,11 +215982,29 @@ async function build2(cwd, save = false) {
|
|
|
215804
215982
|
const entryPoints = [];
|
|
215805
215983
|
const umdEntries = [];
|
|
215806
215984
|
for (const entry of entries) {
|
|
215807
|
-
|
|
215808
|
-
|
|
215985
|
+
let entryPath;
|
|
215986
|
+
let jsEntryPath;
|
|
215987
|
+
let sourceDir;
|
|
215988
|
+
if (entry.startsWith("bin/")) {
|
|
215989
|
+
const binEntryName = entry.replace("bin/", "");
|
|
215990
|
+
const binEntryInfo = allBinEntries.find((binEntry) => binEntry.name === binEntryName);
|
|
215991
|
+
if (binEntryInfo?.source === "src") {
|
|
215992
|
+
entryPath = Path3.join(srcDir, "bin", `${binEntryName}.ts`);
|
|
215993
|
+
jsEntryPath = Path3.join(srcDir, "bin", `${binEntryName}.js`);
|
|
215994
|
+
sourceDir = "src/bin/";
|
|
215995
|
+
} else {
|
|
215996
|
+
entryPath = Path3.join(binDir, `${binEntryName}.ts`);
|
|
215997
|
+
jsEntryPath = Path3.join(binDir, `${binEntryName}.js`);
|
|
215998
|
+
sourceDir = "bin/";
|
|
215999
|
+
}
|
|
216000
|
+
} else {
|
|
216001
|
+
entryPath = Path3.join(srcDir, `${entry}.ts`);
|
|
216002
|
+
jsEntryPath = Path3.join(srcDir, `${entry}.js`);
|
|
216003
|
+
sourceDir = "src/";
|
|
216004
|
+
}
|
|
215809
216005
|
const actualPath = await fileExists(entryPath) ? entryPath : jsEntryPath;
|
|
215810
216006
|
if (!await fileExists(actualPath)) {
|
|
215811
|
-
throw new Error(`Entry point file not found: ${actualPath}. Expected ${entry}.ts or ${entry}.js in
|
|
216007
|
+
throw new Error(`Entry point file not found: ${actualPath}. Expected ${entry.replace("bin/", "")}.ts or ${entry.replace("bin/", "")}.js in ${sourceDir} directory.`);
|
|
215812
216008
|
}
|
|
215813
216009
|
if (entry === "umd") {
|
|
215814
216010
|
umdEntries.push(actualPath);
|
|
@@ -215816,58 +216012,107 @@ async function build2(cwd, save = false) {
|
|
|
215816
216012
|
entryPoints.push(actualPath);
|
|
215817
216013
|
}
|
|
215818
216014
|
}
|
|
216015
|
+
const srcEntryPoints = entryPoints.filter((path) => path.includes(srcDir));
|
|
216016
|
+
const binEntryPoints = entryPoints.filter((path) => path.includes(binDir));
|
|
216017
|
+
const distBinDir = Path3.join(distDir, "bin");
|
|
216018
|
+
if (binEntryPoints.length > 0) {
|
|
216019
|
+
await FS3.mkdir(distBinDir, { recursive: true });
|
|
216020
|
+
}
|
|
215819
216021
|
if (entryPoints.length > 0) {
|
|
215820
|
-
|
|
216022
|
+
console.info(` Building ${entryPoints.length} entries (ESM)...`);
|
|
216023
|
+
const srcEntryNames = srcEntryPoints.map((path) => {
|
|
215821
216024
|
const name = Path3.basename(path, Path3.extname(path));
|
|
215822
216025
|
return name;
|
|
215823
216026
|
});
|
|
215824
|
-
|
|
215825
|
-
|
|
215826
|
-
|
|
215827
|
-
outdir: distSrcDir,
|
|
215828
|
-
format: "esm",
|
|
215829
|
-
outExtension: { ".js": ".js" },
|
|
215830
|
-
bundle: true,
|
|
215831
|
-
minify: false,
|
|
215832
|
-
sourcemap: false,
|
|
215833
|
-
external: externalDeps,
|
|
215834
|
-
platform: "node",
|
|
215835
|
-
target: "node18",
|
|
215836
|
-
packages: "external",
|
|
215837
|
-
supported: { "import-attributes": true },
|
|
215838
|
-
plugins: [
|
|
215839
|
-
externalEntrypointsPlugin({
|
|
215840
|
-
entryNames,
|
|
215841
|
-
outputExtension: ".js"
|
|
215842
|
-
}),
|
|
215843
|
-
dtsPlugin({
|
|
215844
|
-
outDir: distSrcDir,
|
|
215845
|
-
rootDir: srcDir,
|
|
215846
|
-
entryPoints
|
|
215847
|
-
})
|
|
215848
|
-
]
|
|
216027
|
+
const binEntryNames = binEntryPoints.map((path) => {
|
|
216028
|
+
const name = Path3.basename(path, Path3.extname(path));
|
|
216029
|
+
return name;
|
|
215849
216030
|
});
|
|
215850
|
-
|
|
215851
|
-
|
|
216031
|
+
const allESMEntryPoints = [...srcEntryPoints, ...binEntryPoints];
|
|
216032
|
+
const allEntryNames = [...srcEntryNames, ...binEntryNames];
|
|
216033
|
+
if (allESMEntryPoints.length > 0) {
|
|
215852
216034
|
await ESBuild.build({
|
|
215853
|
-
entryPoints,
|
|
215854
|
-
outdir:
|
|
215855
|
-
|
|
215856
|
-
|
|
216035
|
+
entryPoints: allESMEntryPoints,
|
|
216036
|
+
outdir: distDir,
|
|
216037
|
+
outbase: cwd,
|
|
216038
|
+
// Preserve src/ and bin/ directory structure
|
|
216039
|
+
format: "esm",
|
|
216040
|
+
outExtension: { ".js": ".js" },
|
|
215857
216041
|
bundle: true,
|
|
215858
216042
|
minify: false,
|
|
215859
216043
|
sourcemap: false,
|
|
215860
216044
|
external: externalDeps,
|
|
215861
216045
|
platform: "node",
|
|
215862
216046
|
target: "node18",
|
|
216047
|
+
packages: "external",
|
|
215863
216048
|
supported: { "import-attributes": true },
|
|
215864
216049
|
plugins: [
|
|
215865
216050
|
externalEntrypointsPlugin({
|
|
215866
|
-
entryNames,
|
|
215867
|
-
outputExtension: ".
|
|
215868
|
-
})
|
|
216051
|
+
entryNames: allEntryNames,
|
|
216052
|
+
outputExtension: ".js"
|
|
216053
|
+
}),
|
|
216054
|
+
// Generate TypeScript declarations for src entries
|
|
216055
|
+
...srcEntryPoints.length > 0 ? [dtsPlugin({
|
|
216056
|
+
outDir: distSrcDir,
|
|
216057
|
+
rootDir: srcDir,
|
|
216058
|
+
entryPoints: srcEntryPoints
|
|
216059
|
+
})] : [],
|
|
216060
|
+
// Generate TypeScript declarations for bin entries
|
|
216061
|
+
...binEntryPoints.length > 0 ? [dtsPlugin({
|
|
216062
|
+
outDir: distBinDir,
|
|
216063
|
+
rootDir: binDir,
|
|
216064
|
+
entryPoints: binEntryPoints
|
|
216065
|
+
})] : []
|
|
215869
216066
|
]
|
|
215870
216067
|
});
|
|
216068
|
+
if (binEntryPoints.length > 0) {
|
|
216069
|
+
const runtimeBanner = generateRuntimeBanner(pkg);
|
|
216070
|
+
for (const binEntryName of binEntryNames) {
|
|
216071
|
+
const outputPath = Path3.join(distBinDir, `${binEntryName}.js`);
|
|
216072
|
+
await processJavaScriptExecutable(outputPath, runtimeBanner);
|
|
216073
|
+
}
|
|
216074
|
+
}
|
|
216075
|
+
}
|
|
216076
|
+
if (options.formats.cjs) {
|
|
216077
|
+
console.info(` Building ${entryPoints.length} entries (CJS)...`);
|
|
216078
|
+
if (srcEntryPoints.length > 0) {
|
|
216079
|
+
try {
|
|
216080
|
+
await ESBuild.build({
|
|
216081
|
+
entryPoints: srcEntryPoints,
|
|
216082
|
+
outdir: distSrcDir,
|
|
216083
|
+
format: "cjs",
|
|
216084
|
+
outExtension: { ".js": ".cjs" },
|
|
216085
|
+
bundle: true,
|
|
216086
|
+
minify: false,
|
|
216087
|
+
sourcemap: false,
|
|
216088
|
+
external: externalDeps,
|
|
216089
|
+
platform: "node",
|
|
216090
|
+
target: "node18",
|
|
216091
|
+
supported: { "import-attributes": true },
|
|
216092
|
+
plugins: [
|
|
216093
|
+
externalEntrypointsPlugin({
|
|
216094
|
+
entryNames: srcEntryNames,
|
|
216095
|
+
outputExtension: ".cjs"
|
|
216096
|
+
})
|
|
216097
|
+
]
|
|
216098
|
+
});
|
|
216099
|
+
} catch (error) {
|
|
216100
|
+
const errorMessage = error.message || "";
|
|
216101
|
+
const hasErrorsArray = error.errors && Array.isArray(error.errors);
|
|
216102
|
+
const isTLAError = errorMessage.includes('Top-level await is currently not supported with the "cjs" output format') || hasErrorsArray && error.errors.some((e) => e.text && e.text.includes('Top-level await is currently not supported with the "cjs" output format'));
|
|
216103
|
+
if (isTLAError) {
|
|
216104
|
+
console.info(`
|
|
216105
|
+
\u26A0\uFE0F Top-level await detected - CommonJS generation disabled`);
|
|
216106
|
+
console.info(` Top-level await is incompatible with CommonJS format`);
|
|
216107
|
+
console.info(` Building ESM-only (Node.js 14+ and modern bundlers supported)`);
|
|
216108
|
+
console.info(` To permanently disable CJS: remove "main" field from package.json
|
|
216109
|
+
`);
|
|
216110
|
+
options.formats.cjs = false;
|
|
216111
|
+
} else {
|
|
216112
|
+
throw error;
|
|
216113
|
+
}
|
|
216114
|
+
}
|
|
216115
|
+
}
|
|
215871
216116
|
}
|
|
215872
216117
|
}
|
|
215873
216118
|
for (const umdPath of umdEntries) {
|
|
@@ -215890,8 +216135,8 @@ async function build2(cwd, save = false) {
|
|
|
215890
216135
|
}
|
|
215891
216136
|
const autoDiscoveredFiles = [];
|
|
215892
216137
|
console.info(" Generating package.json...");
|
|
215893
|
-
const cleanedPkg = await cleanPackageJSON(pkg, mainEntry, options, cwd);
|
|
215894
|
-
const exportsResult = generateExports(entries, mainEntry, options, pkg.exports);
|
|
216138
|
+
const cleanedPkg = await cleanPackageJSON(pkg, mainEntry, options, cwd, distDir);
|
|
216139
|
+
const exportsResult = await generateExports(entries, mainEntry, options, pkg.exports, distDir, allBinEntries);
|
|
215895
216140
|
cleanedPkg.exports = fixExportsForDist(exportsResult.exports);
|
|
215896
216141
|
if (exportsResult.staleExports.length > 0) {
|
|
215897
216142
|
console.warn(`\u26A0\uFE0F WARNING: Found ${exportsResult.staleExports.length} stale export(s) pointing to missing src/ files:`);
|
|
@@ -215992,7 +216237,10 @@ async function build2(cwd, save = false) {
|
|
|
215992
216237
|
rootPkg2.main = `./dist/src/${mainEntry}.cjs`;
|
|
215993
216238
|
}
|
|
215994
216239
|
rootPkg2.module = `./dist/src/${mainEntry}.js`;
|
|
215995
|
-
|
|
216240
|
+
const dtsPath = Path3.join(distDir, "src", `${mainEntry}.d.ts`);
|
|
216241
|
+
if (await fileExists(dtsPath)) {
|
|
216242
|
+
rootPkg2.types = `./dist/src/${mainEntry}.d.ts`;
|
|
216243
|
+
}
|
|
215996
216244
|
if (rootPkg2.typings && typeof rootPkg2.typings === "string") {
|
|
215997
216245
|
rootPkg2.typings = rootPkg2.typings.startsWith("./dist/") ? rootPkg2.typings : "./" + Path3.join("dist", rootPkg2.typings);
|
|
215998
216246
|
}
|
|
@@ -216023,6 +216271,27 @@ async function build2(cwd, save = false) {
|
|
|
216023
216271
|
}
|
|
216024
216272
|
}
|
|
216025
216273
|
rootPkg2.exports = rootExports;
|
|
216274
|
+
if (allBinEntries.length > 0) {
|
|
216275
|
+
const generatedBin = {};
|
|
216276
|
+
for (const binEntryInfo of allBinEntries) {
|
|
216277
|
+
const binPath = binEntryInfo.source === "src" ? `./dist/src/bin/${binEntryInfo.name}.js` : `./dist/bin/${binEntryInfo.name}.js`;
|
|
216278
|
+
const fullPath = Path3.join(cwd, binPath);
|
|
216279
|
+
if (await fileExists(fullPath)) {
|
|
216280
|
+
generatedBin[binEntryInfo.name] = binPath;
|
|
216281
|
+
}
|
|
216282
|
+
}
|
|
216283
|
+
if (Object.keys(generatedBin).length > 0) {
|
|
216284
|
+
if (rootPkg2.bin) {
|
|
216285
|
+
if (typeof rootPkg2.bin === "string") {
|
|
216286
|
+
const existingName = pkg.name?.split("/").pop() || "cli";
|
|
216287
|
+
rootPkg2.bin = { [existingName]: rootPkg2.bin };
|
|
216288
|
+
}
|
|
216289
|
+
rootPkg2.bin = { ...rootPkg2.bin, ...generatedBin };
|
|
216290
|
+
} else {
|
|
216291
|
+
rootPkg2.bin = generatedBin;
|
|
216292
|
+
}
|
|
216293
|
+
}
|
|
216294
|
+
}
|
|
216026
216295
|
if (rootPkg2.bin) {
|
|
216027
216296
|
if (typeof rootPkg2.bin === "string") {
|
|
216028
216297
|
const distPath = rootPkg2.bin.startsWith("./dist/") ? rootPkg2.bin : rootPkg2.bin.startsWith("dist/") ? "./" + rootPkg2.bin : "./" + Path3.join("dist", rootPkg2.bin);
|
|
@@ -216085,6 +216354,9 @@ async function build2(cwd, save = false) {
|
|
|
216085
216354
|
if (save) {
|
|
216086
216355
|
rootPkg = JSON.parse(await FS3.readFile(pkgPath, "utf-8"));
|
|
216087
216356
|
}
|
|
216357
|
+
if (allBinEntries.length > 0 || pkg.bin) {
|
|
216358
|
+
await makeFilesExecutable(pkg, cwd, allBinEntries);
|
|
216359
|
+
}
|
|
216088
216360
|
return { distPkg: fixedDistPkg, rootPkg };
|
|
216089
216361
|
}
|
|
216090
216362
|
async function publish(cwd, save = true, extraArgs = []) {
|
package/src/libuild.js
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
/// <reference types="./libuild.d.ts" />
|
|
2
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
|
+
}) : x)(function(x) {
|
|
5
|
+
if (typeof require !== "undefined")
|
|
6
|
+
return require.apply(this, arguments);
|
|
7
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
8
|
+
});
|
|
9
|
+
|
|
2
10
|
// src/libuild.ts
|
|
3
11
|
import * as FS3 from "fs/promises";
|
|
4
12
|
import * as Path3 from "path";
|
|
@@ -67,6 +75,21 @@ function externalEntrypointsPlugin(options) {
|
|
|
67
75
|
};
|
|
68
76
|
}
|
|
69
77
|
});
|
|
78
|
+
build3.onResolve({ filter: /^\.\.\/(?:src|bin)\// }, (args) => {
|
|
79
|
+
const withoutExt = args.path.replace(/\.(ts|js)$/, "");
|
|
80
|
+
const match = withoutExt.match(/^\.\.\/(?:src|bin)\/(.+)$/);
|
|
81
|
+
if (match) {
|
|
82
|
+
const entryName = match[1];
|
|
83
|
+
if (externalEntries.includes(entryName)) {
|
|
84
|
+
const dir = withoutExt.match(/^(\.\.\/(?:src|bin))\//)?.[1];
|
|
85
|
+
return {
|
|
86
|
+
path: `${dir}/${entryName}${outputExtension}`,
|
|
87
|
+
external: true
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return void 0;
|
|
92
|
+
});
|
|
70
93
|
}
|
|
71
94
|
};
|
|
72
95
|
}
|
|
@@ -92,27 +115,34 @@ function dtsPlugin(options) {
|
|
|
92
115
|
let TS;
|
|
93
116
|
try {
|
|
94
117
|
TS = await import("typescript");
|
|
95
|
-
} catch {
|
|
118
|
+
} catch (error) {
|
|
96
119
|
return;
|
|
97
120
|
}
|
|
98
121
|
const tsFiles = entryFiles.filter((file) => {
|
|
99
122
|
if (!file.endsWith(".ts"))
|
|
100
123
|
return false;
|
|
101
124
|
return options.entryPoints.some((entryPoint) => {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
125
|
+
try {
|
|
126
|
+
const fs = __require("fs");
|
|
127
|
+
const normalizedEntry = fs.realpathSync(Path2.resolve(entryPoint));
|
|
128
|
+
const normalizedFile = fs.realpathSync(Path2.resolve(file));
|
|
129
|
+
return normalizedEntry === normalizedFile;
|
|
130
|
+
} catch {
|
|
131
|
+
const normalizedEntry = Path2.resolve(entryPoint);
|
|
132
|
+
const normalizedFile = Path2.resolve(file);
|
|
133
|
+
return normalizedEntry === normalizedFile;
|
|
134
|
+
}
|
|
105
135
|
});
|
|
106
136
|
});
|
|
107
137
|
if (tsFiles.length === 0) {
|
|
108
138
|
return;
|
|
109
139
|
}
|
|
110
140
|
try {
|
|
141
|
+
await FS2.mkdir(options.outDir, { recursive: true });
|
|
111
142
|
const compilerOptions = {
|
|
112
143
|
declaration: true,
|
|
113
144
|
emitDeclarationOnly: true,
|
|
114
145
|
outDir: options.outDir,
|
|
115
|
-
rootDir: options.rootDir,
|
|
116
146
|
skipLibCheck: true,
|
|
117
147
|
esModuleInterop: true,
|
|
118
148
|
target: TS.ScriptTarget.ES2020,
|
|
@@ -187,6 +217,38 @@ ${content}`;
|
|
|
187
217
|
}
|
|
188
218
|
|
|
189
219
|
// src/libuild.ts
|
|
220
|
+
function generateRuntimeBanner(pkg) {
|
|
221
|
+
const prefersBun = pkg.engines?.bun !== void 0;
|
|
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" "$@"';
|
|
224
|
+
} else {
|
|
225
|
+
return '//bin/true; exec "$([ "${npm_config_user_agent#bun/}" != "$npm_config_user_agent" ] && command -v bun || command -v node)" "$0" "$@"';
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
async function processJavaScriptExecutable(filePath, runtimeBanner) {
|
|
229
|
+
try {
|
|
230
|
+
const contents = await FS3.readFile(filePath, "utf8");
|
|
231
|
+
const lines = contents.split("\n");
|
|
232
|
+
let modified = false;
|
|
233
|
+
if (lines[0]?.startsWith("#!")) {
|
|
234
|
+
const existingShebang = lines[0];
|
|
235
|
+
if (existingShebang.includes("python") || existingShebang.includes("bash") || !existingShebang.includes("node") && !existingShebang.includes("bun") && !existingShebang.includes("sh")) {
|
|
236
|
+
console.warn(`\u26A0\uFE0F WARNING: ${filePath} has non-JavaScript shebang but is a JS file. Adding dual runtime support.`);
|
|
237
|
+
}
|
|
238
|
+
lines[0] = "#!/usr/bin/env sh";
|
|
239
|
+
lines.splice(1, 0, runtimeBanner);
|
|
240
|
+
modified = true;
|
|
241
|
+
} else {
|
|
242
|
+
lines.unshift("#!/usr/bin/env sh", runtimeBanner);
|
|
243
|
+
modified = true;
|
|
244
|
+
}
|
|
245
|
+
if (modified) {
|
|
246
|
+
await FS3.writeFile(filePath, lines.join("\n"));
|
|
247
|
+
}
|
|
248
|
+
} catch (error) {
|
|
249
|
+
console.warn(`\u26A0\uFE0F WARNING: Could not process executable ${filePath}: ${error.message}`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
190
252
|
function isValidEntrypoint(filename) {
|
|
191
253
|
if (!filename.endsWith(".ts") && !filename.endsWith(".js"))
|
|
192
254
|
return false;
|
|
@@ -213,6 +275,22 @@ async function findEntrypoints(srcDir) {
|
|
|
213
275
|
return isValidEntrypoint(dirent.name);
|
|
214
276
|
}).map((dirent) => Path3.basename(dirent.name, Path3.extname(dirent.name))).sort();
|
|
215
277
|
}
|
|
278
|
+
async function findBinEntrypoints(binDir) {
|
|
279
|
+
try {
|
|
280
|
+
const files = await FS3.readdir(binDir, { withFileTypes: true });
|
|
281
|
+
return files.filter((dirent) => {
|
|
282
|
+
if (dirent.isDirectory()) {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
return isValidEntrypoint(dirent.name);
|
|
286
|
+
}).map((dirent) => Path3.basename(dirent.name, Path3.extname(dirent.name))).sort();
|
|
287
|
+
} catch (error) {
|
|
288
|
+
if (error.code === "ENOENT") {
|
|
289
|
+
return [];
|
|
290
|
+
}
|
|
291
|
+
throw error;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
216
294
|
function detectMainEntry(pkg, entries) {
|
|
217
295
|
function extractEntryFromPath(path) {
|
|
218
296
|
const match = path.match(/\.\/src\/([^.]+)/);
|
|
@@ -310,18 +388,38 @@ function checkIfExportIsStale(exportKey, exportValue, entries) {
|
|
|
310
388
|
}
|
|
311
389
|
return entryName ? !entries.includes(entryName) : false;
|
|
312
390
|
}
|
|
313
|
-
function generateExports(entries, mainEntry, options, existingExports = {}) {
|
|
391
|
+
async function generateExports(entries, mainEntry, options, existingExports = {}, distDir, allBinEntries = []) {
|
|
314
392
|
const exports = {};
|
|
315
393
|
const staleExports = [];
|
|
316
|
-
function createExportEntry(entry) {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
394
|
+
async function createExportEntry(entry) {
|
|
395
|
+
if (entry.startsWith("bin/")) {
|
|
396
|
+
const binEntry = entry.replace("bin/", "");
|
|
397
|
+
const exportEntry = {
|
|
398
|
+
import: `./bin/${binEntry}.js`
|
|
399
|
+
};
|
|
400
|
+
if (distDir) {
|
|
401
|
+
const dtsPath = Path3.join(distDir, "bin", `${binEntry}.d.ts`);
|
|
402
|
+
if (await fileExists(dtsPath)) {
|
|
403
|
+
exportEntry.types = `./bin/${binEntry}.d.ts`;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
return exportEntry;
|
|
407
|
+
} else {
|
|
408
|
+
const exportEntry = {
|
|
409
|
+
import: `./src/${entry}.js`
|
|
410
|
+
};
|
|
411
|
+
if (distDir) {
|
|
412
|
+
const dtsPath = Path3.join(distDir, "src", `${entry}.d.ts`);
|
|
413
|
+
const exists = await fileExists(dtsPath);
|
|
414
|
+
if (exists) {
|
|
415
|
+
exportEntry.types = `./src/${entry}.d.ts`;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if (options.formats.cjs) {
|
|
419
|
+
exportEntry.require = `./src/${entry}.cjs`;
|
|
420
|
+
}
|
|
421
|
+
return exportEntry;
|
|
323
422
|
}
|
|
324
|
-
return exportEntry;
|
|
325
423
|
}
|
|
326
424
|
function expandExistingExport(existing, entryFromPath) {
|
|
327
425
|
if (typeof existing === "string") {
|
|
@@ -395,7 +493,7 @@ function generateExports(entries, mainEntry, options, existingExports = {}) {
|
|
|
395
493
|
}
|
|
396
494
|
}
|
|
397
495
|
if (!exports["."]) {
|
|
398
|
-
exports["."] = createExportEntry(mainEntry);
|
|
496
|
+
exports["."] = await createExportEntry(mainEntry);
|
|
399
497
|
} else {
|
|
400
498
|
exports["."] = expandExistingExport(exports["."], mainEntry);
|
|
401
499
|
}
|
|
@@ -404,7 +502,7 @@ function generateExports(entries, mainEntry, options, existingExports = {}) {
|
|
|
404
502
|
continue;
|
|
405
503
|
const key = `./${entry}`;
|
|
406
504
|
if (!exports[key]) {
|
|
407
|
-
exports[key] = createExportEntry(entry);
|
|
505
|
+
exports[key] = await createExportEntry(entry);
|
|
408
506
|
} else {
|
|
409
507
|
exports[key] = expandExistingExport(exports[key], entry);
|
|
410
508
|
}
|
|
@@ -457,13 +555,30 @@ async function validateSingleBinPath(binPath, fieldName, cwd, save) {
|
|
|
457
555
|
if (save) {
|
|
458
556
|
return;
|
|
459
557
|
}
|
|
460
|
-
if (binPath.startsWith("dist/src/") || binPath.startsWith("./dist/src/")) {
|
|
558
|
+
if (binPath.startsWith("dist/src/") || binPath.startsWith("./dist/src/") || binPath.startsWith("dist/bin/") || binPath.startsWith("./dist/bin/")) {
|
|
461
559
|
const fullPath2 = Path3.join(cwd, binPath);
|
|
462
560
|
const distExists = await fileExists(fullPath2);
|
|
463
561
|
if (distExists) {
|
|
464
562
|
return;
|
|
465
563
|
}
|
|
466
|
-
|
|
564
|
+
let srcPath;
|
|
565
|
+
let sourceDir;
|
|
566
|
+
if (binPath.startsWith("./dist/src/")) {
|
|
567
|
+
srcPath = binPath.replace("./dist/src/", "src/");
|
|
568
|
+
sourceDir = "src";
|
|
569
|
+
} else if (binPath.startsWith("dist/src/")) {
|
|
570
|
+
srcPath = binPath.replace("dist/src/", "src/");
|
|
571
|
+
sourceDir = "src";
|
|
572
|
+
} else if (binPath.startsWith("./dist/bin/")) {
|
|
573
|
+
srcPath = binPath.replace("./dist/bin/", "bin/");
|
|
574
|
+
sourceDir = "bin";
|
|
575
|
+
} else if (binPath.startsWith("dist/bin/")) {
|
|
576
|
+
srcPath = binPath.replace("dist/bin/", "bin/");
|
|
577
|
+
sourceDir = "bin";
|
|
578
|
+
} else {
|
|
579
|
+
srcPath = binPath;
|
|
580
|
+
sourceDir = "src";
|
|
581
|
+
}
|
|
467
582
|
const basePath = srcPath.replace(/\.(js|cjs|mjs)$/, "");
|
|
468
583
|
const tsPath = Path3.join(cwd, basePath + ".ts");
|
|
469
584
|
const jsPath = Path3.join(cwd, basePath + ".js");
|
|
@@ -490,7 +605,16 @@ async function validateSingleBinPath(binPath, fieldName, cwd, save) {
|
|
|
490
605
|
if (pathExists) {
|
|
491
606
|
return;
|
|
492
607
|
}
|
|
493
|
-
if (binPath.startsWith("src/") || binPath.startsWith("./src/")) {
|
|
608
|
+
if (binPath.startsWith("src/") || binPath.startsWith("./src/") || binPath.startsWith("bin/") || binPath.startsWith("./bin/")) {
|
|
609
|
+
let normalizedPath = binPath.startsWith("./") ? binPath.slice(2) : binPath;
|
|
610
|
+
if (normalizedPath.startsWith("src/")) {
|
|
611
|
+
const srcRelativePath = normalizedPath.replace("src/", "");
|
|
612
|
+
if (srcRelativePath.includes("/")) {
|
|
613
|
+
console.warn(`\u26A0\uFE0F WARNING: ${fieldName} field points to "${binPath}" which is in a subdirectory of src/.`);
|
|
614
|
+
console.warn(` libuild only auto-detects top-level src/ files as entrypoints.`);
|
|
615
|
+
console.warn(` Consider moving the file to the top-level src/ directory or use the bin/ directory for executables.`);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
494
618
|
const basePath = fullPath.replace(/\.(js|cjs|mjs)$/, "");
|
|
495
619
|
const tsPath = basePath + ".ts";
|
|
496
620
|
const jsPath = basePath + ".js";
|
|
@@ -515,10 +639,19 @@ function transformBinPaths(value) {
|
|
|
515
639
|
if (value.startsWith("dist/src/")) {
|
|
516
640
|
return value.replace("dist/", "");
|
|
517
641
|
}
|
|
642
|
+
if (value.startsWith("./dist/bin/")) {
|
|
643
|
+
return value.replace("./dist/", "");
|
|
644
|
+
}
|
|
645
|
+
if (value.startsWith("dist/bin/")) {
|
|
646
|
+
return value.replace("dist/", "");
|
|
647
|
+
}
|
|
518
648
|
if (value.startsWith("./src/")) {
|
|
519
649
|
return value.replace("./", "");
|
|
520
650
|
}
|
|
521
|
-
if (value.startsWith("
|
|
651
|
+
if (value.startsWith("./bin/")) {
|
|
652
|
+
return value.replace("./", "");
|
|
653
|
+
}
|
|
654
|
+
if (value.startsWith("src/") || value === "src" || value.startsWith("bin/") || value === "bin") {
|
|
522
655
|
return value;
|
|
523
656
|
}
|
|
524
657
|
return value;
|
|
@@ -563,6 +696,43 @@ function fixExportsForDist(obj) {
|
|
|
563
696
|
}
|
|
564
697
|
return obj;
|
|
565
698
|
}
|
|
699
|
+
async function setExecutablePermissions(filePath) {
|
|
700
|
+
try {
|
|
701
|
+
await FS3.chmod(filePath, 493);
|
|
702
|
+
} catch (error) {
|
|
703
|
+
console.warn(`\u26A0\uFE0F WARNING: Could not set executable permissions for ${filePath}: ${error.message}`);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
async function makeFilesExecutable(pkg, cwd, allBinEntries) {
|
|
707
|
+
const filesToMakeExecutable = [];
|
|
708
|
+
if (pkg.bin) {
|
|
709
|
+
if (typeof pkg.bin === "string") {
|
|
710
|
+
filesToMakeExecutable.push(Path3.join(cwd, pkg.bin));
|
|
711
|
+
} else if (typeof pkg.bin === "object") {
|
|
712
|
+
for (const binPath of Object.values(pkg.bin)) {
|
|
713
|
+
if (typeof binPath === "string") {
|
|
714
|
+
filesToMakeExecutable.push(Path3.join(cwd, binPath));
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
for (const binEntryInfo of allBinEntries) {
|
|
720
|
+
const baseDir = binEntryInfo.source === "src" ? "dist/src/bin" : "dist/bin";
|
|
721
|
+
const jsPath = Path3.join(cwd, baseDir, `${binEntryInfo.name}.js`);
|
|
722
|
+
const cjsPath = Path3.join(cwd, baseDir, `${binEntryInfo.name}.cjs`);
|
|
723
|
+
if (!filesToMakeExecutable.includes(jsPath)) {
|
|
724
|
+
filesToMakeExecutable.push(jsPath);
|
|
725
|
+
}
|
|
726
|
+
if (!filesToMakeExecutable.includes(cjsPath)) {
|
|
727
|
+
filesToMakeExecutable.push(cjsPath);
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
for (const filePath of filesToMakeExecutable) {
|
|
731
|
+
if (await fileExists(filePath)) {
|
|
732
|
+
await setExecutablePermissions(filePath);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
566
736
|
async function resolveWorkspaceDependencies(dependencies, cwd) {
|
|
567
737
|
if (!dependencies)
|
|
568
738
|
return void 0;
|
|
@@ -622,7 +792,7 @@ async function resolveWorkspaceVersion(packageName, workspaceSpec, cwd) {
|
|
|
622
792
|
return workspaceSpec;
|
|
623
793
|
}
|
|
624
794
|
}
|
|
625
|
-
async function cleanPackageJSON(pkg, mainEntry, options, cwd) {
|
|
795
|
+
async function cleanPackageJSON(pkg, mainEntry, options, cwd, distDir) {
|
|
626
796
|
const cleaned = {
|
|
627
797
|
name: pkg.name,
|
|
628
798
|
version: pkg.version
|
|
@@ -687,7 +857,13 @@ async function cleanPackageJSON(pkg, mainEntry, options, cwd) {
|
|
|
687
857
|
cleaned.main = `src/${mainEntry}.cjs`;
|
|
688
858
|
}
|
|
689
859
|
cleaned.module = `src/${mainEntry}.js`;
|
|
690
|
-
|
|
860
|
+
if (distDir) {
|
|
861
|
+
const dtsPath = Path3.join(distDir, "src", `${mainEntry}.d.ts`);
|
|
862
|
+
const exists = await fileExists(dtsPath);
|
|
863
|
+
if (exists) {
|
|
864
|
+
cleaned.types = `src/${mainEntry}.d.ts`;
|
|
865
|
+
}
|
|
866
|
+
}
|
|
691
867
|
return cleaned;
|
|
692
868
|
}
|
|
693
869
|
async function fileExists(filePath) {
|
|
@@ -739,9 +915,19 @@ async function build2(cwd, save = false) {
|
|
|
739
915
|
console.warn(" Add 'dist/' to your .gitignore file");
|
|
740
916
|
}
|
|
741
917
|
}
|
|
742
|
-
const
|
|
743
|
-
|
|
744
|
-
|
|
918
|
+
const binDir = Path3.join(cwd, "bin");
|
|
919
|
+
const srcEntries = await findEntrypoints(srcDir);
|
|
920
|
+
const binEntries = await findBinEntrypoints(binDir);
|
|
921
|
+
const allBinEntries = binEntries.map((entry) => ({ name: entry, source: "top-level" }));
|
|
922
|
+
const entries = [
|
|
923
|
+
...srcEntries,
|
|
924
|
+
...allBinEntries.map((entry) => `bin/${entry.name}`)
|
|
925
|
+
];
|
|
926
|
+
if (srcEntries.length === 0 && allBinEntries.length === 0) {
|
|
927
|
+
throw new Error("No entry points found in src/ or bin/");
|
|
928
|
+
}
|
|
929
|
+
if (allBinEntries.length > 0) {
|
|
930
|
+
console.info(` Found bin entries: ${allBinEntries.map((entry) => entry.name).join(", ")}`);
|
|
745
931
|
}
|
|
746
932
|
const options = {
|
|
747
933
|
formats: {
|
|
@@ -752,7 +938,7 @@ async function build2(cwd, save = false) {
|
|
|
752
938
|
umd: entries.includes("umd")
|
|
753
939
|
}
|
|
754
940
|
};
|
|
755
|
-
const mainEntry = detectMainEntry(pkg,
|
|
941
|
+
const mainEntry = detectMainEntry(pkg, srcEntries);
|
|
756
942
|
console.info(" Found entries:", entries.join(", "));
|
|
757
943
|
console.info(" Main entry:", mainEntry);
|
|
758
944
|
if (options.formats.cjs) {
|
|
@@ -783,11 +969,29 @@ async function build2(cwd, save = false) {
|
|
|
783
969
|
const entryPoints = [];
|
|
784
970
|
const umdEntries = [];
|
|
785
971
|
for (const entry of entries) {
|
|
786
|
-
|
|
787
|
-
|
|
972
|
+
let entryPath;
|
|
973
|
+
let jsEntryPath;
|
|
974
|
+
let sourceDir;
|
|
975
|
+
if (entry.startsWith("bin/")) {
|
|
976
|
+
const binEntryName = entry.replace("bin/", "");
|
|
977
|
+
const binEntryInfo = allBinEntries.find((binEntry) => binEntry.name === binEntryName);
|
|
978
|
+
if (binEntryInfo?.source === "src") {
|
|
979
|
+
entryPath = Path3.join(srcDir, "bin", `${binEntryName}.ts`);
|
|
980
|
+
jsEntryPath = Path3.join(srcDir, "bin", `${binEntryName}.js`);
|
|
981
|
+
sourceDir = "src/bin/";
|
|
982
|
+
} else {
|
|
983
|
+
entryPath = Path3.join(binDir, `${binEntryName}.ts`);
|
|
984
|
+
jsEntryPath = Path3.join(binDir, `${binEntryName}.js`);
|
|
985
|
+
sourceDir = "bin/";
|
|
986
|
+
}
|
|
987
|
+
} else {
|
|
988
|
+
entryPath = Path3.join(srcDir, `${entry}.ts`);
|
|
989
|
+
jsEntryPath = Path3.join(srcDir, `${entry}.js`);
|
|
990
|
+
sourceDir = "src/";
|
|
991
|
+
}
|
|
788
992
|
const actualPath = await fileExists(entryPath) ? entryPath : jsEntryPath;
|
|
789
993
|
if (!await fileExists(actualPath)) {
|
|
790
|
-
throw new Error(`Entry point file not found: ${actualPath}. Expected ${entry}.ts or ${entry}.js in
|
|
994
|
+
throw new Error(`Entry point file not found: ${actualPath}. Expected ${entry.replace("bin/", "")}.ts or ${entry.replace("bin/", "")}.js in ${sourceDir} directory.`);
|
|
791
995
|
}
|
|
792
996
|
if (entry === "umd") {
|
|
793
997
|
umdEntries.push(actualPath);
|
|
@@ -795,58 +999,107 @@ async function build2(cwd, save = false) {
|
|
|
795
999
|
entryPoints.push(actualPath);
|
|
796
1000
|
}
|
|
797
1001
|
}
|
|
1002
|
+
const srcEntryPoints = entryPoints.filter((path) => path.includes(srcDir));
|
|
1003
|
+
const binEntryPoints = entryPoints.filter((path) => path.includes(binDir));
|
|
1004
|
+
const distBinDir = Path3.join(distDir, "bin");
|
|
1005
|
+
if (binEntryPoints.length > 0) {
|
|
1006
|
+
await FS3.mkdir(distBinDir, { recursive: true });
|
|
1007
|
+
}
|
|
798
1008
|
if (entryPoints.length > 0) {
|
|
799
|
-
|
|
1009
|
+
console.info(` Building ${entryPoints.length} entries (ESM)...`);
|
|
1010
|
+
const srcEntryNames = srcEntryPoints.map((path) => {
|
|
800
1011
|
const name = Path3.basename(path, Path3.extname(path));
|
|
801
1012
|
return name;
|
|
802
1013
|
});
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
outdir: distSrcDir,
|
|
807
|
-
format: "esm",
|
|
808
|
-
outExtension: { ".js": ".js" },
|
|
809
|
-
bundle: true,
|
|
810
|
-
minify: false,
|
|
811
|
-
sourcemap: false,
|
|
812
|
-
external: externalDeps,
|
|
813
|
-
platform: "node",
|
|
814
|
-
target: "node18",
|
|
815
|
-
packages: "external",
|
|
816
|
-
supported: { "import-attributes": true },
|
|
817
|
-
plugins: [
|
|
818
|
-
externalEntrypointsPlugin({
|
|
819
|
-
entryNames,
|
|
820
|
-
outputExtension: ".js"
|
|
821
|
-
}),
|
|
822
|
-
dtsPlugin({
|
|
823
|
-
outDir: distSrcDir,
|
|
824
|
-
rootDir: srcDir,
|
|
825
|
-
entryPoints
|
|
826
|
-
})
|
|
827
|
-
]
|
|
1014
|
+
const binEntryNames = binEntryPoints.map((path) => {
|
|
1015
|
+
const name = Path3.basename(path, Path3.extname(path));
|
|
1016
|
+
return name;
|
|
828
1017
|
});
|
|
829
|
-
|
|
830
|
-
|
|
1018
|
+
const allESMEntryPoints = [...srcEntryPoints, ...binEntryPoints];
|
|
1019
|
+
const allEntryNames = [...srcEntryNames, ...binEntryNames];
|
|
1020
|
+
if (allESMEntryPoints.length > 0) {
|
|
831
1021
|
await ESBuild.build({
|
|
832
|
-
entryPoints,
|
|
833
|
-
outdir:
|
|
834
|
-
|
|
835
|
-
|
|
1022
|
+
entryPoints: allESMEntryPoints,
|
|
1023
|
+
outdir: distDir,
|
|
1024
|
+
outbase: cwd,
|
|
1025
|
+
// Preserve src/ and bin/ directory structure
|
|
1026
|
+
format: "esm",
|
|
1027
|
+
outExtension: { ".js": ".js" },
|
|
836
1028
|
bundle: true,
|
|
837
1029
|
minify: false,
|
|
838
1030
|
sourcemap: false,
|
|
839
1031
|
external: externalDeps,
|
|
840
1032
|
platform: "node",
|
|
841
1033
|
target: "node18",
|
|
1034
|
+
packages: "external",
|
|
842
1035
|
supported: { "import-attributes": true },
|
|
843
1036
|
plugins: [
|
|
844
1037
|
externalEntrypointsPlugin({
|
|
845
|
-
entryNames,
|
|
846
|
-
outputExtension: ".
|
|
847
|
-
})
|
|
1038
|
+
entryNames: allEntryNames,
|
|
1039
|
+
outputExtension: ".js"
|
|
1040
|
+
}),
|
|
1041
|
+
// Generate TypeScript declarations for src entries
|
|
1042
|
+
...srcEntryPoints.length > 0 ? [dtsPlugin({
|
|
1043
|
+
outDir: distSrcDir,
|
|
1044
|
+
rootDir: srcDir,
|
|
1045
|
+
entryPoints: srcEntryPoints
|
|
1046
|
+
})] : [],
|
|
1047
|
+
// Generate TypeScript declarations for bin entries
|
|
1048
|
+
...binEntryPoints.length > 0 ? [dtsPlugin({
|
|
1049
|
+
outDir: distBinDir,
|
|
1050
|
+
rootDir: binDir,
|
|
1051
|
+
entryPoints: binEntryPoints
|
|
1052
|
+
})] : []
|
|
848
1053
|
]
|
|
849
1054
|
});
|
|
1055
|
+
if (binEntryPoints.length > 0) {
|
|
1056
|
+
const runtimeBanner = generateRuntimeBanner(pkg);
|
|
1057
|
+
for (const binEntryName of binEntryNames) {
|
|
1058
|
+
const outputPath = Path3.join(distBinDir, `${binEntryName}.js`);
|
|
1059
|
+
await processJavaScriptExecutable(outputPath, runtimeBanner);
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
if (options.formats.cjs) {
|
|
1064
|
+
console.info(` Building ${entryPoints.length} entries (CJS)...`);
|
|
1065
|
+
if (srcEntryPoints.length > 0) {
|
|
1066
|
+
try {
|
|
1067
|
+
await ESBuild.build({
|
|
1068
|
+
entryPoints: srcEntryPoints,
|
|
1069
|
+
outdir: distSrcDir,
|
|
1070
|
+
format: "cjs",
|
|
1071
|
+
outExtension: { ".js": ".cjs" },
|
|
1072
|
+
bundle: true,
|
|
1073
|
+
minify: false,
|
|
1074
|
+
sourcemap: false,
|
|
1075
|
+
external: externalDeps,
|
|
1076
|
+
platform: "node",
|
|
1077
|
+
target: "node18",
|
|
1078
|
+
supported: { "import-attributes": true },
|
|
1079
|
+
plugins: [
|
|
1080
|
+
externalEntrypointsPlugin({
|
|
1081
|
+
entryNames: srcEntryNames,
|
|
1082
|
+
outputExtension: ".cjs"
|
|
1083
|
+
})
|
|
1084
|
+
]
|
|
1085
|
+
});
|
|
1086
|
+
} catch (error) {
|
|
1087
|
+
const errorMessage = error.message || "";
|
|
1088
|
+
const hasErrorsArray = error.errors && Array.isArray(error.errors);
|
|
1089
|
+
const isTLAError = errorMessage.includes('Top-level await is currently not supported with the "cjs" output format') || hasErrorsArray && error.errors.some((e) => e.text && e.text.includes('Top-level await is currently not supported with the "cjs" output format'));
|
|
1090
|
+
if (isTLAError) {
|
|
1091
|
+
console.info(`
|
|
1092
|
+
\u26A0\uFE0F Top-level await detected - CommonJS generation disabled`);
|
|
1093
|
+
console.info(` Top-level await is incompatible with CommonJS format`);
|
|
1094
|
+
console.info(` Building ESM-only (Node.js 14+ and modern bundlers supported)`);
|
|
1095
|
+
console.info(` To permanently disable CJS: remove "main" field from package.json
|
|
1096
|
+
`);
|
|
1097
|
+
options.formats.cjs = false;
|
|
1098
|
+
} else {
|
|
1099
|
+
throw error;
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
850
1103
|
}
|
|
851
1104
|
}
|
|
852
1105
|
for (const umdPath of umdEntries) {
|
|
@@ -869,8 +1122,8 @@ async function build2(cwd, save = false) {
|
|
|
869
1122
|
}
|
|
870
1123
|
const autoDiscoveredFiles = [];
|
|
871
1124
|
console.info(" Generating package.json...");
|
|
872
|
-
const cleanedPkg = await cleanPackageJSON(pkg, mainEntry, options, cwd);
|
|
873
|
-
const exportsResult = generateExports(entries, mainEntry, options, pkg.exports);
|
|
1125
|
+
const cleanedPkg = await cleanPackageJSON(pkg, mainEntry, options, cwd, distDir);
|
|
1126
|
+
const exportsResult = await generateExports(entries, mainEntry, options, pkg.exports, distDir, allBinEntries);
|
|
874
1127
|
cleanedPkg.exports = fixExportsForDist(exportsResult.exports);
|
|
875
1128
|
if (exportsResult.staleExports.length > 0) {
|
|
876
1129
|
console.warn(`\u26A0\uFE0F WARNING: Found ${exportsResult.staleExports.length} stale export(s) pointing to missing src/ files:`);
|
|
@@ -971,7 +1224,10 @@ async function build2(cwd, save = false) {
|
|
|
971
1224
|
rootPkg2.main = `./dist/src/${mainEntry}.cjs`;
|
|
972
1225
|
}
|
|
973
1226
|
rootPkg2.module = `./dist/src/${mainEntry}.js`;
|
|
974
|
-
|
|
1227
|
+
const dtsPath = Path3.join(distDir, "src", `${mainEntry}.d.ts`);
|
|
1228
|
+
if (await fileExists(dtsPath)) {
|
|
1229
|
+
rootPkg2.types = `./dist/src/${mainEntry}.d.ts`;
|
|
1230
|
+
}
|
|
975
1231
|
if (rootPkg2.typings && typeof rootPkg2.typings === "string") {
|
|
976
1232
|
rootPkg2.typings = rootPkg2.typings.startsWith("./dist/") ? rootPkg2.typings : "./" + Path3.join("dist", rootPkg2.typings);
|
|
977
1233
|
}
|
|
@@ -1002,6 +1258,27 @@ async function build2(cwd, save = false) {
|
|
|
1002
1258
|
}
|
|
1003
1259
|
}
|
|
1004
1260
|
rootPkg2.exports = rootExports;
|
|
1261
|
+
if (allBinEntries.length > 0) {
|
|
1262
|
+
const generatedBin = {};
|
|
1263
|
+
for (const binEntryInfo of allBinEntries) {
|
|
1264
|
+
const binPath = binEntryInfo.source === "src" ? `./dist/src/bin/${binEntryInfo.name}.js` : `./dist/bin/${binEntryInfo.name}.js`;
|
|
1265
|
+
const fullPath = Path3.join(cwd, binPath);
|
|
1266
|
+
if (await fileExists(fullPath)) {
|
|
1267
|
+
generatedBin[binEntryInfo.name] = binPath;
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
if (Object.keys(generatedBin).length > 0) {
|
|
1271
|
+
if (rootPkg2.bin) {
|
|
1272
|
+
if (typeof rootPkg2.bin === "string") {
|
|
1273
|
+
const existingName = pkg.name?.split("/").pop() || "cli";
|
|
1274
|
+
rootPkg2.bin = { [existingName]: rootPkg2.bin };
|
|
1275
|
+
}
|
|
1276
|
+
rootPkg2.bin = { ...rootPkg2.bin, ...generatedBin };
|
|
1277
|
+
} else {
|
|
1278
|
+
rootPkg2.bin = generatedBin;
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1005
1282
|
if (rootPkg2.bin) {
|
|
1006
1283
|
if (typeof rootPkg2.bin === "string") {
|
|
1007
1284
|
const distPath = rootPkg2.bin.startsWith("./dist/") ? rootPkg2.bin : rootPkg2.bin.startsWith("dist/") ? "./" + rootPkg2.bin : "./" + Path3.join("dist", rootPkg2.bin);
|
|
@@ -1064,6 +1341,9 @@ async function build2(cwd, save = false) {
|
|
|
1064
1341
|
if (save) {
|
|
1065
1342
|
rootPkg = JSON.parse(await FS3.readFile(pkgPath, "utf-8"));
|
|
1066
1343
|
}
|
|
1344
|
+
if (allBinEntries.length > 0 || pkg.bin) {
|
|
1345
|
+
await makeFilesExecutable(pkg, cwd, allBinEntries);
|
|
1346
|
+
}
|
|
1067
1347
|
return { distPkg: fixedDistPkg, rootPkg };
|
|
1068
1348
|
}
|
|
1069
1349
|
async function publish(cwd, save = true, extraArgs = []) {
|