bunup 0.8.48 → 0.8.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,949 @@
1
+ import {
2
+ filterBunupBunPlugins,
3
+ filterBunupPlugins,
4
+ runPluginBuildDoneHooks,
5
+ runPluginBuildStartHooks
6
+ } from "./chunk-t9xma3m6.js";
7
+ import {
8
+ loadPackageJson,
9
+ loadTsConfig
10
+ } from "./chunk-5v78yfze.js";
11
+ import {
12
+ BunupBuildError,
13
+ JS_RE,
14
+ cleanOutDir,
15
+ cleanPath,
16
+ deleteExtension,
17
+ ensureArray,
18
+ formatFileSize,
19
+ generateRandomString,
20
+ getDeclarationExtensionFromJsExtension,
21
+ getDefaultDtsExtention,
22
+ getDefaultOutputExtension,
23
+ getExtension,
24
+ getFilesFromGlobs,
25
+ getPackageDeps,
26
+ getShortFilePath,
27
+ isDev,
28
+ isNullOrUndefined,
29
+ isTypeScriptFile,
30
+ link,
31
+ logTable,
32
+ logger,
33
+ replaceExtension,
34
+ returnPathIfExists,
35
+ setSilent
36
+ } from "./chunk-y0jgbvca.js";
37
+
38
+ // src/build.ts
39
+ import path2 from "path";
40
+ import pc3 from "picocolors";
41
+
42
+ // src/dts/generate.ts
43
+ import fs from "fs/promises";
44
+ import path from "path";
45
+ import { isolatedDeclaration } from "oxc-transform";
46
+ import { resolveTsImportPath } from "ts-import-resolver";
47
+
48
+ // src/dts/fake-js.ts
49
+ import { parse } from "@babel/parser";
50
+
51
+ // src/dts/re.ts
52
+ var IMPORT_TYPE_RE = /import\s+type\s+/g;
53
+ var EXPORT_TYPE_RE = /export\s+type\s+/g;
54
+ var IMPORT_EXPORT_NAMES_RE = /(import|export)\s*{([^}]*)}/g;
55
+ var IMPORT_EXPORT_WITH_DEFAULT_RE = /(import|export)(\s+[^{,]+,)?\s*{([^}]*)}/g;
56
+ var TYPE_WORD_RE = /\btype\s+/g;
57
+ var EXPORT_DEFAULT_RE = /\bexport\s+default\s+/g;
58
+ var EXPORT_RE = /\bexport\s+/g;
59
+ var TOKENIZE_RE = /(\s+|\/\/.*?(?:\n|$)|\/\*[\s\S]*?\*\/|[a-zA-Z_$][a-zA-Z0-9_$]*|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`|\d+(?:\.\d*)?(?:[eE][+-]?\d+)?|[(){}[\],.;:]|=>|&&|\|\||[=!<>]=?|\+\+|--|[-+*/%&|^!~?]|\.{3}|::|\.)/g;
60
+ var CAPITAL_LETTER_RE = /[A-Z]/;
61
+ var NODE_MODULES_RE = /node_modules/;
62
+
63
+ // src/dts/ast.ts
64
+ function isLikelyVariableOrTypeName(token) {
65
+ return CAPITAL_LETTER_RE.test(token) && !token.startsWith("/*") && !token.startsWith("@") && !token.startsWith('"') && !token.startsWith("'") && !token.startsWith("`");
66
+ }
67
+ function isImportDeclaration(node) {
68
+ return node.type === "ImportDeclaration";
69
+ }
70
+ function isExportAllDeclaration(node) {
71
+ return node.type === "ExportAllDeclaration";
72
+ }
73
+ function isReExportStatement(node) {
74
+ return node.type === "ExportNamedDeclaration" && !node.declaration;
75
+ }
76
+ function hasExportModifier(node, text) {
77
+ return node.type.startsWith("Export") || text.trim().startsWith("export");
78
+ }
79
+ function hasDefaultExportModifier(node, text) {
80
+ return node.type === "ExportDefaultDeclaration" || text.trim().startsWith("export default");
81
+ }
82
+ function isDefaultReExport(node) {
83
+ return node.type === "ExportDefaultDeclaration" && node.declaration?.type === "Identifier";
84
+ }
85
+ function getName(node, source) {
86
+ if (!node)
87
+ return null;
88
+ if (node.type === "ExportNamedDeclaration" && node.declaration) {
89
+ return getName(node.declaration, source);
90
+ }
91
+ if (node.type === "ExportDefaultDeclaration" && node.declaration) {
92
+ if (node.declaration.type === "Identifier") {
93
+ return node.declaration.name;
94
+ }
95
+ return getName(node.declaration, source);
96
+ }
97
+ switch (node.type) {
98
+ case "TSInterfaceDeclaration":
99
+ case "TSTypeAliasDeclaration":
100
+ case "ClassDeclaration":
101
+ case "TSEnumDeclaration":
102
+ case "FunctionDeclaration":
103
+ case "TSDeclareFunction":
104
+ if (node.id && node.id.type === "Identifier") {
105
+ return node.id.name;
106
+ }
107
+ break;
108
+ case "TSModuleDeclaration":
109
+ if (node.id) {
110
+ if (node.id.type === "Identifier") {
111
+ return node.id.name;
112
+ }
113
+ if (node.id.type === "StringLiteral" && typeof node.id.value === "string") {
114
+ return node.id.value;
115
+ }
116
+ }
117
+ break;
118
+ case "VariableDeclaration": {
119
+ const declarations = node.declarations;
120
+ if (declarations?.length === 1 && declarations[0].id?.type === "Identifier") {
121
+ return declarations[0].id.name;
122
+ }
123
+ break;
124
+ }
125
+ }
126
+ return null;
127
+ }
128
+ function getCommentText(comments) {
129
+ if (!comments)
130
+ return null;
131
+ return comments.map((comment) => {
132
+ return comment.type === "CommentBlock" ? `/*${comment.value}*/` : comment.type === "CommentLine" ? `//${comment.value}` : null;
133
+ }).join(`
134
+ `);
135
+ }
136
+ function getAllImportNames(body) {
137
+ const importNames = [];
138
+ for (const statement of body) {
139
+ if (isImportDeclaration(statement)) {
140
+ const importDecl = statement;
141
+ if (importDecl.specifiers) {
142
+ for (const specifier of importDecl.specifiers) {
143
+ if (specifier.type === "ImportDefaultSpecifier") {
144
+ importNames.push(specifier.local.name);
145
+ } else if (specifier.type === "ImportSpecifier") {
146
+ importNames.push(specifier.local.name);
147
+ } else if (specifier.type === "ImportNamespaceSpecifier") {
148
+ importNames.push(specifier.local.name);
149
+ }
150
+ }
151
+ }
152
+ }
153
+ }
154
+ return importNames;
155
+ }
156
+
157
+ // src/dts/fake-js.ts
158
+ async function dtsToFakeJs(dtsContent) {
159
+ const parsed = parse(dtsContent, {
160
+ sourceType: "module",
161
+ plugins: ["typescript"],
162
+ allowImportExportEverywhere: true,
163
+ allowAwaitOutsideFunction: true
164
+ });
165
+ const referencedNames = new Set;
166
+ const exportedNames = new Set;
167
+ const result = [];
168
+ for (const name of getAllImportNames(parsed.program.body)) {
169
+ referencedNames.add(name);
170
+ }
171
+ for (const statement of parsed.program.body) {
172
+ if (isNullOrUndefined(statement.start) || isNullOrUndefined(statement.end)) {
173
+ continue;
174
+ }
175
+ let leadingComment = null;
176
+ leadingComment = getCommentText(statement.leadingComments);
177
+ const slicedContent = dtsContent.substring(statement.start, statement.end);
178
+ let statementText = `${leadingComment ? `${leadingComment}
179
+ ` : ""}${slicedContent}`;
180
+ const name = getName(statement, dtsContent);
181
+ if (name) {
182
+ referencedNames.add(name);
183
+ }
184
+ const isDefaultExport = hasDefaultExportModifier(statement, statementText);
185
+ const isExported = hasExportModifier(statement, statementText);
186
+ if (isDefaultExport) {
187
+ result.push(`export { ${name} as default };`);
188
+ if (isDefaultReExport(statement)) {
189
+ continue;
190
+ }
191
+ }
192
+ if (isImportDeclaration(statement) || isExportAllDeclaration(statement) || isReExportStatement(statement)) {
193
+ result.push(jsifyImportExport(statement, dtsContent));
194
+ continue;
195
+ }
196
+ if (isExported) {
197
+ statementText = statementText.replace(EXPORT_DEFAULT_RE, "").replace(EXPORT_RE, "");
198
+ }
199
+ const tokens = tokenizeText(statementText, referencedNames);
200
+ const varName = name || generateRandomString();
201
+ result.push(`var ${varName} = [${tokens.join(", ")}];`);
202
+ if (isExported && !isDefaultExport && !exportedNames.has(varName)) {
203
+ result.push(`export { ${varName} };`);
204
+ exportedNames.add(varName);
205
+ }
206
+ }
207
+ return result.join(`
208
+ `);
209
+ }
210
+ async function fakeJsToDts(fakeJsContent) {
211
+ const parseResult = parse(fakeJsContent, {
212
+ sourceType: "module"
213
+ });
214
+ const program = parseResult.program;
215
+ const resultParts = [];
216
+ for (const node of program.body) {
217
+ if (isNullOrUndefined(node.start) || isNullOrUndefined(node.end)) {
218
+ continue;
219
+ }
220
+ if (isImportDeclaration(node) || isExportAllDeclaration(node) || isReExportStatement(node)) {
221
+ resultParts.push(fakeJsContent.substring(node.start, node.end).trim().replace(".mjs", "").replace(".cjs", "").replace(".js", ""));
222
+ continue;
223
+ }
224
+ if (node.type === "ExpressionStatement") {
225
+ const namespaceDecl = handleNamespace(node);
226
+ if (namespaceDecl) {
227
+ resultParts.push(namespaceDecl);
228
+ continue;
229
+ }
230
+ }
231
+ if (node.type === "VariableDeclaration") {
232
+ for (const declaration of node.declarations) {
233
+ if (declaration.init?.type === "ArrayExpression") {
234
+ const dtsContent = processTokenArray(declaration.init);
235
+ if (dtsContent) {
236
+ resultParts.push(dtsContent);
237
+ }
238
+ }
239
+ }
240
+ }
241
+ }
242
+ return resultParts.join(`
243
+ `);
244
+ }
245
+ function jsifyImportExport(node, source) {
246
+ if (isNullOrUndefined(node.start) || isNullOrUndefined(node.end)) {
247
+ return "";
248
+ }
249
+ const text = source.substring(node.start, node.end);
250
+ let result = text.replace(IMPORT_TYPE_RE, "import ").replace(EXPORT_TYPE_RE, "export ").replace(IMPORT_EXPORT_NAMES_RE, (_, keyword, names) => `${keyword} {${names.replace(TYPE_WORD_RE, "")}}`);
251
+ result = result.replace(IMPORT_EXPORT_WITH_DEFAULT_RE, (_, keyword, defaultPart = "", names = "") => {
252
+ const cleanedNames = names.replace(TYPE_WORD_RE, "");
253
+ return `${keyword}${defaultPart}{${cleanedNames}}`;
254
+ });
255
+ return result;
256
+ }
257
+ function tokenizeText(text, referencedNames) {
258
+ const tokens = [];
259
+ let match;
260
+ while (true) {
261
+ match = TOKENIZE_RE.exec(text);
262
+ if (match === null)
263
+ break;
264
+ const token = match[0];
265
+ if (isLikelyVariableOrTypeName(token) || referencedNames.has(token)) {
266
+ tokens.push(token);
267
+ } else {
268
+ const processedToken = token.replace(/\n/g, "\\n").replace(/\t/g, "\\t");
269
+ tokens.push(JSON.stringify(processedToken));
270
+ }
271
+ }
272
+ return tokens;
273
+ }
274
+ function processTokenArray(arrayLiteral) {
275
+ if (arrayLiteral.type !== "ArrayExpression") {
276
+ return null;
277
+ }
278
+ const tokens = [];
279
+ for (const element of arrayLiteral.elements) {
280
+ if (element?.type === "StringLiteral" && typeof element.value === "string") {
281
+ const processedValue = element.value.replace(/\\n/g, `
282
+ `).replace(/\\t/g, "\t").replace(/\\r/g, "\r");
283
+ tokens.push(processedValue);
284
+ } else if (element?.type === "Identifier") {
285
+ tokens.push(element.name);
286
+ }
287
+ }
288
+ return tokens.join("");
289
+ }
290
+ function handleNamespace(stmt) {
291
+ const expr = stmt.expression;
292
+ if (!expr || expr.type !== "CallExpression" || expr.callee?.type !== "Identifier" || expr.arguments?.length !== 2 || expr.arguments[0].type !== "Identifier" || expr.arguments[1].type !== "ObjectExpression") {
293
+ return null;
294
+ }
295
+ const namespaceName = expr.arguments[0].name;
296
+ const properties = expr.arguments[1].properties.filter((prop) => prop.type === "ObjectProperty").map((prop) => {
297
+ if (prop.type === "ObjectProperty" && prop.key.type === "Identifier" && prop.value.type === "ArrowFunctionExpression" && prop.value.body.type === "Identifier") {
298
+ const keyName = prop.key.name;
299
+ const returnName = prop.value.body.name;
300
+ return keyName === returnName ? keyName : `${returnName} as ${keyName}`;
301
+ }
302
+ return null;
303
+ }).filter(Boolean);
304
+ if (properties.length === 0) {
305
+ return null;
306
+ }
307
+ return `declare namespace ${namespaceName} {
308
+ export { ${properties.join(", ")} };
309
+ }`;
310
+ }
311
+
312
+ // src/dts/logger.ts
313
+ import pc from "picocolors";
314
+
315
+ // src/constants/index.ts
316
+ var BUNUP_DOCS_URL = "https://bunup.dev/docs";
317
+ var UNDERSTANDING_ISOLATED_DECLARATIONS_URL = "https://github.com/arshad-yaseen/bunup/blob/main/docs/isolated-declarations.md";
318
+
319
+ // src/dts/logger.ts
320
+ function logIsolatedDeclarationErrors(errors) {
321
+ let hasSeverityError = false;
322
+ for (const error of errors) {
323
+ if (error.error.severity === "Error") {
324
+ hasSeverityError = true;
325
+ }
326
+ logSingle(error);
327
+ }
328
+ if (hasSeverityError) {
329
+ if (isDev()) {
330
+ console.log(`
331
+ ${pc.yellow("Please address the suggestions above before publishing your package.")}
332
+ `);
333
+ }
334
+ console.log(`${pc.cyan("Why?")} ${pc.underline(UNDERSTANDING_ISOLATED_DECLARATIONS_URL)}
335
+ `);
336
+ if (!isDev()) {
337
+ process.exit(1);
338
+ }
339
+ }
340
+ }
341
+ function logSingle(error) {
342
+ const label = error.error.labels[0];
343
+ const position = label ? calculateDtsErrorLineAndColumn(error.content, label.start) : "";
344
+ const shortPath = getShortFilePath(error.file);
345
+ const errorMessage = `${shortPath}${position}: ${formatDtsErrorMessage(error.error.message)}`;
346
+ const { color, prefix } = getSeverityFormatting(error.error.severity);
347
+ const formattedMessage = `${color(prefix)} ${errorMessage}`;
348
+ const codeFrame = label ? getCodeFrame(error.content, label.start, label.end) : error.error.codeframe ? error.error.codeframe : "";
349
+ const helpMessage = error.error.helpMessage ? `
350
+ ${pc.cyan("Help:")} ${error.error.helpMessage}` : "";
351
+ console.log(`
352
+ ${formattedMessage}${helpMessage}
353
+
354
+ ${pc.gray(codeFrame)}`);
355
+ }
356
+ function getSeverityFormatting(severity) {
357
+ if (isDev()) {
358
+ switch (severity) {
359
+ case "Error":
360
+ return {
361
+ color: pc.blue,
362
+ prefix: "Suggestion"
363
+ };
364
+ case "Warning":
365
+ return { color: pc.yellow, prefix: "Suggestion" };
366
+ case "Advice":
367
+ return { color: pc.blue, prefix: "Advice" };
368
+ default:
369
+ return {
370
+ color: pc.blue,
371
+ prefix: "Suggestion"
372
+ };
373
+ }
374
+ }
375
+ switch (severity) {
376
+ case "Error":
377
+ return {
378
+ color: pc.red,
379
+ prefix: "ERROR"
380
+ };
381
+ case "Warning":
382
+ return { color: pc.yellow, prefix: "WARNING" };
383
+ case "Advice":
384
+ return { color: pc.blue, prefix: "ADVICE" };
385
+ default:
386
+ return {
387
+ color: pc.red,
388
+ prefix: "ERROR"
389
+ };
390
+ }
391
+ }
392
+ function formatDtsErrorMessage(errorMessage) {
393
+ return errorMessage.replace(" with --isolatedDeclarations", "").replace(" with --isolatedDeclaration", "");
394
+ }
395
+ function calculateDtsErrorLineAndColumn(sourceText, labelStart) {
396
+ if (labelStart === undefined)
397
+ return "";
398
+ const lines = sourceText.slice(0, labelStart).split(`
399
+ `);
400
+ const lineNumber = lines.length;
401
+ const columnStart = lines[lines.length - 1].length + 1;
402
+ return ` (${lineNumber}:${columnStart})`;
403
+ }
404
+ function getCodeFrame(sourceText, start, end) {
405
+ const lines = sourceText.split(`
406
+ `);
407
+ const errorLine = sourceText.slice(0, start).split(`
408
+ `).length;
409
+ const lineContent = lines[errorLine - 1];
410
+ const startCol = start - sourceText.slice(0, start).lastIndexOf(`
411
+ `) - 1;
412
+ const endCol = end ? Math.min(end - sourceText.slice(0, start).lastIndexOf(`
413
+ `) - 1, lineContent.length) : startCol + 1;
414
+ const arrowLine = " ".repeat(startCol) + pc[isDev() ? "blue" : "red"](pc.dim("\u23AF".repeat(Math.max(1, endCol - startCol))));
415
+ return `${lineContent}
416
+ ${arrowLine}`;
417
+ }
418
+ function handleBunBuildLogs(logs) {
419
+ for (const log of logs) {
420
+ if (log.level === "error") {
421
+ logger.error(`${log.message} in ${log.position?.file}`);
422
+ throw new Error("Failed to generate declaration file");
423
+ }
424
+ if (log.level === "warning") {
425
+ logger.warn(log.message);
426
+ }
427
+ if (log.level === "info") {
428
+ logger.info(log.message);
429
+ }
430
+ }
431
+ }
432
+
433
+ // src/dts/resolver.ts
434
+ import { dirname } from "path";
435
+ import process2 from "process";
436
+ import { ResolverFactory } from "oxc-resolver";
437
+ function createResolver({
438
+ tsconfig,
439
+ cwd = process2.cwd(),
440
+ resolveOption
441
+ }) {
442
+ const resolver = new ResolverFactory({
443
+ mainFields: ["types", "typings", "module", "main"],
444
+ conditionNames: ["types", "typings", "import", "require"],
445
+ extensions: [".d.ts", ".d.mts", ".d.cts", ".ts", ".mts", ".cts"],
446
+ tsconfig: tsconfig ? { configFile: tsconfig, references: "auto" } : undefined
447
+ });
448
+ const resolutionCache = new Map;
449
+ return (importSource, importer) => {
450
+ if (importSource === "bun")
451
+ return null;
452
+ const cacheKey = `${importSource}:${importer || ""}`;
453
+ if (resolutionCache.has(cacheKey)) {
454
+ return resolutionCache.get(cacheKey) || null;
455
+ }
456
+ let shouldResolve = false;
457
+ if (resolveOption !== undefined) {
458
+ if (typeof resolveOption === "boolean") {
459
+ shouldResolve = resolveOption;
460
+ } else if (Array.isArray(resolveOption)) {
461
+ shouldResolve = resolveOption.some((resolver2) => {
462
+ if (typeof resolver2 === "string") {
463
+ return resolver2 === importSource;
464
+ }
465
+ return resolver2.test(importSource);
466
+ });
467
+ }
468
+ }
469
+ if (!shouldResolve) {
470
+ resolutionCache.set(cacheKey, null);
471
+ return null;
472
+ }
473
+ const directory = importer ? dirname(importer) : cwd;
474
+ const resolution = resolver.sync(directory, importSource);
475
+ if (!resolution.path) {
476
+ resolutionCache.set(cacheKey, null);
477
+ return null;
478
+ }
479
+ const resolved = resolution.path;
480
+ if (JS_RE.test(resolved)) {
481
+ const dts = returnPathIfExists(resolved.replace(JS_RE, ".d.ts")) || returnPathIfExists(resolved.replace(JS_RE, ".d.mts")) || returnPathIfExists(resolved.replace(JS_RE, ".d.cts"));
482
+ const result2 = isTypeScriptFile(dts) ? dts : null;
483
+ resolutionCache.set(cacheKey, result2);
484
+ return result2;
485
+ }
486
+ const result = isTypeScriptFile(resolved) ? resolved : null;
487
+ resolutionCache.set(cacheKey, result);
488
+ return result;
489
+ };
490
+ }
491
+
492
+ // src/dts/generate.ts
493
+ async function generateDts(entrypoints, options) {
494
+ const { resolve, preferredTsConfigPath } = options;
495
+ const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd();
496
+ const tsconfig = await loadTsConfig(cwd, preferredTsConfigPath);
497
+ const tempOutDir = path.resolve(path.join(cwd, `.bunup-dts-${generateRandomString()}`));
498
+ const nonAbsoluteEntrypoints = entrypoints.filter((entrypoint) => !path.isAbsolute(entrypoint));
499
+ const resolvedEntrypoints = await getFilesFromGlobs(nonAbsoluteEntrypoints, cwd);
500
+ const absoluteEntrypoints = entrypoints.filter((entrypoint) => path.isAbsolute(entrypoint));
501
+ if (![...resolvedEntrypoints, ...absoluteEntrypoints].length) {
502
+ throw new Error("The dts entrypoints you provided do not exist. Please make sure the entrypoints point to valid files.");
503
+ }
504
+ const collectedErrors = [];
505
+ const resolver = createResolver({
506
+ cwd,
507
+ resolveOption: resolve,
508
+ tsconfig: tsconfig.filepath
509
+ });
510
+ const fakeJsPlugin = {
511
+ name: "fake-js",
512
+ setup(build) {
513
+ build.onResolve({ filter: /.*/ }, (args) => {
514
+ if (!NODE_MODULES_RE.test(args.importer)) {
515
+ const resolved = resolveTsImportPath({
516
+ importer: args.importer,
517
+ path: args.path,
518
+ cwd,
519
+ tsconfig: tsconfig.config
520
+ });
521
+ if (resolved && isTypeScriptFile(resolved)) {
522
+ return { path: resolved };
523
+ }
524
+ }
525
+ const resolvedFromNodeModules = resolver(args.path, args.importer);
526
+ if (resolvedFromNodeModules) {
527
+ return { path: resolvedFromNodeModules };
528
+ }
529
+ return {
530
+ path: args.path,
531
+ external: true
532
+ };
533
+ });
534
+ build.onLoad({ filter: /\.(ts|tsx|d\.ts|d\.mts|d\.cts)$/ }, async (args) => {
535
+ const sourceText = await Bun.file(args.path).text();
536
+ const declarationResult = isolatedDeclaration(args.path, sourceText);
537
+ if (!collectedErrors.some((e) => e.file === args.path)) {
538
+ for (const error of declarationResult.errors) {
539
+ collectedErrors.push({
540
+ error,
541
+ file: args.path,
542
+ content: sourceText
543
+ });
544
+ }
545
+ }
546
+ const fakeJsContent = await dtsToFakeJs(declarationResult.code);
547
+ return {
548
+ loader: "js",
549
+ contents: fakeJsContent
550
+ };
551
+ });
552
+ }
553
+ };
554
+ const result = await Bun.build({
555
+ entrypoints: [
556
+ ...resolvedEntrypoints.map((entry) => path.resolve(path.join(cwd, entry))),
557
+ ...absoluteEntrypoints
558
+ ],
559
+ outdir: tempOutDir,
560
+ format: "esm",
561
+ target: "node",
562
+ splitting: options.splitting,
563
+ plugins: [fakeJsPlugin],
564
+ throw: false,
565
+ packages: "external",
566
+ minify: options.minify
567
+ });
568
+ handleBunBuildLogs(result.logs);
569
+ try {
570
+ const outputs = result.outputs.filter((output) => output.kind === "chunk" || output.kind === "entry-point");
571
+ const bundledFiles = [];
572
+ for (const output of outputs) {
573
+ const bundledFakeJsPath = output.path;
574
+ const bundledFakeJsContent = await Bun.file(bundledFakeJsPath).text();
575
+ const dtsContent = isolatedDeclaration("treeshake.d.ts", await fakeJsToDts(bundledFakeJsContent));
576
+ const entrypoint = output.kind === "entry-point" ? entrypoints[bundledFiles.length] : undefined;
577
+ const chunkFileName = output.kind === "chunk" ? replaceExtension(path.basename(output.path), getDeclarationExtensionFromJsExtension(getExtension(output.path))) : undefined;
578
+ const outputPath = cleanPath(replaceExtension(cleanPath(output.path).replace(`${cleanPath(tempOutDir)}/`, ""), getDeclarationExtensionFromJsExtension(getExtension(output.path))));
579
+ bundledFiles.push({
580
+ kind: output.kind === "entry-point" ? "entry-point" : "chunk",
581
+ entrypoint,
582
+ chunkFileName,
583
+ outputPath,
584
+ dts: dtsContent.code,
585
+ pathInfo: {
586
+ outputPathWithoutExtension: deleteExtension(outputPath),
587
+ ext: getExtension(outputPath)
588
+ }
589
+ });
590
+ }
591
+ return {
592
+ files: bundledFiles,
593
+ errors: collectedErrors
594
+ };
595
+ } catch (error) {
596
+ console.error(error);
597
+ return {
598
+ files: [],
599
+ errors: collectedErrors
600
+ };
601
+ } finally {
602
+ await fs.rm(tempOutDir, { recursive: true, force: true });
603
+ }
604
+ }
605
+ // src/plugins/internal/linter.ts
606
+ var rules = [
607
+ {
608
+ check: (ctx) => {
609
+ const hasMinification = !!(ctx.options.minify || ctx.options.minifyWhitespace || ctx.options.minifyIdentifiers || ctx.options.minifySyntax);
610
+ return hasMinification && !ctx.options.sourcemap;
611
+ },
612
+ message: `You are using minification without source maps. Consider enabling source maps to help with debugging minified code. Learn more: ${link("https://bunup.dev/docs/guide/options#source-maps")}`,
613
+ logLevel: "recommended"
614
+ }
615
+ ];
616
+ function linter() {
617
+ return {
618
+ type: "bunup",
619
+ name: "linter",
620
+ hooks: {
621
+ onBuildDone: (ctx) => {
622
+ let hasWarnings = false;
623
+ for (const rule of rules) {
624
+ if (rule.check(ctx)) {
625
+ if (!hasWarnings) {
626
+ logger.space();
627
+ }
628
+ logger[rule.logLevel ?? "warn"](rule.message);
629
+ hasWarnings = true;
630
+ }
631
+ }
632
+ }
633
+ }
634
+ };
635
+ }
636
+
637
+ // src/plugins/internal/report.ts
638
+ import pc2 from "picocolors";
639
+ function report() {
640
+ return {
641
+ type: "bunup",
642
+ name: "report",
643
+ hooks: {
644
+ onBuildDone: async ({ options, output }) => {
645
+ if (options.watch)
646
+ return;
647
+ const files = await Promise.all(output.files.map(async (file) => {
648
+ const name = file.relativePathToRootDir;
649
+ const size = Bun.file(file.fullPath).size;
650
+ const gzipSize = Bun.gzipSync(new Uint8Array(await Bun.file(file.fullPath).arrayBuffer())).length;
651
+ const formattedGzipSize = formatFileSize(gzipSize);
652
+ return {
653
+ name,
654
+ size,
655
+ formattedSize: formatFileSize(size),
656
+ gzipSize,
657
+ formattedGzipSize
658
+ };
659
+ }));
660
+ const totalSize = files.reduce((sum, file) => sum + file.size, 0);
661
+ const formattedTotalSize = formatFileSize(totalSize);
662
+ const totalGzipSize = files.reduce((sum, file) => sum + (file.gzipSize || 0), 0);
663
+ const formattedTotalGzipSize = formatFileSize(totalGzipSize);
664
+ const columns = [
665
+ { header: "File", align: "left", color: pc2.blue },
666
+ { header: "Size", align: "right", color: pc2.green },
667
+ {
668
+ header: "Gzip",
669
+ align: "right",
670
+ color: pc2.magenta
671
+ }
672
+ ];
673
+ const data = files.map((file) => {
674
+ return {
675
+ File: file.name,
676
+ Size: file.formattedSize,
677
+ Gzip: file.formattedGzipSize
678
+ };
679
+ });
680
+ const footer = {
681
+ File: "Total",
682
+ Size: formattedTotalSize,
683
+ Gzip: formattedTotalGzipSize
684
+ };
685
+ logger.space();
686
+ logTable(columns, data, footer);
687
+ logger.space();
688
+ }
689
+ }
690
+ };
691
+ }
692
+
693
+ // src/plugins/internal/use-client.ts
694
+ function useClient() {
695
+ return {
696
+ type: "bunup",
697
+ name: "use-client",
698
+ hooks: {
699
+ onBuildDone: async ({ output }) => {
700
+ for (const file of output.files) {
701
+ let text = await Bun.file(file.fullPath).text();
702
+ const hasUseClient = text.split(`
703
+ `).some((line) => line.trim().startsWith(`"use client";`));
704
+ if (hasUseClient) {
705
+ text = text.replaceAll(`"use client";`, "");
706
+ text = `"use client";
707
+ ${text}`;
708
+ }
709
+ await Bun.write(file.fullPath, text);
710
+ }
711
+ }
712
+ }
713
+ };
714
+ }
715
+
716
+ // src/options.ts
717
+ var DEFAULT_OPTIONS = {
718
+ entry: ["src/index.ts"],
719
+ format: ["cjs"],
720
+ outDir: "dist",
721
+ target: "node",
722
+ clean: true
723
+ };
724
+ function createBuildOptions(partialOptions) {
725
+ const options = {
726
+ ...DEFAULT_OPTIONS,
727
+ ...partialOptions
728
+ };
729
+ return {
730
+ ...options,
731
+ plugins: [...options.plugins ?? [], useClient(), linter(), report()]
732
+ };
733
+ }
734
+ function getResolvedMinify(options) {
735
+ const { minify, minifyWhitespace, minifyIdentifiers, minifySyntax } = options;
736
+ const defaultValue = minify === true;
737
+ return {
738
+ whitespace: minifyWhitespace ?? defaultValue,
739
+ identifiers: minifyIdentifiers ?? defaultValue,
740
+ syntax: minifySyntax ?? defaultValue
741
+ };
742
+ }
743
+ function getResolvedBytecode(bytecode, format) {
744
+ return format === "cjs" ? bytecode : undefined;
745
+ }
746
+ function getResolvedSourcemap(sourcemap) {
747
+ if (sourcemap === true) {
748
+ return "inline";
749
+ }
750
+ return typeof sourcemap === "string" ? sourcemap : undefined;
751
+ }
752
+ function getResolvedDefine(define, env) {
753
+ return {
754
+ ...typeof env === "object" && Object.keys(env).reduce((acc, key) => {
755
+ const value = JSON.stringify(env[key]);
756
+ acc[`process.env.${key}`] = value;
757
+ acc[`import.meta.env.${key}`] = value;
758
+ return acc;
759
+ }, {}),
760
+ ...define
761
+ };
762
+ }
763
+ function getResolvedSplitting(splitting, format) {
764
+ return splitting === undefined ? format === "esm" : splitting;
765
+ }
766
+ function getResolvedDtsSplitting(splitting) {
767
+ return splitting ?? true;
768
+ }
769
+ var DEFAULT_ENTRY_NAMING = "[dir]/[name].[ext]";
770
+ function getResolvedNaming(fmt, packageType) {
771
+ const replaceExt = (pattern) => pattern.replace(".[ext]", getDefaultOutputExtension(fmt, packageType));
772
+ return replaceExt(DEFAULT_ENTRY_NAMING);
773
+ }
774
+ function getResolvedEnv(env) {
775
+ return typeof env === "string" ? env : undefined;
776
+ }
777
+
778
+ // src/helpers/external.ts
779
+ function getPackageDepsPatterns(packageJson) {
780
+ return getPackageDeps(packageJson).map((dep) => new RegExp(`^${dep}($|\\/|\\\\)`));
781
+ }
782
+ function matchesPattern(path2, pattern) {
783
+ return typeof pattern === "string" ? pattern === path2 : pattern.test(path2);
784
+ }
785
+ function isExternal(path2, options, packageJson) {
786
+ const packageDepsPatterns = getPackageDepsPatterns(packageJson);
787
+ const matchesExternalPattern = packageDepsPatterns.some((pattern) => pattern.test(path2)) || options.external?.some((pattern) => matchesPattern(path2, pattern));
788
+ const isExcludedFromExternal = options.noExternal?.some((pattern) => matchesPattern(path2, pattern));
789
+ return matchesExternalPattern && !isExcludedFromExternal;
790
+ }
791
+
792
+ // src/plugins/internal/external-option.ts
793
+ function externalOptionPlugin(options, packageJson) {
794
+ return {
795
+ name: "bunup:external-option-plugin",
796
+ setup(build) {
797
+ build.onResolve({ filter: /.*/ }, (args) => {
798
+ const importPath = args.path;
799
+ if (isExternal(importPath, options, packageJson)) {
800
+ return {
801
+ path: importPath,
802
+ external: true
803
+ };
804
+ }
805
+ return null;
806
+ });
807
+ }
808
+ };
809
+ }
810
+
811
+ // src/build.ts
812
+ async function build(partialOptions, rootDir = process.cwd()) {
813
+ const buildOutput = {
814
+ files: []
815
+ };
816
+ const options = createBuildOptions(partialOptions);
817
+ if (!options.entry || options.entry.length === 0 || !options.outDir) {
818
+ throw new BunupBuildError("Nothing to build. Please make sure you have provided a proper bunup configuration or cli arguments.");
819
+ }
820
+ if (options.clean) {
821
+ cleanOutDir(rootDir, options.outDir);
822
+ }
823
+ setSilent(options.silent);
824
+ const packageJson = await loadPackageJson(rootDir);
825
+ if (packageJson.data && packageJson.path) {
826
+ logger.info(`Using ${getShortFilePath(packageJson.path, 2)}`, {
827
+ muted: true,
828
+ identifier: options.name,
829
+ once: `${packageJson.path}:${options.name}`
830
+ });
831
+ }
832
+ const bunupPlugins = filterBunupPlugins(options.plugins);
833
+ await runPluginBuildStartHooks(bunupPlugins, options);
834
+ const packageType = packageJson.data?.type;
835
+ const plugins = [
836
+ externalOptionPlugin(options, packageJson.data),
837
+ ...filterBunupBunPlugins(options.plugins).map((p) => p.plugin)
838
+ ];
839
+ const entrypoints = await getFilesFromGlobs(ensureArray(options.entry), rootDir);
840
+ if (!entrypoints.length) {
841
+ throw new BunupBuildError("The entrypoints you provided do not exist. Please make sure the entrypoints point to valid files.");
842
+ }
843
+ const buildPromises = options.format.flatMap(async (fmt) => {
844
+ const result = await Bun.build({
845
+ entrypoints: entrypoints.map((file) => `${rootDir}/${file}`),
846
+ format: fmt,
847
+ naming: getResolvedNaming(fmt, packageType),
848
+ splitting: getResolvedSplitting(options.splitting, fmt),
849
+ bytecode: getResolvedBytecode(options.bytecode, fmt),
850
+ define: getResolvedDefine(options.define, options.env),
851
+ minify: getResolvedMinify(options),
852
+ outdir: `${rootDir}/${options.outDir}`,
853
+ target: options.target,
854
+ sourcemap: getResolvedSourcemap(options.sourcemap),
855
+ loader: options.loader,
856
+ drop: options.drop,
857
+ banner: options.banner,
858
+ footer: options.footer,
859
+ publicPath: options.publicPath,
860
+ env: getResolvedEnv(options.env),
861
+ ignoreDCEAnnotations: options.ignoreDCEAnnotations,
862
+ emitDCEAnnotations: options.emitDCEAnnotations,
863
+ throw: false,
864
+ plugins
865
+ });
866
+ for (const log of result.logs) {
867
+ if (log.level === "error") {
868
+ throw new BunupBuildError(log.message);
869
+ }
870
+ if (log.level === "warning")
871
+ logger.warn(log.message);
872
+ else if (log.level === "info")
873
+ logger.info(log.message);
874
+ }
875
+ let entrypointIndex = 0;
876
+ for (const file of result.outputs) {
877
+ const relativePathToRootDir = getRelativePathToRootDir(file.path, rootDir);
878
+ const relativePathToOutputDir = getRelativePathToOutputDir(relativePathToRootDir, options.outDir);
879
+ if (file.kind === "entry-point") {
880
+ logger.success(`${pc3.dim(`${options.outDir}/`)}${relativePathToOutputDir}`, {
881
+ identifier: options.name
882
+ });
883
+ }
884
+ buildOutput.files.push({
885
+ fullPath: file.path,
886
+ relativePathToRootDir,
887
+ relativePathToOutputDir,
888
+ dts: false,
889
+ format: fmt,
890
+ kind: file.kind,
891
+ entrypoint: file.kind === "entry-point" ? cleanPath(entrypoints[entrypointIndex]) : undefined
892
+ });
893
+ if (file.kind === "entry-point") {
894
+ entrypointIndex++;
895
+ }
896
+ }
897
+ });
898
+ await Promise.all(buildPromises);
899
+ if (options.dts) {
900
+ const { entry, splitting, ...dtsOptions } = typeof options.dts === "object" ? options.dts : {};
901
+ const dtsResult = await generateDts(ensureArray(entry ?? entrypoints), {
902
+ cwd: rootDir,
903
+ preferredTsConfigPath: options.preferredTsconfigPath,
904
+ splitting: getResolvedDtsSplitting(splitting),
905
+ ...dtsOptions
906
+ });
907
+ if (dtsResult.errors.length) {
908
+ logIsolatedDeclarationErrors(dtsResult.errors);
909
+ }
910
+ for (const fmt of options.format) {
911
+ for (const file of dtsResult.files) {
912
+ const dtsExtension = getDefaultDtsExtention(fmt, packageType);
913
+ const relativePathToOutputDir = cleanPath(`${file.pathInfo.outputPathWithoutExtension}${dtsExtension}`);
914
+ const relativePathToRootDir = cleanPath(`${options.outDir}/${relativePathToOutputDir}`);
915
+ if (file.kind === "entry-point") {
916
+ logger.success(`${pc3.dim(`${options.outDir}/`)}${relativePathToOutputDir}`, {
917
+ identifier: options.name
918
+ });
919
+ }
920
+ const fullPath = path2.join(rootDir, relativePathToRootDir);
921
+ await Bun.write(fullPath, file.dts);
922
+ buildOutput.files.push({
923
+ fullPath,
924
+ relativePathToRootDir,
925
+ relativePathToOutputDir,
926
+ dts: true,
927
+ format: fmt,
928
+ kind: file.kind,
929
+ entrypoint: file.entrypoint ? cleanPath(file.entrypoint) : undefined
930
+ });
931
+ }
932
+ }
933
+ }
934
+ await runPluginBuildDoneHooks(bunupPlugins, options, buildOutput, {
935
+ packageJson,
936
+ rootDir
937
+ });
938
+ if (options.onSuccess) {
939
+ await options.onSuccess(options);
940
+ }
941
+ }
942
+ function getRelativePathToRootDir(filePath, rootDir) {
943
+ return cleanPath(filePath).replace(`${cleanPath(rootDir)}/`, "");
944
+ }
945
+ function getRelativePathToOutputDir(relativePathToRootDir, outDir) {
946
+ return cleanPath(relativePathToRootDir).replace(`${cleanPath(outDir)}/`, "");
947
+ }
948
+
949
+ export { BUNUP_DOCS_URL, createBuildOptions, build };