bunup 0.8.46 → 0.8.48

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.
@@ -27,6 +27,12 @@ type BuildMeta = {
27
27
  rootDir: string
28
28
  };
29
29
  type BuildOutputFile = {
30
+ /**
31
+ * The entry point for which this file was generated
32
+ *
33
+ * Undefined for non-entry point files (e.g., assets, sourcemaps, chunks)
34
+ */
35
+ entrypoint: string | undefined
30
36
  /** The kind of the file */
31
37
  kind: "entry-point" | "chunk" | "asset" | "sourcemap" | "bytecode"
32
38
  /** Path to the generated file */
@@ -299,6 +299,7 @@ async function build(partialOptions, rootDir = process.cwd()) {
299
299
  else if (log.level === "info")
300
300
  logger.info(log.message);
301
301
  }
302
+ let entrypointIndex = 0;
302
303
  for (const file of result.outputs) {
303
304
  const relativePathToRootDir = getRelativePathToRootDir(file.path, rootDir);
304
305
  const relativePathToOutputDir = getRelativePathToOutputDir(relativePathToRootDir, options.outDir);
@@ -313,8 +314,12 @@ async function build(partialOptions, rootDir = process.cwd()) {
313
314
  relativePathToOutputDir,
314
315
  dts: false,
315
316
  format: fmt,
316
- kind: file.kind
317
+ kind: file.kind,
318
+ entrypoint: file.kind === "entry-point" ? cleanPath(entrypoints[entrypointIndex]) : undefined
317
319
  });
320
+ if (file.kind === "entry-point") {
321
+ entrypointIndex++;
322
+ }
318
323
  }
319
324
  });
320
325
  await Promise.all(buildPromises);
@@ -349,7 +354,8 @@ async function build(partialOptions, rootDir = process.cwd()) {
349
354
  relativePathToOutputDir,
350
355
  dts: true,
351
356
  format: fmt,
352
- kind: file.kind
357
+ kind: file.kind,
358
+ entrypoint: file.entrypoint ? cleanPath(file.entrypoint) : undefined
353
359
  });
354
360
  }
355
361
  }
package/dist/cli/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  import {
4
4
  build,
5
5
  createBuildOptions
6
- } from "../chunk-ycxcdce7.js";
6
+ } from "../chunk-kpthwads.js";
7
7
  import"../chunk-snvybwa2.js";
8
8
  import {
9
9
  processLoadedConfigs
@@ -28,7 +28,7 @@ import { loadConfig } from "coffi";
28
28
  import pc3 from "picocolors";
29
29
  import { exec } from "tinyexec";
30
30
  // package.json
31
- var version = "0.8.46";
31
+ var version = "0.8.48";
32
32
 
33
33
  // src/watch.ts
34
34
  import path from "path";
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Arrayable, BuildOptions, DefineConfigItem, DefineWorkspaceItem, Plugin } from "./chunk-0f0jc2gd";
1
+ import { Arrayable, BuildOptions, DefineConfigItem, DefineWorkspaceItem, Plugin } from "./chunk-djb64jje";
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: DefineWorkspaceItem[]): DefineWorkspaceItem[];
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  build
4
- } from "./chunk-ycxcdce7.js";
4
+ } from "./chunk-kpthwads.js";
5
5
  import"./chunk-snvybwa2.js";
6
6
  import"./chunk-gh7z7s46.js";
7
7
  import"./chunk-a76fsvj7.js";
package/dist/plugins.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { BuildContext, BunupPlugin, MaybePromise, Plugin } from "./chunk-0f0jc2gd";
1
+ import { BuildContext, BunupPlugin, MaybePromise, Plugin } from "./chunk-djb64jje";
2
2
  /**
3
3
  * A plugin that copies files and directories to the output directory.
4
4
  *
@@ -8,23 +8,20 @@ import { BuildContext, BunupPlugin, MaybePromise, Plugin } from "./chunk-0f0jc2g
8
8
  */
