pm2-orbit 1.0.4 → 1.0.5

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/server.js CHANGED
@@ -881,7 +881,7 @@ Bus `);for(let a=1;a<o.length;a++){let l=tMe(o[a]);i.push(l)}}e&&e(i),t(i)}),KNe
881
881
  To: <invalid@invalid>\r
882
882
  Subject: Invalid\r
883
883
  \r
884
- Invalid`)}},FromEmailAddress:"invalid@invalid",Destination:{ToAddresses:["invalid@invalid"]}};return this.getRegion(()=>{let s=new this.ses.SendEmailCommand(n);this.ses.sesClient.send(s).then(()=>r(null)).catch(a=>r(a))}),i}};SX.exports=GP});var RX=S((j6e,lv)=>{"use strict";var qqe=zK(),OX=Hi(),$qe=cX(),Fqe=hX(),Bqe=gX(),zqe=xX(),Uqe=bX(),Hqe=EX(),Vqe=ur(),Wqe=sh(),TX=dn(),Gqe=(process.env.ETHEREAL_API||"https://api.nodemailer.com").replace(/\/+$/,""),Kqe=(process.env.ETHEREAL_WEB||"https://ethereal.email").replace(/\/+$/,""),CX=(process.env.ETHEREAL_API_KEY||"").replace(/\s*/g,"")||null,Xqe=["true","yes","y","1"].includes((process.env.ETHEREAL_CACHE||"yes").toString().trim().toLowerCase()),fh=!1;lv.exports.createTransport=function(e,t){let i;if(typeof e=="object"&&typeof e.send!="function"||typeof e=="string"&&/^(smtps?|direct):/i.test(e)){let r=typeof e=="string"?e:e.url;if(r?i=OX.parseConnectionUrl(r):i=e,i.pool)e=new $qe(i);else if(i.sendmail)e=new Bqe(i);else if(i.streamTransport)e=new zqe(i);else if(i.jsonTransport)e=new Uqe(i);else if(i.SES){if(i.SES.ses&&i.SES.aws){let n=new Error("Using legacy SES configuration, expecting @aws-sdk/client-sesv2, see https://nodemailer.com/transports/ses/");throw n.code=Vqe.ECONFIG,n}e=new Hqe(i)}else e=new Fqe(i)}return new qqe(e,i,t)};lv.exports.createTestAccount=function(e,t){let i;if(!t&&typeof e=="function"&&(t=e,e=!1),t||(i=new Promise((c,u)=>{t=OX.callbackPromise(c,u)})),Xqe&&fh)return setImmediate(()=>t(null,fh)),i;e=e||Gqe;let r=[],n=0,s={},o={requestor:TX.name,version:TX.version};CX&&(s.Authorization="Bearer "+CX);let a={contentType:"application/json",method:"POST",headers:s,body:Buffer.from(JSON.stringify(o))};/^https:/i.test(e)&&(a.tls={rejectUnauthorized:!0});let l=Wqe(e+"/user",a);return l.on("readable",()=>{let c;for(;(c=l.read())!==null;)r.push(c),n+=c.length}),l.once("error",c=>t(c)),l.once("end",()=>{let c=Buffer.concat(r,n),u;try{u=JSON.parse(c.toString())}catch(p){return t(p)}if(u.status!=="success"||u.error)return t(new Error(u.error||"Request failed"));delete u.status,fh=u,t(null,fh)}),i};lv.exports.getTestMessageUrl=function(e){if(!e||!e.response)return!1;let t=new Map,i=e.response.toString();if(i.length>2&&i.charAt(i.length-1)==="]"){let r=i.indexOf("[",i.lastIndexOf("]",i.length-2)+1);r>=0&&r<i.length-2&&i.substring(r+1,i.length-1).replace(/\b([A-Z0-9]+)=([^\s]+)/g,(s,o,a)=>{t.set(o,a)})}return t.has("STATUS")&&t.has("MSGID")?(fh.web||Kqe)+"/message/"+t.get("MSGID"):!1}});var PX={};js(PX,{isEmailConfigured:()=>Qqe,sendEmail:()=>Jqe});function Yqe(){if(cv)return cv;if(!uv)return null;let e=process.env.SMTP_HOST,t=parseInt(process.env.SMTP_PORT||"587",10),i=process.env.SMTP_USER,r=process.env.SMTP_PASS,n=process.env.SMTP_FROM;return!e||!n?null:(cv=uv.createTransport({host:e,port:t,secure:t===465,auth:i&&r?{user:i,pass:r}:void 0}),cv)}async function Jqe(e,t){let i=Yqe(),r=process.env.SMTP_TO;if(!i||!r)return!1;try{return await i.sendMail({from:process.env.SMTP_FROM,to:r,subject:`[PM2 Orbit] ${e}`,text:t,html:`<p>${t}</p>`}),!0}catch{return!1}}function Qqe(){return!!uv&&!!process.env.SMTP_HOST&&!!process.env.SMTP_FROM&&!!process.env.SMTP_TO}var uv,cv,AX=dr(()=>{"use strict";uv=null;try{uv=RX()}catch{}cv=null});var jX=S((tWe,hh)=>{"use strict";var{FifoMap:t$e}=Pm(),i$e=/^[!#$%&'*+\-.^\w`|~]+$/u;function r$e(e){if(i$e.test(e)===!1)throw new TypeError("Fieldname contains invalid characters.")}function DX(e){e=e.trim().toLowerCase();let t=[];if(e.length!==0)if(e.indexOf(",")===-1)t.push(e);else{let i=e.length,r=0,n=0,s;for(r;r<i;++r)s=e[r],s===" "?n=r+1:s===","&&(n!==r&&t.push(e.slice(n,r)),n=r+1);n!==r&&t.push(e.slice(n,r))}return t}function XP(e){let t=new t$e(1e3);return r$e(e),function(i){let r=i.getHeader("Vary");if(!r){i.header("Vary",e);return}if(r==="*")return;if(e==="*"){i.header("Vary","*");return}if(Array.isArray(r)&&(r=r.join(", ")),t.get(r)===void 0){let s=DX(r);s.indexOf("*")!==-1?t.set(r,"*"):s.indexOf(e.toLowerCase())===-1?t.set(r,r+", "+e):t.set(r,null)}let n=t.get(r);n!==null&&i.header("Vary",n)}}hh.exports.createAddFieldnameToVary=XP;hh.exports.addOriginToVaryHeader=XP("Origin");hh.exports.addAccessControlRequestHeadersToVaryHeader=XP("Access-Control-Request-Headers");hh.exports.parse=DX});var zX=S((iWe,dv)=>{"use strict";var n$e=bd(),{addAccessControlRequestHeadersToVaryHeader:s$e,addOriginToVaryHeader:o$e}=jX(),JP={origin:"*",methods:"GET,HEAD,POST",hook:"onRequest",preflightContinue:!1,optionsSuccessStatus:204,credentials:!1,exposedHeaders:null,allowedHeaders:null,maxAge:null,preflight:!0,strictPreflight:!0},a$e=["onRequest","preParsing","preValidation","preHandler","preSerialization","onSend"],YP=["preSerialization","preParsing","onSend"];function FX(e,t){a$e.indexOf(e)===-1&&t(new TypeError("@fastify/cors: Invalid hook option provided."))}function l$e(e,t,i){e.decorateRequest("corsPreflightEnabled",!1);let r=!0,n;if(typeof t=="function")qX(t,e,{hook:JP.hook},i);else if(t.delegator){let{delegator:s,...o}=t;qX(s,e,o,i)}else{let s=pv(t);FX(s.hook,i),YP.indexOf(s.hook)!==-1?e.addHook(s.hook,function(a,l,c,u){mh(e,s,a,l,u)}):e.addHook(s.hook,function(a,l,c){mh(e,s,a,l,c)})}t.logLevel!==void 0&&(n=t.logLevel),t.hideOptionsRoute!==void 0&&(r=t.hideOptionsRoute),e.options("*",{schema:{hide:r},logLevel:n},(s,o)=>{if(!s.corsPreflightEnabled){o.callNotFound();return}o.send()}),i()}function qX(e,t,i,r){let n=i?.hook||JP.hook;FX(n,r),e.length===2?YP.indexOf(n)!==-1?t.addHook(n,function(o,a,l,c){$X(e,t,o,a,c)}):t.addHook(n,function(o,a,l){$X(e,t,o,a,l)}):YP.indexOf(n)!==-1?t.addHook(n,function(o,a,l,c){let u=e(o);if(u&&typeof u.then=="function"){u.then(p=>mh(t,pv(p,!0),o,a,c)).catch(c);return}c(new Error("Invalid CORS origin option"))}):t.addHook(n,function(o,a,l){let c=e(o);if(c&&typeof c.then=="function"){c.then(u=>mh(t,pv(u,!0),o,a,l)).catch(l);return}l(new Error("Invalid CORS origin option"))})}function $X(e,t,i,r,n){e(i,(s,o)=>{s?n(s):mh(t,pv(o,!0),i,r,n)})}function pv(e,t){let i={...JP,...e};return Array.isArray(e.origin)&&e.origin.indexOf("*")!==-1&&(i.origin="*"),Number.isInteger(i.cacheControl)?i.cacheControl=`max-age=${i.cacheControl}`:typeof i.cacheControl!="string"&&(i.cacheControl=null),i.dynamic=t||!1,i}function mh(e,t,i,r,n){let s={...t,...i.routeOptions.config?.cors};(typeof s.origin!="string"&&s.origin!==!1||s.dynamic)&&o$e(r),(typeof s.origin=="function"?p$e(e,s.origin):(a,l)=>l(null,s.origin))(i,(a,l)=>{if(a!==null)return n(a);if(l===!1||i.routeOptions.config?.cors===!1)return n();if(!l)return n(new Error("Invalid CORS origin option"));if(c$e(i,r,l,s),i.raw.method==="OPTIONS"&&s.preflight===!0){if(s.strictPreflight===!0&&(!i.headers.origin||!i.headers["access-control-request-method"])){r.status(400).type("text/plain").send("Invalid Preflight Request");return}if(i.corsPreflightEnabled=!0,u$e(i,r,s),!s.preflightContinue){r.code(s.optionsSuccessStatus).header("Content-Length","0").send();return}}return n()})}function c$e(e,t,i,r){let n=d$e(e.headers.origin,i);n&&t.header("Access-Control-Allow-Origin",n),r.credentials&&t.header("Access-Control-Allow-Credentials","true"),r.exposedHeaders!==null&&t.header("Access-Control-Expose-Headers",Array.isArray(r.exposedHeaders)?r.exposedHeaders.join(", "):r.exposedHeaders)}function u$e(e,t,i){if(t.header("Access-Control-Allow-Methods",Array.isArray(i.methods)?i.methods.join(", "):i.methods),i.allowedHeaders===null){s$e(t);let r=e.headers["access-control-request-headers"];r!==void 0&&t.header("Access-Control-Allow-Headers",r)}else t.header("Access-Control-Allow-Headers",Array.isArray(i.allowedHeaders)?i.allowedHeaders.join(", "):i.allowedHeaders);i.maxAge!==null&&t.header("Access-Control-Max-Age",String(i.maxAge)),i.cacheControl&&t.header("Cache-Control",i.cacheControl)}function p$e(e,t){return function(i,r){let n=t.call(e,i.headers.origin,r);n&&typeof n.then=="function"&&n.then(s=>r(null,s),r)}}function d$e(e,t){return typeof t=="string"?t:BX(e,t)?e:!1}function BX(e,t){if(Array.isArray(t)){for(let i=0;i<t.length;++i)if(BX(e,t[i]))return!0;return!1}else return typeof t=="string"?e===t:t instanceof RegExp?(t.lastIndex=0,t.test(e)):!!t}var QP=n$e(l$e,{fastify:"5.x",name:"@fastify/cors"});dv.exports=QP;dv.exports.fastifyCors=QP;dv.exports.default=QP});function GX(){try{if(hn.default.existsSync(ZP))return Buffer.from(hn.default.readFileSync(ZP,"utf-8"),"hex")}catch{}let e=(0,fl.randomBytes)(32);try{hn.default.existsSync(ju)||hn.default.mkdirSync(ju,{recursive:!0}),hn.default.writeFileSync(ZP,e.toString("hex"),{mode:384})}catch{}return e}function h$e(e){if(!e)return"";try{let t=GX(),i=(0,fl.randomBytes)(16),r=(0,fl.createCipheriv)("aes-256-cbc",t,i),n=Buffer.concat([r.update(e,"utf8"),r.final()]);return i.toString("hex")+":"+n.toString("hex")}catch{return e}}function m$e(e){if(!e||!e.includes(":"))return e;try{let t=GX(),[i,r]=e.split(":"),n=Buffer.from(i,"hex"),s=Buffer.from(r,"hex"),o=(0,fl.createDecipheriv)("aes-256-cbc",t,n);return Buffer.concat([o.update(s),o.final()]).toString("utf8")}catch{return e}}function tA(){if(Du)return Du;try{if(hn.default.existsSync(eA)){let e=hn.default.readFileSync(eA,"utf-8"),t=JSON.parse(e),i={...VX,...t};for(let r of WX)i[r]&&(i[r]=m$e(i[r]));return Du=i,i}}catch{}return Du={...VX},Du}function g$e(){Du=null}function y$e(e){try{hn.default.existsSync(ju)||hn.default.mkdirSync(ju,{recursive:!0});let t={...e};for(let i of WX)t[i]&&(t[i]=h$e(t[i]));hn.default.writeFileSync(eA,JSON.stringify(t,null,2),{mode:384}),g$e()}catch{}}function hv(){return tA()}function KX(){let e=tA();return{...e,authToken:e.authToken?"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022":"",smtpPass:e.smtpPass?"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022":""}}function XX(e){let i={...tA()};for(let[r,n]of Object.entries(e))(r==="authToken"||r==="smtpPass")&&(n==="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"||n==="")||(i[r]=n);return y$e(i),i}function mv(e){e.authToken&&(process.env.PM2_ORBIT_TOKEN=e.authToken),e.slackWebhookUrl&&(process.env.SLACK_WEBHOOK_URL=e.slackWebhookUrl),e.discordWebhookUrl&&(process.env.DISCORD_WEBHOOK_URL=e.discordWebhookUrl),e.webhookUrl&&(process.env.WEBHOOK_URL=e.webhookUrl),e.smtpHost&&(process.env.SMTP_HOST=e.smtpHost),e.smtpPort&&(process.env.SMTP_PORT=String(e.smtpPort)),e.smtpUser&&(process.env.SMTP_USER=e.smtpUser),e.smtpPass&&(process.env.SMTP_PASS=e.smtpPass),e.smtpFrom&&(process.env.SMTP_FROM=e.smtpFrom),e.smtpTo&&(process.env.SMTP_TO=e.smtpTo),e.theme&&(process.env.PM2_ORBIT_THEME=e.theme);for(let t of Object.keys(e.enabledChannels))process.env[`NOTIFY_${t.toUpperCase()}_ENABLED`]=e.enabledChannels[t]?"1":"0"}var hn,fv,fl,ju,eA,ZP,VX,WX,Du,iA=dr(()=>{"use strict";hn=dt(require("fs")),fv=dt(require("path")),fl=require("crypto"),ju=fv.default.join(process.env.HOME||process.env.USERPROFILE||"",".pm2-orbit"),eA=fv.default.join(ju,"settings.json"),ZP=fv.default.join(ju,".key"),VX={theme:"dark",port:9823,authToken:"",slackWebhookUrl:"",discordWebhookUrl:"",webhookUrl:"",smtpHost:"",smtpPort:587,smtpUser:"",smtpPass:"",smtpFrom:"",smtpTo:"",enabledChannels:{browser:!0,slack:!0,discord:!0,webhook:!0,email:!0}},WX=["authToken","smtpPass","slackWebhookUrl","discordWebhookUrl","webhookUrl"];Du=null});var YX=S((sWe,x$e)=>{x$e.exports={name:"pm2",preferGlobal:!0,version:"7.0.3",engines:{node:">=18.0.0"},directories:{bin:"./bin",lib:"./lib",example:"./examples"},author:{name:"Strzelewicz Alexandre",email:"alex@edgecraft.io <Pour ce Nouveau Monde>",url:"https://pm2.io"},maintainers:[{name:"Alexandre Strzelewicz",email:"alexandre@pm2.io"}],contributors:["Mathilde Tuffier","Antoine Bluchet","Alex Kocharin","Antoine Bluchet","Subhash Burramsetty","Valentin Marchaud","Valentin Touffet","Florian Hermouet-Joscht","Vincent Vallet","Joni Shkurti","Jun Tjatse","Xu Jingxin","Ben Postlethwaite","Devo.ps","Bret Copeland","John Hurliman","TruongSinh Tran-Nguyen","Michael Hueuberger","Chris Wiggins"],homepage:"http://pm2.keymetrics.io/",description:"Production process manager for Node.JS applications with a built-in load balancer.",main:"index.js",types:"types/index.d.ts",scripts:{"test:unit":"bash test/unit.sh","test:e2e":"bash test/e2e.sh",test:"bash test/unit.sh && bash test/e2e.sh","test:parallel":"bash test/docker-parallel.sh","test:bpm":"mocha 'modules/pm2-io-bpm/test/**/*.spec.js' --exit --timeout 10000","test:axon-rpc":"mocha 'modules/pm2-axon-rpc/test/' --reporter spec --exit","test:axon":"bash modules/pm2-axon/test/run modules/pm2-axon/test/test.*.js","test:io-agent":"mocha 'modules/pm2-io-agent/test/units/*.mocha.js' --reporter spec --exit","test:windows":"bash test/windows.sh"},keywords:["cli","fault tolerant","sysadmin","tools","pm2","logs","log","json","express","hapi","kraken","reload","load balancer","lb","load-balancer","kubernetes","k8s","pm2-docker","runtime","source maps","graceful","microservice","programmatic","harmony","node-pm2","production","keymetrics","node.js monitoring","strong-pm","deploy","deployment","daemon","supervisor","supervisord","nodemon","pm2.io","ghost","ghost production","monitoring","keymetrics","process manager","forever","profiling","probes","apm","container","forever-monitor","keep process alive","process configuration","clustering","cluster cli","cluster","docker","cron","devops","dev ops"],bin:{pm2:"bin/pm2","pm2-dev":"bin/pm2-dev","pm2-docker":"bin/pm2-docker","pm2-runtime":"bin/pm2-runtime"},dependencies:{"@pm2/blessed":"0.1.81","@pm2/js-api":"0.8.1","@pm2/pm2-version-check":"1.0.4",amp:"0.3.1","amp-message":"0.1.2",ansis:"4.0.0-node10",async:"3.2.6",chokidar:"3.6.0","cli-tableau":"2.0.1",commander:"2.15.1",croner:"4.1.97",dayjs:"1.11.15",debug:"4.4.3",eventemitter2:"6.4.9","fast-json-patch":"3.1.1","js-yaml":"4.3.0",pidusage:"4.0.1","pm2-deploy":"1.0.2","proxy-agent":"6.5.0",semver:"7.7.2",tx2:"1.0.5",ws:"8.21.0"},overrides:{debug:"4.4.3"},devDependencies:{express:"^4.21.0",mocha:"^11.7.0",should:"^13.2.3"},bugs:{url:"https://github.com/Unitech/pm2/issues"},repository:{type:"git",url:"git://github.com/Unitech/pm2.git"},license:"AGPL-3.0"}});var JX=S((oWe,v$e)=>{v$e.exports={name:"pm2-orbit",version:"1.0.4",files:["dist/","dist-ui/","bin/"],description:"High-performance PM2 monitoring dashboard \u2014 event-driven, 1000+ processes, < 150KB",main:"dist/server.js",bin:{"pm2-orbit":"bin/pm2-orbit.js"},scripts:{"dev:ui":"cd ui && vite","dev:server":"tsx watch src/server.ts",dev:'concurrently -k -n ui,server -c blue,green "npm:dev:ui" "npm:dev:server"',build:"node build.js",start:"node dist/server.js",lint:"tsc --noEmit",typecheck:"tsc --noEmit && cd ui && tsc --noEmit",test:"vitest run","test:watch":"vitest","test:e2e":"vitest --config vitest.e2e.config.ts",prepare:"husky",prepublishOnly:"npm run build",postinstall:`node -e "try{require.resolve('pm2')}catch{console.log('\\n \u2139 Install pm2 for process monitoring: npm install -g pm2\\n')}"`},engines:{node:">=18"},dependencies:{"@fastify/compress":"^9","@fastify/cors":"^11","@fastify/helmet":"^13","@fastify/rate-limit":"^11","@fastify/static":"^9.1.3",fastify:"^5",mri:"^1.2",open:"^10",systeminformation:"^5.31.11",ws:"^8"},optionalDependencies:{"better-sqlite3":"^11",nodemailer:"^9.0.1",pm2:"^7"},devDependencies:{"@tailwindcss/postcss":"^4","@testing-library/react":"^14","@types/node":"^26.0.1","@types/nodemailer":"^8.0.1","@types/ws":"^8.18.1","@vitejs/plugin-react":"^4",autoprefixer:"^10",concurrently:"^8",esbuild:"^0.25",husky:"^9","lint-staged":"^15",postcss:"^8",tailwindcss:"^4",tsx:"^4",typescript:"^5",vite:"^6",vitest:"^3"},keywords:["pm2","monitoring","dashboard","devops","nodejs","react"],license:"MIT"}});var QX={};js(QX,{registerHealthRoutes:()=>w$e});function b$e(e,t){switch(e){case"browser":return!0;case"slack":return!!t.slackWebhookUrl;case"discord":return!!t.discordWebhookUrl;case"webhook":return!!t.webhookUrl;case"email":return!!t.smtpHost&&!!t.smtpFrom&&!!t.smtpTo}}async function w$e(e,t){e.get("/api/health",async()=>{let i="unknown";try{i=YX().version}catch{try{i=require("pm2/package.json").version}catch{}}return{status:"ok",uptime:process.uptime(),version:JX().version,processes:(await t.bridge.list()).length,nodeVersion:process.version,pm2Version:i}}),e.get("/api/ping",async()=>"pong"),e.get("/api/system",async()=>{let{readSystem:i}=await Promise.resolve().then(()=>(Yf(),_R));return i()}),e.get("/api/settings",async()=>KX()),e.get("/api/channels",async()=>{let i=hv(),r=["browser","slack","discord","webhook","email"],n={};for(let s of r){let o=b$e(s,i),a=i.enabledChannels[s]!==!1;n[s]={configured:o,enabled:a}}return n}),e.put("/api/settings",async(i,r)=>{let n=i.body;if(!n||typeof n!="object")return r.code(400).send({error:"Invalid request body"});let s=["theme","authToken","slackWebhookUrl","discordWebhookUrl","webhookUrl","smtpHost","smtpPort","smtpUser","smtpPass","smtpFrom","smtpTo","enabledChannels"],o={};for(let l of s)l in n&&(o[l]=n[l]);let a=XX(o);return mv(a),{success:!0,settings:a}})}var ZX=dr(()=>{"use strict";iA()});function eY(e){return e.replace(/\.\.(\/|\\)/g,"").replace(/[/\\]/g,"_").replace(/\0/g,"").replace(/\s+/g,"_").replace(/^_+|_+$/g,"").substring(0,128)}function Jo(e){if(!e||typeof e!="string")return null;let t=parseInt(e,10);return isNaN(t)||t<0||!Number.isSafeInteger(t)?null:t}function tY(e){if(!e||typeof e!="object")return null;let t=e;if(typeof t.id!="string"||!t.id||typeof t.metric!="string"||!_$e.includes(t.metric)||typeof t.operator!="string"||!S$e.includes(t.operator)||typeof t.threshold!="number"||isNaN(t.threshold))return null;let i=[];if(Array.isArray(t.channels))for(let r of t.channels)typeof r=="string"&&E$e.includes(r)&&i.push(r);return{id:t.id,metric:t.metric,operator:t.operator,threshold:t.threshold,...typeof t.processId=="number"?{processId:t.processId}:{},...typeof t.processName=="string"?{processName:t.processName}:{},enabled:t.enabled!==!1,channels:i,...typeof t.webhookUrl=="string"?{webhookUrl:t.webhookUrl}:{},...typeof t.slackWebhook=="string"?{slackWebhook:t.slackWebhook}:{},...typeof t.discordWebhook=="string"?{discordWebhook:t.discordWebhook}:{},...typeof t.emailTo=="string"?{emailTo:t.emailTo}:{}}}var _$e,S$e,E$e,qu=dr(()=>{"use strict";_$e=["cpu","memory","restarts","status"],S$e=[">","<","==",">=","<="],E$e=["browser","webhook","slack","discord","email"]});var rY={};js(rY,{registerProcessRoutes:()=>T$e});async function T$e(e,t){e.get("/api/processes",async()=>t.bridge.list()),e.get("/api/processes/:id/env",async i=>{let{id:r}=i.params,n=Jo(r);if(n===null)return{};try{return Fr?new Promise(s=>{Fr.list((o,a)=>{if(o)return s({});let l=a.find(f=>f.pm_id===n);if(!l)return s({});let c=l.pm2_env||{},u={},p=new Set(["PATH","PATHEXT","SYSTEMROOT","SYSTEMDRIVE","WINDIR","TEMP","TMP","USERPROFILE","USERNAME","USERDOMAIN","USERDOMAIN_ROAMINGPROFILE","PROCESSOR_ARCHITECTURE","PROCESSOR_IDENTIFIER","PROCESSOR_LEVEL","PROCESSOR_REVISION","PROGRAMDATA","PROGRAMFILES","PROGRAMW6432","COMMONPROGRAMFILES","COMMONPROGRAMW6432","COMPUTERNAME","COMSPEC","DRIVERDATA","HOMEDRIVE","HOMEPATH","LOCALAPPDATA","LOGONSERVER","NUMBER_OF_PROCESSORS","ONEDRIVE","OS","PSMODULEPATH","PUBLIC","SESSIONNAME","ALLUSERSPROFILE","APPDATA","COLORTERM","LANG","TERM","TERM_PROGRAM","TERM_PROGRAM_VERSION","ZES_ENABLE_SYSMAN","ZED_TERM","ZED_ENVIRONMENT","PM2_USAGE","PM2_JSON_PROCESSING"]);for(let[f,d]of Object.entries(c))typeof d=="string"&&!p.has(f)&&!f.startsWith("MIMOCODE_")&&!f.startsWith("FPS_BROWSER_")&&!f.startsWith("EFC_")&&(u[f]=d);s(u)})}):{}}catch{return{}}}),e.post("/api/processes/:id/action",async(i,r)=>{let{id:n}=i.params,s=Jo(n);if(s===null)return r.code(400).send({error:"Invalid process ID"});let o=i.body,a=typeof o?.action=="string"?o.action:"",l=typeof o?.instances=="number"?o.instances:void 0;if(!a||!iY.includes(a))return r.code(400).send({error:`Invalid action. Must be one of: ${iY.join(", ")}`});try{if(!Fr)return r.code(500).send({error:"PM2 not available"});if(a==="scale"){let u=await new Promise((p,f)=>{Fr.list((d,h)=>{if(d)return f(d);let m=h.find(y=>y.pm_id===s);if(!m)return f(new Error("Process not found"));p(m.name)})});return await new Promise((p,f)=>{Fr.scale(u,l!==void 0?String(l):"+1",d=>{d?f(d):p()})}),{success:!0}}let c={restart:u=>Fr.restart(s,u),stop:u=>Fr.stop(s,u),start:u=>Fr.restart(s,u),reload:u=>Fr.reload(s,u),delete:u=>Fr.delete(s,u),flush:u=>Fr.flush(s,u)}[a];return c?(await new Promise((u,p)=>{c(f=>{f?p(f):u()})}),{success:!0}):r.code(400).send({error:`Unknown action: ${a}`})}catch(c){return r.code(500).send({error:c.message})}})}var Fr,iY,nY=dr(()=>{"use strict";qu();Fr=null;try{Fr=require("pm2")}catch{}iY=["restart","stop","start","reload","delete","scale","flush"]});var sY={};js(sY,{registerHistoryRoutes:()=>C$e});async function C$e(e,t){e.get("/api/history/:id",async(i,r)=>{let{id:n}=i.params,{hours:s}=i.query,o=Jo(n);if(o===null)return r.code(400).send({error:"Invalid process ID"});if(!t.persistence)return r.code(503).send({error:"Persistence not available"});let a=s?parseInt(s,10):24;return isNaN(a)||a<1||a>168?r.code(400).send({error:"Invalid hours parameter (1-168)"}):t.persistence.getProcessHistory(o,a)}),e.get("/api/history/system",async(i,r)=>{let{hours:n}=i.query;if(!t.persistence)return r.code(503).send({error:"Persistence not available"});let s=n?parseInt(n,10):24;return isNaN(s)||s<1||s>168?r.code(400).send({error:"Invalid hours parameter (1-168)"}):t.persistence.getSystemHistory(s)})}var oY=dr(()=>{"use strict";qu()});var aY={};js(aY,{registerAlertRoutes:()=>O$e});async function O$e(e,t){e.get("/api/alerts",async()=>t.alerts.getRules()),e.post("/api/alerts",async(i,r)=>{let n=tY(i.body);return n?(t.alerts.addRule(n),{success:!0}):r.code(400).send({error:"Invalid alert rule. Required: id (string), metric (cpu|memory|restarts|status), operator (>|<|==|>=|<=), threshold (number)"})}),e.delete("/api/alerts/:id",async(i,r)=>{let{id:n}=i.params;return!n||typeof n!="string"||n.length===0?r.code(400).send({error:"Invalid rule ID"}):(t.alerts.removeRule(n),{success:!0})}),e.get("/api/alerts/history",async()=>t.alerts.getHistory())}var lY=dr(()=>{"use strict";qu()});function pY(e,t,i){let r=[],n=!1,s="",o="",a={},l=null;function c(g){if(i){if(g==="out"&&i.out)return i.out;if(g==="err"&&i.err)return i.err}let v=process.env.HOME||process.env.USERPROFILE||"",b=uY.default.join(v,".pm2","logs",eY(t)),x=`${b}-${g}-${e}.log`;if(Ns.default.existsSync(x))return x;if(g==="err"){let C=`${b}-error-${e}.log`;if(Ns.default.existsSync(C))return C}let _=[`${b}-${g}.log`];g==="err"&&_.push(`${b}-error.log`);for(let C=0;C<16;C++)_.push(`${b}-${g}-${C}.log`),g==="err"&&_.push(`${b}-error-${C}.log`);for(let C of _)if(Ns.default.existsSync(C))return C;return _[0]}function u(g,v){try{if(!Ns.default.existsSync(g))return;let b=Ns.default.statSync(g),x=a[g]||0;if(b.size<x&&(a[g]=0,l=null),b.size<=(a[g]||0))return;let _=Ns.default.openSync(g,"r"),C=Buffer.alloc(b.size-(a[g]||0));Ns.default.readSync(_,C,0,C.length,a[g]||0),Ns.default.closeSync(_),a[g]=b.size;let E=C.toString("utf-8");if(l!==null&&(E=l+E,l=null),!E.endsWith(`
884
+ Invalid`)}},FromEmailAddress:"invalid@invalid",Destination:{ToAddresses:["invalid@invalid"]}};return this.getRegion(()=>{let s=new this.ses.SendEmailCommand(n);this.ses.sesClient.send(s).then(()=>r(null)).catch(a=>r(a))}),i}};SX.exports=GP});var RX=S((j6e,lv)=>{"use strict";var qqe=zK(),OX=Hi(),$qe=cX(),Fqe=hX(),Bqe=gX(),zqe=xX(),Uqe=bX(),Hqe=EX(),Vqe=ur(),Wqe=sh(),TX=dn(),Gqe=(process.env.ETHEREAL_API||"https://api.nodemailer.com").replace(/\/+$/,""),Kqe=(process.env.ETHEREAL_WEB||"https://ethereal.email").replace(/\/+$/,""),CX=(process.env.ETHEREAL_API_KEY||"").replace(/\s*/g,"")||null,Xqe=["true","yes","y","1"].includes((process.env.ETHEREAL_CACHE||"yes").toString().trim().toLowerCase()),fh=!1;lv.exports.createTransport=function(e,t){let i;if(typeof e=="object"&&typeof e.send!="function"||typeof e=="string"&&/^(smtps?|direct):/i.test(e)){let r=typeof e=="string"?e:e.url;if(r?i=OX.parseConnectionUrl(r):i=e,i.pool)e=new $qe(i);else if(i.sendmail)e=new Bqe(i);else if(i.streamTransport)e=new zqe(i);else if(i.jsonTransport)e=new Uqe(i);else if(i.SES){if(i.SES.ses&&i.SES.aws){let n=new Error("Using legacy SES configuration, expecting @aws-sdk/client-sesv2, see https://nodemailer.com/transports/ses/");throw n.code=Vqe.ECONFIG,n}e=new Hqe(i)}else e=new Fqe(i)}return new qqe(e,i,t)};lv.exports.createTestAccount=function(e,t){let i;if(!t&&typeof e=="function"&&(t=e,e=!1),t||(i=new Promise((c,u)=>{t=OX.callbackPromise(c,u)})),Xqe&&fh)return setImmediate(()=>t(null,fh)),i;e=e||Gqe;let r=[],n=0,s={},o={requestor:TX.name,version:TX.version};CX&&(s.Authorization="Bearer "+CX);let a={contentType:"application/json",method:"POST",headers:s,body:Buffer.from(JSON.stringify(o))};/^https:/i.test(e)&&(a.tls={rejectUnauthorized:!0});let l=Wqe(e+"/user",a);return l.on("readable",()=>{let c;for(;(c=l.read())!==null;)r.push(c),n+=c.length}),l.once("error",c=>t(c)),l.once("end",()=>{let c=Buffer.concat(r,n),u;try{u=JSON.parse(c.toString())}catch(p){return t(p)}if(u.status!=="success"||u.error)return t(new Error(u.error||"Request failed"));delete u.status,fh=u,t(null,fh)}),i};lv.exports.getTestMessageUrl=function(e){if(!e||!e.response)return!1;let t=new Map,i=e.response.toString();if(i.length>2&&i.charAt(i.length-1)==="]"){let r=i.indexOf("[",i.lastIndexOf("]",i.length-2)+1);r>=0&&r<i.length-2&&i.substring(r+1,i.length-1).replace(/\b([A-Z0-9]+)=([^\s]+)/g,(s,o,a)=>{t.set(o,a)})}return t.has("STATUS")&&t.has("MSGID")?(fh.web||Kqe)+"/message/"+t.get("MSGID"):!1}});var PX={};js(PX,{isEmailConfigured:()=>Qqe,sendEmail:()=>Jqe});function Yqe(){if(cv)return cv;if(!uv)return null;let e=process.env.SMTP_HOST,t=parseInt(process.env.SMTP_PORT||"587",10),i=process.env.SMTP_USER,r=process.env.SMTP_PASS,n=process.env.SMTP_FROM;return!e||!n?null:(cv=uv.createTransport({host:e,port:t,secure:t===465,auth:i&&r?{user:i,pass:r}:void 0}),cv)}async function Jqe(e,t){let i=Yqe(),r=process.env.SMTP_TO;if(!i||!r)return!1;try{return await i.sendMail({from:process.env.SMTP_FROM,to:r,subject:`[PM2 Orbit] ${e}`,text:t,html:`<p>${t}</p>`}),!0}catch{return!1}}function Qqe(){return!!uv&&!!process.env.SMTP_HOST&&!!process.env.SMTP_FROM&&!!process.env.SMTP_TO}var uv,cv,AX=dr(()=>{"use strict";uv=null;try{uv=RX()}catch{}cv=null});var jX=S((tWe,hh)=>{"use strict";var{FifoMap:t$e}=Pm(),i$e=/^[!#$%&'*+\-.^\w`|~]+$/u;function r$e(e){if(i$e.test(e)===!1)throw new TypeError("Fieldname contains invalid characters.")}function DX(e){e=e.trim().toLowerCase();let t=[];if(e.length!==0)if(e.indexOf(",")===-1)t.push(e);else{let i=e.length,r=0,n=0,s;for(r;r<i;++r)s=e[r],s===" "?n=r+1:s===","&&(n!==r&&t.push(e.slice(n,r)),n=r+1);n!==r&&t.push(e.slice(n,r))}return t}function XP(e){let t=new t$e(1e3);return r$e(e),function(i){let r=i.getHeader("Vary");if(!r){i.header("Vary",e);return}if(r==="*")return;if(e==="*"){i.header("Vary","*");return}if(Array.isArray(r)&&(r=r.join(", ")),t.get(r)===void 0){let s=DX(r);s.indexOf("*")!==-1?t.set(r,"*"):s.indexOf(e.toLowerCase())===-1?t.set(r,r+", "+e):t.set(r,null)}let n=t.get(r);n!==null&&i.header("Vary",n)}}hh.exports.createAddFieldnameToVary=XP;hh.exports.addOriginToVaryHeader=XP("Origin");hh.exports.addAccessControlRequestHeadersToVaryHeader=XP("Access-Control-Request-Headers");hh.exports.parse=DX});var zX=S((iWe,dv)=>{"use strict";var n$e=bd(),{addAccessControlRequestHeadersToVaryHeader:s$e,addOriginToVaryHeader:o$e}=jX(),JP={origin:"*",methods:"GET,HEAD,POST",hook:"onRequest",preflightContinue:!1,optionsSuccessStatus:204,credentials:!1,exposedHeaders:null,allowedHeaders:null,maxAge:null,preflight:!0,strictPreflight:!0},a$e=["onRequest","preParsing","preValidation","preHandler","preSerialization","onSend"],YP=["preSerialization","preParsing","onSend"];function FX(e,t){a$e.indexOf(e)===-1&&t(new TypeError("@fastify/cors: Invalid hook option provided."))}function l$e(e,t,i){e.decorateRequest("corsPreflightEnabled",!1);let r=!0,n;if(typeof t=="function")qX(t,e,{hook:JP.hook},i);else if(t.delegator){let{delegator:s,...o}=t;qX(s,e,o,i)}else{let s=pv(t);FX(s.hook,i),YP.indexOf(s.hook)!==-1?e.addHook(s.hook,function(a,l,c,u){mh(e,s,a,l,u)}):e.addHook(s.hook,function(a,l,c){mh(e,s,a,l,c)})}t.logLevel!==void 0&&(n=t.logLevel),t.hideOptionsRoute!==void 0&&(r=t.hideOptionsRoute),e.options("*",{schema:{hide:r},logLevel:n},(s,o)=>{if(!s.corsPreflightEnabled){o.callNotFound();return}o.send()}),i()}function qX(e,t,i,r){let n=i?.hook||JP.hook;FX(n,r),e.length===2?YP.indexOf(n)!==-1?t.addHook(n,function(o,a,l,c){$X(e,t,o,a,c)}):t.addHook(n,function(o,a,l){$X(e,t,o,a,l)}):YP.indexOf(n)!==-1?t.addHook(n,function(o,a,l,c){let u=e(o);if(u&&typeof u.then=="function"){u.then(p=>mh(t,pv(p,!0),o,a,c)).catch(c);return}c(new Error("Invalid CORS origin option"))}):t.addHook(n,function(o,a,l){let c=e(o);if(c&&typeof c.then=="function"){c.then(u=>mh(t,pv(u,!0),o,a,l)).catch(l);return}l(new Error("Invalid CORS origin option"))})}function $X(e,t,i,r,n){e(i,(s,o)=>{s?n(s):mh(t,pv(o,!0),i,r,n)})}function pv(e,t){let i={...JP,...e};return Array.isArray(e.origin)&&e.origin.indexOf("*")!==-1&&(i.origin="*"),Number.isInteger(i.cacheControl)?i.cacheControl=`max-age=${i.cacheControl}`:typeof i.cacheControl!="string"&&(i.cacheControl=null),i.dynamic=t||!1,i}function mh(e,t,i,r,n){let s={...t,...i.routeOptions.config?.cors};(typeof s.origin!="string"&&s.origin!==!1||s.dynamic)&&o$e(r),(typeof s.origin=="function"?p$e(e,s.origin):(a,l)=>l(null,s.origin))(i,(a,l)=>{if(a!==null)return n(a);if(l===!1||i.routeOptions.config?.cors===!1)return n();if(!l)return n(new Error("Invalid CORS origin option"));if(c$e(i,r,l,s),i.raw.method==="OPTIONS"&&s.preflight===!0){if(s.strictPreflight===!0&&(!i.headers.origin||!i.headers["access-control-request-method"])){r.status(400).type("text/plain").send("Invalid Preflight Request");return}if(i.corsPreflightEnabled=!0,u$e(i,r,s),!s.preflightContinue){r.code(s.optionsSuccessStatus).header("Content-Length","0").send();return}}return n()})}function c$e(e,t,i,r){let n=d$e(e.headers.origin,i);n&&t.header("Access-Control-Allow-Origin",n),r.credentials&&t.header("Access-Control-Allow-Credentials","true"),r.exposedHeaders!==null&&t.header("Access-Control-Expose-Headers",Array.isArray(r.exposedHeaders)?r.exposedHeaders.join(", "):r.exposedHeaders)}function u$e(e,t,i){if(t.header("Access-Control-Allow-Methods",Array.isArray(i.methods)?i.methods.join(", "):i.methods),i.allowedHeaders===null){s$e(t);let r=e.headers["access-control-request-headers"];r!==void 0&&t.header("Access-Control-Allow-Headers",r)}else t.header("Access-Control-Allow-Headers",Array.isArray(i.allowedHeaders)?i.allowedHeaders.join(", "):i.allowedHeaders);i.maxAge!==null&&t.header("Access-Control-Max-Age",String(i.maxAge)),i.cacheControl&&t.header("Cache-Control",i.cacheControl)}function p$e(e,t){return function(i,r){let n=t.call(e,i.headers.origin,r);n&&typeof n.then=="function"&&n.then(s=>r(null,s),r)}}function d$e(e,t){return typeof t=="string"?t:BX(e,t)?e:!1}function BX(e,t){if(Array.isArray(t)){for(let i=0;i<t.length;++i)if(BX(e,t[i]))return!0;return!1}else return typeof t=="string"?e===t:t instanceof RegExp?(t.lastIndex=0,t.test(e)):!!t}var QP=n$e(l$e,{fastify:"5.x",name:"@fastify/cors"});dv.exports=QP;dv.exports.fastifyCors=QP;dv.exports.default=QP});function GX(){try{if(hn.default.existsSync(ZP))return Buffer.from(hn.default.readFileSync(ZP,"utf-8"),"hex")}catch{}let e=(0,fl.randomBytes)(32);try{hn.default.existsSync(ju)||hn.default.mkdirSync(ju,{recursive:!0}),hn.default.writeFileSync(ZP,e.toString("hex"),{mode:384})}catch{}return e}function h$e(e){if(!e)return"";try{let t=GX(),i=(0,fl.randomBytes)(16),r=(0,fl.createCipheriv)("aes-256-cbc",t,i),n=Buffer.concat([r.update(e,"utf8"),r.final()]);return i.toString("hex")+":"+n.toString("hex")}catch{return e}}function m$e(e){if(!e||!e.includes(":"))return e;try{let t=GX(),[i,r]=e.split(":"),n=Buffer.from(i,"hex"),s=Buffer.from(r,"hex"),o=(0,fl.createDecipheriv)("aes-256-cbc",t,n);return Buffer.concat([o.update(s),o.final()]).toString("utf8")}catch{return e}}function tA(){if(Du)return Du;try{if(hn.default.existsSync(eA)){let e=hn.default.readFileSync(eA,"utf-8"),t=JSON.parse(e),i={...VX,...t};for(let r of WX)i[r]&&(i[r]=m$e(i[r]));return Du=i,i}}catch{}return Du={...VX},Du}function g$e(){Du=null}function y$e(e){try{hn.default.existsSync(ju)||hn.default.mkdirSync(ju,{recursive:!0});let t={...e};for(let i of WX)t[i]&&(t[i]=h$e(t[i]));hn.default.writeFileSync(eA,JSON.stringify(t,null,2),{mode:384}),g$e()}catch{}}function hv(){return tA()}function KX(){let e=tA();return{...e,authToken:e.authToken?"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022":"",smtpPass:e.smtpPass?"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022":""}}function XX(e){let i={...tA()};for(let[r,n]of Object.entries(e))(r==="authToken"||r==="smtpPass")&&(n==="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"||n==="")||(i[r]=n);return y$e(i),i}function mv(e){e.authToken&&(process.env.PM2_ORBIT_TOKEN=e.authToken),e.slackWebhookUrl&&(process.env.SLACK_WEBHOOK_URL=e.slackWebhookUrl),e.discordWebhookUrl&&(process.env.DISCORD_WEBHOOK_URL=e.discordWebhookUrl),e.webhookUrl&&(process.env.WEBHOOK_URL=e.webhookUrl),e.smtpHost&&(process.env.SMTP_HOST=e.smtpHost),e.smtpPort&&(process.env.SMTP_PORT=String(e.smtpPort)),e.smtpUser&&(process.env.SMTP_USER=e.smtpUser),e.smtpPass&&(process.env.SMTP_PASS=e.smtpPass),e.smtpFrom&&(process.env.SMTP_FROM=e.smtpFrom),e.smtpTo&&(process.env.SMTP_TO=e.smtpTo),e.theme&&(process.env.PM2_ORBIT_THEME=e.theme);for(let t of Object.keys(e.enabledChannels))process.env[`NOTIFY_${t.toUpperCase()}_ENABLED`]=e.enabledChannels[t]?"1":"0"}var hn,fv,fl,ju,eA,ZP,VX,WX,Du,iA=dr(()=>{"use strict";hn=dt(require("fs")),fv=dt(require("path")),fl=require("crypto"),ju=fv.default.join(process.env.HOME||process.env.USERPROFILE||"",".pm2-orbit"),eA=fv.default.join(ju,"settings.json"),ZP=fv.default.join(ju,".key"),VX={theme:"dark",port:9823,authToken:"",slackWebhookUrl:"",discordWebhookUrl:"",webhookUrl:"",smtpHost:"",smtpPort:587,smtpUser:"",smtpPass:"",smtpFrom:"",smtpTo:"",enabledChannels:{browser:!0,slack:!0,discord:!0,webhook:!0,email:!0}},WX=["authToken","smtpPass","slackWebhookUrl","discordWebhookUrl","webhookUrl"];Du=null});var YX=S((sWe,x$e)=>{x$e.exports={name:"pm2",preferGlobal:!0,version:"7.0.3",engines:{node:">=18.0.0"},directories:{bin:"./bin",lib:"./lib",example:"./examples"},author:{name:"Strzelewicz Alexandre",email:"alex@edgecraft.io <Pour ce Nouveau Monde>",url:"https://pm2.io"},maintainers:[{name:"Alexandre Strzelewicz",email:"alexandre@pm2.io"}],contributors:["Mathilde Tuffier","Antoine Bluchet","Alex Kocharin","Antoine Bluchet","Subhash Burramsetty","Valentin Marchaud","Valentin Touffet","Florian Hermouet-Joscht","Vincent Vallet","Joni Shkurti","Jun Tjatse","Xu Jingxin","Ben Postlethwaite","Devo.ps","Bret Copeland","John Hurliman","TruongSinh Tran-Nguyen","Michael Hueuberger","Chris Wiggins"],homepage:"http://pm2.keymetrics.io/",description:"Production process manager for Node.JS applications with a built-in load balancer.",main:"index.js",types:"types/index.d.ts",scripts:{"test:unit":"bash test/unit.sh","test:e2e":"bash test/e2e.sh",test:"bash test/unit.sh && bash test/e2e.sh","test:parallel":"bash test/docker-parallel.sh","test:bpm":"mocha 'modules/pm2-io-bpm/test/**/*.spec.js' --exit --timeout 10000","test:axon-rpc":"mocha 'modules/pm2-axon-rpc/test/' --reporter spec --exit","test:axon":"bash modules/pm2-axon/test/run modules/pm2-axon/test/test.*.js","test:io-agent":"mocha 'modules/pm2-io-agent/test/units/*.mocha.js' --reporter spec --exit","test:windows":"bash test/windows.sh"},keywords:["cli","fault tolerant","sysadmin","tools","pm2","logs","log","json","express","hapi","kraken","reload","load balancer","lb","load-balancer","kubernetes","k8s","pm2-docker","runtime","source maps","graceful","microservice","programmatic","harmony","node-pm2","production","keymetrics","node.js monitoring","strong-pm","deploy","deployment","daemon","supervisor","supervisord","nodemon","pm2.io","ghost","ghost production","monitoring","keymetrics","process manager","forever","profiling","probes","apm","container","forever-monitor","keep process alive","process configuration","clustering","cluster cli","cluster","docker","cron","devops","dev ops"],bin:{pm2:"bin/pm2","pm2-dev":"bin/pm2-dev","pm2-docker":"bin/pm2-docker","pm2-runtime":"bin/pm2-runtime"},dependencies:{"@pm2/blessed":"0.1.81","@pm2/js-api":"0.8.1","@pm2/pm2-version-check":"1.0.4",amp:"0.3.1","amp-message":"0.1.2",ansis:"4.0.0-node10",async:"3.2.6",chokidar:"3.6.0","cli-tableau":"2.0.1",commander:"2.15.1",croner:"4.1.97",dayjs:"1.11.15",debug:"4.4.3",eventemitter2:"6.4.9","fast-json-patch":"3.1.1","js-yaml":"4.3.0",pidusage:"4.0.1","pm2-deploy":"1.0.2","proxy-agent":"6.5.0",semver:"7.7.2",tx2:"1.0.5",ws:"8.21.0"},overrides:{debug:"4.4.3"},devDependencies:{express:"^4.21.0",mocha:"^11.7.0",should:"^13.2.3"},bugs:{url:"https://github.com/Unitech/pm2/issues"},repository:{type:"git",url:"git://github.com/Unitech/pm2.git"},license:"AGPL-3.0"}});var JX=S((oWe,v$e)=>{v$e.exports={name:"pm2-orbit",version:"1.0.5",files:["dist/","dist-ui/","bin/"],description:"High-performance PM2 monitoring dashboard \u2014 event-driven, 1000+ processes, < 150KB",main:"dist/server.js",bin:{"pm2-orbit":"bin/pm2-orbit.js"},scripts:{"dev:ui":"cd ui && vite","dev:server":"tsx watch src/server.ts",dev:'concurrently -k -n ui,server -c blue,green "npm:dev:ui" "npm:dev:server"',build:"node build.js",start:"node dist/server.js",lint:"tsc --noEmit",typecheck:"tsc --noEmit && cd ui && tsc --noEmit",test:"vitest run","test:watch":"vitest","test:e2e":"vitest --config vitest.e2e.config.ts",prepare:"husky",prepublishOnly:"npm run build",postinstall:`node -e "try{require.resolve('pm2')}catch{console.log('\\n \u2139 Install pm2 for process monitoring: npm install -g pm2\\n')}"`},engines:{node:">=18"},dependencies:{"@fastify/compress":"^9","@fastify/cors":"^11","@fastify/helmet":"^13","@fastify/rate-limit":"^11","@fastify/static":"^9.1.3",fastify:"^5",mri:"^1.2",open:"^10",systeminformation:"^5.31.11",ws:"^8"},optionalDependencies:{"better-sqlite3":"^11",nodemailer:"^9.0.1",pm2:"^7"},devDependencies:{"@tailwindcss/postcss":"^4","@testing-library/react":"^14","@types/node":"^26.0.1","@types/nodemailer":"^8.0.1","@types/ws":"^8.18.1","@vitejs/plugin-react":"^4",autoprefixer:"^10",concurrently:"^8",esbuild:"^0.25",husky:"^9","lint-staged":"^15",postcss:"^8",tailwindcss:"^4",tsx:"^4",typescript:"^5",vite:"^6",vitest:"^3"},keywords:["pm2","monitoring","dashboard","devops","nodejs","react"],license:"MIT"}});var QX={};js(QX,{registerHealthRoutes:()=>w$e});function b$e(e,t){switch(e){case"browser":return!0;case"slack":return!!t.slackWebhookUrl;case"discord":return!!t.discordWebhookUrl;case"webhook":return!!t.webhookUrl;case"email":return!!t.smtpHost&&!!t.smtpFrom&&!!t.smtpTo}}async function w$e(e,t){e.get("/api/health",async()=>{let i="unknown";try{i=YX().version}catch{try{i=require("pm2/package.json").version}catch{}}return{status:"ok",uptime:process.uptime(),version:JX().version,processes:(await t.bridge.list()).length,nodeVersion:process.version,pm2Version:i}}),e.get("/api/ping",async()=>"pong"),e.get("/api/system",async()=>{let{readSystem:i}=await Promise.resolve().then(()=>(Yf(),_R));return i()}),e.get("/api/settings",async()=>KX()),e.get("/api/channels",async()=>{let i=hv(),r=["browser","slack","discord","webhook","email"],n={};for(let s of r){let o=b$e(s,i),a=i.enabledChannels[s]!==!1;n[s]={configured:o,enabled:a}}return n}),e.put("/api/settings",async(i,r)=>{let n=i.body;if(!n||typeof n!="object")return r.code(400).send({error:"Invalid request body"});let s=["theme","authToken","slackWebhookUrl","discordWebhookUrl","webhookUrl","smtpHost","smtpPort","smtpUser","smtpPass","smtpFrom","smtpTo","enabledChannels"],o={};for(let l of s)l in n&&(o[l]=n[l]);let a=XX(o);return mv(a),{success:!0,settings:a}})}var ZX=dr(()=>{"use strict";iA()});function eY(e){return e.replace(/\.\.(\/|\\)/g,"").replace(/[/\\]/g,"_").replace(/\0/g,"").replace(/\s+/g,"_").replace(/^_+|_+$/g,"").substring(0,128)}function Jo(e){if(!e||typeof e!="string")return null;let t=parseInt(e,10);return isNaN(t)||t<0||!Number.isSafeInteger(t)?null:t}function tY(e){if(!e||typeof e!="object")return null;let t=e;if(typeof t.id!="string"||!t.id||typeof t.metric!="string"||!_$e.includes(t.metric)||typeof t.operator!="string"||!S$e.includes(t.operator)||typeof t.threshold!="number"||isNaN(t.threshold))return null;let i=[];if(Array.isArray(t.channels))for(let r of t.channels)typeof r=="string"&&E$e.includes(r)&&i.push(r);return{id:t.id,metric:t.metric,operator:t.operator,threshold:t.threshold,...typeof t.processId=="number"?{processId:t.processId}:{},...typeof t.processName=="string"?{processName:t.processName}:{},enabled:t.enabled!==!1,channels:i,...typeof t.webhookUrl=="string"?{webhookUrl:t.webhookUrl}:{},...typeof t.slackWebhook=="string"?{slackWebhook:t.slackWebhook}:{},...typeof t.discordWebhook=="string"?{discordWebhook:t.discordWebhook}:{},...typeof t.emailTo=="string"?{emailTo:t.emailTo}:{}}}var _$e,S$e,E$e,qu=dr(()=>{"use strict";_$e=["cpu","memory","restarts","status"],S$e=[">","<","==",">=","<="],E$e=["browser","webhook","slack","discord","email"]});var rY={};js(rY,{registerProcessRoutes:()=>T$e});async function T$e(e,t){e.get("/api/processes",async()=>t.bridge.list()),e.get("/api/processes/:id/env",async i=>{let{id:r}=i.params,n=Jo(r);if(n===null)return{};try{return Fr?new Promise(s=>{Fr.list((o,a)=>{if(o)return s({});let l=a.find(f=>f.pm_id===n);if(!l)return s({});let c=l.pm2_env||{},u={},p=new Set(["PATH","PATHEXT","SYSTEMROOT","SYSTEMDRIVE","WINDIR","TEMP","TMP","USERPROFILE","USERNAME","USERDOMAIN","USERDOMAIN_ROAMINGPROFILE","PROCESSOR_ARCHITECTURE","PROCESSOR_IDENTIFIER","PROCESSOR_LEVEL","PROCESSOR_REVISION","PROGRAMDATA","PROGRAMFILES","PROGRAMW6432","COMMONPROGRAMFILES","COMMONPROGRAMW6432","COMPUTERNAME","COMSPEC","DRIVERDATA","HOMEDRIVE","HOMEPATH","LOCALAPPDATA","LOGONSERVER","NUMBER_OF_PROCESSORS","ONEDRIVE","OS","PSMODULEPATH","PUBLIC","SESSIONNAME","ALLUSERSPROFILE","APPDATA","COLORTERM","LANG","TERM","TERM_PROGRAM","TERM_PROGRAM_VERSION","ZES_ENABLE_SYSMAN","ZED_TERM","ZED_ENVIRONMENT","PM2_USAGE","PM2_JSON_PROCESSING"]);for(let[f,d]of Object.entries(c))typeof d=="string"&&!p.has(f)&&!f.startsWith("MIMOCODE_")&&!f.startsWith("FPS_BROWSER_")&&!f.startsWith("EFC_")&&(u[f]=d);s(u)})}):{}}catch{return{}}}),e.post("/api/processes/:id/action",async(i,r)=>{let{id:n}=i.params,s=Jo(n);if(s===null)return r.code(400).send({error:"Invalid process ID"});let o=i.body,a=typeof o?.action=="string"?o.action:"",l=typeof o?.instances=="number"?o.instances:void 0;if(!a||!iY.includes(a))return r.code(400).send({error:`Invalid action. Must be one of: ${iY.join(", ")}`});try{if(!Fr)return r.code(500).send({error:"PM2 not available"});if(a==="scale"){let u=await new Promise((p,f)=>{Fr.list((d,h)=>{if(d)return f(d);let m=h.find(y=>y.pm_id===s);if(!m)return f(new Error("Process not found"));p(m.name)})});return await new Promise((p,f)=>{Fr.scale(u,l!==void 0?String(l):"+1",d=>{d?f(d):p()})}),{success:!0}}let c={restart:u=>Fr.restart(s,u),stop:u=>Fr.stop(s,u),start:u=>Fr.restart(s,u),reload:u=>Fr.reload(s,u),delete:u=>Fr.delete(s,u),flush:u=>Fr.flush(s,u)}[a];return c?(await new Promise((u,p)=>{c(f=>{f?p(f):u()})}),{success:!0}):r.code(400).send({error:`Unknown action: ${a}`})}catch(c){return r.code(500).send({error:c.message})}})}var Fr,iY,nY=dr(()=>{"use strict";qu();Fr=null;try{Fr=require("pm2")}catch{}iY=["restart","stop","start","reload","delete","scale","flush"]});var sY={};js(sY,{registerHistoryRoutes:()=>C$e});async function C$e(e,t){e.get("/api/history/:id",async(i,r)=>{let{id:n}=i.params,{hours:s}=i.query,o=Jo(n);if(o===null)return r.code(400).send({error:"Invalid process ID"});if(!t.persistence)return r.code(503).send({error:"Persistence not available"});let a=s?parseInt(s,10):24;return isNaN(a)||a<1||a>168?r.code(400).send({error:"Invalid hours parameter (1-168)"}):t.persistence.getProcessHistory(o,a)}),e.get("/api/history/system",async(i,r)=>{let{hours:n}=i.query;if(!t.persistence)return r.code(503).send({error:"Persistence not available"});let s=n?parseInt(n,10):24;return isNaN(s)||s<1||s>168?r.code(400).send({error:"Invalid hours parameter (1-168)"}):t.persistence.getSystemHistory(s)})}var oY=dr(()=>{"use strict";qu()});var aY={};js(aY,{registerAlertRoutes:()=>O$e});async function O$e(e,t){e.get("/api/alerts",async()=>t.alerts.getRules()),e.post("/api/alerts",async(i,r)=>{let n=tY(i.body);return n?(t.alerts.addRule(n),{success:!0}):r.code(400).send({error:"Invalid alert rule. Required: id (string), metric (cpu|memory|restarts|status), operator (>|<|==|>=|<=), threshold (number)"})}),e.delete("/api/alerts/:id",async(i,r)=>{let{id:n}=i.params;return!n||typeof n!="string"||n.length===0?r.code(400).send({error:"Invalid rule ID"}):(t.alerts.removeRule(n),{success:!0})}),e.get("/api/alerts/history",async()=>t.alerts.getHistory())}var lY=dr(()=>{"use strict";qu()});function pY(e,t,i){let r=[],n=!1,s="",o="",a={},l=null;function c(g){if(i){if(g==="out"&&i.out)return i.out;if(g==="err"&&i.err)return i.err}let v=process.env.HOME||process.env.USERPROFILE||"",b=uY.default.join(v,".pm2","logs",eY(t)),x=`${b}-${g}-${e}.log`;if(Ns.default.existsSync(x))return x;if(g==="err"){let C=`${b}-error-${e}.log`;if(Ns.default.existsSync(C))return C}let _=[`${b}-${g}.log`];g==="err"&&_.push(`${b}-error.log`);for(let C=0;C<16;C++)_.push(`${b}-${g}-${C}.log`),g==="err"&&_.push(`${b}-error-${C}.log`);for(let C of _)if(Ns.default.existsSync(C))return C;return _[0]}function u(g,v){try{if(!Ns.default.existsSync(g))return;let b=Ns.default.statSync(g),x=a[g]||0;if(b.size<x&&(a[g]=0,l=null),b.size<=(a[g]||0))return;let _=Ns.default.openSync(g,"r"),C=Buffer.alloc(b.size-(a[g]||0));Ns.default.readSync(_,C,0,C.length,a[g]||0),Ns.default.closeSync(_),a[g]=b.size;let E=C.toString("utf-8");if(l!==null&&(E=l+E,l=null),!E.endsWith(`
885
885
  `)){let P=E.lastIndexOf(`
886
886
  `);if(P>=0)l=E.slice(P+1),E=E.slice(0,P+1);else{l=E;return}}let T=E.split(`
887
887
  `);T.pop();let O=/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORa-z]/g;for(let P of T){let k=P.replace(/\r$/,"").replace(O,"");k.length!==0&&r.push({ts:Date.now(),stream:v,message:k})}r.length>cY&&r.splice(0,r.length-cY)}catch{}}function p(){s=c("out"),o=c("err"),st.debug(`[tailer] processId=${e} name=${t} out=${s} err=${o}`),u(s,"stdout"),u(o,"stderr"),st.debug(`[tailer] buffer after init: ${r.length} entries`)}function f(){n||(u(s,"stdout"),u(o,"stderr"))}function d(){return r}function h(g){return g>=r.length?{entries:[],total:r.length}:g<=0?{entries:r.slice(),total:r.length}:{entries:r.slice(g),total:r.length}}function m(){n=!0}function y(){return n}return p(),{processId:e,processName:t,poll:f,getBuffer:d,getNewEntries:h,close:m,isClosed:y}}var Ns,uY,cY,dY=dr(()=>{"use strict";Ns=dt(require("fs")),uY=dt(require("path"));qu();Ya();cY=parseInt(process.env.PM2_ORBIT_LOG_BUFFER||"2000",10)});function P$e(){gh||(gh=setInterval(()=>{for(let[,e]of $u)e.tailer.poll()},R$e))}function A$e(){gh!==null&&(clearInterval(gh),gh=null)}function fY(e,t,i){let r=$u.get(e);if(r)return r.refs++,r.tailer;let n=pY(e,t,i);return $u.set(e,{tailer:n,refs:1,name:t}),P$e(),n}function hY(e){let t=$u.get(e);t&&(t.refs--,t.refs<=0&&(t.tailer.close(),$u.delete(e),$u.size===0&&A$e()))}var R$e,$u,gh,mY=dr(()=>{"use strict";dY();R$e=2e3,$u=new Map,gh=null});var yY={};js(yY,{registerLogRoutes:()=>k$e});async function k$e(e,t){e.get("/api/logs/:id",async(i,r)=>{let{id:n}=i.params,s=Jo(n);if(s===null)return r.code(400).send({error:"Invalid process ID"});let o=t.bridge,a=o.getLogBuffer(s),l=a.length;r.raw.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"}),r.raw.write(`retry: 2000
@@ -2,8 +2,15 @@
2
2
  <html lang="en" class="dark">
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
+ <meta name="theme-color" content="#14b8a6" />
7
+ <meta name="description" content="High-performance PM2 monitoring dashboard — event-driven, 1000+ processes" />
8
+ <meta name="apple-mobile-web-app-capable" content="yes" />
9
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
10
+ <meta name="apple-mobile-web-app-title" content="PM2 Orbit" />
6
11
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
12
+ <link rel="apple-touch-icon" href="/favicon.svg" />
13
+ <link rel="manifest" href="/manifest.json" />
7
14
  <title>PM2 Orbit</title>
8
15
  <style>
9
16
  @font-face {
@@ -58,5 +65,12 @@
58
65
  </head>
59
66
  <body>
60
67
  <div id="root"></div>
68
+ <script>
69
+ if ('serviceWorker' in navigator) {
70
+ window.addEventListener('load', () => {
71
+ navigator.serviceWorker.register('/sw.js').catch(() => {});
72
+ });
73
+ }
74
+ </script>
61
75
  </body>
62
76
  </html>
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "PM2 Orbit",
3
+ "short_name": "PM2 Orbit",
4
+ "description": "High-performance PM2 monitoring dashboard",
5
+ "start_url": "/",
6
+ "display": "standalone",
7
+ "background_color": "#0b0f1a",
8
+ "theme_color": "#14b8a6",
9
+ "orientation": "any",
10
+ "icons": [
11
+ {
12
+ "src": "/favicon.svg",
13
+ "sizes": "any",
14
+ "type": "image/svg+xml",
15
+ "purpose": "any maskable"
16
+ }
17
+ ],
18
+ "categories": ["developer", "utilities"],
19
+ "lang": "en"
20
+ }
package/dist-ui/sw.js ADDED
@@ -0,0 +1,60 @@
1
+ const CACHE_NAME = 'pm2-orbit-v1';
2
+ const STATIC_ASSETS = [
3
+ '/',
4
+ '/index.html',
5
+ '/favicon.svg',
6
+ ];
7
+
8
+ self.addEventListener('install', (event) => {
9
+ event.waitUntil(
10
+ caches.open(CACHE_NAME).then((cache) => {
11
+ return cache.addAll(STATIC_ASSETS);
12
+ })
13
+ );
14
+ self.skipWaiting();
15
+ });
16
+
17
+ self.addEventListener('activate', (event) => {
18
+ event.waitUntil(
19
+ caches.keys().then((keys) => {
20
+ return Promise.all(
21
+ keys.filter((key) => key !== CACHE_NAME).map((key) => caches.delete(key))
22
+ );
23
+ })
24
+ );
25
+ self.clients.claim();
26
+ });
27
+
28
+ self.addEventListener('fetch', (event) => {
29
+ const url = new URL(event.request.url);
30
+
31
+ if (url.pathname.startsWith('/api/') || url.pathname === '/ws') {
32
+ event.respondWith(
33
+ fetch(event.request).catch(() => {
34
+ return new Response(JSON.stringify({ error: 'Offline' }), {
35
+ status: 503,
36
+ headers: { 'Content-Type': 'application/json' },
37
+ });
38
+ })
39
+ );
40
+ return;
41
+ }
42
+
43
+ event.respondWith(
44
+ caches.match(event.request).then((cached) => {
45
+ return cached || fetch(event.request).then((response) => {
46
+ if (response.status === 200) {
47
+ const responseClone = response.clone();
48
+ caches.open(CACHE_NAME).then((cache) => {
49
+ cache.put(event.request, responseClone);
50
+ });
51
+ }
52
+ return response;
53
+ });
54
+ }).catch(() => {
55
+ if (event.request.destination === 'document') {
56
+ return caches.match('/');
57
+ }
58
+ })
59
+ );
60
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pm2-orbit",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "files": [
5
5
  "dist/",
6
6
  "dist-ui/",