bunup 0.8.32 → 0.8.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,352 @@
1
+ import {
2
+ BunupPluginError,
3
+ cleanPath,
4
+ formatFileSize,
5
+ isDirectoryPath,
6
+ logTable,
7
+ logger,
8
+ removeExtension
9
+ } from "./chunk-8z361mhm.js";
10
+
11
+ // src/constants/re.ts
12
+ var JS_RE = /\.(js|jsx|cjs|mjs)$/;
13
+ var TS_RE = /\.(ts|tsx|mts|cts)$/;
14
+ var DTS_RE = /\.(d\.(ts|mts|cts))$/;
15
+ var JS_TS_RE = new RegExp(`${JS_RE.source}|${TS_RE.source}`);
16
+ var JS_DTS_RE = new RegExp(`${JS_RE.source}|${DTS_RE.source}`);
17
+ var CSS_RE = /\.(css)$/;
18
+
19
+ // src/plugins/built-in/node/shims.ts
20
+ function shims() {
21
+ return {
22
+ type: "bun",
23
+ name: "shims",
24
+ plugin: {
25
+ name: "bunup:shims",
26
+ setup(build) {
27
+ const isNodeCompatibleTarget = build.config.target === "node" || build.config.target === "bun";
28
+ const isEsm = build.config.format === "esm";
29
+ const isCjs = build.config.format === "cjs";
30
+ if (!isNodeCompatibleTarget || !isEsm && !isCjs) {
31
+ return;
32
+ }
33
+ build.config.define = {
34
+ ...build.config.define,
35
+ ...isCjs && {
36
+ "import.meta.url": "importMetaUrl"
37
+ }
38
+ };
39
+ build.onLoad({ filter: JS_TS_RE }, async ({ path }) => {
40
+ const content = await Bun.file(path).text();
41
+ let shimCode = "";
42
+ if (isEsm && (/\b__dirname\b/.test(content) || /\b__filename\b/.test(content))) {
43
+ shimCode = `import { fileURLToPath } from 'url';
44
+ import { dirname } from 'path';
45
+
46
+ const __filename = fileURLToPath(import.meta.url);
47
+ const __dirname = dirname(__filename);
48
+
49
+ `;
50
+ }
51
+ if (isCjs && /\bimport\.meta\.url\b/.test(content)) {
52
+ shimCode = `import { pathToFileURL } from 'url';
53
+
54
+ const importMetaUrl = pathToFileURL(__filename).href;
55
+
56
+ `;
57
+ }
58
+ if (!shimCode)
59
+ return;
60
+ const lines = content.split(`
61
+ `);
62
+ const firstLine = lines[0];
63
+ const restLines = lines.slice(1);
64
+ return {
65
+ contents: [firstLine, shimCode, ...restLines].join(`
66
+ `)
67
+ };
68
+ });
69
+ }
70
+ }
71
+ };
72
+ }
73
+
74
+ // src/plugins/built-in/productivity/exports.ts
75
+ function exports(options = {}) {
76
+ return {
77
+ type: "bunup",
78
+ name: "exports",
79
+ hooks: {
80
+ onBuildDone: async ({ output, options: buildOptions, meta }) => {
81
+ if (!meta.packageJson.path || !meta.packageJson.data) {
82
+ return;
83
+ }
84
+ try {
85
+ const { exportsField, entryPoints } = generateExportsFields(output.files);
86
+ const files = Array.isArray(meta.packageJson.data.files) ? [
87
+ ...new Set([
88
+ ...meta.packageJson.data.files,
89
+ buildOptions.outDir
90
+ ])
91
+ ] : [buildOptions.outDir];
92
+ const mergedExports = { ...exportsField };
93
+ if (options.extraExports) {
94
+ for (const [key, value] of Object.entries(options.extraExports)) {
95
+ if (typeof value === "string") {
96
+ mergedExports[key] = value;
97
+ } else {
98
+ const existingExport = mergedExports[key];
99
+ if (typeof existingExport === "object" && existingExport !== null) {
100
+ mergedExports[key] = {
101
+ ...existingExport,
102
+ ...value
103
+ };
104
+ } else {
105
+ mergedExports[key] = value;
106
+ }
107
+ }
108
+ }
109
+ }
110
+ const newPackageJson = {
111
+ name: meta.packageJson.data.name,
112
+ description: meta.packageJson.data.description,
113
+ version: meta.packageJson.data.version,
114
+ type: meta.packageJson.data.type,
115
+ private: meta.packageJson.data.private,
116
+ files,
117
+ ...entryPoints,
118
+ exports: mergedExports
119
+ };
120
+ for (const key in meta.packageJson.data) {
121
+ if (Object.prototype.hasOwnProperty.call(meta.packageJson.data, key) && !Object.prototype.hasOwnProperty.call(newPackageJson, key)) {
122
+ newPackageJson[key] = meta.packageJson.data[key];
123
+ }
124
+ }
125
+ await Bun.write(meta.packageJson.path, JSON.stringify(newPackageJson, null, 2));
126
+ logger.cli("Updated package.json with exports");
127
+ } catch {
128
+ logger.error("Failed to update package.json");
129
+ }
130
+ }
131
+ }
132
+ };
133
+ }
134
+ function generateExportsFields(files) {
135
+ const exportsField = {};
136
+ const entryPoints = {};
137
+ const filteredFiles = filterFiles(files);
138
+ for (const file of filteredFiles) {
139
+ const exportType = formatToExportField(file.format, file.dts);
140
+ const relativePath = `./${cleanPath(file.relativePathToRootDir)}`;
141
+ const exportKey = getExportKey(cleanPath(file.relativePathToOutputDir));
142
+ exportsField[exportKey] = {
143
+ ...exportsField[exportKey],
144
+ [exportType]: relativePath
145
+ };
146
+ }
147
+ for (const field of Object.keys(exportsField["."] ?? {})) {
148
+ const entryPoint = exportFieldToEntryPoint(field);
149
+ entryPoints[entryPoint] = exportsField["."][field];
150
+ }
151
+ return { exportsField, entryPoints };
152
+ }
153
+ function filterFiles(files) {
154
+ return files.filter((file) => JS_DTS_RE.test(file.fullPath) && file.kind === "entry-point");
155
+ }
156
+ function getExportKey(relativePathToOutputDir) {
157
+ const pathSegments = cleanPath(removeExtension(relativePathToOutputDir)).split("/");
158
+ if (pathSegments.length === 1 && pathSegments[0].startsWith("index")) {
159
+ return ".";
160
+ }
161
+ return `./${pathSegments.filter((p) => !p.startsWith("index")).join("/")}`;
162
+ }
163
+ function exportFieldToEntryPoint(exportField) {
164
+ return exportField === "types" ? "types" : exportField === "require" ? "main" : "module";
165
+ }
166
+ function formatToExportField(format, dts) {
167
+ return dts ? "types" : format === "esm" ? "import" : "require";
168
+ }
169
+
170
+ // src/plugins/built-in/css/inject-styles.ts
171
+ import path from "path";
172
+
173
+ // src/plugins/utils.ts
174
+ import pc from "picocolors";
175
+ function filterBunupBunPlugins(plugins) {
176
+ if (!plugins)
177
+ return [];
178
+ return plugins.filter((p) => p.type === "bun");
179
+ }
180
+ function filterBunupPlugins(plugins) {
181
+ if (!plugins)
182
+ return [];
183
+ return plugins.filter((p) => p.type === "bunup");
184
+ }
185
+ async function runPluginBuildStartHooks(bunupPlugins, options) {
186
+ if (!bunupPlugins)
187
+ return;
188
+ for (const plugin of bunupPlugins) {
189
+ if (plugin.hooks.onBuildStart) {
190
+ await plugin.hooks.onBuildStart(options);
191
+ }
192
+ }
193
+ }
194
+ async function runPluginBuildDoneHooks(bunupPlugins, options, output, meta) {
195
+ if (!bunupPlugins)
196
+ return;
197
+ for (const plugin of bunupPlugins) {
198
+ if (plugin.hooks.onBuildDone) {
199
+ await plugin.hooks.onBuildDone({ options, output, meta });
200
+ }
201
+ }
202
+ }
203
+ async function getPackageForPlugin(name, pluginName) {
204
+ let pkg;
205
+ try {
206
+ pkg = await import(name);
207
+ } catch {
208
+ throw new BunupPluginError(`[${pc.cyan(name)}] is required for the ${pluginName} plugin. Please install it with: ${pc.blue(`bun add ${name} --dev`)}`);
209
+ }
210
+ return pkg;
211
+ }
212
+
213
+ // src/plugins/built-in/css/inject-styles.ts
214
+ function injectStyles(options) {
215
+ const { inject, ...transformOptions } = options ?? {};
216
+ return {
217
+ type: "bun",
218
+ name: "inject-styles",
219
+ plugin: {
220
+ name: "bunup:inject-styles",
221
+ async setup(build) {
222
+ const lightningcss = await getPackageForPlugin("lightningcss", "inject-styles");
223
+ build.onResolve({ filter: /^__inject-style$/ }, () => {
224
+ return {
225
+ path: "__inject-style",
226
+ namespace: "__inject-style"
227
+ };
228
+ });
229
+ build.onLoad({ filter: /^__inject-style$/, namespace: "__inject-style" }, () => {
230
+ return {
231
+ contents: `
232
+ export default function injectStyle(css) {
233
+ if (!css || typeof document === 'undefined') return
234
+
235
+ const head = document.head || document.getElementsByTagName('head')[0]
236
+ const style = document.createElement('style')
237
+ head.appendChild(style)
238
+
239
+ if (style.styleSheet) {
240
+ style.styleSheet.cssText = css
241
+ } else {
242
+ style.appendChild(document.createTextNode(css))
243
+ }
244
+ }
245
+ `,
246
+ loader: "js"
247
+ };
248
+ });
249
+ build.onLoad({ filter: CSS_RE }, async (args) => {
250
+ const source = await Bun.file(args.path).text();
251
+ const { code, warnings } = lightningcss.transform({
252
+ ...transformOptions,
253
+ filename: path.basename(args.path),
254
+ code: Buffer.from(source),
255
+ minify: transformOptions.minify ?? (build.config.minify === true || typeof build.config.minify === "object" && build.config.minify.whitespace)
256
+ });
257
+ for (const warning of warnings) {
258
+ logger.warn(warning.message);
259
+ }
260
+ const stringifiedCode = JSON.stringify(code.toString());
261
+ const js = inject ? await inject(stringifiedCode, args.path) : `import injectStyle from '__inject-style';injectStyle(${stringifiedCode})`;
262
+ return {
263
+ contents: js,
264
+ loader: "js"
265
+ };
266
+ });
267
+ }
268
+ }
269
+ };
270
+ }
271
+
272
+ // src/plugins/built-in/productivity/copy.ts
273
+ import { join } from "path";
274
+ import { basename } from "path";
275
+ function copy(patterns, outPath) {
276
+ return {
277
+ type: "bunup",
278
+ name: "copy",
279
+ hooks: {
280
+ onBuildDone: async ({ options, meta }) => {
281
+ const destinationPath = outPath || options.outDir;
282
+ for (const pattern of patterns) {
283
+ const glob = new Bun.Glob(pattern);
284
+ for await (const filePath of glob.scan({
285
+ cwd: meta.rootDir,
286
+ dot: true
287
+ })) {
288
+ const sourceFile = Bun.file(join(meta.rootDir, filePath));
289
+ await Bun.write(outPath && isDirectoryPath(outPath) ? join(destinationPath, basename(filePath)) : destinationPath, sourceFile);
290
+ }
291
+ }
292
+ }
293
+ }
294
+ };
295
+ }
296
+
297
+ // src/plugins/internal/report.ts
298
+ import pc2 from "picocolors";
299
+ function report() {
300
+ return {
301
+ type: "bunup",
302
+ name: "report",
303
+ hooks: {
304
+ onBuildDone: async ({ options, output }) => {
305
+ if (options.watch)
306
+ return;
307
+ const files = await Promise.all(output.files.map(async (file) => {
308
+ const name = file.relativePathToRootDir;
309
+ const size = Bun.file(file.fullPath).size;
310
+ const gzipSize = Bun.gzipSync(new Uint8Array(await Bun.file(file.fullPath).arrayBuffer())).length;
311
+ const formattedGzipSize = formatFileSize(gzipSize);
312
+ return {
313
+ name,
314
+ size,
315
+ formattedSize: formatFileSize(size),
316
+ gzipSize,
317
+ formattedGzipSize
318
+ };
319
+ }));
320
+ const totalSize = files.reduce((sum, file) => sum + file.size, 0);
321
+ const formattedTotalSize = formatFileSize(totalSize);
322
+ const totalGzipSize = files.reduce((sum, file) => sum + (file.gzipSize || 0), 0);
323
+ const formattedTotalGzipSize = formatFileSize(totalGzipSize);
324
+ const columns = [
325
+ { header: "File", align: "left", color: pc2.blue },
326
+ { header: "Size", align: "right", color: pc2.green },
327
+ {
328
+ header: "Gzip",
329
+ align: "right",
330
+ color: pc2.magenta
331
+ }
332
+ ];
333
+ const data = files.map((file) => {
334
+ return {
335
+ File: file.name,
336
+ Size: file.formattedSize,
337
+ Gzip: file.formattedGzipSize
338
+ };
339
+ });
340
+ const footer = {
341
+ File: "Total",
342
+ Size: formattedTotalSize,
343
+ Gzip: formattedTotalGzipSize
344
+ };
345
+ logger.space();
346
+ logTable(columns, data, footer);
347
+ logger.space();
348
+ }
349
+ }
350
+ };
351
+ }
352
+ export { shims, exports, filterBunupBunPlugins, filterBunupPlugins, runPluginBuildStartHooks, runPluginBuildDoneHooks, injectStyles, copy, report };