bunup 0.1.4 → 0.1.6

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/build/cli.js CHANGED
@@ -38,6 +38,9 @@ var handleError = (error, context) => {
38
38
  function escapeRegExp(string) {
39
39
  return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
40
40
  }
41
+ function generateRandomSuffix(length = 8) {
42
+ return Math.random().toString(36).substring(2, 2 + length);
43
+ }
41
44
  function getDefaultOutputExtension(format, packageType) {
42
45
  switch (format) {
43
46
  case "esm":
@@ -58,15 +61,9 @@ function getDefaultDtsExtention(format, packageType) {
58
61
  return ".d.ts";
59
62
  }
60
63
  }
61
- function getEntryNamingFormat(extension) {
62
- return `[dir]/[name]${extension}`;
63
- }
64
64
  function isModulePackage(packageType) {
65
65
  return packageType === "module";
66
66
  }
67
- function getEntryNameOnly(entry) {
68
- return entry.split("/").pop()?.split(".").slice(0, -1).join(".") || "";
69
- }
70
67
  function formatTime(ms) {
71
68
  return ms >= 1e3 ? `${(ms / 1e3).toFixed(2)}s` : `${Math.round(ms)}ms`;
72
69
  }
@@ -174,7 +171,6 @@ var DEFAULT_OPTIONS = {
174
171
  };
175
172
  function createDefaultBunBuildOptions(options, rootDir) {
176
173
  return {
177
- entrypoints: options.entry.map((e) => `${rootDir}/${e}`),
178
174
  outdir: `${rootDir}/${options.outDir}`,
179
175
  minify: createMinifyOptions(options),
180
176
  target: options.target,
@@ -446,10 +442,9 @@ function validateInputs(rootDir, entry) {
446
442
  self.onmessage = async (event) => {
447
443
  const { name, rootDir, outDir, entry, format, packageType, options } = event.data;
448
444
  try {
449
- const content = await generateDts(rootDir, entry, format, options);
450
- const entryName = getEntryNameOnly(entry);
445
+ const content = await generateDts(rootDir, entry.path, format, options);
451
446
  const extension = getDefaultDtsExtention(format, packageType);
452
- const outputRelativePath = `${outDir}/${entryName}${extension}`;
447
+ const outputRelativePath = `${outDir}/${entry.name}${extension}`;
453
448
  const outputPath = `${rootDir}/${outputRelativePath}`;
454
449
  await Bun.write(outputPath, content);
455
450
  const response = {
@@ -568,6 +563,38 @@ var DtsWorker = class {
568
563
  }
569
564
  };
570
565
 
566
+ // src/helpers/entry.ts
567
+ function getEntryNameOnly(entry) {
568
+ return entry.split("/").pop()?.split(".").slice(0, -1).join(".") || "";
569
+ }
570
+ function normalizeEntryToProcessableEntries(entry) {
571
+ const result = [];
572
+ const usedNames = /* @__PURE__ */ new Set();
573
+ function addEntry(name, path6) {
574
+ if (usedNames.has(name)) {
575
+ const randomSuffix = generateRandomSuffix();
576
+ result.push({ name: `${name}_${randomSuffix}`, path: path6 });
577
+ } else {
578
+ result.push({ name, path: path6 });
579
+ usedNames.add(name);
580
+ }
581
+ }
582
+ if (Array.isArray(entry)) {
583
+ for (const item of entry) {
584
+ const name = getEntryNameOnly(item);
585
+ addEntry(name, item);
586
+ }
587
+ } else {
588
+ Object.entries(entry).forEach(([name, path6]) => {
589
+ addEntry(name, path6);
590
+ });
591
+ }
592
+ return result;
593
+ }
594
+ function getEntryNamingFormat(name, extension) {
595
+ return `[dir]/${name}${extension}`;
596
+ }
597
+
571
598
  // src/plugins/external.ts
572
599
  function externalPlugin(externalPatterns, noExternalPatterns) {
573
600
  return {
@@ -600,8 +627,11 @@ async function build(options, rootDir) {
600
627
  const externalPatterns = getExternalPatterns(options, packageJson);
601
628
  const noExternalPatterns = getNoExternalPatterns(options);
602
629
  const plugins = [externalPlugin(externalPatterns, noExternalPatterns)];
630
+ const processableEntries = normalizeEntryToProcessableEntries(
631
+ options.entry
632
+ );
603
633
  const buildPromises = options.format.flatMap(
604
- (fmt) => options.entry.map(
634
+ (fmt) => processableEntries.map(
605
635
  (entry) => buildEntry(options, rootDir, entry, fmt, packageType, plugins)
606
636
  )
607
637
  );
@@ -623,10 +653,11 @@ async function build(options, rootDir) {
623
653
  }
624
654
  return true;
625
655
  });
656
+ const dtsEntry = options.dts === true ? processableEntries : normalizeEntryToProcessableEntries(options.dts.entry);
626
657
  const dtsWorker = new DtsWorker();
627
658
  try {
628
659
  const dtsPromises = formatsToProcess.flatMap(
629
- (fmt) => options.entry.map(
660
+ (fmt) => dtsEntry.map(
630
661
  (entry) => generateDtsForEntry(
631
662
  options,
632
663
  rootDir,
@@ -667,13 +698,12 @@ async function buildEntry(options, rootDir, entry, fmt, packageType, plugins) {
667
698
  );
668
699
  const result = await Bun.build({
669
700
  ...defaultBunBuildOptions,
670
- entrypoints: [`${rootDir}/${entry}`],
701
+ entrypoints: [`${rootDir}/${entry.path}`],
671
702
  format: fmt,
672
- naming: { entry: getEntryNamingFormat(extension) },
703
+ naming: { entry: getEntryNamingFormat(entry.name, extension) },
673
704
  splitting: getResolvedSplitting(options.splitting, fmt),
674
705
  plugins
675
706
  });
676
- const entryName = getEntryNameOnly(entry);
677
707
  if (!result.success) {
678
708
  result.logs.forEach((log) => {
679
709
  if (log.level === "error") logger.error(log.message);
@@ -684,7 +714,7 @@ async function buildEntry(options, rootDir, entry, fmt, packageType, plugins) {
684
714
  }
685
715
  logger.progress(
686
716
  getLoggerProgressLabel(fmt, options.name),
687
- `${options.outDir}/${entryName}${extension}`
717
+ `${options.outDir}/${entry.name}${extension}`
688
718
  );
689
719
  }
690
720
 
@@ -772,7 +802,9 @@ function parseCliOptions(argv) {
772
802
  if (!cliOptions.entry) {
773
803
  cliOptions.entry = [];
774
804
  }
775
- cliOptions.entry.push(arg);
805
+ if (Array.isArray(cliOptions.entry)) {
806
+ cliOptions.entry.push(arg);
807
+ }
776
808
  }
777
809
  }
778
810
  return cliOptions;
@@ -789,8 +821,9 @@ function parseCliOptions(argv) {
789
821
  })();
790
822
  async function watch(options, rootDir) {
791
823
  const watchPaths = /* @__PURE__ */ new Set();
792
- options.entry.forEach((entry) => {
793
- const entryPath = path2__default.default.resolve(rootDir, entry);
824
+ const normalizedEntry = normalizeEntryToProcessableEntries(options.entry);
825
+ normalizedEntry.forEach((entry) => {
826
+ const entryPath = path2__default.default.resolve(rootDir, entry.path);
794
827
  const parentDir = path2__default.default.dirname(entryPath);
795
828
  watchPaths.add(parentDir);
796
829
  });
package/build/cli.mjs CHANGED
@@ -28,6 +28,9 @@ var handleError = (error, context) => {
28
28
  function escapeRegExp(string) {
29
29
  return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
30
30
  }
31
+ function generateRandomSuffix(length = 8) {
32
+ return Math.random().toString(36).substring(2, 2 + length);
33
+ }
31
34
  function getDefaultOutputExtension(format, packageType) {
32
35
  switch (format) {
33
36
  case "esm":
@@ -48,15 +51,9 @@ function getDefaultDtsExtention(format, packageType) {
48
51
  return ".d.ts";
49
52
  }
50
53
  }
51
- function getEntryNamingFormat(extension) {
52
- return `[dir]/[name]${extension}`;
53
- }
54
54
  function isModulePackage(packageType) {
55
55
  return packageType === "module";
56
56
  }
57
- function getEntryNameOnly(entry) {
58
- return entry.split("/").pop()?.split(".").slice(0, -1).join(".") || "";
59
- }
60
57
  function formatTime(ms) {
61
58
  return ms >= 1e3 ? `${(ms / 1e3).toFixed(2)}s` : `${Math.round(ms)}ms`;
62
59
  }
@@ -164,7 +161,6 @@ var DEFAULT_OPTIONS = {
164
161
  };
165
162
  function createDefaultBunBuildOptions(options, rootDir) {
166
163
  return {
167
- entrypoints: options.entry.map((e) => `${rootDir}/${e}`),
168
164
  outdir: `${rootDir}/${options.outDir}`,
169
165
  minify: createMinifyOptions(options),
170
166
  target: options.target,
@@ -436,10 +432,9 @@ function validateInputs(rootDir, entry) {
436
432
  self.onmessage = async (event) => {
437
433
  const { name, rootDir, outDir, entry, format, packageType, options } = event.data;
438
434
  try {
439
- const content = await generateDts(rootDir, entry, format, options);
440
- const entryName = getEntryNameOnly(entry);
435
+ const content = await generateDts(rootDir, entry.path, format, options);
441
436
  const extension = getDefaultDtsExtention(format, packageType);
442
- const outputRelativePath = `${outDir}/${entryName}${extension}`;
437
+ const outputRelativePath = `${outDir}/${entry.name}${extension}`;
443
438
  const outputPath = `${rootDir}/${outputRelativePath}`;
444
439
  await Bun.write(outputPath, content);
445
440
  const response = {
@@ -558,6 +553,38 @@ var DtsWorker = class {
558
553
  }
559
554
  };
560
555
 
556
+ // src/helpers/entry.ts
557
+ function getEntryNameOnly(entry) {
558
+ return entry.split("/").pop()?.split(".").slice(0, -1).join(".") || "";
559
+ }
560
+ function normalizeEntryToProcessableEntries(entry) {
561
+ const result = [];
562
+ const usedNames = /* @__PURE__ */ new Set();
563
+ function addEntry(name, path6) {
564
+ if (usedNames.has(name)) {
565
+ const randomSuffix = generateRandomSuffix();
566
+ result.push({ name: `${name}_${randomSuffix}`, path: path6 });
567
+ } else {
568
+ result.push({ name, path: path6 });
569
+ usedNames.add(name);
570
+ }
571
+ }
572
+ if (Array.isArray(entry)) {
573
+ for (const item of entry) {
574
+ const name = getEntryNameOnly(item);
575
+ addEntry(name, item);
576
+ }
577
+ } else {
578
+ Object.entries(entry).forEach(([name, path6]) => {
579
+ addEntry(name, path6);
580
+ });
581
+ }
582
+ return result;
583
+ }
584
+ function getEntryNamingFormat(name, extension) {
585
+ return `[dir]/${name}${extension}`;
586
+ }
587
+
561
588
  // src/plugins/external.ts
562
589
  function externalPlugin(externalPatterns, noExternalPatterns) {
563
590
  return {
@@ -590,8 +617,11 @@ async function build(options, rootDir) {
590
617
  const externalPatterns = getExternalPatterns(options, packageJson);
591
618
  const noExternalPatterns = getNoExternalPatterns(options);
592
619
  const plugins = [externalPlugin(externalPatterns, noExternalPatterns)];
620
+ const processableEntries = normalizeEntryToProcessableEntries(
621
+ options.entry
622
+ );
593
623
  const buildPromises = options.format.flatMap(
594
- (fmt) => options.entry.map(
624
+ (fmt) => processableEntries.map(
595
625
  (entry) => buildEntry(options, rootDir, entry, fmt, packageType, plugins)
596
626
  )
597
627
  );
@@ -613,10 +643,11 @@ async function build(options, rootDir) {
613
643
  }
614
644
  return true;
615
645
  });
646
+ const dtsEntry = options.dts === true ? processableEntries : normalizeEntryToProcessableEntries(options.dts.entry);
616
647
  const dtsWorker = new DtsWorker();
617
648
  try {
618
649
  const dtsPromises = formatsToProcess.flatMap(
619
- (fmt) => options.entry.map(
650
+ (fmt) => dtsEntry.map(
620
651
  (entry) => generateDtsForEntry(
621
652
  options,
622
653
  rootDir,
@@ -657,13 +688,12 @@ async function buildEntry(options, rootDir, entry, fmt, packageType, plugins) {
657
688
  );
658
689
  const result = await Bun.build({
659
690
  ...defaultBunBuildOptions,
660
- entrypoints: [`${rootDir}/${entry}`],
691
+ entrypoints: [`${rootDir}/${entry.path}`],
661
692
  format: fmt,
662
- naming: { entry: getEntryNamingFormat(extension) },
693
+ naming: { entry: getEntryNamingFormat(entry.name, extension) },
663
694
  splitting: getResolvedSplitting(options.splitting, fmt),
664
695
  plugins
665
696
  });
666
- const entryName = getEntryNameOnly(entry);
667
697
  if (!result.success) {
668
698
  result.logs.forEach((log) => {
669
699
  if (log.level === "error") logger.error(log.message);
@@ -674,7 +704,7 @@ async function buildEntry(options, rootDir, entry, fmt, packageType, plugins) {
674
704
  }
675
705
  logger.progress(
676
706
  getLoggerProgressLabel(fmt, options.name),
677
- `${options.outDir}/${entryName}${extension}`
707
+ `${options.outDir}/${entry.name}${extension}`
678
708
  );
679
709
  }
680
710
 
@@ -762,7 +792,9 @@ function parseCliOptions(argv) {
762
792
  if (!cliOptions.entry) {
763
793
  cliOptions.entry = [];
764
794
  }
765
- cliOptions.entry.push(arg);
795
+ if (Array.isArray(cliOptions.entry)) {
796
+ cliOptions.entry.push(arg);
797
+ }
766
798
  }
767
799
  }
768
800
  return cliOptions;
@@ -779,8 +811,9 @@ function parseCliOptions(argv) {
779
811
  })();
780
812
  async function watch(options, rootDir) {
781
813
  const watchPaths = /* @__PURE__ */ new Set();
782
- options.entry.forEach((entry) => {
783
- const entryPath = path2.resolve(rootDir, entry);
814
+ const normalizedEntry = normalizeEntryToProcessableEntries(options.entry);
815
+ normalizedEntry.forEach((entry) => {
816
+ const entryPath = path2.resolve(rootDir, entry.path);
784
817
  const parentDir = path2.dirname(entryPath);
785
818
  watchPaths.add(parentDir);
786
819
  });
@@ -1 +1 @@
1
- 'use strict';var h=require('path'),y=require('fs'),N=require('oxc-transform'),rollup=require('rollup'),L=require('rollup-plugin-dts');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var h__default=/*#__PURE__*/_interopDefault(h);var y__default=/*#__PURE__*/_interopDefault(y);var N__default=/*#__PURE__*/_interopDefault(N);var L__default=/*#__PURE__*/_interopDefault(L);var f=r=>r instanceof Error?r.message:String(r);function w(r){return r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function $(r,t){switch(r){case "esm":return ".d.mts";case "cjs":return C(t)?".d.cts":".d.ts";case "iife":return ".d.ts"}}function C(r){return r==="module"}function b(r){return r.split("/").pop()?.split(".").slice(0,-1).join(".")||""}function D(r){return r?Array.from(new Set([...Object.keys(r.dependencies||{}),...Object.keys(r.peerDependencies||{})])):[]}function v(r){return r.map(t=>typeof t=="string"?new RegExp(`^${w(t)}($|\\/|\\\\)`):t)}function P(r,t){return v(r.external||[]).concat(D(t).map(e=>new RegExp(`^${w(e)}($|\\/|\\\\)`)))}function W(r){return v(r.noExternal||[])}var p={MAX_LABEL_LENGTH:5,colors:{cli:"183",info:"240",warn:"221",error:"203",progress:{ESM:"214",CJS:"114",IIFE:"105",DTS:"75"},default:"255"},labels:{cli:"BUNUP",info:"INFO",warn:"WARN",error:"ERROR"},formatMessage(r,t,e){let s=" ".repeat(Math.max(0,this.MAX_LABEL_LENGTH-t.length));return `\x1B[38;5;${r}m[${t}]\x1B[0m ${s}${e}`},cli(r){let t=this.labels.cli;console.log(this.formatMessage(this.colors.cli,t,r));},info(r){let t=this.labels.info;console.log(this.formatMessage(this.colors.info,t,r));},warn(r){let t=this.labels.warn;console.warn(this.formatMessage(this.colors.warn,t,r));},error(r){let t=this.labels.error;console.error(this.formatMessage(this.colors.error,t,r));},progress(r,t){let e=String(r),s=this.colors.default;for(let[n,o]of Object.entries(this.colors.progress))if(e.includes(n)){s=o;break}console.log(this.formatMessage(s,e,t));}};function S(r,t){return `${t?`${t.replace(/-/g,"_")}_`:""}${r}`.toUpperCase()}function O(r){let t=h__default.default.join(r,"package.json");try{if(!y__default.default.existsSync(t))return null;let e=y__default.default.readFileSync(t,"utf8");return JSON.parse(e)}catch(e){return p.error(`Failed to load package.json at ${t}: ${f(e)}`),null}}async function M(r,t,e,s){let{absoluteRootDir:n,absoluteEntry:o}=V(r,t),i=await _(o),a=await J(i);return q(o,a,e,s,n)}async function _(r){let t=new Set,e=[r];for(;e.length>0;){let s=e.pop();if(!(!s||t.has(s))){t.add(s);try{let n=await y__default.default.promises.readFile(s,"utf8"),o=U(n);for(let i of o){let a=h__default.default.dirname(s),l=h__default.default.resolve(a,i),m=[l,`${l}.ts`,`${l}.tsx`,`${l}/index.ts`,`${l}/index.tsx`];for(let g of m)if(y__default.default.existsSync(g)&&g.endsWith(".ts")&&!t.has(g)){e.push(g);break}}}catch(n){p.warn(`Error processing ${s}: ${n instanceof Error?n.message:String(n)}`);}}}return t}function U(r){let t=new Set;try{let e=/(?:import|export)(?:(?:[\s\n]*(?:type[\s\n]+)?(?:\*|\{[^}]*\}|[\w$]+)[\s\n]+from[\s\n]*)|[\s\n]+)(["'`])([^'"]+)\1/g,s;for(;(s=e.exec(r))!==null;){let i=s[2];i.startsWith(".")&&t.add(i);}let n=/import\s+(["'`])([^'"]+)\1\s*;?/g;for(;(s=n.exec(r))!==null;){let i=s[2];i.startsWith(".")&&t.add(i);}let o=/import\s*\(\s*(["'`])([^'"]+)\1\s*\)/g;for(;(s=o.exec(r))!==null;){let i=s[2];i.startsWith(".")&&t.add(i);}}catch(e){p.warn(`Error extracting imports: ${e instanceof Error?e.message:String(e)}`);}return Array.from(t)}async function J(r){let t=new Map;return await Promise.all(Array.from(r).map(async e=>{try{let s=e.replace(/\.tsx?$/,".d.ts"),n=await y__default.default.promises.readFile(e,"utf8"),{code:o}=N__default.default.isolatedDeclaration(e,n);o&&t.set(s,o);}catch(s){p.warn(`Failed to generate declaration for ${e}: ${s instanceof Error?s.message:String(s)}`);}})),t}async function q(r,t,e,s,n){let o="\0virtual:",i=r.replace(/\.tsx?$/,".d.ts"),a=`${o}${i}`,l={name:"virtual-dts",resolveId(c,u){if(c.startsWith(o))return c;if(u?.startsWith(o)){let d=u.slice(o.length),T=h__default.default.dirname(d);if(c.startsWith(".")){let F=h__default.default.resolve(T,c);for(let j of ["",".d.ts","/index.d.ts"]){let k=`${F}${j}`;if(t.has(k))return `${o}${k}`}}}return null},load(c){if(c.startsWith(o)){let u=c.slice(o.length);return t.get(u)||null}return null}},m=O(n),g=P(s,m),E=W(s),x;try{x=await rollup.rollup({input:a,onwarn(u,d){u.code==="UNRESOLVED_IMPORT"||u.code==="CIRCULAR_DEPENDENCY"||u.code==="EMPTY_BUNDLE"||d(u);},plugins:[l,L__default.default()],external:u=>g.some(d=>d.test(u))&&!E.some(d=>d.test(u))});let{output:c}=await x.generate({format:e});if(!c[0]?.code)throw new Error("Generated bundle is empty");return c[0].code}catch(c){throw new Error(`DTS bundling failed: ${f(c)}`)}finally{x&&await x.close();}}function V(r,t){let e=h__default.default.resolve(r),s=h__default.default.resolve(e,t);if(!y__default.default.existsSync(e))throw new Error(`Root directory does not exist: ${e}`);if(!y__default.default.existsSync(s))throw new Error(`Entry file does not exist: ${s}`);if(!s.endsWith(".ts"))throw new Error(`Entry file must be a TypeScript file (.ts): ${s}`);if(h__default.default.relative(e,s).startsWith(".."))throw new Error(`Entry file must be within rootDir: ${s}`);return {absoluteRootDir:e,absoluteEntry:s}}self.onmessage=async r=>{let{name:t,rootDir:e,outDir:s,entry:n,format:o,packageType:i,options:a}=r.data;try{let l=await M(e,n,o,a),m=b(n),g=$(o,i),E=`${s}/${m}${g}`,x=`${e}/${E}`;await Bun.write(x,l);let c={name:t,success:!0,outputRelativePath:E};self.postMessage(c);}catch(l){let m={success:false,error:f(l)};self.postMessage(m);}};var B=class{constructor(t=navigator.hardwareConcurrency||4){this.workers=[];this.queue=[];this.busyWorkers=new Set;this.isShuttingDown=false;this.maxWorkers=t;}async process(t){if(this.isShuttingDown)throw new Error("Worker pool is shutting down");return new Promise((e,s)=>{this.queue.push({task:t,resolve:e,reject:s}),this.processQueue();})}processQueue(){if(!(this.queue.length===0||this.isShuttingDown))if(this.workers.length<this.maxWorkers){let t=new Worker(h__default.default.join(__dirname,"./dtsWorker.js"));this.workers.push(t),this.assignTaskToWorker(t);}else {let t=this.workers.find(e=>!this.busyWorkers.has(e));t&&this.assignTaskToWorker(t);}}assignTaskToWorker(t){let e=this.queue.shift();if(!e)return;let{task:s,resolve:n,reject:o}=e;this.busyWorkers.add(t);let i=()=>{this.busyWorkers.delete(t),this.isShuttingDown&&this.busyWorkers.size===0?this.terminateAllWorkers():this.processQueue();};t.onmessage=a=>{a.data.success?(p.progress(S("DTS",a.data.name),a.data.outputRelativePath),n()):(p.error(`DTS generation failed: ${a.data.error}`),o(new Error(a.data.error))),i();},t.onerror=a=>{let l=f(a);p.error(`Worker error: ${l}`),o(a),i();},t.postMessage(s);}terminateAllWorkers(){this.workers.forEach(t=>{try{t.terminate();}catch(e){p.error(`Error terminating worker: ${f(e)}`);}}),this.workers=[],this.busyWorkers.clear();}async cleanup(){if(this.isShuttingDown=true,this.busyWorkers.size===0){this.terminateAllWorkers();return}return new Promise(t=>{let e=setInterval(()=>{this.busyWorkers.size===0&&(clearInterval(e),this.terminateAllWorkers(),t());},100);setTimeout(()=>{clearInterval(e),this.terminateAllWorkers(),t();},5e3);})}};exports.DtsWorker=B;
1
+ 'use strict';var h=require('path'),y=require('fs'),I=require('oxc-transform'),rollup=require('rollup'),N=require('rollup-plugin-dts');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var h__default=/*#__PURE__*/_interopDefault(h);var y__default=/*#__PURE__*/_interopDefault(y);var I__default=/*#__PURE__*/_interopDefault(I);var N__default=/*#__PURE__*/_interopDefault(N);var f=r=>r instanceof Error?r.message:String(r);function w(r){return r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function b(r,t){switch(r){case "esm":return ".d.mts";case "cjs":return j(t)?".d.cts":".d.ts";case "iife":return ".d.ts"}}function j(r){return r==="module"}function D(r){return r?Array.from(new Set([...Object.keys(r.dependencies||{}),...Object.keys(r.peerDependencies||{})])):[]}function $(r){return r.map(t=>typeof t=="string"?new RegExp(`^${w(t)}($|\\/|\\\\)`):t)}function v(r,t){return $(r.external||[]).concat(D(t).map(e=>new RegExp(`^${w(e)}($|\\/|\\\\)`)))}function P(r){return $(r.noExternal||[])}var p={MAX_LABEL_LENGTH:5,colors:{cli:"183",info:"240",warn:"221",error:"203",progress:{ESM:"214",CJS:"114",IIFE:"105",DTS:"75"},default:"255"},labels:{cli:"BUNUP",info:"INFO",warn:"WARN",error:"ERROR"},formatMessage(r,t,e){let o=" ".repeat(Math.max(0,this.MAX_LABEL_LENGTH-t.length));return `\x1B[38;5;${r}m[${t}]\x1B[0m ${o}${e}`},cli(r){let t=this.labels.cli;console.log(this.formatMessage(this.colors.cli,t,r));},info(r){let t=this.labels.info;console.log(this.formatMessage(this.colors.info,t,r));},warn(r){let t=this.labels.warn;console.warn(this.formatMessage(this.colors.warn,t,r));},error(r){let t=this.labels.error;console.error(this.formatMessage(this.colors.error,t,r));},progress(r,t){let e=String(r),o=this.colors.default;for(let[n,s]of Object.entries(this.colors.progress))if(e.includes(n)){o=s;break}console.log(this.formatMessage(o,e,t));}};function S(r,t){return `${t?`${t.replace(/-/g,"_")}_`:""}${r}`.toUpperCase()}function R(r){let t=h__default.default.join(r,"package.json");try{if(!y__default.default.existsSync(t))return null;let e=y__default.default.readFileSync(t,"utf8");return JSON.parse(e)}catch(e){return p.error(`Failed to load package.json at ${t}: ${f(e)}`),null}}async function O(r,t,e,o){let{absoluteRootDir:n,absoluteEntry:s}=q(r,t),i=await L(s),a=await U(i);return J(s,a,e,o,n)}async function L(r){let t=new Set,e=[r];for(;e.length>0;){let o=e.pop();if(!(!o||t.has(o))){t.add(o);try{let n=await y__default.default.promises.readFile(o,"utf8"),s=_(n);for(let i of s){let a=h__default.default.dirname(o),c=h__default.default.resolve(a,i),m=[c,`${c}.ts`,`${c}.tsx`,`${c}/index.ts`,`${c}/index.tsx`];for(let g of m)if(y__default.default.existsSync(g)&&g.endsWith(".ts")&&!t.has(g)){e.push(g);break}}}catch(n){p.warn(`Error processing ${o}: ${n instanceof Error?n.message:String(n)}`);}}}return t}function _(r){let t=new Set;try{let e=/(?:import|export)(?:(?:[\s\n]*(?:type[\s\n]+)?(?:\*|\{[^}]*\}|[\w$]+)[\s\n]+from[\s\n]*)|[\s\n]+)(["'`])([^'"]+)\1/g,o;for(;(o=e.exec(r))!==null;){let i=o[2];i.startsWith(".")&&t.add(i);}let n=/import\s+(["'`])([^'"]+)\1\s*;?/g;for(;(o=n.exec(r))!==null;){let i=o[2];i.startsWith(".")&&t.add(i);}let s=/import\s*\(\s*(["'`])([^'"]+)\1\s*\)/g;for(;(o=s.exec(r))!==null;){let i=o[2];i.startsWith(".")&&t.add(i);}}catch(e){p.warn(`Error extracting imports: ${e instanceof Error?e.message:String(e)}`);}return Array.from(t)}async function U(r){let t=new Map;return await Promise.all(Array.from(r).map(async e=>{try{let o=e.replace(/\.tsx?$/,".d.ts"),n=await y__default.default.promises.readFile(e,"utf8"),{code:s}=I__default.default.isolatedDeclaration(e,n);s&&t.set(o,s);}catch(o){p.warn(`Failed to generate declaration for ${e}: ${o instanceof Error?o.message:String(o)}`);}})),t}async function J(r,t,e,o,n){let s="\0virtual:",i=r.replace(/\.tsx?$/,".d.ts"),a=`${s}${i}`,c={name:"virtual-dts",resolveId(l,u){if(l.startsWith(s))return l;if(u?.startsWith(s)){let d=u.slice(s.length),B=h__default.default.dirname(d);if(l.startsWith(".")){let T=h__default.default.resolve(B,l);for(let F of ["",".d.ts","/index.d.ts"]){let k=`${T}${F}`;if(t.has(k))return `${s}${k}`}}}return null},load(l){if(l.startsWith(s)){let u=l.slice(s.length);return t.get(u)||null}return null}},m=R(n),g=v(o,m),E=P(o),x;try{x=await rollup.rollup({input:a,onwarn(u,d){u.code==="UNRESOLVED_IMPORT"||u.code==="CIRCULAR_DEPENDENCY"||u.code==="EMPTY_BUNDLE"||d(u);},plugins:[c,N__default.default()],external:u=>g.some(d=>d.test(u))&&!E.some(d=>d.test(u))});let{output:l}=await x.generate({format:e});if(!l[0]?.code)throw new Error("Generated bundle is empty");return l[0].code}catch(l){throw new Error(`DTS bundling failed: ${f(l)}`)}finally{x&&await x.close();}}function q(r,t){let e=h__default.default.resolve(r),o=h__default.default.resolve(e,t);if(!y__default.default.existsSync(e))throw new Error(`Root directory does not exist: ${e}`);if(!y__default.default.existsSync(o))throw new Error(`Entry file does not exist: ${o}`);if(!o.endsWith(".ts"))throw new Error(`Entry file must be a TypeScript file (.ts): ${o}`);if(h__default.default.relative(e,o).startsWith(".."))throw new Error(`Entry file must be within rootDir: ${o}`);return {absoluteRootDir:e,absoluteEntry:o}}self.onmessage=async r=>{let{name:t,rootDir:e,outDir:o,entry:n,format:s,packageType:i,options:a}=r.data;try{let c=await O(e,n.path,s,a),m=b(s,i),g=`${o}/${n.name}${m}`,E=`${e}/${g}`;await Bun.write(E,c);let x={name:t,success:!0,outputRelativePath:g};self.postMessage(x);}catch(c){let m={success:false,error:f(c)};self.postMessage(m);}};var M=class{constructor(t=navigator.hardwareConcurrency||4){this.workers=[];this.queue=[];this.busyWorkers=new Set;this.isShuttingDown=false;this.maxWorkers=t;}async process(t){if(this.isShuttingDown)throw new Error("Worker pool is shutting down");return new Promise((e,o)=>{this.queue.push({task:t,resolve:e,reject:o}),this.processQueue();})}processQueue(){if(!(this.queue.length===0||this.isShuttingDown))if(this.workers.length<this.maxWorkers){let t=new Worker(h__default.default.join(__dirname,"./dtsWorker.js"));this.workers.push(t),this.assignTaskToWorker(t);}else {let t=this.workers.find(e=>!this.busyWorkers.has(e));t&&this.assignTaskToWorker(t);}}assignTaskToWorker(t){let e=this.queue.shift();if(!e)return;let{task:o,resolve:n,reject:s}=e;this.busyWorkers.add(t);let i=()=>{this.busyWorkers.delete(t),this.isShuttingDown&&this.busyWorkers.size===0?this.terminateAllWorkers():this.processQueue();};t.onmessage=a=>{a.data.success?(p.progress(S("DTS",a.data.name),a.data.outputRelativePath),n()):(p.error(`DTS generation failed: ${a.data.error}`),s(new Error(a.data.error))),i();},t.onerror=a=>{let c=f(a);p.error(`Worker error: ${c}`),s(a),i();},t.postMessage(o);}terminateAllWorkers(){this.workers.forEach(t=>{try{t.terminate();}catch(e){p.error(`Error terminating worker: ${f(e)}`);}}),this.workers=[],this.busyWorkers.clear();}async cleanup(){if(this.isShuttingDown=true,this.busyWorkers.size===0){this.terminateAllWorkers();return}return new Promise(t=>{let e=setInterval(()=>{this.busyWorkers.size===0&&(clearInterval(e),this.terminateAllWorkers(),t());},100);setTimeout(()=>{clearInterval(e),this.terminateAllWorkers(),t();},5e3);})}};exports.DtsWorker=M;
package/build/index.d.mts CHANGED
@@ -3,6 +3,32 @@ type WithOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
3
3
  type Format = 'esm' | 'cjs' | 'iife';
4
4
  type Target = 'bun' | 'node' | 'browser';
5
5
  type External = string[];
6
+ type Entry = string[] | Record<string, string>;
7
+ type DtsOptions = {
8
+ /**
9
+ * Entry point files for TypeScript declaration file generation
10
+ *
11
+ * This can be:
12
+ * - An array of file paths
13
+ * - An object where keys are output names and values are input file paths
14
+ *
15
+ * The key names are used for the generated declaration files.
16
+ * For example, {custom: './src/index.ts'} will generate custom.d.ts
17
+ *
18
+ * If not specified, the main entry points will be used for declaration file generation.
19
+ *
20
+ * If a string path is provided in an array, the file name (without extension)
21
+ * will be used as the name for the output declaration file.
22
+ *
23
+ * @example
24
+ * // Using string paths in an array
25
+ * entry: ['./src/index.ts'] // Generates index.d.ts
26
+ *
27
+ * // Using named outputs as an object
28
+ * entry: { myModule: './src/index.ts', utils: './src/utility-functions.ts' } // Generates myModule.d.ts and utils.d.ts
29
+ */
30
+ entry: Entry;
31
+ };
6
32
  interface BunupOptions {
7
33
  /**
8
34
  * Name of the build configuration
@@ -11,9 +37,25 @@ interface BunupOptions {
11
37
  name?: string;
12
38
  /**
13
39
  * Entry point files for the build
14
- * These are the files that will be processed and bundled
40
+ *
41
+ * This can be:
42
+ * - An array of file paths
43
+ * - An object where keys are output names and values are input file paths
44
+ *
45
+ * The key names are used for the generated output files.
46
+ * For example, {custom: './src/index.ts'} will generate custom.js
47
+ *
48
+ * If a string path is provided in an array, the file name (without extension)
49
+ * will be used as the name for the output file.
50
+ *
51
+ * @example
52
+ * // Using string paths in an array
53
+ * entry: ['./src/index.ts'] // Generates index.js
54
+ *
55
+ * // Using named outputs as an object
56
+ * entry: { myModule: './src/index.ts', utils: './src/utility-functions.ts' } // Generates myModule.js and utils.js
15
57
  */
16
- entry: string[];
58
+ entry: Entry;
17
59
  /**
18
60
  * Output directory for the bundled files
19
61
  * Defaults to 'dist' if not specified
@@ -56,8 +98,10 @@ interface BunupOptions {
56
98
  watch?: boolean;
57
99
  /**
58
100
  * Whether to generate TypeScript declaration files (.d.ts)
101
+ * When set to true, generates declaration files for all entry points
102
+ * Can also be configured with DtsOptions for more control
59
103
  */
60
- dts?: boolean;
104
+ dts?: boolean | DtsOptions;
61
105
  /**
62
106
  * External packages that should not be bundled
63
107
  * Useful for dependencies that should be kept as external imports
package/build/index.d.ts CHANGED
@@ -3,6 +3,32 @@ type WithOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
3
3
  type Format = 'esm' | 'cjs' | 'iife';
4
4
  type Target = 'bun' | 'node' | 'browser';
5
5
  type External = string[];
6
+ type Entry = string[] | Record<string, string>;
7
+ type DtsOptions = {
8
+ /**
9
+ * Entry point files for TypeScript declaration file generation
10
+ *
11
+ * This can be:
12
+ * - An array of file paths
13
+ * - An object where keys are output names and values are input file paths
14
+ *
15
+ * The key names are used for the generated declaration files.
16
+ * For example, {custom: './src/index.ts'} will generate custom.d.ts
17
+ *
18
+ * If not specified, the main entry points will be used for declaration file generation.
19
+ *
20
+ * If a string path is provided in an array, the file name (without extension)
21
+ * will be used as the name for the output declaration file.
22
+ *
23
+ * @example
24
+ * // Using string paths in an array
25
+ * entry: ['./src/index.ts'] // Generates index.d.ts
26
+ *
27
+ * // Using named outputs as an object
28
+ * entry: { myModule: './src/index.ts', utils: './src/utility-functions.ts' } // Generates myModule.d.ts and utils.d.ts
29
+ */
30
+ entry: Entry;
31
+ };
6
32
  interface BunupOptions {
7
33
  /**
8
34
  * Name of the build configuration
@@ -11,9 +37,25 @@ interface BunupOptions {
11
37
  name?: string;
12
38
  /**
13
39
  * Entry point files for the build
14
- * These are the files that will be processed and bundled
40
+ *
41
+ * This can be:
42
+ * - An array of file paths
43
+ * - An object where keys are output names and values are input file paths
44
+ *
45
+ * The key names are used for the generated output files.
46
+ * For example, {custom: './src/index.ts'} will generate custom.js
47
+ *
48
+ * If a string path is provided in an array, the file name (without extension)
49
+ * will be used as the name for the output file.
50
+ *
51
+ * @example
52
+ * // Using string paths in an array
53
+ * entry: ['./src/index.ts'] // Generates index.js
54
+ *
55
+ * // Using named outputs as an object
56
+ * entry: { myModule: './src/index.ts', utils: './src/utility-functions.ts' } // Generates myModule.js and utils.js
15
57
  */
16
- entry: string[];
58
+ entry: Entry;
17
59
  /**
18
60
  * Output directory for the bundled files
19
61
  * Defaults to 'dist' if not specified
@@ -56,8 +98,10 @@ interface BunupOptions {
56
98
  watch?: boolean;
57
99
  /**
58
100
  * Whether to generate TypeScript declaration files (.d.ts)
101
+ * When set to true, generates declaration files for all entry points
102
+ * Can also be configured with DtsOptions for more control
59
103
  */
60
- dts?: boolean;
104
+ dts?: boolean | DtsOptions;
61
105
  /**
62
106
  * External packages that should not be bundled
63
107
  * Useful for dependencies that should be kept as external imports
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunup",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "A extremely fast, zero-config bundler for TypeScript & JavaScript, powered by Bun.",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",
@@ -18,13 +18,13 @@
18
18
  "@types/bun": "^1.2.5",
19
19
  "@typescript-eslint/eslint-plugin": "^7.3.1",
20
20
  "bumpp": "^10.1.0",
21
+ "bunup": "^0.1.5",
21
22
  "eslint": "^8.57.0",
22
23
  "husky": "^9.1.6",
23
24
  "prettier": "^3.2.5",
24
25
  "tsup": "^8.0.2",
25
26
  "typescript": "^5.4.3",
26
- "vitest": "^2.0.5",
27
- "bunup": "0.1.4"
27
+ "vitest": "^2.0.5"
28
28
  },
29
29
  "peerDependencies": {
30
30
  "typescript": ">=4.5.0"
@@ -61,7 +61,7 @@
61
61
  "scripts": {
62
62
  "build": "tsup",
63
63
  "dev": "tsup --watch",
64
- "test-build": "bunup",
64
+ "test-build": "pnpm -C tests build",
65
65
  "test": "vitest run",
66
66
  "tsc": "tsc --noEmit",
67
67
  "lint": "eslint src --fix",