virtualizorjs 2.2.1 → 2.2.2

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 ADDED
@@ -0,0 +1,10 @@
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(`
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;
@@ -0,0 +1,478 @@
1
+ declare class VirtualizorApiError extends Error {
2
+ readonly code: number;
3
+ readonly details: Record<string, unknown> | undefined;
4
+ constructor(message: string, code: number, details?: Record<string, unknown>);
5
+ format(): string;
6
+ }
7
+
8
+ interface Logger {
9
+ debug(message: string, ...args: unknown[]): void;
10
+ info(message: string, ...args: unknown[]): void;
11
+ warn(message: string, ...args: unknown[]): void;
12
+ error(message: string, error?: Error): void;
13
+ success?(message: string, ...args: unknown[]): void;
14
+ }
15
+
16
+ declare class ConsoleLogger implements Logger {
17
+ private readonly prefix;
18
+ constructor(prefix?: string);
19
+ private timestamp;
20
+ private tag;
21
+ debug(message: string, ...args: unknown[]): void;
22
+ info(message: string, ...args: unknown[]): void;
23
+ warn(message: string, ...args: unknown[]): void;
24
+ error(message: string, error?: Error): void;
25
+ success(message: string, ...args: unknown[]): void;
26
+ }
27
+ declare const defaultLogger: ConsoleLogger;
28
+
29
+ declare const colors: {
30
+ red: (str: string) => string;
31
+ green: (str: string) => string;
32
+ yellow: (str: string) => string;
33
+ blue: (str: string) => string;
34
+ magenta: (str: string) => string;
35
+ cyan: (str: string) => string;
36
+ white: (str: string) => string;
37
+ gray: (str: string) => string;
38
+ 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
+ };
47
+ declare const symbols: {
48
+ success: string;
49
+ error: string;
50
+ warning: string;
51
+ info: string;
52
+ bullet: string;
53
+ arrow: string;
54
+ chevron: string;
55
+ pointer: string;
56
+ star: string;
57
+ };
58
+
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
+ interface VirtualizorError {
72
+ code: number;
73
+ msg: string;
74
+ }
75
+ interface VirtualizorResponse {
76
+ title?: string;
77
+ timenow?: number;
78
+ time_taken?: string;
79
+ error?: VirtualizorError[];
80
+ }
81
+ interface AsyncTaskResult extends VirtualizorResponse {
82
+ done?: 1;
83
+ taskid?: string;
84
+ }
85
+ type VirtType = 'kvm' | 'xen' | 'openvz' | 'lxc' | 'proxmox' | 'virtuozzo' | 'xcp' | 'hyperv';
86
+ type ApiParams = Record<string, unknown>;
87
+
88
+ interface VirtualizorConfig {
89
+ host: string;
90
+ apiKey: string;
91
+ apiPass?: string;
92
+ port?: number;
93
+ https?: boolean;
94
+ rejectUnauthorized?: boolean;
95
+ timeout?: number;
96
+ debug?: boolean;
97
+ logger?: Logger;
98
+ disableUpdateCheck?: boolean;
99
+ }
100
+ interface ResolvedConfig {
101
+ host: string;
102
+ apiKey: string;
103
+ apiPass: string;
104
+ port: number;
105
+ https: boolean;
106
+ rejectUnauthorized: boolean;
107
+ timeout: number;
108
+ debug: boolean;
109
+ logger: Logger;
110
+ disableUpdateCheck: boolean;
111
+ }
112
+
113
+ declare class HttpClient {
114
+ private readonly config;
115
+ private readonly agent;
116
+ private readonly logger;
117
+ constructor(config: ResolvedConfig);
118
+ parseResponse<T extends VirtualizorResponse>(data: T): T;
119
+ request<T extends VirtualizorResponse>(act: string, queryParams?: ApiParams, bodyParams?: ApiParams): Promise<T>;
120
+ private validateJsonDepth;
121
+ destroy(): void;
122
+ private rawRequest;
123
+ }
124
+
125
+ interface Plan {
126
+ pid: string;
127
+ plan_name: string;
128
+ disk: string;
129
+ ram: string;
130
+ bandwidth: string;
131
+ cpu: string;
132
+ virt?: string;
133
+ }
134
+ interface CreatePlanParams {
135
+ plan_name: string;
136
+ disk: number;
137
+ ram: number;
138
+ bandwidth: number;
139
+ cpu: number;
140
+ virt?: string;
141
+ [key: string]: unknown;
142
+ }
143
+
144
+ declare class PlansResource {
145
+ private readonly http;
146
+ constructor(http: HttpClient);
147
+ list(): Promise<Record<string, Plan>>;
148
+ create(params: CreatePlanParams): Promise<AsyncTaskResult>;
149
+ delete(planId: string): Promise<AsyncTaskResult>;
150
+ }
151
+
152
+ interface Task {
153
+ id: string;
154
+ action: string;
155
+ status: string;
156
+ vpsid?: string;
157
+ data?: unknown;
158
+ }
159
+
160
+ declare class TasksResource {
161
+ private readonly http;
162
+ constructor(http: HttpClient);
163
+ get(taskId: string): Promise<Task | undefined>;
164
+ wait(taskId: string, options?: {
165
+ pollIntervalMs?: number;
166
+ timeoutMs?: number;
167
+ }): Promise<Task>;
168
+ }
169
+
170
+ interface User {
171
+ uid: string;
172
+ email: string;
173
+ fname?: string;
174
+ lname?: string;
175
+ status: string;
176
+ type: string;
177
+ }
178
+ interface CreateUserParams {
179
+ email: string;
180
+ password: string;
181
+ fname?: string;
182
+ lname?: string;
183
+ acttype?: number;
184
+ [key: string]: unknown;
185
+ }
186
+
187
+ declare class UsersResource {
188
+ private readonly http;
189
+ constructor(http: HttpClient);
190
+ list(): Promise<Record<string, User>>;
191
+ create(params: CreateUserParams): Promise<AsyncTaskResult>;
192
+ delete(uid: string): Promise<AsyncTaskResult>;
193
+ suspend(uid: string): Promise<AsyncTaskResult>;
194
+ unsuspend(uid: string): Promise<AsyncTaskResult>;
195
+ }
196
+
197
+ interface VPSData {
198
+ os_type?: number | string;
199
+ rtc?: number | string;
200
+ unprivileged?: number | string;
201
+ vnc_auto_port?: number | string;
202
+ nested_virt?: number | string;
203
+ vga_vram?: number | string;
204
+ discard?: number | string;
205
+ vlan_tag?: number | string;
206
+ enable_guest_agent?: number | string;
207
+ ssd_emulation?: number | string;
208
+ machine_type?: number | string;
209
+ bios?: string;
210
+ enable_tpm?: number | string;
211
+ disable_password?: string;
212
+ ssh_options?: string;
213
+ added_keys?: unknown[];
214
+ io_uring?: number | string;
215
+ min_ram?: number | string;
216
+ vga?: number | string;
217
+ vga_memory?: number | string;
218
+ cpu_flags?: number | string;
219
+ scsi_controller?: number | string;
220
+ demo?: string | null;
221
+ enable_cpu_threshold?: number | string;
222
+ cpu_threshold?: number | string;
223
+ cpu_threshold_time?: number | string;
224
+ disable_guest_agent?: number | string;
225
+ disable_autostart?: number | string;
226
+ iothread?: number | string;
227
+ nesting?: number | string;
228
+ suspended_time?: number | string;
229
+ multiqueue?: number | string;
230
+ freeze_fs_on_backup?: number | string;
231
+ enable_ver_scaling?: number | string;
232
+ ver_max_ram?: string | number;
233
+ ver_ram_threshold?: string | number;
234
+ ver_ram_inc_by?: string | number;
235
+ ver_max_cpu?: string | number;
236
+ ver_cpu_threshold?: string | number;
237
+ ver_cpu_inc_by?: string | number;
238
+ random_ipv6?: number | string;
239
+ encrypted_pass?: number | string;
240
+ vm_admin_name?: string;
241
+ crypted_pass?: string | null;
242
+ crypted_salt?: string | null;
243
+ custom_ipv6_on_edit?: number | string;
244
+ docker_info?: unknown | null;
245
+ }
246
+ interface VPS {
247
+ vpsid: string;
248
+ vps_name?: string;
249
+ uuid?: string;
250
+ serid?: string | number;
251
+ time?: string | number;
252
+ edittime?: string | number;
253
+ virt?: VirtType | string;
254
+ uid?: string | number;
255
+ plid?: string | number;
256
+ hostname: string;
257
+ osid?: string | number;
258
+ os_name: string;
259
+ iso?: string;
260
+ sec_iso?: string;
261
+ boot?: string;
262
+ space?: string | number;
263
+ inodes?: string | number;
264
+ ram: string;
265
+ burst?: string | number;
266
+ swap?: string | number;
267
+ cpu?: string | number;
268
+ cores?: string | number;
269
+ cpupin?: string | number;
270
+ cpu_percent?: string | number;
271
+ bandwidth: string;
272
+ network_speed?: string | number;
273
+ upload_speed?: string | number;
274
+ io?: string | number;
275
+ ubc?: string;
276
+ acpi?: string | number;
277
+ apic?: string | number;
278
+ pae?: string | number;
279
+ shadow?: string | number;
280
+ vnc?: string | number;
281
+ vncport?: string | number;
282
+ vnc_passwd?: string;
283
+ hvm?: string | number;
284
+ suspended?: string | number;
285
+ suspend_reason?: string | null;
286
+ nw_suspended?: string | null;
287
+ rescue?: string | number;
288
+ band_suspend?: string | number;
289
+ tuntap?: string | number;
290
+ ppp?: string | number;
291
+ ploop?: string | number;
292
+ dns_nameserver?: string;
293
+ osreinstall_limit?: string | number;
294
+ preferences?: unknown | null;
295
+ nic_type?: string;
296
+ vif_type?: string;
297
+ virtio?: string | number;
298
+ pv_on_hvm?: string | number;
299
+ disks?: unknown | null;
300
+ kvm_cache?: string | number;
301
+ io_mode?: string | number;
302
+ cpu_mode?: string;
303
+ total_iops_sec?: string | number;
304
+ read_bytes_sec?: string | number;
305
+ write_bytes_sec?: string | number;
306
+ kvm_vga?: string | number;
307
+ acceleration?: string | number;
308
+ vnc_keymap?: string;
309
+ routing?: string | number;
310
+ mg?: string;
311
+ used_bandwidth?: string | number;
312
+ cached_disk?: unknown;
313
+ webuzo?: string | number;
314
+ disable_ebtables?: string | number;
315
+ install_xentools?: string | number;
316
+ admin_managed?: string | number;
317
+ rdp?: string | number;
318
+ topology_sockets?: string | number;
319
+ topology_cores?: string | number;
320
+ topology_threads?: string | number;
321
+ mac?: string;
322
+ notes?: string | null;
323
+ disable_nw_config?: string | number;
324
+ locked?: string;
325
+ openvz_features?: string;
326
+ speed_cap?: string;
327
+ numa?: string | number;
328
+ bpid?: string | number;
329
+ bserid?: string | number;
330
+ timezone?: string | null;
331
+ ha?: string | number;
332
+ load_balancer?: string | number;
333
+ data?: VPSData;
334
+ fwid?: string | number;
335
+ admin_fwid?: string | number;
336
+ current_resource?: unknown | null;
337
+ plan_expiry?: string | number;
338
+ machine_status?: string | number;
339
+ tags?: string | null;
340
+ server_name?: string;
341
+ email?: string;
342
+ pid?: string | number;
343
+ type?: string | number;
344
+ os_distro?: string;
345
+ stid?: number[];
346
+ ips?: Record<string, string>;
347
+ }
348
+ interface ListVPSParams {
349
+ user?: string | number;
350
+ vpsid?: string | number;
351
+ vpsname?: string;
352
+ vpsip?: string;
353
+ vpshostname?: string;
354
+ vsstatus?: string;
355
+ vstype?: VirtType;
356
+ serid?: number;
357
+ plid?: number;
358
+ bpid?: number;
359
+ [key: string]: unknown;
360
+ }
361
+ interface CreateVPSParams {
362
+ hostname: string;
363
+ rootpass: string;
364
+ osid: number;
365
+ plid?: number;
366
+ user_email?: string;
367
+ ips?: number;
368
+ ips_int?: number;
369
+ space?: number;
370
+ ram?: number;
371
+ burst?: number;
372
+ bandwidth?: number;
373
+ cpu?: number;
374
+ cpu_percent?: number;
375
+ virt?: VirtType;
376
+ serid?: number;
377
+ node_select?: 0 | 1;
378
+ recipe?: number;
379
+ sshkey?: string;
380
+ nopassword?: 0 | 1;
381
+ [key: string]: unknown;
382
+ }
383
+ interface RebuildVPSParams {
384
+ osid: number;
385
+ newpass: string;
386
+ /** Must be set to 1 to confirm the rebuild */
387
+ conf: 1;
388
+ /** Format primary disk (0 = no, 1 = yes); defaults to 0 */
389
+ format_primary?: 0 | 1;
390
+ /** Send rebuild notification email (0 = no, 1 = yes) */
391
+ eu_send_rebuild_email?: 0 | 1;
392
+ recipe?: number;
393
+ sshkey?: string;
394
+ }
395
+ interface CloneVPSParams {
396
+ hostname: string;
397
+ rootpass: string;
398
+ from_server: number;
399
+ to_server: number;
400
+ }
401
+ interface MigrateVPSParams {
402
+ /** Destination server ID */
403
+ serid: number;
404
+ /** Source server IP address */
405
+ from_ip: string;
406
+ /** Source server API/root password */
407
+ from_pass: string;
408
+ /** 0 = ignore VDF conflicts, 1 = error on conflict */
409
+ ignore_if_vdfconflict?: 0 | 1;
410
+ /** 0 = use gzip compression, 1 = disable gzip */
411
+ disable_gzip?: 0 | 1;
412
+ /** 0 = offline migration, 1 = live migration */
413
+ online?: 0 | 1;
414
+ }
415
+ interface VPSStatsResponse extends VirtualizorResponse {
416
+ vs_stats?: unknown;
417
+ vs_bandwidth?: unknown;
418
+ time_taken?: string;
419
+ }
420
+ interface VNCInfo extends VirtualizorResponse {
421
+ novnc?: string;
422
+ [key: string]: unknown;
423
+ }
424
+
425
+ declare class VpsResource {
426
+ private readonly http;
427
+ constructor(http: HttpClient);
428
+ list(filters?: ListVPSParams): Promise<Record<string, VPS>>;
429
+ get(filters: ListVPSParams): Promise<VPS>;
430
+ create(params: CreateVPSParams): Promise<AsyncTaskResult>;
431
+ delete(vpsId: string): Promise<AsyncTaskResult>;
432
+ start(vpsId: string): Promise<AsyncTaskResult>;
433
+ stop(vpsId: string): Promise<AsyncTaskResult>;
434
+ restart(vpsId: string): Promise<AsyncTaskResult>;
435
+ poweroff(vpsId: string): Promise<AsyncTaskResult>;
436
+ suspend(vpsId: string): Promise<AsyncTaskResult>;
437
+ unsuspend(vpsId: string): Promise<AsyncTaskResult>;
438
+ rebuild(vpsId: string, params: RebuildVPSParams): Promise<AsyncTaskResult>;
439
+ clone(vpsId: string, params: CloneVPSParams): Promise<AsyncTaskResult>;
440
+ migrate(vpsId: string, params: MigrateVPSParams): Promise<AsyncTaskResult>;
441
+ status(vpsId: string): Promise<unknown>;
442
+ vnc(vpsId: string): Promise<VNCInfo>;
443
+ stats(vpsId: string): Promise<VPSStatsResponse>;
444
+ }
445
+
446
+ declare class VirtualizorClient {
447
+ readonly vps: VpsResource;
448
+ readonly users: UsersResource;
449
+ readonly plans: PlansResource;
450
+ readonly tasks: TasksResource;
451
+ readonly logger: Logger;
452
+ constructor(config: VirtualizorConfig);
453
+ }
454
+ declare function createVirtualizorClient(config: VirtualizorConfig): VirtualizorClient;
455
+
456
+ type IpsInput = string[] | Record<string, string> | string | undefined | null;
457
+ type FormatIpsOptions = {
458
+ /**
459
+ * Choose the return type. Defaults to 'array'.
460
+ * - 'array' returns string[]
461
+ * - 'string' returns a joined string using `separator`
462
+ */
463
+ as?: 'array' | 'string';
464
+ /** Separator used when returning a string. Defaults to ', '. */
465
+ separator?: string;
466
+ };
467
+ /**
468
+ * formatIps
469
+ * - Default behavior: return an array of IP strings (string[])
470
+ * - If options.as === 'string' it returns a joined string using options.separator
471
+ */
472
+ declare function formatIps(ips: IpsInput): string[];
473
+ declare function formatIps(ips: IpsInput, options: FormatIpsOptions & {
474
+ as: 'string';
475
+ }): string;
476
+
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 };
package/dist/index.d.mts CHANGED
@@ -474,4 +474,5 @@ declare function formatIps(ips: IpsInput, options: FormatIpsOptions & {
474
474
  as: 'string';
475
475
  }): string;
476
476
 
477
- export { type AsyncTaskResult, type CloneVPSParams, ConsoleLogger, type CreatePlanParams, type CreateUserParams, type CreateVPSParams, type IpsInput, type ListVPSParams, type Logger, type MigrateVPSParams, type Plan, type RebuildVPSParams, type Task, type User, type VPS, type VirtType, VirtualizorApiError, VirtualizorClient, type VirtualizorConfig, colors, createBox, createErrorBox, createUpdateBox, createVirtualizorClient, defaultLogger, formatError, formatIps, symbols };
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 };
package/dist/index.d.ts CHANGED
@@ -474,4 +474,5 @@ declare function formatIps(ips: IpsInput, options: FormatIpsOptions & {
474
474
  as: 'string';
475
475
  }): string;
476
476
 
477
- export { type AsyncTaskResult, type CloneVPSParams, ConsoleLogger, type CreatePlanParams, type CreateUserParams, type CreateVPSParams, type IpsInput, type ListVPSParams, type Logger, type MigrateVPSParams, type Plan, type RebuildVPSParams, type Task, type User, type VPS, type VirtType, VirtualizorApiError, VirtualizorClient, type VirtualizorConfig, colors, createBox, createErrorBox, createUpdateBox, createVirtualizorClient, defaultLogger, formatError, formatIps, symbols };
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 };
package/dist/index.mjs CHANGED
@@ -1,11 +1,10 @@
1
- import j from'http';import U from'https';var F=(s,t)=>()=>(t||s((t={exports:{}}).exports,t),t.exports);var M=F(($t,Q)=>{Q.exports={name:"virtualizorjs",version:"2.2.1",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.",main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{import:{types:"./dist/index.d.mts",default:"./dist/index.mjs"},require:{types:"./dist/index.d.ts",default:"./dist/index.js"}}},scripts:{build:"tsup",dev:"tsup --watch",test:"bun test","test:watch":"bun test --watch",coverage:"bun test --coverage",typecheck:"tsc --noEmit",lint:"biome check src tests","lint:fix":"biome check --write src tests",format:"biome format --write src tests",release:"bun run build && bumpp",prepublishOnly:"bun run build && bun run typecheck","check-exports":"attw --pack .",prepare:"husky"},files:["dist","README.md","LICENSE"],keywords:["virtualizor","vps","sdk","api","typescript","nodejs","bun"],author:"kkMihai",license:"MIT",repository:{type:"git",url:"git+https://github.com/kkMihai/virtualizorjs.git"},bugs:{url:"https://github.com/kkMihai/virtualizorjs/issues"},homepage:"https://github.com/kkMihai/virtualizorjs#readme",engines:{bun:">=1.3.0"},devDependencies:{"@arethetypeswrong/cli":"^0.17.0","@biomejs/biome":"^1.9.0","@commitlint/cli":"^19.0.0","@commitlint/config-conventional":"^19.0.0","@types/bun":"latest",bumpp:"^9.0.0",husky:"^9.0.0",tsup:"^8.0.0",typescript:"^5.5.0"},trustedDependencies:["@biomejs/biome"]};});var P={port:4085,https:true,rejectUnauthorized:false,timeout:3e4,debug:false},I={pollIntervalMs:2e3,timeoutMs:12e4};var n=class extends Error{code;details;constructor(t,e,o){super(t),this.name="VirtualizorApiError",this.code=e,this.details=o;}format(){return `[API Error ${this.code}] ${this.message}`}};function $(s,t,e){let o={};for(let[p,i]of Object.entries(s))i!==void 0&&(o[p]=i);let r=new URLSearchParams;r.set("api","json"),r.set("adminapikey",t),r.set("adminapipass",e);for(let[p,i]of Object.entries(o))r.set(p,String(i));return `?${r.toString()}`}var q=5e3,v=class{constructor(t){this.config=t;let e=t.https?U.Agent:j.Agent;this.agent=new e({keepAlive:true,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){let e=t.error[0];if(e)throw new n(e.msg,e.code)}return t}async request(t,e={},o={}){let r={act:t,...e},p=$(r,this.config.apiKey,this.config.apiPass);if(this.config.debug){let c=p.replace(/adminapikey=[^&]*/,"adminapikey=[REDACTED]").replace(/adminapipass=[^&]*/,"adminapipass=[REDACTED]");this.logger.debug(`Request: act=${t} path=/index.php${c}`);}let i=`/index.php${p}`,m=Object.entries(o).filter(([,c])=>c!==void 0).map(([c,R])=>`${encodeURIComponent(c)}=${encodeURIComponent(String(R))}`).join("&");try{let c=await this.rawRequest(i,m||void 0);return this.parseResponse(c)}catch(c){throw this.config.debug&&(c instanceof n?this.logger.error(`[Virtualizor] \u25CF Error: [API Error ${c.code}] ${c.message}`):this.logger.error(`[Virtualizor] \u25CF Error: ${c.message}`)),c}}validateJsonDepth(t,e=0){if(e>100)throw new n("JSON depth limit exceeded",-32e3);if(typeof t=="object"&&t!==null)if(Array.isArray(t))for(let r of t)this.validateJsonDepth(r,e+1);else for(let r of Object.values(t))this.validateJsonDepth(r,e+1);}destroy(){this.agent.destroy();}rawRequest(t,e){let o=this.config.https?U:j,r={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((p,i)=>{let m=o.request(r,u=>{let T=[];u.on("data",f=>{T.push(f);}),u.on("end",()=>{let f=Buffer.concat(T).toString("utf8");if(u.statusCode===302||u.statusCode===301){i(new n(`Redirect detected (status ${u.statusCode}). Authentication failed. Location: ${u.headers.location}`,u.statusCode));return}try{let d=JSON.parse(f);this.validateJsonDepth(d),p(d);}catch(d){this.config.debug&&(d instanceof n?this.logger.error(`[Virtualizor] \u25CF Error: [API Error ${d.code}] ${d.message}`):this.logger.error(`[Virtualizor] \u25CF Error: ${d.message}`)),i(new n(`Failed to parse response: ${d.message??"Invalid JSON"}`,-32700));}}),u.on("error",f=>{this.config.debug&&this.logger.error("[Virtualizor] \u25CF Error: Response stream error",f),i(new n(`Response stream error: ${f.message??"Unknown error"}`,-32e3));});}),c=setTimeout(()=>{m.destroy(new n(`Connection timeout after ${q}ms`,-32e3));},q),R=setTimeout(()=>{m.destroy(new n(`Request timed out after ${this.config.timeout}ms`,-32e3));},this.config.timeout);m.once("socket",u=>{u.connecting?u.once("connect",()=>clearTimeout(c)):clearTimeout(c);}),m.once("close",()=>{clearTimeout(c),clearTimeout(R);}),m.on("error",u=>{u instanceof n?i(u):i(new n(`Request error ${u}`,-32e3));}),e&&m.write(e),m.end();})}};var A=process.platform==="win32",G=process.env.NO_COLOR===void 0&&process.stdout.isTTY;function l(s,t){return G?`\x1B[${s}m${t}\x1B[0m`:t}var a={red:s=>l(31,s),green:s=>l(32,s),yellow:s=>l(33,s),blue:s=>l(34,s),magenta:s=>l(35,s),cyan:s=>l(36,s),white:s=>l(37,s),gray:s=>l(90,s),dim:s=>l(2,s),bold:s=>l(1,s),underline:s=>l(4,s),bgRed:s=>l(41,s),bgGreen:s=>l(42,s),bgYellow:s=>l(43,s),bgBlue:s=>l(44,s),bgCyan:s=>l(46,s)},g={success:A?"\u221A":"\u2714",error:A?"\xD7":"\u2716",warning:A?"\u203C":"\u26A0",info:A?"i":"\u2139",bullet:"\u25CF",arrow:"\u2192",chevron:"\u203A",pointer:"\u276F",star:"\u2605"},h={topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:"\u2500",vertical:"\u2502"};var k=class{constructor(t="Virtualizor"){this.prefix=t;}timestamp(){let e=new Date().toISOString().split("T")[1];return a.dim(e?e.slice(0,8):"00:00:00")}tag(){return a.cyan(`[${this.prefix}]`)}debug(t,...e){console.log(this.timestamp(),this.tag(),a.dim(g.bullet),a.dim(t),...e);}info(t,...e){console.log(this.timestamp(),this.tag(),a.blue(g.info),t,...e);}warn(t,...e){console.log(this.timestamp(),this.tag(),a.yellow(g.warning),a.yellow(t),...e);}error(t,e){console.error(this.timestamp(),this.tag(),a.red(g.error),a.red(t)),e?.stack&&console.error(a.dim(e.stack.split(`
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(`
2
2
  `).slice(1,4).join(`
3
- `)));}success(t,...e){console.log(this.timestamp(),this.tag(),a.green(g.success),a.green(t),...e);}},w=new k;function O(s,t={}){let{padding:e=1,margin:o=0,borderColor:r="cyan"}=t,p=s.split(`
4
- `),m=Math.max(...p.map(y=>y.length))+e*2,c=a[r]??a.cyan,R=h.horizontal.repeat(m),u=`${h.topLeft}${R}${h.topRight}`,T=`${h.bottomLeft}${R}${h.bottomRight}`,f=p.map(y=>{let z=" ".repeat(e)+y+" ".repeat(e);return `${h.vertical}${z.padEnd(m)}${h.vertical}`}),d=[c(u),...f.map(y=>c(y)),c(T)].join(`
5
- `);if(o>0){let y=" ".repeat(o);return d.split(`
6
- `).map(z=>y+z).join(`
7
- `)}return d}function b(s,t){let e=["\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: ${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(e)}function N(s,t,e){let o=["\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 ${t.padEnd(34)}\u2551`,"\u2551 \u2551",e?`\u2551 \u{1F4A1} ${e.padEnd(29)}\u2551`:"",e?"\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(o)}function B(s,t=false){if(s instanceof n){let e=s.details&&t?`
10
- ${a.dim(JSON.stringify(s.details,null,2))}`:"";return `${g.error} ${a.red(`[API Error ${s.code}]`)} ${s.message}${e}`}return `${g.error} ${a.red(s.message)}`}var x=class{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})}};var V=class{constructor(t){this.http=t;}async get(t){return (await this.http.request("tasks",{taskid:t},{})).tasks[t]}async wait(t,e={}){let{pollIntervalMs:o=I.pollIntervalMs,timeoutMs:r=I.timeoutMs}=e,p=Date.now()+r;for(;Date.now()<p;){let i=await this.get(t);if(!i)throw new n("Task not found",404);if(i.status==="1"||i.status==="done")return i;if(i.status==="error"||i.status==="-1")throw new n("Task failed",500);await new Promise(m=>setTimeout(m,o));}throw new n(`Task timed out after ${r}ms`,408)}};var C=class{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})}};var E={REBUILD_REOS_FLAG:1,MIGRATE_FLAG:1,MIGRATE_BUT_FLAG:1};var S=class{constructor(t){this.http=t;}async list(t={}){return (await this.http.request("vs",{},t)).vs??{}}async get(t){let e=await this.http.request("vs",{},t),o=Object.entries(e.vs??{});if(o.length===0)throw new n("VPS not found",404);let r=o[0];if(!r)throw new n("VPS not found",404);let[,p]=r;return p}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:E.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:E.MIGRATE_FLAG,migrate_but:E.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})}};var H="https://registry.npmjs.org/virtualizorjs/latest";async function J(s){let t=new AbortController,e=setTimeout(()=>t.abort(),s);try{let o=await fetch(H,{signal:t.signal});if(!o.ok)throw new Error(`HTTP ${o.status}`);return await o.json()}finally{clearTimeout(e);}}function K(s,t){let e=s.split(".").map(Number),o=t.split(".").map(Number);return (o[0]??0)>(e[0]??0)||(o[0]??0)===(e[0]??0)&&(o[1]??0)>(e[1]??0)||(o[0]??0)===(e[0]??0)&&(o[1]??0)===(e[1]??0)&&(o[2]??0)>(e[2]??0)}var _=false;async function D(s,t,e){if(!(_&&true)){_=true;try{let r=(await J(e?.timeout??2e3)).version;if(!K(s,r))return;t.warn(`Update available: ${s} \u2192 ${r}`),console.log(),console.log(b(s,r)),console.log();}catch{}}}var W=M().version,L=class{vps;users;plans;tasks;logger;constructor(t){let e=t.logger??w;this.logger=e;let o={host:t.host,apiKey:t.apiKey,apiPass:t.apiPass??"",port:t.port??P.port,https:t.https??P.https,rejectUnauthorized:t.rejectUnauthorized??P.rejectUnauthorized,timeout:t.timeout??P.timeout,debug:t.debug??P.debug,logger:e,disableUpdateCheck:t.disableUpdateCheck??false},r=new v(o);this.vps=new S(r),this.users=new C(r),this.plans=new x(r),this.tasks=new V(r),o.disableUpdateCheck||D(W,e).catch(()=>{});}};function Y(s){return new L(s)}function X(s,t){let e=t?.as??"array",o=t?.separator??", ";if(!s)return e==="array"?[]:"";let r=[];if(Array.isArray(s))r=s.filter(Boolean);else if(typeof s=="string"){let p=s.trim();p===""?r=[]:p.includes(",")?r=p.split(",").map(i=>i.trim()).filter(Boolean):/\s+/.test(p)?r=p.split(/\s+/).map(i=>i.trim()).filter(Boolean):r=[p];}else typeof s=="object"&&(r=Object.values(s).filter(Boolean));return e==="array"?r:r.join(o)}
11
- export{k as ConsoleLogger,n as VirtualizorApiError,L as VirtualizorClient,a as colors,O as createBox,N as createErrorBox,b as createUpdateBox,Y as createVirtualizorClient,w as defaultLogger,B as formatError,X as formatIps,g as symbols};
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};
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "virtualizorjs",
3
- "version": "2.2.1",
3
+ "version": "2.2.2",
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
- "main": "./dist/index.js",
5
+ "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
7
7
  "types": "./dist/index.d.ts",
8
8
  "exports": {
@@ -12,14 +12,14 @@
12
12
  "default": "./dist/index.mjs"
13
13
  },
14
14
  "require": {
15
- "types": "./dist/index.d.ts",
16
- "default": "./dist/index.js"
15
+ "types": "./dist/index.d.cts",
16
+ "default": "./dist/index.cjs"
17
17
  }
18
18
  }
19
19
  },
20
20
  "scripts": {
21
- "build": "tsup",
22
- "dev": "tsup --watch",
21
+ "build": "unbuild",
22
+ "dev": "unbuild --stub",
23
23
  "test": "bun test",
24
24
  "test:watch": "bun test --watch",
25
25
  "coverage": "bun test --coverage",
@@ -41,24 +41,22 @@
41
41
  "url": "git+https://github.com/kkMihai/virtualizorjs.git"
42
42
  },
43
43
  "bugs": {
44
- "url": "https://github.com/kkMihai/virtualizorjs/issues"
45
- },
46
- "homepage": "https://github.com/kkMihai/virtualizorjs#readme",
47
- "engines": {
48
- "bun": ">=1.3.0"
49
- },
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",
55
- "@types/bun": "latest",
56
- "bumpp": "^9.0.0",
57
- "husky": "^9.0.0",
58
- "tsup": "^8.0.0",
59
- "typescript": "^5.5.0"
60
- },
61
- "trustedDependencies": [
62
- "@biomejs/biome"
63
- ]
44
+ "url": "https://github.com/kkMihai/virtualizorjs/issues"
45
+ },
46
+ "homepage": "https://github.com/kkMihai/virtualizorjs#readme",
47
+ "engines": {
48
+ "bun": ">=1.3.0"
49
+ },
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",
55
+ "@types/bun": "latest",
56
+ "bumpp": "^9.0.0",
57
+ "husky": "^9.0.0",
58
+ "unbuild": "^3.0.0",
59
+ "typescript": "^5.5.0"
60
+ },
61
+ "trustedDependencies": ["@biomejs/biome"]
64
62
  }
package/dist/index.js DELETED
@@ -1,11 +0,0 @@
1
- 'use strict';var j=require('http'),U=require('https');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var j__default=/*#__PURE__*/_interopDefault(j);var U__default=/*#__PURE__*/_interopDefault(U);var F=(s,t)=>()=>(t||s((t={exports:{}}).exports,t),t.exports);var M=F(($t,Q)=>{Q.exports={name:"virtualizorjs",version:"2.2.1",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.",main:"./dist/index.js",module:"./dist/index.mjs",types:"./dist/index.d.ts",exports:{".":{import:{types:"./dist/index.d.mts",default:"./dist/index.mjs"},require:{types:"./dist/index.d.ts",default:"./dist/index.js"}}},scripts:{build:"tsup",dev:"tsup --watch",test:"bun test","test:watch":"bun test --watch",coverage:"bun test --coverage",typecheck:"tsc --noEmit",lint:"biome check src tests","lint:fix":"biome check --write src tests",format:"biome format --write src tests",release:"bun run build && bumpp",prepublishOnly:"bun run build && bun run typecheck","check-exports":"attw --pack .",prepare:"husky"},files:["dist","README.md","LICENSE"],keywords:["virtualizor","vps","sdk","api","typescript","nodejs","bun"],author:"kkMihai",license:"MIT",repository:{type:"git",url:"git+https://github.com/kkMihai/virtualizorjs.git"},bugs:{url:"https://github.com/kkMihai/virtualizorjs/issues"},homepage:"https://github.com/kkMihai/virtualizorjs#readme",engines:{bun:">=1.3.0"},devDependencies:{"@arethetypeswrong/cli":"^0.17.0","@biomejs/biome":"^1.9.0","@commitlint/cli":"^19.0.0","@commitlint/config-conventional":"^19.0.0","@types/bun":"latest",bumpp:"^9.0.0",husky:"^9.0.0",tsup:"^8.0.0",typescript:"^5.5.0"},trustedDependencies:["@biomejs/biome"]};});var P={port:4085,https:true,rejectUnauthorized:false,timeout:3e4,debug:false},I={pollIntervalMs:2e3,timeoutMs:12e4};var n=class extends Error{code;details;constructor(t,e,o){super(t),this.name="VirtualizorApiError",this.code=e,this.details=o;}format(){return `[API Error ${this.code}] ${this.message}`}};function $(s,t,e){let o={};for(let[p,i]of Object.entries(s))i!==void 0&&(o[p]=i);let r=new URLSearchParams;r.set("api","json"),r.set("adminapikey",t),r.set("adminapipass",e);for(let[p,i]of Object.entries(o))r.set(p,String(i));return `?${r.toString()}`}var q=5e3,v=class{constructor(t){this.config=t;let e=t.https?U__default.default.Agent:j__default.default.Agent;this.agent=new e({keepAlive:true,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){let e=t.error[0];if(e)throw new n(e.msg,e.code)}return t}async request(t,e={},o={}){let r={act:t,...e},p=$(r,this.config.apiKey,this.config.apiPass);if(this.config.debug){let c=p.replace(/adminapikey=[^&]*/,"adminapikey=[REDACTED]").replace(/adminapipass=[^&]*/,"adminapipass=[REDACTED]");this.logger.debug(`Request: act=${t} path=/index.php${c}`);}let i=`/index.php${p}`,m=Object.entries(o).filter(([,c])=>c!==void 0).map(([c,R])=>`${encodeURIComponent(c)}=${encodeURIComponent(String(R))}`).join("&");try{let c=await this.rawRequest(i,m||void 0);return this.parseResponse(c)}catch(c){throw this.config.debug&&(c instanceof n?this.logger.error(`[Virtualizor] \u25CF Error: [API Error ${c.code}] ${c.message}`):this.logger.error(`[Virtualizor] \u25CF Error: ${c.message}`)),c}}validateJsonDepth(t,e=0){if(e>100)throw new n("JSON depth limit exceeded",-32e3);if(typeof t=="object"&&t!==null)if(Array.isArray(t))for(let r of t)this.validateJsonDepth(r,e+1);else for(let r of Object.values(t))this.validateJsonDepth(r,e+1);}destroy(){this.agent.destroy();}rawRequest(t,e){let o=this.config.https?U__default.default:j__default.default,r={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((p,i)=>{let m=o.request(r,u=>{let T=[];u.on("data",f=>{T.push(f);}),u.on("end",()=>{let f=Buffer.concat(T).toString("utf8");if(u.statusCode===302||u.statusCode===301){i(new n(`Redirect detected (status ${u.statusCode}). Authentication failed. Location: ${u.headers.location}`,u.statusCode));return}try{let d=JSON.parse(f);this.validateJsonDepth(d),p(d);}catch(d){this.config.debug&&(d instanceof n?this.logger.error(`[Virtualizor] \u25CF Error: [API Error ${d.code}] ${d.message}`):this.logger.error(`[Virtualizor] \u25CF Error: ${d.message}`)),i(new n(`Failed to parse response: ${d.message??"Invalid JSON"}`,-32700));}}),u.on("error",f=>{this.config.debug&&this.logger.error("[Virtualizor] \u25CF Error: Response stream error",f),i(new n(`Response stream error: ${f.message??"Unknown error"}`,-32e3));});}),c=setTimeout(()=>{m.destroy(new n(`Connection timeout after ${q}ms`,-32e3));},q),R=setTimeout(()=>{m.destroy(new n(`Request timed out after ${this.config.timeout}ms`,-32e3));},this.config.timeout);m.once("socket",u=>{u.connecting?u.once("connect",()=>clearTimeout(c)):clearTimeout(c);}),m.once("close",()=>{clearTimeout(c),clearTimeout(R);}),m.on("error",u=>{u instanceof n?i(u):i(new n(`Request error ${u}`,-32e3));}),e&&m.write(e),m.end();})}};var A=process.platform==="win32",G=process.env.NO_COLOR===void 0&&process.stdout.isTTY;function l(s,t){return G?`\x1B[${s}m${t}\x1B[0m`:t}var a={red:s=>l(31,s),green:s=>l(32,s),yellow:s=>l(33,s),blue:s=>l(34,s),magenta:s=>l(35,s),cyan:s=>l(36,s),white:s=>l(37,s),gray:s=>l(90,s),dim:s=>l(2,s),bold:s=>l(1,s),underline:s=>l(4,s),bgRed:s=>l(41,s),bgGreen:s=>l(42,s),bgYellow:s=>l(43,s),bgBlue:s=>l(44,s),bgCyan:s=>l(46,s)},g={success:A?"\u221A":"\u2714",error:A?"\xD7":"\u2716",warning:A?"\u203C":"\u26A0",info:A?"i":"\u2139",bullet:"\u25CF",arrow:"\u2192",chevron:"\u203A",pointer:"\u276F",star:"\u2605"},h={topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:"\u2500",vertical:"\u2502"};var k=class{constructor(t="Virtualizor"){this.prefix=t;}timestamp(){let e=new Date().toISOString().split("T")[1];return a.dim(e?e.slice(0,8):"00:00:00")}tag(){return a.cyan(`[${this.prefix}]`)}debug(t,...e){console.log(this.timestamp(),this.tag(),a.dim(g.bullet),a.dim(t),...e);}info(t,...e){console.log(this.timestamp(),this.tag(),a.blue(g.info),t,...e);}warn(t,...e){console.log(this.timestamp(),this.tag(),a.yellow(g.warning),a.yellow(t),...e);}error(t,e){console.error(this.timestamp(),this.tag(),a.red(g.error),a.red(t)),e?.stack&&console.error(a.dim(e.stack.split(`
2
- `).slice(1,4).join(`
3
- `)));}success(t,...e){console.log(this.timestamp(),this.tag(),a.green(g.success),a.green(t),...e);}},w=new k;function O(s,t={}){let{padding:e=1,margin:o=0,borderColor:r="cyan"}=t,p=s.split(`
4
- `),m=Math.max(...p.map(y=>y.length))+e*2,c=a[r]??a.cyan,R=h.horizontal.repeat(m),u=`${h.topLeft}${R}${h.topRight}`,T=`${h.bottomLeft}${R}${h.bottomRight}`,f=p.map(y=>{let z=" ".repeat(e)+y+" ".repeat(e);return `${h.vertical}${z.padEnd(m)}${h.vertical}`}),d=[c(u),...f.map(y=>c(y)),c(T)].join(`
5
- `);if(o>0){let y=" ".repeat(o);return d.split(`
6
- `).map(z=>y+z).join(`
7
- `)}return d}function b(s,t){let e=["\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: ${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(e)}function N(s,t,e){let o=["\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 ${t.padEnd(34)}\u2551`,"\u2551 \u2551",e?`\u2551 \u{1F4A1} ${e.padEnd(29)}\u2551`:"",e?"\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(o)}function B(s,t=false){if(s instanceof n){let e=s.details&&t?`
10
- ${a.dim(JSON.stringify(s.details,null,2))}`:"";return `${g.error} ${a.red(`[API Error ${s.code}]`)} ${s.message}${e}`}return `${g.error} ${a.red(s.message)}`}var x=class{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})}};var V=class{constructor(t){this.http=t;}async get(t){return (await this.http.request("tasks",{taskid:t},{})).tasks[t]}async wait(t,e={}){let{pollIntervalMs:o=I.pollIntervalMs,timeoutMs:r=I.timeoutMs}=e,p=Date.now()+r;for(;Date.now()<p;){let i=await this.get(t);if(!i)throw new n("Task not found",404);if(i.status==="1"||i.status==="done")return i;if(i.status==="error"||i.status==="-1")throw new n("Task failed",500);await new Promise(m=>setTimeout(m,o));}throw new n(`Task timed out after ${r}ms`,408)}};var C=class{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})}};var E={REBUILD_REOS_FLAG:1,MIGRATE_FLAG:1,MIGRATE_BUT_FLAG:1};var S=class{constructor(t){this.http=t;}async list(t={}){return (await this.http.request("vs",{},t)).vs??{}}async get(t){let e=await this.http.request("vs",{},t),o=Object.entries(e.vs??{});if(o.length===0)throw new n("VPS not found",404);let r=o[0];if(!r)throw new n("VPS not found",404);let[,p]=r;return p}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:E.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:E.MIGRATE_FLAG,migrate_but:E.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})}};var H="https://registry.npmjs.org/virtualizorjs/latest";async function J(s){let t=new AbortController,e=setTimeout(()=>t.abort(),s);try{let o=await fetch(H,{signal:t.signal});if(!o.ok)throw new Error(`HTTP ${o.status}`);return await o.json()}finally{clearTimeout(e);}}function K(s,t){let e=s.split(".").map(Number),o=t.split(".").map(Number);return (o[0]??0)>(e[0]??0)||(o[0]??0)===(e[0]??0)&&(o[1]??0)>(e[1]??0)||(o[0]??0)===(e[0]??0)&&(o[1]??0)===(e[1]??0)&&(o[2]??0)>(e[2]??0)}var _=false;async function D(s,t,e){if(!(_&&true)){_=true;try{let r=(await J(e?.timeout??2e3)).version;if(!K(s,r))return;t.warn(`Update available: ${s} \u2192 ${r}`),console.log(),console.log(b(s,r)),console.log();}catch{}}}var W=M().version,L=class{vps;users;plans;tasks;logger;constructor(t){let e=t.logger??w;this.logger=e;let o={host:t.host,apiKey:t.apiKey,apiPass:t.apiPass??"",port:t.port??P.port,https:t.https??P.https,rejectUnauthorized:t.rejectUnauthorized??P.rejectUnauthorized,timeout:t.timeout??P.timeout,debug:t.debug??P.debug,logger:e,disableUpdateCheck:t.disableUpdateCheck??false},r=new v(o);this.vps=new S(r),this.users=new C(r),this.plans=new x(r),this.tasks=new V(r),o.disableUpdateCheck||D(W,e).catch(()=>{});}};function Y(s){return new L(s)}function X(s,t){let e=t?.as??"array",o=t?.separator??", ";if(!s)return e==="array"?[]:"";let r=[];if(Array.isArray(s))r=s.filter(Boolean);else if(typeof s=="string"){let p=s.trim();p===""?r=[]:p.includes(",")?r=p.split(",").map(i=>i.trim()).filter(Boolean):/\s+/.test(p)?r=p.split(/\s+/).map(i=>i.trim()).filter(Boolean):r=[p];}else typeof s=="object"&&(r=Object.values(s).filter(Boolean));return e==="array"?r:r.join(o)}
11
- exports.ConsoleLogger=k;exports.VirtualizorApiError=n;exports.VirtualizorClient=L;exports.colors=a;exports.createBox=O;exports.createErrorBox=N;exports.createUpdateBox=b;exports.createVirtualizorClient=Y;exports.defaultLogger=w;exports.formatError=B;exports.formatIps=X;exports.symbols=g;