@ebowwa/pkg-ops 0.1.18 → 0.1.19
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/index.d.ts.map +1 -1
- package/dist/index.js +16 -16
- package/dist/index.js.map +5 -7
- package/package.json +2 -2
- package/rust/src/lib.rs +438 -0
- package/rust/src/main.rs +177 -0
- package/src/index.ts +4 -2
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;GAqBG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;GAqBG;AA+kCH,OAAO,EACL,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,kBAAkB,GACxB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,UAAU,EACV,WAAW,EACX,UAAU,EACV,SAAS,EACT,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,oBAAoB,EACzB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,WAAW,GACjB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,+BAA+B,EAC/B,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
-
import{readFileSync as
|
|
4
|
-
${
|
|
3
|
+
import{readFileSync as l0,existsSync as m0}from"fs";import{constants as I,mkdirSync as U0,readFileSync as J0,writeFileSync as K0,existsSync as d}from"fs";import{dirname as F0}from"path";var C={packages:{},healthPort:8914,workDir:"/root",logLevel:"info"},A0="/etc/pkg-ops",L0=`${A0}/config.json`;function S(){return process.env.PKG_OPS_CONFIG??L0}function p(){let Y=F0(S());if(!d(Y))U0(Y,{recursive:!0,mode:I.S_IRWXU|I.S_IRGRP|I.S_IXGRP})}function _(){let Y=S();try{if(!d(Y))return{...C};let $=J0(Y,"utf-8"),W=JSON.parse($);return{...C,...W}}catch($){return console.error(`Failed to load config from ${Y}:`,$),{...C}}}function b(Y){let $=S();p();let W=JSON.stringify(Y,null,2);K0($,W,{encoding:"utf-8",mode:I.S_IRUSR|I.S_IWUSR|I.S_IRGRP})}function M(Y,$){let W=_();return W.packages[Y]=$,b(W),W}function R0(Y){let $=_();return delete $.packages[Y],b($),$}function J(Y){return _().packages[Y]}function z(){let Y=_();return Object.entries(Y.packages).map(([$,W])=>({name:$,config:W}))}function K(Y){return Y.startsWith("@ebowwa/")}function D(Y){let $=Y.lastIndexOf("@");if($<=0)return{name:Y,version:"latest"};let W=Y.slice(0,$),X=Y.slice($+1);if(!X)return{name:W,version:"latest"};return{name:W,version:X}}function y0(Y){let W=_().packages[Y];if(!W?.versions)return[];return Object.entries(W.versions).map(([X,Z])=>({version:X,...Z}))}function x0(Y,$){return!!_().packages[Y]?.versions?.[$]}function V0(Y){return _().packages[Y]?.version??null}function I0(Y,$,W){let X=_();if(!X.packages[Y])X.packages[Y]={version:$,versions:{},service:Y.replace("@ebowwa/",""),autoStart:!0};X.packages[Y].versions[$]={installedAt:W.installedAt??new Date().toISOString(),distSizeBytes:W.distSizeBytes??null,fileCount:W.fileCount??null},b(X)}function b0(Y,$){let W=_(),X=W.packages[Y];if(!X?.versions?.[$])return!1;if(delete X.versions[$],X.version===$){let Z=Object.keys(X.versions).sort((q,Q)=>{let H=X.versions[q]?.installedAt??"";return(X.versions[Q]?.installedAt??"").localeCompare(H)});if(Z.length>0)X.version=Z[0];else delete W.packages[Y]}return b(W),!0}function G0(Y,$){let W=_(),X=W.packages[Y];if(!X?.versions?.[$])return!1;return X.version=$,b(W),!0}function M0(Y){let W=_().packages[Y];return Object.keys(W?.versions??{}).length}function D0(){let Y=_(),$=[];for(let[W,X]of Object.entries(Y.packages)){let Z=Object.keys(X.versions??{});if(Z.length>1)$.push({name:W,activeVersion:X.version,totalVersions:Z.length,versions:Z.sort((q,Q)=>Q.localeCompare(q,void 0,{numeric:!0}))})}return $}var{getPrototypeOf:K1,defineProperty:P0,getOwnPropertyNames:F1,getOwnPropertyDescriptor:A1}=Object;var S0=(Y,$)=>{for(var W in $)P0(Y,W,{get:$[W],enumerable:!0,configurable:!0,set:(X)=>$[W]=()=>X})},C0=(Y,$)=>()=>(Y&&($=Y(Y=0)),$),j={};S0(j,{writeFile:()=>N0,sudo:()=>P,pkgInstall:()=>z0,exec:()=>m});async function P(Y,$){let W=Array.isArray(Y)?Y:Y.split(/\s+/),X=["sudo",...$.env?Object.entries($.env).map(([Z,q])=>`${Z}=${N(q)}`):[],...W];return m(X,$)}async function z0(Y,$){let W=$.pm??"apt",X={...$.env,...$.nonInteractive!==!1?{DEBIAN_FRONTEND:"noninteractive"}:{}};return await P(o[W],{...$,env:X,quiet:!0}),P([...c[W],...Y],{...$,env:X})}async function N0(Y,$,W){let X=`tee ${W.append?"-a":""} ${N(Y)}`.trim(),Z=await h0($,["sudo",X],W);if(Z.ok&&W.mode)await P(["chmod",W.mode,Y],W);if(Z.ok&&W.owner)await P(["chown",W.owner,Y],W);return Z}function l(Y){let $=["ssh","-F","/dev/null","-o","StrictHostKeyChecking=no","-o","UserKnownHostsFile=/dev/null"];if(Y.keyPath)$.push("-i",Y.keyPath);else if(Y.key)$.push("-i",Y.key);if(Y.port)$.push("-p",String(Y.port));return $.push(`${Y.user??"root"}@${Y.host}`),$}async function m(Y,$){let W=$.context??{type:"local"},X=W.type==="ssh"?[...l(W),Y.map(N).join(" ")]:Y,Z=Bun.spawn(X,{stdout:"pipe",stderr:"pipe",timeout:$.timeout??30000}),q=await Z.exited,Q=$.quiet?"":await new Response(Z.stdout).text(),H=await new Response(Z.stderr).text();return{stdout:Q,stderr:H,exitCode:q,ok:q===0}}async function h0(Y,$,W){let X=W.context??{type:"local"};if(X.type==="ssh"){let w=l(X),y=$.join(" "),x=[...w,y],E=Bun.spawn(x,{stdin:new TextEncoder().encode(Y),stdout:"pipe",stderr:"pipe",timeout:W.timeout??30000}),V=await E.exited,F=W.quiet?"":await new Response(E.stdout).text(),A=await new Response(E.stderr).text();return{stdout:F,stderr:A,exitCode:V,ok:V===0}}let Z=Bun.spawn(["sh","-c",$.join(" ")],{stdin:new TextEncoder().encode(Y),stdout:"pipe",stderr:"pipe",timeout:W.timeout??30000}),q=await Z.exited,Q=W.quiet?"":await new Response(Z.stdout).text(),H=await new Response(Z.stderr).text();return{stdout:Q,stderr:H,exitCode:q,ok:q===0}}function N(Y){if(/^[a-zA-Z0-9._\-\/=:@]+$/.test(Y))return Y;return`'${Y.replace(/'/g,"'\\''")}'`}var c,o,f0=C0(()=>{c={apt:["apt-get","install","-y"],dnf:["dnf","install","-y"],apk:["apk","add","--no-cache"]},o={apt:["apt-get","update","-qq"],dnf:["dnf","check-update"],apk:["apk","update"]}});async function L(Y,$){let{sudo:W}=await Promise.resolve().then(()=>(f0(),j));return W(Y,$)}async function t(Y,$){return L(["systemctl","enable",Y],$)}async function i(Y,$){return L(["systemctl","disable",Y],$)}async function n(Y,$){return L(["systemctl","start",Y],$)}async function g(Y,$){return L(["systemctl","stop",Y],$)}async function s(Y,$){return L(["systemctl","restart",Y],$)}async function r(Y,$){let W=await L(["systemctl","show",Y,"--property=LoadState,ActiveState,SubState,MainPID,Description"],{...$});if(!W.ok)return{loaded:!1,active:!1,subState:"unknown",mainPid:0,description:""};let X=(Z)=>{return W.stdout.match(new RegExp(`^${Z}=(.+)$`,"m"))?.[1]?.trim()??""};return{loaded:X("LoadState")==="loaded",active:X("ActiveState")==="active",subState:X("SubState"),mainPid:parseInt(X("MainPID")||"0",10),description:X("Description")}}async function a(Y,$){let W=await L(["systemctl","list-unit-files",Y+".service"],$);return W.ok&&W.stdout.includes(Y)}async function e(Y,$={}){let W=["journalctl","-u",Y,"-n",String($.lines??100)];if($.since)W.push("--since",$.since);if(!$.follow)W.push("-n",String($.lines??100));return(await L(W,$)).stdout}class f{sudoOptions;constructor(Y){this.sudoOptions=Y??{context:{type:"local"}}}async start(Y){let $=await n(Y,this.sudoOptions);return{success:$.ok,message:$.ok?`Service ${Y} started`:$.stderr||$.stdout}}async stop(Y){let $=await g(Y,this.sudoOptions);return{success:$.ok,message:$.ok?`Service ${Y} stopped`:$.stderr||$.stdout}}async restart(Y){let $=await s(Y,this.sudoOptions);return{success:$.ok,message:$.ok?`Service ${Y} restarted`:$.stderr||$.stdout}}async status(Y){return r(Y,this.sudoOptions)}async enable(Y){let $=await t(Y,this.sudoOptions);return{success:$.ok,message:$.ok?`Service ${Y} enabled`:$.stderr||$.stdout}}async disable(Y){let $=await i(Y,this.sudoOptions);return{success:$.ok,message:$.ok?`Service ${Y} disabled`:$.stderr||$.stdout}}async exists(Y){return a(Y,this.sudoOptions)}async logs(Y,$){return e(Y,{...this.sudoOptions,lines:$?.lines??100,since:$?.since})}async info(Y){let[$,W]=await Promise.all([this.exists(Y),this.status(Y)]);return{name:Y,exists:$,status:W}}async isHealthy(Y){let $=await this.status(Y);return $.active&&$.subState==="running"}async waitForHealthy(Y,$){let W=$?.timeout??30000,X=$?.interval??1000,Z=Date.now();while(Date.now()-Z<W){if(await this.isHealthy(Y))return!0;await new Promise((Q)=>setTimeout(Q,X))}return!1}}var h=null;function T(){if(!h)h=new f;return h}import{spawn as B0}from"child_process";import{accessSync as Y0,constants as $0}from"fs";import{join as B,dirname as u0}from"path";import{fileURLToPath as k0}from"url";var v0=30000;class u{process=null;pendingRequests=new Map;requestId=0;buffer="";async start(){if(this.process)return;let Y=this.getBinaryPath();try{Y0(Y,$0.X_OK)}catch{throw Error(`Rust binary not found at ${Y}. Run 'bun run build:rust' in the pkg-ops package.`)}if(this.process=B0(Y,[],{stdio:["pipe","pipe","pipe"]}),!this.process.stdin||!this.process.stdout)throw Error("Failed to create stdin/stdout pipes");this.process.stdout.on("data",($)=>{this.buffer+=$.toString("utf-8"),this.processBuffer()}),this.process.stderr?.on("data",($)=>{console.error("[rust-worker]",$.toString("utf-8").trim())}),this.process.on("exit",($)=>{console.error(`Rust worker exited with code ${$}`),this.process=null})}async stop(){if(!this.process)return;try{await this.sendRequest("shutdown",{})}catch{}if(await new Promise((Y)=>setTimeout(Y,1000)),this.process)this.process.kill("SIGTERM"),this.process=null;for(let[Y,$]of this.pendingRequests)clearTimeout($.timeout),$.reject(Error("Bridge shutdown"));this.pendingRequests.clear()}async install(Y,$){return this.sendRequest("install",{packageName:Y,version:$})}async update(Y){return this.sendRequest("update",{packageName:Y})}async updateAll(){return this.sendRequest("updateAll",{})}async list(){return this.sendRequest("list",{})}async rollback(Y){return this.sendRequest("rollback",{packageName:Y})}async health(){return this.sendRequest("health",{})}async verify(Y){return this.sendRequest("verify",{packageName:Y})}async audit(){return this.sendRequest("audit",{})}async getBundleSizes(){return this.sendRequest("sizes",{})}async getInstalledInfo(){return this.sendRequest("installedInfo",{})}async listVersions(Y){return this.sendRequest("listVersions",{packageName:Y})}async switchVersion(Y,$){return this.sendRequest("switchVersion",{packageName:Y,version:$})}async pruneVersions(Y,$){return this.sendRequest("pruneVersions",{packageName:Y,keepCount:$})}async removeVersion(Y,$){return this.sendRequest("removeVersion",{packageName:Y,version:$})}async getMultiVersionPackages(){return this.sendRequest("getMultiVersionPackages",{})}getBinaryPath(){let Y=u0(k0(import.meta.url)),$=[B(Y,"..","rust","target","release","pkg-ops-core"),B(Y,"..","rust","pkg-ops-core"),B(Y,"..","rust","target","x86_64-unknown-linux-gnu","release","pkg-ops-core")];for(let W of $)try{return Y0(W,$0.X_OK),W}catch{}throw Error(`Rust binary not found. Tried:
|
|
4
|
+
${$.map((W)=>` - ${W}`).join(`
|
|
5
5
|
`)}
|
|
6
|
-
Run 'bun run build:rust' or 'cargo build --release' in the pkg-ops package.`)}sendRequest(
|
|
7
|
-
`;this.process.stdin.write(H,"utf-8",(
|
|
8
|
-
`);this.buffer
|
|
9
|
-
`);try{let W=await(await U()).list();if(W.length===0){console.log(" No packages installed");return}for(let X of W){let Z=X.installed?"installed":"not installed",q=X.service?` (service: ${X.service})`:"";console.log(` ${X.name}@${X.version} [${Z}]${q}`)}}catch(
|
|
10
|
-
Packages:`);let W=
|
|
11
|
-
Package: ${X.packageName}@${X.version}`),console.log(` Status: ${X.success?"VALID":"INVALID"}`),console.log(` Dist exists: ${X.distExists?"Yes":"No"}`),X.checksum)console.log(` Checksum: ${X.checksum}`);console.log(` Message: ${X.message}`)}catch(W){console.error("Verification failed:",W),process.exit(1)}finally{await
|
|
12
|
-
`),Z&&
|
|
6
|
+
Run 'bun run build:rust' or 'cargo build --release' in the pkg-ops package.`)}sendRequest(Y,$){return new Promise((W,X)=>{if(!this.process?.stdin){X(Error("Rust worker not started"));return}let Z=String(++this.requestId),q={jsonrpc:"2.0",id:Z,method:Y,params:$},Q=setTimeout(()=>{this.pendingRequests.delete(Z),X(Error(`Request timeout: ${Y}`))},v0);this.pendingRequests.set(Z,{resolve:W,reject:X,timeout:Q});let H=JSON.stringify(q)+`
|
|
7
|
+
`;this.process.stdin.write(H,"utf-8",(w)=>{if(w)this.pendingRequests.delete(Z),clearTimeout(Q),X(w)})})}processBuffer(){let Y=this.buffer.split(`
|
|
8
|
+
`);this.buffer=Y.pop()??"";for(let $ of Y){if(!$.trim())continue;try{let W=JSON.parse($),X=this.pendingRequests.get(W.id);if(X)if(clearTimeout(X.timeout),this.pendingRequests.delete(W.id),W.error)X.reject(Error(W.error.message));else X.resolve(W.result)}catch(W){console.error("Failed to parse response:",$,W)}}}}var G=null;function W0(){if(!G)G=new u;return G}async function U(){let Y=W0();return await Y.start(),Y}async function O(){if(G)await G.stop(),G=null}import{createServer as d0}from"http";class k{server=null;checks=new Map;startTime=Date.now();port;constructor(Y=8914){this.port=Y}async start(){if(this.server)return;return new Promise((Y,$)=>{this.server=d0((W,X)=>this.handleRequest(W,X)),this.server.on("error",$),this.server.listen(this.port,()=>{console.log(`Health server listening on port ${this.port}`),this.server?.off("error",$),Y()})})}async stop(){if(!this.server)return;return new Promise((Y)=>{this.server?.close(()=>{this.server=null,Y()})})}addCheck(Y,$){this.checks.set(Y,$)}removeCheck(Y){this.checks.delete(Y)}async checkHealth(Y){if(Y)return this.getServiceHealth(Y);return this.getSystemHealth()}async handleRequest(Y,$){let W=Y.url??"/",X=Y.method??"GET";try{if(X==="GET"&&W==="/health"){let Z=await this.getSystemHealth();this.sendJson($,200,Z)}else if(X==="GET"&&W.startsWith("/health/")){let Z=W.slice(8).replace(".service",""),q=await this.getServiceHealth(Z);this.sendJson($,q?200:404,q??{error:"Service not found"})}else if(X==="GET"&&W==="/ready"){let Z=await this.getSystemHealth();this.sendJson($,Z.healthy?200:503,{ready:Z.healthy})}else if(X==="GET"&&W==="/live")this.sendJson($,200,{alive:!0});else this.sendJson($,404,{error:"Not found"})}catch(Z){console.error("Health check error:",Z),this.sendJson($,500,{error:"Internal server error"})}}async getSystemHealth(){let Y=_(),$=T(),W=[];for(let[q,Q]of Object.entries(Y.packages)){if(!Q.service)continue;let H=await $.status(Q.service),w=H.active&&H.subState==="running";W.push({name:Q.service,healthy:w,status:H,checkedAt:new Date().toISOString()})}let X={};for(let[q,Q]of this.checks)try{X[q]=await Q()}catch(H){X[q]={healthy:!1,message:H instanceof Error?H.message:"Unknown error"}}return{healthy:W.every((q)=>q.healthy)&&Object.values(X).every((q)=>q.healthy),services:W,uptime:Math.floor((Date.now()-this.startTime)/1000),timestamp:new Date().toISOString()}}async getServiceHealth(Y){let $=T();if(!await $.exists(Y))return null;let X=await $.status(Y),Z=X.active&&X.subState==="running";return{name:Y,healthy:Z,status:X,checkedAt:new Date().toISOString()}}sendJson(Y,$,W){Y.statusCode=$,Y.setHeader("Content-Type","application/json"),Y.end(JSON.stringify(W,null,2))}}var R=null;async function p0(Y){let $=_(),W=Y??$.healthPort??8914;if(!R)R=new k(W);return await R.start(),R}async function j0(){if(R)await R.stop(),R=null}function v(){return R}async function c0(Y){if(Y.length===0)console.error("Usage: pkg-ops install <package>[@version]"),process.exit(1);let $=Y[0],{name:W,version:X}=D($);if(!K(W))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);console.log(`Installing ${W}@${X}...`);try{let q=await(await U()).install(W,X);if(q.success){if(console.log(`Successfully installed ${W}@${q.version}`),q.previousVersion)console.log(` Previous version: ${q.previousVersion}`);let Q=J(W);M(W,{version:q.version,versions:{...Q?.versions,[q.version]:{installedAt:new Date().toISOString(),distSizeBytes:null,fileCount:null}},service:W.replace("@ebowwa/","")});let H=J(W);if(H?.service&&H.autoStart!==!1){let y=await T().start(H.service);if(y.success)console.log(` Service ${H.service} started`);else console.warn(` Failed to start service: ${y.message}`)}}else console.error(`Failed to install ${W}: ${q.message}`),process.exit(1)}catch(Z){console.error("Install failed:",Z),process.exit(1)}finally{await O()}}async function o0(Y){if(Y.length===0)console.error("Usage: pkg-ops update <package>"),process.exit(1);let $=Y[0];if(!K($))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);console.log(`Updating ${$}...`);try{let X=await(await U()).update($);if(X.success){if(console.log(`Successfully updated ${$} to ${X.version}`),X.previousVersion)console.log(` Previous version: ${X.previousVersion}`);let Z=J($);M($,{version:X.version,versions:{...Z?.versions,[X.version]:{installedAt:new Date().toISOString(),distSizeBytes:null,fileCount:null}},service:$.replace("@ebowwa/","")});let q=T(),Q=J($);if(Q?.service){if((await q.status(Q.service)).active)await q.restart(Q.service),console.log(` Service ${Q.service} restarted`)}}else console.error(`Failed to update ${$}: ${X.message}`),process.exit(1)}catch(W){console.error("Update failed:",W),process.exit(1)}finally{await O()}}async function t0(Y){console.log("Updating all managed packages...");try{let W=await(await U()).updateAll();for(let X of W)if(X.success)console.log(`Updated ${X.version}`);else console.error(`Failed to update: ${X.message}`)}catch($){console.error("Update all failed:",$),process.exit(1)}finally{await O()}}async function i0(Y){console.log(`Installed packages:
|
|
9
|
+
`);try{let W=await(await U()).list();if(W.length===0){console.log(" No packages installed");return}for(let X of W){let Z=X.installed?"installed":"not installed",q=X.service?` (service: ${X.service})`:"";console.log(` ${X.name}@${X.version} [${Z}]${q}`)}}catch($){console.error("Failed to list packages:",$),process.exit(1)}finally{await O()}}async function n0(Y){if(Y.length===0)console.error("Usage: pkg-ops rollback <package>"),process.exit(1);let $=Y[0];console.log(`Rolling back ${$}...`);try{let X=await(await U()).rollback($);if(X.success){console.log(`Rolled back ${$} from ${X.currentVersion} to ${X.previousVersion}`);let Z=T(),q=J($);if(q?.service){if((await Z.status(q.service)).active)await Z.restart(q.service),console.log(` Service ${q.service} restarted`)}}else console.error(`Rollback failed: ${X.message}`),process.exit(1)}catch(W){console.error("Rollback failed:",W),process.exit(1)}finally{await O()}}async function X0(Y){if(Y.length===0)console.error("Usage: pkg-ops service start <name>"),process.exit(1);let $=Y[0],W=T();console.log(`Starting ${$}...`);let X=await W.start($);if(X.success)console.log(`Service ${$} started`);else console.error(`Failed to start ${$}: ${X.message}`),process.exit(1)}async function Z0(Y){if(Y.length===0)console.error("Usage: pkg-ops service stop <name>"),process.exit(1);let $=Y[0],W=T();console.log(`Stopping ${$}...`);let X=await W.stop($);if(X.success)console.log(`Service ${$} stopped`);else console.error(`Failed to stop ${$}: ${X.message}`),process.exit(1)}async function q0(Y){if(Y.length===0)console.error("Usage: pkg-ops service restart <name>"),process.exit(1);let $=Y[0],W=T();console.log(`Restarting ${$}...`);let X=await W.restart($);if(X.success)console.log(`Service ${$} restarted`);else console.error(`Failed to restart ${$}: ${X.message}`),process.exit(1)}async function Q0(Y){if(Y.length===0)console.error("Usage: pkg-ops service status <name>"),process.exit(1);let $=Y[0],X=await T().info($);if(!X.exists){console.log(`Service ${$} not found`);return}console.log(`Service: ${$}`),console.log(` Loaded: ${X.status.loaded}`),console.log(` Active: ${X.status.active}`),console.log(` State: ${X.status.subState}`),console.log(` PID: ${X.status.mainPid||"N/A"}`),console.log(` Description: ${X.status.description||"N/A"}`)}async function H0(Y){if(Y.length===0)console.error("Usage: pkg-ops service logs <name> [--lines N]"),process.exit(1);let $=Y[0],W=Y.indexOf("--lines"),X=W>=0&&Y[W+1]?parseInt(Y[W+1],10):100,q=await T().logs($,{lines:X});console.log(q)}async function O0(Y){if(Y.length===0)console.error("Usage: pkg-ops service enable <name>"),process.exit(1);let $=Y[0],W=T();console.log(`Enabling ${$}...`);let X=await W.enable($);if(X.success)console.log(`Service ${$} enabled on boot`);else console.error(`Failed to enable ${$}: ${X.message}`),process.exit(1)}async function _0(Y){if(Y.length===0)console.error("Usage: pkg-ops service disable <name>"),process.exit(1);let $=Y[0],W=T();console.log(`Disabling ${$}...`);let X=await W.disable($);if(X.success)console.log(`Service ${$} disabled from boot`);else console.error(`Failed to disable ${$}: ${X.message}`),process.exit(1)}async function g0(Y){let $=Y[0],W=v();if(!W)console.error("Health server not initialized"),process.exit(1);let X=await W.checkHealth($);if(!X){console.log("Service not found");return}if("services"in X){if(X.healthy)console.log("All services healthy");else console.log("Some services unhealthy");for(let Z of X.services){let q=Z.healthy?"OK":"FAIL";console.log(` [${q}] ${Z.name}: ${Z.status.subState}`)}}else{let Z=X.healthy?"OK":"FAIL";console.log(`[${Z}] ${X.name}: ${X.status.subState}`)}}async function w0(Y){let $=_();console.log("PkgOps Configuration"),console.log("Config path: /etc/pkg-ops/config.json"),console.log(`Health port: ${$.healthPort}`),console.log(`Work dir: ${$.workDir}`),console.log(`Log level: ${$.logLevel}`),console.log(`
|
|
10
|
+
Packages:`);let W=z();if(W.length===0){console.log(" No packages configured");return}for(let{name:X,config:Z}of W){if(console.log(` ${X}:`),console.log(` Version: ${Z.version}`),Z.service)console.log(` Service: ${Z.service}`);if(Z.autoStart!==void 0)console.log(` Auto-start: ${Z.autoStart}`)}}async function E0(Y){if(Y.length<3)console.error("Usage: pkg-ops config set <package> <key> <value>"),process.exit(1);let $=Y[0],W=Y[1],X=Y[2];if(!K($))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);let Z=J($)??{version:"latest",versions:{}};switch(W){case"version":Z.version=X;break;case"service":Z.service=X;break;case"autoStart":Z.autoStart=X==="true";break;default:console.error(`Unknown config key: ${W}`),console.error("Valid keys: version, service, autoStart"),process.exit(1)}M($,Z),console.log(`Updated ${$}.${W} = ${X}`)}async function s0(Y){if(Y.length===0)console.error("Usage: pkg-ops verify <package>"),process.exit(1);let $=Y[0];if(!K($))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);console.log(`Verifying ${$}...`);try{let X=await(await U()).verify($);if(console.log(`
|
|
11
|
+
Package: ${X.packageName}@${X.version}`),console.log(` Status: ${X.success?"VALID":"INVALID"}`),console.log(` Dist exists: ${X.distExists?"Yes":"No"}`),X.checksum)console.log(` Checksum: ${X.checksum}`);console.log(` Message: ${X.message}`)}catch(W){console.error("Verification failed:",W),process.exit(1)}finally{await O()}}async function r0(Y){let $=Y.indexOf("--local"),W=Y.indexOf("--local-path"),X="./package.json";if(W>=0&&Y[W+1])X=Y[W+1];let Z=$>=0||W>=0;try{let Q=await(await U()).getInstalledInfo();if(console.log(`Sync Status: Local vs VPS
|
|
12
|
+
`),Z&&m0(X)){let H=l0(X,"utf-8"),w=JSON.parse(H),y={...w.dependencies,...w.devDependencies},x=new Map;for(let E of Q)x.set(E.packageName,E.version);for(let[E,V]of Object.entries(y)){if(!E.startsWith("@ebowwa/"))continue;let F=x.get(E),A=V.replace(/^[\^~]/,"");if(F){if(A===F)console.log(` ${E}: local=${A}, vps=${F} (in sync)`);else if(A>F)console.log(` ${E}: local=${A}, vps=${F} (VPS behind)`);else console.log(` ${E}: local=${A}, vps=${F} (local behind)`);x.delete(E)}else console.log(` ${E}: local=${A}, vps=not installed`)}for(let[E,V]of x)console.log(` ${E}: local=not in package.json, vps=${V}`)}else if(Q.length===0)console.log(" No packages installed on VPS");else for(let H of Q){let w=H.distSizeBytes?` (${(H.distSizeBytes/1024).toFixed(1)} KB)`:"";console.log(` ${H.packageName}@${H.version}${w}`)}}catch(q){console.error("Failed to get sync status:",q),process.exit(1)}finally{await O()}}async function T0(Y){console.log(`Running vulnerability scan...
|
|
13
13
|
`);try{let W=await(await U()).audit();if(W.length===0){console.log("No vulnerabilities found.");return}console.log(`Found ${W.length} vulnerability(es):
|
|
14
|
-
`);for(let X of W)console.log(`[${X.severity.toUpperCase()}] ${X.packageName}`),console.log(` Vulnerability: ${X.vulnerability}`),console.log(` Description: ${X.description}`),console.log("")}catch(
|
|
15
|
-
`);try{let W=await(await U()).getBundleSizes();if(W.length===0){console.log(" No packages installed");return}console.log(" Package | Version | Dist Size"),console.log(" --------------------------------|----------|-----------");for(let X of W){let Z=X.packageName.padEnd(32),q=X.version.padEnd(9),Q=(X.distSizeBytes/1024).toFixed(1)+" KB",H=X.fileCount?` (${X.fileCount} files)`:"";console.log(` ${Z} | ${q} | ${Q}${H}`)}}catch(
|
|
16
|
-
`);let Z=[...X].sort((q,Q)=>Q.installedAt.localeCompare(q.installedAt));for(let q of Z){let Q=q.active?" [ACTIVE]":"",H=q.distSizeBytes?` (${(q.distSizeBytes/1024).toFixed(1)} KB)`:"",
|
|
17
|
-
Total: ${X.length} version(s)`)}catch(W){console.error("Failed to list versions:",W),process.exit(1)}finally{await
|
|
18
|
-
`);for(let X of W)console.log(` ${X.packageName}:`),console.log(` Active: ${X.activeVersion}`),console.log(` Total: ${X.totalVersions} version(s)`),console.log(` Versions: ${X.versions.join(", ")}`),console.log("")}catch(
|
|
14
|
+
`);for(let X of W)console.log(`[${X.severity.toUpperCase()}] ${X.packageName}`),console.log(` Vulnerability: ${X.vulnerability}`),console.log(` Description: ${X.description}`),console.log("")}catch($){console.error("Audit failed:",$),process.exit(1)}finally{await O()}}async function a0(Y){await T0(Y)}async function e0(Y){console.log(`Bundle sizes:
|
|
15
|
+
`);try{let W=await(await U()).getBundleSizes();if(W.length===0){console.log(" No packages installed");return}console.log(" Package | Version | Dist Size"),console.log(" --------------------------------|----------|-----------");for(let X of W){let Z=X.packageName.padEnd(32),q=X.version.padEnd(9),Q=(X.distSizeBytes/1024).toFixed(1)+" KB",H=X.fileCount?` (${X.fileCount} files)`:"";console.log(` ${Z} | ${q} | ${Q}${H}`)}}catch($){console.error("Failed to get bundle sizes:",$),process.exit(1)}finally{await O()}}async function Y1(Y){if(Y.length===0)console.error("Usage: pkg-ops versions <package>"),process.exit(1);let $=Y[0];if(!K($))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);try{let X=await(await U()).listVersions($);if(await O(),X.length===0){console.log(`No versions of ${$} installed.`);return}console.log(`Installed versions for ${$}:
|
|
16
|
+
`);let Z=[...X].sort((q,Q)=>Q.installedAt.localeCompare(q.installedAt));for(let q of Z){let Q=q.active?" [ACTIVE]":"",H=q.distSizeBytes?` (${(q.distSizeBytes/1024).toFixed(1)} KB)`:"",w=new Date(q.installedAt).toLocaleString();if(console.log(` ${q.version}${Q}${H}`),console.log(` Installed: ${w}`),q.fileCount)console.log(` Files: ${q.fileCount}`)}console.log(`
|
|
17
|
+
Total: ${X.length} version(s)`)}catch(W){console.error("Failed to list versions:",W),process.exit(1)}finally{await O()}}async function $1(Y){if(Y.length===0)console.error("Usage: pkg-ops switch <package>@<version>"),process.exit(1);let $=Y[0],{name:W,version:X}=D($);if(!K(W))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);if(!X||X==="latest")console.error("Error: Must specify a version to switch to (e.g., @ebowwa/stack@0.7.12)"),process.exit(1);console.log(`Switching ${W} to version ${X}...`);try{let q=await(await U()).switchVersion(W,X);if(q.success){console.log(`Switched ${W} from ${q.fromVersion} to ${q.toVersion}`);let Q=T(),H=J(W);if(H?.service){if((await Q.status(H.service)).active)await Q.restart(H.service),console.log(` Service ${H.service} restarted`)}}else console.error(`Switch failed: ${q.message}`),process.exit(1)}catch(Z){console.error("Switch failed:",Z),process.exit(1)}finally{await O()}}async function W1(Y){if(Y.length===0)console.error("Usage: pkg-ops prune <package> [--keep N]"),process.exit(1);let $=Y[0],W=Y.indexOf("--keep"),X=W>=0&&Y[W+1]?parseInt(Y[W+1],10):2;if(!K($))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);console.log(`Pruning ${$}, keeping ${X} most recent version(s)...`);try{let q=await(await U()).pruneVersions($,X);if(await O(),q.success)if(q.removedVersions.length===0)console.log(`No versions to remove (only ${q.keptVersions.length} installed).`);else{console.log(`Removed ${q.removedVersions.length} version(s):`);for(let Q of q.removedVersions)console.log(` - ${Q}`);console.log(`Freed: ${(q.freedBytes/1024).toFixed(1)} KB`),console.log(`Kept: ${q.keptVersions.join(", ")}`)}else console.error(`Prune failed: ${q.message}`),process.exit(1)}catch(Z){console.error("Prune failed:",Z),process.exit(1)}finally{await O()}}async function X1(Y){if(Y.length===0)console.error("Usage: pkg-ops remove-version <package>@<version>"),process.exit(1);let $=Y[0],{name:W,version:X}=D($);if(!K(W))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);if(!X||X==="latest")console.error("Error: Must specify a version to remove (e.g., @ebowwa/stack@0.7.12)"),process.exit(1);if(J(W)?.version===X)console.error(`Error: Cannot remove active version ${X}. Switch to another version first.`),process.exit(1);console.log(`Removing ${W}@${X}...`);try{let Q=await(await U()).removeVersion(W,X);if(await O(),Q.success)console.log(`Removed ${W}@${X}`);else console.error(`Remove failed: ${Q.message}`),process.exit(1)}catch(q){console.error("Remove failed:",q),process.exit(1)}finally{await O()}}async function Z1(Y){try{let W=await(await U()).getMultiVersionPackages();if(await O(),W.length===0){console.log("No packages with multiple versions installed.");return}console.log(`Packages with multiple versions:
|
|
18
|
+
`);for(let X of W)console.log(` ${X.packageName}:`),console.log(` Active: ${X.activeVersion}`),console.log(` Total: ${X.totalVersions} version(s)`),console.log(` Versions: ${X.versions.join(", ")}`),console.log("")}catch($){console.error("Failed to list multi-version packages:",$),process.exit(1)}finally{await O()}}var q1=[{name:"install",description:"Install an @ebowwa/* package",usage:"pkg-ops install <package>[@version]",handler:c0},{name:"update",description:"Update a package to latest version",usage:"pkg-ops update <package>",handler:o0},{name:"update-all",description:"Update all managed packages",usage:"pkg-ops update-all",handler:t0},{name:"list",description:"List installed packages",usage:"pkg-ops list",handler:i0},{name:"rollback",description:"Rollback a package to previous version",usage:"pkg-ops rollback <package>",handler:n0},{name:"versions",description:"List all installed versions of a package",usage:"pkg-ops versions <package>",handler:Y1},{name:"switch",description:"Switch to a specific installed version",usage:"pkg-ops switch <package>@<version>",handler:$1},{name:"prune",description:"Remove old versions, keeping N most recent",usage:"pkg-ops prune <package> [--keep N]",handler:W1},{name:"remove-version",description:"Remove a specific version",usage:"pkg-ops remove-version <package>@<version>",handler:X1},{name:"multi",description:"List packages with multiple versions",usage:"pkg-ops multi",handler:Z1},{name:"start",description:"Start a systemd service",usage:"pkg-ops service start <name>",handler:X0},{name:"stop",description:"Stop a systemd service",usage:"pkg-ops service stop <name>",handler:Z0},{name:"restart",description:"Restart a systemd service",usage:"pkg-ops service restart <name>",handler:q0},{name:"status",description:"Get service status",usage:"pkg-ops service status <name>",handler:Q0},{name:"logs",description:"View service logs",usage:"pkg-ops service logs <name> [--lines N]",handler:H0},{name:"enable",description:"Enable service on boot",usage:"pkg-ops service enable <name>",handler:O0},{name:"disable",description:"Disable service from boot",usage:"pkg-ops service disable <name>",handler:_0},{name:"health",description:"Check health of all services",usage:"pkg-ops health [service]",handler:g0},{name:"config",description:"Show configuration",usage:"pkg-ops config show",handler:w0},{name:"set-config",description:"Set a config value",usage:"pkg-ops config set <package> <key> <value>",handler:E0},{name:"verify",description:"Verify package integrity",usage:"pkg-ops verify <package>",handler:s0},{name:"sync-status",description:"Show local vs VPS version sync",usage:"pkg-ops sync-status [--local-path path]",handler:r0},{name:"audit",description:"Check for vulnerabilities",usage:"pkg-ops audit",handler:T0},{name:"scan",description:"Alias for audit",usage:"pkg-ops scan",handler:a0},{name:"sizes",description:"Show bundle sizes",usage:"pkg-ops sizes",handler:e0}],Q1=[{name:"start",description:"Start a systemd service",usage:"pkg-ops service start <name>",handler:X0},{name:"stop",description:"Stop a systemd service",usage:"pkg-ops service stop <name>",handler:Z0},{name:"restart",description:"Restart a systemd service",usage:"pkg-ops service restart <name>",handler:q0},{name:"status",description:"Get service status",usage:"pkg-ops service status <name>",handler:Q0},{name:"logs",description:"View service logs",usage:"pkg-ops service logs <name> [--lines N]",handler:H0},{name:"enable",description:"Enable service on boot",usage:"pkg-ops service enable <name>",handler:O0},{name:"disable",description:"Disable service from boot",usage:"pkg-ops service disable <name>",handler:_0}],H1=[{name:"show",description:"Show configuration",usage:"pkg-ops config show",handler:w0},{name:"set",description:"Set a config value",usage:"pkg-ops config set <package> <key> <value>",handler:E0}];function O1(){console.log(`
|
|
19
19
|
PkgOps - Package operations CLI for VPS
|
|
20
20
|
|
|
21
21
|
Usage:
|
|
@@ -69,7 +69,7 @@ Examples:
|
|
|
69
69
|
pkg-ops sync-status --local-path ./package.json
|
|
70
70
|
pkg-ops verify @ebowwa/stack
|
|
71
71
|
pkg-ops audit
|
|
72
|
-
`)}async function
|
|
72
|
+
`)}async function _1(){let Y=process.argv.slice(2);if(Y.length===0||Y[0]==="--help"||Y[0]==="-h")O1(),process.exit(0);if(Y[0]==="--version"||Y[0]==="-v"){let Z=_();console.log(`pkg-ops ${Z.packages?.["@ebowwa/pkg-ops"]?.version??"0.1.0"}`),process.exit(0)}let $=Y[0],W=Y.slice(1);if($==="service"){if(W.length===0)console.error("Missing service subcommand"),console.error("Usage: pkg-ops service <start|stop|restart|status|logs|enable|disable> <name>"),process.exit(1);let Z=W[0],q=Q1.find((Q)=>Q.name===Z);if(!q)console.error(`Unknown service subcommand: ${Z}`),process.exit(1);await q.handler(W.slice(1));return}if($==="config"){if(W.length===0)console.error("Missing config subcommand"),console.error("Usage: pkg-ops config <show|set> [args...]"),process.exit(1);let Z=W[0],q=H1.find((Q)=>Q.name===Z);if(!q)console.error(`Unknown config subcommand: ${Z}`),process.exit(1);await q.handler(W.slice(1));return}let X=q1.find((Z)=>Z.name===$);if(!X)console.error(`Unknown command: ${$}`),console.error("Run 'pkg-ops --help' for usage"),process.exit(1);await X.handler(W)}var w1=process.argv[1]?.includes("pkg-ops");if(w1)_1().catch((Y)=>{console.error("Fatal error:",Y),process.exit(1)});export{M as updatePackageConfig,j0 as stopHealthServer,O as stopBridge,p0 as startHealthServer,U as startBridge,G0 as setActiveVersion,b as saveConfig,b0 as removePackageVersion,R0 as removePackageConfig,D as parsePackageSpec,_ as loadConfig,z as listManagedPackages,x0 as isVersionInstalled,K as isValidPackageName,M0 as getVersionCount,T as getServiceManager,D0 as getPackagesWithMultipleVersions,J as getPackageConfig,y0 as getInstalledVersions,v as getHealthServer,S as getConfigPath,W0 as getBridge,V0 as getActiveVersion,p as ensureConfigDir,I0 as addPackageVersion,f as ServiceManager,u as RustBridge,k as HealthServer};
|
|
73
73
|
|
|
74
|
-
//# debugId=
|
|
74
|
+
//# debugId=94261EB445BE021464756E2164756E21
|
|
75
75
|
//# sourceMappingURL=index.js.map
|