bunup 0.9.1 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/cli/index.js +12 -37
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -4
- package/dist/plugins.d.ts +1 -1
- package/dist/plugins.js +2 -4
- package/dist/shared/{chunk-f8vey9gb.js → chunk-7vsq500x.js} +87 -19
- package/dist/shared/{chunk-25dcyfg9.d.ts → chunk-wpey1xte.d.ts} +47 -6
- package/dist/shared/{chunk-sfjfqxjy.js → chunk-yrc9t3ye.js} +62 -13
- package/package.json +5 -7
- package/dist/shared/chunk-295440tx.js +0 -30
- package/dist/shared/chunk-b17s55p9.js +0 -25
- package/dist/shared/chunk-g6c05fxa.js +0 -45
- package/dist/shared/chunk-j0x1xdhb.js +0 -156
- package/dist/shared/chunk-s6wnc2s1.js +0 -341
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
<!-- markdownlint-disable-next-line no-alt-text -->
|
|
8
8
|
|
|
9
|
+
|
|
9
10
|

|
|
10
11
|
|
|
11
12
|

|
|
@@ -38,3 +39,10 @@ To get started, visit the [documentation](https://bunup.dev).
|
|
|
38
39
|
For guidelines on contributing, please read the [contributing guide](../../CONTRIBUTING.md).
|
|
39
40
|
|
|
40
41
|
We welcome contributions from the community to enhance Bunup's capabilities and make it even more powerful.
|
|
42
|
+
|
|
43
|
+

|
|
44
|
+
|
|
45
|
+
<div align="center">
|
|
46
|
+
|
|
47
|
+

|
|
48
|
+
</div>
|
package/dist/cli/index.js
CHANGED
|
@@ -2,12 +2,9 @@
|
|
|
2
2
|
// @bun
|
|
3
3
|
import {
|
|
4
4
|
build,
|
|
5
|
-
createBuildOptions
|
|
6
|
-
} from "../shared/chunk-f8vey9gb.js";
|
|
7
|
-
import"../shared/chunk-g6c05fxa.js";
|
|
8
|
-
import {
|
|
5
|
+
createBuildOptions,
|
|
9
6
|
processLoadedConfigs
|
|
10
|
-
} from "../shared/chunk-
|
|
7
|
+
} from "../shared/chunk-7vsq500x.js";
|
|
11
8
|
import {
|
|
12
9
|
BunupCLIError,
|
|
13
10
|
BunupWatchError,
|
|
@@ -21,14 +18,13 @@ import {
|
|
|
21
18
|
logger,
|
|
22
19
|
parseErrorMessage,
|
|
23
20
|
setSilent
|
|
24
|
-
} from "../shared/chunk-
|
|
21
|
+
} from "../shared/chunk-yrc9t3ye.js";
|
|
25
22
|
|
|
26
23
|
// src/cli/index.ts
|
|
27
24
|
import { loadConfig } from "coffi";
|
|
28
25
|
import pc3 from "picocolors";
|
|
29
|
-
import { exec } from "tinyexec";
|
|
30
26
|
// package.json
|
|
31
|
-
var version = "0.9.
|
|
27
|
+
var version = "0.9.3";
|
|
32
28
|
|
|
33
29
|
// src/watch.ts
|
|
34
30
|
import path from "path";
|
|
@@ -325,13 +321,6 @@ var OPTION_DEFINITIONS = {
|
|
|
325
321
|
type: "string",
|
|
326
322
|
category: "build"
|
|
327
323
|
},
|
|
328
|
-
onSuccess: {
|
|
329
|
-
flags: ["onSuccess"],
|
|
330
|
-
handler: handlers.string("onSuccess"),
|
|
331
|
-
description: "Command to execute after a successful build",
|
|
332
|
-
type: "string",
|
|
333
|
-
category: "development"
|
|
334
|
-
},
|
|
335
324
|
filter: {
|
|
336
325
|
flags: ["filter"],
|
|
337
326
|
handler: handlers.array("filter"),
|
|
@@ -367,6 +356,13 @@ var OPTION_DEFINITIONS = {
|
|
|
367
356
|
type: "string|boolean",
|
|
368
357
|
category: "development"
|
|
369
358
|
},
|
|
359
|
+
onSuccess: {
|
|
360
|
+
flags: ["onSuccess"],
|
|
361
|
+
handler: handlers.string("onSuccess"),
|
|
362
|
+
description: "Command to run after the build process completes",
|
|
363
|
+
type: "string",
|
|
364
|
+
category: "utility"
|
|
365
|
+
},
|
|
370
366
|
help: {
|
|
371
367
|
flags: ["h", "help"],
|
|
372
368
|
handler: handlers.showHelp,
|
|
@@ -481,16 +477,6 @@ var parseCliOptions = (argv) => {
|
|
|
481
477
|
// src/cli/index.ts
|
|
482
478
|
async function main(args = Bun.argv.slice(2)) {
|
|
483
479
|
const cliOptions = parseCliOptions(args);
|
|
484
|
-
if (cliOptions.new) {
|
|
485
|
-
const { newProject } = await import("../shared/chunk-j0x1xdhb.js");
|
|
486
|
-
await newProject();
|
|
487
|
-
return;
|
|
488
|
-
}
|
|
489
|
-
if (cliOptions.init) {
|
|
490
|
-
const { init } = await import("../shared/chunk-s6wnc2s1.js");
|
|
491
|
-
await init();
|
|
492
|
-
return;
|
|
493
|
-
}
|
|
494
480
|
setSilent(cliOptions.silent);
|
|
495
481
|
const cwd = process.cwd();
|
|
496
482
|
const { config, filepath } = await loadConfig({
|
|
@@ -534,14 +520,6 @@ async function main(args = Bun.argv.slice(2)) {
|
|
|
534
520
|
verticalSpace: true
|
|
535
521
|
});
|
|
536
522
|
}
|
|
537
|
-
if (cliOptions.onSuccess) {
|
|
538
|
-
logger.info(`Running command: ${cliOptions.onSuccess}`, {
|
|
539
|
-
muted: true
|
|
540
|
-
});
|
|
541
|
-
await exec(cliOptions.onSuccess, [], {
|
|
542
|
-
nodeOptions: { shell: true, stdio: "inherit" }
|
|
543
|
-
});
|
|
544
|
-
}
|
|
545
523
|
if (!cliOptions.watch) {
|
|
546
524
|
process.exit(process.exitCode ?? 0);
|
|
547
525
|
}
|
|
@@ -549,11 +527,8 @@ async function main(args = Bun.argv.slice(2)) {
|
|
|
549
527
|
function removeCliOnlyOptions(options) {
|
|
550
528
|
return {
|
|
551
529
|
...options,
|
|
552
|
-
onSuccess: undefined,
|
|
553
530
|
config: undefined,
|
|
554
|
-
filter: undefined
|
|
555
|
-
new: undefined,
|
|
556
|
-
init: undefined
|
|
531
|
+
filter: undefined
|
|
557
532
|
};
|
|
558
533
|
}
|
|
559
534
|
main().catch((error) => handleErrorAndExit(error));
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Arrayable, BuildOptions, DefineConfigItem, DefineWorkspaceItem, Plugin, WithOptional } from "./shared/chunk-
|
|
1
|
+
import { Arrayable, BuildOptions, DefineConfigItem, DefineWorkspaceItem, Plugin, WithOptional } from "./shared/chunk-wpey1xte";
|
|
2
2
|
declare function build(partialOptions: Partial<BuildOptions>, rootDir?: string): Promise<void>;
|
|
3
3
|
declare function defineConfig(options: Arrayable<DefineConfigItem>): Arrayable<DefineConfigItem>;
|
|
4
4
|
declare function defineWorkspace(options: WithOptional<DefineWorkspaceItem, "config">[], sharedOptions?: DefineConfigItem): DefineWorkspaceItem[];
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
build
|
|
4
|
-
} from "./shared/chunk-
|
|
5
|
-
import"./shared/chunk-
|
|
6
|
-
import"./shared/chunk-295440tx.js";
|
|
7
|
-
import"./shared/chunk-sfjfqxjy.js";
|
|
4
|
+
} from "./shared/chunk-7vsq500x.js";
|
|
5
|
+
import"./shared/chunk-yrc9t3ye.js";
|
|
8
6
|
// src/define.ts
|
|
9
7
|
function defineConfig(options) {
|
|
10
8
|
return options;
|
package/dist/plugins.d.ts
CHANGED
package/dist/plugins.js
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import {
|
|
3
|
-
getPackageForPlugin
|
|
4
|
-
} from "./shared/chunk-g6c05fxa.js";
|
|
5
2
|
import {
|
|
6
3
|
CSS_RE,
|
|
7
4
|
JS_DTS_RE,
|
|
8
5
|
JS_TS_RE,
|
|
9
6
|
cleanPath,
|
|
10
7
|
formatListWithAnd,
|
|
8
|
+
getPackageForPlugin,
|
|
11
9
|
isDirectoryPath,
|
|
12
10
|
logger
|
|
13
|
-
} from "./shared/chunk-
|
|
11
|
+
} from "./shared/chunk-yrc9t3ye.js";
|
|
14
12
|
|
|
15
13
|
// src/plugins/built-in/copy.ts
|
|
16
14
|
import { basename, join } from "path";
|
|
@@ -1,18 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
filterBunupBunPlugins,
|
|
3
|
-
filterBunupPlugins,
|
|
4
|
-
runPluginBuildDoneHooks,
|
|
5
|
-
runPluginBuildStartHooks
|
|
6
|
-
} from "./chunk-g6c05fxa.js";
|
|
7
|
-
import {
|
|
8
|
-
loadPackageJson
|
|
9
|
-
} from "./chunk-295440tx.js";
|
|
10
1
|
import {
|
|
11
2
|
BunupBuildError,
|
|
12
3
|
BunupDTSBuildError,
|
|
13
4
|
cleanOutDir,
|
|
14
5
|
cleanPath,
|
|
15
6
|
ensureArray,
|
|
7
|
+
filterBunupBunPlugins,
|
|
8
|
+
filterBunupPlugins,
|
|
16
9
|
formatFileSize,
|
|
17
10
|
getDefaultDtsExtention,
|
|
18
11
|
getDefaultOutputExtension,
|
|
@@ -23,15 +16,85 @@ import {
|
|
|
23
16
|
logTable,
|
|
24
17
|
logger,
|
|
25
18
|
parseErrorMessage,
|
|
19
|
+
runPluginBuildDoneHooks,
|
|
20
|
+
runPluginBuildStartHooks,
|
|
26
21
|
setSilent,
|
|
27
22
|
silent
|
|
28
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-yrc9t3ye.js";
|
|
29
24
|
|
|
30
|
-
// src/
|
|
25
|
+
// src/loaders.ts
|
|
31
26
|
import path from "path";
|
|
27
|
+
import { loadConfig } from "coffi";
|
|
28
|
+
async function processLoadedConfigs(config, cwd, filter) {
|
|
29
|
+
return Array.isArray(config) && "root" in config[0] ? config.filter((c) => filter ? filter.includes(c.name) : true).map((c) => ({
|
|
30
|
+
rootDir: path.resolve(cwd, c.root),
|
|
31
|
+
options: addField(c.config, "name", c.name)
|
|
32
|
+
})) : [
|
|
33
|
+
{
|
|
34
|
+
rootDir: cwd,
|
|
35
|
+
options: config
|
|
36
|
+
}
|
|
37
|
+
];
|
|
38
|
+
}
|
|
39
|
+
function addField(objectOrArray, field, value) {
|
|
40
|
+
return Array.isArray(objectOrArray) ? objectOrArray.map((o) => ({ ...o, [field]: value })) : { ...objectOrArray, [field]: value };
|
|
41
|
+
}
|
|
42
|
+
async function loadPackageJson(cwd = process.cwd()) {
|
|
43
|
+
const { config, filepath } = await loadConfig({
|
|
44
|
+
name: "package",
|
|
45
|
+
cwd,
|
|
46
|
+
extensions: [".json"]
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
data: config,
|
|
50
|
+
path: filepath
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// src/build.ts
|
|
55
|
+
import path2 from "path";
|
|
32
56
|
import pc2 from "picocolors";
|
|
33
57
|
import { generateDts, logIsolatedDeclarationErrors } from "typeroll";
|
|
34
58
|
|
|
59
|
+
// src/helpers/on-success.ts
|
|
60
|
+
import { exec } from "tinyexec";
|
|
61
|
+
import treeKill from "tree-kill";
|
|
62
|
+
async function executeOnSuccess(onSuccess, options, signal) {
|
|
63
|
+
if (typeof onSuccess === "function") {
|
|
64
|
+
const result = await onSuccess(options);
|
|
65
|
+
if (typeof result === "function") {
|
|
66
|
+
signal.addEventListener("abort", () => {
|
|
67
|
+
result();
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
const command = typeof onSuccess === "string" ? onSuccess : onSuccess.cmd;
|
|
72
|
+
const spawnOptions = typeof onSuccess === "object" && "options" in onSuccess ? onSuccess.options : {};
|
|
73
|
+
logger.info(`Running command: ${command}`, {
|
|
74
|
+
muted: true
|
|
75
|
+
});
|
|
76
|
+
const proc = exec(command, [], {
|
|
77
|
+
timeout: spawnOptions?.timeout,
|
|
78
|
+
nodeOptions: {
|
|
79
|
+
shell: true,
|
|
80
|
+
stdio: "inherit",
|
|
81
|
+
env: spawnOptions?.env,
|
|
82
|
+
cwd: spawnOptions?.cwd
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
proc.then(({ exitCode }) => {
|
|
86
|
+
if (exitCode) {
|
|
87
|
+
process.exitCode = exitCode;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
signal.addEventListener("abort", () => {
|
|
91
|
+
if (typeof proc.pid === "number") {
|
|
92
|
+
treeKill(proc.pid, spawnOptions?.killSignal ?? "SIGTERM");
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
35
98
|
// src/plugins/internal/report.ts
|
|
36
99
|
import pc from "picocolors";
|
|
37
100
|
function report() {
|
|
@@ -187,13 +250,13 @@ function getResolvedEnv(env) {
|
|
|
187
250
|
function getPackageDepsPatterns(packageJson) {
|
|
188
251
|
return getPackageDeps(packageJson).map((dep) => new RegExp(`^${dep}($|\\/|\\\\)`));
|
|
189
252
|
}
|
|
190
|
-
function matchesPattern(
|
|
191
|
-
return typeof pattern === "string" ? pattern ===
|
|
253
|
+
function matchesPattern(path2, pattern) {
|
|
254
|
+
return typeof pattern === "string" ? pattern === path2 : pattern.test(path2);
|
|
192
255
|
}
|
|
193
|
-
function isExternal(
|
|
256
|
+
function isExternal(path2, options, packageJson) {
|
|
194
257
|
const packageDepsPatterns = getPackageDepsPatterns(packageJson);
|
|
195
|
-
const matchesExternalPattern = packageDepsPatterns.some((pattern) => pattern.test(
|
|
196
|
-
const isExcludedFromExternal = options.noExternal?.some((pattern) => matchesPattern(
|
|
258
|
+
const matchesExternalPattern = packageDepsPatterns.some((pattern) => pattern.test(path2)) || options.external?.some((pattern) => matchesPattern(path2, pattern));
|
|
259
|
+
const isExcludedFromExternal = options.noExternal?.some((pattern) => matchesPattern(path2, pattern));
|
|
197
260
|
return matchesExternalPattern && !isExcludedFromExternal;
|
|
198
261
|
}
|
|
199
262
|
|
|
@@ -217,7 +280,12 @@ function externalOptionPlugin(options, packageJson) {
|
|
|
217
280
|
}
|
|
218
281
|
|
|
219
282
|
// src/build.ts
|
|
283
|
+
var ac = null;
|
|
220
284
|
async function build(partialOptions, rootDir = process.cwd()) {
|
|
285
|
+
if (ac) {
|
|
286
|
+
ac.abort();
|
|
287
|
+
}
|
|
288
|
+
ac = new AbortController;
|
|
221
289
|
const buildOutput = {
|
|
222
290
|
files: []
|
|
223
291
|
};
|
|
@@ -329,7 +397,7 @@ async function build(partialOptions, rootDir = process.cwd()) {
|
|
|
329
397
|
identifier: options.name
|
|
330
398
|
});
|
|
331
399
|
}
|
|
332
|
-
const fullPath =
|
|
400
|
+
const fullPath = path2.join(rootDir, relativePathToRootDir);
|
|
333
401
|
await Bun.write(fullPath, file.dts);
|
|
334
402
|
buildOutput.files.push({
|
|
335
403
|
fullPath,
|
|
@@ -351,7 +419,7 @@ async function build(partialOptions, rootDir = process.cwd()) {
|
|
|
351
419
|
rootDir
|
|
352
420
|
});
|
|
353
421
|
if (options.onSuccess) {
|
|
354
|
-
await options.onSuccess
|
|
422
|
+
await executeOnSuccess(options.onSuccess, options, ac.signal);
|
|
355
423
|
}
|
|
356
424
|
}
|
|
357
425
|
function getRelativePathToRootDir(filePath, rootDir) {
|
|
@@ -361,4 +429,4 @@ function getRelativePathToOutputDir(relativePathToRootDir, outDir) {
|
|
|
361
429
|
return cleanPath(relativePathToRootDir).replace(`${cleanPath(outDir)}/`, "");
|
|
362
430
|
}
|
|
363
431
|
|
|
364
|
-
export { createBuildOptions, build };
|
|
432
|
+
export { processLoadedConfigs, createBuildOptions, build };
|
|
@@ -101,6 +101,35 @@ type Format = "esm" | "cjs" | "iife";
|
|
|
101
101
|
type Target = "bun" | "node" | "browser";
|
|
102
102
|
type External = (string | RegExp)[];
|
|
103
103
|
type Env = "inline" | "disable" | `${string}*` | Record<string, string>;
|
|
104
|
+
type OnSuccess = ((options: Partial<BuildOptions>) => MaybePromise<void> | (() => void)) | string | {
|
|
105
|
+
/**
|
|
106
|
+
* The shell command to execute after a successful build
|
|
107
|
+
*/
|
|
108
|
+
cmd: string
|
|
109
|
+
/**
|
|
110
|
+
* Additional options for the command execution
|
|
111
|
+
*/
|
|
112
|
+
options?: {
|
|
113
|
+
/**
|
|
114
|
+
* Working directory for the command
|
|
115
|
+
*/
|
|
116
|
+
cwd?: string
|
|
117
|
+
/**
|
|
118
|
+
* Environment variables to pass to the command
|
|
119
|
+
* @default process.env
|
|
120
|
+
*/
|
|
121
|
+
env?: Record<string, string | undefined>
|
|
122
|
+
/**
|
|
123
|
+
* Maximum time in milliseconds the command is allowed to run
|
|
124
|
+
*/
|
|
125
|
+
timeout?: number
|
|
126
|
+
/**
|
|
127
|
+
* Signal to use when killing the process
|
|
128
|
+
* @default 'SIGTERM'
|
|
129
|
+
*/
|
|
130
|
+
killSignal?: NodeJS.Signals | number
|
|
131
|
+
}
|
|
132
|
+
};
|
|
104
133
|
interface BuildOptions {
|
|
105
134
|
/**
|
|
106
135
|
* Name of the build configuration
|
|
@@ -224,15 +253,27 @@ interface BuildOptions {
|
|
|
224
253
|
/**\\n\\t* Define global constants for the build\\n\\t* These values will be replaced at build time\\n\\t*\\n\\t* @see https://bun.sh/docs/bundler#define\\n\\t*\\n\\t* @example\\n\\t* define: {\\n\\t* 'process.env.NODE_ENV': '"production"',\\n\\t* 'PACKAGE_VERSION': '"1.0.0"'\\n\\t* }\\n\\t*/
|
|
225
254
|
define?: Define;
|
|
226
255
|
/**
|
|
227
|
-
* A callback
|
|
228
|
-
*
|
|
229
|
-
*
|
|
256
|
+
* A callback or command to run after a successful build.
|
|
257
|
+
*
|
|
258
|
+
* If a function is provided, it can optionally return a cleanup function
|
|
259
|
+
* that will be called when the operation is cancelled.
|
|
230
260
|
*
|
|
231
|
-
*
|
|
261
|
+
* @example
|
|
262
|
+
* onSuccess: (options) => {
|
|
263
|
+
* const server = startServer();
|
|
264
|
+
* return () => server.close();
|
|
265
|
+
* }
|
|
266
|
+
*
|
|
267
|
+
* @example
|
|
268
|
+
* onSuccess: "echo Build completed!"
|
|
232
269
|
*
|
|
233
|
-
* @
|
|
270
|
+
* @example
|
|
271
|
+
* onSuccess: {
|
|
272
|
+
* cmd: "bun run dist/server.js",
|
|
273
|
+
* options: { env: { ...process.env, FOO: "bar" } }
|
|
274
|
+
* }
|
|
234
275
|
*/
|
|
235
|
-
onSuccess?:
|
|
276
|
+
onSuccess?: OnSuccess;
|
|
236
277
|
/**\\n\\t* A banner to be added to the final bundle, this can be a directive like "use client" for react or a comment block such as a license for the code.\\n\\t*\\n\\t* @see https://bun.sh/docs/bundler#banner\\n\\t*\\n\\t* @example\\n\\t* banner: '"use client";'\\n\\t*/
|
|
237
278
|
banner?: string;
|
|
238
279
|
/**
|
|
@@ -163,7 +163,12 @@ function logTable(columns, data, footer) {
|
|
|
163
163
|
console.log(footerRow);
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
|
-
var link = (url) =>
|
|
166
|
+
var link = (url, label) => {
|
|
167
|
+
if (!label) {
|
|
168
|
+
label = url;
|
|
169
|
+
}
|
|
170
|
+
return `\x1B]8;;${url}\x07${pc.underline(pc.cyan(label))}\x1B]8;;\x07`;
|
|
171
|
+
};
|
|
167
172
|
var logger = Logger.getInstance();
|
|
168
173
|
|
|
169
174
|
// src/errors.ts
|
|
@@ -251,7 +256,8 @@ var handleError = (error, context) => {
|
|
|
251
256
|
}
|
|
252
257
|
const knownError = KNOWN_ERRORS.find((error2) => error2.pattern.test(errorMessage) && (error2.errorType === errorType || !error2.errorType));
|
|
253
258
|
if (!knownError && errorType) {
|
|
254
|
-
console.error(
|
|
259
|
+
console.error(`
|
|
260
|
+
${pc2.red(errorType)} ${contextPrefix}${errorMessage}`);
|
|
255
261
|
}
|
|
256
262
|
if (knownError) {
|
|
257
263
|
console.log(`
|
|
@@ -260,7 +266,19 @@ var handleError = (error, context) => {
|
|
|
260
266
|
console.log(`
|
|
261
267
|
`);
|
|
262
268
|
} else {
|
|
263
|
-
|
|
269
|
+
const issueUrl = new URL("https://github.com/arshad-yaseen/bunup/issues/new");
|
|
270
|
+
issueUrl.searchParams.set("title", `[${errorType}] Error encountered`);
|
|
271
|
+
issueUrl.searchParams.set("body", `## Error Details
|
|
272
|
+
|
|
273
|
+
**Error Type:** ${errorType}
|
|
274
|
+
**Error Message:** ${errorMessage}
|
|
275
|
+
|
|
276
|
+
## Additional Context
|
|
277
|
+
|
|
278
|
+
<!-- Please provide any additional context about what you were trying to do when the error occurred -->`);
|
|
279
|
+
console.error(pc2.white(`
|
|
280
|
+
If you think this is a bug, please `) + link(issueUrl.toString(), "open an issue") + ` with details about this error
|
|
281
|
+
`);
|
|
264
282
|
}
|
|
265
283
|
};
|
|
266
284
|
var handleErrorAndExit = (error, context) => {
|
|
@@ -269,7 +287,6 @@ var handleErrorAndExit = (error, context) => {
|
|
|
269
287
|
};
|
|
270
288
|
|
|
271
289
|
// src/utils.ts
|
|
272
|
-
import fsSync from "fs";
|
|
273
290
|
import fs from "fs/promises";
|
|
274
291
|
import path, { normalize } from "path";
|
|
275
292
|
|
|
@@ -429,14 +446,6 @@ function cleanPath(path2) {
|
|
|
429
446
|
function isDirectoryPath(filePath) {
|
|
430
447
|
return path.extname(filePath) === "";
|
|
431
448
|
}
|
|
432
|
-
function pathExistsSync(filePath) {
|
|
433
|
-
try {
|
|
434
|
-
fsSync.accessSync(filePath);
|
|
435
|
-
return true;
|
|
436
|
-
} catch {
|
|
437
|
-
return false;
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
449
|
function formatListWithAnd(arr) {
|
|
441
450
|
return new Intl.ListFormat("en", {
|
|
442
451
|
style: "long",
|
|
@@ -469,4 +478,44 @@ function isTypeScriptFile(path2) {
|
|
|
469
478
|
return TS_RE.test(path2);
|
|
470
479
|
}
|
|
471
480
|
|
|
472
|
-
|
|
481
|
+
// src/plugins/utils.ts
|
|
482
|
+
import pc3 from "picocolors";
|
|
483
|
+
function filterBunupBunPlugins(plugins) {
|
|
484
|
+
if (!plugins)
|
|
485
|
+
return [];
|
|
486
|
+
return plugins.filter((p2) => p2.type === "bun");
|
|
487
|
+
}
|
|
488
|
+
function filterBunupPlugins(plugins) {
|
|
489
|
+
if (!plugins)
|
|
490
|
+
return [];
|
|
491
|
+
return plugins.filter((p2) => p2.type === "bunup");
|
|
492
|
+
}
|
|
493
|
+
async function runPluginBuildStartHooks(bunupPlugins, options) {
|
|
494
|
+
if (!bunupPlugins)
|
|
495
|
+
return;
|
|
496
|
+
for (const plugin of bunupPlugins) {
|
|
497
|
+
if (plugin.hooks.onBuildStart) {
|
|
498
|
+
await plugin.hooks.onBuildStart(options);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
async function runPluginBuildDoneHooks(bunupPlugins, options, output, meta) {
|
|
503
|
+
if (!bunupPlugins)
|
|
504
|
+
return;
|
|
505
|
+
for (const plugin of bunupPlugins) {
|
|
506
|
+
if (plugin.hooks.onBuildDone) {
|
|
507
|
+
await plugin.hooks.onBuildDone({ options, output, meta });
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
async function getPackageForPlugin(name, pluginName) {
|
|
512
|
+
let pkg;
|
|
513
|
+
try {
|
|
514
|
+
pkg = await import(name);
|
|
515
|
+
} catch {
|
|
516
|
+
throw new BunupPluginError(`[${pc3.cyan(name)}] is required for the ${pluginName} plugin. Please install it with: ${pc3.blue(`bun add ${name} --dev`)}`);
|
|
517
|
+
}
|
|
518
|
+
return pkg;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
export { __toESM, __require, silent, setSilent, logTable, logger, BunupBuildError, BunupDTSBuildError, BunupCLIError, BunupWatchError, parseErrorMessage, handleError, handleErrorAndExit, JS_TS_RE, JS_DTS_RE, CSS_RE, ensureArray, getDefaultOutputExtension, getDefaultDtsExtention, formatTime, getPackageDeps, formatFileSize, getShortFilePath, cleanOutDir, cleanPath, isDirectoryPath, formatListWithAnd, getFilesFromGlobs, isTypeScriptFile, filterBunupBunPlugins, filterBunupPlugins, runPluginBuildStartHooks, runPluginBuildDoneHooks, getPackageForPlugin };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bunup",
|
|
3
3
|
"description": "⚡ A blazing-fast build tool for your libraries built with Bun.",
|
|
4
|
-
"version": "0.9.
|
|
4
|
+
"version": "0.9.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist"
|
|
@@ -46,25 +46,23 @@
|
|
|
46
46
|
"bunup": "dist/cli/index.js"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@clack/prompts": "^0.10.1",
|
|
50
49
|
"chokidar": "^4.0.3",
|
|
51
50
|
"coffi": "^0.1.31",
|
|
52
51
|
"fast-deep-equal": "^3.1.3",
|
|
53
|
-
"giget": "^2.0.0",
|
|
54
52
|
"picocolors": "^1.1.1",
|
|
55
|
-
"replace-in-file": "^8.3.0",
|
|
56
53
|
"tinyexec": "^1.0.1",
|
|
57
|
-
"
|
|
54
|
+
"tree-kill": "^1.2.2",
|
|
55
|
+
"typeroll": "^0.6.22"
|
|
58
56
|
},
|
|
59
57
|
"devDependencies": {
|
|
60
58
|
"@babel/types": "^7.28.2",
|
|
61
59
|
"@biomejs/biome": "2.0.0",
|
|
62
60
|
"@types/bun": "^1.2.19",
|
|
63
|
-
"bumpp": "^10.2.
|
|
61
|
+
"bumpp": "^10.2.2",
|
|
64
62
|
"husky": "^9.1.7",
|
|
65
63
|
"lightningcss": "^1.30.1",
|
|
66
64
|
"lint-staged": "^15.5.2",
|
|
67
|
-
"typescript": "^5.
|
|
65
|
+
"typescript": "^5.9.2"
|
|
68
66
|
},
|
|
69
67
|
"peerDependencies": {
|
|
70
68
|
"typescript": ">=4.5.0",
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// src/loaders.ts
|
|
2
|
-
import path from "path";
|
|
3
|
-
import { loadConfig } from "coffi";
|
|
4
|
-
async function processLoadedConfigs(config, cwd, filter) {
|
|
5
|
-
return Array.isArray(config) && "root" in config[0] ? config.filter((c) => filter ? filter.includes(c.name) : true).map((c) => ({
|
|
6
|
-
rootDir: path.resolve(cwd, c.root),
|
|
7
|
-
options: addField(c.config, "name", c.name)
|
|
8
|
-
})) : [
|
|
9
|
-
{
|
|
10
|
-
rootDir: cwd,
|
|
11
|
-
options: config
|
|
12
|
-
}
|
|
13
|
-
];
|
|
14
|
-
}
|
|
15
|
-
function addField(objectOrArray, field, value) {
|
|
16
|
-
return Array.isArray(objectOrArray) ? objectOrArray.map((o) => ({ ...o, [field]: value })) : { ...objectOrArray, [field]: value };
|
|
17
|
-
}
|
|
18
|
-
async function loadPackageJson(cwd = process.cwd()) {
|
|
19
|
-
const { config, filepath } = await loadConfig({
|
|
20
|
-
name: "package",
|
|
21
|
-
cwd,
|
|
22
|
-
extensions: [".json"]
|
|
23
|
-
});
|
|
24
|
-
return {
|
|
25
|
-
data: config,
|
|
26
|
-
path: filepath
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export { processLoadedConfigs, loadPackageJson };
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
logger
|
|
3
|
-
} from "./chunk-sfjfqxjy.js";
|
|
4
|
-
|
|
5
|
-
// src/cli/utils.ts
|
|
6
|
-
import pc from "picocolors";
|
|
7
|
-
function displayBunupGradientArt() {
|
|
8
|
-
const art = `
|
|
9
|
-
\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
|
|
10
|
-
\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
|
|
11
|
-
\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
|
|
12
|
-
\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
|
|
13
|
-
\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
|
|
14
|
-
\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
|
|
15
|
-
`.trim();
|
|
16
|
-
const lines = art.split(`
|
|
17
|
-
`);
|
|
18
|
-
logger.space();
|
|
19
|
-
for (const line of lines) {
|
|
20
|
-
console.log(pc.cyan(line));
|
|
21
|
-
}
|
|
22
|
-
logger.space();
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export { displayBunupGradientArt };
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BunupPluginError
|
|
3
|
-
} from "./chunk-sfjfqxjy.js";
|
|
4
|
-
|
|
5
|
-
// src/plugins/utils.ts
|
|
6
|
-
import pc from "picocolors";
|
|
7
|
-
function filterBunupBunPlugins(plugins) {
|
|
8
|
-
if (!plugins)
|
|
9
|
-
return [];
|
|
10
|
-
return plugins.filter((p) => p.type === "bun");
|
|
11
|
-
}
|
|
12
|
-
function filterBunupPlugins(plugins) {
|
|
13
|
-
if (!plugins)
|
|
14
|
-
return [];
|
|
15
|
-
return plugins.filter((p) => p.type === "bunup");
|
|
16
|
-
}
|
|
17
|
-
async function runPluginBuildStartHooks(bunupPlugins, options) {
|
|
18
|
-
if (!bunupPlugins)
|
|
19
|
-
return;
|
|
20
|
-
for (const plugin of bunupPlugins) {
|
|
21
|
-
if (plugin.hooks.onBuildStart) {
|
|
22
|
-
await plugin.hooks.onBuildStart(options);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
async function runPluginBuildDoneHooks(bunupPlugins, options, output, meta) {
|
|
27
|
-
if (!bunupPlugins)
|
|
28
|
-
return;
|
|
29
|
-
for (const plugin of bunupPlugins) {
|
|
30
|
-
if (plugin.hooks.onBuildDone) {
|
|
31
|
-
await plugin.hooks.onBuildDone({ options, output, meta });
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
async function getPackageForPlugin(name, pluginName) {
|
|
36
|
-
let pkg;
|
|
37
|
-
try {
|
|
38
|
-
pkg = await import(name);
|
|
39
|
-
} catch {
|
|
40
|
-
throw new BunupPluginError(`[${pc.cyan(name)}] is required for the ${pluginName} plugin. Please install it with: ${pc.blue(`bun add ${name} --dev`)}`);
|
|
41
|
-
}
|
|
42
|
-
return pkg;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export { filterBunupBunPlugins, filterBunupPlugins, runPluginBuildStartHooks, runPluginBuildDoneHooks, getPackageForPlugin };
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import {
|
|
3
|
-
displayBunupGradientArt
|
|
4
|
-
} from "./chunk-b17s55p9.js";
|
|
5
|
-
import {
|
|
6
|
-
link,
|
|
7
|
-
pathExistsSync
|
|
8
|
-
} from "./chunk-sfjfqxjy.js";
|
|
9
|
-
|
|
10
|
-
// src/cli/new.ts
|
|
11
|
-
import { renameSync } from "fs";
|
|
12
|
-
import path from "path";
|
|
13
|
-
import {
|
|
14
|
-
cancel,
|
|
15
|
-
confirm,
|
|
16
|
-
intro,
|
|
17
|
-
outro,
|
|
18
|
-
select,
|
|
19
|
-
tasks,
|
|
20
|
-
text
|
|
21
|
-
} from "@clack/prompts";
|
|
22
|
-
import { downloadTemplate } from "giget";
|
|
23
|
-
import pc from "picocolors";
|
|
24
|
-
import { replaceInFile } from "replace-in-file";
|
|
25
|
-
var TEMPLATE_OWNER = "arshad-yaseen";
|
|
26
|
-
var TEMPLATE_REPO = "bunup-new";
|
|
27
|
-
var GITHUB_USERNAME_PLACEHOLDER = "username";
|
|
28
|
-
var GITHUB_REPO_PLACEHOLDER = "repo-name";
|
|
29
|
-
var MONOREPO_FIRST_PACKAGE_NAME_PLACEHOLDER = "package-1";
|
|
30
|
-
var MONOREPO_PACKAGES_DIR = "packages";
|
|
31
|
-
var TEMPLATES = [
|
|
32
|
-
{
|
|
33
|
-
type: "typescript",
|
|
34
|
-
defaultName: "my-ts-lib",
|
|
35
|
-
name: "Typescript Library",
|
|
36
|
-
dir: "ts-lib",
|
|
37
|
-
monorepoDir: "ts-lib-monorepo"
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
type: "react",
|
|
41
|
-
defaultName: "my-react-lib",
|
|
42
|
-
name: "React Library",
|
|
43
|
-
dir: "react-lib"
|
|
44
|
-
}
|
|
45
|
-
];
|
|
46
|
-
async function newProject() {
|
|
47
|
-
displayBunupGradientArt();
|
|
48
|
-
intro(pc.bgCyan(pc.black(" Scaffold a new project with Bunup ")));
|
|
49
|
-
const selectedTemplateDir = await select({
|
|
50
|
-
message: "Select a template",
|
|
51
|
-
options: TEMPLATES.map((template2) => ({
|
|
52
|
-
value: template2.dir,
|
|
53
|
-
label: pc.blue(template2.name)
|
|
54
|
-
}))
|
|
55
|
-
});
|
|
56
|
-
const template = TEMPLATES.find((t) => t.dir === selectedTemplateDir);
|
|
57
|
-
if (!template) {
|
|
58
|
-
cancel("Invalid template");
|
|
59
|
-
process.exit(1);
|
|
60
|
-
}
|
|
61
|
-
const hasMonorepo = template.monorepoDir !== undefined;
|
|
62
|
-
const projectName = await text({
|
|
63
|
-
message: "Enter the project name",
|
|
64
|
-
placeholder: template.defaultName,
|
|
65
|
-
defaultValue: template.defaultName,
|
|
66
|
-
validate: (value) => {
|
|
67
|
-
if (!value) {
|
|
68
|
-
return "Project name is required";
|
|
69
|
-
}
|
|
70
|
-
if (value.includes(" ")) {
|
|
71
|
-
return "Project name cannot contain spaces";
|
|
72
|
-
}
|
|
73
|
-
if (pathExistsSync(getProjectPath(value))) {
|
|
74
|
-
return "Project already exists";
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
const projectPath = getProjectPath(projectName);
|
|
79
|
-
let useMonorepo = false;
|
|
80
|
-
let monorepoFirstPackageName;
|
|
81
|
-
if (hasMonorepo) {
|
|
82
|
-
useMonorepo = await confirm({
|
|
83
|
-
message: "Do you want to create a monorepo?",
|
|
84
|
-
initialValue: false
|
|
85
|
-
});
|
|
86
|
-
if (useMonorepo) {
|
|
87
|
-
monorepoFirstPackageName = await text({
|
|
88
|
-
message: "Enter the name of the first package",
|
|
89
|
-
placeholder: MONOREPO_FIRST_PACKAGE_NAME_PLACEHOLDER,
|
|
90
|
-
defaultValue: MONOREPO_FIRST_PACKAGE_NAME_PLACEHOLDER
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
const githubRepoInfo = await text({
|
|
95
|
-
message: "GitHub username and repo name (username/repo):",
|
|
96
|
-
placeholder: `${GITHUB_USERNAME_PLACEHOLDER}/${GITHUB_REPO_PLACEHOLDER}`,
|
|
97
|
-
defaultValue: `${GITHUB_USERNAME_PLACEHOLDER}/${GITHUB_REPO_PLACEHOLDER}`
|
|
98
|
-
});
|
|
99
|
-
const [githubUsername, githubRepoName] = githubRepoInfo.split("/");
|
|
100
|
-
await tasks([
|
|
101
|
-
{
|
|
102
|
-
title: "Downloading template",
|
|
103
|
-
task: async () => {
|
|
104
|
-
const templatePath = useMonorepo ? template.monorepoDir : template.dir;
|
|
105
|
-
await downloadTemplate(`github:${TEMPLATE_OWNER}/${TEMPLATE_REPO}/${templatePath}`, {
|
|
106
|
-
dir: projectPath
|
|
107
|
-
});
|
|
108
|
-
return "Template downloaded";
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
title: "Making the project yours",
|
|
113
|
-
task: async () => {
|
|
114
|
-
await replaceInFile({
|
|
115
|
-
files: path.join(projectPath, "**/*"),
|
|
116
|
-
from: [
|
|
117
|
-
new RegExp(GITHUB_REPO_PLACEHOLDER, "g"),
|
|
118
|
-
new RegExp(GITHUB_USERNAME_PLACEHOLDER, "g"),
|
|
119
|
-
new RegExp(template.defaultName, "g")
|
|
120
|
-
],
|
|
121
|
-
to: [githubRepoName, githubUsername, projectName],
|
|
122
|
-
ignore: ["node_modules", "dist", "bun.lock"]
|
|
123
|
-
});
|
|
124
|
-
if (useMonorepo && monorepoFirstPackageName) {
|
|
125
|
-
await replaceInFile({
|
|
126
|
-
files: path.join(projectPath, "**/*"),
|
|
127
|
-
from: [new RegExp(MONOREPO_FIRST_PACKAGE_NAME_PLACEHOLDER, "g")],
|
|
128
|
-
to: [monorepoFirstPackageName],
|
|
129
|
-
ignore: ["node_modules", "dist", "bun.lock"]
|
|
130
|
-
});
|
|
131
|
-
renameSync(path.join(projectPath, MONOREPO_PACKAGES_DIR, MONOREPO_FIRST_PACKAGE_NAME_PLACEHOLDER), path.join(projectPath, MONOREPO_PACKAGES_DIR, monorepoFirstPackageName));
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
]);
|
|
136
|
-
outro(`
|
|
137
|
-
${pc.green("\u2728 Project scaffolded successfully! \u2728")}
|
|
138
|
-
|
|
139
|
-
${pc.bold("Ready to launch your awesome new project?")}
|
|
140
|
-
|
|
141
|
-
${pc.cyan("cd")} ${projectName}
|
|
142
|
-
${pc.cyan("bun install")}
|
|
143
|
-
${pc.cyan("bun run dev")}${pc.dim(" (watch mode for development)")}${template.type === "react" ? `
|
|
144
|
-
${pc.cyan("bun run dev:test")} ${pc.dim("(preview components in a test Next.js app)")} ` : ""}
|
|
145
|
-
|
|
146
|
-
${pc.dim("Learn more:")} ${link("https://bunup.dev/docs")}
|
|
147
|
-
|
|
148
|
-
${pc.yellow("Happy coding!")} \uD83D\uDE80
|
|
149
|
-
`);
|
|
150
|
-
}
|
|
151
|
-
function getProjectPath(projectName) {
|
|
152
|
-
return path.join(process.cwd(), projectName);
|
|
153
|
-
}
|
|
154
|
-
export {
|
|
155
|
-
newProject
|
|
156
|
-
};
|
|
@@ -1,341 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import {
|
|
3
|
-
loadPackageJson
|
|
4
|
-
} from "./chunk-295440tx.js";
|
|
5
|
-
import {
|
|
6
|
-
displayBunupGradientArt
|
|
7
|
-
} from "./chunk-b17s55p9.js";
|
|
8
|
-
import {
|
|
9
|
-
formatListWithAnd,
|
|
10
|
-
link
|
|
11
|
-
} from "./chunk-sfjfqxjy.js";
|
|
12
|
-
|
|
13
|
-
// src/cli/init.ts
|
|
14
|
-
import fs from "fs";
|
|
15
|
-
import path from "path";
|
|
16
|
-
import {
|
|
17
|
-
confirm,
|
|
18
|
-
intro,
|
|
19
|
-
log,
|
|
20
|
-
multiselect,
|
|
21
|
-
outro,
|
|
22
|
-
select,
|
|
23
|
-
tasks,
|
|
24
|
-
text
|
|
25
|
-
} from "@clack/prompts";
|
|
26
|
-
import pc from "picocolors";
|
|
27
|
-
import { exec } from "tinyexec";
|
|
28
|
-
async function init() {
|
|
29
|
-
displayBunupGradientArt();
|
|
30
|
-
intro(pc.bgCyan(pc.black(" Initialize bunup in an existing project ")));
|
|
31
|
-
const { path: packageJsonPath } = await loadPackageJson();
|
|
32
|
-
if (!packageJsonPath) {
|
|
33
|
-
log.error("package.json not found");
|
|
34
|
-
process.exit(1);
|
|
35
|
-
}
|
|
36
|
-
const shouldSetupWorkspace = await promptForWorkspace();
|
|
37
|
-
if (shouldSetupWorkspace) {
|
|
38
|
-
await initializeWorkspace(packageJsonPath);
|
|
39
|
-
} else {
|
|
40
|
-
await initializeSinglePackage(packageJsonPath);
|
|
41
|
-
}
|
|
42
|
-
await tasks([
|
|
43
|
-
{
|
|
44
|
-
title: "Installing bunup",
|
|
45
|
-
task: async () => {
|
|
46
|
-
await installBunup();
|
|
47
|
-
return "Bunup installed";
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
]);
|
|
51
|
-
showSuccessOutro(shouldSetupWorkspace);
|
|
52
|
-
}
|
|
53
|
-
async function promptForWorkspace() {
|
|
54
|
-
return await confirm({
|
|
55
|
-
message: "Do you want to setup a Bunup workspace? (for building multiple packages with one command)",
|
|
56
|
-
initialValue: false
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
async function initializeWorkspace(packageJsonPath) {
|
|
60
|
-
const workspacePackages = await collectWorkspacePackages();
|
|
61
|
-
const configMethod = await selectWorkspaceConfigurationMethod();
|
|
62
|
-
await generateWorkspaceConfiguration(configMethod, workspacePackages);
|
|
63
|
-
await handleWorkspaceBuildScripts(packageJsonPath);
|
|
64
|
-
}
|
|
65
|
-
async function initializeSinglePackage(packageJsonPath) {
|
|
66
|
-
const entryFiles = await collectEntryFiles();
|
|
67
|
-
const outputFormats = await selectOutputFormats();
|
|
68
|
-
const configMethod = await selectConfigurationMethod();
|
|
69
|
-
await generateConfiguration(configMethod, entryFiles, outputFormats, packageJsonPath);
|
|
70
|
-
await handleBuildScripts(packageJsonPath, entryFiles, outputFormats, configMethod);
|
|
71
|
-
}
|
|
72
|
-
async function collectWorkspacePackages() {
|
|
73
|
-
const packages = [];
|
|
74
|
-
while (true) {
|
|
75
|
-
const packageName = await text({
|
|
76
|
-
message: packages.length > 0 ? "Enter the next package name:" : "Enter the first package name:",
|
|
77
|
-
placeholder: "core",
|
|
78
|
-
validate: (value) => {
|
|
79
|
-
if (!value)
|
|
80
|
-
return "Package name is required";
|
|
81
|
-
if (packages.some((pkg) => pkg.name === value))
|
|
82
|
-
return "Package name already exists";
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
const packageRoot = await text({
|
|
86
|
-
message: `Enter the root directory for "${packageName}":`,
|
|
87
|
-
placeholder: `packages/${packageName}`,
|
|
88
|
-
defaultValue: `packages/${packageName}`,
|
|
89
|
-
validate: (value) => {
|
|
90
|
-
if (!value)
|
|
91
|
-
return "Package root is required";
|
|
92
|
-
if (!fs.existsSync(value))
|
|
93
|
-
return "Package root directory does not exist";
|
|
94
|
-
if (!fs.statSync(value).isDirectory())
|
|
95
|
-
return "Package root must be a directory";
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
const entryFiles = await collectEntryFilesForPackage(packageRoot, packageName);
|
|
99
|
-
const outputFormats = await selectOutputFormats();
|
|
100
|
-
packages.push({
|
|
101
|
-
name: packageName,
|
|
102
|
-
root: packageRoot,
|
|
103
|
-
entryFiles,
|
|
104
|
-
outputFormats
|
|
105
|
-
});
|
|
106
|
-
const shouldAddMore = await confirm({
|
|
107
|
-
message: "Do you want to add another package?",
|
|
108
|
-
initialValue: true
|
|
109
|
-
});
|
|
110
|
-
if (!shouldAddMore)
|
|
111
|
-
break;
|
|
112
|
-
}
|
|
113
|
-
return packages;
|
|
114
|
-
}
|
|
115
|
-
async function collectEntryFilesForPackage(packageRoot, packageName) {
|
|
116
|
-
const entryFiles = [];
|
|
117
|
-
while (true) {
|
|
118
|
-
const entryFile = await text({
|
|
119
|
-
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})`,
|
|
120
|
-
placeholder: "src/index.ts",
|
|
121
|
-
defaultValue: "src/index.ts",
|
|
122
|
-
validate: (value) => {
|
|
123
|
-
if (!value)
|
|
124
|
-
return "Entry file is required";
|
|
125
|
-
const fullPath = path.join(packageRoot, value);
|
|
126
|
-
if (!fs.existsSync(fullPath))
|
|
127
|
-
return `Entry file does not exist at ${fullPath}`;
|
|
128
|
-
if (!fs.statSync(fullPath).isFile())
|
|
129
|
-
return "Entry file must be a file";
|
|
130
|
-
if (entryFiles.includes(value))
|
|
131
|
-
return "You have already added this entry file";
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
entryFiles.push(entryFile);
|
|
135
|
-
const shouldAddMore = await confirm({
|
|
136
|
-
message: "Do you want to add another entry file for this package?",
|
|
137
|
-
initialValue: false
|
|
138
|
-
});
|
|
139
|
-
if (!shouldAddMore)
|
|
140
|
-
break;
|
|
141
|
-
}
|
|
142
|
-
return entryFiles;
|
|
143
|
-
}
|
|
144
|
-
async function collectEntryFiles() {
|
|
145
|
-
const entryFiles = [];
|
|
146
|
-
while (true) {
|
|
147
|
-
const entryFile = await text({
|
|
148
|
-
message: entryFiles.length > 0 ? "Where is your next entry file?" : "Where is your entry file?",
|
|
149
|
-
placeholder: "src/index.ts",
|
|
150
|
-
defaultValue: "src/index.ts",
|
|
151
|
-
validate: (value) => {
|
|
152
|
-
if (!value)
|
|
153
|
-
return "Entry file is required";
|
|
154
|
-
if (!fs.existsSync(value))
|
|
155
|
-
return "Entry file does not exist";
|
|
156
|
-
if (!fs.statSync(value).isFile())
|
|
157
|
-
return "Entry file must be a file";
|
|
158
|
-
if (entryFiles.includes(value))
|
|
159
|
-
return "You have already added this entry file";
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
entryFiles.push(entryFile);
|
|
163
|
-
const shouldAddMore = await confirm({
|
|
164
|
-
message: "Do you want to add another entry file?",
|
|
165
|
-
initialValue: false
|
|
166
|
-
});
|
|
167
|
-
if (!shouldAddMore)
|
|
168
|
-
break;
|
|
169
|
-
}
|
|
170
|
-
return entryFiles;
|
|
171
|
-
}
|
|
172
|
-
async function selectOutputFormats() {
|
|
173
|
-
return await multiselect({
|
|
174
|
-
message: "Select the output formats",
|
|
175
|
-
options: [
|
|
176
|
-
{ value: "esm", label: "ESM (.mjs)" },
|
|
177
|
-
{ value: "cjs", label: "CommonJS (.cjs)" },
|
|
178
|
-
{ value: "iife", label: "IIFE (.global.js)" }
|
|
179
|
-
],
|
|
180
|
-
initialValues: ["esm", "cjs"]
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
async function selectWorkspaceConfigurationMethod() {
|
|
184
|
-
return await select({
|
|
185
|
-
message: "How would you like to configure your workspace?",
|
|
186
|
-
options: [
|
|
187
|
-
{ value: "ts", label: "bunup.config.ts", hint: "Recommended" },
|
|
188
|
-
{ value: "js", label: "bunup.config.js" }
|
|
189
|
-
],
|
|
190
|
-
initialValue: "ts"
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
async function selectConfigurationMethod() {
|
|
194
|
-
return await select({
|
|
195
|
-
message: "How would you like to configure Bunup?",
|
|
196
|
-
options: [
|
|
197
|
-
{ value: "ts", label: "bunup.config.ts", hint: "Recommended" },
|
|
198
|
-
{ value: "js", label: "bunup.config.js" },
|
|
199
|
-
{ value: "json", label: 'package.json "bunup" property' },
|
|
200
|
-
{
|
|
201
|
-
value: "none",
|
|
202
|
-
label: "No config file",
|
|
203
|
-
hint: "Configure via CLI only"
|
|
204
|
-
}
|
|
205
|
-
],
|
|
206
|
-
initialValue: "ts"
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
async function generateWorkspaceConfiguration(configMethod, workspacePackages) {
|
|
210
|
-
const configContent = createWorkspaceConfigFileContent(workspacePackages);
|
|
211
|
-
await Bun.write(`bunup.config.${configMethod}`, configContent);
|
|
212
|
-
}
|
|
213
|
-
async function generateConfiguration(configMethod, entryFiles, outputFormats, packageJsonPath) {
|
|
214
|
-
if (configMethod === "none") {
|
|
215
|
-
log.info("If you need more control (such as adding plugins or customizing output), you can always create a config file later.");
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
if (configMethod === "ts" || configMethod === "js") {
|
|
219
|
-
await Bun.write(`bunup.config.${configMethod}`, createConfigFileContent(entryFiles, outputFormats));
|
|
220
|
-
} else if (configMethod === "json") {
|
|
221
|
-
const { data: packageJsonConfig } = await loadPackageJson();
|
|
222
|
-
const updatedConfig = {
|
|
223
|
-
...packageJsonConfig,
|
|
224
|
-
bunup: createPackageJsonConfig(entryFiles, outputFormats)
|
|
225
|
-
};
|
|
226
|
-
await Bun.write(packageJsonPath, JSON.stringify(updatedConfig, null, 2));
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
async function handleWorkspaceBuildScripts(packageJsonPath) {
|
|
230
|
-
const { data: packageJsonConfig } = await loadPackageJson();
|
|
231
|
-
const existingScripts = packageJsonConfig?.scripts ?? {};
|
|
232
|
-
const newScripts = createWorkspaceBuildScripts();
|
|
233
|
-
const conflictingScripts = Object.keys(newScripts).filter((script) => existingScripts[script]);
|
|
234
|
-
if (conflictingScripts.length > 0) {
|
|
235
|
-
const shouldOverride = await confirm({
|
|
236
|
-
message: `The ${formatListWithAnd(conflictingScripts)} ${conflictingScripts.length > 1 ? "scripts already exist" : "script already exists"} in package.json. Override ${conflictingScripts.length > 1 ? "them" : "it"}?`,
|
|
237
|
-
initialValue: true
|
|
238
|
-
});
|
|
239
|
-
if (!shouldOverride) {
|
|
240
|
-
log.info("Skipped adding build scripts to avoid conflicts.");
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
const updatedConfig = {
|
|
245
|
-
...packageJsonConfig,
|
|
246
|
-
scripts: { ...existingScripts, ...newScripts }
|
|
247
|
-
};
|
|
248
|
-
await Bun.write(packageJsonPath, JSON.stringify(updatedConfig, null, 2));
|
|
249
|
-
}
|
|
250
|
-
async function handleBuildScripts(packageJsonPath, entryFiles, outputFormats, configMethod) {
|
|
251
|
-
const { data: packageJsonConfig } = await loadPackageJson();
|
|
252
|
-
const existingScripts = packageJsonConfig?.scripts ?? {};
|
|
253
|
-
const newScripts = createBuildScripts(entryFiles, outputFormats, configMethod);
|
|
254
|
-
const conflictingScripts = Object.keys(newScripts).filter((script) => existingScripts[script]);
|
|
255
|
-
if (conflictingScripts.length > 0) {
|
|
256
|
-
const shouldOverride = await confirm({
|
|
257
|
-
message: `The ${formatListWithAnd(conflictingScripts)} ${conflictingScripts.length > 1 ? "scripts already exist" : "script already exists"} in package.json. Override ${conflictingScripts.length > 1 ? "them" : "it"}?`,
|
|
258
|
-
initialValue: true
|
|
259
|
-
});
|
|
260
|
-
if (!shouldOverride) {
|
|
261
|
-
log.info("Skipped adding build scripts to avoid conflicts.");
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
const updatedConfig = {
|
|
266
|
-
...packageJsonConfig,
|
|
267
|
-
scripts: { ...existingScripts, ...newScripts }
|
|
268
|
-
};
|
|
269
|
-
await Bun.write(packageJsonPath, JSON.stringify(updatedConfig, null, 2));
|
|
270
|
-
}
|
|
271
|
-
function createWorkspaceConfigFileContent(workspacePackages) {
|
|
272
|
-
const packagesConfig = workspacePackages.map((pkg) => {
|
|
273
|
-
return ` {
|
|
274
|
-
name: '${pkg.name}',
|
|
275
|
-
root: '${pkg.root}',
|
|
276
|
-
config: {
|
|
277
|
-
entry: [${pkg.entryFiles.map((file) => `'${file}'`).join(", ")}],
|
|
278
|
-
format: [${pkg.outputFormats.map((format) => `'${format}'`).join(", ")}],
|
|
279
|
-
},
|
|
280
|
-
}`;
|
|
281
|
-
}).join(`,
|
|
282
|
-
`);
|
|
283
|
-
return `import { defineWorkspace } from 'bunup'
|
|
284
|
-
|
|
285
|
-
export default defineWorkspace([
|
|
286
|
-
${packagesConfig}
|
|
287
|
-
])
|
|
288
|
-
`;
|
|
289
|
-
}
|
|
290
|
-
function createConfigFileContent(entryFiles, outputFormats) {
|
|
291
|
-
return `import { defineConfig } from 'bunup'
|
|
292
|
-
|
|
293
|
-
export default defineConfig({
|
|
294
|
-
entry: [${entryFiles.map((file) => `'${file}'`).join(", ")}],
|
|
295
|
-
format: [${outputFormats.map((format) => `'${format}'`).join(", ")}],
|
|
296
|
-
})
|
|
297
|
-
`;
|
|
298
|
-
}
|
|
299
|
-
function createPackageJsonConfig(entryFiles, outputFormats) {
|
|
300
|
-
return {
|
|
301
|
-
entry: entryFiles,
|
|
302
|
-
format: outputFormats
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
function createWorkspaceBuildScripts() {
|
|
306
|
-
return {
|
|
307
|
-
build: "bunup",
|
|
308
|
-
dev: "bunup --watch"
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
function createBuildScripts(entryFiles, outputFormats, configMethod) {
|
|
312
|
-
const cliOptions = configMethod === "none" ? ` ${entryFiles.join(" ")} --format ${outputFormats.join(",")}` : "";
|
|
313
|
-
return {
|
|
314
|
-
build: `bunup${cliOptions}`,
|
|
315
|
-
dev: `bunup${cliOptions} --watch`
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
function showSuccessOutro(isWorkspace) {
|
|
319
|
-
const buildCommand = isWorkspace ? `${pc.cyan("bun run build")} - Build all packages in your workspace` : `${pc.cyan("bun run build")} - Build your library`;
|
|
320
|
-
const devCommand = isWorkspace ? `${pc.cyan("bun run dev")} - Start development mode (watches all packages)` : `${pc.cyan("bun run dev")} - Start development mode`;
|
|
321
|
-
const filterCommand = isWorkspace ? `${pc.cyan("bunup --filter core,utils")} - Build specific packages` : "";
|
|
322
|
-
outro(`
|
|
323
|
-
${pc.green("\u2728 Bunup initialized successfully! \u2728")}
|
|
324
|
-
|
|
325
|
-
${buildCommand}
|
|
326
|
-
${devCommand}${isWorkspace ? `
|
|
327
|
-
${filterCommand}` : ""}
|
|
328
|
-
|
|
329
|
-
${pc.dim("Learn more:")} ${link("https://bunup.dev/docs")}
|
|
330
|
-
|
|
331
|
-
${pc.yellow("Happy building!")} \uD83D\uDE80
|
|
332
|
-
`);
|
|
333
|
-
}
|
|
334
|
-
async function installBunup() {
|
|
335
|
-
await exec("bun add -d bunup", [], {
|
|
336
|
-
nodeOptions: { shell: true, stdio: "pipe" }
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
export {
|
|
340
|
-
init
|
|
341
|
-
};
|