virtualizorjs 2.1.3 → 2.2.1
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 +12 -11
- package/dist/index.d.mts +81 -6
- package/dist/index.d.ts +81 -6
- package/dist/index.js +11 -346
- package/dist/index.mjs +11 -336
- package/package.json +1 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -6,9 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
A **TypeScript-first** SDK for the [Virtualizor](https://www.virtualizor.com/) server management API. Manage VPS instances, users, and plans with a clean, namespaced interface and zero production dependencies.
|
|
8
8
|
|
|
9
|
-
> [!IMPORTANT]
|
|
10
|
-
> Since the Virtualizor API documentation is a mess (at least for me), I need help from YOU to report bugs, missing features or just to tell me that something is not clear. You can do that by opening an issue or a pull request.
|
|
11
|
-
|
|
12
9
|
## Installation
|
|
13
10
|
|
|
14
11
|
**npm:**
|
|
@@ -29,12 +26,12 @@ bun add virtualizorjs
|
|
|
29
26
|
import { createVirtualizorClient } from 'virtualizorjs';
|
|
30
27
|
|
|
31
28
|
const client = createVirtualizorClient({
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
host: process.env.VIRTUALIZOR_HOST!,
|
|
30
|
+
apiKey: process.env.VIRTUALIZOR_API_KEY!,
|
|
31
|
+
apiPass: process.env.VIRTUALIZOR_API_PASS!,
|
|
32
|
+
// Optional: port (default 4085), https (default true),
|
|
33
|
+
// rejectUnauthorized (default false), timeout (default 30000ms)
|
|
34
|
+
// Ports: 4085 (HTTPS), 4084 (HTTP)
|
|
38
35
|
});
|
|
39
36
|
```
|
|
40
37
|
|
|
@@ -83,8 +80,8 @@ try {
|
|
|
83
80
|
|
|
84
81
|
| Method | Parameters | Returns | Notes |
|
|
85
82
|
|--------|-----------|---------|-------|
|
|
86
|
-
| `list()` |
|
|
87
|
-
| `get(
|
|
83
|
+
| `list(filters?)` | `filters: ListVPSParams` | `Record<string, VPS>` | List all VPS with optional filters |
|
|
84
|
+
| `get(filters)` | `filters: ListVPSParams` | `VPS` | Get a single VPS with filters |
|
|
88
85
|
| `create(params)` | `CreateVPSParams` | `AsyncTaskResult` | Async |
|
|
89
86
|
| `delete(vpsId)` | `vpsId: string` | `AsyncTaskResult` | Async |
|
|
90
87
|
| `start(vpsId)` | `vpsId: string` | `AsyncTaskResult` | Async |
|
|
@@ -173,16 +170,20 @@ All resources are fully typed. Import types as needed:
|
|
|
173
170
|
```typescript
|
|
174
171
|
import type {
|
|
175
172
|
VPS,
|
|
173
|
+
ListVPSParams,
|
|
176
174
|
CreateVPSParams,
|
|
177
175
|
RebuildVPSParams,
|
|
178
176
|
CloneVPSParams,
|
|
179
177
|
MigrateVPSParams,
|
|
178
|
+
VirtType,
|
|
180
179
|
User,
|
|
181
180
|
CreateUserParams,
|
|
182
181
|
Plan,
|
|
183
182
|
CreatePlanParams,
|
|
184
183
|
Task,
|
|
185
184
|
AsyncTaskResult,
|
|
185
|
+
VirtualizorConfig,
|
|
186
|
+
IpsInput,
|
|
186
187
|
} from 'virtualizorjs';
|
|
187
188
|
```
|
|
188
189
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,73 @@
|
|
|
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
|
+
|
|
1
71
|
interface VirtualizorError {
|
|
2
72
|
code: number;
|
|
3
73
|
msg: string;
|
|
@@ -24,6 +94,8 @@ interface VirtualizorConfig {
|
|
|
24
94
|
rejectUnauthorized?: boolean;
|
|
25
95
|
timeout?: number;
|
|
26
96
|
debug?: boolean;
|
|
97
|
+
logger?: Logger;
|
|
98
|
+
disableUpdateCheck?: boolean;
|
|
27
99
|
}
|
|
28
100
|
interface ResolvedConfig {
|
|
29
101
|
host: string;
|
|
@@ -34,17 +106,19 @@ interface ResolvedConfig {
|
|
|
34
106
|
rejectUnauthorized: boolean;
|
|
35
107
|
timeout: number;
|
|
36
108
|
debug: boolean;
|
|
109
|
+
logger: Logger;
|
|
110
|
+
disableUpdateCheck: boolean;
|
|
37
111
|
}
|
|
38
112
|
|
|
39
|
-
declare class VirtualizorApiError extends Error {
|
|
40
|
-
readonly code: number;
|
|
41
|
-
constructor(message: string, code: number);
|
|
42
|
-
}
|
|
43
113
|
declare class HttpClient {
|
|
44
114
|
private readonly config;
|
|
115
|
+
private readonly agent;
|
|
116
|
+
private readonly logger;
|
|
45
117
|
constructor(config: ResolvedConfig);
|
|
46
118
|
parseResponse<T extends VirtualizorResponse>(data: T): T;
|
|
47
119
|
request<T extends VirtualizorResponse>(act: string, queryParams?: ApiParams, bodyParams?: ApiParams): Promise<T>;
|
|
120
|
+
private validateJsonDepth;
|
|
121
|
+
destroy(): void;
|
|
48
122
|
private rawRequest;
|
|
49
123
|
}
|
|
50
124
|
|
|
@@ -352,7 +426,7 @@ declare class VpsResource {
|
|
|
352
426
|
private readonly http;
|
|
353
427
|
constructor(http: HttpClient);
|
|
354
428
|
list(filters?: ListVPSParams): Promise<Record<string, VPS>>;
|
|
355
|
-
get(
|
|
429
|
+
get(filters: ListVPSParams): Promise<VPS>;
|
|
356
430
|
create(params: CreateVPSParams): Promise<AsyncTaskResult>;
|
|
357
431
|
delete(vpsId: string): Promise<AsyncTaskResult>;
|
|
358
432
|
start(vpsId: string): Promise<AsyncTaskResult>;
|
|
@@ -374,6 +448,7 @@ declare class VirtualizorClient {
|
|
|
374
448
|
readonly users: UsersResource;
|
|
375
449
|
readonly plans: PlansResource;
|
|
376
450
|
readonly tasks: TasksResource;
|
|
451
|
+
readonly logger: Logger;
|
|
377
452
|
constructor(config: VirtualizorConfig);
|
|
378
453
|
}
|
|
379
454
|
declare function createVirtualizorClient(config: VirtualizorConfig): VirtualizorClient;
|
|
@@ -399,4 +474,4 @@ declare function formatIps(ips: IpsInput, options: FormatIpsOptions & {
|
|
|
399
474
|
as: 'string';
|
|
400
475
|
}): string;
|
|
401
476
|
|
|
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 };
|
|
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,73 @@
|
|
|
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
|
+
|
|
1
71
|
interface VirtualizorError {
|
|
2
72
|
code: number;
|
|
3
73
|
msg: string;
|
|
@@ -24,6 +94,8 @@ interface VirtualizorConfig {
|
|
|
24
94
|
rejectUnauthorized?: boolean;
|
|
25
95
|
timeout?: number;
|
|
26
96
|
debug?: boolean;
|
|
97
|
+
logger?: Logger;
|
|
98
|
+
disableUpdateCheck?: boolean;
|
|
27
99
|
}
|
|
28
100
|
interface ResolvedConfig {
|
|
29
101
|
host: string;
|
|
@@ -34,17 +106,19 @@ interface ResolvedConfig {
|
|
|
34
106
|
rejectUnauthorized: boolean;
|
|
35
107
|
timeout: number;
|
|
36
108
|
debug: boolean;
|
|
109
|
+
logger: Logger;
|
|
110
|
+
disableUpdateCheck: boolean;
|
|
37
111
|
}
|
|
38
112
|
|
|
39
|
-
declare class VirtualizorApiError extends Error {
|
|
40
|
-
readonly code: number;
|
|
41
|
-
constructor(message: string, code: number);
|
|
42
|
-
}
|
|
43
113
|
declare class HttpClient {
|
|
44
114
|
private readonly config;
|
|
115
|
+
private readonly agent;
|
|
116
|
+
private readonly logger;
|
|
45
117
|
constructor(config: ResolvedConfig);
|
|
46
118
|
parseResponse<T extends VirtualizorResponse>(data: T): T;
|
|
47
119
|
request<T extends VirtualizorResponse>(act: string, queryParams?: ApiParams, bodyParams?: ApiParams): Promise<T>;
|
|
120
|
+
private validateJsonDepth;
|
|
121
|
+
destroy(): void;
|
|
48
122
|
private rawRequest;
|
|
49
123
|
}
|
|
50
124
|
|
|
@@ -352,7 +426,7 @@ declare class VpsResource {
|
|
|
352
426
|
private readonly http;
|
|
353
427
|
constructor(http: HttpClient);
|
|
354
428
|
list(filters?: ListVPSParams): Promise<Record<string, VPS>>;
|
|
355
|
-
get(
|
|
429
|
+
get(filters: ListVPSParams): Promise<VPS>;
|
|
356
430
|
create(params: CreateVPSParams): Promise<AsyncTaskResult>;
|
|
357
431
|
delete(vpsId: string): Promise<AsyncTaskResult>;
|
|
358
432
|
start(vpsId: string): Promise<AsyncTaskResult>;
|
|
@@ -374,6 +448,7 @@ declare class VirtualizorClient {
|
|
|
374
448
|
readonly users: UsersResource;
|
|
375
449
|
readonly plans: PlansResource;
|
|
376
450
|
readonly tasks: TasksResource;
|
|
451
|
+
readonly logger: Logger;
|
|
377
452
|
constructor(config: VirtualizorConfig);
|
|
378
453
|
}
|
|
379
454
|
declare function createVirtualizorClient(config: VirtualizorConfig): VirtualizorClient;
|
|
@@ -399,4 +474,4 @@ declare function formatIps(ips: IpsInput, options: FormatIpsOptions & {
|
|
|
399
474
|
as: 'string';
|
|
400
475
|
}): string;
|
|
401
476
|
|
|
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 };
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -1,346 +1,11 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
|
346
|
-
//# sourceMappingURL=index.js.map
|
|
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;
|
package/dist/index.mjs
CHANGED
|
@@ -1,336 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
var DEFAULT_TASK_POLLING = {
|
|
13
|
-
pollIntervalMs: 2e3,
|
|
14
|
-
timeoutMs: 12e4
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
// src/auth.ts
|
|
18
|
-
function buildQueryString(params, apiKey, apiPass) {
|
|
19
|
-
const clean = {};
|
|
20
|
-
for (const [key, value] of Object.entries(params)) {
|
|
21
|
-
if (value !== void 0) {
|
|
22
|
-
clean[key] = value;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
const urlParams = new URLSearchParams();
|
|
26
|
-
urlParams.set("api", "json");
|
|
27
|
-
urlParams.set("adminapikey", apiKey);
|
|
28
|
-
urlParams.set("adminapipass", apiPass);
|
|
29
|
-
for (const [key, value] of Object.entries(clean)) {
|
|
30
|
-
urlParams.set(key, String(value));
|
|
31
|
-
}
|
|
32
|
-
return `?${urlParams.toString()}`;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// src/http.ts
|
|
36
|
-
var VirtualizorApiError = class extends Error {
|
|
37
|
-
code;
|
|
38
|
-
constructor(message, code) {
|
|
39
|
-
super(message);
|
|
40
|
-
this.name = "VirtualizorApiError";
|
|
41
|
-
this.code = code;
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
var HttpClient = class {
|
|
45
|
-
constructor(config) {
|
|
46
|
-
this.config = config;
|
|
47
|
-
}
|
|
48
|
-
parseResponse(data) {
|
|
49
|
-
if (data.error && data.error.length > 0) {
|
|
50
|
-
const first = data.error[0];
|
|
51
|
-
if (first) {
|
|
52
|
-
throw new VirtualizorApiError(first.msg, first.code);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return data;
|
|
56
|
-
}
|
|
57
|
-
async request(act, queryParams = {}, bodyParams = {}) {
|
|
58
|
-
const allQueryParams = { act, ...queryParams };
|
|
59
|
-
const qs = buildQueryString(allQueryParams, this.config.apiKey, this.config.apiPass);
|
|
60
|
-
const path = `/index.php${qs}`;
|
|
61
|
-
const bodyString = Object.entries(bodyParams).filter(([, v]) => v !== void 0).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`).join("&");
|
|
62
|
-
const data = await this.rawRequest(path, bodyString || void 0);
|
|
63
|
-
return this.parseResponse(data);
|
|
64
|
-
}
|
|
65
|
-
rawRequest(path, body) {
|
|
66
|
-
const transport = this.config.https ? https : http;
|
|
67
|
-
const options = {
|
|
68
|
-
host: this.config.host,
|
|
69
|
-
port: this.config.port,
|
|
70
|
-
path,
|
|
71
|
-
method: body ? "POST" : "GET",
|
|
72
|
-
headers: {
|
|
73
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
74
|
-
...body ? { "Content-Length": Buffer.byteLength(body) } : {}
|
|
75
|
-
},
|
|
76
|
-
...this.config.https ? { agent: new https.Agent({ rejectUnauthorized: this.config.rejectUnauthorized }) } : {}
|
|
77
|
-
};
|
|
78
|
-
return new Promise((resolve, reject) => {
|
|
79
|
-
const req = transport.request(options, (res) => {
|
|
80
|
-
let raw = "";
|
|
81
|
-
res.on("data", (chunk) => {
|
|
82
|
-
raw += chunk.toString();
|
|
83
|
-
});
|
|
84
|
-
res.on("end", () => {
|
|
85
|
-
if (res.statusCode === 302 || res.statusCode === 301) {
|
|
86
|
-
reject(
|
|
87
|
-
new Error(
|
|
88
|
-
`Redirect detected (status ${res.statusCode}). Authentication failed. Check your API credentials. Location: ${res.headers.location}`
|
|
89
|
-
)
|
|
90
|
-
);
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
try {
|
|
94
|
-
resolve(JSON.parse(raw));
|
|
95
|
-
} catch (err) {
|
|
96
|
-
if (this.config.debug)
|
|
97
|
-
console.debug("[Virtualizor] Raw response (first 500 chars):", raw.slice(0, 500));
|
|
98
|
-
reject(
|
|
99
|
-
new Error(
|
|
100
|
-
`Failed to parse response: ${raw.slice(0, 200)}. Parse error: ${err instanceof Error ? err.message : String(err)}`
|
|
101
|
-
)
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
req.setTimeout(this.config.timeout, () => {
|
|
107
|
-
req.destroy(new Error(`Request timed out after ${this.config.timeout}ms`));
|
|
108
|
-
});
|
|
109
|
-
req.on("error", reject);
|
|
110
|
-
if (body) {
|
|
111
|
-
req.write(body);
|
|
112
|
-
}
|
|
113
|
-
req.end();
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
// src/resources/plans.ts
|
|
119
|
-
var PlansResource = class {
|
|
120
|
-
constructor(http2) {
|
|
121
|
-
this.http = http2;
|
|
122
|
-
}
|
|
123
|
-
async list() {
|
|
124
|
-
const res = await this.http.request("plans", {}, {});
|
|
125
|
-
return res.plans;
|
|
126
|
-
}
|
|
127
|
-
async create(params) {
|
|
128
|
-
return this.http.request("addplan", {}, params);
|
|
129
|
-
}
|
|
130
|
-
async delete(planId) {
|
|
131
|
-
return this.http.request("plans", {}, { delete: planId });
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
// src/resources/tasks.ts
|
|
136
|
-
var TasksResource = class {
|
|
137
|
-
constructor(http2) {
|
|
138
|
-
this.http = http2;
|
|
139
|
-
}
|
|
140
|
-
async get(taskId) {
|
|
141
|
-
const res = await this.http.request("tasks", { taskid: taskId }, {});
|
|
142
|
-
return res.tasks[taskId];
|
|
143
|
-
}
|
|
144
|
-
async wait(taskId, options = {}) {
|
|
145
|
-
const {
|
|
146
|
-
pollIntervalMs = DEFAULT_TASK_POLLING.pollIntervalMs,
|
|
147
|
-
timeoutMs = DEFAULT_TASK_POLLING.timeoutMs
|
|
148
|
-
} = options;
|
|
149
|
-
const deadline = Date.now() + timeoutMs;
|
|
150
|
-
while (Date.now() < deadline) {
|
|
151
|
-
const task = await this.get(taskId);
|
|
152
|
-
if (!task) throw new Error(`Task ${taskId} not found`);
|
|
153
|
-
if (task.status === "1" || task.status === "done") return task;
|
|
154
|
-
if (task.status === "error" || task.status === "-1") {
|
|
155
|
-
throw new Error(`Task ${taskId} failed`);
|
|
156
|
-
}
|
|
157
|
-
await new Promise((r) => setTimeout(r, pollIntervalMs));
|
|
158
|
-
}
|
|
159
|
-
throw new Error(`Task ${taskId} timed out after ${timeoutMs}ms`);
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
// src/resources/users.ts
|
|
164
|
-
var UsersResource = class {
|
|
165
|
-
constructor(http2) {
|
|
166
|
-
this.http = http2;
|
|
167
|
-
}
|
|
168
|
-
async list() {
|
|
169
|
-
const res = await this.http.request("users", {}, {});
|
|
170
|
-
return res.users;
|
|
171
|
-
}
|
|
172
|
-
async create(params) {
|
|
173
|
-
return this.http.request("adduser", {}, params);
|
|
174
|
-
}
|
|
175
|
-
async delete(uid) {
|
|
176
|
-
return this.http.request("users", {}, { delete: uid });
|
|
177
|
-
}
|
|
178
|
-
async suspend(uid) {
|
|
179
|
-
return this.http.request("users", {}, { suspend: uid });
|
|
180
|
-
}
|
|
181
|
-
async unsuspend(uid) {
|
|
182
|
-
return this.http.request("users", {}, { unsuspend: uid });
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
// src/constants/vps.ts
|
|
187
|
-
var VPS_CONSTANTS = {
|
|
188
|
-
// Rebuild operation requires reos=1 flag
|
|
189
|
-
REBUILD_REOS_FLAG: 1,
|
|
190
|
-
// Migrate operation requires migrate=1 flag
|
|
191
|
-
MIGRATE_FLAG: 1,
|
|
192
|
-
// Migrate operation requires migrate_but=1 flag
|
|
193
|
-
MIGRATE_BUT_FLAG: 1
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
// src/resources/vps.ts
|
|
197
|
-
var VpsResource = class {
|
|
198
|
-
constructor(http2) {
|
|
199
|
-
this.http = http2;
|
|
200
|
-
}
|
|
201
|
-
async list(filters = {}) {
|
|
202
|
-
const res = await this.http.request("vs", {}, filters);
|
|
203
|
-
return res.vs ?? {};
|
|
204
|
-
}
|
|
205
|
-
async get(vpsId) {
|
|
206
|
-
const res = await this.http.request("vs", { vpsid: vpsId }, {});
|
|
207
|
-
const vps = res.vs[vpsId];
|
|
208
|
-
if (!vps) throw new Error(`VPS ${vpsId} not found in response`);
|
|
209
|
-
return vps;
|
|
210
|
-
}
|
|
211
|
-
async create(params) {
|
|
212
|
-
return this.http.request("addvs", {}, params);
|
|
213
|
-
}
|
|
214
|
-
async delete(vpsId) {
|
|
215
|
-
return this.http.request("vs", { delete: vpsId }, {});
|
|
216
|
-
}
|
|
217
|
-
async start(vpsId) {
|
|
218
|
-
return this.http.request("vs", { vpsid: vpsId, action: "start" }, {});
|
|
219
|
-
}
|
|
220
|
-
async stop(vpsId) {
|
|
221
|
-
return this.http.request("vs", { vpsid: vpsId, action: "stop" }, {});
|
|
222
|
-
}
|
|
223
|
-
async restart(vpsId) {
|
|
224
|
-
return this.http.request("vs", { vpsid: vpsId, action: "restart" }, {});
|
|
225
|
-
}
|
|
226
|
-
async poweroff(vpsId) {
|
|
227
|
-
return this.http.request("vs", { vpsid: vpsId, action: "poweroff" }, {});
|
|
228
|
-
}
|
|
229
|
-
async suspend(vpsId) {
|
|
230
|
-
return this.http.request("vs", { suspend: vpsId }, {});
|
|
231
|
-
}
|
|
232
|
-
async unsuspend(vpsId) {
|
|
233
|
-
return this.http.request("vs", { unsuspend: vpsId }, {});
|
|
234
|
-
}
|
|
235
|
-
async rebuild(vpsId, params) {
|
|
236
|
-
return this.http.request(
|
|
237
|
-
"rebuild",
|
|
238
|
-
{},
|
|
239
|
-
{
|
|
240
|
-
vpsid: vpsId,
|
|
241
|
-
reos: VPS_CONSTANTS.REBUILD_REOS_FLAG,
|
|
242
|
-
...params
|
|
243
|
-
}
|
|
244
|
-
);
|
|
245
|
-
}
|
|
246
|
-
async clone(vpsId, params) {
|
|
247
|
-
return this.http.request(
|
|
248
|
-
"clone",
|
|
249
|
-
{},
|
|
250
|
-
{
|
|
251
|
-
vpsid: vpsId,
|
|
252
|
-
...params
|
|
253
|
-
}
|
|
254
|
-
);
|
|
255
|
-
}
|
|
256
|
-
async migrate(vpsId, params) {
|
|
257
|
-
return this.http.request(
|
|
258
|
-
"migrate",
|
|
259
|
-
{},
|
|
260
|
-
{
|
|
261
|
-
vpsid: vpsId,
|
|
262
|
-
migrate: VPS_CONSTANTS.MIGRATE_FLAG,
|
|
263
|
-
migrate_but: VPS_CONSTANTS.MIGRATE_BUT_FLAG,
|
|
264
|
-
...params
|
|
265
|
-
}
|
|
266
|
-
);
|
|
267
|
-
}
|
|
268
|
-
async status(vpsId) {
|
|
269
|
-
return this.http.request("vstatus", { vpsid: vpsId }, {});
|
|
270
|
-
}
|
|
271
|
-
async vnc(vpsId) {
|
|
272
|
-
return this.http.request("vnc", { vpsid: vpsId }, {});
|
|
273
|
-
}
|
|
274
|
-
async stats(vpsId) {
|
|
275
|
-
return this.http.request("vps_stats", {}, { vpsid: vpsId });
|
|
276
|
-
}
|
|
277
|
-
};
|
|
278
|
-
|
|
279
|
-
// src/client.ts
|
|
280
|
-
var VirtualizorClient = class {
|
|
281
|
-
vps;
|
|
282
|
-
users;
|
|
283
|
-
plans;
|
|
284
|
-
tasks;
|
|
285
|
-
constructor(config) {
|
|
286
|
-
const resolved = {
|
|
287
|
-
host: config.host,
|
|
288
|
-
apiKey: config.apiKey,
|
|
289
|
-
apiPass: config.apiPass ?? "",
|
|
290
|
-
port: config.port ?? DEFAULT_CONFIG.port,
|
|
291
|
-
https: config.https ?? DEFAULT_CONFIG.https,
|
|
292
|
-
rejectUnauthorized: config.rejectUnauthorized ?? DEFAULT_CONFIG.rejectUnauthorized,
|
|
293
|
-
timeout: config.timeout ?? DEFAULT_CONFIG.timeout,
|
|
294
|
-
debug: config.debug ?? DEFAULT_CONFIG.debug
|
|
295
|
-
};
|
|
296
|
-
const http2 = new HttpClient(resolved);
|
|
297
|
-
this.vps = new VpsResource(http2);
|
|
298
|
-
this.users = new UsersResource(http2);
|
|
299
|
-
this.plans = new PlansResource(http2);
|
|
300
|
-
this.tasks = new TasksResource(http2);
|
|
301
|
-
}
|
|
302
|
-
};
|
|
303
|
-
function createVirtualizorClient(config) {
|
|
304
|
-
return new VirtualizorClient(config);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
// src/utils/format-ips.ts
|
|
308
|
-
function formatIps(ips, options) {
|
|
309
|
-
const as = options?.as ?? "array";
|
|
310
|
-
const separator = options?.separator ?? ", ";
|
|
311
|
-
if (!ips) {
|
|
312
|
-
return as === "array" ? [] : "";
|
|
313
|
-
}
|
|
314
|
-
let result = [];
|
|
315
|
-
if (Array.isArray(ips)) {
|
|
316
|
-
result = ips.filter(Boolean);
|
|
317
|
-
} else if (typeof ips === "string") {
|
|
318
|
-
const str = ips.trim();
|
|
319
|
-
if (str === "") {
|
|
320
|
-
result = [];
|
|
321
|
-
} else if (str.includes(",")) {
|
|
322
|
-
result = str.split(",").map((s) => s.trim()).filter(Boolean);
|
|
323
|
-
} else if (/\s+/.test(str)) {
|
|
324
|
-
result = str.split(/\s+/).map((s) => s.trim()).filter(Boolean);
|
|
325
|
-
} else {
|
|
326
|
-
result = [str];
|
|
327
|
-
}
|
|
328
|
-
} else if (typeof ips === "object") {
|
|
329
|
-
result = Object.values(ips).filter(Boolean);
|
|
330
|
-
}
|
|
331
|
-
return as === "array" ? result : result.join(separator);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
export { VirtualizorApiError, VirtualizorClient, createVirtualizorClient, formatIps };
|
|
335
|
-
//# sourceMappingURL=index.mjs.map
|
|
336
|
-
//# sourceMappingURL=index.mjs.map
|
|
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(`
|
|
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};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "virtualizorjs",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "TypeScript SDK for the Virtualizor server management API. Create, start, stop, restart, rebuild, and manage VPS instances with a type-safe, developer-friendly client.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config/defaults.ts","../src/auth.ts","../src/http.ts","../src/resources/plans.ts","../src/resources/tasks.ts","../src/resources/users.ts","../src/constants/vps.ts","../src/resources/vps.ts","../src/client.ts","../src/utils/format-ips.ts"],"names":["https","http"],"mappings":"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","file":"index.js","sourcesContent":["export const DEFAULT_CONFIG = {\n port: 4085,\n https: true,\n rejectUnauthorized: false,\n timeout: 30000,\n debug: false,\n} as const;\n\nexport const DEFAULT_TASK_POLLING = {\n pollIntervalMs: 2000,\n timeoutMs: 120000,\n} as const;\n","import type { ApiParams } from './types/common.js';\n\nexport function buildQueryString(params: ApiParams, apiKey: string, apiPass: string): string {\n const clean: ApiParams = {};\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n clean[key] = value;\n }\n }\n\n const urlParams = new URLSearchParams();\n urlParams.set('api', 'json');\n urlParams.set('adminapikey', apiKey);\n urlParams.set('adminapipass', apiPass);\n\n for (const [key, value] of Object.entries(clean)) {\n urlParams.set(key, String(value));\n }\n\n return `?${urlParams.toString()}`;\n}\n","import http from 'node:http';\nimport https from 'node:https';\nimport { buildQueryString } from './auth.js';\nimport type { ApiParams } from './types/common.js';\nimport type { VirtualizorResponse } from './types/common.js';\nimport type { ResolvedConfig } from './types/config.js';\n\nexport class VirtualizorApiError extends Error {\n readonly code: number;\n\n constructor(message: string, code: number) {\n super(message);\n this.name = 'VirtualizorApiError';\n this.code = code;\n }\n}\n\nexport class HttpClient {\n constructor(private readonly config: ResolvedConfig) {}\n\n parseResponse<T extends VirtualizorResponse>(data: T): T {\n if (data.error && data.error.length > 0) {\n const first = data.error[0];\n if (first) {\n throw new VirtualizorApiError(first.msg, first.code);\n }\n }\n return data;\n }\n\n async request<T extends VirtualizorResponse>(\n act: string,\n queryParams: ApiParams = {},\n bodyParams: ApiParams = {},\n ): Promise<T> {\n const allQueryParams: ApiParams = { act, ...queryParams };\n const qs = buildQueryString(allQueryParams, this.config.apiKey, this.config.apiPass);\n\n const path = `/index.php${qs}`;\n\n const bodyString = Object.entries(bodyParams as Record<string, unknown>)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)\n .join('&');\n\n const data = await this.rawRequest(path, bodyString || undefined);\n return this.parseResponse(data as T);\n }\n\n private rawRequest(path: string, body?: string): Promise<VirtualizorResponse> {\n const transport = this.config.https ? https : http;\n const options: https.RequestOptions = {\n host: this.config.host,\n port: this.config.port,\n path,\n method: body ? 'POST' : 'GET',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n ...(body ? { 'Content-Length': Buffer.byteLength(body) } : {}),\n },\n ...(this.config.https\n ? { agent: new https.Agent({ rejectUnauthorized: this.config.rejectUnauthorized }) }\n : {}),\n };\n\n return new Promise((resolve, reject) => {\n const req = transport.request(options, (res) => {\n let raw = '';\n res.on('data', (chunk: Buffer) => {\n raw += chunk.toString();\n });\n res.on('end', () => {\n // Handle redirect (302) - usually means auth failed\n if (res.statusCode === 302 || res.statusCode === 301) {\n reject(\n new Error(\n `Redirect detected (status ${res.statusCode}). Authentication failed. ` +\n `Check your API credentials. Location: ${res.headers.location}`,\n ),\n );\n return;\n }\n\n try {\n resolve(JSON.parse(raw) as VirtualizorResponse);\n } catch (err) {\n if (this.config.debug)\n console.debug('[Virtualizor] Raw response (first 500 chars):', raw.slice(0, 500));\n reject(\n new Error(\n `Failed to parse response: ${raw.slice(0, 200)}. Parse error: ${err instanceof Error ? err.message : String(err)}`,\n ),\n );\n }\n });\n });\n\n req.setTimeout(this.config.timeout, () => {\n req.destroy(new Error(`Request timed out after ${this.config.timeout}ms`));\n });\n\n req.on('error', reject);\n\n if (body) {\n req.write(body);\n }\n\n req.end();\n });\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type { ApiParams } from '../types/common.js';\nimport type { AsyncTaskResult, VirtualizorResponse } from '../types/common.js';\nimport type { CreatePlanParams, Plan } from '../types/plans.js';\n\ninterface ListPlansResponse extends VirtualizorResponse {\n plans: Record<string, Plan>;\n}\nexport class PlansResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<Record<string, Plan>> {\n const res = await this.http.request<ListPlansResponse>('plans', {}, {});\n return res.plans;\n }\n\n async create(params: CreatePlanParams): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('addplan', {}, params);\n }\n\n async delete(planId: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('plans', {}, { delete: planId });\n }\n}\n","import { DEFAULT_TASK_POLLING } from '../config/defaults.js';\nimport type { HttpClient } from '../http.js';\nimport type { VirtualizorResponse } from '../types/common.js';\nimport type { Task } from '../types/tasks.js';\n\ninterface TasksResponse extends VirtualizorResponse {\n tasks: Record<string, Task>;\n}\n\nexport class TasksResource {\n constructor(private readonly http: HttpClient) {}\n\n async get(taskId: string): Promise<Task | undefined> {\n const res = await this.http.request<TasksResponse>('tasks', { taskid: taskId }, {});\n return res.tasks[taskId];\n }\n\n async wait(\n taskId: string,\n options: { pollIntervalMs?: number; timeoutMs?: number } = {},\n ): Promise<Task> {\n const {\n pollIntervalMs = DEFAULT_TASK_POLLING.pollIntervalMs,\n timeoutMs = DEFAULT_TASK_POLLING.timeoutMs,\n } = options;\n const deadline = Date.now() + timeoutMs;\n\n while (Date.now() < deadline) {\n const task = await this.get(taskId);\n if (!task) throw new Error(`Task ${taskId} not found`);\n if (task.status === '1' || task.status === 'done') return task;\n if (task.status === 'error' || task.status === '-1') {\n throw new Error(`Task ${taskId} failed`);\n }\n await new Promise((r) => setTimeout(r, pollIntervalMs));\n }\n\n throw new Error(`Task ${taskId} timed out after ${timeoutMs}ms`);\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type { ApiParams } from '../types/common.js';\nimport type { AsyncTaskResult, VirtualizorResponse } from '../types/common.js';\nimport type { CreateUserParams, User } from '../types/users.js';\n\ninterface ListUsersResponse extends VirtualizorResponse {\n users: Record<string, User>;\n}\n\nexport class UsersResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<Record<string, User>> {\n const res = await this.http.request<ListUsersResponse>('users', {}, {});\n return res.users;\n }\n\n async create(params: CreateUserParams): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('adduser', {}, params);\n }\n\n async delete(uid: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('users', {}, { delete: uid });\n }\n\n async suspend(uid: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('users', {}, { suspend: uid });\n }\n\n async unsuspend(uid: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('users', {}, { unsuspend: uid });\n }\n}\n","// VPS operation constants\nexport const VPS_CONSTANTS = {\n // Rebuild operation requires reos=1 flag\n REBUILD_REOS_FLAG: 1,\n // Migrate operation requires migrate=1 flag\n MIGRATE_FLAG: 1,\n // Migrate operation requires migrate_but=1 flag\n MIGRATE_BUT_FLAG: 1,\n} as const;\n","import { VPS_CONSTANTS } from '../constants/vps.js';\nimport type { HttpClient } from '../http.js';\nimport type { ApiParams } from '../types/common.js';\nimport type { AsyncTaskResult, VirtualizorResponse } from '../types/common.js';\nimport type {\n CloneVPSParams,\n CreateVPSParams,\n ListVPSParams,\n MigrateVPSParams,\n RebuildVPSParams,\n VNCInfo,\n VPS,\n VPSStatsResponse,\n} from '../types/vps.js';\n\ninterface ListVPSResponse extends VirtualizorResponse {\n vs: Record<string, VPS>;\n}\ninterface GetVPSResponse extends VirtualizorResponse {\n vs: Record<string, VPS>;\n}\n\nexport class VpsResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(filters: ListVPSParams = {}): Promise<Record<string, VPS>> {\n const res = await this.http.request<ListVPSResponse>('vs', {}, filters);\n return res.vs ?? {};\n }\n\n async get(vpsId: string): Promise<VPS> {\n const res = await this.http.request<GetVPSResponse>('vs', { vpsid: vpsId }, {});\n const vps = res.vs[vpsId];\n if (!vps) throw new Error(`VPS ${vpsId} not found in response`);\n return vps;\n }\n\n async create(params: CreateVPSParams): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('addvs', {}, params);\n }\n\n async delete(vpsId: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('vs', { delete: vpsId }, {});\n }\n\n async start(vpsId: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('vs', { vpsid: vpsId, action: 'start' }, {});\n }\n\n async stop(vpsId: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('vs', { vpsid: vpsId, action: 'stop' }, {});\n }\n\n async restart(vpsId: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('vs', { vpsid: vpsId, action: 'restart' }, {});\n }\n\n async poweroff(vpsId: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('vs', { vpsid: vpsId, action: 'poweroff' }, {});\n }\n\n async suspend(vpsId: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('vs', { suspend: vpsId }, {});\n }\n\n async unsuspend(vpsId: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('vs', { unsuspend: vpsId }, {});\n }\n\n async rebuild(vpsId: string, params: RebuildVPSParams): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>(\n 'rebuild',\n {},\n {\n vpsid: vpsId,\n reos: VPS_CONSTANTS.REBUILD_REOS_FLAG,\n ...params,\n },\n );\n }\n\n async clone(vpsId: string, params: CloneVPSParams): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>(\n 'clone',\n {},\n {\n vpsid: vpsId,\n ...params,\n },\n );\n }\n\n async migrate(vpsId: string, params: MigrateVPSParams): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>(\n 'migrate',\n {},\n {\n vpsid: vpsId,\n migrate: VPS_CONSTANTS.MIGRATE_FLAG,\n migrate_but: VPS_CONSTANTS.MIGRATE_BUT_FLAG,\n ...params,\n },\n );\n }\n\n async status(vpsId: string): Promise<unknown> {\n return this.http.request('vstatus', { vpsid: vpsId }, {});\n }\n\n async vnc(vpsId: string): Promise<VNCInfo> {\n return this.http.request<VNCInfo>('vnc', { vpsid: vpsId }, {});\n }\n\n async stats(vpsId: string): Promise<VPSStatsResponse> {\n return this.http.request<VPSStatsResponse>('vps_stats', {}, { vpsid: vpsId });\n }\n}\n","import { DEFAULT_CONFIG } from './config/defaults.js';\nimport { HttpClient } from './http.js';\nimport { PlansResource } from './resources/plans.js';\nimport { TasksResource } from './resources/tasks.js';\nimport { UsersResource } from './resources/users.js';\nimport { VpsResource } from './resources/vps.js';\nimport type { ResolvedConfig, VirtualizorConfig } from './types/config.js';\n\nexport class VirtualizorClient {\n readonly vps: VpsResource;\n readonly users: UsersResource;\n readonly plans: PlansResource;\n readonly tasks: TasksResource;\n\n constructor(config: VirtualizorConfig) {\n const resolved: ResolvedConfig = {\n host: config.host,\n apiKey: config.apiKey,\n apiPass: config.apiPass ?? '',\n port: config.port ?? DEFAULT_CONFIG.port,\n https: config.https ?? DEFAULT_CONFIG.https,\n rejectUnauthorized: config.rejectUnauthorized ?? DEFAULT_CONFIG.rejectUnauthorized,\n timeout: config.timeout ?? DEFAULT_CONFIG.timeout,\n debug: config.debug ?? DEFAULT_CONFIG.debug,\n };\n const http = new HttpClient(resolved);\n this.vps = new VpsResource(http);\n this.users = new UsersResource(http);\n this.plans = new PlansResource(http);\n this.tasks = new TasksResource(http);\n }\n}\n\nexport function createVirtualizorClient(config: VirtualizorConfig): VirtualizorClient {\n return new VirtualizorClient(config);\n}\n","export type IpsInput = string[] | Record<string, string> | string | undefined | null;\n\nexport type FormatIpsOptions = {\n /**\n * Choose the return type. Defaults to 'array'.\n * - 'array' returns string[]\n * - 'string' returns a joined string using `separator`\n */\n as?: 'array' | 'string';\n /** Separator used when returning a string. Defaults to ', '. */\n separator?: string;\n};\n\n/**\n * formatIps\n * - Default behavior: return an array of IP strings (string[])\n * - If options.as === 'string' it returns a joined string using options.separator\n */\nexport function formatIps(ips: IpsInput): string[];\nexport function formatIps(ips: IpsInput, options: FormatIpsOptions & { as: 'string' }): string;\nexport function formatIps(ips: IpsInput, options?: FormatIpsOptions): string | string[] {\n const as = options?.as ?? 'array';\n const separator = options?.separator ?? ', ';\n\n if (!ips) {\n return as === 'array' ? [] : '';\n }\n\n let result: string[] = [];\n\n if (Array.isArray(ips)) {\n result = ips.filter(Boolean);\n } else if (typeof ips === 'string') {\n const str = ips.trim();\n if (str === '') {\n result = [];\n } else if (str.includes(',')) {\n result = str\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n } else if (/\\s+/.test(str)) {\n result = str\n .split(/\\s+/)\n .map((s) => s.trim())\n .filter(Boolean);\n } else {\n result = [str];\n }\n } else if (typeof ips === 'object') {\n result = Object.values(ips).filter(Boolean);\n }\n\n return as === 'array' ? result : result.join(separator);\n}\n"]}
|
package/dist/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config/defaults.ts","../src/auth.ts","../src/http.ts","../src/resources/plans.ts","../src/resources/tasks.ts","../src/resources/users.ts","../src/constants/vps.ts","../src/resources/vps.ts","../src/client.ts","../src/utils/format-ips.ts"],"names":["http"],"mappings":"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","file":"index.mjs","sourcesContent":["export const DEFAULT_CONFIG = {\n port: 4085,\n https: true,\n rejectUnauthorized: false,\n timeout: 30000,\n debug: false,\n} as const;\n\nexport const DEFAULT_TASK_POLLING = {\n pollIntervalMs: 2000,\n timeoutMs: 120000,\n} as const;\n","import type { ApiParams } from './types/common.js';\n\nexport function buildQueryString(params: ApiParams, apiKey: string, apiPass: string): string {\n const clean: ApiParams = {};\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n clean[key] = value;\n }\n }\n\n const urlParams = new URLSearchParams();\n urlParams.set('api', 'json');\n urlParams.set('adminapikey', apiKey);\n urlParams.set('adminapipass', apiPass);\n\n for (const [key, value] of Object.entries(clean)) {\n urlParams.set(key, String(value));\n }\n\n return `?${urlParams.toString()}`;\n}\n","import http from 'node:http';\nimport https from 'node:https';\nimport { buildQueryString } from './auth.js';\nimport type { ApiParams } from './types/common.js';\nimport type { VirtualizorResponse } from './types/common.js';\nimport type { ResolvedConfig } from './types/config.js';\n\nexport class VirtualizorApiError extends Error {\n readonly code: number;\n\n constructor(message: string, code: number) {\n super(message);\n this.name = 'VirtualizorApiError';\n this.code = code;\n }\n}\n\nexport class HttpClient {\n constructor(private readonly config: ResolvedConfig) {}\n\n parseResponse<T extends VirtualizorResponse>(data: T): T {\n if (data.error && data.error.length > 0) {\n const first = data.error[0];\n if (first) {\n throw new VirtualizorApiError(first.msg, first.code);\n }\n }\n return data;\n }\n\n async request<T extends VirtualizorResponse>(\n act: string,\n queryParams: ApiParams = {},\n bodyParams: ApiParams = {},\n ): Promise<T> {\n const allQueryParams: ApiParams = { act, ...queryParams };\n const qs = buildQueryString(allQueryParams, this.config.apiKey, this.config.apiPass);\n\n const path = `/index.php${qs}`;\n\n const bodyString = Object.entries(bodyParams as Record<string, unknown>)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)\n .join('&');\n\n const data = await this.rawRequest(path, bodyString || undefined);\n return this.parseResponse(data as T);\n }\n\n private rawRequest(path: string, body?: string): Promise<VirtualizorResponse> {\n const transport = this.config.https ? https : http;\n const options: https.RequestOptions = {\n host: this.config.host,\n port: this.config.port,\n path,\n method: body ? 'POST' : 'GET',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n ...(body ? { 'Content-Length': Buffer.byteLength(body) } : {}),\n },\n ...(this.config.https\n ? { agent: new https.Agent({ rejectUnauthorized: this.config.rejectUnauthorized }) }\n : {}),\n };\n\n return new Promise((resolve, reject) => {\n const req = transport.request(options, (res) => {\n let raw = '';\n res.on('data', (chunk: Buffer) => {\n raw += chunk.toString();\n });\n res.on('end', () => {\n // Handle redirect (302) - usually means auth failed\n if (res.statusCode === 302 || res.statusCode === 301) {\n reject(\n new Error(\n `Redirect detected (status ${res.statusCode}). Authentication failed. ` +\n `Check your API credentials. Location: ${res.headers.location}`,\n ),\n );\n return;\n }\n\n try {\n resolve(JSON.parse(raw) as VirtualizorResponse);\n } catch (err) {\n if (this.config.debug)\n console.debug('[Virtualizor] Raw response (first 500 chars):', raw.slice(0, 500));\n reject(\n new Error(\n `Failed to parse response: ${raw.slice(0, 200)}. Parse error: ${err instanceof Error ? err.message : String(err)}`,\n ),\n );\n }\n });\n });\n\n req.setTimeout(this.config.timeout, () => {\n req.destroy(new Error(`Request timed out after ${this.config.timeout}ms`));\n });\n\n req.on('error', reject);\n\n if (body) {\n req.write(body);\n }\n\n req.end();\n });\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type { ApiParams } from '../types/common.js';\nimport type { AsyncTaskResult, VirtualizorResponse } from '../types/common.js';\nimport type { CreatePlanParams, Plan } from '../types/plans.js';\n\ninterface ListPlansResponse extends VirtualizorResponse {\n plans: Record<string, Plan>;\n}\nexport class PlansResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<Record<string, Plan>> {\n const res = await this.http.request<ListPlansResponse>('plans', {}, {});\n return res.plans;\n }\n\n async create(params: CreatePlanParams): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('addplan', {}, params);\n }\n\n async delete(planId: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('plans', {}, { delete: planId });\n }\n}\n","import { DEFAULT_TASK_POLLING } from '../config/defaults.js';\nimport type { HttpClient } from '../http.js';\nimport type { VirtualizorResponse } from '../types/common.js';\nimport type { Task } from '../types/tasks.js';\n\ninterface TasksResponse extends VirtualizorResponse {\n tasks: Record<string, Task>;\n}\n\nexport class TasksResource {\n constructor(private readonly http: HttpClient) {}\n\n async get(taskId: string): Promise<Task | undefined> {\n const res = await this.http.request<TasksResponse>('tasks', { taskid: taskId }, {});\n return res.tasks[taskId];\n }\n\n async wait(\n taskId: string,\n options: { pollIntervalMs?: number; timeoutMs?: number } = {},\n ): Promise<Task> {\n const {\n pollIntervalMs = DEFAULT_TASK_POLLING.pollIntervalMs,\n timeoutMs = DEFAULT_TASK_POLLING.timeoutMs,\n } = options;\n const deadline = Date.now() + timeoutMs;\n\n while (Date.now() < deadline) {\n const task = await this.get(taskId);\n if (!task) throw new Error(`Task ${taskId} not found`);\n if (task.status === '1' || task.status === 'done') return task;\n if (task.status === 'error' || task.status === '-1') {\n throw new Error(`Task ${taskId} failed`);\n }\n await new Promise((r) => setTimeout(r, pollIntervalMs));\n }\n\n throw new Error(`Task ${taskId} timed out after ${timeoutMs}ms`);\n }\n}\n","import type { HttpClient } from '../http.js';\nimport type { ApiParams } from '../types/common.js';\nimport type { AsyncTaskResult, VirtualizorResponse } from '../types/common.js';\nimport type { CreateUserParams, User } from '../types/users.js';\n\ninterface ListUsersResponse extends VirtualizorResponse {\n users: Record<string, User>;\n}\n\nexport class UsersResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(): Promise<Record<string, User>> {\n const res = await this.http.request<ListUsersResponse>('users', {}, {});\n return res.users;\n }\n\n async create(params: CreateUserParams): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('adduser', {}, params);\n }\n\n async delete(uid: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('users', {}, { delete: uid });\n }\n\n async suspend(uid: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('users', {}, { suspend: uid });\n }\n\n async unsuspend(uid: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('users', {}, { unsuspend: uid });\n }\n}\n","// VPS operation constants\nexport const VPS_CONSTANTS = {\n // Rebuild operation requires reos=1 flag\n REBUILD_REOS_FLAG: 1,\n // Migrate operation requires migrate=1 flag\n MIGRATE_FLAG: 1,\n // Migrate operation requires migrate_but=1 flag\n MIGRATE_BUT_FLAG: 1,\n} as const;\n","import { VPS_CONSTANTS } from '../constants/vps.js';\nimport type { HttpClient } from '../http.js';\nimport type { ApiParams } from '../types/common.js';\nimport type { AsyncTaskResult, VirtualizorResponse } from '../types/common.js';\nimport type {\n CloneVPSParams,\n CreateVPSParams,\n ListVPSParams,\n MigrateVPSParams,\n RebuildVPSParams,\n VNCInfo,\n VPS,\n VPSStatsResponse,\n} from '../types/vps.js';\n\ninterface ListVPSResponse extends VirtualizorResponse {\n vs: Record<string, VPS>;\n}\ninterface GetVPSResponse extends VirtualizorResponse {\n vs: Record<string, VPS>;\n}\n\nexport class VpsResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(filters: ListVPSParams = {}): Promise<Record<string, VPS>> {\n const res = await this.http.request<ListVPSResponse>('vs', {}, filters);\n return res.vs ?? {};\n }\n\n async get(vpsId: string): Promise<VPS> {\n const res = await this.http.request<GetVPSResponse>('vs', { vpsid: vpsId }, {});\n const vps = res.vs[vpsId];\n if (!vps) throw new Error(`VPS ${vpsId} not found in response`);\n return vps;\n }\n\n async create(params: CreateVPSParams): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('addvs', {}, params);\n }\n\n async delete(vpsId: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('vs', { delete: vpsId }, {});\n }\n\n async start(vpsId: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('vs', { vpsid: vpsId, action: 'start' }, {});\n }\n\n async stop(vpsId: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('vs', { vpsid: vpsId, action: 'stop' }, {});\n }\n\n async restart(vpsId: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('vs', { vpsid: vpsId, action: 'restart' }, {});\n }\n\n async poweroff(vpsId: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('vs', { vpsid: vpsId, action: 'poweroff' }, {});\n }\n\n async suspend(vpsId: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('vs', { suspend: vpsId }, {});\n }\n\n async unsuspend(vpsId: string): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>('vs', { unsuspend: vpsId }, {});\n }\n\n async rebuild(vpsId: string, params: RebuildVPSParams): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>(\n 'rebuild',\n {},\n {\n vpsid: vpsId,\n reos: VPS_CONSTANTS.REBUILD_REOS_FLAG,\n ...params,\n },\n );\n }\n\n async clone(vpsId: string, params: CloneVPSParams): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>(\n 'clone',\n {},\n {\n vpsid: vpsId,\n ...params,\n },\n );\n }\n\n async migrate(vpsId: string, params: MigrateVPSParams): Promise<AsyncTaskResult> {\n return this.http.request<AsyncTaskResult>(\n 'migrate',\n {},\n {\n vpsid: vpsId,\n migrate: VPS_CONSTANTS.MIGRATE_FLAG,\n migrate_but: VPS_CONSTANTS.MIGRATE_BUT_FLAG,\n ...params,\n },\n );\n }\n\n async status(vpsId: string): Promise<unknown> {\n return this.http.request('vstatus', { vpsid: vpsId }, {});\n }\n\n async vnc(vpsId: string): Promise<VNCInfo> {\n return this.http.request<VNCInfo>('vnc', { vpsid: vpsId }, {});\n }\n\n async stats(vpsId: string): Promise<VPSStatsResponse> {\n return this.http.request<VPSStatsResponse>('vps_stats', {}, { vpsid: vpsId });\n }\n}\n","import { DEFAULT_CONFIG } from './config/defaults.js';\nimport { HttpClient } from './http.js';\nimport { PlansResource } from './resources/plans.js';\nimport { TasksResource } from './resources/tasks.js';\nimport { UsersResource } from './resources/users.js';\nimport { VpsResource } from './resources/vps.js';\nimport type { ResolvedConfig, VirtualizorConfig } from './types/config.js';\n\nexport class VirtualizorClient {\n readonly vps: VpsResource;\n readonly users: UsersResource;\n readonly plans: PlansResource;\n readonly tasks: TasksResource;\n\n constructor(config: VirtualizorConfig) {\n const resolved: ResolvedConfig = {\n host: config.host,\n apiKey: config.apiKey,\n apiPass: config.apiPass ?? '',\n port: config.port ?? DEFAULT_CONFIG.port,\n https: config.https ?? DEFAULT_CONFIG.https,\n rejectUnauthorized: config.rejectUnauthorized ?? DEFAULT_CONFIG.rejectUnauthorized,\n timeout: config.timeout ?? DEFAULT_CONFIG.timeout,\n debug: config.debug ?? DEFAULT_CONFIG.debug,\n };\n const http = new HttpClient(resolved);\n this.vps = new VpsResource(http);\n this.users = new UsersResource(http);\n this.plans = new PlansResource(http);\n this.tasks = new TasksResource(http);\n }\n}\n\nexport function createVirtualizorClient(config: VirtualizorConfig): VirtualizorClient {\n return new VirtualizorClient(config);\n}\n","export type IpsInput = string[] | Record<string, string> | string | undefined | null;\n\nexport type FormatIpsOptions = {\n /**\n * Choose the return type. Defaults to 'array'.\n * - 'array' returns string[]\n * - 'string' returns a joined string using `separator`\n */\n as?: 'array' | 'string';\n /** Separator used when returning a string. Defaults to ', '. */\n separator?: string;\n};\n\n/**\n * formatIps\n * - Default behavior: return an array of IP strings (string[])\n * - If options.as === 'string' it returns a joined string using options.separator\n */\nexport function formatIps(ips: IpsInput): string[];\nexport function formatIps(ips: IpsInput, options: FormatIpsOptions & { as: 'string' }): string;\nexport function formatIps(ips: IpsInput, options?: FormatIpsOptions): string | string[] {\n const as = options?.as ?? 'array';\n const separator = options?.separator ?? ', ';\n\n if (!ips) {\n return as === 'array' ? [] : '';\n }\n\n let result: string[] = [];\n\n if (Array.isArray(ips)) {\n result = ips.filter(Boolean);\n } else if (typeof ips === 'string') {\n const str = ips.trim();\n if (str === '') {\n result = [];\n } else if (str.includes(',')) {\n result = str\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n } else if (/\\s+/.test(str)) {\n result = str\n .split(/\\s+/)\n .map((s) => s.trim())\n .filter(Boolean);\n } else {\n result = [str];\n }\n } else if (typeof ips === 'object') {\n result = Object.values(ips).filter(Boolean);\n }\n\n return as === 'array' ? result : result.join(separator);\n}\n"]}
|