9
9
  declare function copy(patterns: string[], outPath?: string): BunupPlugin;
10
10
  type CustomExports = Record<string, string | Record<string, string | Record<string, string>>>;
11
+ type Exclude = ((ctx: BuildContext) => string[] | undefined) | string[];
11
12
  interface ExportsPluginOptions {
12
13
  /**
13
14
  * Additional export fields to preserve alongside automatically generated exports
14
15
  *
15
- * @example
16
- * ```ts
17
- * {
18
- * customExports: (ctx) => {
19
- * const { output, options, meta } = ctx
20
- * return {
21
- * './package.json': "package.json",
22
- * }
23
- * },
24
- * }
25
- * ```
16
+ * @see https://bunup.dev/docs/plugins/exports#customexports
26
17
  */
27
18
  customExports?: (ctx: BuildContext) => CustomExports | undefined;
19
+ /**
20
+ * Entry points to exclude from the exports field
21
+ *
22
+ * @see https://bunup.dev/docs/plugins/exports#exclude
23
+ */
24
+ exclude?: Exclude;
28
25
  }
29
26
  /**
30
27
  * A plugin that generates the exports field in the package.json file automatically.
package/dist/plugins.js CHANGED
@@ -49,94 +49,199 @@ function exports(options = {}) {
49
49
  name: "exports",
50
50
  hooks: {
51
51
  onBuildDone: async (ctx) => {
52
- const { output, options: buildOptions, meta } = ctx;
53
- if (!meta.packageJson.path || !meta.packageJson.data) {
54
- return;
55
- }
56
- try {
57
- const { exportsField, entryPoints } = generateExportsFields(output.files);
58
- const files = Array.isArray(meta.packageJson.data.files) ? [
59
- ...new Set([
60
- ...meta.packageJson.data.files,
61
- buildOptions.outDir
62
- ])
63
- ] : [buildOptions.outDir];
64
- const mergedExports = { ...exportsField };
65
- if (options.customExports) {
66
- for (const [key, value] of Object.entries(options.customExports(ctx) ?? {})) {
67
- if (typeof value === "string") {
68
- mergedExports[key] = value;
69
- } else {
70
- const existingExport = mergedExports[key];
71
- if (typeof existingExport === "object" && existingExport !== null) {
72
- mergedExports[key] = {
73
- ...existingExport,
74
- ...value
75
- };
76
- } else {
77
- mergedExports[key] = value;
78
- }
79
- }
80
- }
81
- }
82
- const { main, module, types, ...restPackageJson } = meta.packageJson.data;
83
- const newPackageJson = {
84
- name: meta.packageJson.data.name,
85
- description: meta.packageJson.data.description,
86
- version: meta.packageJson.data.version,
87
- type: meta.packageJson.data.type,
88
- private: meta.packageJson.data.private,
89
- files,
90
- ...entryPoints,
91
- exports: mergedExports
92
- };
93
- for (const key in restPackageJson) {
94
- if (Object.hasOwn(restPackageJson, key) && !Object.hasOwn(newPackageJson, key)) {
95
- newPackageJson[key] = restPackageJson[key];
96
- }
97
- }
98
- await Bun.write(meta.packageJson.path, JSON.stringify(newPackageJson, null, 2));
99
- } catch {
100
- logger.error("Failed to update package.json");
101
- }
52
+ await processPackageJsonExports(ctx, options);
102
53
  }
103
54
  }
104
55
  };
105
56
  }
106
- function generateExportsFields(files) {
57
+ async function processPackageJsonExports(ctx, options) {
58
+ const { output, options: buildOptions, meta } = ctx;
59
+ if (!meta.packageJson.path || !meta.packageJson.data) {
60
+ return;
61
+ }
62
+ try {
63
+ const { exportsField, entryPoints } = generateExportsFields(output.files, options.exclude, ctx);
64
+ const updatedFiles = createUpdatedFilesArray(meta.packageJson.data, buildOptions.outDir);
65
+ const mergedExports = mergeCustomExportsWithGenerated(exportsField, options.customExports, ctx);
66
+ const newPackageJson = createUpdatedPackageJson(meta.packageJson.data, entryPoints, mergedExports, updatedFiles);
67
+ await Bun.write(meta.packageJson.path, JSON.stringify(newPackageJson, null, 2));
68
+ } catch {
69
+ logger.error("Failed to update package.json");
70
+ }
71
+ }
72
+ function generateExportsFields(files, exclude, ctx) {
73
+ const filteredFiles = filterFiles(files, exclude, ctx);
74
+ const { filesByExportKey, allDtsFiles } = groupFilesByExportKey(filteredFiles);
75
+ const exportsField = createExportEntries(filesByExportKey);
76
+ const entryPoints = extractEntryPoints(exportsField, allDtsFiles);
77
+ return { exportsField, entryPoints };
78
+ }
79
+ function groupFilesByExportKey(files) {
80
+ const filesByExportKey = new Map;
81
+ const allDtsFiles = new Map;
82
+ for (const file of files) {
83
+ const exportKey = getExportKey(cleanPath(file.relativePathToOutputDir));
84
+ const format = file.format === "esm" ? "import" : "require";
85
+ if (!filesByExportKey.has(exportKey)) {
86
+ filesByExportKey.set(exportKey, new Map);
87
+ allDtsFiles.set(exportKey, []);
88
+ }
89
+ const formatMap = filesByExportKey.get(exportKey);
90
+ const dtsFiles = allDtsFiles.get(exportKey);
91
+ if (formatMap && dtsFiles) {
92
+ if (!formatMap.has(format)) {
93
+ formatMap.set(format, { dts: undefined, source: undefined });
94
+ }
95
+ const fileEntry = formatMap.get(format);
96
+ if (fileEntry) {
97
+ if (file.dts) {
98
+ fileEntry.dts = file;
99
+ dtsFiles.push(file);
100
+ } else {
101
+ fileEntry.source = file;
102
+ }
103
+ }
104
+ }
105
+ }
106
+ return { filesByExportKey, allDtsFiles };
107
+ }
108
+ function createExportEntries(filesByExportKey) {
107
109
  const exportsField = {};
110
+ for (const [exportKey, formatMap] of filesByExportKey.entries()) {
111
+ exportsField[exportKey] = {};
112
+ let hasFormatSpecificTypes = false;
113
+ let primaryTypesPath;
114
+ for (const [format, files] of formatMap.entries()) {
115
+ const formatKey = format;
116
+ if (files.dts && files.source) {
117
+ exportsField[exportKey][formatKey] = {
118
+ types: `./${cleanPath(files.dts.relativePathToRootDir)}`,
119
+ default: `./${cleanPath(files.source.relativePathToRootDir)}`
120
+ };
121
+ hasFormatSpecificTypes = true;
122
+ if (!primaryTypesPath) {
123
+ primaryTypesPath = `./${cleanPath(files.dts.relativePathToRootDir)}`;
124
+ }
125
+ } else if (files.source) {
126
+ exportsField[exportKey][formatKey] = `./${cleanPath(files.source.relativePathToRootDir)}`;
127
+ if (files.dts) {
128
+ primaryTypesPath = `./${cleanPath(files.dts.relativePathToRootDir)}`;
129
+ }
130
+ } else if (files.dts) {
131
+ primaryTypesPath = `./${cleanPath(files.dts.relativePathToRootDir)}`;
132
+ }
133
+ }
134
+ if (!hasFormatSpecificTypes && primaryTypesPath) {
135
+ exportsField[exportKey].types = primaryTypesPath;
136
+ }
137
+ }
138
+ return exportsField;
139
+ }
140
+ function extractEntryPoints(exportsField, allDtsFiles) {
108
141
  const entryPoints = {};
109
- const filteredFiles = filterFiles(files);
110
- for (const file of filteredFiles) {
111
- const exportType = formatToExportField(file.format, file.dts);
112
- const relativePath = `./${cleanPath(file.relativePathToRootDir)}`;
113
- const exportKey = getExportKey(cleanPath(file.relativePathToOutputDir));
114
- exportsField[exportKey] = {
115
- ...exportsField[exportKey],
116
- [exportType]: relativePath
117
- };
142
+ const dotExport = exportsField["."];
143
+ if (!dotExport) {
144
+ return entryPoints;
118
145
  }
119
- for (const field of Object.keys(exportsField["."] ?? {})) {
146
+ for (const [field, value] of Object.entries(dotExport)) {
147
+ if (field === "types")
148
+ continue;
120
149
  const entryPoint = exportFieldToEntryPoint(field);
121
- entryPoints[entryPoint] = exportsField["."][field];
150
+ if (typeof value === "string") {
151
+ entryPoints[entryPoint] = value;
152
+ } else if (value && typeof value === "object" && "default" in value) {
153
+ entryPoints[entryPoint] = value.default;
154
+ }
122
155
  }
123
- return { exportsField, entryPoints };
156
+ const dotEntryDtsFiles = allDtsFiles.get(".");
157
+ if (dotEntryDtsFiles?.length) {
158
+ const standardDts = findStandardDtsFile(dotEntryDtsFiles);
159
+ if (standardDts) {
160
+ entryPoints.types = `./${cleanPath(standardDts.relativePathToRootDir)}`;
161
+ } else {
162
+ entryPoints.types = extractTypesFromExport(dotExport);
163
+ }
164
+ }
165
+ return entryPoints;
166
+ }
167
+ function findStandardDtsFile(dtsFiles) {
168
+ return dtsFiles.find((file) => file.relativePathToRootDir.endsWith(".d.ts") && !file.relativePathToRootDir.endsWith(".d.mts") && !file.relativePathToRootDir.endsWith(".d.cts"));
169
+ }
170
+ function extractTypesFromExport(dotExport) {
171
+ const typesValue = dotExport.types;
172
+ if (typeof typesValue === "string") {
173
+ return typesValue;
174
+ }
175
+ if (typesValue && typeof typesValue === "object" && "types" in typesValue) {
176
+ return typesValue.types;
177
+ }
178
+ const importValue = dotExport.import;
179
+ if (importValue && typeof importValue === "object" && "types" in importValue) {
180
+ return importValue.types;
181
+ }
182
+ return;
124
183
  }
125
- function filterFiles(files) {
126
- return files.filter((file) => JS_DTS_RE.test(file.fullPath) && file.kind === "entry-point");
184
+ function createUpdatedFilesArray(packageJsonData, outDir) {
185
+ const existingFiles = Array.isArray(packageJsonData.files) ? packageJsonData.files : [];
186
+ return [...new Set([...existingFiles, outDir])];
187
+ }
188
+ function mergeCustomExportsWithGenerated(baseExports, customExportsProvider, ctx) {
189
+ const mergedExports = { ...baseExports };
190
+ if (!customExportsProvider) {
191
+ return mergedExports;
192
+ }
193
+ const customExports = customExportsProvider(ctx);
194
+ if (!customExports) {
195
+ return mergedExports;
196
+ }
197
+ for (const [key, value] of Object.entries(customExports)) {
198
+ if (typeof value === "string") {
199
+ mergedExports[key] = value;
200
+ } else {
201
+ const existingExport = mergedExports[key];
202
+ if (typeof existingExport === "object" && existingExport !== null) {
203
+ mergedExports[key] = { ...existingExport, ...value };
204
+ } else {
205
+ mergedExports[key] = value;
206
+ }
207
+ }
208
+ }
209
+ return mergedExports;
210
+ }
211
+ function createUpdatedPackageJson(originalData, entryPoints, exports2, files) {
212
+ const { main, module, types, ...restPackageJson } = originalData;
213
+ const newPackageJson = {
214
+ name: originalData.name,
215
+ description: originalData.description,
216
+ version: originalData.version,
217
+ type: originalData.type,
218
+ private: originalData.private,
219
+ files,
220
+ ...entryPoints,
221
+ exports: exports2
222
+ };
223
+ for (const key in restPackageJson) {
224
+ if (Object.hasOwn(restPackageJson, key) && !Object.hasOwn(newPackageJson, key)) {
225
+ newPackageJson[key] = restPackageJson[key];
226
+ }
227
+ }
228
+ return newPackageJson;
229
+ }
230
+ function filterFiles(files, exclude, ctx) {
231
+ return files.filter((file) => JS_DTS_RE.test(file.fullPath) && file.kind === "entry-point" && file.entrypoint && (file.format === "esm" || file.format === "cjs") && !isExcluded(file.entrypoint, exclude, ctx));
232
+ }
233
+ function isExcluded(entrypoint, exclude, ctx) {
234
+ if (!exclude)
235
+ return false;
236
+ const patterns = typeof exclude === "function" ? exclude(ctx) : exclude;
237
+ return patterns?.some((pattern) => new Bun.Glob(pattern).match(entrypoint)) ?? false;
127
238
  }
128
239
  function getExportKey(relativePathToOutputDir) {
129
240
  const pathSegments = cleanPath(removeExtension(relativePathToOutputDir)).split("/");
130
241
  if (pathSegments.length === 1 && pathSegments[0].startsWith("index")) {
131
242
  return ".";
132
243
  }
133
- return `./${pathSegments.filter((p) => !p.startsWith("index")).join("/")}`;
134
- }
135
- function exportFieldToEntryPoint(exportField) {
136
- return exportField === "types" ? "types" : exportField === "require" ? "main" : "module";
137
- }
138
- function formatToExportField(format, dts) {
139
- return dts ? "types" : format === "esm" ? "import" : "require";
244
+ return `./${pathSegments.filter((segment) => !segment.startsWith("index")).join("/")}`;
140
245
  }
141
246
  function removeExtension(filePath) {
142
247
  const basename2 = path.basename(filePath);
@@ -148,6 +253,16 @@ function removeExtension(filePath) {
148
253
  const directory = path.dirname(filePath);
149
254
  return directory === "." ? nameWithoutExtensions : path.join(directory, nameWithoutExtensions);
150
255
  }
256
+ function exportFieldToEntryPoint(exportField) {
257
+ switch (exportField) {
258
+ case "types":
259
+ return "types";
260
+ case "require":
261
+ return "main";
262
+ default:
263
+ return "module";
264
+ }
265
+ }
151
266
  // src/plugins/built-in/inject-styles.ts
152
267
  import path2 from "path";
153
268
  function injectStyles(options) {
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.8.46",
4
+ "version": "0.8.48",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"
@@ -10,15 +10,16 @@
10
10
  "types": "./dist/index.d.ts",
11
11
  "exports": {
12
12
  ".": {
13
- "import": "./dist/index.js",
14
- "types": "./dist/index.d.ts"
13
+ "import": {
14
+ "types": "./dist/index.d.ts",
15
+ "default": "./dist/index.js"
16
+ }
15
17
  },
16
18
  "./plugins": {
17
- "import": "./dist/plugins.js",
18
- "types": "./dist/plugins.d.ts"
19
- },
20
- "./cli": {
21
- "import": "./dist/cli/index.js"
19
+ "import": {
20
+ "types": "./dist/plugins.d.ts",
21
+ "default": "./dist/plugins.js"
22
+ }
22
23
  }
23
24
  },
24
25
  "license": "MIT",