virtualizorjs 2.2.2 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,10 +1,4 @@
1
- "use strict";const h$1=require("node:http"),m=require("node:https");function _interopDefaultCompat(s){return s&&typeof s=="object"&&"default"in s?s.default:s}const h__default=_interopDefaultCompat(h$1),m__default=_interopDefaultCompat(m),DEFAULT_CONFIG={port:4085,https:!0,rejectUnauthorized:!1,timeout:3e4,debug:!1},DEFAULT_TASK_POLLING={pollIntervalMs:2e3,timeoutMs:12e4};class VirtualizorApiError extends Error{code;details;constructor(e,r,u){super(e),this.name="VirtualizorApiError",this.code=r,this.details=u}format(){return`[API Error ${this.code}] ${this.message}`}}function buildQueryString(s,e,r){const u={};for(const[d,p]of Object.entries(s))p!==void 0&&(u[d]=p);const i=new URLSearchParams;i.set("api","json"),i.set("adminapikey",e),i.set("adminapipass",r);for(const[d,p]of Object.entries(u))i.set(d,String(p));return`?${i.toString()}`}const f=5e3;class HttpClient{constructor(e){this.config=e;const r=e.https?m__default.Agent:h__default.Agent;this.agent=new r({keepAlive:!0,maxSockets:50,maxFreeSockets:10,scheduling:"lifo",...e.https?{rejectUnauthorized:e.rejectUnauthorized}:{}}),this.logger=e.logger}agent;logger;parseResponse(e){if(e.error&&e.error.length>0){const r=e.error[0];if(r)throw new VirtualizorApiError(r.msg,r.code)}return e}async request(e,r={},u={}){const i={act:e,...r},d=buildQueryString(i,this.config.apiKey,this.config.apiPass);if(this.config.debug){const g=d.replace(/adminapikey=[^&]*/,"adminapikey=[REDACTED]").replace(/adminapipass=[^&]*/,"adminapipass=[REDACTED]");this.logger.debug(`Request: act=${e} path=/index.php${g}`)}const p=`/index.php${d}`,v=Object.entries(u).filter(([,g])=>g!==void 0).map(([g,b])=>`${encodeURIComponent(g)}=${encodeURIComponent(String(b))}`).join("&");try{const g=await this.rawRequest(p,v||void 0);return this.parseResponse(g)}catch(g){throw this.config.debug&&(g instanceof VirtualizorApiError?this.logger.error(`[Virtualizor] \u25CF Error: [API Error ${g.code}] ${g.message}`):this.logger.error(`[Virtualizor] \u25CF Error: ${g.message}`)),g}}validateJsonDepth(e,r=0){if(r>100)throw new VirtualizorApiError("JSON depth limit exceeded",-32e3);if(typeof e=="object"&&e!==null)if(Array.isArray(e))for(const u of e)this.validateJsonDepth(u,r+1);else for(const u of Object.values(e))this.validateJsonDepth(u,r+1)}destroy(){this.agent.destroy()}rawRequest(e,r){const u=this.config.https?m__default:h__default,i={host:this.config.host,port:this.config.port,path:e,method:r?"POST":"GET",headers:{"Content-Type":"application/x-www-form-urlencoded",...r?{"Content-Length":Buffer.byteLength(r)}:{}},agent:this.agent};return new Promise((d,p)=>{const v=u.request(i,y=>{const E=[];y.on("data",$=>{E.push($)}),y.on("end",()=>{const $=Buffer.concat(E).toString("utf8");if(y.statusCode===302||y.statusCode===301){p(new VirtualizorApiError(`Redirect detected (status ${y.statusCode}). Authentication failed. Location: ${y.headers.location}`,y.statusCode));return}try{const w=JSON.parse($);this.validateJsonDepth(w),d(w)}catch(w){this.config.debug&&(w instanceof VirtualizorApiError?this.logger.error(`[Virtualizor] \u25CF Error: [API Error ${w.code}] ${w.message}`):this.logger.error(`[Virtualizor] \u25CF Error: ${w.message}`)),p(new VirtualizorApiError(`Failed to parse response: ${w.message??"Invalid JSON"}`,-32700))}}),y.on("error",$=>{this.config.debug&&this.logger.error("[Virtualizor] \u25CF Error: Response stream error",$),p(new VirtualizorApiError(`Response stream error: ${$.message??"Unknown error"}`,-32e3))})}),g=setTimeout(()=>{v.destroy(new VirtualizorApiError(`Connection timeout after ${f}ms`,-32e3))},f),b=setTimeout(()=>{v.destroy(new VirtualizorApiError(`Request timed out after ${this.config.timeout}ms`,-32e3))},this.config.timeout);v.once("socket",y=>{y.connecting?y.once("connect",()=>clearTimeout(g)):clearTimeout(g)}),v.once("close",()=>{clearTimeout(g),clearTimeout(b)}),v.on("error",y=>{y instanceof VirtualizorApiError?p(y):p(new VirtualizorApiError(`Request error ${y}`,-32e3))}),r&&v.write(r),v.end()})}}const n$1=process.platform==="win32",o=process.env.NO_COLOR===void 0&&process.stdout.isTTY;function t(s,e){return o?`\x1B[${s}m${e}\x1B[0m`:e}const colors={red:s=>t(31,s),green:s=>t(32,s),yellow:s=>t(33,s),blue:s=>t(34,s),magenta:s=>t(35,s),cyan:s=>t(36,s),white:s=>t(37,s),gray:s=>t(90,s),dim:s=>t(2,s),bold:s=>t(1,s),underline:s=>t(4,s),bgRed:s=>t(41,s),bgGreen:s=>t(42,s),bgYellow:s=>t(43,s),bgBlue:s=>t(44,s),bgCyan:s=>t(46,s)},symbols={success:n$1?"\u221A":"\u2714",error:n$1?"\xD7":"\u2716",warning:n$1?"\u203C":"\u26A0",info:n$1?"i":"\u2139",bullet:"\u25CF",arrow:"\u2192",chevron:"\u203A",pointer:"\u276F",star:"\u2605"},boxChars={topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:"\u2500",vertical:"\u2502"};class ConsoleLogger{constructor(e="Virtualizor"){this.prefix=e}timestamp(){const e=new Date().toISOString().split("T")[1];return colors.dim(e?e.slice(0,8):"00:00:00")}tag(){return colors.cyan(`[${this.prefix}]`)}debug(e,...r){console.log(this.timestamp(),this.tag(),colors.dim(symbols.bullet),colors.dim(e),...r)}info(e,...r){console.log(this.timestamp(),this.tag(),colors.blue(symbols.info),e,...r)}warn(e,...r){console.log(this.timestamp(),this.tag(),colors.yellow(symbols.warning),colors.yellow(e),...r)}error(e,r){console.error(this.timestamp(),this.tag(),colors.red(symbols.error),colors.red(e)),r?.stack&&console.error(colors.dim(r.stack.split(`
1
+ "use strict";const h$1=require("node:http"),m=require("node:https");function _interopDefaultCompat(o){return o&&typeof o=="object"&&"default"in o?o.default:o}const h__default=_interopDefaultCompat(h$1),m__default=_interopDefaultCompat(m),DEFAULT_CONFIG={port:4085,https:!0,rejectUnauthorized:!1,timeout:3e4,debug:!1},DEFAULT_TASK_POLLING={pollIntervalMs:2e3,timeoutMs:12e4};class VirtualizorApiError extends Error{code;details;constructor(e,r,u){super(e),this.name="VirtualizorApiError",this.code=r,this.details=u}format(){return`[API Error ${this.code}] ${this.message}`}}function buildQueryString(o,e,r){const u={};for(const[d,p]of Object.entries(o))p!==void 0&&(u[d]=p);const l=new URLSearchParams;l.set("api","json"),l.set("adminapikey",e),l.set("adminapipass",r);for(const[d,p]of Object.entries(u))l.set(d,String(p));return`?${l.toString()}`}const f=5e3;class HttpClient{constructor(e){this.config=e;const r=e.https?m__default.Agent:h__default.Agent;this.agent=new r({keepAlive:!0,maxSockets:50,maxFreeSockets:10,scheduling:"lifo",...e.https?{rejectUnauthorized:e.rejectUnauthorized}:{}}),this.logger=e.logger}agent;logger;parseResponse(e){if(e.error&&e.error.length>0){const r=e.error[0];if(r)throw new VirtualizorApiError(r.msg,r.code)}return e}async request(e,r={},u={}){const l={act:e,...r},d=buildQueryString(l,this.config.apiKey,this.config.apiPass);if(this.config.debug){const g=d.replace(/adminapikey=[^&]*/,"adminapikey=[REDACTED]").replace(/adminapipass=[^&]*/,"adminapipass=[REDACTED]");this.logger.debug(`Request: act=${e} path=/index.php${g}`)}const p=`/index.php${d}`,y=Object.entries(u).filter(([,g])=>g!==void 0).map(([g,b])=>`${encodeURIComponent(g)}=${encodeURIComponent(String(b))}`).join("&");try{const g=await this.rawRequest(p,y||void 0);return this.parseResponse(g)}catch(g){throw this.config.debug&&(g instanceof VirtualizorApiError?this.logger.error(`[Virtualizor] \u25CF Error: [API Error ${g.code}] ${g.message}`):this.logger.error(`[Virtualizor] \u25CF Error: ${g.message}`)),g}}validateJsonDepth(e,r=0){if(r>100)throw new VirtualizorApiError("JSON depth limit exceeded",-32e3);if(typeof e=="object"&&e!==null)if(Array.isArray(e))for(const u of e)this.validateJsonDepth(u,r+1);else for(const u of Object.values(e))this.validateJsonDepth(u,r+1)}destroy(){this.agent.destroy()}rawRequest(e,r){const u=this.config.https?m__default:h__default,l={host:this.config.host,port:this.config.port,path:e,method:r?"POST":"GET",headers:{"Content-Type":"application/x-www-form-urlencoded",...r?{"Content-Length":Buffer.byteLength(r)}:{}},agent:this.agent};return new Promise((d,p)=>{const y=u.request(l,w=>{const $=[];w.on("data",q=>{$.push(q)}),w.on("end",()=>{const q=Buffer.concat($).toString("utf8");if(w.statusCode===302||w.statusCode===301){p(new VirtualizorApiError(`Redirect detected (status ${w.statusCode}). Authentication failed. Location: ${w.headers.location}`,w.statusCode));return}try{const v=JSON.parse(q);this.validateJsonDepth(v),d(v)}catch(v){this.config.debug&&(v instanceof VirtualizorApiError?this.logger.error(`[Virtualizor] \u25CF Error: [API Error ${v.code}] ${v.message}`):this.logger.error(`[Virtualizor] \u25CF Error: ${v.message}`)),p(new VirtualizorApiError(`Failed to parse response: ${v.message??"Invalid JSON"}`,-32700))}}),w.on("error",q=>{this.config.debug&&this.logger.error("[Virtualizor] \u25CF Error: Response stream error",q),p(new VirtualizorApiError(`Response stream error: ${q.message??"Unknown error"}`,-32e3))})}),g=setTimeout(()=>{y.destroy(new VirtualizorApiError(`Connection timeout after ${f}ms`,-32e3))},f),b=setTimeout(()=>{y.destroy(new VirtualizorApiError(`Request timed out after ${this.config.timeout}ms`,-32e3))},this.config.timeout);y.once("socket",w=>{w.connecting?w.once("connect",()=>clearTimeout(g)):clearTimeout(g)}),y.once("close",()=>{clearTimeout(g),clearTimeout(b)}),y.on("error",w=>{w instanceof VirtualizorApiError?p(w):p(new VirtualizorApiError(`Request error ${w}`,-32e3))}),r&&y.write(r),y.end()})}}const n$1=process.platform==="win32",t=process.env.NO_COLOR===void 0&&process.stdout.isTTY;function s(o,e){return t?`\x1B[${o}m${e}\x1B[0m`:e}const colors={red:o=>s(31,o),green:o=>s(32,o),yellow:o=>s(33,o),blue:o=>s(34,o),cyan:o=>s(36,o),dim:o=>s(2,o)},symbols={success:n$1?"\u221A":"\u2714",error:n$1?"\xD7":"\u2716",warning:n$1?"\u203C":"\u26A0",info:n$1?"i":"\u2139",bullet:"\u25CF",arrow:"\u2192",chevron:"\u203A",pointer:"\u276F",star:"\u2605"};class ConsoleLogger{constructor(e="Virtualizor"){this.prefix=e}timestamp(){const e=new Date().toISOString().split("T")[1];return colors.dim(e?e.slice(0,8):"00:00:00")}tag(){return colors.cyan(`[${this.prefix}]`)}debug(e,...r){console.log(this.timestamp(),this.tag(),colors.dim(symbols.bullet),colors.dim(e),...r)}info(e,...r){console.log(this.timestamp(),this.tag(),colors.blue(symbols.info),e,...r)}warn(e,...r){console.log(this.timestamp(),this.tag(),colors.yellow(symbols.warning),colors.yellow(e),...r)}error(e,r){console.error(this.timestamp(),this.tag(),colors.red(symbols.error),colors.red(e)),r?.stack&&console.error(colors.dim(r.stack.split(`
2
2
  `).slice(1,4).join(`
3
- `)))}success(e,...r){console.log(this.timestamp(),this.tag(),colors.green(symbols.success),colors.green(e),...r)}}const defaultLogger=new ConsoleLogger;function createBox(s,e={}){const{padding:r=1,margin:u=0,borderColor:i="cyan"}=e,d=s.split(`
4
- `),p=Math.max(...d.map(w=>w.length))+r*2,v=colors[i]??colors.cyan,g=boxChars.horizontal.repeat(p),b=`${boxChars.topLeft}${g}${boxChars.topRight}`,y=`${boxChars.bottomLeft}${g}${boxChars.bottomRight}`,E=d.map(w=>{const A=" ".repeat(r)+w+" ".repeat(r);return`${boxChars.vertical}${A.padEnd(p)}${boxChars.vertical}`}),$=[v(b),...E.map(w=>v(w)),v(y)].join(`
5
- `);if(u>0){const w=" ".repeat(u);return $.split(`
6
- `).map(A=>w+A).join(`
7
- `)}return $}function createUpdateBox(s,e){const r=["\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557","\u2551 \u{1F680} UPDATE AVAILABLE \u{1F680} \u2551","\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563","\u2551 \u2551",`\u2551 Current version: ${s.padEnd(18)} \u2551`,`\u2551 Latest version: ${e.padEnd(17)} \u2551`,"\u2551 \u2551","\u2551 To update, run: \u2551","\u2551 npm install virtualizorjs@latest \u2551","\u2551 \u2551","\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"].join(`
8
- `);return colors.yellow(r)}function createErrorBox(s,e,r){const u=["\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557","\u2551 \u274C ERROR OCCURRED \u274C \u2551","\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563","\u2551 \u2551",`\u2551 ${s.padEnd(34)}\u2551`,"\u2551 \u2551",`\u2551 ${e.padEnd(34)}\u2551`,"\u2551 \u2551",r?`\u2551 \u{1F4A1} ${r.padEnd(29)}\u2551`:"",r?"\u2551 \u2551":"","\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"].filter(i=>i!==void 0).join(`
9
- `);return colors.red(u)}function formatError(s,e=!1){if(s instanceof VirtualizorApiError){const r=s.details&&e?`
10
- ${colors.dim(JSON.stringify(s.details,null,2))}`:"";return`${symbols.error} ${colors.red(`[API Error ${s.code}]`)} ${s.message}${r}`}return`${symbols.error} ${colors.red(s.message)}`}class PlansResource{constructor(e){this.http=e}async list(){return(await this.http.request("plans",{},{})).plans}async create(e){return this.http.request("addplan",{},e)}async delete(e){return this.http.request("plans",{},{delete:e})}}class TasksResource{constructor(e){this.http=e}async get(e){return(await this.http.request("tasks",{taskid:e},{})).tasks[e]}async wait(e,r={}){const{pollIntervalMs:u=DEFAULT_TASK_POLLING.pollIntervalMs,timeoutMs:i=DEFAULT_TASK_POLLING.timeoutMs}=r,d=Date.now()+i;for(;Date.now()<d;){const p=await this.get(e);if(!p)throw new VirtualizorApiError("Task not found",404);if(p.status==="1"||p.status==="done")return p;if(p.status==="error"||p.status==="-1")throw new VirtualizorApiError("Task failed",500);await new Promise(v=>setTimeout(v,u))}throw new VirtualizorApiError(`Task timed out after ${i}ms`,408)}}class UsersResource{constructor(e){this.http=e}async list(){return(await this.http.request("users",{},{})).users}async create(e){return this.http.request("adduser",{},e)}async delete(e){return this.http.request("users",{},{delete:e})}async suspend(e){return this.http.request("users",{},{suspend:e})}async unsuspend(e){return this.http.request("users",{},{unsuspend:e})}}const VPS_CONSTANTS={REBUILD_REOS_FLAG:1,MIGRATE_FLAG:1,MIGRATE_BUT_FLAG:1};class VpsResource{constructor(e){this.http=e}async list(e={}){return(await this.http.request("vs",{},e)).vs??{}}async get(e){const r=await this.http.request("vs",{},e),u=Object.entries(r.vs??{});if(u.length===0)throw new VirtualizorApiError("VPS not found",404);const i=u[0];if(!i)throw new VirtualizorApiError("VPS not found",404);const[,d]=i;return d}async create(e){return this.http.request("addvs",{},e)}async delete(e){return this.http.request("vs",{delete:e},{})}async start(e){return this.http.request("vs",{vpsid:e,action:"start"},{})}async stop(e){return this.http.request("vs",{vpsid:e,action:"stop"},{})}async restart(e){return this.http.request("vs",{vpsid:e,action:"restart"},{})}async poweroff(e){return this.http.request("vs",{vpsid:e,action:"poweroff"},{})}async suspend(e){return this.http.request("vs",{suspend:e},{})}async unsuspend(e){return this.http.request("vs",{unsuspend:e},{})}async rebuild(e,r){return this.http.request("rebuild",{},{vpsid:e,reos:VPS_CONSTANTS.REBUILD_REOS_FLAG,...r})}async clone(e,r){return this.http.request("clone",{},{vpsid:e,...r})}async migrate(e,r){return this.http.request("migrate",{},{vpsid:e,migrate:VPS_CONSTANTS.MIGRATE_FLAG,migrate_but:VPS_CONSTANTS.MIGRATE_BUT_FLAG,...r})}async status(e){return this.http.request("vstatus",{vpsid:e},{})}async vnc(e){return this.http.request("vnc",{vpsid:e},{})}async stats(e){return this.http.request("vps_stats",{},{vpsid:e})}}const a="https://registry.npmjs.org/virtualizorjs/latest";async function c(s){const e=new AbortController,r=setTimeout(()=>e.abort(),s);try{const u=await fetch(a,{signal:e.signal});if(!u.ok)throw new Error(`HTTP ${u.status}`);return await u.json()}finally{clearTimeout(r)}}function l(s,e){const r=s.split(".").map(Number),u=e.split(".").map(Number);return(u[0]??0)>(r[0]??0)||(u[0]??0)===(r[0]??0)&&(u[1]??0)>(r[1]??0)||(u[0]??0)===(r[0]??0)&&(u[1]??0)===(r[1]??0)&&(u[2]??0)>(r[2]??0)}let n=!1;async function checkForUpdates(s,e,r){if(!n){n=!0;try{const u=(await c(r?.timeout??2e3)).version;if(!l(s,u))return;e.warn(`Update available: ${s} \u2192 ${u}`),console.log(),console.log(createUpdateBox(s,u)),console.log()}catch{}}}const h=require("../package.json").version;class VirtualizorClient{vps;users;plans;tasks;logger;constructor(e){const r=e.logger??defaultLogger;this.logger=r;const u={host:e.host,apiKey:e.apiKey,apiPass:e.apiPass??"",port:e.port??DEFAULT_CONFIG.port,https:e.https??DEFAULT_CONFIG.https,rejectUnauthorized:e.rejectUnauthorized??DEFAULT_CONFIG.rejectUnauthorized,timeout:e.timeout??DEFAULT_CONFIG.timeout,debug:e.debug??DEFAULT_CONFIG.debug,logger:r,disableUpdateCheck:e.disableUpdateCheck??!1},i=new HttpClient(u);this.vps=new VpsResource(i),this.users=new UsersResource(i),this.plans=new PlansResource(i),this.tasks=new TasksResource(i),u.disableUpdateCheck||checkForUpdates(h,r).catch(()=>{})}}function createVirtualizorClient(s){return new VirtualizorClient(s)}function formatIps(s,e){const r=e?.as??"array",u=e?.separator??", ";if(!s)return r==="array"?[]:"";let i=[];if(Array.isArray(s))i=s.filter(Boolean);else if(typeof s=="string"){const d=s.trim();d===""?i=[]:d.includes(",")?i=d.split(",").map(p=>p.trim()).filter(Boolean):/\s+/.test(d)?i=d.split(/\s+/).map(p=>p.trim()).filter(Boolean):i=[d]}else typeof s=="object"&&(i=Object.values(s).filter(Boolean));return r==="array"?i:i.join(u)}exports.ConsoleLogger=ConsoleLogger;exports.VirtualizorApiError=VirtualizorApiError;exports.VirtualizorClient=VirtualizorClient;exports.colors=colors;exports.createBox=createBox;exports.createErrorBox=createErrorBox;exports.createUpdateBox=createUpdateBox;exports.createVirtualizorClient=createVirtualizorClient;exports.defaultLogger=defaultLogger;exports.formatError=formatError;exports.formatIps=formatIps;exports.symbols=symbols;
3
+ `)))}success(e,...r){console.log(this.timestamp(),this.tag(),colors.green(symbols.success),colors.green(e),...r)}}const defaultLogger=new ConsoleLogger;function formatError(o,e=!1){if(o instanceof VirtualizorApiError){const r=o.details&&e?`
4
+ ${colors.dim(JSON.stringify(o.details,null,2))}`:"";return`${symbols.error} ${colors.red(`[API Error ${o.code}]`)} ${o.message}${r}`}return`${symbols.error} ${colors.red(o.message)}`}class PlansResource{constructor(e){this.http=e}async list(){return(await this.http.request("plans",{},{})).plans}async create(e){return this.http.request("addplan",{},e)}async delete(e){return this.http.request("plans",{},{delete:e})}async get(e){const r=(await this.http.request("plans",{},{})).plans[e];if(!r)throw new VirtualizorApiError("Plan not found",404);return r}async update(e){return this.http.request("editplan",{},e)}}class TasksResource{constructor(e){this.http=e}async get(e){return(await this.http.request("tasks",{taskid:e},{})).tasks[e]}async wait(e,r={}){const{pollIntervalMs:u=DEFAULT_TASK_POLLING.pollIntervalMs,timeoutMs:l=DEFAULT_TASK_POLLING.timeoutMs}=r,d=Date.now()+l;for(;Date.now()<d;){const p=await this.get(e);if(!p)throw new VirtualizorApiError("Task not found",404);if(p.status==="1"||p.status==="done")return p;if(p.status==="error"||p.status==="-1")throw new VirtualizorApiError("Task failed",500);await new Promise(y=>setTimeout(y,u))}throw new VirtualizorApiError(`Task timed out after ${l}ms`,408)}}class UsersResource{constructor(e){this.http=e}async list(){return(await this.http.request("users",{},{})).users}async create(e){return this.http.request("adduser",{},e)}async delete(e){return this.http.request("users",{},{delete:e})}async suspend(e){return this.http.request("users",{},{suspend:e})}async unsuspend(e){return this.http.request("users",{},{unsuspend:e})}async get(e){const r=(await this.http.request("users",{},{uid:e})).user[e];if(!r)throw new VirtualizorApiError("User not found",404);return r}async update(e){return this.http.request("edituser",{},e)}}const VPS_CONSTANTS={REBUILD_REOS_FLAG:1,MIGRATE_FLAG:1,MIGRATE_BUT_FLAG:1};class VpsResource{constructor(e){this.http=e}async list(e={}){return(await this.http.request("vs",{},e)).vs??{}}async get(e){const r=await this.http.request("vs",{},e),u=Object.entries(r.vs??{});if(u.length===0)throw new VirtualizorApiError("VPS not found",404);const l=u[0];if(!l)throw new VirtualizorApiError("VPS not found",404);const[,d]=l;return d}async create(e){return this.http.request("addvs",{},e)}async delete(e){return this.http.request("vs",{delete:e},{})}async start(e){return this.http.request("vs",{vpsid:e,action:"start"},{})}async stop(e){return this.http.request("vs",{vpsid:e,action:"stop"},{})}async restart(e){return this.http.request("vs",{vpsid:e,action:"restart"},{})}async poweroff(e){return this.http.request("vs",{vpsid:e,action:"poweroff"},{})}async suspend(e){return this.http.request("vs",{suspend:e},{})}async unsuspend(e){return this.http.request("vs",{unsuspend:e},{})}async rebuild(e,r){return this.http.request("rebuild",{},{vpsid:e,reos:VPS_CONSTANTS.REBUILD_REOS_FLAG,...r})}async clone(e,r){return this.http.request("clone",{},{vpsid:e,...r})}async migrate(e,r){return this.http.request("migrate",{},{vpsid:e,migrate:VPS_CONSTANTS.MIGRATE_FLAG,migrate_but:VPS_CONSTANTS.MIGRATE_BUT_FLAG,...r})}async status(e){return this.http.request("vstatus",{vpsid:e},{})}async vnc(e){return this.http.request("vnc",{vpsid:e},{})}async stats(e){return this.http.request("vps_stats",{},{vpsid:e})}}const i="https://registry.npmjs.org/virtualizorjs/latest";async function a(o){const e=new AbortController,r=setTimeout(()=>e.abort(),o);try{const u=await fetch(i,{signal:e.signal});if(!u.ok)throw new Error(`HTTP ${u.status}`);return await u.json()}finally{clearTimeout(r)}}function c(o,e){const r=o.split(".").map(Number),u=e.split(".").map(Number);return(u[0]??0)>(r[0]??0)||(u[0]??0)===(r[0]??0)&&(u[1]??0)>(r[1]??0)||(u[0]??0)===(r[0]??0)&&(u[1]??0)===(r[1]??0)&&(u[2]??0)>(r[2]??0)}let n=!1;async function checkForUpdates(o,e,r){if(!n){n=!0;try{const u=(await a(r?.timeout??2e3)).version;if(!c(o,u))return;e.warn(`Update available: ${o} \u2192 ${u}`),e.warn('Run "npm install virtualizorjs@latest" to update')}catch{}}}const h=require("../package.json").version;class VirtualizorClient{vps;users;plans;tasks;logger;constructor(e){const r=e.logger??defaultLogger;this.logger=r;const u={host:e.host,apiKey:e.apiKey,apiPass:e.apiPass??"",port:e.port??DEFAULT_CONFIG.port,https:e.https??DEFAULT_CONFIG.https,rejectUnauthorized:e.rejectUnauthorized??DEFAULT_CONFIG.rejectUnauthorized,timeout:e.timeout??DEFAULT_CONFIG.timeout,debug:e.debug??DEFAULT_CONFIG.debug,logger:r,disableUpdateCheck:e.disableUpdateCheck??!1},l=new HttpClient(u);this.vps=new VpsResource(l),this.users=new UsersResource(l),this.plans=new PlansResource(l),this.tasks=new TasksResource(l),u.disableUpdateCheck||checkForUpdates(h,r).catch(()=>{})}}function createVirtualizorClient(o){return new VirtualizorClient(o)}function formatIps(o,e){const r=e?.as??"array",u=e?.separator??", ";if(!o)return r==="array"?[]:"";let l=[];if(Array.isArray(o))l=o.filter(Boolean);else if(typeof o=="string"){const d=o.trim();d===""?l=[]:d.includes(",")?l=d.split(",").map(p=>p.trim()).filter(Boolean):/\s+/.test(d)?l=d.split(/\s+/).map(p=>p.trim()).filter(Boolean):l=[d]}else typeof o=="object"&&(l=Object.values(o).filter(Boolean));return r==="array"?l:l.join(u)}exports.ConsoleLogger=ConsoleLogger;exports.VirtualizorApiError=VirtualizorApiError;exports.VirtualizorClient=VirtualizorClient;exports.colors=colors;exports.createVirtualizorClient=createVirtualizorClient;exports.defaultLogger=defaultLogger;exports.formatError=formatError;exports.formatIps=formatIps;exports.symbols=symbols;
package/dist/index.d.cts CHANGED
@@ -26,23 +26,15 @@ declare class ConsoleLogger implements Logger {
26
26
  }
27
27
  declare const defaultLogger: ConsoleLogger;
28
28
 
29
+ declare function formatError(error: Error, verbose?: boolean): string;
30
+
29
31
  declare const colors: {
30
32
  red: (str: string) => string;
31
33
  green: (str: string) => string;
32
34
  yellow: (str: string) => string;
33
35
  blue: (str: string) => string;
34
- magenta: (str: string) => string;
35
36
  cyan: (str: string) => string;
36
- white: (str: string) => string;
37
- gray: (str: string) => string;
38
37
  dim: (str: string) => string;
39
- bold: (str: string) => string;
40
- underline: (str: string) => string;
41
- bgRed: (str: string) => string;
42
- bgGreen: (str: string) => string;
43
- bgYellow: (str: string) => string;
44
- bgBlue: (str: string) => string;
45
- bgCyan: (str: string) => string;
46
38
  };
47
39
  declare const symbols: {
48
40
  success: string;
@@ -56,18 +48,6 @@ declare const symbols: {
56
48
  star: string;
57
49
  };
58
50
 
59
- interface BoxOptions {
60
- title?: string;
61
- borderColor?: 'cyan' | 'yellow' | 'red' | 'green' | 'blue' | 'magenta';
62
- padding?: number;
63
- margin?: number;
64
- }
65
- declare function createBox(content: string, options?: BoxOptions): string;
66
- declare function createUpdateBox(current: string, latest: string): string;
67
- declare function createErrorBox(title: string, message: string, hint?: string): string;
68
-
69
- declare function formatError(error: Error, verbose?: boolean): string;
70
-
71
51
  interface VirtualizorError {
72
52
  code: number;
73
53
  msg: string;
@@ -140,6 +120,16 @@ interface CreatePlanParams {
140
120
  virt?: string;
141
121
  [key: string]: unknown;
142
122
  }
123
+ interface UpdatePlanParams {
124
+ pid: string;
125
+ plan_name?: string;
126
+ disk?: number;
127
+ ram?: number;
128
+ bandwidth?: number;
129
+ cpu?: number;
130
+ virt?: string;
131
+ [key: string]: unknown;
132
+ }
143
133
 
144
134
  declare class PlansResource {
145
135
  private readonly http;
@@ -147,6 +137,8 @@ declare class PlansResource {
147
137
  list(): Promise<Record<string, Plan>>;
148
138
  create(params: CreatePlanParams): Promise<AsyncTaskResult>;
149
139
  delete(planId: string): Promise<AsyncTaskResult>;
140
+ get(planId: string): Promise<Plan>;
141
+ update(params: UpdatePlanParams): Promise<AsyncTaskResult>;
150
142
  }
151
143
 
152
144
  interface Task {
@@ -183,6 +175,16 @@ interface CreateUserParams {
183
175
  acttype?: number;
184
176
  [key: string]: unknown;
185
177
  }
178
+ interface UpdateUserParams {
179
+ uid: string;
180
+ email?: string;
181
+ password?: string;
182
+ fname?: string;
183
+ lname?: string;
184
+ status?: string;
185
+ acttype?: number;
186
+ [key: string]: unknown;
187
+ }
186
188
 
187
189
  declare class UsersResource {
188
190
  private readonly http;
@@ -192,6 +194,8 @@ declare class UsersResource {
192
194
  delete(uid: string): Promise<AsyncTaskResult>;
193
195
  suspend(uid: string): Promise<AsyncTaskResult>;
194
196
  unsuspend(uid: string): Promise<AsyncTaskResult>;
197
+ get(uid: string): Promise<User>;
198
+ update(params: UpdateUserParams): Promise<AsyncTaskResult>;
195
199
  }
196
200
 
197
201
  interface VPSData {
@@ -421,6 +425,26 @@ interface VNCInfo extends VirtualizorResponse {
421
425
  novnc?: string;
422
426
  [key: string]: unknown;
423
427
  }
428
+ interface VPSStatusInfo {
429
+ status: number;
430
+ used_cpu?: string;
431
+ used_ram?: number;
432
+ used_disk?: number;
433
+ net_in?: number;
434
+ net_out?: number;
435
+ used_inode?: string;
436
+ io_read?: number;
437
+ io_write?: number;
438
+ inode?: number;
439
+ ram?: string;
440
+ disk?: string;
441
+ used_bandwidth?: string;
442
+ bandwidth?: string;
443
+ virt?: string;
444
+ }
445
+ interface VPSStatusResponse extends VirtualizorResponse {
446
+ [key: string]: VPSStatusInfo | unknown;
447
+ }
424
448
 
425
449
  declare class VpsResource {
426
450
  private readonly http;
@@ -438,7 +462,7 @@ declare class VpsResource {
438
462
  rebuild(vpsId: string, params: RebuildVPSParams): Promise<AsyncTaskResult>;
439
463
  clone(vpsId: string, params: CloneVPSParams): Promise<AsyncTaskResult>;
440
464
  migrate(vpsId: string, params: MigrateVPSParams): Promise<AsyncTaskResult>;
441
- status(vpsId: string): Promise<unknown>;
465
+ status(vpsId: string): Promise<VPSStatusResponse>;
442
466
  vnc(vpsId: string): Promise<VNCInfo>;
443
467
  stats(vpsId: string): Promise<VPSStatsResponse>;
444
468
  }
@@ -474,5 +498,5 @@ declare function formatIps(ips: IpsInput, options: FormatIpsOptions & {
474
498
  as: 'string';
475
499
  }): string;
476
500
 
477
- export { ConsoleLogger, VirtualizorApiError, VirtualizorClient, colors, createBox, createErrorBox, createUpdateBox, createVirtualizorClient, defaultLogger, formatError, formatIps, symbols };
478
- export type { AsyncTaskResult, CloneVPSParams, CreatePlanParams, CreateUserParams, CreateVPSParams, IpsInput, ListVPSParams, Logger, MigrateVPSParams, Plan, RebuildVPSParams, Task, User, VPS, VirtType, VirtualizorConfig };
501
+ export { ConsoleLogger, VirtualizorApiError, VirtualizorClient, colors, createVirtualizorClient, defaultLogger, formatError, formatIps, symbols };
502
+ export type { AsyncTaskResult, CloneVPSParams, CreatePlanParams, CreateUserParams, CreateVPSParams, IpsInput, ListVPSParams, Logger, MigrateVPSParams, Plan, RebuildVPSParams, Task, UpdatePlanParams, UpdateUserParams, User, VNCInfo, VPS, VPSStatsResponse, VPSStatusInfo, VPSStatusResponse, VirtType, VirtualizorConfig };
package/dist/index.d.mts CHANGED
@@ -26,23 +26,15 @@ declare class ConsoleLogger implements Logger {
26
26
  }
27
27
  declare const defaultLogger: ConsoleLogger;
28
28
 
29
+ declare function formatError(error: Error, verbose?: boolean): string;
30
+
29
31
  declare const colors: {
30
32
  red: (str: string) => string;
31
33
  green: (str: string) => string;
32
34
  yellow: (str: string) => string;
33
35
  blue: (str: string) => string;
34
- magenta: (str: string) => string;
35
36
  cyan: (str: string) => string;
36
- white: (str: string) => string;
37
- gray: (str: string) => string;
38
37
  dim: (str: string) => string;
39
- bold: (str: string) => string;
40
- underline: (str: string) => string;
41
- bgRed: (str: string) => string;
42
- bgGreen: (str: string) => string;
43
- bgYellow: (str: string) => string;
44
- bgBlue: (str: string) => string;
45
- bgCyan: (str: string) => string;
46
38
  };
47
39
  declare const symbols: {
48
40
  success: string;
@@ -56,18 +48,6 @@ declare const symbols: {
56
48
  star: string;
57
49
  };
58
50
 
59
- interface BoxOptions {
60
- title?: string;
61
- borderColor?: 'cyan' | 'yellow' | 'red' | 'green' | 'blue' | 'magenta';
62
- padding?: number;
63
- margin?: number;
64
- }
65
- declare function createBox(content: string, options?: BoxOptions): string;
66
- declare function createUpdateBox(current: string, latest: string): string;
67
- declare function createErrorBox(title: string, message: string, hint?: string): string;
68
-
69
- declare function formatError(error: Error, verbose?: boolean): string;
70
-
71
51
  interface VirtualizorError {
72
52
  code: number;
73
53
  msg: string;
@@ -140,6 +120,16 @@ interface CreatePlanParams {
140
120
  virt?: string;
141
121
  [key: string]: unknown;
142
122
  }
123
+ interface UpdatePlanParams {
124
+ pid: string;
125
+ plan_name?: string;
126
+ disk?: number;
127
+ ram?: number;
128
+ bandwidth?: number;
129
+ cpu?: number;
130
+ virt?: string;
131
+ [key: string]: unknown;
132
+ }
143
133
 
144
134
  declare class PlansResource {
145
135
  private readonly http;
@@ -147,6 +137,8 @@ declare class PlansResource {
147
137
  list(): Promise<Record<string, Plan>>;
148
138
  create(params: CreatePlanParams): Promise<AsyncTaskResult>;
149
139
  delete(planId: string): Promise<AsyncTaskResult>;
140
+ get(planId: string): Promise<Plan>;
141
+ update(params: UpdatePlanParams): Promise<AsyncTaskResult>;
150
142
  }
151
143
 
152
144
  interface Task {
@@ -183,6 +175,16 @@ interface CreateUserParams {
183
175
  acttype?: number;
184
176
  [key: string]: unknown;
185
177
  }
178
+ interface UpdateUserParams {
179
+ uid: string;
180
+ email?: string;
181
+ password?: string;
182
+ fname?: string;
183
+ lname?: string;
184
+ status?: string;
185
+ acttype?: number;
186
+ [key: string]: unknown;
187
+ }
186
188
 
187
189
  declare class UsersResource {
188
190
  private readonly http;
@@ -192,6 +194,8 @@ declare class UsersResource {
192
194
  delete(uid: string): Promise<AsyncTaskResult>;
193
195
  suspend(uid: string): Promise<AsyncTaskResult>;
194
196
  unsuspend(uid: string): Promise<AsyncTaskResult>;
197
+ get(uid: string): Promise<User>;
198
+ update(params: UpdateUserParams): Promise<AsyncTaskResult>;
195
199
  }
196
200
 
197
201
  interface VPSData {
@@ -421,6 +425,26 @@ interface VNCInfo extends VirtualizorResponse {
421
425
  novnc?: string;
422
426
  [key: string]: unknown;
423
427
  }
428
+ interface VPSStatusInfo {
429
+ status: number;
430
+ used_cpu?: string;
431
+ used_ram?: number;
432
+ used_disk?: number;
433
+ net_in?: number;
434
+ net_out?: number;
435
+ used_inode?: string;
436
+ io_read?: number;
437
+ io_write?: number;
438
+ inode?: number;
439
+ ram?: string;
440
+ disk?: string;
441
+ used_bandwidth?: string;
442
+ bandwidth?: string;
443
+ virt?: string;
444
+ }
445
+ interface VPSStatusResponse extends VirtualizorResponse {
446
+ [key: string]: VPSStatusInfo | unknown;
447
+ }
424
448
 
425
449
  declare class VpsResource {
426
450
  private readonly http;
@@ -438,7 +462,7 @@ declare class VpsResource {
438
462
  rebuild(vpsId: string, params: RebuildVPSParams): Promise<AsyncTaskResult>;
439
463
  clone(vpsId: string, params: CloneVPSParams): Promise<AsyncTaskResult>;
440
464
  migrate(vpsId: string, params: MigrateVPSParams): Promise<AsyncTaskResult>;
441
- status(vpsId: string): Promise<unknown>;
465
+ status(vpsId: string): Promise<VPSStatusResponse>;
442
466
  vnc(vpsId: string): Promise<VNCInfo>;
443
467
  stats(vpsId: string): Promise<VPSStatsResponse>;
444
468
  }
@@ -474,5 +498,5 @@ declare function formatIps(ips: IpsInput, options: FormatIpsOptions & {
474
498
  as: 'string';
475
499
  }): string;
476
500
 
477
- export { ConsoleLogger, VirtualizorApiError, VirtualizorClient, colors, createBox, createErrorBox, createUpdateBox, createVirtualizorClient, defaultLogger, formatError, formatIps, symbols };
478
- export type { AsyncTaskResult, CloneVPSParams, CreatePlanParams, CreateUserParams, CreateVPSParams, IpsInput, ListVPSParams, Logger, MigrateVPSParams, Plan, RebuildVPSParams, Task, User, VPS, VirtType, VirtualizorConfig };
501
+ export { ConsoleLogger, VirtualizorApiError, VirtualizorClient, colors, createVirtualizorClient, defaultLogger, formatError, formatIps, symbols };
502
+ export type { AsyncTaskResult, CloneVPSParams, CreatePlanParams, CreateUserParams, CreateVPSParams, IpsInput, ListVPSParams, Logger, MigrateVPSParams, Plan, RebuildVPSParams, Task, UpdatePlanParams, UpdateUserParams, User, VNCInfo, VPS, VPSStatsResponse, VPSStatusInfo, VPSStatusResponse, VirtType, VirtualizorConfig };
package/dist/index.d.ts CHANGED
@@ -26,23 +26,15 @@ declare class ConsoleLogger implements Logger {
26
26
  }
27
27
  declare const defaultLogger: ConsoleLogger;
28
28
 
29
+ declare function formatError(error: Error, verbose?: boolean): string;
30
+
29
31
  declare const colors: {
30
32
  red: (str: string) => string;
31
33
  green: (str: string) => string;
32
34
  yellow: (str: string) => string;
33
35
  blue: (str: string) => string;
34
- magenta: (str: string) => string;
35
36
  cyan: (str: string) => string;
36
- white: (str: string) => string;
37
- gray: (str: string) => string;
38
37
  dim: (str: string) => string;
39
- bold: (str: string) => string;
40
- underline: (str: string) => string;
41
- bgRed: (str: string) => string;
42
- bgGreen: (str: string) => string;
43
- bgYellow: (str: string) => string;
44
- bgBlue: (str: string) => string;
45
- bgCyan: (str: string) => string;
46
38
  };
47
39
  declare const symbols: {
48
40
  success: string;
@@ -56,18 +48,6 @@ declare const symbols: {
56
48
  star: string;
57
49
  };
58
50
 
59
- interface BoxOptions {
60
- title?: string;
61
- borderColor?: 'cyan' | 'yellow' | 'red' | 'green' | 'blue' | 'magenta';
62
- padding?: number;
63
- margin?: number;
64
- }
65
- declare function createBox(content: string, options?: BoxOptions): string;
66
- declare function createUpdateBox(current: string, latest: string): string;
67
- declare function createErrorBox(title: string, message: string, hint?: string): string;
68
-
69
- declare function formatError(error: Error, verbose?: boolean): string;
70
-
71
51
  interface VirtualizorError {
72
52
  code: number;
73
53
  msg: string;
@@ -140,6 +120,16 @@ interface CreatePlanParams {
140
120
  virt?: string;
141
121
  [key: string]: unknown;
142
122
  }
123
+ interface UpdatePlanParams {
124
+ pid: string;
125
+ plan_name?: string;
126
+ disk?: number;
127
+ ram?: number;
128
+ bandwidth?: number;
129
+ cpu?: number;
130
+ virt?: string;
131
+ [key: string]: unknown;
132
+ }
143
133
 
144
134
  declare class PlansResource {
145
135
  private readonly http;
@@ -147,6 +137,8 @@ declare class PlansResource {
147
137
  list(): Promise<Record<string, Plan>>;
148
138
  create(params: CreatePlanParams): Promise<AsyncTaskResult>;
149
139
  delete(planId: string): Promise<AsyncTaskResult>;
140
+ get(planId: string): Promise<Plan>;
141
+ update(params: UpdatePlanParams): Promise<AsyncTaskResult>;
150
142
  }
151
143
 
152
144
  interface Task {
@@ -183,6 +175,16 @@ interface CreateUserParams {
183
175
  acttype?: number;
184
176
  [key: string]: unknown;
185
177
  }
178
+ interface UpdateUserParams {
179
+ uid: string;
180
+ email?: string;
181
+ password?: string;
182
+ fname?: string;
183
+ lname?: string;
184
+ status?: string;
185
+ acttype?: number;
186
+ [key: string]: unknown;
187
+ }
186
188
 
187
189
  declare class UsersResource {
188
190
  private readonly http;
@@ -192,6 +194,8 @@ declare class UsersResource {
192
194
  delete(uid: string): Promise<AsyncTaskResult>;
193
195
  suspend(uid: string): Promise<AsyncTaskResult>;
194
196
  unsuspend(uid: string): Promise<AsyncTaskResult>;
197
+ get(uid: string): Promise<User>;
198
+ update(params: UpdateUserParams): Promise<AsyncTaskResult>;
195
199
  }
196
200
 
197
201
  interface VPSData {
@@ -421,6 +425,26 @@ interface VNCInfo extends VirtualizorResponse {
421
425
  novnc?: string;
422
426
  [key: string]: unknown;
423
427
  }
428
+ interface VPSStatusInfo {
429
+ status: number;
430
+ used_cpu?: string;
431
+ used_ram?: number;
432
+ used_disk?: number;
433
+ net_in?: number;
434
+ net_out?: number;
435
+ used_inode?: string;
436
+ io_read?: number;
437
+ io_write?: number;
438
+ inode?: number;
439
+ ram?: string;
440
+ disk?: string;
441
+ used_bandwidth?: string;
442
+ bandwidth?: string;
443
+ virt?: string;
444
+ }
445
+ interface VPSStatusResponse extends VirtualizorResponse {
446
+ [key: string]: VPSStatusInfo | unknown;
447
+ }
424
448
 
425
449
  declare class VpsResource {
426
450
  private readonly http;
@@ -438,7 +462,7 @@ declare class VpsResource {
438
462
  rebuild(vpsId: string, params: RebuildVPSParams): Promise<AsyncTaskResult>;
439
463
  clone(vpsId: string, params: CloneVPSParams): Promise<AsyncTaskResult>;
440
464
  migrate(vpsId: string, params: MigrateVPSParams): Promise<AsyncTaskResult>;
441
- status(vpsId: string): Promise<unknown>;
465
+ status(vpsId: string): Promise<VPSStatusResponse>;
442
466
  vnc(vpsId: string): Promise<VNCInfo>;
443
467
  stats(vpsId: string): Promise<VPSStatsResponse>;
444
468
  }
@@ -474,5 +498,5 @@ declare function formatIps(ips: IpsInput, options: FormatIpsOptions & {
474
498
  as: 'string';
475
499
  }): string;
476
500
 
477
- export { ConsoleLogger, VirtualizorApiError, VirtualizorClient, colors, createBox, createErrorBox, createUpdateBox, createVirtualizorClient, defaultLogger, formatError, formatIps, symbols };
478
- export type { AsyncTaskResult, CloneVPSParams, CreatePlanParams, CreateUserParams, CreateVPSParams, IpsInput, ListVPSParams, Logger, MigrateVPSParams, Plan, RebuildVPSParams, Task, User, VPS, VirtType, VirtualizorConfig };
501
+ export { ConsoleLogger, VirtualizorApiError, VirtualizorClient, colors, createVirtualizorClient, defaultLogger, formatError, formatIps, symbols };
502
+ export type { AsyncTaskResult, CloneVPSParams, CreatePlanParams, CreateUserParams, CreateVPSParams, IpsInput, ListVPSParams, Logger, MigrateVPSParams, Plan, RebuildVPSParams, Task, UpdatePlanParams, UpdateUserParams, User, VNCInfo, VPS, VPSStatsResponse, VPSStatusInfo, VPSStatusResponse, VirtType, VirtualizorConfig };
package/dist/index.mjs CHANGED
@@ -1,10 +1,4 @@
1
- import E from"node:http";import C from"node:https";const y={port:4085,https:!0,rejectUnauthorized:!1,timeout:3e4,debug:!1},R={pollIntervalMs:2e3,timeoutMs:12e4};class c extends Error{code;details;constructor(t,s,u){super(t),this.name="VirtualizorApiError",this.code=s,this.details=u}format(){return`[API Error ${this.code}] ${this.message}`}}function S(e,t,s){const u={};for(const[n,o]of Object.entries(e))o!==void 0&&(u[n]=o);const r=new URLSearchParams;r.set("api","json"),r.set("adminapikey",t),r.set("adminapipass",s);for(const[n,o]of Object.entries(u))r.set(n,String(o));return`?${r.toString()}`}const T=5e3;class F{constructor(t){this.config=t;const s=t.https?C.Agent:E.Agent;this.agent=new s({keepAlive:!0,maxSockets:50,maxFreeSockets:10,scheduling:"lifo",...t.https?{rejectUnauthorized:t.rejectUnauthorized}:{}}),this.logger=t.logger}agent;logger;parseResponse(t){if(t.error&&t.error.length>0){const s=t.error[0];if(s)throw new c(s.msg,s.code)}return t}async request(t,s={},u={}){const r={act:t,...s},n=S(r,this.config.apiKey,this.config.apiPass);if(this.config.debug){const i=n.replace(/adminapikey=[^&]*/,"adminapikey=[REDACTED]").replace(/adminapipass=[^&]*/,"adminapipass=[REDACTED]");this.logger.debug(`Request: act=${t} path=/index.php${i}`)}const o=`/index.php${n}`,d=Object.entries(u).filter(([,i])=>i!==void 0).map(([i,w])=>`${encodeURIComponent(i)}=${encodeURIComponent(String(w))}`).join("&");try{const i=await this.rawRequest(o,d||void 0);return this.parseResponse(i)}catch(i){throw this.config.debug&&(i instanceof c?this.logger.error(`[Virtualizor] \u25CF Error: [API Error ${i.code}] ${i.message}`):this.logger.error(`[Virtualizor] \u25CF Error: ${i.message}`)),i}}validateJsonDepth(t,s=0){if(s>100)throw new c("JSON depth limit exceeded",-32e3);if(typeof t=="object"&&t!==null)if(Array.isArray(t))for(const u of t)this.validateJsonDepth(u,s+1);else for(const u of Object.values(t))this.validateJsonDepth(u,s+1)}destroy(){this.agent.destroy()}rawRequest(t,s){const u=this.config.https?C:E,r={host:this.config.host,port:this.config.port,path:t,method:s?"POST":"GET",headers:{"Content-Type":"application/x-www-form-urlencoded",...s?{"Content-Length":Buffer.byteLength(s)}:{}},agent:this.agent};return new Promise((n,o)=>{const d=u.request(r,l=>{const v=[];l.on("data",g=>{v.push(g)}),l.on("end",()=>{const g=Buffer.concat(v).toString("utf8");if(l.statusCode===302||l.statusCode===301){o(new c(`Redirect detected (status ${l.statusCode}). Authentication failed. Location: ${l.headers.location}`,l.statusCode));return}try{const p=JSON.parse(g);this.validateJsonDepth(p),n(p)}catch(p){this.config.debug&&(p instanceof c?this.logger.error(`[Virtualizor] \u25CF Error: [API Error ${p.code}] ${p.message}`):this.logger.error(`[Virtualizor] \u25CF Error: ${p.message}`)),o(new c(`Failed to parse response: ${p.message??"Invalid JSON"}`,-32700))}}),l.on("error",g=>{this.config.debug&&this.logger.error("[Virtualizor] \u25CF Error: Response stream error",g),o(new c(`Response stream error: ${g.message??"Unknown error"}`,-32e3))})}),i=setTimeout(()=>{d.destroy(new c(`Connection timeout after ${T}ms`,-32e3))},T),w=setTimeout(()=>{d.destroy(new c(`Request timed out after ${this.config.timeout}ms`,-32e3))},this.config.timeout);d.once("socket",l=>{l.connecting?l.once("connect",()=>clearTimeout(i)):clearTimeout(i)}),d.once("close",()=>{clearTimeout(i),clearTimeout(w)}),d.on("error",l=>{l instanceof c?o(l):o(new c(`Request error ${l}`,-32e3))}),s&&d.write(s),d.end()})}}const $=process.platform==="win32",O=process.env.NO_COLOR===void 0&&process.stdout.isTTY;function h(e,t){return O?`\x1B[${e}m${t}\x1B[0m`:t}const a={red:e=>h(31,e),green:e=>h(32,e),yellow:e=>h(33,e),blue:e=>h(34,e),magenta:e=>h(35,e),cyan:e=>h(36,e),white:e=>h(37,e),gray:e=>h(90,e),dim:e=>h(2,e),bold:e=>h(1,e),underline:e=>h(4,e),bgRed:e=>h(41,e),bgGreen:e=>h(42,e),bgYellow:e=>h(43,e),bgBlue:e=>h(44,e),bgCyan:e=>h(46,e)},m={success:$?"\u221A":"\u2714",error:$?"\xD7":"\u2716",warning:$?"\u203C":"\u26A0",info:$?"i":"\u2139",bullet:"\u25CF",arrow:"\u2192",chevron:"\u203A",pointer:"\u276F",star:"\u2605"},f={topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:"\u2500",vertical:"\u2502"};class j{constructor(t="Virtualizor"){this.prefix=t}timestamp(){const t=new Date().toISOString().split("T")[1];return a.dim(t?t.slice(0,8):"00:00:00")}tag(){return a.cyan(`[${this.prefix}]`)}debug(t,...s){console.log(this.timestamp(),this.tag(),a.dim(m.bullet),a.dim(t),...s)}info(t,...s){console.log(this.timestamp(),this.tag(),a.blue(m.info),t,...s)}warn(t,...s){console.log(this.timestamp(),this.tag(),a.yellow(m.warning),a.yellow(t),...s)}error(t,s){console.error(this.timestamp(),this.tag(),a.red(m.error),a.red(t)),s?.stack&&console.error(a.dim(s.stack.split(`
1
+ import q from"node:http";import b from"node:https";const m={port:4085,https:!0,rejectUnauthorized:!1,timeout:3e4,debug:!1},A={pollIntervalMs:2e3,timeoutMs:12e4};class i extends Error{code;details;constructor(t,e,r){super(t),this.name="VirtualizorApiError",this.code=e,this.details=r}format(){return`[API Error ${this.code}] ${this.message}`}}function j(s,t,e){const r={};for(const[a,o]of Object.entries(s))o!==void 0&&(r[a]=o);const n=new URLSearchParams;n.set("api","json"),n.set("adminapikey",t),n.set("adminapipass",e);for(const[a,o]of Object.entries(r))n.set(a,String(o));return`?${n.toString()}`}const T=5e3;class S{constructor(t){this.config=t;const e=t.https?b.Agent:q.Agent;this.agent=new e({keepAlive:!0,maxSockets:50,maxFreeSockets:10,scheduling:"lifo",...t.https?{rejectUnauthorized:t.rejectUnauthorized}:{}}),this.logger=t.logger}agent;logger;parseResponse(t){if(t.error&&t.error.length>0){const e=t.error[0];if(e)throw new i(e.msg,e.code)}return t}async request(t,e={},r={}){const n={act:t,...e},a=j(n,this.config.apiKey,this.config.apiPass);if(this.config.debug){const u=a.replace(/adminapikey=[^&]*/,"adminapikey=[REDACTED]").replace(/adminapipass=[^&]*/,"adminapipass=[REDACTED]");this.logger.debug(`Request: act=${t} path=/index.php${u}`)}const o=`/index.php${a}`,p=Object.entries(r).filter(([,u])=>u!==void 0).map(([u,y])=>`${encodeURIComponent(u)}=${encodeURIComponent(String(y))}`).join("&");try{const u=await this.rawRequest(o,p||void 0);return this.parseResponse(u)}catch(u){throw this.config.debug&&(u instanceof i?this.logger.error(`[Virtualizor] \u25CF Error: [API Error ${u.code}] ${u.message}`):this.logger.error(`[Virtualizor] \u25CF Error: ${u.message}`)),u}}validateJsonDepth(t,e=0){if(e>100)throw new i("JSON depth limit exceeded",-32e3);if(typeof t=="object"&&t!==null)if(Array.isArray(t))for(const r of t)this.validateJsonDepth(r,e+1);else for(const r of Object.values(t))this.validateJsonDepth(r,e+1)}destroy(){this.agent.destroy()}rawRequest(t,e){const r=this.config.https?b:q,n={host:this.config.host,port:this.config.port,path:t,method:e?"POST":"GET",headers:{"Content-Type":"application/x-www-form-urlencoded",...e?{"Content-Length":Buffer.byteLength(e)}:{}},agent:this.agent};return new Promise((a,o)=>{const p=r.request(n,h=>{const $=[];h.on("data",g=>{$.push(g)}),h.on("end",()=>{const g=Buffer.concat($).toString("utf8");if(h.statusCode===302||h.statusCode===301){o(new i(`Redirect detected (status ${h.statusCode}). Authentication failed. Location: ${h.headers.location}`,h.statusCode));return}try{const l=JSON.parse(g);this.validateJsonDepth(l),a(l)}catch(l){this.config.debug&&(l instanceof i?this.logger.error(`[Virtualizor] \u25CF Error: [API Error ${l.code}] ${l.message}`):this.logger.error(`[Virtualizor] \u25CF Error: ${l.message}`)),o(new i(`Failed to parse response: ${l.message??"Invalid JSON"}`,-32700))}}),h.on("error",g=>{this.config.debug&&this.logger.error("[Virtualizor] \u25CF Error: Response stream error",g),o(new i(`Response stream error: ${g.message??"Unknown error"}`,-32e3))})}),u=setTimeout(()=>{p.destroy(new i(`Connection timeout after ${T}ms`,-32e3))},T),y=setTimeout(()=>{p.destroy(new i(`Request timed out after ${this.config.timeout}ms`,-32e3))},this.config.timeout);p.once("socket",h=>{h.connecting?h.once("connect",()=>clearTimeout(u)):clearTimeout(u)}),p.once("close",()=>{clearTimeout(u),clearTimeout(y)}),p.on("error",h=>{h instanceof i?o(h):o(new i(`Request error ${h}`,-32e3))}),e&&p.write(e),p.end()})}}const w=process.platform==="win32",U=process.env.NO_COLOR===void 0&&process.stdout.isTTY;function f(s,t){return U?`\x1B[${s}m${t}\x1B[0m`:t}const c={red:s=>f(31,s),green:s=>f(32,s),yellow:s=>f(33,s),blue:s=>f(34,s),cyan:s=>f(36,s),dim:s=>f(2,s)},d={success:w?"\u221A":"\u2714",error:w?"\xD7":"\u2716",warning:w?"\u203C":"\u26A0",info:w?"i":"\u2139",bullet:"\u25CF",arrow:"\u2192",chevron:"\u203A",pointer:"\u276F",star:"\u2605"};class E{constructor(t="Virtualizor"){this.prefix=t}timestamp(){const t=new Date().toISOString().split("T")[1];return c.dim(t?t.slice(0,8):"00:00:00")}tag(){return c.cyan(`[${this.prefix}]`)}debug(t,...e){console.log(this.timestamp(),this.tag(),c.dim(d.bullet),c.dim(t),...e)}info(t,...e){console.log(this.timestamp(),this.tag(),c.blue(d.info),t,...e)}warn(t,...e){console.log(this.timestamp(),this.tag(),c.yellow(d.warning),c.yellow(t),...e)}error(t,e){console.error(this.timestamp(),this.tag(),c.red(d.error),c.red(t)),e?.stack&&console.error(c.dim(e.stack.split(`
2
2
  `).slice(1,4).join(`
3
- `)))}success(t,...s){console.log(this.timestamp(),this.tag(),a.green(m.success),a.green(t),...s)}}const L=new j;function I(e,t={}){const{padding:s=1,margin:u=0,borderColor:r="cyan"}=t,n=e.split(`
4
- `),o=Math.max(...n.map(p=>p.length))+s*2,d=a[r]??a.cyan,i=f.horizontal.repeat(o),w=`${f.topLeft}${i}${f.topRight}`,l=`${f.bottomLeft}${i}${f.bottomRight}`,v=n.map(p=>{const b=" ".repeat(s)+p+" ".repeat(s);return`${f.vertical}${b.padEnd(o)}${f.vertical}`}),g=[d(w),...v.map(p=>d(p)),d(l)].join(`
5
- `);if(u>0){const p=" ".repeat(u);return g.split(`
6
- `).map(b=>p+b).join(`
7
- `)}return g}function k(e,t){const s=["\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557","\u2551 \u{1F680} UPDATE AVAILABLE \u{1F680} \u2551","\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563","\u2551 \u2551",`\u2551 Current version: ${e.padEnd(18)} \u2551`,`\u2551 Latest version: ${t.padEnd(17)} \u2551`,"\u2551 \u2551","\u2551 To update, run: \u2551","\u2551 npm install virtualizorjs@latest \u2551","\u2551 \u2551","\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"].join(`
8
- `);return a.yellow(s)}function z(e,t,s){const u=["\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557","\u2551 \u274C ERROR OCCURRED \u274C \u2551","\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563","\u2551 \u2551",`\u2551 ${e.padEnd(34)}\u2551`,"\u2551 \u2551",`\u2551 ${t.padEnd(34)}\u2551`,"\u2551 \u2551",s?`\u2551 \u{1F4A1} ${s.padEnd(29)}\u2551`:"",s?"\u2551 \u2551":"","\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"].filter(r=>r!==void 0).join(`
9
- `);return a.red(u)}function D(e,t=!1){if(e instanceof c){const s=e.details&&t?`
10
- ${a.dim(JSON.stringify(e.details,null,2))}`:"";return`${m.error} ${a.red(`[API Error ${e.code}]`)} ${e.message}${s}`}return`${m.error} ${a.red(e.message)}`}class x{constructor(t){this.http=t}async list(){return(await this.http.request("plans",{},{})).plans}async create(t){return this.http.request("addplan",{},t)}async delete(t){return this.http.request("plans",{},{delete:t})}}class P{constructor(t){this.http=t}async get(t){return(await this.http.request("tasks",{taskid:t},{})).tasks[t]}async wait(t,s={}){const{pollIntervalMs:u=R.pollIntervalMs,timeoutMs:r=R.timeoutMs}=s,n=Date.now()+r;for(;Date.now()<n;){const o=await this.get(t);if(!o)throw new c("Task not found",404);if(o.status==="1"||o.status==="done")return o;if(o.status==="error"||o.status==="-1")throw new c("Task failed",500);await new Promise(d=>setTimeout(d,u))}throw new c(`Task timed out after ${r}ms`,408)}}class B{constructor(t){this.http=t}async list(){return(await this.http.request("users",{},{})).users}async create(t){return this.http.request("adduser",{},t)}async delete(t){return this.http.request("users",{},{delete:t})}async suspend(t){return this.http.request("users",{},{suspend:t})}async unsuspend(t){return this.http.request("users",{},{unsuspend:t})}}const A={REBUILD_REOS_FLAG:1,MIGRATE_FLAG:1,MIGRATE_BUT_FLAG:1};class _{constructor(t){this.http=t}async list(t={}){return(await this.http.request("vs",{},t)).vs??{}}async get(t){const s=await this.http.request("vs",{},t),u=Object.entries(s.vs??{});if(u.length===0)throw new c("VPS not found",404);const r=u[0];if(!r)throw new c("VPS not found",404);const[,n]=r;return n}async create(t){return this.http.request("addvs",{},t)}async delete(t){return this.http.request("vs",{delete:t},{})}async start(t){return this.http.request("vs",{vpsid:t,action:"start"},{})}async stop(t){return this.http.request("vs",{vpsid:t,action:"stop"},{})}async restart(t){return this.http.request("vs",{vpsid:t,action:"restart"},{})}async poweroff(t){return this.http.request("vs",{vpsid:t,action:"poweroff"},{})}async suspend(t){return this.http.request("vs",{suspend:t},{})}async unsuspend(t){return this.http.request("vs",{unsuspend:t},{})}async rebuild(t,s){return this.http.request("rebuild",{},{vpsid:t,reos:A.REBUILD_REOS_FLAG,...s})}async clone(t,s){return this.http.request("clone",{},{vpsid:t,...s})}async migrate(t,s){return this.http.request("migrate",{},{vpsid:t,migrate:A.MIGRATE_FLAG,migrate_but:A.MIGRATE_BUT_FLAG,...s})}async status(t){return this.http.request("vstatus",{vpsid:t},{})}async vnc(t){return this.http.request("vnc",{vpsid:t},{})}async stats(t){return this.http.request("vps_stats",{},{vpsid:t})}}const V="https://registry.npmjs.org/virtualizorjs/latest";async function G(e){const t=new AbortController,s=setTimeout(()=>t.abort(),e);try{const u=await fetch(V,{signal:t.signal});if(!u.ok)throw new Error(`HTTP ${u.status}`);return await u.json()}finally{clearTimeout(s)}}function M(e,t){const s=e.split(".").map(Number),u=t.split(".").map(Number);return(u[0]??0)>(s[0]??0)||(u[0]??0)===(s[0]??0)&&(u[1]??0)>(s[1]??0)||(u[0]??0)===(s[0]??0)&&(u[1]??0)===(s[1]??0)&&(u[2]??0)>(s[2]??0)}let q=!1;async function N(e,t,s){if(!q){q=!0;try{const u=(await G(s?.timeout??2e3)).version;if(!M(e,u))return;t.warn(`Update available: ${e} \u2192 ${u}`),console.log(),console.log(k(e,u)),console.log()}catch{}}}const J=require("../package.json").version;class U{vps;users;plans;tasks;logger;constructor(t){const s=t.logger??L;this.logger=s;const u={host:t.host,apiKey:t.apiKey,apiPass:t.apiPass??"",port:t.port??y.port,https:t.https??y.https,rejectUnauthorized:t.rejectUnauthorized??y.rejectUnauthorized,timeout:t.timeout??y.timeout,debug:t.debug??y.debug,logger:s,disableUpdateCheck:t.disableUpdateCheck??!1},r=new F(u);this.vps=new _(r),this.users=new B(r),this.plans=new x(r),this.tasks=new P(r),u.disableUpdateCheck||N(J,s).catch(()=>{})}}function K(e){return new U(e)}function H(e,t){const s=t?.as??"array",u=t?.separator??", ";if(!e)return s==="array"?[]:"";let r=[];if(Array.isArray(e))r=e.filter(Boolean);else if(typeof e=="string"){const n=e.trim();n===""?r=[]:n.includes(",")?r=n.split(",").map(o=>o.trim()).filter(Boolean):/\s+/.test(n)?r=n.split(/\s+/).map(o=>o.trim()).filter(Boolean):r=[n]}else typeof e=="object"&&(r=Object.values(e).filter(Boolean));return s==="array"?r:r.join(u)}export{j as ConsoleLogger,c as VirtualizorApiError,U as VirtualizorClient,a as colors,I as createBox,z as createErrorBox,k as createUpdateBox,K as createVirtualizorClient,L as defaultLogger,D as formatError,H as formatIps,m as symbols};
3
+ `)))}success(t,...e){console.log(this.timestamp(),this.tag(),c.green(d.success),c.green(t),...e)}}const R=new E;function I(s,t=!1){if(s instanceof i){const e=s.details&&t?`
4
+ ${c.dim(JSON.stringify(s.details,null,2))}`:"";return`${d.error} ${c.red(`[API Error ${s.code}]`)} ${s.message}${e}`}return`${d.error} ${c.red(s.message)}`}class O{constructor(t){this.http=t}async list(){return(await this.http.request("plans",{},{})).plans}async create(t){return this.http.request("addplan",{},t)}async delete(t){return this.http.request("plans",{},{delete:t})}async get(t){const e=(await this.http.request("plans",{},{})).plans[t];if(!e)throw new i("Plan not found",404);return e}async update(t){return this.http.request("editplan",{},t)}}class F{constructor(t){this.http=t}async get(t){return(await this.http.request("tasks",{taskid:t},{})).tasks[t]}async wait(t,e={}){const{pollIntervalMs:r=A.pollIntervalMs,timeoutMs:n=A.timeoutMs}=e,a=Date.now()+n;for(;Date.now()<a;){const o=await this.get(t);if(!o)throw new i("Task not found",404);if(o.status==="1"||o.status==="done")return o;if(o.status==="error"||o.status==="-1")throw new i("Task failed",500);await new Promise(p=>setTimeout(p,r))}throw new i(`Task timed out after ${n}ms`,408)}}class L{constructor(t){this.http=t}async list(){return(await this.http.request("users",{},{})).users}async create(t){return this.http.request("adduser",{},t)}async delete(t){return this.http.request("users",{},{delete:t})}async suspend(t){return this.http.request("users",{},{suspend:t})}async unsuspend(t){return this.http.request("users",{},{unsuspend:t})}async get(t){const e=(await this.http.request("users",{},{uid:t})).user[t];if(!e)throw new i("User not found",404);return e}async update(t){return this.http.request("edituser",{},t)}}const v={REBUILD_REOS_FLAG:1,MIGRATE_FLAG:1,MIGRATE_BUT_FLAG:1};class z{constructor(t){this.http=t}async list(t={}){return(await this.http.request("vs",{},t)).vs??{}}async get(t){const e=await this.http.request("vs",{},t),r=Object.entries(e.vs??{});if(r.length===0)throw new i("VPS not found",404);const n=r[0];if(!n)throw new i("VPS not found",404);const[,a]=n;return a}async create(t){return this.http.request("addvs",{},t)}async delete(t){return this.http.request("vs",{delete:t},{})}async start(t){return this.http.request("vs",{vpsid:t,action:"start"},{})}async stop(t){return this.http.request("vs",{vpsid:t,action:"stop"},{})}async restart(t){return this.http.request("vs",{vpsid:t,action:"restart"},{})}async poweroff(t){return this.http.request("vs",{vpsid:t,action:"poweroff"},{})}async suspend(t){return this.http.request("vs",{suspend:t},{})}async unsuspend(t){return this.http.request("vs",{unsuspend:t},{})}async rebuild(t,e){return this.http.request("rebuild",{},{vpsid:t,reos:v.REBUILD_REOS_FLAG,...e})}async clone(t,e){return this.http.request("clone",{},{vpsid:t,...e})}async migrate(t,e){return this.http.request("migrate",{},{vpsid:t,migrate:v.MIGRATE_FLAG,migrate_but:v.MIGRATE_BUT_FLAG,...e})}async status(t){return this.http.request("vstatus",{vpsid:t},{})}async vnc(t){return this.http.request("vnc",{vpsid:t},{})}async stats(t){return this.http.request("vps_stats",{},{vpsid:t})}}const P="https://registry.npmjs.org/virtualizorjs/latest";async function _(s){const t=new AbortController,e=setTimeout(()=>t.abort(),s);try{const r=await fetch(P,{signal:t.signal});if(!r.ok)throw new Error(`HTTP ${r.status}`);return await r.json()}finally{clearTimeout(e)}}function D(s,t){const e=s.split(".").map(Number),r=t.split(".").map(Number);return(r[0]??0)>(e[0]??0)||(r[0]??0)===(e[0]??0)&&(r[1]??0)>(e[1]??0)||(r[0]??0)===(e[0]??0)&&(r[1]??0)===(e[1]??0)&&(r[2]??0)>(e[2]??0)}let C=!1;async function V(s,t,e){if(!C){C=!0;try{const r=(await _(e?.timeout??2e3)).version;if(!D(s,r))return;t.warn(`Update available: ${s} \u2192 ${r}`),t.warn('Run "npm install virtualizorjs@latest" to update')}catch{}}}const x=require("../package.json").version;class k{vps;users;plans;tasks;logger;constructor(t){const e=t.logger??R;this.logger=e;const r={host:t.host,apiKey:t.apiKey,apiPass:t.apiPass??"",port:t.port??m.port,https:t.https??m.https,rejectUnauthorized:t.rejectUnauthorized??m.rejectUnauthorized,timeout:t.timeout??m.timeout,debug:t.debug??m.debug,logger:e,disableUpdateCheck:t.disableUpdateCheck??!1},n=new S(r);this.vps=new z(n),this.users=new L(n),this.plans=new O(n),this.tasks=new F(n),r.disableUpdateCheck||V(x,e).catch(()=>{})}}function G(s){return new k(s)}function B(s,t){const e=t?.as??"array",r=t?.separator??", ";if(!s)return e==="array"?[]:"";let n=[];if(Array.isArray(s))n=s.filter(Boolean);else if(typeof s=="string"){const a=s.trim();a===""?n=[]:a.includes(",")?n=a.split(",").map(o=>o.trim()).filter(Boolean):/\s+/.test(a)?n=a.split(/\s+/).map(o=>o.trim()).filter(Boolean):n=[a]}else typeof s=="object"&&(n=Object.values(s).filter(Boolean));return e==="array"?n:n.join(r)}export{E as ConsoleLogger,i as VirtualizorApiError,k as VirtualizorClient,c as colors,G as createVirtualizorClient,R as defaultLogger,I as formatError,B as formatIps,d as symbols};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "virtualizorjs",
3
- "version": "2.2.2",
3
+ "version": "2.3.0",
4
4
  "description": "TypeScript SDK for the Virtualizor server management API. Create, start, stop, restart, rebuild, and manage VPS instances with a type-safe, developer-friendly client.",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -19,7 +19,7 @@
19
19
  },
20
20
  "scripts": {
21
21
  "build": "unbuild",
22
- "dev": "unbuild --stub",
22
+ "dev": "unbuild --watch",
23
23
  "test": "bun test",
24
24
  "test:watch": "bun test --watch",
25
25
  "coverage": "bun test --coverage",
@@ -45,18 +45,18 @@
45
45
  },
46
46
  "homepage": "https://github.com/kkMihai/virtualizorjs#readme",
47
47
  "engines": {
48
- "bun": ">=1.3.0"
48
+ "bun": ">=1.3.10"
49
49
  },
50
50
  "devDependencies": {
51
- "@arethetypeswrong/cli": "^0.17.0",
52
- "@biomejs/biome": "^1.9.0",
53
- "@commitlint/cli": "^19.0.0",
54
- "@commitlint/config-conventional": "^19.0.0",
51
+ "@arethetypeswrong/cli": "^0.18.2",
52
+ "@biomejs/biome": "^2.4.7",
53
+ "@commitlint/cli": "^20.5.0",
54
+ "@commitlint/config-conventional": "^20.5.0",
55
55
  "@types/bun": "latest",
56
- "bumpp": "^9.0.0",
57
- "husky": "^9.0.0",
58
- "unbuild": "^3.0.0",
59
- "typescript": "^5.5.0"
56
+ "bumpp": "^11.0.1",
57
+ "husky": "^9.1.7",
58
+ "unbuild": "^3.6.1",
59
+ "typescript": "^5.9.3"
60
60
  },
61
61
  "trustedDependencies": ["@biomejs/biome"]
62
62
  }