bunli 0.2.0 → 0.3.0
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/dist/cli.js +3 -3
- package/dist/config.d.ts +1 -0
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -125,13 +125,13 @@ declare module '@bunli/core' {
|
|
|
125
125
|
`}function uF1(J){return J.split(/[^a-zA-Z0-9]/).filter(Boolean).map((X)=>X.charAt(0).toUpperCase()+X.slice(1)).join("")||"Command"}function n3(J,X){let Z=[];if(Z.push("{"),Z.push(`${X} name: '${s0(J.name)}',`),Z.push(`${X} description: '${s0(J.description||"")}',`),J.alias)if(Array.isArray(J.alias))Z.push(`${X} alias: ${JSON.stringify(J.alias)},`);else Z.push(`${X} alias: '${s0(J.alias)}',`);if(J.options&&Object.keys(J.options).length>0){let Q=Object.entries(J.options).map(([Y,H])=>{let G=[`type: '${H.type}'`,`required: ${H.required}`,`hasDefault: ${H.hasDefault}`,H.hasDefault?`default: ${JSON.stringify(H.default)}`:void 0,H.description?`description: '${s0(H.description)}'`:void 0,H.short?`short: '${s0(H.short)}'`:void 0,H.schema?`schema: ${JSON.stringify(H.schema)}`:void 0,H.validator?`validator: '${s0(H.validator)}'`:void 0].filter(Boolean).join(", ");return`${X} '${Y}': { ${G} }`});Z.push(`${X} options: {`),Z.push(Q.join(`,
|
|
126
126
|
`)),Z.push(`${X} },`)}if(J.commands&&J.commands.length>0)Z.push(`${X} commands: [`),Z.push(J.commands.map((Q)=>`${X} ${n3(Q,X+" ")}`).join(`,
|
|
127
127
|
`)),Z.push(`${X} ],`);return Z.push(`${X} path: '${s0(J.exportPath)}'`),Z.push(`${X}}`),Z.join(`
|
|
128
|
-
`)}function s0(J){return(J??"").replace(/'/g,"\\'")}import{mkdir as mF1}from"fs/promises";import{dirname as cF1}from"path";class g0{config;scanner;constructor(J){this.config=J,this.scanner=new UX}async run(J){try{let X=await this.scanCommands(),Z=await this.parseCommands(X),Q=P8(Z);await this.writeTypes(Q)
|
|
128
|
+
`)}function s0(J){return(J??"").replace(/'/g,"\\'")}import{mkdir as mF1}from"fs/promises";import{dirname as cF1}from"path";class g0{config;scanner;constructor(J){this.config=J,this.scanner=new UX}async run(J){try{let X=await this.scanCommands(),Z=await this.parseCommands(X),Q=P8(Z);if(await this.writeTypes(Q),this.config.generateReport){let Y={commandsParsed:Z.length,filesScanned:X.length,skipped:X.filter((H)=>!Z.some((G)=>G.filePath===H)),names:Z.map((H)=>H.name).sort()};await this.writeReport(Y)}console.log(`\u2713 Generated types for ${Z.length} commands`)}catch(X){throw console.error("Failed to generate types:",X),X}}async scanCommands(){return await this.scanner.scanCommands(this.config.commandsDir)}async parseCommands(J){let X=[];for(let Z of J){console.log(`Parsing file: ${Z}`);let Q=await w8(Z,this.config.commandsDir,this.config.outputFile);if(Q)console.log(`\u2705 Successfully parsed: ${Q.name}`),X.push(Q);else console.log(`\u274C Failed to parse: ${Z}`)}return X}async writeTypes(J){let X=cF1(this.config.outputFile);await mF1(X,{recursive:!0}),await Bun.write(this.config.outputFile,J)}async writeReport(J){let X=this.config.outputFile.replace(/\.ts$/,".report.json");await Bun.write(X,JSON.stringify(J,null,2))}getConfig(){return{...this.config}}updateConfig(J){this.config={...this.config,...J}}}var T8=G0(()=>{L2();S8()});function GX(J={}){let{commandsDir:X="commands",outputFile:Z="./commands.gen.ts",config:Q,generateReport:Y}=J,H=null;return{name:"bunli-codegen",setup(G){H=new g0({commandsDir:X,outputFile:Z,config:Q,generateReport:Y}),G.onStart(async()=>{if(H)try{console.log("\uD83D\uDD27 Generating command types..."),await H.run(),console.log("\u2705 Command types generated")}catch(z){console.warn("\u26A0\uFE0F Failed to generate command types:",z instanceof Error?z.message:String(z))}}),G.onResolve({filter:/^\.\/commands\//},async(z)=>{return{path:z.path,namespace:"file"}}),G.onLoad({filter:/\.(ts|tsx|js|jsx)$/,namespace:"file"},async(z)=>{if(z.path.includes(X))return;return}),G.onEnd(async(z)=>{if(z.success&&H)try{await H.run()}catch(W){console.warn("\u26A0\uFE0F Failed to regenerate types:",W instanceof Error?W.message:String(W))}})}}}var C2=G0(()=>{T8()});var zX=G0(()=>{T8();L2();S8();C2()});import{existsSync as o3}from"fs";import e3 from"path";async function D2(J=process.cwd()){for(let Z of lF1){let Q=e3.join(J,Z);if(o3(Q))return Z}let X=e3.join(J,"package.json");if(o3(X))try{let Z=await Bun.file(X).json();if(Z.bin){if(typeof Z.bin==="string")return Z.bin;else if(typeof Z.bin==="object"){let Q=Object.values(Z.bin)[0];if(typeof Q==="string")return Q}}}catch{}return}var lF1;var L8=G0(()=>{lF1=["src/cli.ts","src/index.ts","src/main.ts","cli.ts","index.ts","main.ts","src/cli.js","src/index.js","src/main.js","cli.js","index.js","main.js"]});var XV={};yJ(XV,{default:()=>pF1});import{defineCommand as iF1,option as _J}from"@bunli/core";import{z as gJ}from"zod";import JV from"path";var pF1;var ZV=G0(()=>{zX();C2();$J();L8();pF1=iF1({name:"dev",description:"Run your CLI in development mode with hot reload",alias:"d",options:{entry:_J(gJ.string().optional(),{short:"e",description:"Entry file (defaults to auto-detect)"}),commandsDir:_J(gJ.string().default("commands"),{description:"Commands directory"}),generate:_J(gJ.boolean().default(!0),{description:"Enable codegen"}),clearScreen:_J(gJ.boolean().default(!0),{description:"Clear screen on reload"}),watch:_J(gJ.boolean().default(!0),{short:"w",description:"Watch for changes"}),inspect:_J(gJ.boolean().default(!1),{short:"i",description:"Enable debugger"}),port:_J(gJ.number().int().min(1).max(65535).optional(),{short:"p",description:"Debugger port"})},handler:async({flags:J,positional:X,spinner:Z,colors:Q})=>{let Y=await R0();if(J.generate){let V=new g0({commandsDir:J.commandsDir,outputFile:"./.bunli/commands.gen.ts",config:Y,generateReport:Y.commands?.generateReport}),U=Z("Generating command types...");try{await V.run(),U.succeed("Types generated")}catch($){U.fail("Failed to generate types");let j=$ instanceof Error?$.message:String($);console.error(Q.red(j));return}}let H=J.entry||Y.build?.entry||await D2();if(!H)console.error(Q.red("No entry file found. Please specify with --entry or in bunli.config.ts")),process.exit(1);let G=Array.isArray(H)?H[0]:H;if(!G)console.error(Q.red("Entry file is required")),process.exit(1);let z=JV.resolve(G),W=async()=>{let V=await Bun.build({entrypoints:[z],outdir:".bunli/dev",target:"bun",plugins:J.generate?[GX({commandsDir:J.commandsDir,outputFile:"./.bunli/commands.gen.ts",config:Y,generateReport:Y.commands?.generateReport})]:[]});if(!V.success){console.error(Q.red("Build failed"));for(let U of V.logs)console.error(U);return null}return V.outputs[0]};if(console.log(Q.cyan(`
|
|
129
129
|
\uD83D\uDC40 Starting dev mode...
|
|
130
130
|
`)),J.watch??Y.dev?.watch??!0){let V=null,U=await W();if(U)V=Bun.spawn(["bun",U.path],{stdio:["inherit","inherit","inherit"],env:{...process.env,NODE_ENV:"development"},onExit:(A,S,w,P)=>{if(S!==0&&S!==null&&!w)console.log(Q.dim(`Process exited with code ${S}`))}});let{watch:$}=await import("fs/promises"),j=new AbortController,{signal:C}=j;process.on("SIGINT",()=>{if(console.log(Q.dim(`
|
|
131
131
|
|
|
132
132
|
Stopping dev server...`)),V)V.kill();j.abort(),process.exit(0)});try{let A=JV.dirname(z),S=$(A,{recursive:!0,signal:C});for await(let w of S){if(!w.filename?.match(/\.(ts|tsx|js|jsx)$/))continue;if(w.filename?.includes("commands.gen.ts"))continue;if(w.filename?.includes(".bunli/"))continue;if(J.clearScreen)console.clear();console.log(Q.dim(`[${new Date().toLocaleTimeString()}] File changed: ${w.filename}`)),console.log(Q.cyan("Rebuilding..."));let P=await W();if(P){if(V)V.kill(),await new Promise((b)=>setTimeout(b,100));V=Bun.spawn(["bun",P.path],{stdio:["inherit","inherit","inherit"],env:{...process.env,NODE_ENV:"development"},onExit:(b,t,m,d)=>{if(t!==0&&t!==null&&!m)console.log(Q.dim(`Process exited with code ${t}`))}}),console.log(Q.green(`\u2713 Reloaded
|
|
133
|
-
`))}}}catch(A){if(A.name==="AbortError"){console.log(Q.dim("Watch stopped"));return}throw A}}else{let V=await W();if(V){let U=Bun.spawn(["bun",V.path],{stdio:["inherit","inherit","inherit"],env:{...process.env,NODE_ENV:"development"},onExit:($,j,C,A)=>{if(j!==0&&j!==null&&!C)console.log(Q.dim(`Process exited with code ${j}`))}});await U.exited,process.exit(U.exitCode??0)}else process.exit(1)}}})});var QV={};yJ(QV,{default:()=>dF1});import{defineCommand as rF1,option as t0}from"@bunli/core";import{z as n0}from"zod";var{$:WJ}=globalThis.Bun;import WX from"path";var dF1;var YV=G0(()=>{zX();C2();$J();L8();dF1=rF1({name:"build",description:"Build your CLI for production",alias:"b",options:{entry:t0(n0.string().optional(),{short:"e",description:"Entry file (defaults to auto-detect)"}),outdir:t0(n0.string().optional(),{short:"o",description:"Output directory"}),outfile:t0(n0.string().optional(),{description:"Output filename (for single executable)"}),minify:t0(n0.boolean().optional(),{short:"m",description:"Minify output"}),sourcemap:t0(n0.boolean().optional(),{short:"s",description:"Generate sourcemaps"}),bytecode:t0(n0.boolean().default(!1),{description:"Enable bytecode compilation (experimental)"}),runtime:t0(n0.enum(["bun","node"]).optional(),{short:"r",description:"Runtime target (for non-compiled builds)"}),targets:t0(n0.string().optional().transform((J)=>{if(!J)return;return J.split(",").map((X)=>X.trim())}),{short:"t",description:"Target platforms for compilation (e.g., darwin-arm64,linux-x64)"}),watch:t0(n0.boolean().default(!1),{short:"w",description:"Watch for changes"})},handler:async({flags:J,spinner:X,colors:Z})=>{let Q=await R0();{let U=X("Generating types...");try{await new g0({commandsDir:Q.commands?.directory||"commands",outputFile:"./.bunli/commands.gen.ts",config:Q}).run(),U.succeed("Types generated")}catch($){U.fail("Failed to generate types");let j=$ instanceof Error?$.message:String($);console.error(Z.red(j));return}}let Y=J.entry||Q.build?.entry||await D2();if(!Y)console.error(Z.red("No entry file found. Please specify with --entry or in bunli.config.ts")),process.exit(1);let H=J.targets||Q.build?.targets,G=H&&H.length>0;if(G&&Array.isArray(Y))console.error(Z.red("Compiled builds only support a single entry file")),process.exit(1);let z=Array.isArray(Y)?Y[0]:Y;if(!z)console.error(Z.red("Entry file is undefined")),process.exit(1);let W=J.outdir||Q.build?.outdir||"./dist",V=X("Building CLI...");V.start();try{if(await WJ`rm -rf ${W}`,await WJ`mkdir -p ${W}`,G){V.update("Compiling to standalone executable...");let $=[];if(H.includes("all"))$=["darwin-arm64","darwin-x64","linux-arm64","linux-x64","windows-x64"];else if(H.includes("native"))$=[`${process.platform}-${process.arch}`];else $=H;for(let j of $){V.update(`Compiling for ${j}...`);let A=$.length>1?WX.join(W,j):W;await WJ`mkdir -p ${A}`;let S=WX.extname(z),w=S?z.slice(0,-S.length):z,P=WX.basename(w),b=j.includes("windows"),t=J.outfile||WX.join(A,b?`${P}.exe`:P),m=["build",z,"--compile","--outfile",t,"--target",`bun-${j}`];if(J.minify??Q.build?.minify??!0)m.push("--minify");if(J.sourcemap??Q.build?.sourcemap??!1)m.push("--sourcemap");if(J.bytecode)m.push("--bytecode");let d=Q.build?.external||[];for(let D1 of d)m.push("--external",D1);if((await WJ`bun ${m}`.quiet()).exitCode!==0)throw Error(`Compilation failed for ${j}`)}if(Q.build?.compress&&$.length>1){V.update("Compressing builds...");for(let j of $)await WJ`cd ${W} && tar -czf ${j}.tar.gz ${j}`,await WJ`rm -rf ${W}/${j}`}}else{let j={entrypoints:Array.isArray(Y)?Y:[Y],outdir:W,target:J.runtime||"bun",format:"esm",minify:J.minify??Q.build?.minify??!0,sourcemap:J.sourcemap??Q.build?.sourcemap??!1,external:Q.build?.external||[],plugins:[GX({commandsDir:Q.commands?.directory||"commands",outputFile:"./.bunli/commands.gen.ts",config:Q})]},C=await Bun.build(j);if(!C.success)throw Error(`Build failed: ${C.logs.join("\\n")}`);for(let A of C.outputs)if(A.path.endsWith(".js")){let S=await A.text(),P=`#!/usr/bin/env ${J.runtime==="node"?"node":"bun"}
|
|
134
|
-
${S}`;await Bun.write(A.path,P),await WJ`chmod +x ${A.path}`}}V.succeed("Build complete!");let U=await WJ`du -sh ${W}`.text();console.log(Z.dim(`Output size: ${U.trim()}`))}catch(U){V.fail("Build failed"),console.error(Z.red(U instanceof Error?U.message:String(U))),process.exit(1)}}})});var HV={};yJ(HV,{default:()=>tF1});import{defineCommand as aF1,option as k8}from"@bunli/core";import{z as b8}from"zod";import{join as sF1}from"path";var tF1;var GV=G0(()=>{zX();zX();$J();tF1=aF1({name:"generate",description:"Generate command type definitions",alias:"gen",options:{commandsDir:k8(b8.string().optional(),{description:"Commands directory"}),output:k8(b8.string().default("./.bunli/commands.gen.ts"),{short:"o",description:"Output file"}),watch:k8(b8.boolean().default(!1),{short:"w",description:"Watch for changes"})},async handler({flags:J,colors:X,spinner:Z}){let Q=await R0(),Y=J.commandsDir||Q.commands?.directory||"commands",H=J.output||"./.bunli/commands.gen.ts",G=new g0({commandsDir:Y,outputFile:H,config:Q}),z=Z("Generating types...");try{await G.run(),z.succeed("Types generated")}catch(W){z.fail("Failed to generate types");let V=W instanceof Error?W.message:String(W);console.error(X.red(V));return}if(J.watch){console.log(X.cyan(`
|
|
133
|
+
`))}}}catch(A){if(A.name==="AbortError"){console.log(Q.dim("Watch stopped"));return}throw A}}else{let V=await W();if(V){let U=Bun.spawn(["bun",V.path],{stdio:["inherit","inherit","inherit"],env:{...process.env,NODE_ENV:"development"},onExit:($,j,C,A)=>{if(j!==0&&j!==null&&!C)console.log(Q.dim(`Process exited with code ${j}`))}});await U.exited,process.exit(U.exitCode??0)}else process.exit(1)}}})});var QV={};yJ(QV,{default:()=>dF1});import{defineCommand as rF1,option as t0}from"@bunli/core";import{z as n0}from"zod";var{$:WJ}=globalThis.Bun;import WX from"path";var dF1;var YV=G0(()=>{zX();C2();$J();L8();dF1=rF1({name:"build",description:"Build your CLI for production",alias:"b",options:{entry:t0(n0.string().optional(),{short:"e",description:"Entry file (defaults to auto-detect)"}),outdir:t0(n0.string().optional(),{short:"o",description:"Output directory"}),outfile:t0(n0.string().optional(),{description:"Output filename (for single executable)"}),minify:t0(n0.boolean().optional(),{short:"m",description:"Minify output"}),sourcemap:t0(n0.boolean().optional(),{short:"s",description:"Generate sourcemaps"}),bytecode:t0(n0.boolean().default(!1),{description:"Enable bytecode compilation (experimental)"}),runtime:t0(n0.enum(["bun","node"]).optional(),{short:"r",description:"Runtime target (for non-compiled builds)"}),targets:t0(n0.string().optional().transform((J)=>{if(!J)return;return J.split(",").map((X)=>X.trim())}),{short:"t",description:"Target platforms for compilation (e.g., darwin-arm64,linux-x64)"}),watch:t0(n0.boolean().default(!1),{short:"w",description:"Watch for changes"})},handler:async({flags:J,spinner:X,colors:Z})=>{let Q=await R0();{let U=X("Generating types...");try{await new g0({commandsDir:Q.commands?.directory||"commands",outputFile:"./.bunli/commands.gen.ts",config:Q,generateReport:Q.commands?.generateReport}).run(),U.succeed("Types generated")}catch($){U.fail("Failed to generate types");let j=$ instanceof Error?$.message:String($);console.error(Z.red(j));return}}let Y=J.entry||Q.build?.entry||await D2();if(!Y)console.error(Z.red("No entry file found. Please specify with --entry or in bunli.config.ts")),process.exit(1);let H=J.targets||Q.build?.targets,G=H&&H.length>0;if(G&&Array.isArray(Y))console.error(Z.red("Compiled builds only support a single entry file")),process.exit(1);let z=Array.isArray(Y)?Y[0]:Y;if(!z)console.error(Z.red("Entry file is undefined")),process.exit(1);let W=J.outdir||Q.build?.outdir||"./dist",V=X("Building CLI...");V.start();try{if(await WJ`rm -rf ${W}`,await WJ`mkdir -p ${W}`,G){V.update("Compiling to standalone executable...");let $=[];if(H.includes("all"))$=["darwin-arm64","darwin-x64","linux-arm64","linux-x64","windows-x64"];else if(H.includes("native"))$=[`${process.platform}-${process.arch}`];else $=H;for(let j of $){V.update(`Compiling for ${j}...`);let A=$.length>1?WX.join(W,j):W;await WJ`mkdir -p ${A}`;let S=WX.extname(z),w=S?z.slice(0,-S.length):z,P=WX.basename(w),b=j.includes("windows"),t=J.outfile||WX.join(A,b?`${P}.exe`:P),m=["build",z,"--compile","--outfile",t,"--target",`bun-${j}`];if(J.minify??Q.build?.minify??!0)m.push("--minify");if(J.sourcemap??Q.build?.sourcemap??!1)m.push("--sourcemap");if(J.bytecode)m.push("--bytecode");let d=Q.build?.external||[];for(let D1 of d)m.push("--external",D1);if((await WJ`bun ${m}`.quiet()).exitCode!==0)throw Error(`Compilation failed for ${j}`)}if(Q.build?.compress&&$.length>1){V.update("Compressing builds...");for(let j of $)await WJ`cd ${W} && tar -czf ${j}.tar.gz ${j}`,await WJ`rm -rf ${W}/${j}`}}else{let j={entrypoints:Array.isArray(Y)?Y:[Y],outdir:W,target:J.runtime||"bun",format:"esm",minify:J.minify??Q.build?.minify??!0,sourcemap:J.sourcemap??Q.build?.sourcemap??!1,external:Q.build?.external||[],plugins:[GX({commandsDir:Q.commands?.directory||"commands",outputFile:"./.bunli/commands.gen.ts",config:Q})]},C=await Bun.build(j);if(!C.success)throw Error(`Build failed: ${C.logs.join("\\n")}`);for(let A of C.outputs)if(A.path.endsWith(".js")){let S=await A.text(),P=`#!/usr/bin/env ${J.runtime==="node"?"node":"bun"}
|
|
134
|
+
${S}`;await Bun.write(A.path,P),await WJ`chmod +x ${A.path}`}}V.succeed("Build complete!");let U=await WJ`du -sh ${W}`.text();console.log(Z.dim(`Output size: ${U.trim()}`))}catch(U){V.fail("Build failed"),console.error(Z.red(U instanceof Error?U.message:String(U))),process.exit(1)}}})});var HV={};yJ(HV,{default:()=>tF1});import{defineCommand as aF1,option as k8}from"@bunli/core";import{z as b8}from"zod";import{join as sF1}from"path";var tF1;var GV=G0(()=>{zX();zX();$J();tF1=aF1({name:"generate",description:"Generate command type definitions",alias:"gen",options:{commandsDir:k8(b8.string().optional(),{description:"Commands directory"}),output:k8(b8.string().default("./.bunli/commands.gen.ts"),{short:"o",description:"Output file"}),watch:k8(b8.boolean().default(!1),{short:"w",description:"Watch for changes"})},async handler({flags:J,colors:X,spinner:Z}){let Q=await R0(),Y=J.commandsDir||Q.commands?.directory||"commands",H=J.output||"./.bunli/commands.gen.ts",G=new g0({commandsDir:Y,outputFile:H,config:Q,generateReport:Q.commands?.generateReport}),z=Z("Generating types...");try{await G.run(),z.succeed("Types generated")}catch(W){z.fail("Failed to generate types");let V=W instanceof Error?W.message:String(W);console.error(X.red(V));return}if(J.watch){console.log(X.cyan(`
|
|
135
135
|
\uD83D\uDC40 Watching ${Y}...
|
|
136
136
|
`));let{watch:W}=await import("fs/promises"),V=new AbortController,{signal:U}=V;process.on("SIGINT",()=>{console.log(X.dim(`
|
|
137
137
|
Stopping watcher...`)),V.abort(),process.exit(0)});try{let $=W(Y,{recursive:!0,signal:U});for await(let j of $){if(!j.filename||!T2(j.filename))continue;console.log(X.dim(`${j.eventType}: ${j.filename}`));let C=Z("Regenerating...");try{await G.run({type:j.eventType==="rename"?"delete":"update",path:sF1(Y,j.filename)}),C.succeed("Updated")}catch(A){C.fail("Failed");let S=A instanceof Error?A.message:String(A);console.error(X.red(S))}}}catch($){if($ instanceof Error&&$.name==="AbortError"){console.log(X.dim("Watcher stopped"));return}throw $}}}})});var KV={};yJ(KV,{default:()=>Jj1});import{defineCommand as nF1,option as K9}from"@bunli/core";import{z as VJ}from"zod";import{spawn as oF1}from"child_process";import{readdir as eF1}from"fs/promises";import{existsSync as zV}from"fs";import WV from"path";async function VV(J,X,Z){return new Promise((Q,Y)=>{let H=["test"],G=X.pattern||Z.test?.pattern||"**/*.test.ts",z=Array.isArray(G)?G:[G];if(H.push(...z),X.watch??Z.test?.watch)H.push("--watch");if(X.coverage??Z.test?.coverage)H.push("--coverage");if(X.bail)H.push("--bail");if(X.timeout)H.push("--timeout",X.timeout.toString());let W=oF1("bun",H,{cwd:J,stdio:["inherit","pipe","pipe"],env:{...process.env,NODE_ENV:"test"}}),V="",U="";W.stdout?.on("data",($)=>{V+=$.toString(),process.stdout.write($)}),W.stderr?.on("data",($)=>{U+=$.toString(),process.stderr.write($)}),W.on("exit",($)=>{let j=(V.match(/\u2713/g)||[]).length,C=(V.match(/\u2717/g)||[]).length,A=(V.match(/\u229D/g)||[]).length;Q({success:$===0,passed:j,failed:C,skipped:A})}),W.on("error",Y)})}async function Xj1(J){if(J.endsWith("/*")){let X=J.slice(0,-2);if(zV(X))return(await eF1(X,{withFileTypes:!0})).filter((Q)=>Q.isDirectory()&&zV(WV.join(X,Q.name,"package.json"))).map((Q)=>WV.join(X,Q.name))}return[]}var Jj1;var UV=G0(()=>{$J();Jj1=nF1({name:"test",description:"Run tests for your CLI",alias:"t",options:{pattern:K9(VJ.string().or(VJ.array(VJ.string())).optional(),{short:"p",description:"Test file patterns"}),watch:K9(VJ.boolean().default(!1),{short:"w",description:"Watch for changes"}),coverage:K9(VJ.boolean().default(!1),{short:"c",description:"Generate coverage report"}),bail:K9(VJ.boolean().default(!1),{short:"b",description:"Stop on first failure"}),timeout:K9(VJ.number().int().positive().optional(),{description:"Test timeout in milliseconds"}),all:K9(VJ.boolean().default(!1),{description:"Run tests in all packages (workspace mode)"})},handler:async({flags:J,positional:X,spinner:Z,colors:Q})=>{let Y=await R0();if(J.all&&Y.workspace?.packages){let H=Y.workspace.packages,G=!0;for(let z of H){let W=await Xj1(z);for(let V of W){let U=Z(`Testing ${V}...`);U.start();try{if((await VV(V,J,Y)).success)U.succeed(`${V} tests passed`);else if(U.fail(`${V} tests failed`),G=!1,J.bail)break}catch($){if(U.fail(`${V} tests failed`),console.error(Q.red($ instanceof Error?$.message:String($))),G=!1,J.bail)break}}if(!G&&J.bail)break}if(!G)process.exit(1)}else{let H=Z("Running tests...");H.start();try{let G=await VV(".",J,Y);if(G.success){if(H.succeed("All tests passed!"),console.log(Q.green(`\u2713 ${G.passed} tests passed`)),G.skipped>0)console.log(Q.yellow(`\u229D ${G.skipped} tests skipped`))}else H.fail("Tests failed"),console.log(Q.red(`\u2717 ${G.failed} tests failed`)),process.exit(1)}catch(G){H.fail("Tests failed"),console.error(Q.red(G instanceof Error?G.message:String(G))),process.exit(1)}}}})});var RV={};yJ(RV,{default:()=>Qj1});import{defineCommand as Zj1,option as U9}from"@bunli/core";import{z as fJ}from"zod";var{$:N0}=globalThis.Bun;async function Yj1(J,X,Z,Q,Y){let H=await v8(),G=H.version||"0.0.0",z=await Gj1(J.version,G,Z);if(console.log(Y.bold(`Releasing ${H.name||"CLI"}`)),console.log(Y.dim(` Current: ${G}`)),console.log(Y.dim(` New: ${z}`)),console.log(),!J.dry){if(!await Z.confirm("Continue with release?",{default:!0})){console.log(Y.yellow("Release cancelled"));return}}let W=[{name:"Running tests",cmd:()=>N0`bun test`},{name:"Building project",cmd:()=>N0`bun run build`},{name:"Updating version",cmd:()=>zj1(z)},{name:"Creating git tag",cmd:()=>Wj1(z,X,J)},{name:"Publishing to npm",cmd:()=>Vj1(J,X)},{name:"Creating GitHub release",cmd:()=>Kj1(z,J,X)}];for(let V of W){if(V.name.includes("npm")&&!(J.npm??X.release?.npm??!0))continue;if(V.name.includes("GitHub")&&!(J.github??X.release?.github??!0))continue;let U=Q(V.name);U.start();try{if(!J.dry)await V.cmd();U.succeed(V.name)}catch($){if(U.fail(V.name),console.error(Y.red($ instanceof Error?$.message:String($))),!J.dry)process.exit(1)}}if(console.log(),console.log(Y.green(`\u2728 Released ${H.name||"CLI"} v${z}!`)),J.github??X.release?.github??!0)console.log(Y.dim(`GitHub: https://github.com/${await BV()}/releases/tag/v${z}`));if(J.npm??X.release?.npm??!0)console.log(Y.dim(`NPM: https://npmjs.com/package/${H.name}`))}async function Hj1(J,X,Z,Q,Y){if(console.log(Y.bold("Workspace Release")),X.workspace?.versionStrategy==="independent")console.log("Using independent versioning...");else console.log("Using fixed versioning...")}async function v8(){return await Bun.file("package.json").json()}async function Gj1(J,X,Z){if(J)if(["patch","minor","major"].includes(J))return VX(X,J);else return J;let Q=await Z.select("Select version bump:",{choices:[{name:`patch (${VX(X,"patch")})`,value:"patch"},{name:`minor (${VX(X,"minor")})`,value:"minor"},{name:`major (${VX(X,"major")})`,value:"major"},{name:"custom",value:"custom"}]});if(Q==="custom")return await Z("Enter version:");return VX(X,Q)}function VX(J,X){let Z=J.split(".").map(Number),[Q=0,Y=0,H=0]=Z;switch(X){case"patch":return`${Q}.${Y}.${H+1}`;case"minor":return`${Q}.${Y+1}.0`;case"major":return`${Q+1}.0.0`}}async function zj1(J){let X=await v8();X.version=J,await Bun.write("package.json",JSON.stringify(X,null,2)+"\\n")}async function Wj1(J,X,Z){let Y=(Z.tag||X.release?.tagFormat||"v${version}").replace("${version}",J);await N0`git add package.json`,await N0`git commit -m "chore: release v${J}"`,await N0`git tag ${Y}`,await N0`git push origin main --tags`}async function Vj1(J,X){if(!(J.npm??X.release?.npm??!0))return;if((await v8()).private)throw Error("Cannot publish private package to npm");await N0`npm publish`}async function Kj1(J,X,Z){if(!(X.github??Z.release?.github??!0))return;let Q=`v${J}`,Y=await BV();try{await N0`gh --version`.quiet()}catch{console.warn("GitHub CLI not found, skipping GitHub release");return}await N0`gh release create ${Q} --title "Release ${Q}" --generate-notes`}async function BV(){return(await N0`git remote get-url origin`.text()).match(/github\.com[:/]([^\s/]+\/[^\s/]+?)(?:\.git)?(?:\s|$)/)?.[1]??"unknown/repo"}var Qj1;var $V=G0(()=>{$J();Qj1=Zj1({name:"release",description:"Create a release of your CLI",alias:"r",options:{version:U9(fJ.enum(["patch","minor","major"]).or(fJ.string()).optional(),{short:"v",description:"Version to release (patch/minor/major/x.y.z)"}),tag:U9(fJ.string().optional(),{short:"t",description:"Git tag format"}),npm:U9(fJ.boolean().optional(),{description:"Publish to npm"}),github:U9(fJ.boolean().optional(),{description:"Create GitHub release"}),dry:U9(fJ.boolean().default(!1),{short:"d",description:"Dry run - show what would be done"}),all:U9(fJ.boolean().default(!1),{description:"Release all packages (workspace mode)"})},handler:async({flags:J,prompt:X,spinner:Z,colors:Q})=>{let Y=await R0();try{if((await N0`git status --porcelain`.text()).trim()&&!J.dry)console.error(Q.red("Working directory is not clean. Please commit or stash changes first.")),process.exit(1)}catch{console.error(Q.red("Not a git repository")),process.exit(1)}if(J.all&&Y.workspace?.packages)await Hj1(J,Y,X,Z,Q);else await Yj1(J,Y,X,Z,Q)}})});var qV={};yJ(qV,{default:()=>Rj1});import{defineCommand as Uj1,option as B9}from"@bunli/core";import{z as R9}from"zod";import{spawn as Bj1}from"child_process";var Rj1;var FV=G0(()=>{Rj1=Uj1({name:"init",description:"Initialize a new Bunli CLI project",alias:"i",options:{name:B9(R9.string().optional(),{short:"n",description:"Project name"}),template:B9(R9.enum(["basic","advanced","monorepo"]).default("basic"),{short:"t",description:"Project template"}),dir:B9(R9.string().optional(),{short:"d",description:"Directory to create project in"}),git:B9(R9.boolean().default(!0),{short:"g",description:"Initialize git repository"}),install:B9(R9.boolean().default(!0),{description:"Install dependencies"}),"package-manager":B9(R9.enum(["bun","pnpm","yarn","npm"]).default("bun"),{short:"p",description:"Package manager to use"})},handler:async({flags:J,positional:X,colors:Z})=>{console.log(Z.cyan("\uD83D\uDE80 Creating new Bunli CLI project...")),console.log();let Q=["create-bunli"];if(X[0])Q.push(X[0]);else if(J.name)Q.push(J.name);if(J.template!=="basic")Q.push("--template",J.template);if(J.dir)Q.push("--dir",J.dir);if(!J.git)Q.push("--no-git");if(!J.install)Q.push("--no-install");if(J["package-manager"]!=="bun")Q.push("--package-manager",J["package-manager"]);console.log(Z.dim(`> bunx ${Q.join(" ")}`)),console.log();let Y=Bj1("bunx",Q,{stdio:"inherit",env:process.env});Y.on("exit",(H)=>{if(H===0){console.log(),console.log(Z.green("\uD83C\uDF89 Project created successfully!")),console.log(),console.log("Next steps:");let G=X[0]||J.name||"your-project";console.log(Z.gray(` cd ${G}`)),console.log(Z.gray(" bunli dev"))}else console.error(Z.red("Failed to create project")),process.exit(H||1)}),Y.on("error",(H)=>{console.error(Z.red("Failed to run create-bunli:"),H.message),console.log(),console.log("Make sure create-bunli is available:"),console.log(Z.gray(" bunx create-bunli --help")),process.exit(1)})}})});$J();import{createCLI as $j1}from"@bunli/core";var jV=await $j1({name:"bunli",version:"0.1.0",description:"The Bunli CLI toolchain for developing, building, and distributing CLIs"}),Nk1=await R0();await jV.load({dev:()=>Promise.resolve().then(() => (ZV(),XV)),build:()=>Promise.resolve().then(() => (YV(),QV)),generate:()=>Promise.resolve().then(() => (GV(),HV)),test:()=>Promise.resolve().then(() => (UV(),KV)),release:()=>Promise.resolve().then(() => ($V(),RV)),init:()=>Promise.resolve().then(() => (FV(),qV))});await jV.run();
|
package/dist/config.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bunli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The Bunli CLI toolchain for developing, building, and distributing CLIs",
|
|
6
6
|
"bin": {
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"prepublishOnly": "bun run build"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@bunli/core": "0.
|
|
51
|
-
"@bunli/generator": "0.
|
|
50
|
+
"@bunli/core": "0.3.0",
|
|
51
|
+
"@bunli/generator": "0.3.0",
|
|
52
52
|
"@bunli/utils": "0.2.0",
|
|
53
53
|
"zod": "^3.24.1"
|
|
54
54
|
},
|