@b9g/libuild 0.1.3 → 0.1.5
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 +11 -13
- package/package.json +15 -15
- package/src/cli.cjs +62 -795
- package/src/cli.js +167 -11
- package/src/libuild.cjs +344 -183
- package/src/libuild.d.ts +1 -1
- package/src/libuild.js +934 -8
- package/src/chunk-EVLPGECD.js +0 -71
- package/src/chunk-EVLPGECD.js.map +0 -7
- package/src/chunk-YRPHTAV4.js +0 -713
- package/src/chunk-YRPHTAV4.js.map +0 -7
- package/src/cli.cjs.map +0 -7
- package/src/cli.js.map +0 -7
- package/src/libuild.cjs.map +0 -7
- package/src/libuild.js.map +0 -7
- package/src/package-4E3XK74J.js +0 -132
- package/src/package-4E3XK74J.js.map +0 -7
- package/src/umd-plugin.cjs +0 -105
- package/src/umd-plugin.cjs.map +0 -7
- package/src/umd-plugin.d.ts +0 -8
- package/src/umd-plugin.js +0 -8
- package/src/umd-plugin.js.map +0 -7
package/src/libuild.cjs
CHANGED
|
@@ -35,19 +35,17 @@ __export(libuild_exports, {
|
|
|
35
35
|
transformSrcToDist: () => transformSrcToDist
|
|
36
36
|
});
|
|
37
37
|
module.exports = __toCommonJS(libuild_exports);
|
|
38
|
-
var
|
|
39
|
-
var
|
|
38
|
+
var FS3 = __toESM(require("fs/promises"), 1);
|
|
39
|
+
var Path3 = __toESM(require("path"), 1);
|
|
40
40
|
var import_child_process = require("child_process");
|
|
41
41
|
var ESBuild = __toESM(require("esbuild"), 1);
|
|
42
|
-
var TS = __toESM(require("typescript"), 1);
|
|
43
42
|
|
|
44
|
-
// src/umd
|
|
43
|
+
// src/plugins/umd.ts
|
|
45
44
|
var FS = __toESM(require("fs/promises"), 1);
|
|
46
45
|
var Path = __toESM(require("path"), 1);
|
|
47
|
-
var import_magic_string = __toESM(require("magic-string"), 1);
|
|
48
46
|
function umdPlugin(options) {
|
|
49
47
|
return {
|
|
50
|
-
name: "umd
|
|
48
|
+
name: "umd",
|
|
51
49
|
setup(build3) {
|
|
52
50
|
build3.onEnd(async (result) => {
|
|
53
51
|
if (result.errors.length > 0)
|
|
@@ -57,7 +55,7 @@ function umdPlugin(options) {
|
|
|
57
55
|
const files = await FS.readdir(outputDir);
|
|
58
56
|
for (const file of files) {
|
|
59
57
|
if (file.endsWith(".js") && !file.endsWith(".js.map")) {
|
|
60
|
-
await
|
|
58
|
+
await wrapWithUMD(Path.join(outputDir, file), options.globalName);
|
|
61
59
|
}
|
|
62
60
|
}
|
|
63
61
|
}
|
|
@@ -65,20 +63,9 @@ function umdPlugin(options) {
|
|
|
65
63
|
}
|
|
66
64
|
};
|
|
67
65
|
}
|
|
68
|
-
async function
|
|
66
|
+
async function wrapWithUMD(filePath, globalName) {
|
|
69
67
|
const code = await FS.readFile(filePath, "utf-8");
|
|
70
|
-
|
|
71
|
-
const sourcemapComment = code.match(/\/\/# sourceMappingURL=.+$/m);
|
|
72
|
-
if (sourcemapComment) {
|
|
73
|
-
const index = code.lastIndexOf(sourcemapComment[0]);
|
|
74
|
-
ms.remove(index, index + sourcemapComment[0].length);
|
|
75
|
-
}
|
|
76
|
-
const exportsMatch = code.match(/\nmodule\.exports\s*=\s*([^;]+);?\s*$/);
|
|
77
|
-
if (exportsMatch) {
|
|
78
|
-
const index = code.lastIndexOf(exportsMatch[0]);
|
|
79
|
-
ms.overwrite(index, index + exportsMatch[0].length, `
|
|
80
|
-
return ${exportsMatch[1]};`);
|
|
81
|
-
}
|
|
68
|
+
let modifiedCode = code.replace(/\nmodule\.exports\s*=\s*([^;]+);?\s*$/, "\nreturn $1;");
|
|
82
69
|
const umdHeader = `(function (root, factory) {
|
|
83
70
|
if (typeof define === 'function' && define.amd) {
|
|
84
71
|
// AMD
|
|
@@ -94,18 +81,144 @@ return ${exportsMatch[1]};`);
|
|
|
94
81
|
`;
|
|
95
82
|
const umdFooter = `
|
|
96
83
|
}));`;
|
|
97
|
-
|
|
98
|
-
ms.append(umdFooter);
|
|
99
|
-
const result = ms.toString();
|
|
100
|
-
const map = ms.generateMap({
|
|
101
|
-
file: Path.basename(filePath),
|
|
102
|
-
source: Path.basename(filePath).replace(".js", ".ts"),
|
|
103
|
-
includeContent: true
|
|
104
|
-
});
|
|
84
|
+
const result = umdHeader + modifiedCode + umdFooter;
|
|
105
85
|
await FS.writeFile(filePath, result);
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// src/plugins/external.ts
|
|
89
|
+
function externalEntrypointsPlugin(options) {
|
|
90
|
+
return {
|
|
91
|
+
name: "external-entrypoints",
|
|
92
|
+
setup(build3) {
|
|
93
|
+
const { entryNames, currentEntry, outputExtension } = options;
|
|
94
|
+
const externalEntries = currentEntry ? entryNames.filter((name) => name !== currentEntry) : entryNames;
|
|
95
|
+
build3.onResolve({ filter: /^\.\// }, (args) => {
|
|
96
|
+
const withoutExt = args.path.replace(/\.(ts|js)$/, "");
|
|
97
|
+
const entryName = withoutExt.replace(/^\.\//, "");
|
|
98
|
+
if (externalEntries.includes(entryName)) {
|
|
99
|
+
return {
|
|
100
|
+
path: `./${entryName}${outputExtension}`,
|
|
101
|
+
external: true
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// src/plugins/dts.ts
|
|
110
|
+
var FS2 = __toESM(require("fs/promises"), 1);
|
|
111
|
+
var Path2 = __toESM(require("path"), 1);
|
|
112
|
+
function dtsPlugin(options) {
|
|
113
|
+
return {
|
|
114
|
+
name: "dts",
|
|
115
|
+
setup(build3) {
|
|
116
|
+
const entryFiles = [];
|
|
117
|
+
build3.onLoad({ filter: /\.tsx?$/ }, async (args) => {
|
|
118
|
+
if (!entryFiles.includes(args.path)) {
|
|
119
|
+
entryFiles.push(args.path);
|
|
120
|
+
}
|
|
121
|
+
return void 0;
|
|
122
|
+
});
|
|
123
|
+
build3.onEnd(async (result) => {
|
|
124
|
+
if (result.errors.length > 0) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
let TS;
|
|
128
|
+
try {
|
|
129
|
+
TS = await import("typescript");
|
|
130
|
+
} catch {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const tsFiles = entryFiles.filter((file) => {
|
|
134
|
+
if (!file.endsWith(".ts"))
|
|
135
|
+
return false;
|
|
136
|
+
return options.entryPoints.some((entryPoint) => {
|
|
137
|
+
const normalizedEntry = Path2.resolve(entryPoint);
|
|
138
|
+
const normalizedFile = Path2.resolve(file);
|
|
139
|
+
return normalizedEntry === normalizedFile;
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
if (tsFiles.length === 0) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
const compilerOptions = {
|
|
147
|
+
declaration: true,
|
|
148
|
+
emitDeclarationOnly: true,
|
|
149
|
+
outDir: options.outDir,
|
|
150
|
+
rootDir: options.rootDir,
|
|
151
|
+
skipLibCheck: true,
|
|
152
|
+
esModuleInterop: true,
|
|
153
|
+
target: TS.ScriptTarget.ES2020,
|
|
154
|
+
module: TS.ModuleKind.ESNext,
|
|
155
|
+
isolatedModules: true,
|
|
156
|
+
// Prevent cross-file type dependencies
|
|
157
|
+
noResolve: true
|
|
158
|
+
// Don't resolve imports - only process the specific files
|
|
159
|
+
};
|
|
160
|
+
const program = TS.createProgram(tsFiles, compilerOptions);
|
|
161
|
+
const emitResult = program.emit();
|
|
162
|
+
if (emitResult.diagnostics.length > 0) {
|
|
163
|
+
const diagnostics = TS.formatDiagnosticsWithColorAndContext(emitResult.diagnostics, {
|
|
164
|
+
getCanonicalFileName: (path) => path,
|
|
165
|
+
getCurrentDirectory: () => process.cwd(),
|
|
166
|
+
getNewLine: () => "\n"
|
|
167
|
+
});
|
|
168
|
+
result.errors.push({
|
|
169
|
+
id: "typescript-declarations",
|
|
170
|
+
pluginName: "dts",
|
|
171
|
+
text: `TypeScript declaration generation failed:
|
|
172
|
+
${diagnostics}`,
|
|
173
|
+
location: null,
|
|
174
|
+
notes: [],
|
|
175
|
+
detail: void 0
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
} catch (error) {
|
|
179
|
+
result.errors.push({
|
|
180
|
+
id: "typescript-plugin-error",
|
|
181
|
+
pluginName: "dts",
|
|
182
|
+
text: `TypeScript plugin error: ${error.message}`,
|
|
183
|
+
location: null,
|
|
184
|
+
notes: [],
|
|
185
|
+
detail: void 0
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
await addTripleSlashReferences(tsFiles, options.outDir);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
async function addTripleSlashReferences(tsFiles, outDir) {
|
|
194
|
+
for (const tsFile of tsFiles) {
|
|
195
|
+
const baseName = Path2.basename(tsFile, Path2.extname(tsFile));
|
|
196
|
+
const jsPath = Path2.join(outDir, `${baseName}.js`);
|
|
197
|
+
const dtsPath = Path2.join(outDir, `${baseName}.d.ts`);
|
|
198
|
+
const [jsExists, dtsExists] = await Promise.all([
|
|
199
|
+
FS2.access(jsPath).then(() => true).catch(() => false),
|
|
200
|
+
FS2.access(dtsPath).then(() => true).catch(() => false)
|
|
201
|
+
]);
|
|
202
|
+
if (!jsExists || !dtsExists)
|
|
203
|
+
continue;
|
|
204
|
+
const content = await FS2.readFile(jsPath, "utf-8");
|
|
205
|
+
const referenceComment = `/// <reference types="./${baseName}.d.ts" />`;
|
|
206
|
+
let modifiedContent;
|
|
207
|
+
if (content.startsWith("#!")) {
|
|
208
|
+
const firstNewline = content.indexOf("\n");
|
|
209
|
+
if (firstNewline !== -1) {
|
|
210
|
+
modifiedContent = content.slice(0, firstNewline + 1) + `${referenceComment}
|
|
211
|
+
` + content.slice(firstNewline + 1);
|
|
212
|
+
} else {
|
|
213
|
+
modifiedContent = content + `
|
|
214
|
+
${referenceComment}`;
|
|
215
|
+
}
|
|
216
|
+
} else {
|
|
217
|
+
modifiedContent = `${referenceComment}
|
|
218
|
+
${content}`;
|
|
219
|
+
}
|
|
220
|
+
await FS2.writeFile(jsPath, modifiedContent);
|
|
221
|
+
}
|
|
109
222
|
}
|
|
110
223
|
|
|
111
224
|
// src/libuild.ts
|
|
@@ -120,11 +233,15 @@ function isValidEntrypoint(filename) {
|
|
|
120
233
|
return false;
|
|
121
234
|
return true;
|
|
122
235
|
}
|
|
123
|
-
async function
|
|
124
|
-
const files = await
|
|
125
|
-
return files.filter(isValidEntrypoint).map((file) =>
|
|
236
|
+
async function findEntrypoints(srcDir) {
|
|
237
|
+
const files = await FS3.readdir(srcDir);
|
|
238
|
+
return files.filter(isValidEntrypoint).map((file) => Path3.basename(file, Path3.extname(file))).sort();
|
|
126
239
|
}
|
|
127
|
-
|
|
240
|
+
function detectMainEntry(pkg, entries) {
|
|
241
|
+
function extractEntryFromPath(path) {
|
|
242
|
+
const match = path.match(/\.\/src\/([^.]+)/);
|
|
243
|
+
return match ? match[1] : void 0;
|
|
244
|
+
}
|
|
128
245
|
if (pkg.exports && pkg.exports["."]) {
|
|
129
246
|
const dotExport = pkg.exports["."];
|
|
130
247
|
let importPath;
|
|
@@ -134,18 +251,24 @@ async function detectMainEntry(pkg, entries) {
|
|
|
134
251
|
importPath = dotExport.import;
|
|
135
252
|
}
|
|
136
253
|
if (importPath) {
|
|
137
|
-
const
|
|
138
|
-
if (
|
|
139
|
-
return
|
|
254
|
+
const entry = extractEntryFromPath(importPath);
|
|
255
|
+
if (entry && entries.includes(entry)) {
|
|
256
|
+
return entry;
|
|
140
257
|
}
|
|
141
258
|
}
|
|
142
259
|
}
|
|
143
260
|
if (pkg.main && typeof pkg.main === "string") {
|
|
144
|
-
const mainBase =
|
|
261
|
+
const mainBase = Path3.basename(pkg.main, Path3.extname(pkg.main));
|
|
145
262
|
if (entries.includes(mainBase)) {
|
|
146
263
|
return mainBase;
|
|
147
264
|
}
|
|
148
265
|
}
|
|
266
|
+
if (pkg.module && typeof pkg.module === "string") {
|
|
267
|
+
const moduleBase = Path3.basename(pkg.module, Path3.extname(pkg.module));
|
|
268
|
+
if (entries.includes(moduleBase)) {
|
|
269
|
+
return moduleBase;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
149
272
|
if (entries.includes("index")) {
|
|
150
273
|
return "index";
|
|
151
274
|
}
|
|
@@ -236,7 +359,7 @@ function generateExports(entries, mainEntry, options, existingExports = {}) {
|
|
|
236
359
|
if (!isValidEntrypoint(filename)) {
|
|
237
360
|
throw new Error(`Export path '${existing}' references '${filename}' which is not a valid entrypoint. Valid entrypoints cannot start with '_' or '.' and must be .ts/.js files in src/.`);
|
|
238
361
|
}
|
|
239
|
-
const entry =
|
|
362
|
+
const entry = Path3.basename(filename, Path3.extname(filename));
|
|
240
363
|
return options.formats.cjs ? {
|
|
241
364
|
types: `./src/${entry}.d.ts`,
|
|
242
365
|
import: existing,
|
|
@@ -265,7 +388,7 @@ function generateExports(entries, mainEntry, options, existingExports = {}) {
|
|
|
265
388
|
if (!isValidEntrypoint(filename)) {
|
|
266
389
|
throw new Error(`Export import path '${existing.import}' references '${filename}' which is not a valid entrypoint. Valid entrypoints cannot start with '_' or '.' and must be .ts/.js files in src/.`);
|
|
267
390
|
}
|
|
268
|
-
const entry =
|
|
391
|
+
const entry = Path3.basename(filename, Path3.extname(filename));
|
|
269
392
|
return {
|
|
270
393
|
...existing,
|
|
271
394
|
types: existing.types || `./src/${entry}.d.ts`,
|
|
@@ -313,14 +436,6 @@ function generateExports(entries, mainEntry, options, existingExports = {}) {
|
|
|
313
436
|
if (!exports2[`${key}.js`]) {
|
|
314
437
|
exports2[`${key}.js`] = exports2[key];
|
|
315
438
|
}
|
|
316
|
-
if (entry === "jsx-runtime") {
|
|
317
|
-
if (!exports2["./jsx-dev-runtime"]) {
|
|
318
|
-
exports2["./jsx-dev-runtime"] = exports2[key];
|
|
319
|
-
}
|
|
320
|
-
if (!exports2["./jsx-dev-runtime.js"]) {
|
|
321
|
-
exports2["./jsx-dev-runtime.js"] = exports2[key];
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
439
|
}
|
|
325
440
|
if (options.formats.umd && !exports2["./umd"]) {
|
|
326
441
|
exports2["./umd"] = {
|
|
@@ -352,6 +467,30 @@ function transformSrcToDist(value) {
|
|
|
352
467
|
}
|
|
353
468
|
return value;
|
|
354
469
|
}
|
|
470
|
+
function transformBinPaths(value) {
|
|
471
|
+
if (typeof value === "string") {
|
|
472
|
+
if (value.startsWith("./dist/src/")) {
|
|
473
|
+
return value.replace("./dist/", "");
|
|
474
|
+
}
|
|
475
|
+
if (value.startsWith("dist/src/")) {
|
|
476
|
+
return value.replace("dist/", "");
|
|
477
|
+
}
|
|
478
|
+
if (value.startsWith("./src/")) {
|
|
479
|
+
return value.replace("./", "");
|
|
480
|
+
}
|
|
481
|
+
if (value.startsWith("src/") || value === "src") {
|
|
482
|
+
return value;
|
|
483
|
+
}
|
|
484
|
+
return value;
|
|
485
|
+
} else if (typeof value === "object" && value !== null) {
|
|
486
|
+
const transformed = {};
|
|
487
|
+
for (const [key, val] of Object.entries(value)) {
|
|
488
|
+
transformed[key] = transformBinPaths(val);
|
|
489
|
+
}
|
|
490
|
+
return transformed;
|
|
491
|
+
}
|
|
492
|
+
return value;
|
|
493
|
+
}
|
|
355
494
|
function fixExportsForDist(obj) {
|
|
356
495
|
if (typeof obj === "string") {
|
|
357
496
|
if (obj.includes("/dist/") && obj.includes("/src/")) {
|
|
@@ -374,6 +513,8 @@ function fixExportsForDist(obj) {
|
|
|
374
513
|
for (const [key, val] of Object.entries(obj)) {
|
|
375
514
|
if (key === "files" && Array.isArray(val)) {
|
|
376
515
|
fixed[key] = val.filter((file) => file !== "dist/" && file !== "dist").concat(val.includes("dist/") || val.includes("dist") ? ["src/"] : []);
|
|
516
|
+
} else if (key === "bin") {
|
|
517
|
+
fixed[key] = val;
|
|
377
518
|
} else {
|
|
378
519
|
fixed[key] = fixExportsForDist(val);
|
|
379
520
|
}
|
|
@@ -401,7 +542,9 @@ function cleanPackageJSON(pkg, mainEntry, options) {
|
|
|
401
542
|
"bin",
|
|
402
543
|
"scripts",
|
|
403
544
|
"dependencies",
|
|
545
|
+
"devDependencies",
|
|
404
546
|
"peerDependencies",
|
|
547
|
+
"peerDependenciesMeta",
|
|
405
548
|
"optionalDependencies",
|
|
406
549
|
"bundledDependencies",
|
|
407
550
|
"engines",
|
|
@@ -428,7 +571,7 @@ function cleanPackageJSON(pkg, mainEntry, options) {
|
|
|
428
571
|
cleaned[field] = transformSrcToDist(filteredScripts);
|
|
429
572
|
}
|
|
430
573
|
} else if (field === "bin") {
|
|
431
|
-
cleaned[field] =
|
|
574
|
+
cleaned[field] = transformBinPaths(pkg[field]);
|
|
432
575
|
} else if (pathFields.includes(field)) {
|
|
433
576
|
cleaned[field] = transformSrcToDist(pkg[field]);
|
|
434
577
|
} else {
|
|
@@ -448,36 +591,50 @@ function cleanPackageJSON(pkg, mainEntry, options) {
|
|
|
448
591
|
}
|
|
449
592
|
async function fileExists(filePath) {
|
|
450
593
|
try {
|
|
451
|
-
await
|
|
594
|
+
await FS3.access(filePath);
|
|
452
595
|
return true;
|
|
453
596
|
} catch {
|
|
454
597
|
return false;
|
|
455
598
|
}
|
|
456
599
|
}
|
|
600
|
+
function validatePath(inputPath, basePath) {
|
|
601
|
+
if (Path3.isAbsolute(inputPath)) {
|
|
602
|
+
throw new Error(`Absolute paths are not allowed: ${inputPath}`);
|
|
603
|
+
}
|
|
604
|
+
if (inputPath.includes("..")) {
|
|
605
|
+
throw new Error(`Path traversal is not allowed: ${inputPath}`);
|
|
606
|
+
}
|
|
607
|
+
const resolvedPath = Path3.resolve(basePath, inputPath);
|
|
608
|
+
const resolvedBase = Path3.resolve(basePath);
|
|
609
|
+
if (!resolvedPath.startsWith(resolvedBase + Path3.sep) && resolvedPath !== resolvedBase) {
|
|
610
|
+
throw new Error(`Path ${inputPath} resolves outside the project directory`);
|
|
611
|
+
}
|
|
612
|
+
return resolvedPath;
|
|
613
|
+
}
|
|
457
614
|
async function build2(cwd, save = false) {
|
|
458
|
-
console.
|
|
459
|
-
const srcDir =
|
|
460
|
-
const distDir =
|
|
461
|
-
const distSrcDir =
|
|
615
|
+
console.info("Building with libuild...");
|
|
616
|
+
const srcDir = Path3.join(cwd, "src");
|
|
617
|
+
const distDir = Path3.join(cwd, "dist");
|
|
618
|
+
const distSrcDir = Path3.join(distDir, "src");
|
|
462
619
|
if (!await fileExists(srcDir)) {
|
|
463
620
|
throw new Error("No src/ directory found");
|
|
464
621
|
}
|
|
465
|
-
const pkgPath =
|
|
466
|
-
const pkg = JSON.parse(await
|
|
622
|
+
const pkgPath = Path3.join(cwd, "package.json");
|
|
623
|
+
const pkg = JSON.parse(await FS3.readFile(pkgPath, "utf-8"));
|
|
467
624
|
if (!pkg.private) {
|
|
468
625
|
console.warn("\u26A0\uFE0F WARNING: Root package.json is not private - this could lead to accidental publishing of development package.json");
|
|
469
626
|
console.warn(" Consider setting 'private: true' in your root package.json");
|
|
470
627
|
}
|
|
471
|
-
const gitignorePath =
|
|
628
|
+
const gitignorePath = Path3.join(cwd, ".gitignore");
|
|
472
629
|
if (await fileExists(gitignorePath)) {
|
|
473
|
-
const gitignoreContent = await
|
|
630
|
+
const gitignoreContent = await FS3.readFile(gitignorePath, "utf-8");
|
|
474
631
|
const isDistIgnored = gitignoreContent.includes("dist/") || gitignoreContent.includes("/dist") || gitignoreContent.includes("dist\n") || gitignoreContent.includes("dist\r\n");
|
|
475
632
|
if (!isDistIgnored) {
|
|
476
633
|
console.warn("\u26A0\uFE0F WARNING: dist/ directory is not in .gitignore - built files should not be committed");
|
|
477
634
|
console.warn(" Add 'dist/' to your .gitignore file");
|
|
478
635
|
}
|
|
479
636
|
}
|
|
480
|
-
const entries = await
|
|
637
|
+
const entries = await findEntrypoints(srcDir);
|
|
481
638
|
if (entries.length === 0) {
|
|
482
639
|
throw new Error("No entry points found in src/");
|
|
483
640
|
}
|
|
@@ -490,23 +647,40 @@ async function build2(cwd, save = false) {
|
|
|
490
647
|
umd: entries.includes("umd")
|
|
491
648
|
}
|
|
492
649
|
};
|
|
493
|
-
const mainEntry =
|
|
494
|
-
console.
|
|
495
|
-
console.
|
|
650
|
+
const mainEntry = detectMainEntry(pkg, entries);
|
|
651
|
+
console.info(" Found entries:", entries.join(", "));
|
|
652
|
+
console.info(" Main entry:", mainEntry);
|
|
496
653
|
if (options.formats.cjs) {
|
|
497
|
-
console.
|
|
654
|
+
console.info(" Formats: ESM, CJS" + (options.formats.umd ? ", UMD" : ""));
|
|
498
655
|
} else {
|
|
499
|
-
console.
|
|
656
|
+
console.info(" Formats: ESM" + (options.formats.umd ? ", UMD" : "") + " (no main field - CJS disabled)");
|
|
500
657
|
}
|
|
501
|
-
|
|
502
|
-
|
|
658
|
+
const tempDistDir = `${distDir}.tmp.${Date.now()}.${Math.random().toString(36).substr(2, 9)}`;
|
|
659
|
+
try {
|
|
660
|
+
await FS3.mkdir(tempDistDir, { recursive: true });
|
|
661
|
+
if (await fileExists(distDir)) {
|
|
662
|
+
await FS3.rm(distDir, { recursive: true });
|
|
663
|
+
}
|
|
664
|
+
await FS3.rename(tempDistDir, distDir);
|
|
665
|
+
} catch (error) {
|
|
666
|
+
try {
|
|
667
|
+
if (await fileExists(tempDistDir)) {
|
|
668
|
+
await FS3.rm(tempDistDir, { recursive: true });
|
|
669
|
+
}
|
|
670
|
+
} catch {
|
|
671
|
+
}
|
|
672
|
+
throw error;
|
|
503
673
|
}
|
|
504
|
-
|
|
674
|
+
const externalDeps = [
|
|
675
|
+
...Object.keys(pkg.dependencies || {}),
|
|
676
|
+
...Object.keys(pkg.peerDependencies || {}),
|
|
677
|
+
...Object.keys(pkg.optionalDependencies || {})
|
|
678
|
+
];
|
|
505
679
|
const entryPoints = [];
|
|
506
680
|
const umdEntries = [];
|
|
507
681
|
for (const entry of entries) {
|
|
508
|
-
const entryPath =
|
|
509
|
-
const jsEntryPath =
|
|
682
|
+
const entryPath = Path3.join(srcDir, `${entry}.ts`);
|
|
683
|
+
const jsEntryPath = Path3.join(srcDir, `${entry}.js`);
|
|
510
684
|
const actualPath = await fileExists(entryPath) ? entryPath : jsEntryPath;
|
|
511
685
|
if (!await fileExists(actualPath)) {
|
|
512
686
|
throw new Error(`Entry point file not found: ${actualPath}. Expected ${entry}.ts or ${entry}.js in src/ directory.`);
|
|
@@ -518,105 +692,75 @@ async function build2(cwd, save = false) {
|
|
|
518
692
|
}
|
|
519
693
|
}
|
|
520
694
|
if (entryPoints.length > 0) {
|
|
521
|
-
|
|
695
|
+
const entryNames = entryPoints.map((path) => {
|
|
696
|
+
const name = Path3.basename(path, Path3.extname(path));
|
|
697
|
+
return name;
|
|
698
|
+
});
|
|
699
|
+
console.info(` Building ${entryPoints.length} entries (ESM)...`);
|
|
522
700
|
await ESBuild.build({
|
|
523
701
|
entryPoints,
|
|
524
702
|
outdir: distSrcDir,
|
|
525
703
|
format: "esm",
|
|
526
|
-
entryNames: "[name]",
|
|
527
704
|
outExtension: { ".js": ".js" },
|
|
528
705
|
bundle: true,
|
|
529
|
-
splitting: true,
|
|
530
|
-
// Enable shared chunk extraction
|
|
531
706
|
minify: false,
|
|
532
|
-
sourcemap:
|
|
533
|
-
external:
|
|
707
|
+
sourcemap: false,
|
|
708
|
+
external: externalDeps,
|
|
534
709
|
platform: "node",
|
|
535
|
-
target: "node16"
|
|
710
|
+
target: "node16",
|
|
711
|
+
plugins: [
|
|
712
|
+
externalEntrypointsPlugin({
|
|
713
|
+
entryNames,
|
|
714
|
+
outputExtension: ".js"
|
|
715
|
+
}),
|
|
716
|
+
dtsPlugin({
|
|
717
|
+
outDir: distSrcDir,
|
|
718
|
+
rootDir: srcDir,
|
|
719
|
+
entryPoints
|
|
720
|
+
})
|
|
721
|
+
]
|
|
536
722
|
});
|
|
537
723
|
if (options.formats.cjs) {
|
|
538
|
-
console.
|
|
724
|
+
console.info(` Building ${entryPoints.length} entries (CJS)...`);
|
|
539
725
|
await ESBuild.build({
|
|
540
726
|
entryPoints,
|
|
541
727
|
outdir: distSrcDir,
|
|
542
728
|
format: "cjs",
|
|
543
|
-
entryNames: "[name]",
|
|
544
729
|
outExtension: { ".js": ".cjs" },
|
|
545
730
|
bundle: true,
|
|
546
731
|
minify: false,
|
|
547
|
-
sourcemap:
|
|
548
|
-
external:
|
|
732
|
+
sourcemap: false,
|
|
733
|
+
external: externalDeps,
|
|
549
734
|
platform: "node",
|
|
550
|
-
target: "node16"
|
|
551
|
-
|
|
735
|
+
target: "node16",
|
|
736
|
+
plugins: [
|
|
737
|
+
externalEntrypointsPlugin({
|
|
738
|
+
entryNames,
|
|
739
|
+
outputExtension: ".cjs"
|
|
740
|
+
})
|
|
741
|
+
]
|
|
552
742
|
});
|
|
553
743
|
}
|
|
554
744
|
}
|
|
555
745
|
for (const umdPath of umdEntries) {
|
|
556
|
-
const entry =
|
|
557
|
-
console.
|
|
746
|
+
const entry = Path3.basename(umdPath, Path3.extname(umdPath));
|
|
747
|
+
console.info(` Building ${entry} (UMD)...`);
|
|
558
748
|
const globalName = pkg.name.includes("/") ? pkg.name.split("/").pop().replace(/-/g, "").charAt(0).toUpperCase() + pkg.name.split("/").pop().replace(/-/g, "").slice(1) : pkg.name.replace(/-/g, "").charAt(0).toUpperCase() + pkg.name.replace(/-/g, "").slice(1);
|
|
559
749
|
await ESBuild.build({
|
|
560
750
|
entryPoints: [umdPath],
|
|
561
751
|
outdir: distSrcDir,
|
|
562
752
|
format: "cjs",
|
|
563
|
-
entryNames: "[name]",
|
|
564
753
|
bundle: true,
|
|
565
754
|
minify: false,
|
|
566
|
-
sourcemap:
|
|
567
|
-
external:
|
|
755
|
+
sourcemap: false,
|
|
756
|
+
external: externalDeps,
|
|
568
757
|
platform: "node",
|
|
569
758
|
target: "node16",
|
|
570
759
|
plugins: [umdPlugin({ globalName })]
|
|
571
760
|
});
|
|
572
761
|
}
|
|
573
|
-
console.log(" Generating TypeScript declarations...");
|
|
574
|
-
const allTsFiles = [...entryPoints, ...umdEntries].filter((file) => file.endsWith(".ts"));
|
|
575
|
-
if (allTsFiles.length > 0) {
|
|
576
|
-
const compilerOptions = {
|
|
577
|
-
declaration: true,
|
|
578
|
-
emitDeclarationOnly: true,
|
|
579
|
-
outDir: distSrcDir,
|
|
580
|
-
rootDir: srcDir,
|
|
581
|
-
skipLibCheck: true,
|
|
582
|
-
esModuleInterop: true,
|
|
583
|
-
target: TS.ScriptTarget.ES2020,
|
|
584
|
-
module: TS.ModuleKind.ESNext
|
|
585
|
-
};
|
|
586
|
-
const program = TS.createProgram(allTsFiles, compilerOptions);
|
|
587
|
-
const emitResult = program.emit();
|
|
588
|
-
if (emitResult.diagnostics.length > 0) {
|
|
589
|
-
const diagnostics = TS.formatDiagnosticsWithColorAndContext(emitResult.diagnostics, {
|
|
590
|
-
getCanonicalFileName: (path) => path,
|
|
591
|
-
getCurrentDirectory: () => cwd,
|
|
592
|
-
getNewLine: () => "\n"
|
|
593
|
-
});
|
|
594
|
-
throw new Error(`TypeScript declaration generation failed:
|
|
595
|
-
${diagnostics}`);
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
for (const entry of entries) {
|
|
599
|
-
if (entry === "umd")
|
|
600
|
-
continue;
|
|
601
|
-
const jsPath = Path2.join(distSrcDir, `${entry}.js`);
|
|
602
|
-
const dtsPath = Path2.join(distSrcDir, `${entry}.d.ts`);
|
|
603
|
-
if (await fileExists(jsPath) && await fileExists(dtsPath)) {
|
|
604
|
-
const content = await FS2.readFile(jsPath, "utf-8");
|
|
605
|
-
if (content.startsWith("#!")) {
|
|
606
|
-
const lines = content.split("\n");
|
|
607
|
-
const shebang = lines[0];
|
|
608
|
-
const rest = lines.slice(1).join("\n");
|
|
609
|
-
await FS2.writeFile(jsPath, `${shebang}
|
|
610
|
-
/// <reference types="./${entry}.d.ts" />
|
|
611
|
-
${rest}`);
|
|
612
|
-
} else {
|
|
613
|
-
await FS2.writeFile(jsPath, `/// <reference types="./${entry}.d.ts" />
|
|
614
|
-
${content}`);
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
762
|
const autoDiscoveredFiles = [];
|
|
619
|
-
console.
|
|
763
|
+
console.info(" Generating package.json...");
|
|
620
764
|
const cleanedPkg = cleanPackageJSON(pkg, mainEntry, options);
|
|
621
765
|
const exportsResult = generateExports(entries, mainEntry, options, pkg.exports);
|
|
622
766
|
cleanedPkg.exports = fixExportsForDist(exportsResult.exports);
|
|
@@ -626,7 +770,7 @@ ${content}`);
|
|
|
626
770
|
console.warn(` - ${staleExport}`);
|
|
627
771
|
}
|
|
628
772
|
if (save) {
|
|
629
|
-
console.
|
|
773
|
+
console.info(" Removing stale exports from root package.json (--save mode)");
|
|
630
774
|
} else {
|
|
631
775
|
console.warn(" Use --save to remove these from root package.json");
|
|
632
776
|
}
|
|
@@ -639,62 +783,71 @@ ${content}`);
|
|
|
639
783
|
}
|
|
640
784
|
}
|
|
641
785
|
const fixedDistPkg = fixExportsForDist(cleanedPkg);
|
|
642
|
-
await
|
|
643
|
-
|
|
786
|
+
await FS3.writeFile(
|
|
787
|
+
Path3.join(distDir, "package.json"),
|
|
644
788
|
JSON.stringify(fixedDistPkg, null, 2) + "\n"
|
|
645
789
|
);
|
|
646
790
|
const defaultFilesToCopy = ["README.md", "LICENSE", "CHANGELOG.md"];
|
|
647
791
|
for (const file of defaultFilesToCopy) {
|
|
648
|
-
const srcPath =
|
|
792
|
+
const srcPath = Path3.join(cwd, file);
|
|
649
793
|
if (await fileExists(srcPath)) {
|
|
650
|
-
console.
|
|
651
|
-
await
|
|
794
|
+
console.info(` Copying ${file}...`);
|
|
795
|
+
await FS3.copyFile(srcPath, Path3.join(distDir, file));
|
|
652
796
|
}
|
|
653
797
|
}
|
|
654
798
|
const commonFiles = ["README.md", "LICENSE", "CHANGELOG.md", "COPYING", "AUTHORS"];
|
|
655
799
|
if (pkg.files && Array.isArray(pkg.files)) {
|
|
656
800
|
for (const commonFile of commonFiles) {
|
|
657
|
-
const commonPath =
|
|
801
|
+
const commonPath = Path3.join(cwd, commonFile);
|
|
658
802
|
if (await fileExists(commonPath) && !pkg.files.includes(commonFile)) {
|
|
659
|
-
console.
|
|
803
|
+
console.info(` Auto-discovered ${commonFile}, adding to files field...`);
|
|
660
804
|
pkg.files.push(commonFile);
|
|
661
805
|
autoDiscoveredFiles.push(commonFile);
|
|
662
806
|
}
|
|
663
807
|
}
|
|
664
808
|
}
|
|
665
809
|
if (pkg.files && Array.isArray(pkg.files)) {
|
|
666
|
-
console.
|
|
810
|
+
console.info(" Copying files from package.json files field...");
|
|
667
811
|
for (const pattern of pkg.files) {
|
|
668
812
|
if (typeof pattern === "string" && (pattern.includes("src") || pattern.includes("dist"))) {
|
|
669
813
|
continue;
|
|
670
814
|
}
|
|
671
815
|
if (typeof pattern === "string") {
|
|
672
|
-
const
|
|
673
|
-
const
|
|
674
|
-
if (await fileExists(
|
|
675
|
-
const stat2 = await
|
|
816
|
+
const validatedSrcPath = validatePath(pattern, cwd);
|
|
817
|
+
const validatedDestPath = validatePath(pattern, distDir);
|
|
818
|
+
if (await fileExists(validatedSrcPath)) {
|
|
819
|
+
const stat2 = await FS3.stat(validatedSrcPath);
|
|
820
|
+
if (stat2.isSymbolicLink()) {
|
|
821
|
+
throw new Error(`Symbolic links are not allowed in files field: ${pattern}`);
|
|
822
|
+
}
|
|
676
823
|
if (stat2.isDirectory()) {
|
|
677
|
-
console.
|
|
678
|
-
await
|
|
679
|
-
await
|
|
824
|
+
console.info(` Copying directory ${pattern}/...`);
|
|
825
|
+
await FS3.mkdir(Path3.dirname(validatedDestPath), { recursive: true });
|
|
826
|
+
await FS3.cp(validatedSrcPath, validatedDestPath, { recursive: true });
|
|
827
|
+
} else if (stat2.isFile()) {
|
|
828
|
+
console.info(` Copying ${pattern}...`);
|
|
829
|
+
await FS3.mkdir(Path3.dirname(validatedDestPath), { recursive: true });
|
|
830
|
+
await FS3.copyFile(validatedSrcPath, validatedDestPath);
|
|
680
831
|
} else {
|
|
681
|
-
|
|
682
|
-
await FS2.mkdir(Path2.dirname(destPath), { recursive: true });
|
|
683
|
-
await FS2.copyFile(srcPath, destPath);
|
|
832
|
+
throw new Error(`Unsupported file type for ${pattern}. Only regular files and directories are allowed.`);
|
|
684
833
|
}
|
|
685
834
|
} else if (pattern.includes("*")) {
|
|
686
835
|
const baseDir = pattern.split("*")[0].replace(/\/$/, "");
|
|
687
|
-
if (baseDir
|
|
688
|
-
|
|
689
|
-
const
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
836
|
+
if (baseDir) {
|
|
837
|
+
const validatedBaseSrcPath = validatePath(baseDir, cwd);
|
|
838
|
+
const validatedBaseDestPath = validatePath(baseDir, distDir);
|
|
839
|
+
if (await fileExists(validatedBaseSrcPath)) {
|
|
840
|
+
console.info(` Copying pattern ${pattern}...`);
|
|
841
|
+
await FS3.mkdir(Path3.dirname(validatedBaseDestPath), { recursive: true });
|
|
842
|
+
await FS3.cp(validatedBaseSrcPath, validatedBaseDestPath, { recursive: true });
|
|
843
|
+
} else {
|
|
844
|
+
throw new Error(`Pattern base directory not found for "${pattern}". Expected directory: ${validatedBaseSrcPath}`);
|
|
845
|
+
}
|
|
693
846
|
} else {
|
|
694
|
-
throw new Error(`
|
|
847
|
+
throw new Error(`Invalid pattern "${pattern}". Pattern must have a base directory before the wildcard.`);
|
|
695
848
|
}
|
|
696
849
|
} else {
|
|
697
|
-
throw new Error(`File specified in files field not found: ${
|
|
850
|
+
throw new Error(`File specified in files field not found: ${validatedSrcPath}. Remove "${pattern}" from package.json files field or create the file.`);
|
|
698
851
|
}
|
|
699
852
|
} else {
|
|
700
853
|
throw new Error(`Invalid files field entry: ${JSON.stringify(pattern)}. Files field entries must be strings.`);
|
|
@@ -702,7 +855,7 @@ ${content}`);
|
|
|
702
855
|
}
|
|
703
856
|
}
|
|
704
857
|
if (save) {
|
|
705
|
-
console.
|
|
858
|
+
console.info(" Updating root package.json...");
|
|
706
859
|
const rootPkg2 = { ...pkg };
|
|
707
860
|
rootPkg2.private = true;
|
|
708
861
|
if (options.formats.cjs) {
|
|
@@ -711,7 +864,7 @@ ${content}`);
|
|
|
711
864
|
rootPkg2.module = `./dist/src/${mainEntry}.js`;
|
|
712
865
|
rootPkg2.types = `./dist/src/${mainEntry}.d.ts`;
|
|
713
866
|
if (rootPkg2.typings && typeof rootPkg2.typings === "string") {
|
|
714
|
-
rootPkg2.typings = rootPkg2.typings.startsWith("./dist/") ? rootPkg2.typings : "./" +
|
|
867
|
+
rootPkg2.typings = rootPkg2.typings.startsWith("./dist/") ? rootPkg2.typings : "./" + Path3.join("dist", rootPkg2.typings);
|
|
715
868
|
}
|
|
716
869
|
const rootExports = {};
|
|
717
870
|
for (const [key, value] of Object.entries(cleanedPkg.exports)) {
|
|
@@ -730,12 +883,20 @@ ${content}`);
|
|
|
730
883
|
if (rootPkg2.bin) {
|
|
731
884
|
if (typeof rootPkg2.bin === "string") {
|
|
732
885
|
if (!rootPkg2.bin.startsWith("./dist/")) {
|
|
733
|
-
rootPkg2.bin
|
|
886
|
+
if (rootPkg2.bin.startsWith("dist/")) {
|
|
887
|
+
rootPkg2.bin = "./" + rootPkg2.bin;
|
|
888
|
+
} else {
|
|
889
|
+
rootPkg2.bin = "./" + Path3.join("dist", rootPkg2.bin);
|
|
890
|
+
}
|
|
734
891
|
}
|
|
735
892
|
} else {
|
|
736
893
|
for (const [name, binPath] of Object.entries(rootPkg2.bin)) {
|
|
737
894
|
if (typeof binPath === "string" && !binPath.startsWith("./dist/")) {
|
|
738
|
-
|
|
895
|
+
if (binPath.startsWith("dist/")) {
|
|
896
|
+
rootPkg2.bin[name] = "./" + binPath;
|
|
897
|
+
} else {
|
|
898
|
+
rootPkg2.bin[name] = "./" + Path3.join("dist", binPath);
|
|
899
|
+
}
|
|
739
900
|
}
|
|
740
901
|
}
|
|
741
902
|
}
|
|
@@ -755,51 +916,52 @@ ${content}`);
|
|
|
755
916
|
rootPkg2.files.push("dist/");
|
|
756
917
|
}
|
|
757
918
|
}
|
|
758
|
-
await
|
|
919
|
+
await FS3.writeFile(pkgPath, JSON.stringify(rootPkg2, null, 2) + "\n");
|
|
759
920
|
} else {
|
|
760
|
-
console.
|
|
921
|
+
console.info(" Skipping root package.json update (use --save to enable)");
|
|
761
922
|
}
|
|
762
|
-
console.
|
|
763
|
-
console.
|
|
923
|
+
console.info("\nBuild complete!");
|
|
924
|
+
console.info(`
|
|
764
925
|
Output: ${distDir}`);
|
|
765
|
-
console.
|
|
926
|
+
console.info(`
|
|
766
927
|
Entries: ${entries.length}`);
|
|
767
928
|
if (options.formats.cjs) {
|
|
768
|
-
console.
|
|
929
|
+
console.info(`
|
|
769
930
|
Formats: ESM, CJS${options.formats.umd ? ", UMD" : ""}`);
|
|
770
931
|
} else {
|
|
771
|
-
console.
|
|
932
|
+
console.info(`
|
|
772
933
|
Formats: ESM${options.formats.umd ? ", UMD" : ""}`);
|
|
773
934
|
}
|
|
774
935
|
let rootPkg = pkg;
|
|
775
936
|
if (save) {
|
|
776
|
-
rootPkg = JSON.parse(await
|
|
937
|
+
rootPkg = JSON.parse(await FS3.readFile(pkgPath, "utf-8"));
|
|
777
938
|
}
|
|
778
939
|
return { distPkg: fixedDistPkg, rootPkg };
|
|
779
940
|
}
|
|
780
|
-
async function publish(cwd, save = true) {
|
|
941
|
+
async function publish(cwd, save = true, extraArgs = []) {
|
|
781
942
|
await build2(cwd, save);
|
|
782
|
-
console.
|
|
783
|
-
const distDir =
|
|
784
|
-
const distPkgPath =
|
|
943
|
+
console.info("\nPublishing to npm...");
|
|
944
|
+
const distDir = Path3.join(cwd, "dist");
|
|
945
|
+
const distPkgPath = Path3.join(distDir, "package.json");
|
|
785
946
|
if (!await fileExists(distPkgPath)) {
|
|
786
947
|
throw new Error("No dist/package.json found. Run 'libuild build' first.");
|
|
787
948
|
}
|
|
788
|
-
const distPkg = JSON.parse(await
|
|
949
|
+
const distPkg = JSON.parse(await FS3.readFile(distPkgPath, "utf-8"));
|
|
789
950
|
const publishArgs = ["publish"];
|
|
790
951
|
if (distPkg.name.startsWith("@")) {
|
|
791
952
|
publishArgs.push("--access", "public");
|
|
792
953
|
}
|
|
954
|
+
publishArgs.push(...extraArgs);
|
|
793
955
|
const proc = (0, import_child_process.spawn)("npm", publishArgs, {
|
|
794
956
|
cwd: distDir,
|
|
795
957
|
stdio: "inherit"
|
|
796
958
|
});
|
|
797
|
-
const exitCode = await new Promise((
|
|
798
|
-
proc.on("close",
|
|
959
|
+
const exitCode = await new Promise((resolve3) => {
|
|
960
|
+
proc.on("close", resolve3);
|
|
799
961
|
});
|
|
800
962
|
if (exitCode === 0) {
|
|
801
|
-
const distPkg2 = JSON.parse(await
|
|
802
|
-
console.
|
|
963
|
+
const distPkg2 = JSON.parse(await FS3.readFile(distPkgPath, "utf-8"));
|
|
964
|
+
console.info(`
|
|
803
965
|
Published ${distPkg2.name}@${distPkg2.version}!`);
|
|
804
966
|
} else {
|
|
805
967
|
throw new Error("npm publish failed");
|
|
@@ -811,4 +973,3 @@ Published ${distPkg2.name}@${distPkg2.version}!`);
|
|
|
811
973
|
publish,
|
|
812
974
|
transformSrcToDist
|
|
813
975
|
});
|
|
814
|
-
//# sourceMappingURL=libuild.cjs.map
|