bunup 0.1.8 → 0.1.10

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
@@ -1,5 +1,5 @@
1
- #!/usr/bin/env node
2
- var pr=require("node:module");var mr=Object.create;var{getPrototypeOf:gr,defineProperty:S,getOwnPropertyNames:X,getOwnPropertyDescriptor:xr}=Object,z=Object.prototype.hasOwnProperty;var g=(r,s,e)=>{e=r!=null?mr(gr(r)):{};let n=s||!r||!r.__esModule?S(e,"default",{value:r,enumerable:!0}):e;for(let t of X(r))if(!z.call(n,t))S(n,t,{get:()=>r[t],enumerable:!0});return n},I=new WeakMap,Or=(r)=>{var s=I.get(r),e;if(s)return s;if(s=S({},"__esModule",{value:!0}),r&&typeof r==="object"||typeof r==="function")X(r).map((n)=>!z.call(s,n)&&S(s,n,{get:()=>r[n],enumerable:!(e=xr(r,n))||e.enumerable}));return I.set(r,s),s};var wr=(r,s)=>{for(var e in s)S(r,e,{get:s[e],enumerable:!0,configurable:!0,set:(n)=>s[e]=()=>n})};var Ar={};wr(Ar,{main:()=>hr});module.exports=Or(Ar);var R=g(require("fs")),lr=g(require("path"));var er=g(require("path"));var $=g(require("fs")),d=g(require("path")),T=g(require("oxc-transform")),rr=require("rollup"),sr=g(require("rollup-plugin-dts"));var x=(r)=>{if(r instanceof Error)return r.message;return String(r)},K=(r,s)=>{let e=x(r),n=s?`[${s}] `:"";if(console.error(`\x1B[31m[ERROR]\x1B[0m ${n}${e}`),r instanceof Error&&r.stack)console.error("\x1B[2m"+r.stack.split(`
1
+ #!/usr/bin/env bun
2
+ "use strict"; function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs);var _path = require('path'); var _path2 = _interopRequireDefault(_path);var _os = require('os');var _worker_threads = require('worker_threads');var f=r=>r instanceof Error?r.message:String(r),v=(r,t)=>{let e=f(r),o=t?`[${t}] `:"";console.error(`\x1B[31m[ERROR]\x1B[0m ${o}${e}`),process.env.NODE_ENV!=="production"&&r instanceof Error&&r.stack&&console.error("\x1B[2m"+r.stack.split(`
3
3
  `).slice(1).join(`
4
- `)+"\x1B[0m")};function H(r){return r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Y(r=8){return Math.random().toString(36).substring(2,2+r)}function Z(r,s){switch(r){case"esm":return".mjs";case"cjs":return E(s)?".cjs":".js";case"iife":return".global.js"}}function D(r,s){switch(r){case"esm":return".d.mts";case"cjs":return E(s)?".d.cts":".d.ts";case"iife":return".d.ts"}}function E(r){return r==="module"}function q(r){return r>=1000?`${(r/1000).toFixed(2)}s`:`${Math.round(r)}ms`}function F(r){if(!r)return[];return Array.from(new Set([...Object.keys(r.dependencies||{}),...Object.keys(r.peerDependencies||{})]))}function J(r,s){return r===void 0?s==="esm":r}function V(r){return r.map((s)=>typeof s==="string"?new RegExp(`^${H(s)}($|\\/|\\\\)`):s)}function B(r,s){return V(r.external||[]).concat(F(s).map((e)=>new RegExp(`^${H(e)}($|\\/|\\\\)`)))}function C(r){return V(r.noExternal||[])}var k=g(require("fs")),U=g(require("path"));var c={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,s,e){let n=" ".repeat(Math.max(0,this.MAX_LABEL_LENGTH-s.length));return`\x1B[38;5;${r}m[${s}]\x1B[0m ${n}${e}`},cli(r){let s=this.labels.cli;console.log(this.formatMessage(this.colors.cli,s,r))},info(r){let s=this.labels.info;console.log(this.formatMessage(this.colors.info,s,r))},warn(r){let s=this.labels.warn;console.warn(this.formatMessage(this.colors.warn,s,r))},error(r){let s=this.labels.error;console.error(this.formatMessage(this.colors.error,s,r))},progress(r,s){let e=String(r),n=this.colors.default;for(let[t,i]of Object.entries(this.colors.progress))if(e.includes(t)){n=i;break}console.log(this.formatMessage(n,e,s))}};function y(r,s){return`${s?`${s.replace(/-/g,"_")}_`:""}${r}`.toUpperCase()}var W={entry:[],format:["esm"],outDir:"dist",minify:!1,watch:!1,dts:!1,target:"node",external:[],clean:!0};function P(r,s){return{outdir:`${s}/${r.outDir}`,minify:dr(r),target:r.target,splitting:r.splitting}}function dr(r){let{minify:s,minifyWhitespace:e,minifyIdentifiers:n,minifySyntax:t}=r,i=s===!0;return{whitespace:e??i,identifiers:n??i,syntax:t??i}}async function b(r){let s=[];for(let e of[".ts",".js",".mjs",".cjs",".mts",".cts",".json",".jsonc"]){let n=U.default.join(r,`bunup.config${e}`);try{if(!k.default.existsSync(n))continue;let t;if(e===".json"||e===".jsonc"){let i=k.default.readFileSync(n,"utf8");t=JSON.parse(i)}else{let i=await import(`file://${n}`);if(t=i.default||i,!t)c.warn(`No default export found in ${n}`),t={}}if(Array.isArray(t))for(let i of t)s.push({options:{...W,...i},rootDir:r});else s.push({options:{...W,...t},rootDir:r});break}catch(t){c.error(`Failed to load config from ${n}: ${x(t)}`)}if(s.length>0)break}return s}function j(r){let s=U.default.join(r,"package.json");try{if(!k.default.existsSync(s))return null;let e=k.default.readFileSync(s,"utf8");return JSON.parse(e)}catch(e){return c.error(`Failed to load package.json at ${s}: ${x(e)}`),null}}async function nr(r,s,e,n){let{absoluteRootDir:t,absoluteEntry:i}=vr(r,s),o=await Wr(i),u=await Sr(o);return kr(i,u,e,n,t)}async function Wr(r){let s=new Set,e=[r];while(e.length>0){let n=e.pop();if(!n||s.has(n))continue;s.add(n);try{let t=await $.default.promises.readFile(n,"utf8"),i=$r(t);for(let o of i){let u=d.default.dirname(n),a=d.default.resolve(u,o),f=[a,`${a}.ts`,`${a}.tsx`,`${a}/index.ts`,`${a}/index.tsx`];for(let l of f)if($.default.existsSync(l)&&l.endsWith(".ts")&&!s.has(l)){e.push(l);break}}}catch(t){c.warn(`Error processing ${n}: ${t instanceof Error?t.message:String(t)}`)}}return s}function $r(r){let s=new Set;try{let e=/(?:import|export)(?:(?:[\s\n]*(?:type[\s\n]+)?(?:\*|\{[^}]*\}|[\w$]+)[\s\n]+from[\s\n]*)|[\s\n]+)(["'`])([^'"]+)\1/g,n;while((n=e.exec(r))!==null){let o=n[2];if(o.startsWith("."))s.add(o)}let t=/import\s+(["'`])([^'"]+)\1\s*;?/g;while((n=t.exec(r))!==null){let o=n[2];if(o.startsWith("."))s.add(o)}let i=/import\s*\(\s*(["'`])([^'"]+)\1\s*\)/g;while((n=i.exec(r))!==null){let o=n[2];if(o.startsWith("."))s.add(o)}}catch(e){c.warn(`Error extracting imports: ${e instanceof Error?e.message:String(e)}`)}return Array.from(s)}async function Sr(r){let s=new Map;return await Promise.all(Array.from(r).map(async(e)=>{try{let n=e.replace(/\.tsx?$/,".d.ts"),t=await $.default.promises.readFile(e,"utf8"),{code:i}=T.default.isolatedDeclaration(e,t);if(i)s.set(n,i)}catch(n){c.warn(`Failed to generate declaration for ${e}: ${n instanceof Error?n.message:String(n)}`)}})),s}async function kr(r,s,e,n,t){let u=`\x00virtual:${r.replace(/\.tsx?$/,".d.ts")}`,a={name:"virtual-dts",resolveId(m,h){if(m.startsWith("\x00virtual:"))return m;if(h?.startsWith("\x00virtual:")){let w=h.slice(9),L=d.default.dirname(w);if(m.startsWith(".")){let _=d.default.resolve(L,m);for(let M of["",".d.ts","/index.d.ts"]){let G=`${_}${M}`;if(s.has(G))return`\x00virtual:${G}`}}}return null},load(m){if(m.startsWith("\x00virtual:")){let h=m.slice(9);return s.get(h)||null}return null}},f=j(t),l=B(n,f),O=C(n),p;try{p=await rr.rollup({input:u,onwarn(h,w){if(h.code==="UNRESOLVED_IMPORT"||h.code==="CIRCULAR_DEPENDENCY"||h.code==="EMPTY_BUNDLE")return;w(h)},plugins:[a,sr.default()],external:(h)=>l.some((w)=>w.test(h))&&!O.some((w)=>w.test(h))});let{output:m}=await p.generate({format:e});if(!m[0]?.code)throw new Error("Generated bundle is empty");return m[0].code}catch(m){throw new Error(`DTS bundling failed: ${x(m)}`)}finally{if(p)await p.close()}}function vr(r,s){let e=d.default.resolve(r),n=d.default.resolve(e,s);if(!$.default.existsSync(e))throw new Error(`Root directory does not exist: ${e}`);if(!$.default.existsSync(n))throw new Error(`Entry file does not exist: ${n}`);if(!n.endsWith(".ts"))throw new Error(`Entry file must be a TypeScript file (.ts): ${n}`);if(d.default.relative(e,n).startsWith(".."))throw new Error(`Entry file must be within rootDir: ${n}`);return{absoluteRootDir:e,absoluteEntry:n}}var __dirname="/home/runner/work/bunup/bunup/src/dts";self.onmessage=async(r)=>{let{name:s,rootDir:e,outDir:n,entry:t,format:i,packageType:o,options:u}=r.data;try{let a=await nr(e,t.path,i,u),f=D(i,o),l=`${n}/${t.name}${f}`,O=`${e}/${l}`;await Bun.write(O,a);let p={name:s,success:!0,outputRelativePath:l};self.postMessage(p)}catch(a){let f={success:!1,error:x(a)};self.postMessage(f)}};class Q{workers=[];queue=[];maxWorkers;busyWorkers=new Set;isShuttingDown=!1;constructor(r=navigator.hardwareConcurrency||4){this.maxWorkers=r}async process(r){if(this.isShuttingDown)throw new Error("Worker pool is shutting down");return new Promise((s,e)=>{this.queue.push({task:r,resolve:s,reject:e}),this.processQueue()})}processQueue(){if(this.queue.length===0||this.isShuttingDown)return;if(this.workers.length<this.maxWorkers){let r=new Worker(er.default.join(__dirname,"./dtsWorker.js"));this.workers.push(r),this.assignTaskToWorker(r)}else{let r=this.workers.find((s)=>!this.busyWorkers.has(s));if(r)this.assignTaskToWorker(r)}}assignTaskToWorker(r){let s=this.queue.shift();if(!s)return;let{task:e,resolve:n,reject:t}=s;this.busyWorkers.add(r);let i=()=>{if(this.busyWorkers.delete(r),this.isShuttingDown&&this.busyWorkers.size===0)this.terminateAllWorkers();else this.processQueue()};r.onmessage=(o)=>{if(o.data.success)c.progress(y("DTS",o.data.name),o.data.outputRelativePath),n();else c.error(`DTS generation failed: ${o.data.error}`),t(new Error(o.data.error));i()},r.onerror=(o)=>{let u=x(o);c.error(`Worker error: ${u}`),t(o),i()},r.postMessage(e)}terminateAllWorkers(){this.workers.forEach((r)=>{try{r.terminate()}catch(s){c.error(`Error terminating worker: ${x(s)}`)}}),this.workers=[],this.busyWorkers.clear()}async cleanup(){if(this.isShuttingDown=!0,this.busyWorkers.size===0){this.terminateAllWorkers();return}return new Promise((r)=>{let s=setInterval(()=>{if(this.busyWorkers.size===0)clearInterval(s),this.terminateAllWorkers(),r()},100);setTimeout(()=>{clearInterval(s),this.terminateAllWorkers(),r()},5000)})}}function Er(r){return r.split("/").pop()?.split(".").slice(0,-1).join(".")||""}function v(r){let s=[],e=new Set;function n(t,i){if(e.has(t)){let o=Y();s.push({name:`${t}_${o}`,path:i})}else s.push({name:t,path:i}),e.add(t)}if(Array.isArray(r))for(let t of r){let i=Er(t);n(i,t)}else Object.entries(r).forEach(([t,i])=>{n(t,i)});return s}function tr(r,s){return`[dir]/${r}${s}`}function ir(r,s){return{name:"bunup:external-plugin",setup(e){e.onResolve({filter:/.*/},(n)=>{let t=n.path;if(r.some((o)=>o.test(t))&&!s.some((o)=>o.test(t)))return{path:t,external:!0};return null})}}}async function A(r,s){if(!r.entry||r.entry.length===0||!r.outDir){c.cli("Nothing to build. Please make sure you have provided a proper bunup configuration or cli arguments.");return}let e=performance.now();c.cli("Build started");let n=j(s),t=n?.type,i=B(r,n),o=C(r),u=[ir(i,o)],a=v(r.entry),f=r.format.flatMap((l)=>a.map((O)=>Cr(r,s,O,l,t,u)));try{await Promise.all(f);let l=performance.now()-e,O=q(l);c.cli(`⚡ Build success in ${O}`)}catch(l){c.error("Build process encountered errors."),process.exit(1)}if(r.dts){let l=performance.now();c.progress("DTS","Bundling types");let O=r.format.filter((h)=>{if(h==="iife"&&!E(t)&&r.format.includes("cjs"))return!1;return!0}),p=r.dts===!0?a:v(r.dts.entry),m=new Q;try{let h=O.flatMap((_)=>p.map((M)=>Br(r,s,M,_,t,m)));await Promise.all(h);let w=performance.now()-l,L=q(w);c.progress("DTS",`Bundled types in ${L}`)}catch(h){await m.cleanup()}await m.cleanup()}}async function Br(r,s,e,n,t,i){let o={name:r.name,rootDir:s,outDir:r.outDir,entry:e,format:n,packageType:t,options:r};await i.process(o)}async function Cr(r,s,e,n,t,i){let o=Z(n,t),u=P(r,s),a=await Bun.build({...u,entrypoints:[`${s}/${e.path}`],format:n,naming:{entry:tr(e.name,o)},splitting:J(r.splitting,n),plugins:i});if(!a.success)throw a.logs.forEach((f)=>{if(f.level==="error")c.error(f.message);else if(f.level==="warning")c.warn(f.message);else if(f.level==="info")c.info(f.message)}),new Error(`Build failed for ${e} (${n})`);c.progress(y(n,r.name),`${r.outDir}/${e.name}${o}`)}var yr={n:"name",f:"format",o:"outDir",m:"minify",w:"watch",d:"dts",e:"external",t:"target",mw:"minifyWhitespace",mi:"minifyIdentifiers",ms:"minifySyntax",c:"clean",s:"splitting",ne:"noExternal"},jr={name:(r,s)=>{s.name=r},format:(r,s)=>{s.format=r.split(",")},outDir:(r,s)=>{s.outDir=r},minify:(r,s)=>{s.minify=!!r},watch:(r,s)=>{s.watch=!!r},dts:(r,s)=>{s.dts=!!r},external:(r,s)=>{s.external=r.split(",")},minifyWhitespace:(r,s)=>{s.minifyWhitespace=!!r},minifyIdentifiers:(r,s)=>{s.minifyIdentifiers=!!r},minifySyntax:(r,s)=>{s.minifySyntax=!!r},target:(r,s)=>{s.target=r},clean:(r,s)=>{s.clean=!!r},splitting:(r,s)=>{s.splitting=!!r},noExternal:(r,s)=>{s.noExternal=r.split(",")}};function or(r){let s={};for(let e=0;e<r.length;e++){let n=r[e];if(n.startsWith("--")||n.startsWith("-")){let t=n.startsWith("-")&&!n.startsWith("--"),i=t?n.slice(1):n.slice(2),o=t?yr[i]:i,u=jr[o];if(!u){c.error(`Unknown option: ${i}`);continue}let a=r[e+1],f=a&&!a.startsWith("-")?a:!0;if(u(f,s),typeof f==="string")e++}else{if(!s.entry)s.entry=[];if(Array.isArray(s.entry))s.entry.push(n)}}return s}(()=>{if(typeof Bun==="undefined")c.error(`Bunup requires Bun to run.
5
- To install Bun, visit https://bun.sh/docs/installation`),process.exit(1)})();var N=g(require("path")),cr=g(require("chokidar"));async function ar(r,s){let e=new Set;v(r.entry).forEach((a)=>{let f=N.default.resolve(s,a.path),l=N.default.dirname(f);e.add(l)});let t=cr.default.watch(Array.from(e),{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},atomic:!0,ignorePermissionErrors:!0,ignored:[/[\\/]\.git[\\/]/,/[\\/]node_modules[\\/]/,r.outDir]}),i=null,o=!1,u=async(a)=>{if(o)return;o=!0;try{await A({...r,entry:[a],clean:!1},s)}catch(f){c.error(`Build failed: ${f}`)}finally{o=!1}};t.on("change",(a)=>{let f=N.default.relative(s,a);if(c.cli(`File changed: ${f}`),i)clearTimeout(i);i=setTimeout(()=>u(f),300)}),t.on("error",(a)=>{c.error(`Watcher error: ${a}`)})}async function hr(r=Bun.argv.slice(2)){let s=or(r),e=await b(process.cwd()),n=process.cwd();if(s.watch)c.cli("Starting watch mode"),c.cli("Watching for file changes");if(e.length===0){let t={...W,...s};if(t.clean)ur(n,t.outDir);await fr(t,n)}else{for(let{options:t,rootDir:i}of e)if(t.clean)ur(i,t.outDir);await Promise.all(e.map(async({options:t,rootDir:i})=>{let o={...W,...t,...s};await fr(o,i)}))}if(!s.watch)process.exit(0)}async function fr(r,s){if(r.watch)await ar(r,s);else await A(r,s)}function ur(r,s){let e=lr.default.join(r,s);if(R.default.existsSync(e))try{R.default.rmSync(e,{recursive:!0,force:!0})}catch(n){c.error(`Failed to clean output directory: ${n}`)}R.default.mkdirSync(e,{recursive:!0})}hr().catch((r)=>{K(r),process.exit(1)});
4
+ `)+"\x1B[0m")};var i={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 h(r,t){return`${t?`${t.replace(/-/g,"_")}_`:""}${r}`.toUpperCase()}var x=class{constructor(t=_os.cpus.call(void 0, ).length||4){this.workers=[];this.queue=[];this.busyWorkers=new Set;this.isShuttingDown=!1;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 (0, _worker_threads.Worker)(_path2.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 a=()=>{this.busyWorkers.delete(t),this.isShuttingDown&&this.busyWorkers.size===0?this.terminateAllWorkers():this.processQueue()};t.on("message",u=>{u.success?(i.progress(h("DTS",u.name),u.outputRelativePath),n()):(i.error(`DTS generation failed: ${u.error}`),s(new Error(u.error))),a()}),t.on("error",u=>{let l=f(u);i.error(`Worker error: ${l}`),s(u),a()}),t.postMessage(o)}terminateAllWorkers(){this.workers.forEach(t=>{try{t.terminate()}catch(e){i.error(`Error terminating worker: ${f(e)}`)}}),this.workers=[],this.busyWorkers.clear()}async cleanup(){if(this.isShuttingDown=!0,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)})}};function k(r){return r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function S(r=8){return Math.random().toString(36).substring(2,2+r)}function T(r,t){switch(r){case"esm":return".mjs";case"cjs":return O(t)?".cjs":".js";case"iife":return".global.js"}}function O(r){return r==="module"}function P(r){return r>=1e3?`${(r/1e3).toFixed(2)}s`:`${Math.round(r)}ms`}function W(r){return r?Array.from(new Set([...Object.keys(r.dependencies||{}),...Object.keys(r.peerDependencies||{})])):[]}function $(r,t){return r===void 0?t==="esm":r}function Z(r){return _optionalChain([r, 'access', _2 => _2.split, 'call', _3 => _3("/"), 'access', _4 => _4.pop, 'call', _5 => _5(), 'optionalAccess', _6 => _6.split, 'call', _7 => _7("."), 'access', _8 => _8.slice, 'call', _9 => _9(0,-1), 'access', _10 => _10.join, 'call', _11 => _11(".")])||""}function d(r){let t=[],e=new Set;function o(n,s){if(e.has(n)){let a=S();t.push({name:`${n}_${a}`,path:s})}else t.push({name:n,path:s}),e.add(n)}if(Array.isArray(r))for(let n of r){let s=Z(n);o(s,n)}else Object.entries(r).forEach(([n,s])=>{o(n,s)});return t}function F(r,t){return`[dir]/${r}${t}`}function R(r){return r.map(t=>typeof t=="string"?new RegExp(`^${k(t)}($|\\/|\\\\)`):t)}function j(r,t){return R(r.external||[]).concat(W(t).map(e=>new RegExp(`^${k(e)}($|\\/|\\\\)`)))}function M(r){return R(r.noExternal||[])}var m={entry:[],format:["esm"],outDir:"dist",minify:!1,watch:!1,dts:!1,target:"node",external:[],clean:!0};function C(r,t){return{outdir:`${t}/${r.outDir}`,minify:rr(r),target:r.target,splitting:r.splitting}}function rr(r){let{minify:t,minifyWhitespace:e,minifyIdentifiers:o,minifySyntax:n}=r,s=t===!0;return{whitespace:_nullishCoalesce(e, () => (s)),identifiers:_nullishCoalesce(o, () => (s)),syntax:_nullishCoalesce(n, () => (s))}}async function N(r){let t=[];for(let e of[".ts",".js",".mjs",".cjs",".mts",".cts",".json",".jsonc"]){let o=_path2.default.join(r,`bunup.config${e}`);try{if(!_fs2.default.existsSync(o))continue;let n;if(e===".json"||e===".jsonc"){let s=_fs2.default.readFileSync(o,"utf8");n=JSON.parse(s)}else{let s=await Promise.resolve().then(() => _interopRequireWildcard(require(`file://${o}`)));n=s.default||s,n||(i.warn(`No default export found in ${o}`),n={})}if(Array.isArray(n))for(let s of n)t.push({options:{...m,...s},rootDir:r});else t.push({options:{...m,...n},rootDir:r});break}catch(n){i.error(`Failed to load config from ${o}: ${f(n)}`)}if(t.length>0)break}return t}function I(r){let t=_path2.default.join(r,"package.json");try{if(!_fs2.default.existsSync(t))return null;let e=_fs2.default.readFileSync(t,"utf8");return JSON.parse(e)}catch(e){return i.error(`Failed to load package.json at ${t}: ${f(e)}`),null}}function L(r,t){return{name:"bunup:external-plugin",setup(e){e.onResolve({filter:/.*/},o=>{let n=o.path;return r.some(a=>a.test(n))&&!t.some(a=>a.test(n))?{path:n,external:!0}:null})}}}async function w(r,t){if(!r.entry||r.entry.length===0||!r.outDir){i.cli("Nothing to build. Please make sure you have provided a proper bunup configuration or cli arguments.");return}let e=performance.now();i.cli("Build started");let o=I(t),n=_optionalChain([o, 'optionalAccess', _12 => _12.type]),s=j(r,o),a=M(r),u=[L(s,a)],l=d(r.entry),c=r.format.flatMap(p=>l.map(g=>er(r,t,g,p,n,u)));try{await Promise.all(c);let p=performance.now()-e,g=P(p);i.cli(`\u26A1 Build success in ${g}`)}catch (e2){i.error("Build process encountered errors."),process.exit(1)}if(r.dts){let p=performance.now();i.progress("DTS","Bundling types");let g=r.format.filter(y=>!(y==="iife"&&!O(n)&&r.format.includes("cjs"))),U=r.dts===!0?l:d(r.dts.entry),b=new x;try{let y=g.flatMap(G=>U.map(V=>tr(r,t,V,G,n,b)));await Promise.all(y);let q=performance.now()-p,Q=P(q);i.progress("DTS",`Bundled types in ${Q}`)}catch (e3){await b.cleanup()}await b.cleanup()}}async function tr(r,t,e,o,n,s){let a={name:r.name,rootDir:t,outDir:r.outDir,entry:e,format:o,packageType:n,options:r};await s.process(a)}async function er(r,t,e,o,n,s){let a=T(o,n),u=C(r,t),l=await Bun.build({...u,entrypoints:[`${t}/${e.path}`],format:o,naming:{entry:F(e.name,a)},splitting:$(r.splitting,o),plugins:s,throw:!1});if(!l.success)throw l.logs.forEach(c=>{c.level==="error"?i.error(c.message):c.level==="warning"?i.warn(c.message):c.level==="info"&&i.info(c.message)}),new Error(`Build failed for ${e} (${o})`);i.progress(h(o,r.name),`${r.outDir}/${e.name}${a}`)}var nr={n:"name",f:"format",o:"outDir",m:"minify",w:"watch",d:"dts",e:"external",t:"target",mw:"minifyWhitespace",mi:"minifyIdentifiers",ms:"minifySyntax",c:"clean",s:"splitting",ne:"noExternal"},or={name:(r,t)=>{t.name=r},format:(r,t)=>{t.format=r.split(",")},outDir:(r,t)=>{t.outDir=r},minify:(r,t)=>{t.minify=!!r},watch:(r,t)=>{t.watch=!!r},dts:(r,t)=>{t.dts=!!r},external:(r,t)=>{t.external=r.split(",")},minifyWhitespace:(r,t)=>{t.minifyWhitespace=!!r},minifyIdentifiers:(r,t)=>{t.minifyIdentifiers=!!r},minifySyntax:(r,t)=>{t.minifySyntax=!!r},target:(r,t)=>{t.target=r},clean:(r,t)=>{t.clean=!!r},splitting:(r,t)=>{t.splitting=!!r},noExternal:(r,t)=>{t.noExternal=r.split(",")}};function _(r){let t={};for(let e=0;e<r.length;e++){let o=r[e];if(o.startsWith("--")||o.startsWith("-")){let n=o.startsWith("-")&&!o.startsWith("--"),s=n?o.slice(1):o.slice(2),a=n?nr[s]:s,u=or[a];if(!u){i.error(`Unknown option: ${s}`);continue}let l=r[e+1],c=l&&!l.startsWith("-")?l:!0;u(c,t),typeof c=="string"&&e++}else t.entry||(t.entry=[]),Array.isArray(t.entry)&&t.entry.push(o)}return t}typeof Bun>"u"&&(i.error(`Bunup requires Bun to run.
5
+ To install Bun, visit https://bun.sh/docs/installation`),process.exit(1));var _chokidar = require('chokidar'); var _chokidar2 = _interopRequireDefault(_chokidar);async function z(r,t){let e=new Set;d(r.entry).forEach(l=>{let c=_path2.default.resolve(t,l.path),p=_path2.default.dirname(c);e.add(p)});let n=_chokidar2.default.watch(Array.from(e),{persistent:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},atomic:!0,ignorePermissionErrors:!0,ignored:[/[\\/]\.git[\\/]/,/[\\/]node_modules[\\/]/,r.outDir]}),s=null,a=!1,u=async l=>{if(!a){a=!0;try{await w({...r,entry:[l],clean:!1},t)}catch(c){i.error(`Build failed: ${c}`)}finally{a=!1}}};n.on("change",l=>{let c=_path2.default.relative(t,l);i.cli(`File changed: ${c}`),s&&clearTimeout(s),s=setTimeout(()=>u(c),300)}),n.on("error",l=>{i.error(`Watcher error: ${l}`)})}async function ar(r=Bun.argv.slice(2)){let t=_(r),e=await N(process.cwd()),o=process.cwd();if(t.watch&&(i.cli("Starting watch mode"),i.cli("Watching for file changes")),e.length===0){let n={...m,...t};n.clean&&J(o,n.outDir),await H(n,o)}else{for(let{options:n,rootDir:s}of e)n.clean&&J(s,n.outDir);await Promise.all(e.map(async({options:n,rootDir:s})=>{let a={...m,...n,...t};await H(a,s)}))}t.watch||process.exit(0)}async function H(r,t){r.watch?await z(r,t):await w(r,t)}function J(r,t){let e=_path2.default.join(r,t);if(_fs2.default.existsSync(e))try{_fs2.default.rmSync(e,{recursive:!0,force:!0})}catch(o){i.error(`Failed to clean output directory: ${o}`)}_fs2.default.mkdirSync(e,{recursive:!0})}ar().catch(r=>{v(r),process.exit(1)});
package/build/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
- #!/usr/bin/env node
2
- import H from"fs";import wr from"path";import ur from"path";import W from"fs";import p from"path";import nr from"oxc-transform";import{rollup as er}from"rollup";import tr from"rollup-plugin-dts";var g=(r)=>{if(r instanceof Error)return r.message;return String(r)},U=(r,s)=>{let e=g(r),n=s?`[${s}] `:"";if(console.error(`\x1B[31m[ERROR]\x1B[0m ${n}${e}`),r instanceof Error&&r.stack)console.error("\x1B[2m"+r.stack.split(`
1
+ #!/usr/bin/env bun
2
+ import D from"fs";import ir from"path";import{cpus as X}from"os";import K from"path";import{Worker as Y}from"worker_threads";var f=r=>r instanceof Error?r.message:String(r),v=(r,t)=>{let e=f(r),o=t?`[${t}] `:"";console.error(`\x1B[31m[ERROR]\x1B[0m ${o}${e}`),process.env.NODE_ENV!=="production"&&r instanceof Error&&r.stack&&console.error("\x1B[2m"+r.stack.split(`
3
3
  `).slice(1).join(`
4
- `)+"\x1B[0m")};function R(r){return r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Q(r=8){return Math.random().toString(36).substring(2,2+r)}function G(r,s){switch(r){case"esm":return".mjs";case"cjs":return S(s)?".cjs":".js";case"iife":return".global.js"}}function I(r,s){switch(r){case"esm":return".d.mts";case"cjs":return S(s)?".d.cts":".d.ts";case"iife":return".d.ts"}}function S(r){return r==="module"}function L(r){return r>=1000?`${(r/1000).toFixed(2)}s`:`${Math.round(r)}ms`}function X(r){if(!r)return[];return Array.from(new Set([...Object.keys(r.dependencies||{}),...Object.keys(r.peerDependencies||{})]))}function z(r,s){return r===void 0?s==="esm":r}function K(r){return r.map((s)=>typeof s==="string"?new RegExp(`^${R(s)}($|\\/|\\\\)`):s)}function k(r,s){return K(r.external||[]).concat(X(s).map((e)=>new RegExp(`^${R(e)}($|\\/|\\\\)`)))}function v(r){return K(r.noExternal||[])}import B from"fs";import Z from"path";var c={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,s,e){let n=" ".repeat(Math.max(0,this.MAX_LABEL_LENGTH-s.length));return`\x1B[38;5;${r}m[${s}]\x1B[0m ${n}${e}`},cli(r){let s=this.labels.cli;console.log(this.formatMessage(this.colors.cli,s,r))},info(r){let s=this.labels.info;console.log(this.formatMessage(this.colors.info,s,r))},warn(r){let s=this.labels.warn;console.warn(this.formatMessage(this.colors.warn,s,r))},error(r){let s=this.labels.error;console.error(this.formatMessage(this.colors.error,s,r))},progress(r,s){let e=String(r),n=this.colors.default;for(let[t,i]of Object.entries(this.colors.progress))if(e.includes(t)){n=i;break}console.log(this.formatMessage(n,e,s))}};function E(r,s){return`${s?`${s.replace(/-/g,"_")}_`:""}${r}`.toUpperCase()}var d={entry:[],format:["esm"],outDir:"dist",minify:!1,watch:!1,dts:!1,target:"node",external:[],clean:!0};function Y(r,s){return{outdir:`${s}/${r.outDir}`,minify:sr(r),target:r.target,splitting:r.splitting}}function sr(r){let{minify:s,minifyWhitespace:e,minifyIdentifiers:n,minifySyntax:t}=r,i=s===!0;return{whitespace:e??i,identifiers:n??i,syntax:t??i}}async function D(r){let s=[];for(let e of[".ts",".js",".mjs",".cjs",".mts",".cts",".json",".jsonc"]){let n=Z.join(r,`bunup.config${e}`);try{if(!B.existsSync(n))continue;let t;if(e===".json"||e===".jsonc"){let i=B.readFileSync(n,"utf8");t=JSON.parse(i)}else{let i=await import(`file://${n}`);if(t=i.default||i,!t)c.warn(`No default export found in ${n}`),t={}}if(Array.isArray(t))for(let i of t)s.push({options:{...d,...i},rootDir:r});else s.push({options:{...d,...t},rootDir:r});break}catch(t){c.error(`Failed to load config from ${n}: ${g(t)}`)}if(s.length>0)break}return s}function C(r){let s=Z.join(r,"package.json");try{if(!B.existsSync(s))return null;let e=B.readFileSync(s,"utf8");return JSON.parse(e)}catch(e){return c.error(`Failed to load package.json at ${s}: ${g(e)}`),null}}async function F(r,s,e,n){let{absoluteRootDir:t,absoluteEntry:i}=fr(r,s),o=await ir(i),u=await cr(o);return ar(i,u,e,n,t)}async function ir(r){let s=new Set,e=[r];while(e.length>0){let n=e.pop();if(!n||s.has(n))continue;s.add(n);try{let t=await W.promises.readFile(n,"utf8"),i=or(t);for(let o of i){let u=p.dirname(n),a=p.resolve(u,o),f=[a,`${a}.ts`,`${a}.tsx`,`${a}/index.ts`,`${a}/index.tsx`];for(let l of f)if(W.existsSync(l)&&l.endsWith(".ts")&&!s.has(l)){e.push(l);break}}}catch(t){c.warn(`Error processing ${n}: ${t instanceof Error?t.message:String(t)}`)}}return s}function or(r){let s=new Set;try{let e=/(?:import|export)(?:(?:[\s\n]*(?:type[\s\n]+)?(?:\*|\{[^}]*\}|[\w$]+)[\s\n]+from[\s\n]*)|[\s\n]+)(["'`])([^'"]+)\1/g,n;while((n=e.exec(r))!==null){let o=n[2];if(o.startsWith("."))s.add(o)}let t=/import\s+(["'`])([^'"]+)\1\s*;?/g;while((n=t.exec(r))!==null){let o=n[2];if(o.startsWith("."))s.add(o)}let i=/import\s*\(\s*(["'`])([^'"]+)\1\s*\)/g;while((n=i.exec(r))!==null){let o=n[2];if(o.startsWith("."))s.add(o)}}catch(e){c.warn(`Error extracting imports: ${e instanceof Error?e.message:String(e)}`)}return Array.from(s)}async function cr(r){let s=new Map;return await Promise.all(Array.from(r).map(async(e)=>{try{let n=e.replace(/\.tsx?$/,".d.ts"),t=await W.promises.readFile(e,"utf8"),{code:i}=nr.isolatedDeclaration(e,t);if(i)s.set(n,i)}catch(n){c.warn(`Failed to generate declaration for ${e}: ${n instanceof Error?n.message:String(n)}`)}})),s}async function ar(r,s,e,n,t){let u=`\x00virtual:${r.replace(/\.tsx?$/,".d.ts")}`,a={name:"virtual-dts",resolveId(m,h){if(m.startsWith("\x00virtual:"))return m;if(h?.startsWith("\x00virtual:")){let O=h.slice(9),j=p.dirname(O);if(m.startsWith(".")){let A=p.resolve(j,m);for(let N of["",".d.ts","/index.d.ts"]){let q=`${A}${N}`;if(s.has(q))return`\x00virtual:${q}`}}}return null},load(m){if(m.startsWith("\x00virtual:")){let h=m.slice(9);return s.get(h)||null}return null}},f=C(t),l=k(n,f),x=v(n),w;try{w=await er({input:u,onwarn(h,O){if(h.code==="UNRESOLVED_IMPORT"||h.code==="CIRCULAR_DEPENDENCY"||h.code==="EMPTY_BUNDLE")return;O(h)},plugins:[a,tr()],external:(h)=>l.some((O)=>O.test(h))&&!x.some((O)=>O.test(h))});let{output:m}=await w.generate({format:e});if(!m[0]?.code)throw new Error("Generated bundle is empty");return m[0].code}catch(m){throw new Error(`DTS bundling failed: ${g(m)}`)}finally{if(w)await w.close()}}function fr(r,s){let e=p.resolve(r),n=p.resolve(e,s);if(!W.existsSync(e))throw new Error(`Root directory does not exist: ${e}`);if(!W.existsSync(n))throw new Error(`Entry file does not exist: ${n}`);if(!n.endsWith(".ts"))throw new Error(`Entry file must be a TypeScript file (.ts): ${n}`);if(p.relative(e,n).startsWith(".."))throw new Error(`Entry file must be within rootDir: ${n}`);return{absoluteRootDir:e,absoluteEntry:n}}var __dirname="/home/runner/work/bunup/bunup/src/dts";self.onmessage=async(r)=>{let{name:s,rootDir:e,outDir:n,entry:t,format:i,packageType:o,options:u}=r.data;try{let a=await F(e,t.path,i,u),f=I(i,o),l=`${n}/${t.name}${f}`,x=`${e}/${l}`;await Bun.write(x,a);let w={name:s,success:!0,outputRelativePath:l};self.postMessage(w)}catch(a){let f={success:!1,error:g(a)};self.postMessage(f)}};class _{workers=[];queue=[];maxWorkers;busyWorkers=new Set;isShuttingDown=!1;constructor(r=navigator.hardwareConcurrency||4){this.maxWorkers=r}async process(r){if(this.isShuttingDown)throw new Error("Worker pool is shutting down");return new Promise((s,e)=>{this.queue.push({task:r,resolve:s,reject:e}),this.processQueue()})}processQueue(){if(this.queue.length===0||this.isShuttingDown)return;if(this.workers.length<this.maxWorkers){let r=new Worker(ur.join(__dirname,"./dtsWorker.js"));this.workers.push(r),this.assignTaskToWorker(r)}else{let r=this.workers.find((s)=>!this.busyWorkers.has(s));if(r)this.assignTaskToWorker(r)}}assignTaskToWorker(r){let s=this.queue.shift();if(!s)return;let{task:e,resolve:n,reject:t}=s;this.busyWorkers.add(r);let i=()=>{if(this.busyWorkers.delete(r),this.isShuttingDown&&this.busyWorkers.size===0)this.terminateAllWorkers();else this.processQueue()};r.onmessage=(o)=>{if(o.data.success)c.progress(E("DTS",o.data.name),o.data.outputRelativePath),n();else c.error(`DTS generation failed: ${o.data.error}`),t(new Error(o.data.error));i()},r.onerror=(o)=>{let u=g(o);c.error(`Worker error: ${u}`),t(o),i()},r.postMessage(e)}terminateAllWorkers(){this.workers.forEach((r)=>{try{r.terminate()}catch(s){c.error(`Error terminating worker: ${g(s)}`)}}),this.workers=[],this.busyWorkers.clear()}async cleanup(){if(this.isShuttingDown=!0,this.busyWorkers.size===0){this.terminateAllWorkers();return}return new Promise((r)=>{let s=setInterval(()=>{if(this.busyWorkers.size===0)clearInterval(s),this.terminateAllWorkers(),r()},100);setTimeout(()=>{clearInterval(s),this.terminateAllWorkers(),r()},5000)})}}function lr(r){return r.split("/").pop()?.split(".").slice(0,-1).join(".")||""}function $(r){let s=[],e=new Set;function n(t,i){if(e.has(t)){let o=Q();s.push({name:`${t}_${o}`,path:i})}else s.push({name:t,path:i}),e.add(t)}if(Array.isArray(r))for(let t of r){let i=lr(t);n(i,t)}else Object.entries(r).forEach(([t,i])=>{n(t,i)});return s}function J(r,s){return`[dir]/${r}${s}`}function V(r,s){return{name:"bunup:external-plugin",setup(e){e.onResolve({filter:/.*/},(n)=>{let t=n.path;if(r.some((o)=>o.test(t))&&!s.some((o)=>o.test(t)))return{path:t,external:!0};return null})}}}async function y(r,s){if(!r.entry||r.entry.length===0||!r.outDir){c.cli("Nothing to build. Please make sure you have provided a proper bunup configuration or cli arguments.");return}let e=performance.now();c.cli("Build started");let n=C(s),t=n?.type,i=k(r,n),o=v(r),u=[V(i,o)],a=$(r.entry),f=r.format.flatMap((l)=>a.map((x)=>mr(r,s,x,l,t,u)));try{await Promise.all(f);let l=performance.now()-e,x=L(l);c.cli(`⚡ Build success in ${x}`)}catch(l){c.error("Build process encountered errors."),process.exit(1)}if(r.dts){let l=performance.now();c.progress("DTS","Bundling types");let x=r.format.filter((h)=>{if(h==="iife"&&!S(t)&&r.format.includes("cjs"))return!1;return!0}),w=r.dts===!0?a:$(r.dts.entry),m=new _;try{let h=x.flatMap((A)=>w.map((N)=>hr(r,s,N,A,t,m)));await Promise.all(h);let O=performance.now()-l,j=L(O);c.progress("DTS",`Bundled types in ${j}`)}catch(h){await m.cleanup()}await m.cleanup()}}async function hr(r,s,e,n,t,i){let o={name:r.name,rootDir:s,outDir:r.outDir,entry:e,format:n,packageType:t,options:r};await i.process(o)}async function mr(r,s,e,n,t,i){let o=G(n,t),u=Y(r,s),a=await Bun.build({...u,entrypoints:[`${s}/${e.path}`],format:n,naming:{entry:J(e.name,o)},splitting:z(r.splitting,n),plugins:i});if(!a.success)throw a.logs.forEach((f)=>{if(f.level==="error")c.error(f.message);else if(f.level==="warning")c.warn(f.message);else if(f.level==="info")c.info(f.message)}),new Error(`Build failed for ${e} (${n})`);c.progress(E(n,r.name),`${r.outDir}/${e.name}${o}`)}var gr={n:"name",f:"format",o:"outDir",m:"minify",w:"watch",d:"dts",e:"external",t:"target",mw:"minifyWhitespace",mi:"minifyIdentifiers",ms:"minifySyntax",c:"clean",s:"splitting",ne:"noExternal"},xr={name:(r,s)=>{s.name=r},format:(r,s)=>{s.format=r.split(",")},outDir:(r,s)=>{s.outDir=r},minify:(r,s)=>{s.minify=!!r},watch:(r,s)=>{s.watch=!!r},dts:(r,s)=>{s.dts=!!r},external:(r,s)=>{s.external=r.split(",")},minifyWhitespace:(r,s)=>{s.minifyWhitespace=!!r},minifyIdentifiers:(r,s)=>{s.minifyIdentifiers=!!r},minifySyntax:(r,s)=>{s.minifySyntax=!!r},target:(r,s)=>{s.target=r},clean:(r,s)=>{s.clean=!!r},splitting:(r,s)=>{s.splitting=!!r},noExternal:(r,s)=>{s.noExternal=r.split(",")}};function P(r){let s={};for(let e=0;e<r.length;e++){let n=r[e];if(n.startsWith("--")||n.startsWith("-")){let t=n.startsWith("-")&&!n.startsWith("--"),i=t?n.slice(1):n.slice(2),o=t?gr[i]:i,u=xr[o];if(!u){c.error(`Unknown option: ${i}`);continue}let a=r[e+1],f=a&&!a.startsWith("-")?a:!0;if(u(f,s),typeof f==="string")e++}else{if(!s.entry)s.entry=[];if(Array.isArray(s.entry))s.entry.push(n)}}return s}(()=>{if(typeof Bun==="undefined")c.error(`Bunup requires Bun to run.
5
- To install Bun, visit https://bun.sh/docs/installation`),process.exit(1)})();import M from"path";import Or from"chokidar";async function b(r,s){let e=new Set;$(r.entry).forEach((a)=>{let f=M.resolve(s,a.path),l=M.dirname(f);e.add(l)});let t=Or.watch(Array.from(e),{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},atomic:!0,ignorePermissionErrors:!0,ignored:[/[\\/]\.git[\\/]/,/[\\/]node_modules[\\/]/,r.outDir]}),i=null,o=!1,u=async(a)=>{if(o)return;o=!0;try{await y({...r,entry:[a],clean:!1},s)}catch(f){c.error(`Build failed: ${f}`)}finally{o=!1}};t.on("change",(a)=>{let f=M.relative(s,a);if(c.cli(`File changed: ${f}`),i)clearTimeout(i);i=setTimeout(()=>u(f),300)}),t.on("error",(a)=>{c.error(`Watcher error: ${a}`)})}async function pr(r=Bun.argv.slice(2)){let s=P(r),e=await D(process.cwd()),n=process.cwd();if(s.watch)c.cli("Starting watch mode"),c.cli("Watching for file changes");if(e.length===0){let t={...d,...s};if(t.clean)rr(n,t.outDir);await T(t,n)}else{for(let{options:t,rootDir:i}of e)if(t.clean)rr(i,t.outDir);await Promise.all(e.map(async({options:t,rootDir:i})=>{let o={...d,...t,...s};await T(o,i)}))}if(!s.watch)process.exit(0)}async function T(r,s){if(r.watch)await b(r,s);else await y(r,s)}function rr(r,s){let e=wr.join(r,s);if(H.existsSync(e))try{H.rmSync(e,{recursive:!0,force:!0})}catch(n){c.error(`Failed to clean output directory: ${n}`)}H.mkdirSync(e,{recursive:!0})}pr().catch((r)=>{U(r),process.exit(1)});export{pr as main};
4
+ `)+"\x1B[0m")};var i={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 h(r,t){return`${t?`${t.replace(/-/g,"_")}_`:""}${r}`.toUpperCase()}var x=class{constructor(t=X().length||4){this.workers=[];this.queue=[];this.busyWorkers=new Set;this.isShuttingDown=!1;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 Y(K.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 a=()=>{this.busyWorkers.delete(t),this.isShuttingDown&&this.busyWorkers.size===0?this.terminateAllWorkers():this.processQueue()};t.on("message",u=>{u.success?(i.progress(h("DTS",u.name),u.outputRelativePath),n()):(i.error(`DTS generation failed: ${u.error}`),s(new Error(u.error))),a()}),t.on("error",u=>{let l=f(u);i.error(`Worker error: ${l}`),s(u),a()}),t.postMessage(o)}terminateAllWorkers(){this.workers.forEach(t=>{try{t.terminate()}catch(e){i.error(`Error terminating worker: ${f(e)}`)}}),this.workers=[],this.busyWorkers.clear()}async cleanup(){if(this.isShuttingDown=!0,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)})}};function k(r){return r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function S(r=8){return Math.random().toString(36).substring(2,2+r)}function T(r,t){switch(r){case"esm":return".mjs";case"cjs":return O(t)?".cjs":".js";case"iife":return".global.js"}}function O(r){return r==="module"}function P(r){return r>=1e3?`${(r/1e3).toFixed(2)}s`:`${Math.round(r)}ms`}function W(r){return r?Array.from(new Set([...Object.keys(r.dependencies||{}),...Object.keys(r.peerDependencies||{})])):[]}function $(r,t){return r===void 0?t==="esm":r}function Z(r){return r.split("/").pop()?.split(".").slice(0,-1).join(".")||""}function d(r){let t=[],e=new Set;function o(n,s){if(e.has(n)){let a=S();t.push({name:`${n}_${a}`,path:s})}else t.push({name:n,path:s}),e.add(n)}if(Array.isArray(r))for(let n of r){let s=Z(n);o(s,n)}else Object.entries(r).forEach(([n,s])=>{o(n,s)});return t}function F(r,t){return`[dir]/${r}${t}`}function R(r){return r.map(t=>typeof t=="string"?new RegExp(`^${k(t)}($|\\/|\\\\)`):t)}function j(r,t){return R(r.external||[]).concat(W(t).map(e=>new RegExp(`^${k(e)}($|\\/|\\\\)`)))}function M(r){return R(r.noExternal||[])}import E from"fs";import A from"path";var m={entry:[],format:["esm"],outDir:"dist",minify:!1,watch:!1,dts:!1,target:"node",external:[],clean:!0};function C(r,t){return{outdir:`${t}/${r.outDir}`,minify:rr(r),target:r.target,splitting:r.splitting}}function rr(r){let{minify:t,minifyWhitespace:e,minifyIdentifiers:o,minifySyntax:n}=r,s=t===!0;return{whitespace:e??s,identifiers:o??s,syntax:n??s}}async function N(r){let t=[];for(let e of[".ts",".js",".mjs",".cjs",".mts",".cts",".json",".jsonc"]){let o=A.join(r,`bunup.config${e}`);try{if(!E.existsSync(o))continue;let n;if(e===".json"||e===".jsonc"){let s=E.readFileSync(o,"utf8");n=JSON.parse(s)}else{let s=await import(`file://${o}`);n=s.default||s,n||(i.warn(`No default export found in ${o}`),n={})}if(Array.isArray(n))for(let s of n)t.push({options:{...m,...s},rootDir:r});else t.push({options:{...m,...n},rootDir:r});break}catch(n){i.error(`Failed to load config from ${o}: ${f(n)}`)}if(t.length>0)break}return t}function I(r){let t=A.join(r,"package.json");try{if(!E.existsSync(t))return null;let e=E.readFileSync(t,"utf8");return JSON.parse(e)}catch(e){return i.error(`Failed to load package.json at ${t}: ${f(e)}`),null}}function L(r,t){return{name:"bunup:external-plugin",setup(e){e.onResolve({filter:/.*/},o=>{let n=o.path;return r.some(a=>a.test(n))&&!t.some(a=>a.test(n))?{path:n,external:!0}:null})}}}async function w(r,t){if(!r.entry||r.entry.length===0||!r.outDir){i.cli("Nothing to build. Please make sure you have provided a proper bunup configuration or cli arguments.");return}let e=performance.now();i.cli("Build started");let o=I(t),n=o?.type,s=j(r,o),a=M(r),u=[L(s,a)],l=d(r.entry),c=r.format.flatMap(p=>l.map(g=>er(r,t,g,p,n,u)));try{await Promise.all(c);let p=performance.now()-e,g=P(p);i.cli(`\u26A1 Build success in ${g}`)}catch{i.error("Build process encountered errors."),process.exit(1)}if(r.dts){let p=performance.now();i.progress("DTS","Bundling types");let g=r.format.filter(y=>!(y==="iife"&&!O(n)&&r.format.includes("cjs"))),U=r.dts===!0?l:d(r.dts.entry),b=new x;try{let y=g.flatMap(G=>U.map(V=>tr(r,t,V,G,n,b)));await Promise.all(y);let q=performance.now()-p,Q=P(q);i.progress("DTS",`Bundled types in ${Q}`)}catch{await b.cleanup()}await b.cleanup()}}async function tr(r,t,e,o,n,s){let a={name:r.name,rootDir:t,outDir:r.outDir,entry:e,format:o,packageType:n,options:r};await s.process(a)}async function er(r,t,e,o,n,s){let a=T(o,n),u=C(r,t),l=await Bun.build({...u,entrypoints:[`${t}/${e.path}`],format:o,naming:{entry:F(e.name,a)},splitting:$(r.splitting,o),plugins:s,throw:!1});if(!l.success)throw l.logs.forEach(c=>{c.level==="error"?i.error(c.message):c.level==="warning"?i.warn(c.message):c.level==="info"&&i.info(c.message)}),new Error(`Build failed for ${e} (${o})`);i.progress(h(o,r.name),`${r.outDir}/${e.name}${a}`)}var nr={n:"name",f:"format",o:"outDir",m:"minify",w:"watch",d:"dts",e:"external",t:"target",mw:"minifyWhitespace",mi:"minifyIdentifiers",ms:"minifySyntax",c:"clean",s:"splitting",ne:"noExternal"},or={name:(r,t)=>{t.name=r},format:(r,t)=>{t.format=r.split(",")},outDir:(r,t)=>{t.outDir=r},minify:(r,t)=>{t.minify=!!r},watch:(r,t)=>{t.watch=!!r},dts:(r,t)=>{t.dts=!!r},external:(r,t)=>{t.external=r.split(",")},minifyWhitespace:(r,t)=>{t.minifyWhitespace=!!r},minifyIdentifiers:(r,t)=>{t.minifyIdentifiers=!!r},minifySyntax:(r,t)=>{t.minifySyntax=!!r},target:(r,t)=>{t.target=r},clean:(r,t)=>{t.clean=!!r},splitting:(r,t)=>{t.splitting=!!r},noExternal:(r,t)=>{t.noExternal=r.split(",")}};function _(r){let t={};for(let e=0;e<r.length;e++){let o=r[e];if(o.startsWith("--")||o.startsWith("-")){let n=o.startsWith("-")&&!o.startsWith("--"),s=n?o.slice(1):o.slice(2),a=n?nr[s]:s,u=or[a];if(!u){i.error(`Unknown option: ${s}`);continue}let l=r[e+1],c=l&&!l.startsWith("-")?l:!0;u(c,t),typeof c=="string"&&e++}else t.entry||(t.entry=[]),Array.isArray(t.entry)&&t.entry.push(o)}return t}typeof Bun>"u"&&(i.error(`Bunup requires Bun to run.
5
+ To install Bun, visit https://bun.sh/docs/installation`),process.exit(1));import B from"path";import sr from"chokidar";async function z(r,t){let e=new Set;d(r.entry).forEach(l=>{let c=B.resolve(t,l.path),p=B.dirname(c);e.add(p)});let n=sr.watch(Array.from(e),{persistent:!0,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50},atomic:!0,ignorePermissionErrors:!0,ignored:[/[\\/]\.git[\\/]/,/[\\/]node_modules[\\/]/,r.outDir]}),s=null,a=!1,u=async l=>{if(!a){a=!0;try{await w({...r,entry:[l],clean:!1},t)}catch(c){i.error(`Build failed: ${c}`)}finally{a=!1}}};n.on("change",l=>{let c=B.relative(t,l);i.cli(`File changed: ${c}`),s&&clearTimeout(s),s=setTimeout(()=>u(c),300)}),n.on("error",l=>{i.error(`Watcher error: ${l}`)})}async function ar(r=Bun.argv.slice(2)){let t=_(r),e=await N(process.cwd()),o=process.cwd();if(t.watch&&(i.cli("Starting watch mode"),i.cli("Watching for file changes")),e.length===0){let n={...m,...t};n.clean&&J(o,n.outDir),await H(n,o)}else{for(let{options:n,rootDir:s}of e)n.clean&&J(s,n.outDir);await Promise.all(e.map(async({options:n,rootDir:s})=>{let a={...m,...n,...t};await H(a,s)}))}t.watch||process.exit(0)}async function H(r,t){r.watch?await z(r,t):await w(r,t)}function J(r,t){let e=ir.join(r,t);if(D.existsSync(e))try{D.rmSync(e,{recursive:!0,force:!0})}catch(o){i.error(`Failed to clean output directory: ${o}`)}D.mkdirSync(e,{recursive:!0})}ar().catch(r=>{v(r),process.exit(1)});
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var _os = require('os');var _path = require('path'); var _path2 = _interopRequireDefault(_path);var _worker_threads = require('worker_threads');var l=e=>e instanceof Error?e.message:String(e);var i={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(e,r,s){let o=" ".repeat(Math.max(0,this.MAX_LABEL_LENGTH-r.length));return`\x1B[38;5;${e}m[${r}]\x1B[0m ${o}${s}`},cli(e){let r=this.labels.cli;console.log(this.formatMessage(this.colors.cli,r,e))},info(e){let r=this.labels.info;console.log(this.formatMessage(this.colors.info,r,e))},warn(e){let r=this.labels.warn;console.warn(this.formatMessage(this.colors.warn,r,e))},error(e){let r=this.labels.error;console.error(this.formatMessage(this.colors.error,r,e))},progress(e,r){let s=String(e),o=this.colors.default;for(let[a,n]of Object.entries(this.colors.progress))if(s.includes(a)){o=n;break}console.log(this.formatMessage(o,s,r))}};function g(e,r){return`${r?`${r.replace(/-/g,"_")}_`:""}${e}`.toUpperCase()}var u=class{constructor(r=_os.cpus.call(void 0, ).length||4){this.workers=[];this.queue=[];this.busyWorkers=new Set;this.isShuttingDown=!1;this.maxWorkers=r}async process(r){if(this.isShuttingDown)throw new Error("Worker pool is shutting down");return new Promise((s,o)=>{this.queue.push({task:r,resolve:s,reject:o}),this.processQueue()})}processQueue(){if(!(this.queue.length===0||this.isShuttingDown))if(this.workers.length<this.maxWorkers){let r=new (0, _worker_threads.Worker)(_path2.default.join(__dirname,"./dtsWorker.js"));this.workers.push(r),this.assignTaskToWorker(r)}else{let r=this.workers.find(s=>!this.busyWorkers.has(s));r&&this.assignTaskToWorker(r)}}assignTaskToWorker(r){let s=this.queue.shift();if(!s)return;let{task:o,resolve:a,reject:n}=s;this.busyWorkers.add(r);let c=()=>{this.busyWorkers.delete(r),this.isShuttingDown&&this.busyWorkers.size===0?this.terminateAllWorkers():this.processQueue()};r.on("message",t=>{t.success?(i.progress(g("DTS",t.name),t.outputRelativePath),a()):(i.error(`DTS generation failed: ${t.error}`),n(new Error(t.error))),c()}),r.on("error",t=>{let h=l(t);i.error(`Worker error: ${h}`),n(t),c()}),r.postMessage(o)}terminateAllWorkers(){this.workers.forEach(r=>{try{r.terminate()}catch(s){i.error(`Error terminating worker: ${l(s)}`)}}),this.workers=[],this.busyWorkers.clear()}async cleanup(){if(this.isShuttingDown=!0,this.busyWorkers.size===0){this.terminateAllWorkers();return}return new Promise(r=>{let s=setInterval(()=>{this.busyWorkers.size===0&&(clearInterval(s),this.terminateAllWorkers(),r())},100);setTimeout(()=>{clearInterval(s),this.terminateAllWorkers(),r()},5e3)})}};exports.DtsWorker = u;
package/build/index.d.mts CHANGED
@@ -1,135 +1,143 @@
1
- type WithOptional<
2
- T,
3
- K extends keyof T
4
- > = Omit<T, K> & Partial<Pick<T, K>>;
1
+ type WithOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
5
2
 
6
- type Format = "esm" | "cjs" | "iife";
7
- type Target = "bun" | "node" | "browser";
3
+ type Format = 'esm' | 'cjs' | 'iife';
4
+ type Target = 'bun' | 'node' | 'browser';
8
5
  type External = string[];
9
6
  type Entry = string[] | Record<string, string>;
10
7
  type DtsOptions = {
11
- /**
12
- * Entry point files for TypeScript declaration file generation
13
- *
14
- * This can be:
15
- * - An array of file paths
16
- * - An object where keys are output names and values are input file paths
17
- *
18
- * The key names are used for the generated declaration files.
19
- * For example, {custom: './src/index.ts'} will generate custom.d.ts
20
- *
21
- * If not specified, the main entry points will be used for declaration file generation.
22
- *
23
- * If a string path is provided in an array, the file name (without extension)
24
- * will be used as the name for the output declaration file.
25
- *
26
- * @example
27
- * // Using string paths in an array
28
- * entry: ['./src/index.ts'] // Generates index.d.ts
29
- *
30
- * // Using named outputs as an object
31
- * entry: { myModule: './src/index.ts', utils: './src/utility-functions.ts' } // Generates myModule.d.ts and utils.d.ts
32
- */
33
- entry: Entry
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
+ /**
32
+ * Path to a preferred tsconfig.json file to use for declaration generation
33
+ *
34
+ * If not specified, the tsconfig.json in the project root will be used.
35
+ * This option allows you to use a different TypeScript configuration
36
+ * specifically for declaration file generation.
37
+ *
38
+ * @example
39
+ * preferredTsconfigPath: './tsconfig.build.json'
40
+ */
41
+ preferredTsconfigPath?: string;
34
42
  };
35
43
  interface BunupOptions {
36
- /**
37
- * Name of the build configuration
38
- * Used for logging and identification purposes
39
- */
40
- name?: string;
41
- /**
42
- * Entry point files for the build
43
- *
44
- * This can be:
45
- * - An array of file paths
46
- * - An object where keys are output names and values are input file paths
47
- *
48
- * The key names are used for the generated output files.
49
- * For example, {custom: './src/index.ts'} will generate custom.js
50
- *
51
- * If a string path is provided in an array, the file name (without extension)
52
- * will be used as the name for the output file.
53
- *
54
- * @example
55
- * // Using string paths in an array
56
- * entry: ['./src/index.ts'] // Generates index.js
57
- *
58
- * // Using named outputs as an object
59
- * entry: { myModule: './src/index.ts', utils: './src/utility-functions.ts' } // Generates myModule.js and utils.js
60
- */
61
- entry: Entry;
62
- /**
63
- * Output directory for the bundled files
64
- * Defaults to 'dist' if not specified
65
- */
66
- outDir: string;
67
- /**
68
- * Output formats for the bundle
69
- * Can include 'esm', 'cjs', and/or 'iife'
70
- * Defaults to ['esm'] if not specified
71
- */
72
- format: Format[];
73
- /**
74
- * Whether to enable all minification options
75
- * When true, enables minifyWhitespace, minifyIdentifiers, and minifySyntax
76
- */
77
- minify?: boolean;
78
- /**
79
- * Whether to enable code splitting
80
- * Defaults to true for ESM format, false for CJS format
81
- */
82
- splitting?: boolean;
83
- /**
84
- * Whether to minify whitespace in the output
85
- * Removes unnecessary whitespace to reduce file size
86
- */
87
- minifyWhitespace?: boolean;
88
- /**
89
- * Whether to minify identifiers in the output
90
- * Renames variables and functions to shorter names
91
- */
92
- minifyIdentifiers?: boolean;
93
- /**
94
- * Whether to minify syntax in the output
95
- * Optimizes code structure for smaller file size
96
- */
97
- minifySyntax?: boolean;
98
- /**
99
- * Whether to watch for file changes and rebuild automatically
100
- */
101
- watch?: boolean;
102
- /**
103
- * Whether to generate TypeScript declaration files (.d.ts)
104
- * When set to true, generates declaration files for all entry points
105
- * Can also be configured with DtsOptions for more control
106
- */
107
- dts?: boolean | DtsOptions;
108
- /**
109
- * External packages that should not be bundled
110
- * Useful for dependencies that should be kept as external imports
111
- */
112
- external?: External;
113
- /**
114
- * Packages that should be bundled even if they are in external
115
- * Useful for dependencies that should be included in the bundle
116
- */
117
- noExternal?: External;
118
- /**
119
- * The target environment for the bundle
120
- * Can be 'browser', 'bun', 'node', etc.
121
- * Defaults to 'node' if not specified
122
- */
123
- target?: Target;
124
- /**
125
- * Whether to clean the output directory before building
126
- * When true, removes all files in the outDir before starting a new build
127
- * Defaults to true if not specified
128
- */
129
- clean?: boolean;
44
+ /**
45
+ * Name of the build configuration
46
+ * Used for logging and identification purposes
47
+ */
48
+ name?: string;
49
+ /**
50
+ * Entry point files for the build
51
+ *
52
+ * This can be:
53
+ * - An array of file paths
54
+ * - An object where keys are output names and values are input file paths
55
+ *
56
+ * The key names are used for the generated output files.
57
+ * For example, {custom: './src/index.ts'} will generate custom.js
58
+ *
59
+ * If a string path is provided in an array, the file name (without extension)
60
+ * will be used as the name for the output file.
61
+ *
62
+ * @example
63
+ * // Using string paths in an array
64
+ * entry: ['./src/index.ts'] // Generates index.js
65
+ *
66
+ * // Using named outputs as an object
67
+ * entry: { myModule: './src/index.ts', utils: './src/utility-functions.ts' } // Generates myModule.js and utils.js
68
+ */
69
+ entry: Entry;
70
+ /**
71
+ * Output directory for the bundled files
72
+ * Defaults to 'dist' if not specified
73
+ */
74
+ outDir: string;
75
+ /**
76
+ * Output formats for the bundle
77
+ * Can include 'esm', 'cjs', and/or 'iife'
78
+ * Defaults to ['esm'] if not specified
79
+ */
80
+ format: Format[];
81
+ /**
82
+ * Whether to enable all minification options
83
+ * When true, enables minifyWhitespace, minifyIdentifiers, and minifySyntax
84
+ */
85
+ minify?: boolean;
86
+ /**
87
+ * Whether to enable code splitting
88
+ * Defaults to true for ESM format, false for CJS format
89
+ */
90
+ splitting?: boolean;
91
+ /**
92
+ * Whether to minify whitespace in the output
93
+ * Removes unnecessary whitespace to reduce file size
94
+ */
95
+ minifyWhitespace?: boolean;
96
+ /**
97
+ * Whether to minify identifiers in the output
98
+ * Renames variables and functions to shorter names
99
+ */
100
+ minifyIdentifiers?: boolean;
101
+ /**
102
+ * Whether to minify syntax in the output
103
+ * Optimizes code structure for smaller file size
104
+ */
105
+ minifySyntax?: boolean;
106
+ /**
107
+ * Whether to watch for file changes and rebuild automatically
108
+ */
109
+ watch?: boolean;
110
+ /**
111
+ * Whether to generate TypeScript declaration files (.d.ts)
112
+ * When set to true, generates declaration files for all entry points
113
+ * Can also be configured with DtsOptions for more control
114
+ */
115
+ dts?: boolean | DtsOptions;
116
+ /**
117
+ * External packages that should not be bundled
118
+ * Useful for dependencies that should be kept as external imports
119
+ */
120
+ external?: External;
121
+ /**
122
+ * Packages that should be bundled even if they are in external
123
+ * Useful for dependencies that should be included in the bundle
124
+ */
125
+ noExternal?: External;
126
+ /**
127
+ * The target environment for the bundle
128
+ * Can be 'browser', 'bun', 'node', etc.
129
+ * Defaults to 'node' if not specified
130
+ */
131
+ target?: Target;
132
+ /**
133
+ * Whether to clean the output directory before building
134
+ * When true, removes all files in the outDir before starting a new build
135
+ * Defaults to true if not specified
136
+ */
137
+ clean?: boolean;
130
138
  }
131
139
 
132
- type DefineConfigOption = WithOptional<BunupOptions, "outDir" | "format">;
140
+ type DefineConfigOption = WithOptional<BunupOptions, 'outDir' | 'format'>;
133
141
  type DefineConfigOptions = DefineConfigOption | DefineConfigOption[];
134
142
  declare function defineConfig(options: DefineConfigOptions): DefineConfigOptions;
135
143
 
package/build/index.d.ts CHANGED
@@ -1,135 +1,143 @@
1
- type WithOptional<
2
- T,
3
- K extends keyof T
4
- > = Omit<T, K> & Partial<Pick<T, K>>;
1
+ type WithOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
5
2
 
6
- type Format = "esm" | "cjs" | "iife";
7
- type Target = "bun" | "node" | "browser";
3
+ type Format = 'esm' | 'cjs' | 'iife';
4
+ type Target = 'bun' | 'node' | 'browser';
8
5
  type External = string[];
9
6
  type Entry = string[] | Record<string, string>;
10
7
  type DtsOptions = {
11
- /**
12
- * Entry point files for TypeScript declaration file generation
13
- *
14
- * This can be:
15
- * - An array of file paths
16
- * - An object where keys are output names and values are input file paths
17
- *
18
- * The key names are used for the generated declaration files.
19
- * For example, {custom: './src/index.ts'} will generate custom.d.ts
20
- *
21
- * If not specified, the main entry points will be used for declaration file generation.
22
- *
23
- * If a string path is provided in an array, the file name (without extension)
24
- * will be used as the name for the output declaration file.
25
- *
26
- * @example
27
- * // Using string paths in an array
28
- * entry: ['./src/index.ts'] // Generates index.d.ts
29
- *
30
- * // Using named outputs as an object
31
- * entry: { myModule: './src/index.ts', utils: './src/utility-functions.ts' } // Generates myModule.d.ts and utils.d.ts
32
- */
33
- entry: Entry
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
+ /**
32
+ * Path to a preferred tsconfig.json file to use for declaration generation
33
+ *
34
+ * If not specified, the tsconfig.json in the project root will be used.
35
+ * This option allows you to use a different TypeScript configuration
36
+ * specifically for declaration file generation.
37
+ *
38
+ * @example
39
+ * preferredTsconfigPath: './tsconfig.build.json'
40
+ */
41
+ preferredTsconfigPath?: string;
34
42
  };
35
43
  interface BunupOptions {
36
- /**
37
- * Name of the build configuration
38
- * Used for logging and identification purposes
39
- */
40
- name?: string;
41
- /**
42
- * Entry point files for the build
43
- *
44
- * This can be:
45
- * - An array of file paths
46
- * - An object where keys are output names and values are input file paths
47
- *
48
- * The key names are used for the generated output files.
49
- * For example, {custom: './src/index.ts'} will generate custom.js
50
- *
51
- * If a string path is provided in an array, the file name (without extension)
52
- * will be used as the name for the output file.
53
- *
54
- * @example
55
- * // Using string paths in an array
56
- * entry: ['./src/index.ts'] // Generates index.js
57
- *
58
- * // Using named outputs as an object
59
- * entry: { myModule: './src/index.ts', utils: './src/utility-functions.ts' } // Generates myModule.js and utils.js
60
- */
61
- entry: Entry;
62
- /**
63
- * Output directory for the bundled files
64
- * Defaults to 'dist' if not specified
65
- */
66
- outDir: string;
67
- /**
68
- * Output formats for the bundle
69
- * Can include 'esm', 'cjs', and/or 'iife'
70
- * Defaults to ['esm'] if not specified
71
- */
72
- format: Format[];
73
- /**
74
- * Whether to enable all minification options
75
- * When true, enables minifyWhitespace, minifyIdentifiers, and minifySyntax
76
- */
77
- minify?: boolean;
78
- /**
79
- * Whether to enable code splitting
80
- * Defaults to true for ESM format, false for CJS format
81
- */
82
- splitting?: boolean;
83
- /**
84
- * Whether to minify whitespace in the output
85
- * Removes unnecessary whitespace to reduce file size
86
- */
87
- minifyWhitespace?: boolean;
88
- /**
89
- * Whether to minify identifiers in the output
90
- * Renames variables and functions to shorter names
91
- */
92
- minifyIdentifiers?: boolean;
93
- /**
94
- * Whether to minify syntax in the output
95
- * Optimizes code structure for smaller file size
96
- */
97
- minifySyntax?: boolean;
98
- /**
99
- * Whether to watch for file changes and rebuild automatically
100
- */
101
- watch?: boolean;
102
- /**
103
- * Whether to generate TypeScript declaration files (.d.ts)
104
- * When set to true, generates declaration files for all entry points
105
- * Can also be configured with DtsOptions for more control
106
- */
107
- dts?: boolean | DtsOptions;
108
- /**
109
- * External packages that should not be bundled
110
- * Useful for dependencies that should be kept as external imports
111
- */
112
- external?: External;
113
- /**
114
- * Packages that should be bundled even if they are in external
115
- * Useful for dependencies that should be included in the bundle
116
- */
117
- noExternal?: External;
118
- /**
119
- * The target environment for the bundle
120
- * Can be 'browser', 'bun', 'node', etc.
121
- * Defaults to 'node' if not specified
122
- */
123
- target?: Target;
124
- /**
125
- * Whether to clean the output directory before building
126
- * When true, removes all files in the outDir before starting a new build
127
- * Defaults to true if not specified
128
- */
129
- clean?: boolean;
44
+ /**
45
+ * Name of the build configuration
46
+ * Used for logging and identification purposes
47
+ */
48
+ name?: string;
49
+ /**
50
+ * Entry point files for the build
51
+ *
52
+ * This can be:
53
+ * - An array of file paths
54
+ * - An object where keys are output names and values are input file paths
55
+ *
56
+ * The key names are used for the generated output files.
57
+ * For example, {custom: './src/index.ts'} will generate custom.js
58
+ *
59
+ * If a string path is provided in an array, the file name (without extension)
60
+ * will be used as the name for the output file.
61
+ *
62
+ * @example
63
+ * // Using string paths in an array
64
+ * entry: ['./src/index.ts'] // Generates index.js
65
+ *
66
+ * // Using named outputs as an object
67
+ * entry: { myModule: './src/index.ts', utils: './src/utility-functions.ts' } // Generates myModule.js and utils.js
68
+ */
69
+ entry: Entry;
70
+ /**
71
+ * Output directory for the bundled files
72
+ * Defaults to 'dist' if not specified
73
+ */
74
+ outDir: string;
75
+ /**
76
+ * Output formats for the bundle
77
+ * Can include 'esm', 'cjs', and/or 'iife'
78
+ * Defaults to ['esm'] if not specified
79
+ */
80
+ format: Format[];
81
+ /**
82
+ * Whether to enable all minification options
83
+ * When true, enables minifyWhitespace, minifyIdentifiers, and minifySyntax
84
+ */
85
+ minify?: boolean;
86
+ /**
87
+ * Whether to enable code splitting
88
+ * Defaults to true for ESM format, false for CJS format
89
+ */
90
+ splitting?: boolean;
91
+ /**
92
+ * Whether to minify whitespace in the output
93
+ * Removes unnecessary whitespace to reduce file size
94
+ */
95
+ minifyWhitespace?: boolean;
96
+ /**
97
+ * Whether to minify identifiers in the output
98
+ * Renames variables and functions to shorter names
99
+ */
100
+ minifyIdentifiers?: boolean;
101
+ /**
102
+ * Whether to minify syntax in the output
103
+ * Optimizes code structure for smaller file size
104
+ */
105
+ minifySyntax?: boolean;
106
+ /**
107
+ * Whether to watch for file changes and rebuild automatically
108
+ */
109
+ watch?: boolean;
110
+ /**
111
+ * Whether to generate TypeScript declaration files (.d.ts)
112
+ * When set to true, generates declaration files for all entry points
113
+ * Can also be configured with DtsOptions for more control
114
+ */
115
+ dts?: boolean | DtsOptions;
116
+ /**
117
+ * External packages that should not be bundled
118
+ * Useful for dependencies that should be kept as external imports
119
+ */
120
+ external?: External;
121
+ /**
122
+ * Packages that should be bundled even if they are in external
123
+ * Useful for dependencies that should be included in the bundle
124
+ */
125
+ noExternal?: External;
126
+ /**
127
+ * The target environment for the bundle
128
+ * Can be 'browser', 'bun', 'node', etc.
129
+ * Defaults to 'node' if not specified
130
+ */
131
+ target?: Target;
132
+ /**
133
+ * Whether to clean the output directory before building
134
+ * When true, removes all files in the outDir before starting a new build
135
+ * Defaults to true if not specified
136
+ */
137
+ clean?: boolean;
130
138
  }
131
139
 
132
- type DefineConfigOption = WithOptional<BunupOptions, "outDir" | "format">;
140
+ type DefineConfigOption = WithOptional<BunupOptions, 'outDir' | 'format'>;
133
141
  type DefineConfigOptions = DefineConfigOption | DefineConfigOption[];
134
142
  declare function defineConfig(options: DefineConfigOptions): DefineConfigOptions;
135
143
 
package/build/index.js CHANGED
@@ -1 +1 @@
1
- var D=require("node:module");var{defineProperty:e,getOwnPropertyNames:r,getOwnPropertyDescriptor:O}=Object,g=Object.prototype.hasOwnProperty;var f=new WeakMap,C=(i)=>{var n=f.get(i),o;if(n)return n;if(n=e({},"__esModule",{value:!0}),i&&typeof i==="object"||typeof i==="function")r(i).map((t)=>!g.call(n,t)&&e(n,t,{get:()=>i[t],enumerable:!(o=O(i,t))||o.enumerable}));return f.set(i,n),n};var u=(i,n)=>{for(var o in n)e(i,o,{get:n[o],enumerable:!0,configurable:!0,set:(t)=>n[o]=()=>t})};var m={};u(m,{defineConfig:()=>p});module.exports=C(m);function p(i){return i}
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});function n(i){return i}exports.defineConfig = n;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunup",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
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,10 +18,11 @@
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.6",
21
+ "bunup": "^0.1.9",
22
22
  "eslint": "^8.57.0",
23
23
  "husky": "^9.1.6",
24
24
  "prettier": "^3.2.5",
25
+ "tsup": "^8.4.0",
25
26
  "typescript": "^5.4.3",
26
27
  "vitest": "^2.0.5"
27
28
  },
@@ -58,8 +59,8 @@
58
59
  "rollup-plugin-dts": "^6.1.1"
59
60
  },
60
61
  "scripts": {
61
- "build": "bunup",
62
- "dev": "bunup --watch",
62
+ "build": "tsup",
63
+ "dev": "tsup --watch",
63
64
  "test-build": "pnpm -C tests build",
64
65
  "test": "vitest run",
65
66
  "tsc": "tsc --noEmit",
@@ -1 +0,0 @@
1
- import X from"path";import E from"fs";import $ from"path";import _ from"oxc-transform";import{rollup as T}from"rollup";import q from"rollup-plugin-dts";var h=(r)=>{if(r instanceof Error)return r.message;return String(r)};function v(r){return r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function p(r,s){switch(r){case"esm":return".d.mts";case"cjs":return N(s)?".d.cts":".d.ts";case"iife":return".d.ts"}}function N(r){return r==="module"}function x(r){if(!r)return[];return Array.from(new Set([...Object.keys(r.dependencies||{}),...Object.keys(r.peerDependencies||{})]))}function C(r){return r.map((s)=>typeof s==="string"?new RegExp(`^${v(s)}($|\\/|\\\\)`):s)}function j(r,s){return C(r.external||[]).concat(x(s).map((e)=>new RegExp(`^${v(e)}($|\\/|\\\\)`)))}function m(r){return C(r.noExternal||[])}import B from"fs";import y from"path";var f={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,s,e){let o=" ".repeat(Math.max(0,this.MAX_LABEL_LENGTH-s.length));return`\x1B[38;5;${r}m[${s}]\x1B[0m ${o}${e}`},cli(r){let s=this.labels.cli;console.log(this.formatMessage(this.colors.cli,s,r))},info(r){let s=this.labels.info;console.log(this.formatMessage(this.colors.info,s,r))},warn(r){let s=this.labels.warn;console.warn(this.formatMessage(this.colors.warn,s,r))},error(r){let s=this.labels.error;console.error(this.formatMessage(this.colors.error,s,r))},progress(r,s){let e=String(r),o=this.colors.default;for(let[t,i]of Object.entries(this.colors.progress))if(e.includes(t)){o=i;break}console.log(this.formatMessage(o,e,s))}};function O(r,s){return`${s?`${s.replace(/-/g,"_")}_`:""}${r}`.toUpperCase()}function D(r){let s=y.join(r,"package.json");try{if(!B.existsSync(s))return null;let e=B.readFileSync(s,"utf8");return JSON.parse(e)}catch(e){return f.error(`Failed to load package.json at ${s}: ${h(e)}`),null}}async function A(r,s,e,o){let{absoluteRootDir:t,absoluteEntry:i}=H(r,s),n=await U(i),k=await Q(n);return G(i,k,e,o,t)}async function U(r){let s=new Set,e=[r];while(e.length>0){let o=e.pop();if(!o||s.has(o))continue;s.add(o);try{let t=await E.promises.readFile(o,"utf8"),i=z(t);for(let n of i){let k=$.dirname(o),g=$.resolve(k,n),l=[g,`${g}.ts`,`${g}.tsx`,`${g}/index.ts`,`${g}/index.tsx`];for(let u of l)if(E.existsSync(u)&&u.endsWith(".ts")&&!s.has(u)){e.push(u);break}}}catch(t){f.warn(`Error processing ${o}: ${t instanceof Error?t.message:String(t)}`)}}return s}function z(r){let s=new Set;try{let e=/(?:import|export)(?:(?:[\s\n]*(?:type[\s\n]+)?(?:\*|\{[^}]*\}|[\w$]+)[\s\n]+from[\s\n]*)|[\s\n]+)(["'`])([^'"]+)\1/g,o;while((o=e.exec(r))!==null){let n=o[2];if(n.startsWith("."))s.add(n)}let t=/import\s+(["'`])([^'"]+)\1\s*;?/g;while((o=t.exec(r))!==null){let n=o[2];if(n.startsWith("."))s.add(n)}let i=/import\s*\(\s*(["'`])([^'"]+)\1\s*\)/g;while((o=i.exec(r))!==null){let n=o[2];if(n.startsWith("."))s.add(n)}}catch(e){f.warn(`Error extracting imports: ${e instanceof Error?e.message:String(e)}`)}return Array.from(s)}async function Q(r){let s=new Map;return await Promise.all(Array.from(r).map(async(e)=>{try{let o=e.replace(/\.tsx?$/,".d.ts"),t=await E.promises.readFile(e,"utf8"),{code:i}=_.isolatedDeclaration(e,t);if(i)s.set(o,i)}catch(o){f.warn(`Failed to generate declaration for ${e}: ${o instanceof Error?o.message:String(o)}`)}})),s}async function G(r,s,e,o,t){let k=`\x00virtual:${r.replace(/\.tsx?$/,".d.ts")}`,g={name:"virtual-dts",resolveId(c,a){if(c.startsWith("\x00virtual:"))return c;if(a?.startsWith("\x00virtual:")){let W=a.slice(9),M=$.dirname(W);if(c.startsWith(".")){let R=$.resolve(M,c);for(let L of["",".d.ts","/index.d.ts"]){let d=`${R}${L}`;if(s.has(d))return`\x00virtual:${d}`}}}return null},load(c){if(c.startsWith("\x00virtual:")){let a=c.slice(9);return s.get(a)||null}return null}},l=D(t),u=j(o,l),S=m(o),w;try{w=await T({input:k,onwarn(a,W){if(a.code==="UNRESOLVED_IMPORT"||a.code==="CIRCULAR_DEPENDENCY"||a.code==="EMPTY_BUNDLE")return;W(a)},plugins:[g,q()],external:(a)=>u.some((W)=>W.test(a))&&!S.some((W)=>W.test(a))});let{output:c}=await w.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: ${h(c)}`)}finally{if(w)await w.close()}}function H(r,s){let e=$.resolve(r),o=$.resolve(e,s);if(!E.existsSync(e))throw new Error(`Root directory does not exist: ${e}`);if(!E.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($.relative(e,o).startsWith(".."))throw new Error(`Entry file must be within rootDir: ${o}`);return{absoluteRootDir:e,absoluteEntry:o}}var __dirname="/home/runner/work/bunup/bunup/src/dts";self.onmessage=async(r)=>{let{name:s,rootDir:e,outDir:o,entry:t,format:i,packageType:n,options:k}=r.data;try{let g=await A(e,t.path,i,k),l=p(i,n),u=`${o}/${t.name}${l}`,S=`${e}/${u}`;await Bun.write(S,g);let w={name:s,success:!0,outputRelativePath:u};self.postMessage(w)}catch(g){let l={success:!1,error:h(g)};self.postMessage(l)}};class K{workers=[];queue=[];maxWorkers;busyWorkers=new Set;isShuttingDown=!1;constructor(r=navigator.hardwareConcurrency||4){this.maxWorkers=r}async process(r){if(this.isShuttingDown)throw new Error("Worker pool is shutting down");return new Promise((s,e)=>{this.queue.push({task:r,resolve:s,reject:e}),this.processQueue()})}processQueue(){if(this.queue.length===0||this.isShuttingDown)return;if(this.workers.length<this.maxWorkers){let r=new Worker(X.join(__dirname,"./dtsWorker.js"));this.workers.push(r),this.assignTaskToWorker(r)}else{let r=this.workers.find((s)=>!this.busyWorkers.has(s));if(r)this.assignTaskToWorker(r)}}assignTaskToWorker(r){let s=this.queue.shift();if(!s)return;let{task:e,resolve:o,reject:t}=s;this.busyWorkers.add(r);let i=()=>{if(this.busyWorkers.delete(r),this.isShuttingDown&&this.busyWorkers.size===0)this.terminateAllWorkers();else this.processQueue()};r.onmessage=(n)=>{if(n.data.success)f.progress(O("DTS",n.data.name),n.data.outputRelativePath),o();else f.error(`DTS generation failed: ${n.data.error}`),t(new Error(n.data.error));i()},r.onerror=(n)=>{let k=h(n);f.error(`Worker error: ${k}`),t(n),i()},r.postMessage(e)}terminateAllWorkers(){this.workers.forEach((r)=>{try{r.terminate()}catch(s){f.error(`Error terminating worker: ${h(s)}`)}}),this.workers=[],this.busyWorkers.clear()}async cleanup(){if(this.isShuttingDown=!0,this.busyWorkers.size===0){this.terminateAllWorkers();return}return new Promise((r)=>{let s=setInterval(()=>{if(this.busyWorkers.size===0)clearInterval(s),this.terminateAllWorkers(),r()},100);setTimeout(()=>{clearInterval(s),this.terminateAllWorkers(),r()},5000)})}}export{K as DtsWorker};