bunup 0.8.29 → 0.8.30
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/bin/bunup.mjs +1 -1
- package/dist/cli/index.cjs +2030 -0
- package/dist/cli/index.d.cts +360 -0
- package/dist/cli/index.d.ts +360 -0
- package/dist/cli/index.js +2027 -0
- package/dist/index.cjs +1168 -0
- package/dist/index.d.cts +362 -0
- package/dist/index.d.ts +24 -126
- package/dist/index.js +552 -199
- package/dist/plugins.cjs +866 -0
- package/dist/plugins.d.cts +385 -0
- package/dist/plugins.d.ts +385 -0
- package/dist/plugins.js +846 -0
- package/package.json +11 -6
|
@@ -0,0 +1,2030 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// @bun @bun-cjs
|
|
3
|
+
(function(exports, require, module, __filename, __dirname) {var __create = Object.create;
|
|
4
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
10
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
11
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
12
|
+
for (let key of __getOwnPropNames(mod))
|
|
13
|
+
if (!__hasOwnProp.call(to, key))
|
|
14
|
+
__defProp(to, key, {
|
|
15
|
+
get: () => mod[key],
|
|
16
|
+
enumerable: true
|
|
17
|
+
});
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
21
|
+
var __toCommonJS = (from) => {
|
|
22
|
+
var entry = __moduleCache.get(from), desc;
|
|
23
|
+
if (entry)
|
|
24
|
+
return entry;
|
|
25
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
26
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
27
|
+
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
28
|
+
get: () => from[key],
|
|
29
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
30
|
+
}));
|
|
31
|
+
__moduleCache.set(from, entry);
|
|
32
|
+
return entry;
|
|
33
|
+
};
|
|
34
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
35
|
+
var __export = (target, all) => {
|
|
36
|
+
for (var name in all)
|
|
37
|
+
__defProp(target, name, {
|
|
38
|
+
get: all[name],
|
|
39
|
+
enumerable: true,
|
|
40
|
+
configurable: true,
|
|
41
|
+
set: (newValue) => all[name] = () => newValue
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
45
|
+
|
|
46
|
+
// node_modules/picocolors/picocolors.js
|
|
47
|
+
var require_picocolors = __commonJS((exports2, module2) => {
|
|
48
|
+
var p = process || {};
|
|
49
|
+
var argv = p.argv || [];
|
|
50
|
+
var env = p.env || {};
|
|
51
|
+
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
52
|
+
var formatter = (open, close, replace = open) => (input) => {
|
|
53
|
+
let string = "" + input, index = string.indexOf(close, open.length);
|
|
54
|
+
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
55
|
+
};
|
|
56
|
+
var replaceClose = (string, close, replace, index) => {
|
|
57
|
+
let result = "", cursor = 0;
|
|
58
|
+
do {
|
|
59
|
+
result += string.substring(cursor, index) + replace;
|
|
60
|
+
cursor = index + close.length;
|
|
61
|
+
index = string.indexOf(close, cursor);
|
|
62
|
+
} while (~index);
|
|
63
|
+
return result + string.substring(cursor);
|
|
64
|
+
};
|
|
65
|
+
var createColors = (enabled = isColorSupported) => {
|
|
66
|
+
let f = enabled ? formatter : () => String;
|
|
67
|
+
return {
|
|
68
|
+
isColorSupported: enabled,
|
|
69
|
+
reset: f("\x1B[0m", "\x1B[0m"),
|
|
70
|
+
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
71
|
+
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
72
|
+
italic: f("\x1B[3m", "\x1B[23m"),
|
|
73
|
+
underline: f("\x1B[4m", "\x1B[24m"),
|
|
74
|
+
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
75
|
+
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
76
|
+
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
77
|
+
black: f("\x1B[30m", "\x1B[39m"),
|
|
78
|
+
red: f("\x1B[31m", "\x1B[39m"),
|
|
79
|
+
green: f("\x1B[32m", "\x1B[39m"),
|
|
80
|
+
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
81
|
+
blue: f("\x1B[34m", "\x1B[39m"),
|
|
82
|
+
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
83
|
+
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
84
|
+
white: f("\x1B[37m", "\x1B[39m"),
|
|
85
|
+
gray: f("\x1B[90m", "\x1B[39m"),
|
|
86
|
+
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
87
|
+
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
88
|
+
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
89
|
+
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
90
|
+
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
91
|
+
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
92
|
+
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
93
|
+
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
94
|
+
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
95
|
+
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
96
|
+
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
97
|
+
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
98
|
+
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
99
|
+
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
100
|
+
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
101
|
+
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
102
|
+
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
103
|
+
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
104
|
+
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
105
|
+
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
106
|
+
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
107
|
+
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
108
|
+
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
109
|
+
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
module2.exports = createColors();
|
|
113
|
+
module2.exports.createColors = createColors;
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// src/logger.ts
|
|
117
|
+
function setSilent(value) {
|
|
118
|
+
silent = value ?? false;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
class Logger {
|
|
122
|
+
static instance;
|
|
123
|
+
loggedOnceMessages = new Set;
|
|
124
|
+
MAX_LABEL_LENGTH = 3;
|
|
125
|
+
cliColor = import_picocolors.default.blue;
|
|
126
|
+
mutedColor = import_picocolors.default.dim;
|
|
127
|
+
infoColor = import_picocolors.default.cyan;
|
|
128
|
+
warnColor = import_picocolors.default.yellow;
|
|
129
|
+
errorColor = import_picocolors.default.red;
|
|
130
|
+
defaultColor = import_picocolors.default.white;
|
|
131
|
+
progressFgColorMap = {
|
|
132
|
+
ESM: import_picocolors.default.yellow,
|
|
133
|
+
CJS: import_picocolors.default.green,
|
|
134
|
+
IIFE: import_picocolors.default.magenta,
|
|
135
|
+
DTS: import_picocolors.default.blue
|
|
136
|
+
};
|
|
137
|
+
progressIdentifierBgColorMap = {
|
|
138
|
+
ESM: import_picocolors.default.bgYellow,
|
|
139
|
+
CJS: import_picocolors.default.bgGreen,
|
|
140
|
+
IIFE: import_picocolors.default.bgMagenta,
|
|
141
|
+
DTS: import_picocolors.default.bgBlue
|
|
142
|
+
};
|
|
143
|
+
labels = {
|
|
144
|
+
cli: "CLI",
|
|
145
|
+
info: "INFO",
|
|
146
|
+
warn: "WARN",
|
|
147
|
+
error: "ERROR"
|
|
148
|
+
};
|
|
149
|
+
constructor() {}
|
|
150
|
+
static getInstance() {
|
|
151
|
+
if (!Logger.instance) {
|
|
152
|
+
Logger.instance = new Logger;
|
|
153
|
+
}
|
|
154
|
+
return Logger.instance;
|
|
155
|
+
}
|
|
156
|
+
dispose() {
|
|
157
|
+
this.loggedOnceMessages.clear();
|
|
158
|
+
}
|
|
159
|
+
shouldLog(options) {
|
|
160
|
+
if (!options?.once)
|
|
161
|
+
return true;
|
|
162
|
+
if (this.loggedOnceMessages.has(options.once))
|
|
163
|
+
return false;
|
|
164
|
+
this.loggedOnceMessages.add(options.once);
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
formatMessage({
|
|
168
|
+
fgColor,
|
|
169
|
+
bgColor,
|
|
170
|
+
label,
|
|
171
|
+
message,
|
|
172
|
+
identifier,
|
|
173
|
+
muted
|
|
174
|
+
}) {
|
|
175
|
+
const padding = " ".repeat(Math.max(0, this.MAX_LABEL_LENGTH - label.length));
|
|
176
|
+
const formattedMessage = muted ? this.mutedColor(message) : message;
|
|
177
|
+
const identifierPart = identifier ? ` ${bgColor(import_picocolors.default.black(` ${identifier} `))}` : "";
|
|
178
|
+
return `${fgColor(label)} ${padding}${formattedMessage}${identifierPart}`;
|
|
179
|
+
}
|
|
180
|
+
output(message, options = {}, logFn = console.log) {
|
|
181
|
+
if (silent || !this.shouldLog(options))
|
|
182
|
+
return;
|
|
183
|
+
if (options.verticalSpace)
|
|
184
|
+
logFn("");
|
|
185
|
+
logFn(message);
|
|
186
|
+
if (options.verticalSpace)
|
|
187
|
+
logFn("");
|
|
188
|
+
}
|
|
189
|
+
cli(message, options = {}) {
|
|
190
|
+
const formattedMessage = this.formatMessage({
|
|
191
|
+
fgColor: this.cliColor,
|
|
192
|
+
bgColor: import_picocolors.default.bgBlue,
|
|
193
|
+
label: this.labels.cli,
|
|
194
|
+
message,
|
|
195
|
+
identifier: options.identifier,
|
|
196
|
+
muted: options.muted
|
|
197
|
+
});
|
|
198
|
+
this.output(formattedMessage, options);
|
|
199
|
+
}
|
|
200
|
+
info(message, options = {}) {
|
|
201
|
+
const formattedMessage = this.formatMessage({
|
|
202
|
+
fgColor: this.infoColor,
|
|
203
|
+
bgColor: import_picocolors.default.bgCyan,
|
|
204
|
+
label: this.labels.info,
|
|
205
|
+
message,
|
|
206
|
+
identifier: options.identifier,
|
|
207
|
+
muted: options.muted
|
|
208
|
+
});
|
|
209
|
+
this.output(formattedMessage, options);
|
|
210
|
+
}
|
|
211
|
+
warn(message, options = {}) {
|
|
212
|
+
const formattedMessage = this.formatMessage({
|
|
213
|
+
fgColor: this.warnColor,
|
|
214
|
+
bgColor: import_picocolors.default.bgYellow,
|
|
215
|
+
label: this.labels.warn,
|
|
216
|
+
message,
|
|
217
|
+
identifier: options.identifier,
|
|
218
|
+
muted: options.muted
|
|
219
|
+
});
|
|
220
|
+
this.output(formattedMessage, options, console.warn);
|
|
221
|
+
}
|
|
222
|
+
error(message, options = {}) {
|
|
223
|
+
const formattedMessage = this.formatMessage({
|
|
224
|
+
fgColor: this.errorColor,
|
|
225
|
+
bgColor: import_picocolors.default.bgRed,
|
|
226
|
+
label: this.labels.error,
|
|
227
|
+
message,
|
|
228
|
+
identifier: options.identifier,
|
|
229
|
+
muted: options.muted
|
|
230
|
+
});
|
|
231
|
+
this.output(formattedMessage, options, console.error);
|
|
232
|
+
}
|
|
233
|
+
space() {
|
|
234
|
+
if (silent)
|
|
235
|
+
return;
|
|
236
|
+
console.log("");
|
|
237
|
+
}
|
|
238
|
+
getProgressFgColor(label) {
|
|
239
|
+
for (const [key, colorFn] of Object.entries(this.progressFgColorMap)) {
|
|
240
|
+
if (label.includes(key))
|
|
241
|
+
return colorFn;
|
|
242
|
+
}
|
|
243
|
+
return this.defaultColor;
|
|
244
|
+
}
|
|
245
|
+
getProgressBgColor(label) {
|
|
246
|
+
for (const [key, colorFn] of Object.entries(this.progressIdentifierBgColorMap)) {
|
|
247
|
+
if (label.includes(key))
|
|
248
|
+
return colorFn;
|
|
249
|
+
}
|
|
250
|
+
return import_picocolors.default.bgWhite;
|
|
251
|
+
}
|
|
252
|
+
progress(label, message, options = {}) {
|
|
253
|
+
const fgColor = this.getProgressFgColor(label);
|
|
254
|
+
const bgColor = this.getProgressBgColor(label);
|
|
255
|
+
const formattedMessage = this.formatMessage({
|
|
256
|
+
fgColor,
|
|
257
|
+
bgColor,
|
|
258
|
+
label,
|
|
259
|
+
message,
|
|
260
|
+
identifier: options.identifier,
|
|
261
|
+
muted: options.muted
|
|
262
|
+
});
|
|
263
|
+
this.output(formattedMessage, options);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
function logTable(columns, data, footer) {
|
|
267
|
+
if (silent)
|
|
268
|
+
return;
|
|
269
|
+
const widths = {};
|
|
270
|
+
for (const col of columns) {
|
|
271
|
+
const headerLength = col.header.length;
|
|
272
|
+
const dataLengths = data.map((row) => row[col.header]?.length || 0);
|
|
273
|
+
const footerLength = footer ? footer[col.header]?.length || 0 : 0;
|
|
274
|
+
widths[col.header] = Math.max(headerLength, ...dataLengths, footerLength);
|
|
275
|
+
}
|
|
276
|
+
const pad = (str, width, align) => {
|
|
277
|
+
return align === "left" ? str.padEnd(width) : str.padStart(width);
|
|
278
|
+
};
|
|
279
|
+
const headerRow = columns.map((col) => pad(col.header, widths[col.header], col.align)).join(import_picocolors.default.gray(" | "));
|
|
280
|
+
console.log(import_picocolors.default.gray(headerRow));
|
|
281
|
+
const separator = columns.map((col) => "-".repeat(widths[col.header])).join(" | ");
|
|
282
|
+
console.log(import_picocolors.default.gray(separator));
|
|
283
|
+
for (const row of data) {
|
|
284
|
+
const rowStr = columns.map((col) => {
|
|
285
|
+
const value = row[col.header] || "";
|
|
286
|
+
const padded = pad(value, widths[col.header], col.align);
|
|
287
|
+
return col.color ? col.color(padded) : padded;
|
|
288
|
+
}).join(import_picocolors.default.gray(" | "));
|
|
289
|
+
console.log(rowStr);
|
|
290
|
+
}
|
|
291
|
+
console.log(import_picocolors.default.gray(separator));
|
|
292
|
+
if (footer) {
|
|
293
|
+
const footerRow = columns.map((col) => {
|
|
294
|
+
const value = footer[col.header] || "";
|
|
295
|
+
const padded = pad(value, widths[col.header], col.align);
|
|
296
|
+
return padded;
|
|
297
|
+
}).join(import_picocolors.default.gray(" | "));
|
|
298
|
+
console.log(footerRow);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
var import_picocolors, silent = false, logger;
|
|
302
|
+
var init_logger = __esm(() => {
|
|
303
|
+
import_picocolors = __toESM(require_picocolors());
|
|
304
|
+
logger = Logger.getInstance();
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
// src/errors.ts
|
|
308
|
+
var import_picocolors2, BunupError, BunupBuildError, BunupDTSBuildError, BunupCLIError, BunupWatchError, BunupPluginError, parseErrorMessage = (error) => {
|
|
309
|
+
if (error instanceof Error) {
|
|
310
|
+
return error.message;
|
|
311
|
+
}
|
|
312
|
+
return String(error);
|
|
313
|
+
}, KNOWN_ERRORS, handleError = (error, context) => {
|
|
314
|
+
const errorMessage = parseErrorMessage(error);
|
|
315
|
+
const contextPrefix = context ? `[${context}] ` : "";
|
|
316
|
+
let errorType = "UNKNOWN ERROR";
|
|
317
|
+
if (error instanceof BunupBuildError) {
|
|
318
|
+
errorType = "BUILD ERROR";
|
|
319
|
+
} else if (error instanceof BunupDTSBuildError) {
|
|
320
|
+
errorType = "DTS ERROR";
|
|
321
|
+
} else if (error instanceof BunupCLIError) {
|
|
322
|
+
errorType = "CLI ERROR";
|
|
323
|
+
} else if (error instanceof BunupWatchError) {
|
|
324
|
+
errorType = "WATCH ERROR";
|
|
325
|
+
} else if (error instanceof BunupPluginError) {
|
|
326
|
+
errorType = "PLUGIN ERROR";
|
|
327
|
+
} else if (error instanceof BunupError) {
|
|
328
|
+
errorType = "BUNUP ERROR";
|
|
329
|
+
}
|
|
330
|
+
const knownError = KNOWN_ERRORS.find((error2) => error2.pattern.test(errorMessage) && (error2.errorType === errorType || !error2.errorType));
|
|
331
|
+
if (!knownError && errorType) {
|
|
332
|
+
console.error(`${import_picocolors2.default.red(errorType)} ${contextPrefix}${errorMessage}`);
|
|
333
|
+
}
|
|
334
|
+
if (knownError) {
|
|
335
|
+
console.log(`
|
|
336
|
+
`);
|
|
337
|
+
knownError.logSolution(errorMessage);
|
|
338
|
+
console.log(`
|
|
339
|
+
`);
|
|
340
|
+
} else {
|
|
341
|
+
console.error(import_picocolors2.default.dim(import_picocolors2.default.white("If you think this is a bug, please open an issue at: ") + import_picocolors2.default.cyan("https://github.com/arshad-yaseen/bunup/issues/new")));
|
|
342
|
+
}
|
|
343
|
+
}, handleErrorAndExit = (error, context) => {
|
|
344
|
+
handleError(error, context);
|
|
345
|
+
process.exit(1);
|
|
346
|
+
};
|
|
347
|
+
var init_errors = __esm(() => {
|
|
348
|
+
import_picocolors2 = __toESM(require_picocolors());
|
|
349
|
+
init_logger();
|
|
350
|
+
BunupError = class BunupError extends Error {
|
|
351
|
+
constructor(message) {
|
|
352
|
+
super(message);
|
|
353
|
+
this.name = "BunupError";
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
BunupBuildError = class BunupBuildError extends BunupError {
|
|
357
|
+
constructor(message) {
|
|
358
|
+
super(message);
|
|
359
|
+
this.name = "BunupBuildError";
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
BunupDTSBuildError = class BunupDTSBuildError extends BunupError {
|
|
363
|
+
constructor(message) {
|
|
364
|
+
super(message);
|
|
365
|
+
this.name = "BunupDTSBuildError";
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
BunupCLIError = class BunupCLIError extends BunupError {
|
|
369
|
+
constructor(message) {
|
|
370
|
+
super(message);
|
|
371
|
+
this.name = "BunupCLIError";
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
BunupWatchError = class BunupWatchError extends BunupError {
|
|
375
|
+
constructor(message) {
|
|
376
|
+
super(message);
|
|
377
|
+
this.name = "BunupWatchError";
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
BunupPluginError = class BunupPluginError extends BunupError {
|
|
381
|
+
constructor(message) {
|
|
382
|
+
super(message);
|
|
383
|
+
this.name = "BunupPluginError";
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
KNOWN_ERRORS = [
|
|
387
|
+
{
|
|
388
|
+
pattern: /Could not resolve: "bun"/i,
|
|
389
|
+
errorType: "BUILD ERROR",
|
|
390
|
+
logSolution: () => {
|
|
391
|
+
logger.error(import_picocolors2.default.white("You're trying to build a project that uses Bun. ") + import_picocolors2.default.white("Please set the target option to ") + import_picocolors2.default.cyan("`bun`") + import_picocolors2.default.white(`.
|
|
392
|
+
`) + import_picocolors2.default.white("Example: ") + import_picocolors2.default.green("`bunup --target bun`") + import_picocolors2.default.white(" or in config: ") + import_picocolors2.default.green("{ target: 'bun' }"));
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
];
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
// src/loaders.ts
|
|
399
|
+
async function processLoadedConfigs(config, cwd, filter) {
|
|
400
|
+
return Array.isArray(config) && "root" in config[0] ? config.filter((c) => filter ? filter.includes(c.name) : true).map((c) => ({
|
|
401
|
+
rootDir: import_node_path.default.resolve(cwd, c.root),
|
|
402
|
+
options: addField(c.config, "name", c.name)
|
|
403
|
+
})) : [
|
|
404
|
+
{
|
|
405
|
+
rootDir: cwd,
|
|
406
|
+
options: config
|
|
407
|
+
}
|
|
408
|
+
];
|
|
409
|
+
}
|
|
410
|
+
function addField(objectOrArray, field, value) {
|
|
411
|
+
return Array.isArray(objectOrArray) ? objectOrArray.map((o) => ({ ...o, [field]: value })) : { ...objectOrArray, [field]: value };
|
|
412
|
+
}
|
|
413
|
+
async function loadPackageJson(cwd = process.cwd()) {
|
|
414
|
+
const { config, filepath } = await import_coffi.loadConfig({
|
|
415
|
+
name: "package",
|
|
416
|
+
cwd,
|
|
417
|
+
extensions: [".json"]
|
|
418
|
+
});
|
|
419
|
+
return {
|
|
420
|
+
data: config,
|
|
421
|
+
path: filepath
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
var import_node_path, import_coffi;
|
|
425
|
+
var init_loaders = __esm(() => {
|
|
426
|
+
import_node_path = __toESM(require("path"));
|
|
427
|
+
import_coffi = require("coffi");
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
// src/utils.ts
|
|
431
|
+
function ensureArray(value) {
|
|
432
|
+
return Array.isArray(value) ? value : [value];
|
|
433
|
+
}
|
|
434
|
+
function getDefaultJsOutputExtension(format, packageType) {
|
|
435
|
+
switch (format) {
|
|
436
|
+
case "esm":
|
|
437
|
+
return isModulePackage(packageType) ? ".js" : ".mjs";
|
|
438
|
+
case "cjs":
|
|
439
|
+
return isModulePackage(packageType) ? ".cjs" : ".js";
|
|
440
|
+
case "iife":
|
|
441
|
+
return ".global.js";
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
function removeExtension(filePath) {
|
|
445
|
+
const basename = import_node_path2.default.basename(filePath);
|
|
446
|
+
const firstDotIndex = basename.indexOf(".");
|
|
447
|
+
if (firstDotIndex === -1) {
|
|
448
|
+
return filePath;
|
|
449
|
+
}
|
|
450
|
+
const nameWithoutExtensions = basename.slice(0, firstDotIndex);
|
|
451
|
+
const directory = import_node_path2.default.dirname(filePath);
|
|
452
|
+
return directory === "." ? nameWithoutExtensions : import_node_path2.default.join(directory, nameWithoutExtensions);
|
|
453
|
+
}
|
|
454
|
+
function isModulePackage(packageType) {
|
|
455
|
+
return packageType === "module";
|
|
456
|
+
}
|
|
457
|
+
function formatTime(ms) {
|
|
458
|
+
return ms >= 1000 ? `${(ms / 1000).toFixed(2)}s` : `${Math.round(ms)}ms`;
|
|
459
|
+
}
|
|
460
|
+
function getPackageDeps(packageJson) {
|
|
461
|
+
if (!packageJson)
|
|
462
|
+
return [];
|
|
463
|
+
return Array.from(new Set([
|
|
464
|
+
...Object.keys(packageJson.dependencies || {}),
|
|
465
|
+
...Object.keys(packageJson.peerDependencies || {})
|
|
466
|
+
]));
|
|
467
|
+
}
|
|
468
|
+
function formatFileSize(bytes) {
|
|
469
|
+
if (bytes === 0)
|
|
470
|
+
return "0 B";
|
|
471
|
+
const units = ["B", "KB", "MB", "GB"];
|
|
472
|
+
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
473
|
+
if (i === 0)
|
|
474
|
+
return `${bytes} ${units[i]}`;
|
|
475
|
+
return `${(bytes / 1024 ** i).toFixed(2)} ${units[i]}`;
|
|
476
|
+
}
|
|
477
|
+
function getShortFilePath(filePath, maxLength = 3) {
|
|
478
|
+
const fileParts = filePath.split("/");
|
|
479
|
+
const shortPath = fileParts.slice(-maxLength).join("/");
|
|
480
|
+
return shortPath;
|
|
481
|
+
}
|
|
482
|
+
async function cleanOutDir(rootDir, outDir) {
|
|
483
|
+
const outDirPath = import_node_path2.default.join(rootDir, outDir);
|
|
484
|
+
try {
|
|
485
|
+
await import_promises.default.rm(outDirPath, { recursive: true, force: true });
|
|
486
|
+
} catch (error) {
|
|
487
|
+
throw new BunupBuildError(`Failed to clean output directory: ${error}`);
|
|
488
|
+
}
|
|
489
|
+
await import_promises.default.mkdir(outDirPath, { recursive: true });
|
|
490
|
+
}
|
|
491
|
+
function cleanPath(path3) {
|
|
492
|
+
let cleaned = import_node_path2.normalize(path3).replace(/\\/g, "/");
|
|
493
|
+
cleaned = cleaned.replace(/^[a-zA-Z]:\//, "");
|
|
494
|
+
cleaned = cleaned.replace(/^\/+/, "");
|
|
495
|
+
cleaned = cleaned.replace(/\/+/g, "/");
|
|
496
|
+
return cleaned;
|
|
497
|
+
}
|
|
498
|
+
function isDirectoryPath(filePath) {
|
|
499
|
+
return import_node_path2.default.extname(filePath) === "";
|
|
500
|
+
}
|
|
501
|
+
function pathExistsSync(filePath) {
|
|
502
|
+
try {
|
|
503
|
+
import_node_fs.default.accessSync(filePath);
|
|
504
|
+
return true;
|
|
505
|
+
} catch (error) {
|
|
506
|
+
return false;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
function formatListWithAnd(arr) {
|
|
510
|
+
return new Intl.ListFormat("en", {
|
|
511
|
+
style: "long",
|
|
512
|
+
type: "conjunction"
|
|
513
|
+
}).format(arr);
|
|
514
|
+
}
|
|
515
|
+
async function getFilesFromGlobs(patterns, cwd) {
|
|
516
|
+
const includePatterns = patterns.filter((p) => !p.startsWith("!"));
|
|
517
|
+
const excludePatterns = patterns.filter((p) => p.startsWith("!")).map((p) => p.slice(1));
|
|
518
|
+
const includedFiles = new Set;
|
|
519
|
+
for (const pattern of includePatterns) {
|
|
520
|
+
const glob = new Bun.Glob(pattern);
|
|
521
|
+
for await (const file of glob.scan(cwd)) {
|
|
522
|
+
includedFiles.add(file);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
if (excludePatterns.length > 0) {
|
|
526
|
+
for (const pattern of excludePatterns) {
|
|
527
|
+
const glob = new Bun.Glob(pattern);
|
|
528
|
+
for await (const file of glob.scan(cwd)) {
|
|
529
|
+
includedFiles.delete(file);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
return Array.from(includedFiles);
|
|
534
|
+
}
|
|
535
|
+
var import_node_fs, import_promises, import_node_path2;
|
|
536
|
+
var init_utils = __esm(() => {
|
|
537
|
+
import_node_fs = __toESM(require("fs"));
|
|
538
|
+
import_promises = __toESM(require("fs/promises"));
|
|
539
|
+
import_node_path2 = __toESM(require("path"));
|
|
540
|
+
init_errors();
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
// src/cli/utils.ts
|
|
544
|
+
function displayBunupGradientArt() {
|
|
545
|
+
const art = `
|
|
546
|
+
\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557
|
|
547
|
+
\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557
|
|
548
|
+
\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D
|
|
549
|
+
\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u255D
|
|
550
|
+
\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551
|
|
551
|
+
\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D
|
|
552
|
+
`.trim();
|
|
553
|
+
const lines = art.split(`
|
|
554
|
+
`);
|
|
555
|
+
logger.space();
|
|
556
|
+
for (const line of lines) {
|
|
557
|
+
logger.output(import_picocolors7.default.cyan(line));
|
|
558
|
+
}
|
|
559
|
+
logger.space();
|
|
560
|
+
}
|
|
561
|
+
var import_picocolors7;
|
|
562
|
+
var init_utils2 = __esm(() => {
|
|
563
|
+
import_picocolors7 = __toESM(require_picocolors());
|
|
564
|
+
init_logger();
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
// src/cli/new.ts
|
|
568
|
+
var exports_new = {};
|
|
569
|
+
__export(exports_new, {
|
|
570
|
+
newProject: () => newProject
|
|
571
|
+
});
|
|
572
|
+
async function newProject() {
|
|
573
|
+
displayBunupGradientArt();
|
|
574
|
+
import_prompts.intro(import_picocolors8.default.bgCyan(import_picocolors8.default.black(" Scaffold a new project with Bunup ")));
|
|
575
|
+
const selectedTemplateDir = await import_prompts.select({
|
|
576
|
+
message: "Select a template",
|
|
577
|
+
options: TEMPLATES.map((template2) => ({
|
|
578
|
+
value: template2.dir,
|
|
579
|
+
label: import_picocolors8.default.blue(template2.name)
|
|
580
|
+
}))
|
|
581
|
+
});
|
|
582
|
+
const template = TEMPLATES.find((t) => t.dir === selectedTemplateDir);
|
|
583
|
+
if (!template) {
|
|
584
|
+
import_prompts.cancel("Invalid template");
|
|
585
|
+
process.exit(1);
|
|
586
|
+
}
|
|
587
|
+
const hasMonorepo = template.monorepoDir !== undefined;
|
|
588
|
+
const projectName = await import_prompts.text({
|
|
589
|
+
message: "Enter the project name",
|
|
590
|
+
placeholder: template.defaultName,
|
|
591
|
+
defaultValue: template.defaultName,
|
|
592
|
+
validate: (value) => {
|
|
593
|
+
if (!value) {
|
|
594
|
+
return "Project name is required";
|
|
595
|
+
}
|
|
596
|
+
if (value.includes(" ")) {
|
|
597
|
+
return "Project name cannot contain spaces";
|
|
598
|
+
}
|
|
599
|
+
if (pathExistsSync(getProjectPath(value))) {
|
|
600
|
+
return "Project already exists";
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
});
|
|
604
|
+
const projectPath = getProjectPath(projectName);
|
|
605
|
+
let useMonorepo = false;
|
|
606
|
+
let monorepoFirstPackageName;
|
|
607
|
+
if (hasMonorepo) {
|
|
608
|
+
useMonorepo = await import_prompts.confirm({
|
|
609
|
+
message: "Do you want to create a monorepo?",
|
|
610
|
+
initialValue: false
|
|
611
|
+
});
|
|
612
|
+
if (useMonorepo) {
|
|
613
|
+
monorepoFirstPackageName = await import_prompts.text({
|
|
614
|
+
message: "Enter the name of the first package",
|
|
615
|
+
placeholder: MONOREPO_FIRST_PACKAGE_NAME_PLACEHOLDER,
|
|
616
|
+
defaultValue: MONOREPO_FIRST_PACKAGE_NAME_PLACEHOLDER
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
const githubRepoInfo = await import_prompts.text({
|
|
621
|
+
message: "GitHub username and repo name (username/repo):",
|
|
622
|
+
placeholder: `${GITHUB_USERNAME_PLACEHOLDER}/${GITHUB_REPO_PLACEHOLDER}`,
|
|
623
|
+
defaultValue: `${GITHUB_USERNAME_PLACEHOLDER}/${GITHUB_REPO_PLACEHOLDER}`
|
|
624
|
+
});
|
|
625
|
+
const [githubUsername, githubRepoName] = githubRepoInfo.split("/");
|
|
626
|
+
await import_prompts.tasks([
|
|
627
|
+
{
|
|
628
|
+
title: "Creating project",
|
|
629
|
+
task: async () => {
|
|
630
|
+
const templatePath = useMonorepo ? template.monorepoDir : template.dir;
|
|
631
|
+
await import_giget.downloadTemplate(`github:${TEMPLATE_OWNER}/${TEMPLATE_REPO}/${templatePath}`, {
|
|
632
|
+
dir: projectPath
|
|
633
|
+
});
|
|
634
|
+
return "Template downloaded";
|
|
635
|
+
}
|
|
636
|
+
},
|
|
637
|
+
{
|
|
638
|
+
title: "Making the project yours",
|
|
639
|
+
task: async () => {
|
|
640
|
+
await import_replace_in_file.replaceInFile({
|
|
641
|
+
files: import_node_path8.default.join(projectPath, "**/*"),
|
|
642
|
+
from: [
|
|
643
|
+
new RegExp(GITHUB_REPO_PLACEHOLDER, "g"),
|
|
644
|
+
new RegExp(GITHUB_USERNAME_PLACEHOLDER, "g"),
|
|
645
|
+
new RegExp(template.defaultName, "g")
|
|
646
|
+
],
|
|
647
|
+
to: [githubRepoName, githubUsername, projectName],
|
|
648
|
+
ignore: ["node_modules", "dist", "bun.lock"]
|
|
649
|
+
});
|
|
650
|
+
if (useMonorepo && monorepoFirstPackageName) {
|
|
651
|
+
await import_replace_in_file.replaceInFile({
|
|
652
|
+
files: import_node_path8.default.join(projectPath, "**/*"),
|
|
653
|
+
from: [new RegExp(MONOREPO_FIRST_PACKAGE_NAME_PLACEHOLDER, "g")],
|
|
654
|
+
to: [monorepoFirstPackageName],
|
|
655
|
+
ignore: ["node_modules", "dist", "bun.lock"]
|
|
656
|
+
});
|
|
657
|
+
import_node_fs2.renameSync(import_node_path8.default.join(projectPath, MONOREPO_PACKAGES_DIR, MONOREPO_FIRST_PACKAGE_NAME_PLACEHOLDER), import_node_path8.default.join(projectPath, MONOREPO_PACKAGES_DIR, monorepoFirstPackageName));
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
]);
|
|
662
|
+
import_prompts.outro(`
|
|
663
|
+
${import_picocolors8.default.green("\u2728 Project scaffolded successfully! \u2728")}
|
|
664
|
+
|
|
665
|
+
${import_picocolors8.default.bold("Ready to launch your awesome new project?")}
|
|
666
|
+
|
|
667
|
+
${import_picocolors8.default.cyan("cd")} ${projectName}
|
|
668
|
+
${import_picocolors8.default.cyan("bun install")}
|
|
669
|
+
${import_picocolors8.default.cyan("bun run dev")}
|
|
670
|
+
|
|
671
|
+
${import_picocolors8.default.dim("Learn more:")} ${import_picocolors8.default.underline("https://bunup.dev/docs")}
|
|
672
|
+
|
|
673
|
+
${import_picocolors8.default.yellow("Happy coding!")} \uD83D\uDE80
|
|
674
|
+
`);
|
|
675
|
+
}
|
|
676
|
+
function getProjectPath(projectName) {
|
|
677
|
+
return import_node_path8.default.join(process.cwd(), projectName);
|
|
678
|
+
}
|
|
679
|
+
var import_node_fs2, import_node_path8, import_prompts, import_giget, import_picocolors8, import_replace_in_file, TEMPLATE_OWNER = "arshad-yaseen", TEMPLATE_REPO = "bunup-new", GITHUB_USERNAME_PLACEHOLDER = "username", GITHUB_REPO_PLACEHOLDER = "repo-name", MONOREPO_FIRST_PACKAGE_NAME_PLACEHOLDER = "package-1", MONOREPO_PACKAGES_DIR = "packages", TEMPLATES;
|
|
680
|
+
var init_new = __esm(() => {
|
|
681
|
+
import_node_fs2 = require("fs");
|
|
682
|
+
import_node_path8 = __toESM(require("path"));
|
|
683
|
+
import_prompts = require("@clack/prompts");
|
|
684
|
+
import_giget = require("giget");
|
|
685
|
+
import_picocolors8 = __toESM(require_picocolors());
|
|
686
|
+
import_replace_in_file = require("replace-in-file");
|
|
687
|
+
init_utils();
|
|
688
|
+
init_utils2();
|
|
689
|
+
TEMPLATES = [
|
|
690
|
+
{
|
|
691
|
+
defaultName: "my-ts-lib",
|
|
692
|
+
name: "Typescript Library",
|
|
693
|
+
dir: "ts-lib",
|
|
694
|
+
monorepoDir: "ts-lib-monorepo"
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
defaultName: "my-react-lib",
|
|
698
|
+
name: "React Library",
|
|
699
|
+
dir: "react-lib"
|
|
700
|
+
}
|
|
701
|
+
];
|
|
702
|
+
});
|
|
703
|
+
|
|
704
|
+
// src/cli/init.ts
|
|
705
|
+
var exports_init = {};
|
|
706
|
+
__export(exports_init, {
|
|
707
|
+
init: () => init
|
|
708
|
+
});
|
|
709
|
+
async function init() {
|
|
710
|
+
displayBunupGradientArt();
|
|
711
|
+
import_prompts2.intro(import_picocolors9.default.bgCyan(import_picocolors9.default.black(" Initialize bunup in an existing project ")));
|
|
712
|
+
const { path: packageJsonPath } = await loadPackageJson();
|
|
713
|
+
if (!packageJsonPath) {
|
|
714
|
+
import_prompts2.log.error("package.json not found");
|
|
715
|
+
process.exit(1);
|
|
716
|
+
}
|
|
717
|
+
const shouldSetupWorkspace = await promptForWorkspace();
|
|
718
|
+
if (shouldSetupWorkspace) {
|
|
719
|
+
await initializeWorkspace(packageJsonPath);
|
|
720
|
+
} else {
|
|
721
|
+
await initializeSinglePackage(packageJsonPath);
|
|
722
|
+
}
|
|
723
|
+
await import_prompts2.tasks([
|
|
724
|
+
{
|
|
725
|
+
title: "Installing bunup",
|
|
726
|
+
task: async () => {
|
|
727
|
+
await installBunup();
|
|
728
|
+
return "Bunup installed";
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
]);
|
|
732
|
+
showSuccessOutro(shouldSetupWorkspace);
|
|
733
|
+
}
|
|
734
|
+
async function promptForWorkspace() {
|
|
735
|
+
return await import_prompts2.confirm({
|
|
736
|
+
message: "Do you want to setup a Bunup workspace? (for building multiple packages with one command)",
|
|
737
|
+
initialValue: false
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
async function initializeWorkspace(packageJsonPath) {
|
|
741
|
+
const workspacePackages = await collectWorkspacePackages();
|
|
742
|
+
const configMethod = await selectWorkspaceConfigurationMethod();
|
|
743
|
+
await generateWorkspaceConfiguration(configMethod, workspacePackages);
|
|
744
|
+
await handleWorkspaceBuildScripts(packageJsonPath);
|
|
745
|
+
}
|
|
746
|
+
async function initializeSinglePackage(packageJsonPath) {
|
|
747
|
+
const entryFiles = await collectEntryFiles();
|
|
748
|
+
const outputFormats = await selectOutputFormats();
|
|
749
|
+
const shouldGenerateDts = await promptForTypeScriptDeclarations(entryFiles);
|
|
750
|
+
const configMethod = await selectConfigurationMethod();
|
|
751
|
+
await generateConfiguration(configMethod, entryFiles, outputFormats, shouldGenerateDts, packageJsonPath);
|
|
752
|
+
await handleBuildScripts(packageJsonPath, entryFiles, outputFormats, shouldGenerateDts, configMethod);
|
|
753
|
+
}
|
|
754
|
+
async function collectWorkspacePackages() {
|
|
755
|
+
const packages = [];
|
|
756
|
+
while (true) {
|
|
757
|
+
const packageName = await import_prompts2.text({
|
|
758
|
+
message: packages.length > 0 ? "Enter the next package name:" : "Enter the first package name:",
|
|
759
|
+
placeholder: "core",
|
|
760
|
+
validate: (value) => {
|
|
761
|
+
if (!value)
|
|
762
|
+
return "Package name is required";
|
|
763
|
+
if (packages.some((pkg) => pkg.name === value))
|
|
764
|
+
return "Package name already exists";
|
|
765
|
+
}
|
|
766
|
+
});
|
|
767
|
+
const packageRoot = await import_prompts2.text({
|
|
768
|
+
message: `Enter the root directory for "${packageName}":`,
|
|
769
|
+
placeholder: `packages/${packageName}`,
|
|
770
|
+
defaultValue: `packages/${packageName}`,
|
|
771
|
+
validate: (value) => {
|
|
772
|
+
if (!value)
|
|
773
|
+
return "Package root is required";
|
|
774
|
+
if (!import_node_fs3.default.existsSync(value))
|
|
775
|
+
return "Package root directory does not exist";
|
|
776
|
+
if (!import_node_fs3.default.statSync(value).isDirectory())
|
|
777
|
+
return "Package root must be a directory";
|
|
778
|
+
}
|
|
779
|
+
});
|
|
780
|
+
const entryFiles = await collectEntryFilesForPackage(packageRoot, packageName);
|
|
781
|
+
const outputFormats = await selectOutputFormats();
|
|
782
|
+
const shouldGenerateDts = await promptForTypeScriptDeclarations(entryFiles);
|
|
783
|
+
packages.push({
|
|
784
|
+
name: packageName,
|
|
785
|
+
root: packageRoot,
|
|
786
|
+
entryFiles,
|
|
787
|
+
outputFormats,
|
|
788
|
+
shouldGenerateDts
|
|
789
|
+
});
|
|
790
|
+
const shouldAddMore = await import_prompts2.confirm({
|
|
791
|
+
message: "Do you want to add another package?",
|
|
792
|
+
initialValue: true
|
|
793
|
+
});
|
|
794
|
+
if (!shouldAddMore)
|
|
795
|
+
break;
|
|
796
|
+
}
|
|
797
|
+
return packages;
|
|
798
|
+
}
|
|
799
|
+
async function collectEntryFilesForPackage(packageRoot, packageName) {
|
|
800
|
+
const entryFiles = [];
|
|
801
|
+
while (true) {
|
|
802
|
+
const entryFile = await import_prompts2.text({
|
|
803
|
+
message: entryFiles.length > 0 ? `Where is the next entry file for "${packageName}"? (relative to ${packageRoot})` : `Where is the entry file for "${packageName}"? (relative to ${packageRoot})`,
|
|
804
|
+
placeholder: "src/index.ts",
|
|
805
|
+
defaultValue: "src/index.ts",
|
|
806
|
+
validate: (value) => {
|
|
807
|
+
if (!value)
|
|
808
|
+
return "Entry file is required";
|
|
809
|
+
const fullPath = import_node_path9.default.join(packageRoot, value);
|
|
810
|
+
if (!import_node_fs3.default.existsSync(fullPath))
|
|
811
|
+
return `Entry file does not exist at ${fullPath}`;
|
|
812
|
+
if (!import_node_fs3.default.statSync(fullPath).isFile())
|
|
813
|
+
return "Entry file must be a file";
|
|
814
|
+
if (entryFiles.includes(value))
|
|
815
|
+
return "You have already added this entry file";
|
|
816
|
+
}
|
|
817
|
+
});
|
|
818
|
+
entryFiles.push(entryFile);
|
|
819
|
+
const shouldAddMore = await import_prompts2.confirm({
|
|
820
|
+
message: "Do you want to add another entry file for this package?",
|
|
821
|
+
initialValue: false
|
|
822
|
+
});
|
|
823
|
+
if (!shouldAddMore)
|
|
824
|
+
break;
|
|
825
|
+
}
|
|
826
|
+
return entryFiles;
|
|
827
|
+
}
|
|
828
|
+
async function collectEntryFiles() {
|
|
829
|
+
const entryFiles = [];
|
|
830
|
+
while (true) {
|
|
831
|
+
const entryFile = await import_prompts2.text({
|
|
832
|
+
message: entryFiles.length > 0 ? "Where is your next entry file?" : "Where is your entry file?",
|
|
833
|
+
placeholder: "src/index.ts",
|
|
834
|
+
defaultValue: "src/index.ts",
|
|
835
|
+
validate: (value) => {
|
|
836
|
+
if (!value)
|
|
837
|
+
return "Entry file is required";
|
|
838
|
+
if (!import_node_fs3.default.existsSync(value))
|
|
839
|
+
return "Entry file does not exist";
|
|
840
|
+
if (!import_node_fs3.default.statSync(value).isFile())
|
|
841
|
+
return "Entry file must be a file";
|
|
842
|
+
if (entryFiles.includes(value))
|
|
843
|
+
return "You have already added this entry file";
|
|
844
|
+
}
|
|
845
|
+
});
|
|
846
|
+
entryFiles.push(entryFile);
|
|
847
|
+
const shouldAddMore = await import_prompts2.confirm({
|
|
848
|
+
message: "Do you want to add another entry file?",
|
|
849
|
+
initialValue: false
|
|
850
|
+
});
|
|
851
|
+
if (!shouldAddMore)
|
|
852
|
+
break;
|
|
853
|
+
}
|
|
854
|
+
return entryFiles;
|
|
855
|
+
}
|
|
856
|
+
async function selectOutputFormats() {
|
|
857
|
+
return await import_prompts2.multiselect({
|
|
858
|
+
message: "Select the output formats",
|
|
859
|
+
options: [
|
|
860
|
+
{ value: "esm", label: "ESM (.mjs)" },
|
|
861
|
+
{ value: "cjs", label: "CommonJS (.cjs)" },
|
|
862
|
+
{ value: "iife", label: "IIFE (.global.js)" }
|
|
863
|
+
],
|
|
864
|
+
initialValues: ["esm", "cjs"]
|
|
865
|
+
});
|
|
866
|
+
}
|
|
867
|
+
async function promptForTypeScriptDeclarations(entryFiles) {
|
|
868
|
+
const hasTypeScriptFiles = entryFiles.some((file) => file.endsWith(".ts") || file.endsWith(".tsx"));
|
|
869
|
+
if (!hasTypeScriptFiles)
|
|
870
|
+
return false;
|
|
871
|
+
return await import_prompts2.confirm({
|
|
872
|
+
message: "Generate TypeScript declarations?",
|
|
873
|
+
initialValue: true
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
async function selectWorkspaceConfigurationMethod() {
|
|
877
|
+
return await import_prompts2.select({
|
|
878
|
+
message: "How would you like to configure your workspace?",
|
|
879
|
+
options: [
|
|
880
|
+
{ value: "ts", label: "bunup.config.ts", hint: "Recommended" },
|
|
881
|
+
{ value: "js", label: "bunup.config.js" }
|
|
882
|
+
],
|
|
883
|
+
initialValue: "ts"
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
async function selectConfigurationMethod() {
|
|
887
|
+
return await import_prompts2.select({
|
|
888
|
+
message: "How would you like to configure Bunup?",
|
|
889
|
+
options: [
|
|
890
|
+
{ value: "ts", label: "bunup.config.ts", hint: "Recommended" },
|
|
891
|
+
{ value: "js", label: "bunup.config.js" },
|
|
892
|
+
{ value: "json", label: 'package.json "bunup" property' },
|
|
893
|
+
{
|
|
894
|
+
value: "none",
|
|
895
|
+
label: "No config file",
|
|
896
|
+
hint: "Configure via CLI only"
|
|
897
|
+
}
|
|
898
|
+
],
|
|
899
|
+
initialValue: "ts"
|
|
900
|
+
});
|
|
901
|
+
}
|
|
902
|
+
async function generateWorkspaceConfiguration(configMethod, workspacePackages) {
|
|
903
|
+
const configContent = createWorkspaceConfigFileContent(workspacePackages);
|
|
904
|
+
await Bun.write(`bunup.config.${configMethod}`, configContent);
|
|
905
|
+
}
|
|
906
|
+
async function generateConfiguration(configMethod, entryFiles, outputFormats, shouldGenerateDts, packageJsonPath) {
|
|
907
|
+
if (configMethod === "none") {
|
|
908
|
+
import_prompts2.log.info("If you need more control (such as adding plugins or customizing output), you can always create a config file later.");
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
if (configMethod === "ts" || configMethod === "js") {
|
|
912
|
+
await Bun.write(`bunup.config.${configMethod}`, createConfigFileContent(entryFiles, outputFormats, shouldGenerateDts));
|
|
913
|
+
} else if (configMethod === "json") {
|
|
914
|
+
const { data: packageJsonConfig } = await loadPackageJson();
|
|
915
|
+
const updatedConfig = {
|
|
916
|
+
...packageJsonConfig,
|
|
917
|
+
bunup: createPackageJsonConfig(entryFiles, outputFormats, shouldGenerateDts)
|
|
918
|
+
};
|
|
919
|
+
await Bun.write(packageJsonPath, JSON.stringify(updatedConfig, null, 2));
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
async function handleWorkspaceBuildScripts(packageJsonPath) {
|
|
923
|
+
const { data: packageJsonConfig } = await loadPackageJson();
|
|
924
|
+
const existingScripts = packageJsonConfig?.scripts ?? {};
|
|
925
|
+
const newScripts = createWorkspaceBuildScripts();
|
|
926
|
+
const conflictingScripts = Object.keys(newScripts).filter((script) => existingScripts[script]);
|
|
927
|
+
if (conflictingScripts.length > 0) {
|
|
928
|
+
const shouldOverride = await import_prompts2.confirm({
|
|
929
|
+
message: `The ${formatListWithAnd(conflictingScripts)} ${conflictingScripts.length > 1 ? "scripts already exist" : "script already exists"} in package.json. Override ${conflictingScripts.length > 1 ? "them" : "it"}?`,
|
|
930
|
+
initialValue: true
|
|
931
|
+
});
|
|
932
|
+
if (!shouldOverride) {
|
|
933
|
+
import_prompts2.log.info("Skipped adding build scripts to avoid conflicts.");
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
const updatedConfig = {
|
|
938
|
+
...packageJsonConfig,
|
|
939
|
+
scripts: { ...existingScripts, ...newScripts }
|
|
940
|
+
};
|
|
941
|
+
await Bun.write(packageJsonPath, JSON.stringify(updatedConfig, null, 2));
|
|
942
|
+
}
|
|
943
|
+
async function handleBuildScripts(packageJsonPath, entryFiles, outputFormats, shouldGenerateDts, configMethod) {
|
|
944
|
+
const { data: packageJsonConfig } = await loadPackageJson();
|
|
945
|
+
const existingScripts = packageJsonConfig?.scripts ?? {};
|
|
946
|
+
const newScripts = createBuildScripts(entryFiles, outputFormats, shouldGenerateDts, configMethod);
|
|
947
|
+
const conflictingScripts = Object.keys(newScripts).filter((script) => existingScripts[script]);
|
|
948
|
+
if (conflictingScripts.length > 0) {
|
|
949
|
+
const shouldOverride = await import_prompts2.confirm({
|
|
950
|
+
message: `The ${formatListWithAnd(conflictingScripts)} ${conflictingScripts.length > 1 ? "scripts already exist" : "script already exists"} in package.json. Override ${conflictingScripts.length > 1 ? "them" : "it"}?`,
|
|
951
|
+
initialValue: true
|
|
952
|
+
});
|
|
953
|
+
if (!shouldOverride) {
|
|
954
|
+
import_prompts2.log.info("Skipped adding build scripts to avoid conflicts.");
|
|
955
|
+
return;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
const updatedConfig = {
|
|
959
|
+
...packageJsonConfig,
|
|
960
|
+
scripts: { ...existingScripts, ...newScripts }
|
|
961
|
+
};
|
|
962
|
+
await Bun.write(packageJsonPath, JSON.stringify(updatedConfig, null, 2));
|
|
963
|
+
}
|
|
964
|
+
function createWorkspaceConfigFileContent(workspacePackages) {
|
|
965
|
+
const packagesConfig = workspacePackages.map((pkg) => {
|
|
966
|
+
return ` {
|
|
967
|
+
name: '${pkg.name}',
|
|
968
|
+
root: '${pkg.root}',
|
|
969
|
+
config: {
|
|
970
|
+
entry: [${pkg.entryFiles.map((file) => `'${file}'`).join(", ")}],
|
|
971
|
+
format: [${pkg.outputFormats.map((format) => `'${format}'`).join(", ")}],${pkg.shouldGenerateDts ? `
|
|
972
|
+
dts: true,` : ""}
|
|
973
|
+
},
|
|
974
|
+
}`;
|
|
975
|
+
}).join(`,
|
|
976
|
+
`);
|
|
977
|
+
return `import { defineWorkspace } from 'bunup'
|
|
978
|
+
|
|
979
|
+
export default defineWorkspace([
|
|
980
|
+
${packagesConfig}
|
|
981
|
+
])
|
|
982
|
+
`;
|
|
983
|
+
}
|
|
984
|
+
function createConfigFileContent(entryFiles, outputFormats, shouldGenerateDts) {
|
|
985
|
+
return `import { defineConfig } from 'bunup'
|
|
986
|
+
|
|
987
|
+
export default defineConfig({
|
|
988
|
+
entry: [${entryFiles.map((file) => `'${file}'`).join(", ")}],
|
|
989
|
+
format: [${outputFormats.map((format) => `'${format}'`).join(", ")}],${shouldGenerateDts ? `
|
|
990
|
+
dts: true,` : ""}
|
|
991
|
+
})
|
|
992
|
+
`;
|
|
993
|
+
}
|
|
994
|
+
function createPackageJsonConfig(entryFiles, outputFormats, shouldGenerateDts) {
|
|
995
|
+
return {
|
|
996
|
+
entry: entryFiles,
|
|
997
|
+
format: outputFormats,
|
|
998
|
+
...shouldGenerateDts && { dts: true }
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
1001
|
+
function createWorkspaceBuildScripts() {
|
|
1002
|
+
return {
|
|
1003
|
+
build: "bunup",
|
|
1004
|
+
dev: "bunup --watch"
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
function createBuildScripts(entryFiles, outputFormats, shouldGenerateDts, configMethod) {
|
|
1008
|
+
const cliOptions = configMethod === "none" ? ` ${entryFiles.join(" ")} --format ${outputFormats.join(",")}${shouldGenerateDts ? " --dts" : ""}` : "";
|
|
1009
|
+
return {
|
|
1010
|
+
build: `bunup${cliOptions}`,
|
|
1011
|
+
dev: `bunup${cliOptions} --watch`
|
|
1012
|
+
};
|
|
1013
|
+
}
|
|
1014
|
+
function showSuccessOutro(isWorkspace) {
|
|
1015
|
+
const buildCommand = isWorkspace ? `${import_picocolors9.default.cyan("bun run build")} - Build all packages in your workspace` : `${import_picocolors9.default.cyan("bun run build")} - Build your library`;
|
|
1016
|
+
const devCommand = isWorkspace ? `${import_picocolors9.default.cyan("bun run dev")} - Start development mode (watches all packages)` : `${import_picocolors9.default.cyan("bun run dev")} - Start development mode`;
|
|
1017
|
+
const filterCommand = isWorkspace ? `${import_picocolors9.default.cyan("bunup --filter core,utils")} - Build specific packages` : "";
|
|
1018
|
+
import_prompts2.outro(`
|
|
1019
|
+
${import_picocolors9.default.green("\u2728 Bunup initialized successfully! \u2728")}
|
|
1020
|
+
|
|
1021
|
+
${buildCommand}
|
|
1022
|
+
${devCommand}${isWorkspace ? `
|
|
1023
|
+
${filterCommand}` : ""}
|
|
1024
|
+
|
|
1025
|
+
${import_picocolors9.default.dim("Learn more:")} ${import_picocolors9.default.underline("https://bunup.dev/docs/")}
|
|
1026
|
+
|
|
1027
|
+
${import_picocolors9.default.yellow("Happy building!")} \uD83D\uDE80
|
|
1028
|
+
`);
|
|
1029
|
+
}
|
|
1030
|
+
async function installBunup() {
|
|
1031
|
+
await import_tinyexec.exec("bun add -d bunup", [], {
|
|
1032
|
+
nodeOptions: { shell: true, stdio: "pipe" }
|
|
1033
|
+
});
|
|
1034
|
+
}
|
|
1035
|
+
var import_node_fs3, import_node_path9, import_prompts2, import_picocolors9, import_tinyexec;
|
|
1036
|
+
var init_init = __esm(() => {
|
|
1037
|
+
import_node_fs3 = __toESM(require("fs"));
|
|
1038
|
+
import_node_path9 = __toESM(require("path"));
|
|
1039
|
+
import_prompts2 = require("@clack/prompts");
|
|
1040
|
+
import_picocolors9 = __toESM(require_picocolors());
|
|
1041
|
+
import_tinyexec = require("tinyexec");
|
|
1042
|
+
init_loaders();
|
|
1043
|
+
init_utils();
|
|
1044
|
+
init_utils2();
|
|
1045
|
+
});
|
|
1046
|
+
|
|
1047
|
+
// src/cli/index.ts
|
|
1048
|
+
var exports_cli = {};
|
|
1049
|
+
module.exports = __toCommonJS(exports_cli);
|
|
1050
|
+
var import_tinyexec2 = require("tinyexec");
|
|
1051
|
+
// package.json
|
|
1052
|
+
var version = "0.8.29";
|
|
1053
|
+
|
|
1054
|
+
// src/cli/index.ts
|
|
1055
|
+
init_errors();
|
|
1056
|
+
init_logger();
|
|
1057
|
+
|
|
1058
|
+
// src/cli/options.ts
|
|
1059
|
+
var import_picocolors3 = __toESM(require_picocolors());
|
|
1060
|
+
|
|
1061
|
+
// src/constants/index.ts
|
|
1062
|
+
var BUNUP_CLI_OPTIONS_URL = "https://bunup.dev/docs/guide/cli-options";
|
|
1063
|
+
|
|
1064
|
+
// src/cli/options.ts
|
|
1065
|
+
init_errors();
|
|
1066
|
+
init_logger();
|
|
1067
|
+
function booleanHandler(optionName) {
|
|
1068
|
+
return (value, options) => {
|
|
1069
|
+
options[optionName] = value === true || value === "true";
|
|
1070
|
+
};
|
|
1071
|
+
}
|
|
1072
|
+
function stringHandler(optionName) {
|
|
1073
|
+
return (value, options) => {
|
|
1074
|
+
if (typeof value === "string") {
|
|
1075
|
+
options[optionName] = value;
|
|
1076
|
+
} else {
|
|
1077
|
+
throw new BunupCLIError(`Option --${optionName} requires a string value`);
|
|
1078
|
+
}
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
function arrayHandler(optionName) {
|
|
1082
|
+
return (value, options) => {
|
|
1083
|
+
if (typeof value === "string") {
|
|
1084
|
+
options[optionName] = value.split(",");
|
|
1085
|
+
} else {
|
|
1086
|
+
throw new BunupCLIError(`Option --${optionName} requires a string value`);
|
|
1087
|
+
}
|
|
1088
|
+
};
|
|
1089
|
+
}
|
|
1090
|
+
function booleanOrStringHandler(optionName) {
|
|
1091
|
+
return (value, options) => {
|
|
1092
|
+
if (typeof value === "boolean") {
|
|
1093
|
+
options[optionName] = value;
|
|
1094
|
+
} else if (typeof value === "string") {
|
|
1095
|
+
if (value.toLowerCase() === "true" || value.toLowerCase() === "false") {
|
|
1096
|
+
options[optionName] = value.toLowerCase() === "true";
|
|
1097
|
+
} else {
|
|
1098
|
+
options[optionName] = value;
|
|
1099
|
+
}
|
|
1100
|
+
} else {
|
|
1101
|
+
throw new BunupCLIError(`Option --${optionName} requires a boolean or string value`);
|
|
1102
|
+
}
|
|
1103
|
+
};
|
|
1104
|
+
}
|
|
1105
|
+
function showHelp() {
|
|
1106
|
+
console.log(`
|
|
1107
|
+
Bunup - \u26A1\uFE0F A blazing-fast build tool for your libraries built with Bun.
|
|
1108
|
+
`);
|
|
1109
|
+
console.log("For more information on available options, visit:");
|
|
1110
|
+
console.log(`${import_picocolors3.default.cyan(import_picocolors3.default.underline(BUNUP_CLI_OPTIONS_URL))}
|
|
1111
|
+
`);
|
|
1112
|
+
process.exit(0);
|
|
1113
|
+
}
|
|
1114
|
+
function showVersion() {
|
|
1115
|
+
console.log(version);
|
|
1116
|
+
process.exit(0);
|
|
1117
|
+
}
|
|
1118
|
+
var optionConfigs = {
|
|
1119
|
+
name: { flags: ["n", "name"], handler: stringHandler("name") },
|
|
1120
|
+
format: {
|
|
1121
|
+
flags: ["f", "format"],
|
|
1122
|
+
handler: arrayHandler("format")
|
|
1123
|
+
},
|
|
1124
|
+
outDir: { flags: ["o", "out-dir"], handler: stringHandler("outDir") },
|
|
1125
|
+
minify: { flags: ["m", "minify"], handler: booleanHandler("minify") },
|
|
1126
|
+
watch: { flags: ["w", "watch"], handler: booleanHandler("watch") },
|
|
1127
|
+
dts: { flags: ["d", "dts"], handler: booleanHandler("dts") },
|
|
1128
|
+
banner: { flags: ["bn", "banner"], handler: stringHandler("banner") },
|
|
1129
|
+
footer: { flags: ["ft", "footer"], handler: stringHandler("footer") },
|
|
1130
|
+
external: { flags: ["e", "external"], handler: arrayHandler("external") },
|
|
1131
|
+
sourcemap: {
|
|
1132
|
+
flags: ["sm", "sourcemap"],
|
|
1133
|
+
handler: booleanOrStringHandler("sourcemap")
|
|
1134
|
+
},
|
|
1135
|
+
target: { flags: ["t", "target"], handler: stringHandler("target") },
|
|
1136
|
+
minifyWhitespace: {
|
|
1137
|
+
flags: ["mw", "minify-whitespace"],
|
|
1138
|
+
handler: booleanHandler("minifyWhitespace")
|
|
1139
|
+
},
|
|
1140
|
+
minifyIdentifiers: {
|
|
1141
|
+
flags: ["mi", "minify-identifiers"],
|
|
1142
|
+
handler: booleanHandler("minifyIdentifiers")
|
|
1143
|
+
},
|
|
1144
|
+
minifySyntax: {
|
|
1145
|
+
flags: ["ms", "minify-syntax"],
|
|
1146
|
+
handler: booleanHandler("minifySyntax")
|
|
1147
|
+
},
|
|
1148
|
+
clean: { flags: ["c", "clean"], handler: booleanHandler("clean") },
|
|
1149
|
+
splitting: {
|
|
1150
|
+
flags: ["s", "splitting"],
|
|
1151
|
+
handler: booleanHandler("splitting")
|
|
1152
|
+
},
|
|
1153
|
+
noExternal: {
|
|
1154
|
+
flags: ["ne", "no-external"],
|
|
1155
|
+
handler: arrayHandler("noExternal")
|
|
1156
|
+
},
|
|
1157
|
+
preferredTsconfigPath: {
|
|
1158
|
+
flags: ["tsconfig", "preferred-tsconfig-path"],
|
|
1159
|
+
handler: stringHandler("preferredTsconfigPath")
|
|
1160
|
+
},
|
|
1161
|
+
bytecode: {
|
|
1162
|
+
flags: ["bc", "bytecode"],
|
|
1163
|
+
handler: booleanHandler("bytecode")
|
|
1164
|
+
},
|
|
1165
|
+
silent: { flags: ["silent"], handler: booleanHandler("silent") },
|
|
1166
|
+
config: { flags: ["config"], handler: stringHandler("config") },
|
|
1167
|
+
publicPath: {
|
|
1168
|
+
flags: ["pp", "public-path"],
|
|
1169
|
+
handler: stringHandler("publicPath")
|
|
1170
|
+
},
|
|
1171
|
+
env: { flags: ["env"], handler: stringHandler("env") },
|
|
1172
|
+
onSuccess: {
|
|
1173
|
+
flags: ["onSuccess"],
|
|
1174
|
+
handler: stringHandler("onSuccess")
|
|
1175
|
+
},
|
|
1176
|
+
filter: { flags: ["filter"], handler: arrayHandler("filter") },
|
|
1177
|
+
new: { flags: ["new"], handler: booleanHandler("new") },
|
|
1178
|
+
init: { flags: ["init"], handler: booleanHandler("init") },
|
|
1179
|
+
entry: {
|
|
1180
|
+
flags: ["entry"],
|
|
1181
|
+
handler: (value, options, subPath) => {
|
|
1182
|
+
if (typeof value !== "string") {
|
|
1183
|
+
throw new BunupCLIError(`Entry${subPath ? ` --entry.${subPath}` : ""} requires a string value`);
|
|
1184
|
+
}
|
|
1185
|
+
const entries = Array.isArray(options.entry) ? [...options.entry] : [];
|
|
1186
|
+
if (subPath) {
|
|
1187
|
+
logger.warn(`Subpath '${subPath}' provided via --entry.${subPath}, but object entry format is not supported. Adding entry as string.`);
|
|
1188
|
+
}
|
|
1189
|
+
if (entries.includes(value)) {
|
|
1190
|
+
logger.warn(`Duplicate entry '${value}' provided. Skipping.`);
|
|
1191
|
+
} else {
|
|
1192
|
+
entries.push(value);
|
|
1193
|
+
}
|
|
1194
|
+
options.entry = entries;
|
|
1195
|
+
}
|
|
1196
|
+
},
|
|
1197
|
+
resolveDts: {
|
|
1198
|
+
flags: ["rd", "resolve-dts"],
|
|
1199
|
+
handler: (value, options) => {
|
|
1200
|
+
if (!options.dts)
|
|
1201
|
+
options.dts = {};
|
|
1202
|
+
if (typeof options.dts === "boolean")
|
|
1203
|
+
options.dts = {};
|
|
1204
|
+
if (typeof value === "string") {
|
|
1205
|
+
if (value === "true" || value === "false") {
|
|
1206
|
+
options.dts.resolve = value === "true";
|
|
1207
|
+
} else {
|
|
1208
|
+
options.dts.resolve = value.split(",");
|
|
1209
|
+
}
|
|
1210
|
+
} else {
|
|
1211
|
+
options.dts.resolve = true;
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
},
|
|
1215
|
+
help: { flags: ["h", "help"], handler: () => showHelp() },
|
|
1216
|
+
version: { flags: ["v", "version"], handler: () => showVersion() }
|
|
1217
|
+
};
|
|
1218
|
+
var flagToHandler = {};
|
|
1219
|
+
for (const config of Object.values(optionConfigs)) {
|
|
1220
|
+
for (const flag of config.flags) {
|
|
1221
|
+
flagToHandler[flag] = config.handler;
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
function parseCliOptions(argv) {
|
|
1225
|
+
const options = {};
|
|
1226
|
+
for (let i = 0;i < argv.length; i++) {
|
|
1227
|
+
const arg = argv[i];
|
|
1228
|
+
if (arg.startsWith("--")) {
|
|
1229
|
+
let key;
|
|
1230
|
+
let value;
|
|
1231
|
+
if (arg.includes("=")) {
|
|
1232
|
+
const [keyPart, valuePart] = arg.slice(2).split("=", 2);
|
|
1233
|
+
key = keyPart;
|
|
1234
|
+
value = valuePart;
|
|
1235
|
+
} else {
|
|
1236
|
+
key = arg.slice(2);
|
|
1237
|
+
const nextArg = argv[i + 1];
|
|
1238
|
+
value = nextArg && !nextArg.startsWith("-") ? nextArg : true;
|
|
1239
|
+
if (typeof value === "string")
|
|
1240
|
+
i++;
|
|
1241
|
+
}
|
|
1242
|
+
if (key.includes(".")) {
|
|
1243
|
+
const [mainOption, subPath] = key.split(".", 2);
|
|
1244
|
+
const handler = flagToHandler[mainOption];
|
|
1245
|
+
if (handler) {
|
|
1246
|
+
handler(value, options, subPath);
|
|
1247
|
+
} else {
|
|
1248
|
+
throw new BunupCLIError(`Unknown option: --${key}`);
|
|
1249
|
+
}
|
|
1250
|
+
} else {
|
|
1251
|
+
const handler = flagToHandler[key];
|
|
1252
|
+
if (handler) {
|
|
1253
|
+
handler(value, options);
|
|
1254
|
+
} else {
|
|
1255
|
+
throw new BunupCLIError(`Unknown option: --${key}`);
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
} else if (arg.startsWith("-")) {
|
|
1259
|
+
const key = arg.slice(1);
|
|
1260
|
+
const nextArg = argv[i + 1];
|
|
1261
|
+
const value = nextArg && !nextArg.startsWith("-") ? nextArg : true;
|
|
1262
|
+
if (typeof value === "string")
|
|
1263
|
+
i++;
|
|
1264
|
+
const handler = flagToHandler[key];
|
|
1265
|
+
if (handler) {
|
|
1266
|
+
handler(value, options);
|
|
1267
|
+
} else {
|
|
1268
|
+
throw new BunupCLIError(`Unknown option: -${key}`);
|
|
1269
|
+
}
|
|
1270
|
+
} else {
|
|
1271
|
+
optionConfigs.entry.handler(arg, options, undefined);
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
return options;
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
// src/cli/index.ts
|
|
1278
|
+
var import_coffi2 = require("coffi");
|
|
1279
|
+
var import_picocolors10 = __toESM(require_picocolors());
|
|
1280
|
+
|
|
1281
|
+
// src/build.ts
|
|
1282
|
+
var import_node_path6 = __toESM(require("path"));
|
|
1283
|
+
var import_bun_dts = require("bun-dts");
|
|
1284
|
+
init_errors();
|
|
1285
|
+
init_loaders();
|
|
1286
|
+
init_logger();
|
|
1287
|
+
|
|
1288
|
+
// src/constants/re.ts
|
|
1289
|
+
var JS_RE = /\.(js|jsx|cjs|mjs)$/;
|
|
1290
|
+
var TS_RE = /\.(ts|tsx|mts|cts)$/;
|
|
1291
|
+
var DTS_RE = /\.(d\.(ts|mts|cts))$/;
|
|
1292
|
+
var JS_TS_RE = new RegExp(`${JS_RE.source}|${TS_RE.source}`);
|
|
1293
|
+
var JS_DTS_RE = new RegExp(`${JS_RE.source}|${DTS_RE.source}`);
|
|
1294
|
+
var CSS_RE = /\.(css)$/;
|
|
1295
|
+
|
|
1296
|
+
// src/plugins/built-in/node/shims.ts
|
|
1297
|
+
function shims() {
|
|
1298
|
+
return {
|
|
1299
|
+
type: "bun",
|
|
1300
|
+
name: "shims",
|
|
1301
|
+
plugin: {
|
|
1302
|
+
name: "bunup:shims",
|
|
1303
|
+
setup(build) {
|
|
1304
|
+
const isNodeCompatibleTarget = build.config.target === "node" || build.config.target === "bun";
|
|
1305
|
+
const isEsm = build.config.format === "esm";
|
|
1306
|
+
const isCjs = build.config.format === "cjs";
|
|
1307
|
+
if (!isNodeCompatibleTarget || !isEsm && !isCjs) {
|
|
1308
|
+
return;
|
|
1309
|
+
}
|
|
1310
|
+
build.config.define = {
|
|
1311
|
+
...build.config.define,
|
|
1312
|
+
...isCjs && {
|
|
1313
|
+
"import.meta.url": "importMetaUrl"
|
|
1314
|
+
}
|
|
1315
|
+
};
|
|
1316
|
+
build.onLoad({ filter: JS_TS_RE }, async ({ path: path2 }) => {
|
|
1317
|
+
const content = await Bun.file(path2).text();
|
|
1318
|
+
let shimCode = "";
|
|
1319
|
+
if (isEsm && (/\b__dirname\b/.test(content) || /\b__filename\b/.test(content))) {
|
|
1320
|
+
shimCode = `import { fileURLToPath } from 'url';
|
|
1321
|
+
import { dirname } from 'path';
|
|
1322
|
+
|
|
1323
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
1324
|
+
const __dirname = dirname(__filename);
|
|
1325
|
+
|
|
1326
|
+
`;
|
|
1327
|
+
}
|
|
1328
|
+
if (isCjs && /\bimport\.meta\.url\b/.test(content)) {
|
|
1329
|
+
shimCode = `import { pathToFileURL } from 'url';
|
|
1330
|
+
|
|
1331
|
+
const importMetaUrl = pathToFileURL(__filename).href;
|
|
1332
|
+
|
|
1333
|
+
`;
|
|
1334
|
+
}
|
|
1335
|
+
if (!shimCode)
|
|
1336
|
+
return;
|
|
1337
|
+
const lines = content.split(`
|
|
1338
|
+
`);
|
|
1339
|
+
const firstLine = lines[0];
|
|
1340
|
+
const restLines = lines.slice(1);
|
|
1341
|
+
return {
|
|
1342
|
+
contents: [firstLine, shimCode, ...restLines].join(`
|
|
1343
|
+
`)
|
|
1344
|
+
};
|
|
1345
|
+
});
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
};
|
|
1349
|
+
}
|
|
1350
|
+
// src/plugins/built-in/productivity/exports.ts
|
|
1351
|
+
init_logger();
|
|
1352
|
+
init_utils();
|
|
1353
|
+
function exports2(options = {}) {
|
|
1354
|
+
return {
|
|
1355
|
+
type: "bunup",
|
|
1356
|
+
name: "exports",
|
|
1357
|
+
hooks: {
|
|
1358
|
+
onBuildDone: async ({ output, options: buildOptions, meta }) => {
|
|
1359
|
+
if (!meta.packageJson.path || !meta.packageJson.data) {
|
|
1360
|
+
return;
|
|
1361
|
+
}
|
|
1362
|
+
try {
|
|
1363
|
+
const { exportsField, entryPoints } = generateExportsFields(output.files);
|
|
1364
|
+
const files = Array.isArray(meta.packageJson.data.files) ? [
|
|
1365
|
+
...new Set([
|
|
1366
|
+
...meta.packageJson.data.files,
|
|
1367
|
+
buildOptions.outDir
|
|
1368
|
+
])
|
|
1369
|
+
] : [buildOptions.outDir];
|
|
1370
|
+
const mergedExports = { ...exportsField };
|
|
1371
|
+
if (options.extraExports) {
|
|
1372
|
+
for (const [key, value] of Object.entries(options.extraExports)) {
|
|
1373
|
+
if (typeof value === "string") {
|
|
1374
|
+
mergedExports[key] = value;
|
|
1375
|
+
} else {
|
|
1376
|
+
const existingExport = mergedExports[key];
|
|
1377
|
+
if (typeof existingExport === "object" && existingExport !== null) {
|
|
1378
|
+
mergedExports[key] = {
|
|
1379
|
+
...existingExport,
|
|
1380
|
+
...value
|
|
1381
|
+
};
|
|
1382
|
+
} else {
|
|
1383
|
+
mergedExports[key] = value;
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
const newPackageJson = {
|
|
1389
|
+
name: meta.packageJson.data.name,
|
|
1390
|
+
description: meta.packageJson.data.description,
|
|
1391
|
+
version: meta.packageJson.data.version,
|
|
1392
|
+
type: meta.packageJson.data.type,
|
|
1393
|
+
private: meta.packageJson.data.private,
|
|
1394
|
+
files,
|
|
1395
|
+
...entryPoints,
|
|
1396
|
+
exports: mergedExports
|
|
1397
|
+
};
|
|
1398
|
+
for (const key in meta.packageJson.data) {
|
|
1399
|
+
if (Object.prototype.hasOwnProperty.call(meta.packageJson.data, key) && !Object.prototype.hasOwnProperty.call(newPackageJson, key)) {
|
|
1400
|
+
newPackageJson[key] = meta.packageJson.data[key];
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
await Bun.write(meta.packageJson.path, JSON.stringify(newPackageJson, null, 2));
|
|
1404
|
+
logger.cli("Updated package.json with exports");
|
|
1405
|
+
} catch {
|
|
1406
|
+
logger.error("Failed to update package.json");
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
};
|
|
1411
|
+
}
|
|
1412
|
+
function generateExportsFields(files) {
|
|
1413
|
+
const exportsField = {};
|
|
1414
|
+
const entryPoints = {};
|
|
1415
|
+
const filteredFiles = filterFiles(files);
|
|
1416
|
+
for (const file of filteredFiles) {
|
|
1417
|
+
const exportType = formatToExportField(file.format, file.dts);
|
|
1418
|
+
const relativePath = `./${cleanPath(file.relativePathToRootDir)}`;
|
|
1419
|
+
const exportKey = getExportKey(cleanPath(file.relativePathToOutputDir));
|
|
1420
|
+
exportsField[exportKey] = {
|
|
1421
|
+
...exportsField[exportKey],
|
|
1422
|
+
[exportType]: relativePath
|
|
1423
|
+
};
|
|
1424
|
+
}
|
|
1425
|
+
for (const field of Object.keys(exportsField["."] ?? {})) {
|
|
1426
|
+
const entryPoint = exportFieldToEntryPoint(field);
|
|
1427
|
+
entryPoints[entryPoint] = exportsField["."][field];
|
|
1428
|
+
}
|
|
1429
|
+
return { exportsField, entryPoints };
|
|
1430
|
+
}
|
|
1431
|
+
function filterFiles(files) {
|
|
1432
|
+
return files.filter((file) => JS_DTS_RE.test(file.fullPath) && file.kind === "entry-point");
|
|
1433
|
+
}
|
|
1434
|
+
function getExportKey(relativePathToOutputDir) {
|
|
1435
|
+
const pathSegments = cleanPath(removeExtension(relativePathToOutputDir)).split("/");
|
|
1436
|
+
if (pathSegments.length === 1 && pathSegments[0].startsWith("index")) {
|
|
1437
|
+
return ".";
|
|
1438
|
+
}
|
|
1439
|
+
return `./${pathSegments.filter((p) => !p.startsWith("index")).join("/")}`;
|
|
1440
|
+
}
|
|
1441
|
+
function exportFieldToEntryPoint(exportField) {
|
|
1442
|
+
return exportField === "types" ? "types" : exportField === "require" ? "main" : "module";
|
|
1443
|
+
}
|
|
1444
|
+
function formatToExportField(format, dts) {
|
|
1445
|
+
return dts ? "types" : format === "esm" ? "import" : "require";
|
|
1446
|
+
}
|
|
1447
|
+
// src/plugins/built-in/css/inject-styles.ts
|
|
1448
|
+
var import_node_path3 = __toESM(require("path"));
|
|
1449
|
+
init_logger();
|
|
1450
|
+
|
|
1451
|
+
// src/plugins/utils.ts
|
|
1452
|
+
var import_picocolors4 = __toESM(require_picocolors());
|
|
1453
|
+
init_errors();
|
|
1454
|
+
function filterBunupBunPlugins(plugins) {
|
|
1455
|
+
if (!plugins)
|
|
1456
|
+
return [];
|
|
1457
|
+
return plugins.filter((p) => p.type === "bun");
|
|
1458
|
+
}
|
|
1459
|
+
function filterBunupPlugins(plugins) {
|
|
1460
|
+
if (!plugins)
|
|
1461
|
+
return [];
|
|
1462
|
+
return plugins.filter((p) => p.type === "bunup");
|
|
1463
|
+
}
|
|
1464
|
+
async function runPluginBuildStartHooks(bunupPlugins, options) {
|
|
1465
|
+
if (!bunupPlugins)
|
|
1466
|
+
return;
|
|
1467
|
+
for (const plugin of bunupPlugins) {
|
|
1468
|
+
if (plugin.hooks.onBuildStart) {
|
|
1469
|
+
await plugin.hooks.onBuildStart(options);
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
async function runPluginBuildDoneHooks(bunupPlugins, options, output, meta) {
|
|
1474
|
+
if (!bunupPlugins)
|
|
1475
|
+
return;
|
|
1476
|
+
for (const plugin of bunupPlugins) {
|
|
1477
|
+
if (plugin.hooks.onBuildDone) {
|
|
1478
|
+
await plugin.hooks.onBuildDone({ options, output, meta });
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
async function getPackageForPlugin(name, pluginName) {
|
|
1483
|
+
let pkg;
|
|
1484
|
+
try {
|
|
1485
|
+
pkg = await import(name);
|
|
1486
|
+
} catch {
|
|
1487
|
+
throw new BunupPluginError(`[${import_picocolors4.default.cyan(name)}] is required for the ${pluginName} plugin. Please install it with: ${import_picocolors4.default.blue(`bun add ${name} --dev`)}`);
|
|
1488
|
+
}
|
|
1489
|
+
return pkg;
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
// src/plugins/built-in/css/inject-styles.ts
|
|
1493
|
+
function injectStyles(options) {
|
|
1494
|
+
const { inject, ...transformOptions } = options ?? {};
|
|
1495
|
+
return {
|
|
1496
|
+
type: "bun",
|
|
1497
|
+
name: "inject-styles",
|
|
1498
|
+
plugin: {
|
|
1499
|
+
name: "bunup:inject-styles",
|
|
1500
|
+
async setup(build) {
|
|
1501
|
+
const lightningcss = await getPackageForPlugin("lightningcss", "inject-styles");
|
|
1502
|
+
build.onResolve({ filter: /^__inject-style$/ }, () => {
|
|
1503
|
+
return {
|
|
1504
|
+
path: "__inject-style",
|
|
1505
|
+
namespace: "__inject-style"
|
|
1506
|
+
};
|
|
1507
|
+
});
|
|
1508
|
+
build.onLoad({ filter: /^__inject-style$/, namespace: "__inject-style" }, () => {
|
|
1509
|
+
return {
|
|
1510
|
+
contents: `
|
|
1511
|
+
export default function injectStyle(css) {
|
|
1512
|
+
if (!css || typeof document === 'undefined') return
|
|
1513
|
+
|
|
1514
|
+
const head = document.head || document.getElementsByTagName('head')[0]
|
|
1515
|
+
const style = document.createElement('style')
|
|
1516
|
+
head.appendChild(style)
|
|
1517
|
+
|
|
1518
|
+
if (style.styleSheet) {
|
|
1519
|
+
style.styleSheet.cssText = css
|
|
1520
|
+
} else {
|
|
1521
|
+
style.appendChild(document.createTextNode(css))
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
`,
|
|
1525
|
+
loader: "js"
|
|
1526
|
+
};
|
|
1527
|
+
});
|
|
1528
|
+
build.onLoad({ filter: CSS_RE }, async (args) => {
|
|
1529
|
+
const source = await Bun.file(args.path).text();
|
|
1530
|
+
const { code, warnings } = lightningcss.transform({
|
|
1531
|
+
...transformOptions,
|
|
1532
|
+
filename: import_node_path3.default.basename(args.path),
|
|
1533
|
+
code: Buffer.from(source),
|
|
1534
|
+
minify: transformOptions.minify ?? (build.config.minify === true || typeof build.config.minify === "object" && build.config.minify.whitespace)
|
|
1535
|
+
});
|
|
1536
|
+
for (const warning of warnings) {
|
|
1537
|
+
logger.warn(warning.message);
|
|
1538
|
+
}
|
|
1539
|
+
const stringifiedCode = JSON.stringify(code.toString());
|
|
1540
|
+
const js = inject ? await inject(stringifiedCode, args.path) : `import injectStyle from '__inject-style';injectStyle(${stringifiedCode})`;
|
|
1541
|
+
return {
|
|
1542
|
+
contents: js,
|
|
1543
|
+
loader: "js"
|
|
1544
|
+
};
|
|
1545
|
+
});
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
};
|
|
1549
|
+
}
|
|
1550
|
+
// src/plugins/built-in/productivity/copy.ts
|
|
1551
|
+
var import_node_path4 = require("path");
|
|
1552
|
+
var import_node_path5 = require("path");
|
|
1553
|
+
init_utils();
|
|
1554
|
+
function copy(patterns, outPath) {
|
|
1555
|
+
return {
|
|
1556
|
+
type: "bunup",
|
|
1557
|
+
name: "copy",
|
|
1558
|
+
hooks: {
|
|
1559
|
+
onBuildDone: async ({ options, meta }) => {
|
|
1560
|
+
const destinationPath = outPath || options.outDir;
|
|
1561
|
+
for (const pattern of patterns) {
|
|
1562
|
+
const glob = new Bun.Glob(pattern);
|
|
1563
|
+
for await (const filePath of glob.scan({
|
|
1564
|
+
cwd: meta.rootDir,
|
|
1565
|
+
dot: true
|
|
1566
|
+
})) {
|
|
1567
|
+
const sourceFile = Bun.file(import_node_path4.join(meta.rootDir, filePath));
|
|
1568
|
+
await Bun.write(outPath && isDirectoryPath(outPath) ? import_node_path4.join(destinationPath, import_node_path5.basename(filePath)) : destinationPath, sourceFile);
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
};
|
|
1574
|
+
}
|
|
1575
|
+
// src/plugins/internal/report.ts
|
|
1576
|
+
var import_picocolors5 = __toESM(require_picocolors());
|
|
1577
|
+
init_logger();
|
|
1578
|
+
init_logger();
|
|
1579
|
+
init_utils();
|
|
1580
|
+
function report() {
|
|
1581
|
+
return {
|
|
1582
|
+
type: "bunup",
|
|
1583
|
+
name: "report",
|
|
1584
|
+
hooks: {
|
|
1585
|
+
onBuildDone: async ({ options, output }) => {
|
|
1586
|
+
if (options.watch)
|
|
1587
|
+
return;
|
|
1588
|
+
const files = await Promise.all(output.files.map(async (file) => {
|
|
1589
|
+
const name = file.relativePathToRootDir;
|
|
1590
|
+
const size = Bun.file(file.fullPath).size;
|
|
1591
|
+
const gzipSize = Bun.gzipSync(new Uint8Array(await Bun.file(file.fullPath).arrayBuffer())).length;
|
|
1592
|
+
const formattedGzipSize = formatFileSize(gzipSize);
|
|
1593
|
+
return {
|
|
1594
|
+
name,
|
|
1595
|
+
size,
|
|
1596
|
+
formattedSize: formatFileSize(size),
|
|
1597
|
+
gzipSize,
|
|
1598
|
+
formattedGzipSize
|
|
1599
|
+
};
|
|
1600
|
+
}));
|
|
1601
|
+
const totalSize = files.reduce((sum, file) => sum + file.size, 0);
|
|
1602
|
+
const formattedTotalSize = formatFileSize(totalSize);
|
|
1603
|
+
const totalGzipSize = files.reduce((sum, file) => sum + (file.gzipSize || 0), 0);
|
|
1604
|
+
const formattedTotalGzipSize = formatFileSize(totalGzipSize);
|
|
1605
|
+
const columns = [
|
|
1606
|
+
{ header: "File", align: "left", color: import_picocolors5.default.blue },
|
|
1607
|
+
{ header: "Size", align: "right", color: import_picocolors5.default.green },
|
|
1608
|
+
{
|
|
1609
|
+
header: "Gzip",
|
|
1610
|
+
align: "right",
|
|
1611
|
+
color: import_picocolors5.default.magenta
|
|
1612
|
+
}
|
|
1613
|
+
];
|
|
1614
|
+
const data = files.map((file) => {
|
|
1615
|
+
return {
|
|
1616
|
+
File: file.name,
|
|
1617
|
+
Size: file.formattedSize,
|
|
1618
|
+
Gzip: file.formattedGzipSize
|
|
1619
|
+
};
|
|
1620
|
+
});
|
|
1621
|
+
const footer = {
|
|
1622
|
+
File: "Total",
|
|
1623
|
+
Size: formattedTotalSize,
|
|
1624
|
+
Gzip: formattedTotalGzipSize
|
|
1625
|
+
};
|
|
1626
|
+
logger.space();
|
|
1627
|
+
logTable(columns, data, footer);
|
|
1628
|
+
logger.space();
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
};
|
|
1632
|
+
}
|
|
1633
|
+
// src/plugins/internal/use-client.ts
|
|
1634
|
+
function useClient() {
|
|
1635
|
+
return {
|
|
1636
|
+
type: "bunup",
|
|
1637
|
+
name: "use-client",
|
|
1638
|
+
hooks: {
|
|
1639
|
+
onBuildDone: async ({ output }) => {
|
|
1640
|
+
for (const file of output.files) {
|
|
1641
|
+
let text = await Bun.file(file.fullPath).text();
|
|
1642
|
+
const hasUseClient = text.split(`
|
|
1643
|
+
`).some((line) => line.trim().startsWith(`"use client";`));
|
|
1644
|
+
if (hasUseClient) {
|
|
1645
|
+
text = text.replaceAll(`"use client";`, "");
|
|
1646
|
+
text = `"use client";
|
|
1647
|
+
${text}`;
|
|
1648
|
+
}
|
|
1649
|
+
await Bun.write(file.fullPath, text);
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
};
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
// src/options.ts
|
|
1657
|
+
init_utils();
|
|
1658
|
+
var DEFAULT_OPTIONS = {
|
|
1659
|
+
entry: [],
|
|
1660
|
+
format: ["cjs"],
|
|
1661
|
+
outDir: "dist",
|
|
1662
|
+
target: "node",
|
|
1663
|
+
clean: true
|
|
1664
|
+
};
|
|
1665
|
+
function createBuildOptions(partialOptions) {
|
|
1666
|
+
const options = {
|
|
1667
|
+
...DEFAULT_OPTIONS,
|
|
1668
|
+
...partialOptions
|
|
1669
|
+
};
|
|
1670
|
+
return {
|
|
1671
|
+
...options,
|
|
1672
|
+
plugins: [
|
|
1673
|
+
...options.plugins?.filter((p) => p.name !== "report") ?? [],
|
|
1674
|
+
useClient(),
|
|
1675
|
+
report()
|
|
1676
|
+
]
|
|
1677
|
+
};
|
|
1678
|
+
}
|
|
1679
|
+
function getResolvedMinify(options) {
|
|
1680
|
+
const { minify, minifyWhitespace, minifyIdentifiers, minifySyntax } = options;
|
|
1681
|
+
const defaultValue = minify === true;
|
|
1682
|
+
return {
|
|
1683
|
+
whitespace: minifyWhitespace ?? defaultValue,
|
|
1684
|
+
identifiers: minifyIdentifiers ?? defaultValue,
|
|
1685
|
+
syntax: minifySyntax ?? defaultValue
|
|
1686
|
+
};
|
|
1687
|
+
}
|
|
1688
|
+
function getResolvedBytecode(bytecode, format) {
|
|
1689
|
+
return format === "cjs" ? bytecode : undefined;
|
|
1690
|
+
}
|
|
1691
|
+
function getResolvedSourcemap(sourcemap) {
|
|
1692
|
+
if (sourcemap === true) {
|
|
1693
|
+
return "inline";
|
|
1694
|
+
}
|
|
1695
|
+
return typeof sourcemap === "string" ? sourcemap : undefined;
|
|
1696
|
+
}
|
|
1697
|
+
function getResolvedDefine(define, env) {
|
|
1698
|
+
return {
|
|
1699
|
+
...typeof env === "object" && Object.keys(env).reduce((acc, key) => {
|
|
1700
|
+
const value = JSON.stringify(env[key]);
|
|
1701
|
+
acc[`process.env.${key}`] = value;
|
|
1702
|
+
acc[`import.meta.env.${key}`] = value;
|
|
1703
|
+
return acc;
|
|
1704
|
+
}, {}),
|
|
1705
|
+
...define
|
|
1706
|
+
};
|
|
1707
|
+
}
|
|
1708
|
+
function getResolvedSplitting(splitting, format) {
|
|
1709
|
+
return splitting === undefined ? format === "esm" : splitting;
|
|
1710
|
+
}
|
|
1711
|
+
var DEFAULT_ENTRY_NAMING = "[dir]/[name].[ext]";
|
|
1712
|
+
function getResolvedNaming(naming, fmt, packageType) {
|
|
1713
|
+
const resolvedNaming = typeof naming === "object" ? { entry: DEFAULT_ENTRY_NAMING, ...naming } : naming ?? DEFAULT_ENTRY_NAMING;
|
|
1714
|
+
const replaceExt = (pattern) => pattern.replace(".[ext]", getDefaultJsOutputExtension(fmt, packageType));
|
|
1715
|
+
if (typeof resolvedNaming === "string") {
|
|
1716
|
+
return replaceExt(resolvedNaming);
|
|
1717
|
+
}
|
|
1718
|
+
return {
|
|
1719
|
+
...resolvedNaming,
|
|
1720
|
+
entry: replaceExt(resolvedNaming.entry)
|
|
1721
|
+
};
|
|
1722
|
+
}
|
|
1723
|
+
function getResolvedEnv(env) {
|
|
1724
|
+
return typeof env === "string" ? env : undefined;
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
// src/helpers/external.ts
|
|
1728
|
+
init_utils();
|
|
1729
|
+
function getPackageDepsPatterns(packageJson) {
|
|
1730
|
+
return getPackageDeps(packageJson).map((dep) => new RegExp(`^${dep}($|\\/|\\\\)`));
|
|
1731
|
+
}
|
|
1732
|
+
function matchesPattern(path4, pattern) {
|
|
1733
|
+
return typeof pattern === "string" ? pattern === path4 : pattern.test(path4);
|
|
1734
|
+
}
|
|
1735
|
+
function isExternal(path4, options, packageJson) {
|
|
1736
|
+
const packageDepsPatterns = getPackageDepsPatterns(packageJson);
|
|
1737
|
+
const matchesExternalPattern = packageDepsPatterns.some((pattern) => pattern.test(path4)) || options.external?.some((pattern) => matchesPattern(path4, pattern));
|
|
1738
|
+
const isExcludedFromExternal = options.noExternal?.some((pattern) => matchesPattern(path4, pattern));
|
|
1739
|
+
return matchesExternalPattern && !isExcludedFromExternal;
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
// src/plugins/internal/external-option.ts
|
|
1743
|
+
function externalOptionPlugin(options, packageJson) {
|
|
1744
|
+
return {
|
|
1745
|
+
name: "bunup:external-option-plugin",
|
|
1746
|
+
setup(build) {
|
|
1747
|
+
build.onResolve({ filter: /.*/ }, (args) => {
|
|
1748
|
+
const importPath = args.path;
|
|
1749
|
+
if (isExternal(importPath, options, packageJson)) {
|
|
1750
|
+
return {
|
|
1751
|
+
path: importPath,
|
|
1752
|
+
external: true
|
|
1753
|
+
};
|
|
1754
|
+
}
|
|
1755
|
+
return null;
|
|
1756
|
+
});
|
|
1757
|
+
}
|
|
1758
|
+
};
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
// src/build.ts
|
|
1762
|
+
init_utils();
|
|
1763
|
+
async function build(partialOptions, rootDir = process.cwd()) {
|
|
1764
|
+
const buildOutput = {
|
|
1765
|
+
files: []
|
|
1766
|
+
};
|
|
1767
|
+
const options = createBuildOptions(partialOptions);
|
|
1768
|
+
if (!options.entry || options.entry.length === 0 || !options.outDir) {
|
|
1769
|
+
throw new BunupBuildError("Nothing to build. Please make sure you have provided a proper bunup configuration or cli arguments.");
|
|
1770
|
+
}
|
|
1771
|
+
if (options.clean) {
|
|
1772
|
+
cleanOutDir(rootDir, options.outDir);
|
|
1773
|
+
}
|
|
1774
|
+
setSilent(options.silent);
|
|
1775
|
+
const packageJson = await loadPackageJson(rootDir);
|
|
1776
|
+
if (packageJson.data && packageJson.path) {
|
|
1777
|
+
logger.cli(`Using ${getShortFilePath(packageJson.path, 2)}`, {
|
|
1778
|
+
muted: true,
|
|
1779
|
+
identifier: options.name,
|
|
1780
|
+
once: `${packageJson.path}:${options.name}`
|
|
1781
|
+
});
|
|
1782
|
+
}
|
|
1783
|
+
const bunupPlugins = filterBunupPlugins(options.plugins);
|
|
1784
|
+
await runPluginBuildStartHooks(bunupPlugins, options);
|
|
1785
|
+
const packageType = packageJson.data?.type;
|
|
1786
|
+
const plugins = [
|
|
1787
|
+
externalOptionPlugin(options, packageJson.data),
|
|
1788
|
+
...filterBunupBunPlugins(options.plugins).map((p) => p.plugin)
|
|
1789
|
+
];
|
|
1790
|
+
if (options.dts) {
|
|
1791
|
+
const { resolve, entry, splitting } = typeof options.dts === "object" ? options.dts : {};
|
|
1792
|
+
let entrypoints2;
|
|
1793
|
+
if (entry) {
|
|
1794
|
+
entrypoints2 = await getFilesFromGlobs(ensureArray(entry), rootDir);
|
|
1795
|
+
}
|
|
1796
|
+
if (Array.isArray(entrypoints2) && !entrypoints2.length) {
|
|
1797
|
+
throw new BunupDTSBuildError("The dts entrypoints you provided do not exist. Please make sure the entrypoints point to valid files.");
|
|
1798
|
+
}
|
|
1799
|
+
plugins.push(import_bun_dts.dts({
|
|
1800
|
+
resolve,
|
|
1801
|
+
preferredTsConfigPath: options.preferredTsconfigPath,
|
|
1802
|
+
entry: entrypoints2,
|
|
1803
|
+
cwd: rootDir,
|
|
1804
|
+
splitting,
|
|
1805
|
+
onDeclarationsGenerated({ results, buildConfig }) {
|
|
1806
|
+
for (const result of results) {
|
|
1807
|
+
logger.progress("DTS", `${options.outDir}/${result.outputPath}`, {
|
|
1808
|
+
identifier: options.name
|
|
1809
|
+
});
|
|
1810
|
+
const fullPath = import_node_path6.default.join(rootDir, options.outDir, result.outputPath);
|
|
1811
|
+
if (buildConfig.format) {
|
|
1812
|
+
buildOutput.files.push({
|
|
1813
|
+
fullPath,
|
|
1814
|
+
relativePathToRootDir: getRelativePathToRootDir(fullPath, rootDir),
|
|
1815
|
+
relativePathToOutputDir: result.outputPath,
|
|
1816
|
+
dts: true,
|
|
1817
|
+
format: buildConfig.format,
|
|
1818
|
+
kind: result.kind
|
|
1819
|
+
});
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
}));
|
|
1824
|
+
}
|
|
1825
|
+
const entrypoints = await getFilesFromGlobs(ensureArray(options.entry), rootDir);
|
|
1826
|
+
if (!entrypoints.length) {
|
|
1827
|
+
throw new BunupBuildError("The entrypoints you provided do not exist. Please make sure the entrypoints point to valid files.");
|
|
1828
|
+
}
|
|
1829
|
+
const buildPromises = options.format.flatMap(async (fmt) => {
|
|
1830
|
+
const result = await Bun.build({
|
|
1831
|
+
entrypoints: entrypoints.map((file) => `${rootDir}/${file}`),
|
|
1832
|
+
format: fmt,
|
|
1833
|
+
naming: getResolvedNaming(options.naming, fmt, packageType),
|
|
1834
|
+
splitting: getResolvedSplitting(options.splitting, fmt),
|
|
1835
|
+
bytecode: getResolvedBytecode(options.bytecode, fmt),
|
|
1836
|
+
define: getResolvedDefine(options.define, options.env),
|
|
1837
|
+
minify: getResolvedMinify(options),
|
|
1838
|
+
outdir: `${rootDir}/${options.outDir}`,
|
|
1839
|
+
target: options.target,
|
|
1840
|
+
sourcemap: getResolvedSourcemap(options.sourcemap),
|
|
1841
|
+
loader: options.loader,
|
|
1842
|
+
drop: options.drop,
|
|
1843
|
+
banner: options.banner,
|
|
1844
|
+
footer: options.footer,
|
|
1845
|
+
publicPath: options.publicPath,
|
|
1846
|
+
env: getResolvedEnv(options.env),
|
|
1847
|
+
plugins,
|
|
1848
|
+
throw: false
|
|
1849
|
+
});
|
|
1850
|
+
for (const log of result.logs) {
|
|
1851
|
+
if (log.level === "error") {
|
|
1852
|
+
throw new BunupBuildError(log.message);
|
|
1853
|
+
}
|
|
1854
|
+
if (log.level === "warning")
|
|
1855
|
+
logger.warn(log.message);
|
|
1856
|
+
else if (log.level === "info")
|
|
1857
|
+
logger.info(log.message);
|
|
1858
|
+
}
|
|
1859
|
+
for (const file of result.outputs) {
|
|
1860
|
+
const relativePathToRootDir = getRelativePathToRootDir(file.path, rootDir);
|
|
1861
|
+
if (file.kind === "entry-point") {
|
|
1862
|
+
logger.progress(fmt.toUpperCase(), relativePathToRootDir, {
|
|
1863
|
+
identifier: options.name
|
|
1864
|
+
});
|
|
1865
|
+
}
|
|
1866
|
+
buildOutput.files.push({
|
|
1867
|
+
fullPath: file.path,
|
|
1868
|
+
relativePathToRootDir,
|
|
1869
|
+
relativePathToOutputDir: getRelativePathToOutputDir(relativePathToRootDir, options.outDir),
|
|
1870
|
+
dts: false,
|
|
1871
|
+
format: fmt,
|
|
1872
|
+
kind: file.kind
|
|
1873
|
+
});
|
|
1874
|
+
}
|
|
1875
|
+
});
|
|
1876
|
+
await Promise.all(buildPromises);
|
|
1877
|
+
await runPluginBuildDoneHooks(bunupPlugins, options, buildOutput, {
|
|
1878
|
+
packageJson,
|
|
1879
|
+
rootDir
|
|
1880
|
+
});
|
|
1881
|
+
if (options.onSuccess) {
|
|
1882
|
+
await options.onSuccess(options);
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1885
|
+
function getRelativePathToRootDir(filePath, rootDir) {
|
|
1886
|
+
return cleanPath(filePath).replace(`${cleanPath(rootDir)}/`, "");
|
|
1887
|
+
}
|
|
1888
|
+
function getRelativePathToOutputDir(relativePathToRootDir, outDir) {
|
|
1889
|
+
return cleanPath(relativePathToRootDir).replace(`${cleanPath(outDir)}/`, "");
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
// src/cli/index.ts
|
|
1893
|
+
init_loaders();
|
|
1894
|
+
init_utils();
|
|
1895
|
+
|
|
1896
|
+
// src/watch.ts
|
|
1897
|
+
var import_node_path7 = __toESM(require("path"));
|
|
1898
|
+
var import_picocolors6 = __toESM(require_picocolors());
|
|
1899
|
+
init_errors();
|
|
1900
|
+
init_logger();
|
|
1901
|
+
init_utils();
|
|
1902
|
+
async function watch(partialOptions, rootDir) {
|
|
1903
|
+
const watchPaths = new Set;
|
|
1904
|
+
const options = createBuildOptions(partialOptions);
|
|
1905
|
+
const uniqueEntries = new Set(options.entry);
|
|
1906
|
+
for (const entry of uniqueEntries) {
|
|
1907
|
+
const entryPath = import_node_path7.default.resolve(rootDir, entry);
|
|
1908
|
+
const parentDir = import_node_path7.default.dirname(entryPath);
|
|
1909
|
+
watchPaths.add(parentDir);
|
|
1910
|
+
}
|
|
1911
|
+
const chokidar = await import("chokidar");
|
|
1912
|
+
const watcher = chokidar.watch(Array.from(watchPaths), {
|
|
1913
|
+
ignoreInitial: true,
|
|
1914
|
+
ignorePermissionErrors: true,
|
|
1915
|
+
ignored: [
|
|
1916
|
+
/[\\/]\.git[\\/]/,
|
|
1917
|
+
/[\\/]node_modules[\\/]/,
|
|
1918
|
+
import_node_path7.default.join(rootDir, options.outDir)
|
|
1919
|
+
]
|
|
1920
|
+
});
|
|
1921
|
+
let isRebuilding = false;
|
|
1922
|
+
const triggerRebuild = async (initial = false) => {
|
|
1923
|
+
if (isRebuilding) {
|
|
1924
|
+
return;
|
|
1925
|
+
}
|
|
1926
|
+
isRebuilding = true;
|
|
1927
|
+
try {
|
|
1928
|
+
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
1929
|
+
const start = performance.now();
|
|
1930
|
+
await build(options, rootDir);
|
|
1931
|
+
if (!initial) {
|
|
1932
|
+
logger.cli(`\uD83D\uDCE6 Rebuild finished in ${import_picocolors6.default.green(formatTime(performance.now() - start))}`);
|
|
1933
|
+
}
|
|
1934
|
+
} catch (error) {
|
|
1935
|
+
handleError(error);
|
|
1936
|
+
} finally {
|
|
1937
|
+
isRebuilding = false;
|
|
1938
|
+
}
|
|
1939
|
+
};
|
|
1940
|
+
watcher.on("change", (filePath) => {
|
|
1941
|
+
const changedFile = import_node_path7.default.relative(rootDir, filePath);
|
|
1942
|
+
logger.cli(`File changed: ${changedFile}`, {
|
|
1943
|
+
muted: true,
|
|
1944
|
+
once: changedFile
|
|
1945
|
+
});
|
|
1946
|
+
triggerRebuild();
|
|
1947
|
+
});
|
|
1948
|
+
watcher.on("error", (error) => {
|
|
1949
|
+
throw new BunupWatchError(`Watcher error: ${parseErrorMessage(error)}`);
|
|
1950
|
+
});
|
|
1951
|
+
await triggerRebuild(true);
|
|
1952
|
+
}
|
|
1953
|
+
|
|
1954
|
+
// src/cli/index.ts
|
|
1955
|
+
async function main(args = Bun.argv.slice(2)) {
|
|
1956
|
+
const cliOptions = parseCliOptions(args);
|
|
1957
|
+
if (cliOptions.new) {
|
|
1958
|
+
const { newProject: newProject2 } = await Promise.resolve().then(() => (init_new(), exports_new));
|
|
1959
|
+
await newProject2();
|
|
1960
|
+
return;
|
|
1961
|
+
}
|
|
1962
|
+
if (cliOptions.init) {
|
|
1963
|
+
const { init: init2 } = await Promise.resolve().then(() => (init_init(), exports_init));
|
|
1964
|
+
await init2();
|
|
1965
|
+
return;
|
|
1966
|
+
}
|
|
1967
|
+
setSilent(cliOptions.silent);
|
|
1968
|
+
const cwd = process.cwd();
|
|
1969
|
+
const { config, filepath } = await import_coffi2.loadConfig({
|
|
1970
|
+
name: "bunup.config",
|
|
1971
|
+
extensions: [".ts", ".js", ".mjs", ".cjs"],
|
|
1972
|
+
maxDepth: 1,
|
|
1973
|
+
preferredPath: cliOptions.config,
|
|
1974
|
+
packageJsonProperty: "bunup"
|
|
1975
|
+
});
|
|
1976
|
+
const configsToProcess = !config ? [{ rootDir: cwd, options: cliOptions }] : await processLoadedConfigs(config, cwd, cliOptions.filter);
|
|
1977
|
+
logger.cli(`Using bunup v${version} and bun v${Bun.version}`, {
|
|
1978
|
+
muted: true
|
|
1979
|
+
});
|
|
1980
|
+
if (filepath) {
|
|
1981
|
+
logger.cli(`Using ${getShortFilePath(filepath, 2)}`, {
|
|
1982
|
+
muted: true
|
|
1983
|
+
});
|
|
1984
|
+
}
|
|
1985
|
+
const startTime = performance.now();
|
|
1986
|
+
logger.cli("Build started");
|
|
1987
|
+
await Promise.all(configsToProcess.flatMap(({ options, rootDir }) => {
|
|
1988
|
+
const optionsArray = ensureArray(options);
|
|
1989
|
+
return optionsArray.map(async (o) => {
|
|
1990
|
+
const partialOptions = {
|
|
1991
|
+
...o,
|
|
1992
|
+
...removeCliOnlyOptions(cliOptions)
|
|
1993
|
+
};
|
|
1994
|
+
if (partialOptions.watch) {
|
|
1995
|
+
await watch(partialOptions, rootDir);
|
|
1996
|
+
} else {
|
|
1997
|
+
await build(partialOptions, rootDir);
|
|
1998
|
+
}
|
|
1999
|
+
});
|
|
2000
|
+
}));
|
|
2001
|
+
const buildTimeMs = performance.now() - startTime;
|
|
2002
|
+
const timeDisplay = formatTime(buildTimeMs);
|
|
2003
|
+
logger.cli(`\u26A1\uFE0F Build completed in ${import_picocolors10.default.green(timeDisplay)}`);
|
|
2004
|
+
if (cliOptions.watch) {
|
|
2005
|
+
logger.cli("\uD83D\uDC40 Watching for file changes");
|
|
2006
|
+
}
|
|
2007
|
+
if (cliOptions.onSuccess) {
|
|
2008
|
+
logger.cli(`Running command: ${cliOptions.onSuccess}`, {
|
|
2009
|
+
muted: true
|
|
2010
|
+
});
|
|
2011
|
+
await import_tinyexec2.exec(cliOptions.onSuccess, [], {
|
|
2012
|
+
nodeOptions: { shell: true, stdio: "inherit" }
|
|
2013
|
+
});
|
|
2014
|
+
}
|
|
2015
|
+
if (!cliOptions.watch) {
|
|
2016
|
+
process.exit(process.exitCode ?? 0);
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
function removeCliOnlyOptions(options) {
|
|
2020
|
+
return {
|
|
2021
|
+
...options,
|
|
2022
|
+
onSuccess: undefined,
|
|
2023
|
+
config: undefined,
|
|
2024
|
+
filter: undefined,
|
|
2025
|
+
new: undefined,
|
|
2026
|
+
init: undefined
|
|
2027
|
+
};
|
|
2028
|
+
}
|
|
2029
|
+
main().catch((error) => handleErrorAndExit(error));
|
|
2030
|
+
})
|