virtualizorjs 2.1.3 → 2.2.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/README.md CHANGED
@@ -83,8 +83,8 @@ try {
83
83
 
84
84
  | Method | Parameters | Returns | Notes |
85
85
  |--------|-----------|---------|-------|
86
- | `list()` | | `Record<string, VPS>` | List all VPS |
87
- | `get(vpsId)` | `vpsId: string` | `VPS` | Get a single VPS |
86
+ | `list(filters?)` | `filters: ListVPSParams` | `Record<string, VPS>` | List all VPS with optional filters |
87
+ | `get(filters)` | `filters: ListVPSParams` | `VPS` | Get a single VPS with filters |
88
88
  | `create(params)` | `CreateVPSParams` | `AsyncTaskResult` | Async |
89
89
  | `delete(vpsId)` | `vpsId: string` | `AsyncTaskResult` | Async |
90
90
  | `start(vpsId)` | `vpsId: string` | `AsyncTaskResult` | Async |
@@ -173,16 +173,20 @@ All resources are fully typed. Import types as needed:
173
173
  ```typescript
174
174
  import type {
175
175
  VPS,
176
+ ListVPSParams,
176
177
  CreateVPSParams,
177
178
  RebuildVPSParams,
178
179
  CloneVPSParams,
179
180
  MigrateVPSParams,
181
+ VirtType,
180
182
  User,
181
183
  CreateUserParams,
182
184
  Plan,
183
185
  CreatePlanParams,
184
186
  Task,
185
187
  AsyncTaskResult,
188
+ VirtualizorConfig,
189
+ IpsInput,
186
190
  } from 'virtualizorjs';
187
191
  ```
188
192
 
package/dist/index.d.mts CHANGED
@@ -1,3 +1,70 @@
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';
62
+ padding?: number;
63
+ }
64
+ declare function createBox(content: string, options?: BoxOptions): string;
65
+
66
+ declare function formatError(error: Error, verbose?: boolean): string;
67
+
1
68
  interface VirtualizorError {
2
69
  code: number;
3
70
  msg: string;
@@ -24,6 +91,8 @@ interface VirtualizorConfig {
24
91
  rejectUnauthorized?: boolean;
25
92
  timeout?: number;
26
93
  debug?: boolean;
94
+ logger?: Logger;
95
+ disableUpdateCheck?: boolean;
27
96
  }
28
97
  interface ResolvedConfig {
29
98
  host: string;
@@ -34,17 +103,19 @@ interface ResolvedConfig {
34
103
  rejectUnauthorized: boolean;
35
104
  timeout: number;
36
105
  debug: boolean;
106
+ logger: Logger;
107
+ disableUpdateCheck: boolean;
37
108
  }
38
109
 
39
- declare class VirtualizorApiError extends Error {
40
- readonly code: number;
41
- constructor(message: string, code: number);
42
- }
43
110
  declare class HttpClient {
44
111
  private readonly config;
112
+ private readonly agent;
113
+ private readonly logger;
45
114
  constructor(config: ResolvedConfig);
46
115
  parseResponse<T extends VirtualizorResponse>(data: T): T;
47
116
  request<T extends VirtualizorResponse>(act: string, queryParams?: ApiParams, bodyParams?: ApiParams): Promise<T>;
117
+ private validateJsonDepth;
118
+ destroy(): void;
48
119
  private rawRequest;
49
120
  }
50
121
 
@@ -352,7 +423,7 @@ declare class VpsResource {
352
423
  private readonly http;
353
424
  constructor(http: HttpClient);
354
425
  list(filters?: ListVPSParams): Promise<Record<string, VPS>>;
355
- get(vpsId: string): Promise<VPS>;
426
+ get(filters: ListVPSParams): Promise<VPS>;
356
427
  create(params: CreateVPSParams): Promise<AsyncTaskResult>;
357
428
  delete(vpsId: string): Promise<AsyncTaskResult>;
358
429
  start(vpsId: string): Promise<AsyncTaskResult>;
@@ -374,6 +445,7 @@ declare class VirtualizorClient {
374
445
  readonly users: UsersResource;
375
446
  readonly plans: PlansResource;
376
447
  readonly tasks: TasksResource;
448
+ readonly logger: Logger;
377
449
  constructor(config: VirtualizorConfig);
378
450
  }
379
451
  declare function createVirtualizorClient(config: VirtualizorConfig): VirtualizorClient;
@@ -399,4 +471,4 @@ declare function formatIps(ips: IpsInput, options: FormatIpsOptions & {
399
471
  as: 'string';
400
472
  }): string;
401
473
 
402
- export { type AsyncTaskResult, type CloneVPSParams, type CreatePlanParams, type CreateUserParams, type CreateVPSParams, type IpsInput, type ListVPSParams, type MigrateVPSParams, type Plan, type RebuildVPSParams, type Task, type User, type VPS, type VirtType, VirtualizorApiError, VirtualizorClient, type VirtualizorConfig, createVirtualizorClient, formatIps };
474
+ 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, createVirtualizorClient, defaultLogger, formatError, formatIps, symbols };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,70 @@
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';
62
+ padding?: number;
63
+ }
64
+ declare function createBox(content: string, options?: BoxOptions): string;
65
+
66
+ declare function formatError(error: Error, verbose?: boolean): string;
67
+
1
68
  interface VirtualizorError {
2
69
  code: number;
3
70
  msg: string;
@@ -24,6 +91,8 @@ interface VirtualizorConfig {
24
91
  rejectUnauthorized?: boolean;
25
92
  timeout?: number;
26
93
  debug?: boolean;
94
+ logger?: Logger;
95
+ disableUpdateCheck?: boolean;
27
96
  }
28
97
  interface ResolvedConfig {
29
98
  host: string;
@@ -34,17 +103,19 @@ interface ResolvedConfig {
34
103
  rejectUnauthorized: boolean;
35
104
  timeout: number;
36
105
  debug: boolean;
106
+ logger: Logger;
107
+ disableUpdateCheck: boolean;
37
108
  }
38
109
 
39
- declare class VirtualizorApiError extends Error {
40
- readonly code: number;
41
- constructor(message: string, code: number);
42
- }
43
110
  declare class HttpClient {
44
111
  private readonly config;
112
+ private readonly agent;
113
+ private readonly logger;
45
114
  constructor(config: ResolvedConfig);
46
115
  parseResponse<T extends VirtualizorResponse>(data: T): T;
47
116
  request<T extends VirtualizorResponse>(act: string, queryParams?: ApiParams, bodyParams?: ApiParams): Promise<T>;
117
+ private validateJsonDepth;
118
+ destroy(): void;
48
119
  private rawRequest;
49
120
  }
50
121
 
@@ -352,7 +423,7 @@ declare class VpsResource {
352
423
  private readonly http;
353
424
  constructor(http: HttpClient);
354
425
  list(filters?: ListVPSParams): Promise<Record<string, VPS>>;
355
- get(vpsId: string): Promise<VPS>;
426
+ get(filters: ListVPSParams): Promise<VPS>;
356
427
  create(params: CreateVPSParams): Promise<AsyncTaskResult>;
357
428
  delete(vpsId: string): Promise<AsyncTaskResult>;
358
429
  start(vpsId: string): Promise<AsyncTaskResult>;
@@ -374,6 +445,7 @@ declare class VirtualizorClient {
374
445
  readonly users: UsersResource;
375
446
  readonly plans: PlansResource;
376
447
  readonly tasks: TasksResource;
448
+ readonly logger: Logger;
377
449
  constructor(config: VirtualizorConfig);
378
450
  }
379
451
  declare function createVirtualizorClient(config: VirtualizorConfig): VirtualizorClient;
@@ -399,4 +471,4 @@ declare function formatIps(ips: IpsInput, options: FormatIpsOptions & {
399
471
  as: 'string';
400
472
  }): string;
401
473
 
402
- export { type AsyncTaskResult, type CloneVPSParams, type CreatePlanParams, type CreateUserParams, type CreateVPSParams, type IpsInput, type ListVPSParams, type MigrateVPSParams, type Plan, type RebuildVPSParams, type Task, type User, type VPS, type VirtType, VirtualizorApiError, VirtualizorClient, type VirtualizorConfig, createVirtualizorClient, formatIps };
474
+ 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, createVirtualizorClient, defaultLogger, formatError, formatIps, symbols };
package/dist/index.js CHANGED
@@ -1,346 +1,9 @@
1
- 'use strict';
2
-
3
- var http = require('http');
4
- var https = require('https');
5
-
6
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
-
8
- var http__default = /*#__PURE__*/_interopDefault(http);
9
- var https__default = /*#__PURE__*/_interopDefault(https);
10
-
11
- // src/config/defaults.ts
12
- var DEFAULT_CONFIG = {
13
- port: 4085,
14
- https: true,
15
- rejectUnauthorized: false,
16
- timeout: 3e4,
17
- debug: false
18
- };
19
- var DEFAULT_TASK_POLLING = {
20
- pollIntervalMs: 2e3,
21
- timeoutMs: 12e4
22
- };
23
-
24
- // src/auth.ts
25
- function buildQueryString(params, apiKey, apiPass) {
26
- const clean = {};
27
- for (const [key, value] of Object.entries(params)) {
28
- if (value !== void 0) {
29
- clean[key] = value;
30
- }
31
- }
32
- const urlParams = new URLSearchParams();
33
- urlParams.set("api", "json");
34
- urlParams.set("adminapikey", apiKey);
35
- urlParams.set("adminapipass", apiPass);
36
- for (const [key, value] of Object.entries(clean)) {
37
- urlParams.set(key, String(value));
38
- }
39
- return `?${urlParams.toString()}`;
40
- }
41
-
42
- // src/http.ts
43
- var VirtualizorApiError = class extends Error {
44
- code;
45
- constructor(message, code) {
46
- super(message);
47
- this.name = "VirtualizorApiError";
48
- this.code = code;
49
- }
50
- };
51
- var HttpClient = class {
52
- constructor(config) {
53
- this.config = config;
54
- }
55
- parseResponse(data) {
56
- if (data.error && data.error.length > 0) {
57
- const first = data.error[0];
58
- if (first) {
59
- throw new VirtualizorApiError(first.msg, first.code);
60
- }
61
- }
62
- return data;
63
- }
64
- async request(act, queryParams = {}, bodyParams = {}) {
65
- const allQueryParams = { act, ...queryParams };
66
- const qs = buildQueryString(allQueryParams, this.config.apiKey, this.config.apiPass);
67
- const path = `/index.php${qs}`;
68
- const bodyString = Object.entries(bodyParams).filter(([, v]) => v !== void 0).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`).join("&");
69
- const data = await this.rawRequest(path, bodyString || void 0);
70
- return this.parseResponse(data);
71
- }
72
- rawRequest(path, body) {
73
- const transport = this.config.https ? https__default.default : http__default.default;
74
- const options = {
75
- host: this.config.host,
76
- port: this.config.port,
77
- path,
78
- method: body ? "POST" : "GET",
79
- headers: {
80
- "Content-Type": "application/x-www-form-urlencoded",
81
- ...body ? { "Content-Length": Buffer.byteLength(body) } : {}
82
- },
83
- ...this.config.https ? { agent: new https__default.default.Agent({ rejectUnauthorized: this.config.rejectUnauthorized }) } : {}
84
- };
85
- return new Promise((resolve, reject) => {
86
- const req = transport.request(options, (res) => {
87
- let raw = "";
88
- res.on("data", (chunk) => {
89
- raw += chunk.toString();
90
- });
91
- res.on("end", () => {
92
- if (res.statusCode === 302 || res.statusCode === 301) {
93
- reject(
94
- new Error(
95
- `Redirect detected (status ${res.statusCode}). Authentication failed. Check your API credentials. Location: ${res.headers.location}`
96
- )
97
- );
98
- return;
99
- }
100
- try {
101
- resolve(JSON.parse(raw));
102
- } catch (err) {
103
- if (this.config.debug)
104
- console.debug("[Virtualizor] Raw response (first 500 chars):", raw.slice(0, 500));
105
- reject(
106
- new Error(
107
- `Failed to parse response: ${raw.slice(0, 200)}. Parse error: ${err instanceof Error ? err.message : String(err)}`
108
- )
109
- );
110
- }
111
- });
112
- });
113
- req.setTimeout(this.config.timeout, () => {
114
- req.destroy(new Error(`Request timed out after ${this.config.timeout}ms`));
115
- });
116
- req.on("error", reject);
117
- if (body) {
118
- req.write(body);
119
- }
120
- req.end();
121
- });
122
- }
123
- };
124
-
125
- // src/resources/plans.ts
126
- var PlansResource = class {
127
- constructor(http2) {
128
- this.http = http2;
129
- }
130
- async list() {
131
- const res = await this.http.request("plans", {}, {});
132
- return res.plans;
133
- }
134
- async create(params) {
135
- return this.http.request("addplan", {}, params);
136
- }
137
- async delete(planId) {
138
- return this.http.request("plans", {}, { delete: planId });
139
- }
140
- };
141
-
142
- // src/resources/tasks.ts
143
- var TasksResource = class {
144
- constructor(http2) {
145
- this.http = http2;
146
- }
147
- async get(taskId) {
148
- const res = await this.http.request("tasks", { taskid: taskId }, {});
149
- return res.tasks[taskId];
150
- }
151
- async wait(taskId, options = {}) {
152
- const {
153
- pollIntervalMs = DEFAULT_TASK_POLLING.pollIntervalMs,
154
- timeoutMs = DEFAULT_TASK_POLLING.timeoutMs
155
- } = options;
156
- const deadline = Date.now() + timeoutMs;
157
- while (Date.now() < deadline) {
158
- const task = await this.get(taskId);
159
- if (!task) throw new Error(`Task ${taskId} not found`);
160
- if (task.status === "1" || task.status === "done") return task;
161
- if (task.status === "error" || task.status === "-1") {
162
- throw new Error(`Task ${taskId} failed`);
163
- }
164
- await new Promise((r) => setTimeout(r, pollIntervalMs));
165
- }
166
- throw new Error(`Task ${taskId} timed out after ${timeoutMs}ms`);
167
- }
168
- };
169
-
170
- // src/resources/users.ts
171
- var UsersResource = class {
172
- constructor(http2) {
173
- this.http = http2;
174
- }
175
- async list() {
176
- const res = await this.http.request("users", {}, {});
177
- return res.users;
178
- }
179
- async create(params) {
180
- return this.http.request("adduser", {}, params);
181
- }
182
- async delete(uid) {
183
- return this.http.request("users", {}, { delete: uid });
184
- }
185
- async suspend(uid) {
186
- return this.http.request("users", {}, { suspend: uid });
187
- }
188
- async unsuspend(uid) {
189
- return this.http.request("users", {}, { unsuspend: uid });
190
- }
191
- };
192
-
193
- // src/constants/vps.ts
194
- var VPS_CONSTANTS = {
195
- // Rebuild operation requires reos=1 flag
196
- REBUILD_REOS_FLAG: 1,
197
- // Migrate operation requires migrate=1 flag
198
- MIGRATE_FLAG: 1,
199
- // Migrate operation requires migrate_but=1 flag
200
- MIGRATE_BUT_FLAG: 1
201
- };
202
-
203
- // src/resources/vps.ts
204
- var VpsResource = class {
205
- constructor(http2) {
206
- this.http = http2;
207
- }
208
- async list(filters = {}) {
209
- const res = await this.http.request("vs", {}, filters);
210
- return res.vs ?? {};
211
- }
212
- async get(vpsId) {
213
- const res = await this.http.request("vs", { vpsid: vpsId }, {});
214
- const vps = res.vs[vpsId];
215
- if (!vps) throw new Error(`VPS ${vpsId} not found in response`);
216
- return vps;
217
- }
218
- async create(params) {
219
- return this.http.request("addvs", {}, params);
220
- }
221
- async delete(vpsId) {
222
- return this.http.request("vs", { delete: vpsId }, {});
223
- }
224
- async start(vpsId) {
225
- return this.http.request("vs", { vpsid: vpsId, action: "start" }, {});
226
- }
227
- async stop(vpsId) {
228
- return this.http.request("vs", { vpsid: vpsId, action: "stop" }, {});
229
- }
230
- async restart(vpsId) {
231
- return this.http.request("vs", { vpsid: vpsId, action: "restart" }, {});
232
- }
233
- async poweroff(vpsId) {
234
- return this.http.request("vs", { vpsid: vpsId, action: "poweroff" }, {});
235
- }
236
- async suspend(vpsId) {
237
- return this.http.request("vs", { suspend: vpsId }, {});
238
- }
239
- async unsuspend(vpsId) {
240
- return this.http.request("vs", { unsuspend: vpsId }, {});
241
- }
242
- async rebuild(vpsId, params) {
243
- return this.http.request(
244
- "rebuild",
245
- {},
246
- {
247
- vpsid: vpsId,
248
- reos: VPS_CONSTANTS.REBUILD_REOS_FLAG,
249
- ...params
250
- }
251
- );
252
- }
253
- async clone(vpsId, params) {
254
- return this.http.request(
255
- "clone",
256
- {},
257
- {
258
- vpsid: vpsId,
259
- ...params
260
- }
261
- );
262
- }
263
- async migrate(vpsId, params) {
264
- return this.http.request(
265
- "migrate",
266
- {},
267
- {
268
- vpsid: vpsId,
269
- migrate: VPS_CONSTANTS.MIGRATE_FLAG,
270
- migrate_but: VPS_CONSTANTS.MIGRATE_BUT_FLAG,
271
- ...params
272
- }
273
- );
274
- }
275
- async status(vpsId) {
276
- return this.http.request("vstatus", { vpsid: vpsId }, {});
277
- }
278
- async vnc(vpsId) {
279
- return this.http.request("vnc", { vpsid: vpsId }, {});
280
- }
281
- async stats(vpsId) {
282
- return this.http.request("vps_stats", {}, { vpsid: vpsId });
283
- }
284
- };
285
-
286
- // src/client.ts
287
- var VirtualizorClient = class {
288
- vps;
289
- users;
290
- plans;
291
- tasks;
292
- constructor(config) {
293
- const resolved = {
294
- host: config.host,
295
- apiKey: config.apiKey,
296
- apiPass: config.apiPass ?? "",
297
- port: config.port ?? DEFAULT_CONFIG.port,
298
- https: config.https ?? DEFAULT_CONFIG.https,
299
- rejectUnauthorized: config.rejectUnauthorized ?? DEFAULT_CONFIG.rejectUnauthorized,
300
- timeout: config.timeout ?? DEFAULT_CONFIG.timeout,
301
- debug: config.debug ?? DEFAULT_CONFIG.debug
302
- };
303
- const http2 = new HttpClient(resolved);
304
- this.vps = new VpsResource(http2);
305
- this.users = new UsersResource(http2);
306
- this.plans = new PlansResource(http2);
307
- this.tasks = new TasksResource(http2);
308
- }
309
- };
310
- function createVirtualizorClient(config) {
311
- return new VirtualizorClient(config);
312
- }
313
-
314
- // src/utils/format-ips.ts
315
- function formatIps(ips, options) {
316
- const as = options?.as ?? "array";
317
- const separator = options?.separator ?? ", ";
318
- if (!ips) {
319
- return as === "array" ? [] : "";
320
- }
321
- let result = [];
322
- if (Array.isArray(ips)) {
323
- result = ips.filter(Boolean);
324
- } else if (typeof ips === "string") {
325
- const str = ips.trim();
326
- if (str === "") {
327
- result = [];
328
- } else if (str.includes(",")) {
329
- result = str.split(",").map((s) => s.trim()).filter(Boolean);
330
- } else if (/\s+/.test(str)) {
331
- result = str.split(/\s+/).map((s) => s.trim()).filter(Boolean);
332
- } else {
333
- result = [str];
334
- }
335
- } else if (typeof ips === "object") {
336
- result = Object.values(ips).filter(Boolean);
337
- }
338
- return as === "array" ? result : result.join(separator);
339
- }
340
-
341
- exports.VirtualizorApiError = VirtualizorApiError;
342
- exports.VirtualizorClient = VirtualizorClient;
343
- exports.createVirtualizorClient = createVirtualizorClient;
344
- exports.formatIps = formatIps;
345
- //# sourceMappingURL=index.js.map
1
+ 'use strict';var j=require('http'),$=require('https');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var j__default=/*#__PURE__*/_interopDefault(j);var $__default=/*#__PURE__*/_interopDefault($);var M=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var _=M((Et,H)=>{H.exports={name:"virtualizorjs",version:"2.2.0",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 y={port:4085,https:true,rejectUnauthorized:false,timeout:3e4,debug:false},E={pollIntervalMs:2e3,timeoutMs:12e4};var i=class extends Error{code;details;constructor(t,s,o){super(t),this.name="VirtualizorApiError",this.code=s,this.details=o;}format(){return `[API Error ${this.code}] ${this.message}`}};function I(e,t,s){let o={};for(let[p,n]of Object.entries(e))n!==void 0&&(o[p]=n);let r=new URLSearchParams;r.set("api","json"),r.set("adminapikey",t),r.set("adminapipass",s);for(let[p,n]of Object.entries(o))r.set(p,String(n));return `?${r.toString()}`}var U=5e3,T=class{constructor(t){this.config=t;let s=t.https?$__default.default.Agent:j__default.default.Agent;this.agent=new s({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 s=t.error[0];if(s)throw new i(s.msg,s.code)}return t}async request(t,s={},o={}){let r={act:t,...s},p=I(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 n=`/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(n,m||void 0);return this.parseResponse(c)}catch(c){throw this.config.debug&&(c instanceof i?this.logger.error(`[Virtualizor] \u25CF Error: [API Error ${c.code}] ${c.message}`):this.logger.error(`[Virtualizor] \u25CF Error: ${c.message}`)),c}}validateJsonDepth(t,s=0){if(s>100)throw new i("JSON depth limit exceeded",-32e3);if(typeof t=="object"&&t!==null)if(Array.isArray(t))for(let r of t)this.validateJsonDepth(r,s+1);else for(let r of Object.values(t))this.validateJsonDepth(r,s+1);}destroy(){this.agent.destroy();}rawRequest(t,s){let o=this.config.https?$__default.default:j__default.default,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((p,n)=>{let m=o.request(r,l=>{let k=[];l.on("data",g=>{k.push(g);}),l.on("end",()=>{let g=Buffer.concat(k).toString("utf8");if(l.statusCode===302||l.statusCode===301){n(new i(`Redirect detected (status ${l.statusCode}). Authentication failed. Location: ${l.headers.location}`,l.statusCode));return}try{let f=JSON.parse(g);this.validateJsonDepth(f),p(f);}catch(f){this.config.debug&&(f instanceof i?this.logger.error(`[Virtualizor] \u25CF Error: [API Error ${f.code}] ${f.message}`):this.logger.error(`[Virtualizor] \u25CF Error: ${f.message}`)),n(new i(`Failed to parse response: ${f.message??"Invalid JSON"}`,-32700));}}),l.on("error",g=>{this.config.debug&&this.logger.error("[Virtualizor] \u25CF Error: Response stream error",g),n(new i(`Response stream error: ${g.message??"Unknown error"}`,-32e3));});}),c=setTimeout(()=>{m.destroy(new i(`Connection timeout after ${U}ms`,-32e3));},U),R=setTimeout(()=>{m.destroy(new i(`Request timed out after ${this.config.timeout}ms`,-32e3));},this.config.timeout);m.once("socket",l=>{l.connecting?l.once("connect",()=>clearTimeout(c)):clearTimeout(c);}),m.once("close",()=>{clearTimeout(c),clearTimeout(R);}),m.on("error",l=>{l instanceof i?n(l):n(new i(`Request error ${l}`,-32e3));}),s&&m.write(s),m.end();})}};var v=process.platform==="win32",B=process.env.NO_COLOR===void 0&&process.stdout.isTTY;function u(e,t){return B?`\x1B[${e}m${t}\x1B[0m`:t}var a={red:e=>u(31,e),green:e=>u(32,e),yellow:e=>u(33,e),blue:e=>u(34,e),magenta:e=>u(35,e),cyan:e=>u(36,e),white:e=>u(37,e),gray:e=>u(90,e),dim:e=>u(2,e),bold:e=>u(1,e),underline:e=>u(4,e),bgRed:e=>u(41,e),bgGreen:e=>u(42,e),bgYellow:e=>u(43,e),bgBlue:e=>u(44,e),bgCyan:e=>u(46,e)},d={success:v?"\u221A":"\u2714",error:v?"\xD7":"\u2716",warning:v?"\u203C":"\u26A0",info:v?"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 P=class{constructor(t="Virtualizor"){this.prefix=t;}timestamp(){let s=new Date().toISOString().split("T")[1];return a.dim(s?s.slice(0,8):"00:00:00")}tag(){return a.cyan(`[${this.prefix}]`)}debug(t,...s){console.log(this.timestamp(),this.tag(),a.dim(d.bullet),a.dim(t),...s);}info(t,...s){console.log(this.timestamp(),this.tag(),a.blue(d.info),t,...s);}warn(t,...s){console.log(this.timestamp(),this.tag(),a.yellow(d.warning),a.yellow(t),...s);}error(t,s){console.error(this.timestamp(),this.tag(),a.red(d.error),a.red(t)),s?.stack&&console.error(a.dim(s.stack.split(`
2
+ `).slice(1,4).join(`
3
+ `)));}success(t,...s){console.log(this.timestamp(),this.tag(),a.green(d.success),a.green(t),...s);}},w=new P;function L(e,t={}){let{padding:s=1,borderColor:o="cyan"}=t,r=e.split(`
4
+ `),n=Math.max(...r.map(g=>g.length))+s*2,m=a[o]??a.cyan,c=h.horizontal.repeat(n),R=`${h.topLeft}${c}${h.topRight}`,l=`${h.bottomLeft}${c}${h.bottomRight}`,k=r.map(g=>{let f=" ".repeat(s)+g+" ".repeat(s);return `${h.vertical}${f.padEnd(n)}${h.vertical}`});return [m(R),...k.map(g=>m(g)),m(l)].join(`
5
+ `)}function z(e,t){let s=["New version available!","",`Current: ${e}`,`Latest: ${t}`,"","Run: npm install virtualizorjs@latest"].join(`
6
+ `);return L(s,{borderColor:"yellow"})}function q(e,t=false){if(e instanceof i){let s=e.details&&t?`
7
+ ${a.dim(JSON.stringify(e.details,null,2))}`:"";return `${d.error} ${a.red(`[API Error ${e.code}]`)} ${e.message}${s}`}return `${d.error} ${a.red(e.message)}`}var A=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 b=class{constructor(t){this.http=t;}async get(t){return (await this.http.request("tasks",{taskid:t},{})).tasks[t]}async wait(t,s={}){let{pollIntervalMs:o=E.pollIntervalMs,timeoutMs:r=E.timeoutMs}=s,p=Date.now()+r;for(;Date.now()<p;){let n=await this.get(t);if(!n)throw new i("Task not found",404);if(n.status==="1"||n.status==="done")return n;if(n.status==="error"||n.status==="-1")throw new i("Task failed",500);await new Promise(m=>setTimeout(m,o));}throw new i(`Task timed out after ${r}ms`,408)}};var x=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 V={REBUILD_REOS_FLAG:1,MIGRATE_FLAG:1,MIGRATE_BUT_FLAG:1};var C=class{constructor(t){this.http=t;}async list(t={}){return (await this.http.request("vs",{},t)).vs??{}}async get(t){let s=await this.http.request("vs",{},t),o=Object.entries(s.vs??{});if(o.length===0)throw new i("VPS not found",404);let r=o[0];if(!r)throw new i("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,s){return this.http.request("rebuild",{},{vpsid:t,reos:V.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:V.MIGRATE_FLAG,migrate_but:V.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})}};var D="https://registry.npmjs.org/virtualizorjs/latest";async function F(e){let t=new AbortController,s=setTimeout(()=>t.abort(),e);try{let o=await fetch(D,{signal:t.signal});if(!o.ok)throw new Error(`HTTP ${o.status}`);return await o.json()}finally{clearTimeout(s);}}function G(e,t){let s=e.split(".").map(Number),o=t.split(".").map(Number);return (o[0]??0)>(s[0]??0)||(o[0]??0)===(s[0]??0)&&(o[1]??0)>(s[1]??0)||(o[0]??0)===(s[0]??0)&&(o[1]??0)===(s[1]??0)&&(o[2]??0)>(s[2]??0)}var O=false;async function N(e,t,s){if(!(O&&true)){O=true;try{let r=(await F(s?.timeout??2e3)).version;if(!G(e,r))return;t.warn(`Update available: ${e} \u2192 ${r}`),console.log(),console.log(z(e,r)),console.log();}catch{}}}var J=_().version,S=class{vps;users;plans;tasks;logger;constructor(t){let s=t.logger??w;this.logger=s;let o={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??false},r=new T(o);this.vps=new C(r),this.users=new x(r),this.plans=new A(r),this.tasks=new b(r),o.disableUpdateCheck||N(J,s).catch(()=>{});}};function K(e){return new S(e)}function Q(e,t){let s=t?.as??"array",o=t?.separator??", ";if(!e)return s==="array"?[]:"";let r=[];if(Array.isArray(e))r=e.filter(Boolean);else if(typeof e=="string"){let p=e.trim();p===""?r=[]:p.includes(",")?r=p.split(",").map(n=>n.trim()).filter(Boolean):/\s+/.test(p)?r=p.split(/\s+/).map(n=>n.trim()).filter(Boolean):r=[p];}else typeof e=="object"&&(r=Object.values(e).filter(Boolean));return s==="array"?r:r.join(o)}
8
+ exports.ConsoleLogger=P;exports.VirtualizorApiError=i;exports.VirtualizorClient=S;exports.colors=a;exports.createBox=L;exports.createVirtualizorClient=K;exports.defaultLogger=w;exports.formatError=q;exports.formatIps=Q;exports.symbols=d;//# sourceMappingURL=index.js.map
346
9
  //# sourceMappingURL=index.js.map