jbdeploy 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alex JCM
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # 🚀 JBoss/Wildfly Deploy CLI
2
+
3
+ ![Bun](https://img.shields.io/badge/Bun-%23000000.svg?style=for-the-badge&logo=bun&logoColor=white)
4
+ ![Node.js](https://img.shields.io/badge/Node.js-339933?style=for-the-badge&logo=nodedotjs&logoColor=white)
5
+ ![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white)
6
+ ![License](https://img.shields.io/badge/License-MIT-blue.svg?style=for-the-badge)
7
+
8
+ CLI tool to deploy EAR/WAR artifacts to **JBoss** or **Wildfly**.
9
+
10
+ <p align="center">
11
+ <img src="demo.gif" alt="jbdeploy demo" width="800"/>
12
+ </p>
13
+
14
+ ## Features
15
+
16
+ * **Fast Build**: Automatic project building — supports **Gradle** and **Maven** (auto-detects and uses `gradlew`/`mvnw` wrappers).
17
+ * **Smart Deployment**: Direct deployment to `standalone/deployments` with **real-time validation polling**.
18
+ * **Modern UI**: Interactive TUI based on `@clack/prompts` with semantic logging.
19
+ * **Persistent Preferences**: Remembers your last server, debug port, JVM memory profile, and startup mode between sessions.
20
+ * **Configurable Debug**: Choose your JVM debug port dynamically.
21
+ * **Dynamic JVM Memory**: Assign pre-configured JVM memory capacities independently for each server.
22
+ * **Seamless Workflow**: Automatic server startup after deployment and loop-based interface to keep you in the flow.
23
+
24
+ ## 📋 Requirements
25
+
26
+ - **Bun** (Recommended for development) or **Node.js v22+** (For distribution)
27
+ - **Gradle** or **Maven** (or project wrappers `gradlew` / `mvnw`)
28
+ - **JBoss/Wildfly** configured locally
29
+
30
+ ## ⚙️ Installation & Development
31
+
32
+ ### For Users (Node.js)
33
+ If you want to use the stable, compiled version:
34
+ ```bash
35
+ npm run build
36
+ npm install -g .
37
+ ```
38
+
39
+ ### For Developers (Bun)
40
+ If you want to test changes in real-time:
41
+ 1. Clone the repository and install:
42
+ ```bash
43
+ bun install
44
+ ```
45
+ 2. Enable hot-linking:
46
+ ```bash
47
+ bun run local:link
48
+ ```
49
+ Now you can use `jbdeploy` from any terminal. It executes the source code via Bun, making your changes **immediately active**.
50
+
51
+ ## 🏗️ Build Pipeline
52
+
53
+ This project leverages a **Universal JavaScript** strategy:
54
+ - **Core**: Built with TypeScript and optimized for **Bun**'s high-speed runtime during development.
55
+ - **Distribution**: Compiles with `tsup` into a single, specialized **ESM** bundle (`dist/index.js`) with a Node.js shebang, ensuring seamless usage in any Node environment.
56
+
57
+ ## 🚀 Usage
58
+
59
+ Run the CLI from any project you want to deploy:
60
+
61
+ ```bash
62
+ jbdeploy
63
+ ```
64
+
65
+ ### Workflow
66
+ 1. **Server Selection**: Choose a saved server or add a new one.
67
+ 2. **Action**: Choose between `build + copy + deploy`, `copy + deploy`, or `start server only`.
68
+ 3. **Build (if applicable)**: Gradle or Maven is auto-detected.
69
+ 4. **Server Mode**: If the server is stopped, choose **Normal** or **Debug** mode. Your last choice is remembered.
70
+ 5. **Auto-Start**: After a successful deployment with the server stopped, the CLI starts it automatically.
71
+ 6. **Looping**: After each action, the CLI returns to the main menu automatically.
72
+
73
+ ## 📁 Configuration
74
+
75
+ All preferences, registered JBoss servers, JVM memory profiles, and debug ports are safely saved locally at:
76
+ ```bash
77
+ ~/.jbdeploy/config.json
78
+ ```
79
+
80
+ ---
81
+
82
+ ## 🛠️ Flags
83
+
84
+ | Flag | Description |
85
+ |---|---|
86
+ | `--list` | List deployed artifacts and their status (`✔ deployed`, `✖ failed`, etc.) |
87
+ | `--clean` | Clean error markers (`.failed`, `.pending`) on the active server |
88
+ | `--help`, `-h` | Show help |
89
+
90
+ Example:
91
+ ```bash
92
+ jbdeploy --list
93
+ ```
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ var Te=Object.defineProperty;var A=(e,o)=>()=>(e&&(o=e(e=0)),o);var G=(e,o)=>{for(var r in o)Te(e,r,{get:o[r],enumerable:!0})};import yr from"path";import{fileURLToPath as vr}from"url";var n=A(()=>{"use strict"});var re={};G(re,{ARTIFACT_EXTENSIONS:()=>I,DEFAULT_DEBUG_PORT:()=>R,DEPLOYMENT_MARKERS:()=>l,EXIT_CODES:()=>g,SERVER_PATHS:()=>S,SERVER_SCRIPT:()=>O});var g,S,l,I,R,O,E=A(()=>{"use strict";n();g={SUCCESS:0,GENERAL_ERROR:1,USAGE_ERROR:2,COMMAND_NOT_FOUND:127,INTERRUPTED:130},S={DEPLOYMENTS:["standalone","deployments"],DATA:["standalone","data"],LOG:["standalone","log"],TMP:["standalone","tmp"]},l={DODEPLOY:".dodeploy",DEPLOYED:".deployed",FAILED:".failed",ISDEPLOYING:".isdeploying",SKIPDEPLOY:".skipdeploy",PENDING:".pending"},I=[".war",".ear"],R=5005,O={BIN_DIR:"bin",WIN:"standalone.bat",UNIX:"standalone.sh",OS_FLAG:"-Dos.name=Linux"}});var b,j=A(()=>{"use strict";n();b={isWindows:process.platform==="win32",isMac:process.platform==="darwin",isLinux:process.platform==="linux",platform:process.platform}});var Ee={};G(Ee,{listDeployments:()=>ar});import{readdirSync as sr,existsSync as nr}from"fs";import{join as ir}from"path";function ar(e){let o=ir(e,...S.DEPLOYMENTS);if(!nr(o))return[];let r=sr(o);return r.filter(t=>I.some(c=>t.endsWith(c))).map(t=>{let c="\u{1F550} pending";return r.includes(`${t}${l.DEPLOYED}`)&&(c="\u2714 deployed"),r.includes(`${t}${l.FAILED}`)&&(c="\u2716 failed"),r.includes(`${t}${l.ISDEPLOYING}`)&&(c="\u23F3 deploying"),r.includes(`${t}${l.PENDING}`)&&(c="\u{1F550} pending"),{name:t,status:c}})}var ve=A(()=>{"use strict";n();E()});var he={};G(he,{cleanMarkers:()=>dr});import{readdirSync as cr,rmSync as lr,existsSync as mr}from"fs";import{join as we}from"path";function dr(e){let o=we(e,...S.DEPLOYMENTS);if(!mr(o))return;let s=cr(o).filter(t=>t.endsWith(l.FAILED)||t.endsWith(l.ISDEPLOYING)||t.endsWith(l.PENDING));for(let t of s)lr(we(o,t),{force:!0})}var be=A(()=>{"use strict";n();E()});var xe={};G(xe,{notifySuccess:()=>ur});import{spawn as pr}from"child_process";function ur(e,o="jbdeploy"){if(!b.isMac)return;let r=`display notification "${e}" with title "${o}" sound name "Glass"`;pr("osascript",["-e",r],{stdio:"ignore"})}var $e=A(()=>{"use strict";n();j()});n();import{tasks as Ae}from"@clack/prompts";n();import{note as Re,cancel as Ne,outro as Ie,log as T}from"@clack/prompts";var h={reset:"\x1B[0m",cyan:"\x1B[36m",red:"\x1B[31m",dim:"\x1B[2m"},a={info:e=>T.info(e),success:e=>T.success(e),warn:e=>T.warn(e),error:(e,o)=>{T.error(e),o&&console.error(` ${h.dim}${o}${h.reset}
3
+ `)},step:e=>T.step(e),message:e=>T.message(e),intro:e=>console.log(`${h.cyan}\u250C ${e}${h.reset}`),outro:e=>Ie(`${h.cyan}\u2514 ${e}${h.reset}`),cancel:e=>Ne(`${h.red}${e}${h.reset}`),note:(e,o)=>Re(e,o)};E();n();E();import{existsSync as F,mkdirSync as Oe,readFileSync as Me}from"fs";import{writeFile as Ce}from"fs/promises";import{join as U}from"path";import{homedir as Le}from"os";var B=U(Le(),".jbdeploy"),Y=U(B,"config.json");function k(){if(!F(Y))return{servers:[]};try{let e=Me(Y,"utf-8");return JSON.parse(e)}catch(e){return console.error("Error reading configuration:",e),{servers:[]}}}async function N(e){F(B)||Oe(B,{recursive:!0}),await Ce(Y,JSON.stringify(e,null,2),"utf-8")}function X(e){return e.trim().replace(/^['"]|['"]$/g,"").replace(/\\ /g," ")}function te(e){let o=X(e);if(!F(o))return!1;let r=U(o,...S.DEPLOYMENTS);return F(r)}n();import{group as se,text as V,select as M,isCancel as z,cancel as C,note as ne}from"@clack/prompts";n();E();import _e from"fast-glob";import{statSync as Ge}from"fs";import{basename as Fe}from"path";async function oe(){let e=I.flatMap(t=>[`build/libs/*${t}`,`*/build/libs/*${t}`,`target/*${t}`,`*/target/*${t}`]),r=(await _e(e,{onlyFiles:!0})).map(t=>{let c=Ge(t);return{path:t,name:Fe(t),size:c.size}});return Array.from(new Map(r.map(t=>[t.path,t])).values())}function W(e){if(e===0)return"0 Bytes";let o=1024,r=["Bytes","KB","MB","GB"],s=Math.floor(Math.log(e)/Math.log(o));return parseFloat((e/Math.pow(o,s)).toFixed(2))+" "+r[s]}E();async function H(e){let o=await se({name:()=>V({message:"Name for this server (e.g., wildfly-dev):",placeholder:"server-local",validate:t=>{if(!t)return"Name is required";if(e.servers.some(c=>c.name===t))return"A server with this name already exists"}}),home:()=>V({message:"Full path for Server Home:",placeholder:"/opt/wildfly-20.0",validate:t=>{if(!t)return"Path is required";if(!te(t))return"This path does not look like a valid Server Home (missing standalone/deployments)"}}),profile:()=>M({message:"Select the JVM memory profile for this server (affects -Xms and -Xmx):",options:[{value:"recommended",label:"[ Recommended ] 2GB initial - 5GB max (Default)"},{value:"minimal",label:"[ Minimal ] 1GB initial - 2GB max"}],initialValue:"recommended"})},{onCancel:()=>{C("Operation cancelled"),process.exit(g.INTERRUPTED)}}),r={name:o.name,home:X(o.home),memoryProfile:o.profile},s={...e,servers:[...e.servers,r],lastServer:r.name};return await N(s),ne("Server saved successfully. You can review or modify this configuration directly at: ~/.jbdeploy/config.json"),r}async function ie(e){let r=[...[...e.servers].sort((t,c)=>t.name===e.lastServer?-1:c.name===e.lastServer?1:0).map(t=>({value:t,label:`${t.name} (${t.home})`})),{value:"ADD_NEW",label:"\u2795 Add new server..."}],s=await M({message:"Select server:",options:r,initialValue:e.servers.find(t=>t.name===e.lastServer)||e.servers[0]});return z(s)&&(C("Operation cancelled"),process.exit(g.INTERRUPTED)),s}async function ae(e){if(e.length===1){let s=e[0];return ne(`Artifact detected: ${s.name} (${W(s.size)})`),s}let o=[...e].sort((s,t)=>t.size-s.size),r=await M({message:"Multiple artifacts found. Select one:",options:o.map(s=>({value:s,label:`${s.name} (${W(s.size)})`}))});return z(r)&&(C("Operation cancelled"),process.exit(g.INTERRUPTED)),r}async function ce(){let e=await M({message:"Select action:",options:[{value:"build-deploy",label:"build + copy + deploy"},{value:"deploy-only",label:"copy + deploy"},{value:"start-only",label:"start server only"}]});return z(e)&&(C("Operation cancelled"),process.exit(g.INTERRUPTED)),e}async function K(e,o){let r=e||R,s=e?`\u{1F41E} Debug mode (Port: ${e})`:`\u{1F41E} Debug mode (Default port: ${R})`,t=await se({mode:()=>M({message:"Select startup mode:",options:[{value:"normal",label:"\u{1F680} Normal mode"},{value:"debug",label:s},{value:"debug-custom",label:"\u{1F41E} Debug mode (Custom port...)"}],initialValue:o??"normal"}),port:({results:y})=>y.mode==="debug-custom"?V({message:"Enter debug port:",placeholder:r.toString(),defaultValue:r.toString(),validate:i=>{if(i&&isNaN(Number(i)))return"Port must be a number"}}):Promise.resolve(void 0)},{onCancel:()=>{C("Operation cancelled"),process.exit(g.INTERRUPTED)}}),c=t.mode==="debug"||t.mode==="debug-custom"?"debug":"normal",f=t.mode==="debug"?r:t.port?Number(t.port):void 0;return{mode:c,...f?{port:f}:{}}}n();import{exec as ke}from"child_process";import{promisify as je}from"util";var le=je(ke);async function me(){let e=process.platform;try{if(e==="win32"){let{stdout:o}=await le("tasklist"),r=o.toLowerCase();return r.includes("jboss")||r.includes("wildfly")||r.includes("standalone")}else return await le("pgrep -f standalone"),!0}catch{return!1}}n();E();import{rmSync as Be,existsSync as Ye}from"fs";import{join as q}from"path";async function J(e){let o=[q(e,...S.DATA),q(e,...S.LOG),q(e,...S.TMP)];for(let r of o)if(Ye(r))try{Be(r,{recursive:!0,force:!0})}catch{console.warn(`Could not clean directory: ${r}. It might be locked.`)}}n();E();j();import{spawn as Ue}from"child_process";import{join as de}from"path";import{existsSync as Xe,statSync as We,chmodSync as Ve}from"fs";function ze(e){return e==="minimal"?"-Xms1024m -Xmx2048m":"-Xms2048m -Xmx5120m"}var He=e=>`-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=${e}`;async function Q(e,o=!1,r=R,s){let c=`-server ${ze(s)} -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=2048m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+ParallelRefProcEnabled`,f=b.isWindows,y=de(e,O.BIN_DIR),i=f?O.WIN:O.UNIX,m=de(y,i);if(!Xe(m))throw new Error(`Startup script not found: ${m}`);if(!f&&!((We(m).mode&73)!==0))try{Ve(m,493)}catch(w){throw new Error(`Script does not have execution permissions and auto-fix failed. Run:
4
+ chmod +x ${m}`,{cause:w})}let d=o?`${c} ${He(r)}`:c,D=f?[]:["-Dos.name=Linux"];return new Promise((_,P)=>{let w=Ue(m,D,{cwd:y,stdio:"inherit",env:{...process.env,JAVA_OPTS:d},shell:f});w.on("close",x=>{x===0||x===null?_():P(new Error(`Server process exited with code ${x}`))}),w.on("error",x=>{P(x)})})}n();j();import{spawn as ue}from"child_process";import{existsSync as L,chmodSync as pe}from"fs";function fe(e){let o=b.isWindows;if(e==="gradle"){let r=o?"gradlew.bat":"./gradlew";if(L(r)){if(!o)try{pe(r,493)}catch{}return r}return"gradle"}if(e==="maven"){let r=o?"mvnw.cmd":"./mvnw";if(L(r)){if(!o)try{pe(r,493)}catch{}return r}return"mvn"}return e}function Ke(){return L("build.gradle")||L("build.gradle.kts")}async function qe(){return new Promise(e=>{let o=fe("gradle"),r=b.isWindows,s=ue(o,["clean","build","-x","test","-x","pmdMain"],{stdio:"inherit",shell:r});s.on("close",t=>{e(t===0)}),s.on("error",t=>{console.error(`Gradle build error: ${t.message}`),e(!1)})})}function Je(){return L("pom.xml")}async function Qe(){return new Promise(e=>{let o=fe("maven"),r=b.isWindows,s=ue(o,["clean","package","-DskipTests"],{stdio:"inherit",shell:r});s.on("close",t=>{e(t===0)}),s.on("error",t=>{console.error(`Maven build error: ${t.message}`),e(!1)})})}function ge(){return Ke()?"gradle":Je()?"maven":null}async function Se(e){return e==="gradle"?qe():Qe()}n();E();import{join as Z,basename as Ze,extname as er}from"path";import{readdirSync as rr,rmSync as v,existsSync as ee}from"fs";import{copyFile as tr,writeFile as or}from"fs/promises";async function ye(e,o,r=!0){let s=Z(o,...S.DEPLOYMENTS),t=Z(s,e.name);try{let c=er(e.name),f=Ze(e.name,c),y=/^(.+?)-\d/.exec(f),i=y?y[1]:f;if(ee(s)){let P=rr(s);for(let w of P)if(w.startsWith(`${i}-`)&&w.endsWith(c)&&w!==e.name){let $=Z(s,w);v($,{force:!0}),v(`${$}${l.DEPLOYED}`,{force:!0}),v(`${$}${l.FAILED}`,{force:!0}),v(`${$}${l.ISDEPLOYING}`,{force:!0}),v(`${$}${l.SKIPDEPLOY}`,{force:!0}),v(`${$}${l.PENDING}`,{force:!0})}}if(v(`${t}${l.DEPLOYED}`,{force:!0}),v(`${t}${l.FAILED}`,{force:!0}),v(`${t}${l.ISDEPLOYING}`,{force:!0}),v(`${t}${l.SKIPDEPLOY}`,{force:!0}),v(`${t}${l.PENDING}`,{force:!0}),await tr(e.path,t),await or(`${t}${l.DODEPLOY}`,"","utf-8"),!r)return!0;let m=`${t}${l.DEPLOYED}`,d=`${t}${l.FAILED}`,D=0,_=120;for(;D<_;){if(ee(m))return!0;if(ee(d))return!1;await new Promise(P=>setTimeout(P,1e3)),D++}return!1}catch{return!1}}n();async function De(e){let{listDeployments:o}=await Promise.resolve().then(()=>(ve(),Ee)),r=o(e.home);a.message(`Deployments on ${e.name}:
5
+ `+(r.length>0?r.map(s=>` ${s.status} ${s.name}`).join(`
6
+ `):" No artifacts in deployments/"))}async function Pe(e){let{cleanMarkers:o}=await Promise.resolve().then(()=>(be(),he));o(e.home),a.success(`Error markers cleaned on ${e.name}`)}async function fr(){process.on("SIGINT",()=>{process.stdout.write(`
7
+ `)}),process.on("SIGTERM",()=>{process.exit(g.SUCCESS)}),process.on("exit",()=>{process.stdout.write("\x1B[?25h")}),a.intro("\u{1F680} Deploy CLI"),process.stdout.isTTY||(a.error("This tool requires an interactive terminal (TTY).","Additional flags for automation will be required in the future."),process.exit(g.USAGE_ERROR));let e=k(),o=process.argv.slice(2);if((o.includes("--help")||o.includes("-h"))&&(a.intro("Usage: jbdeploy [options]"),process.stdout.write(`
8
+ `),a.info("Options:"),process.stdout.write(` --list List currently deployed artifacts on the server
9
+ `),process.stdout.write(` --clean Clean error markers (.failed, .pending) on the server
10
+ `),process.stdout.write(` --help, -h Show this help message
11
+
12
+ `),a.info("Configuration:"),process.stdout.write(` \u2022 Stored locally at ~/.jbdeploy/config.json
13
+ `),process.stdout.write(` \u2022 Contains server paths, debug ports, and JVM memory profiles.
14
+
15
+ `),a.info("Features:"),process.stdout.write(` \u2022 Semantic logging and persistent interactive UI.
16
+ `),process.stdout.write(` \u2022 Automatic cleanup of JBoss (data, log, tmp) when started through CLI.
17
+ `),process.stdout.write(` \u2022 Configurable Debug Port (default: 5005).
18
+ `),process.stdout.write(` \u2022 Auto-start server after successful build/deployment if stopped.
19
+ `),process.stdout.write(` \u2022 Loop-based workflow to stay in the CLI after actions.
20
+
21
+ `),process.exit(g.SUCCESS)),o.includes("--list")||o.includes("--clean")){let s=e.servers.find(t=>t.name===e.lastServer)||e.servers[0];s||(a.cancel("No servers configured. Run the CLI without flags first."),process.exit(g.GENERAL_ERROR)),o.includes("--list")&&await De(s),o.includes("--clean")&&await Pe(s),a.outro("Utility executed");return}let r;if(e.servers.length===0)r=await H(e),e=k();else{let s=await ie(e);s==="ADD_NEW"?(r=await H(e),e=k()):(r=s,e.lastServer!==r.name&&(e.lastServer=r.name,await N(e)))}for(a.info(`Server: ${r.name} (${r.home})`);;){let s=await ce(),t=await me();if(s==="start-only"){t&&(a.warn("Server is already running. It may be active in another terminal tab or window."),a.note("If you want to restart it, please stop the other instance first.","Conflict detected"),process.exit(g.SUCCESS));let{mode:i,port:m}=await K(r.lastDebugPort,r.lastServerMode);a.step("Server stopped \u2014 cleaning temporary directories (data, log, tmp)"),await J(r.home),a.step(`Starting server in ${i} mode${i==="debug"?` (port ${m})`:""}...`);try{r.lastServerMode=i,i==="debug"&&m&&(r.lastDebugPort=m),await N(e),await Q(r.home,i==="debug",m,r.memoryProfile),a.success("Server process finished.")}catch(d){a.error("Failed to start server",d instanceof Error?d.message:String(d))}continue}if(s==="build-deploy"){let i=ge();if(!i){a.error("No build tool detected","This project does not contain build.gradle, build.gradle.kts or pom.xml at the root.");continue}let m=i==="gradle"?"Building project (gradle clean build)":"Building project (mvn clean package)";try{await Ae([{title:m,task:async()=>{if(!await Se(i))throw new Error("Build failed");return"Build successful"}}]);let{notifySuccess:d}=await Promise.resolve().then(()=>($e(),xe));d("Build completed successfully!","\u{1F6E0}\uFE0F Build Successful")}catch(d){a.error("Action failed",d instanceof Error?d.message:String(d));continue}}let c=await oe();if(c.length===0){a.warn("No artifacts found (.war or .ear). Make sure you have built the project.");continue}let f=await ae(c),y=!1;try{await Ae([{title:`Deploying ${f.name}`,task:async i=>{t||(i("Cleaning temporary directories (data, log, tmp)"),await J(r.home));let{join:m}=await import("path"),{SERVER_PATHS:d}=await Promise.resolve().then(()=>(E(),re)),D=m(r.home,...d.DEPLOYMENTS);if(i(`Transferring ${f.name} to ${D}`),y=await ye(f,r.home,t),!y)throw new Error("Deployment failed (.failed marker or timeout)");return t?"Deployment validated (.deployed detected)":"Artifact transferred successfully (ready for boot)"}}])}catch(i){a.error("Deployment failed",i instanceof Error?i.message:String(i))}if(y&&!t){let{mode:i,port:m}=await K(r.lastDebugPort,r.lastServerMode);a.step(`Starting server in ${i} mode${i==="debug"?` (port ${m})`:""}...`);try{r.lastServerMode=i,i==="debug"&&m&&(r.lastDebugPort=m),await N(e),await Q(r.home,i==="debug",m,r.memoryProfile),a.success("Server process finished.")}catch(d){a.error("Failed to start server",d instanceof Error?d.message:String(d))}}}}fr().catch(e=>{console.error("Fatal error:",e)});
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "jbdeploy",
3
+ "module": "index.ts",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "version": "1.0.0",
7
+ "description": "CLI tool to deploy EAR/WAR artifacts to JBoss or Wildfly with automatic build detection.",
8
+ "author": "Alex JCM",
9
+ "license": "MIT",
10
+ "keywords": ["jboss", "wildfly", "deploy", "cli", "automation", "java", "maven", "gradle"],
11
+ "files": ["dist", "README.md", "LICENSE"],
12
+ "engines": {
13
+ "node": ">=18",
14
+ "bun": ">=1.0"
15
+ },
16
+ "bin": {
17
+ "jbdeploy": "./dist/index.js"
18
+ },
19
+ "publishConfig": {
20
+ "registry": "https://registry.npmjs.org"
21
+ },
22
+ "scripts": {
23
+ "start": "bun run src/index.ts",
24
+ "dev": "bun --watch run src/index.ts",
25
+ "build": "tsup",
26
+ "local:link": "bun link",
27
+ "prepublishOnly": "bun run build",
28
+ "lint": "eslint src/",
29
+ "lint:fix": "eslint src/ --fix"
30
+ },
31
+ "dependencies": {
32
+ "@clack/prompts": "^1.1.0",
33
+ "fast-glob": "^3.3.3"
34
+ },
35
+ "devDependencies": {
36
+ "@eslint/js": "^10.0.1",
37
+ "@types/node": "^25.5.0",
38
+ "eslint": "^10.0.2",
39
+ "globals": "^17.4.0",
40
+ "tsup": "^8.5.1",
41
+ "typescript": "^5.9.0",
42
+ "typescript-eslint": "^8.56.1"
43
+ },
44
+ "packageManager": "npm@11.4.2+sha512.f90c1ec8b207b625d6edb6693aef23dacb39c38e4217fe8c46a973f119cab392ac0de23fe3f07e583188dae9fd9108b3845ad6f525b598742bd060ebad60bff3"
45
+ }