x3ui-api 1.0.5 → 1.0.6-3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "x3ui-api",
3
- "version": "1.0.5",
3
+ "version": "1.0.6-3",
4
4
  "description": "API client for x3ui panel",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -54,4 +54,6 @@ module.exports = class ClientBuilder {
54
54
  reset: this.reset
55
55
  };
56
56
  }
57
- }
57
+ }
58
+
59
+ module.exports.default = module.exports;
@@ -1,5 +1,6 @@
1
1
  import {AxiosInstance} from "axios";
2
2
  import {
3
+ DeepPartial,
3
4
  InboundConfig,
4
5
  LoginResponse,
5
6
  SystemStats,
@@ -19,7 +20,7 @@ export default class X3UIClient {
19
20
 
20
21
  addInbound(config: Omit<InboundConfig, 'id'>): Promise<InboundConfig>;
21
22
 
22
- updateInbound(id: number, config: Partial<InboundConfig>): Promise<void>;
23
+ updateInbound(id: number, config: DeepPartial<InboundConfig>): Promise<void>;
23
24
 
24
25
  deleteInbound(id: number): Promise<void>;
25
26
 
@@ -1,8 +1,13 @@
1
1
  const axios = require("axios");
2
2
 
3
3
  module.exports = class X3UIClient {
4
+
5
+ isAuthed = false;
6
+ config = {};
7
+
4
8
  constructor(config) {
5
- this.parseJSONSettings = config.parseJSONSettings || true;
9
+ this.config = config;
10
+ this.config.parseJSONSettings ??= true;
6
11
  this.client = axios.create({
7
12
  baseURL: config.baseURL,
8
13
  headers: config.token ? {
@@ -15,14 +20,14 @@ module.exports = class X3UIClient {
15
20
 
16
21
  /**
17
22
  * Login to the x3ui panel
18
- * @param {string} username Panel username
19
- * @param {string} password Panel password
23
+ * @param {string?} username Panel username
24
+ * @param {string?} password Panel password
20
25
  * @returns {Promise<{success: boolean, msg: string, obj: any}>} Login response with success status and token
21
26
  */
22
27
  async login(username, password) {
23
28
  const formData = new URLSearchParams();
24
- formData.append('username', username);
25
- formData.append('password', password);
29
+ formData.append('username', username || this.config.username);
30
+ formData.append('password', password || this.config.password);
26
31
 
27
32
  const response = await this.client.post('/login', formData, {
28
33
  headers: {
@@ -32,12 +37,16 @@ module.exports = class X3UIClient {
32
37
 
33
38
  if (response.data.success) {
34
39
  this.client.defaults.headers.Cookie = `lang=en-US; ${response.headers.get("set-cookie")[0].split(";")[0]}`;
40
+ this.isAuthed = true;
35
41
  }
36
42
 
37
43
  return response.data;
38
44
  }
39
45
 
40
46
  async getSystemStats() {
47
+ if(!this.isAuthed) {
48
+ await this.login();
49
+ }
41
50
  const response = await this.client.post('/server/status');
42
51
  return response.data.obj;
43
52
  }
@@ -61,6 +70,9 @@ module.exports = class X3UIClient {
61
70
  * }>>}
62
71
  */
63
72
  async getInbounds() {
73
+ if(!this.isAuthed) {
74
+ await this.login();
75
+ }
64
76
  const response = await this.client.get('/panel/api/inbounds/list');
65
77
  let inbounds = response.data.obj;
66
78
  if (this.parseJSONSettings) {
@@ -106,6 +118,9 @@ module.exports = class X3UIClient {
106
118
  * @returns {Promise<void>}
107
119
  */
108
120
  async addInbound(config) {
121
+ if(!this.isAuthed) {
122
+ await this.login();
123
+ }
109
124
  config = this.stringifyInbound(config);
110
125
  const response = await this.client.post('/panel/api/inbounds/add', config);
111
126
  if(!response.data.success)
@@ -120,6 +135,9 @@ module.exports = class X3UIClient {
120
135
  * @returns {Promise<void>}
121
136
  */
122
137
  async updateInbound(id, config) {
138
+ if(!this.isAuthed) {
139
+ await this.login();
140
+ }
123
141
  config = this.stringifyInbound(config);
124
142
  const response = await this.client.post(`/panel/api/inbounds/update/${id}`, config);
125
143
  if(!response.data.success)
@@ -133,6 +151,9 @@ module.exports = class X3UIClient {
133
151
  * @returns {Promise<void>}
134
152
  */
135
153
  async deleteInbound(id) {
154
+ if(!this.isAuthed) {
155
+ await this.login();
156
+ }
136
157
  await this.client.post(`/panel/api/inbounds/del/${id}`);
137
158
  }
138
159
 
@@ -141,7 +162,12 @@ module.exports = class X3UIClient {
141
162
  * @returns {Promise<{privateKey: string, publicKey: string}>} New X25519 key pair
142
163
  */
143
164
  async getNewX25519Cert() {
165
+ if(!this.isAuthed) {
166
+ await this.login();
167
+ }
144
168
  const response = await this.client.post('/server/getNewX25519Cert');
145
169
  return response.data.obj;
146
170
  }
147
- }
171
+ }
172
+
173
+ module.exports.default = module.exports;
package/src/index.d.ts CHANGED
@@ -1,11 +1,17 @@
1
1
  import X3UIClient from "./core/X3UIClient";
2
2
 
3
+ export type DeepPartial<T> = {
4
+ [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
5
+ };
6
+
3
7
  export default X3UIClient;
4
8
 
5
9
  export interface X3UIConfig {
6
10
  baseURL: string;
7
11
  token?: string;
8
12
  parseJSONSettings?: boolean;
13
+ username?: string;
14
+ password?: string;
9
15
  }
10
16
 
11
17
  export interface LoginResponse {
package/src/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  const X3UIClient = require('./core/X3UIClient');
2
2
 
3
3
  module.exports = X3UIClient;
4
+ module.exports.default = X3UIClient;
@@ -1,9 +1,9 @@
1
- import X3UIClient, {ClientSettings, InboundConfig} from "../../index";
2
- import ClientBuilder from "../../core/ClientBuilder";
1
+ import X3UIClient, {ClientSettings, InboundConfig, DeepPartial} from "../../index";
2
+ import RealityClientBuilder from "./RealityClientBuilder";
3
3
 
4
4
  export default class RealityBuilder {
5
5
 
6
- constructor(client: X3UIClient, inbound?: Partial<InboundConfig>);
6
+ constructor(client: X3UIClient, inbound?: DeepPartial<InboundConfig>);
7
7
 
8
8
  /**
9
9
  * Set the port for the inbound. If not provided, will auto-generate unused port
@@ -53,14 +53,21 @@ export default class RealityBuilder {
53
53
  /**
54
54
  * Add a new client to the inbound
55
55
  */
56
- addClient(options?: Partial<ClientSettings>): ClientBuilder;
56
+ addClient(options?: DeepPartial<ClientSettings>): RealityClientBuilder;
57
57
 
58
58
  /**
59
59
  * Get connection link for a client
60
60
  * @param clientIndex Index of the client (defaults to 0)
61
61
  * @param host Optional host address (defaults to listenIP or 'localhost')
62
62
  */
63
- getClientLink(clientIndex?: number, host?: string): string;
63
+ getClientLinkByIndex(clientIndex?: number, host?: string): string;
64
+
65
+ /**
66
+ * Get connection link for a client
67
+ * @param email Email of the client
68
+ * @param host Optional host address (defaults to listenIP or 'localhost')
69
+ */
70
+ getClientLinkByEmail(email: string, host?: string): string;
64
71
 
65
72
  /**
66
73
  * Build the final inbound config
@@ -107,7 +107,7 @@ module.exports = class RealityBuilder {
107
107
  return builder;
108
108
  }
109
109
 
110
- getClientLink(clientIndex = 0, host) {
110
+ getClientLinkByIndex(clientIndex = 0, host) {
111
111
  if (clientIndex < 0 || clientIndex >= this.clients.length) {
112
112
  throw new Error('Invalid client index');
113
113
  }
@@ -115,6 +115,14 @@ module.exports = class RealityBuilder {
115
115
  return client.getLink(host || this.listenIP || 'localhost', this.port);
116
116
  }
117
117
 
118
+ getClientLinkByEmail(email, host) {
119
+ const client = this.clients.find(client => client.email === email);
120
+ if (!client) {
121
+ throw new Error('Client not found');
122
+ }
123
+ return client.getLink(host || this.listenIP || 'localhost', this.port);
124
+ }
125
+
118
126
  generateRandomPort() {
119
127
  return Math.floor(Math.random() * (65535 - 1024) + 1024);
120
128
  }
@@ -220,4 +228,6 @@ module.exports = class RealityBuilder {
220
228
  }
221
229
  };
222
230
  }
223
- }
231
+ }
232
+
233
+ module.exports.default = module.exports;
@@ -22,4 +22,6 @@ module.exports = class RealityClientBuilder extends ClientBuilder {
22
22
 
23
23
  return `${protocol}://${id}@${host}:${port}?${params.toString()}#${encodeURIComponent(this.email || 'default')}`;
24
24
  }
25
- }
25
+ }
26
+
27
+ module.exports.default = module.exports;
@@ -1,4 +1,6 @@
1
1
  module.exports = {
2
2
  RealityBuilder: require('./RealityBuilder'),
3
3
  RealityClientBuilder: require('./RealityClientBuilder')
4
- }
4
+ }
5
+
6
+ module.exports.default = module.exports
@@ -1,4 +1,4 @@
1
- import X3UIClient, {ClientSettings, InboundConfig} from "../../index";
1
+ import X3UIClient, { ClientSettings, DeepPartial, InboundConfig } from "../../index";
2
2
  import VmessClientBuilder from "./VmessClientBuilder";
3
3
 
4
4
  /**
@@ -6,7 +6,7 @@ import VmessClientBuilder from "./VmessClientBuilder";
6
6
  */
7
7
  export default class VmessBuilder {
8
8
 
9
- constructor(client: X3UIClient, inbound?: Partial<InboundConfig>);
9
+ constructor(client: X3UIClient, inbound?: DeepPartial<InboundConfig>);
10
10
 
11
11
  /**
12
12
  * Set the port for the inbound. If not provided, will auto-generate unused port
@@ -56,7 +56,7 @@ export default class VmessBuilder {
56
56
  /**
57
57
  * Add a new client to the inbound
58
58
  */
59
- addClient(options?: Partial<ClientSettings>): VmessClientBuilder;
59
+ addClient(options?: DeepPartial<ClientSettings>): VmessClientBuilder;
60
60
 
61
61
  /**
62
62
  * Get connection link for a client
@@ -186,4 +186,6 @@ module.exports = class VmessBuilder {
186
186
  allocate: this.allocate
187
187
  };
188
188
  }
189
- }
189
+ }
190
+
191
+ module.exports.default = module.exports;
@@ -89,4 +89,6 @@ module.exports = class VmessClientBuilder {
89
89
  const vmessLink = 'vmess://' + Buffer.from(JSON.stringify(vmessConfig)).toString('base64');
90
90
  return vmessLink;
91
91
  }
92
- }
92
+ }
93
+
94
+ module.exports.default = module.exports;
@@ -1,4 +1,6 @@
1
1
  module.exports = {
2
2
  VmessBuilder: require('./VmessBuilder'),
3
3
  VmessClientBuilder: require('./VmessClientBuilder')
4
- }
4
+ }
5
+
6
+ module.exports.default = module.exports
@@ -1,5 +1,5 @@
1
1
  import WireguardClientBuilder from './WireguardClientBuilder';
2
- import {ClientSettings} from "../../index";
2
+ import { ClientSettings, DeepPartial } from "../../index";
3
3
 
4
4
  /**
5
5
  * WireguardBuilder class for creating and managing Wireguard server configurations.
@@ -77,7 +77,7 @@ export default class WireguardBuilder {
77
77
  * @param options - Optional client settings
78
78
  * @returns A new WireguardClientBuilder instance for configuring the client
79
79
  */
80
- addClient(options?: Partial<ClientSettings>): WireguardClientBuilder;
80
+ addClient(options?: DeepPartial<ClientSettings>): WireguardClientBuilder;
81
81
 
82
82
  /**
83
83
  * Generates a connection link for a client.
@@ -202,3 +202,5 @@ module.exports = class WireguardBuilder {
202
202
  };
203
203
  }
204
204
  }
205
+
206
+ module.exports.default = module.exports;
@@ -86,3 +86,5 @@ module.exports = class WireguardClientBuilder extends ClientBuilder {
86
86
  return config;
87
87
  }
88
88
  }
89
+
90
+ module.exports.default = module.exports;
@@ -2,3 +2,5 @@ module.exports = {
2
2
  WireguardBuilder: require('./WireguardBuilder'),
3
3
  WireguardClientBuilder: require('./WireguardClientBuilder')
4
4
  }
5
+
6
+ module.exports.default = module.exports
package/src/index.d.ts~ DELETED
@@ -1,185 +0,0 @@
1
- import X3UIClient from "./core/X3UIClient";
2
-
3
- export default X3UIClient;
4
-
5
- export interface X3UIConfig {
6
- baseURL: string;
7
- token?: string;
8
- parseJSONSettings?: boolean;
9
- }
10
-
11
- export interface LoginResponse {
12
- success: boolean;
13
- msg: string;
14
- obj: any;
15
- }
16
-
17
- export interface InboundConfig {
18
- id?: number;
19
- up: number;
20
- down: number;
21
- total: number;
22
- remark: string;
23
- enable: boolean;
24
- expiryTime: number | null;
25
- clientStats: ClientStats[];
26
- listen: string;
27
- port: number;
28
- protocol: string;
29
- settings: string | InboundSettings;
30
- streamSettings: string | StreamSettings;
31
- tag: string;
32
- sniffing: string | SniffingSettings;
33
- allocate: string | AllocateSettings;
34
- }
35
-
36
- export interface AllocateSettings {
37
- strategy: string;
38
- refresh: number;
39
- concurrency: number;
40
- }
41
-
42
- export interface SniffingSettings {
43
- enabled: boolean;
44
- destOverride: string[];
45
- metadataOnly: boolean;
46
- routeOnly: boolean;
47
- }
48
-
49
- export interface StreamSettings {
50
- network: string;
51
- security: string;
52
- externalProxy: any[];
53
- realitySettings?: RealitySettings;
54
- tcpSettings?: TCPSettings;
55
- httpupgradeSettings?: HttpUpgradeSettings;
56
- }
57
-
58
- export interface HttpUpgradeSettings {
59
- acceptProxyProtocol: boolean;
60
- path: string;
61
- host: string;
62
- headers: Record<string, string>;
63
- }
64
-
65
- export interface TCPSettings {
66
- acceptProxyProtocol: boolean;
67
- header: {
68
- type: string;
69
- }
70
- }
71
-
72
- export interface RealitySettings {
73
- show: boolean;
74
- xver: number;
75
- dest: string;
76
- serverNames: string[];
77
- privateKey: string;
78
- minClient: string;
79
- maxClient: string;
80
- maxTimediff: number;
81
- shortIds: string[];
82
- settings: {
83
- publicKey: string;
84
- fingerprint: string;
85
- serverName: string;
86
- spiderX: string;
87
- }
88
- }
89
-
90
- export interface InboundSettings {
91
- clients: ClientSettings[];
92
- decryption: string;
93
- fallbacks: any[];
94
- }
95
-
96
- export interface ClientSettings {
97
- id: string;
98
- flow: string;
99
- email: string;
100
- limitIp: number;
101
- totalGB: number;
102
- expiryTime: number | null;
103
- enable: boolean;
104
- tgId: string;
105
- subId: string;
106
- reset: number;
107
- }
108
-
109
- export interface ClientStats {
110
- id: number;
111
- inboundId: number;
112
- enable: boolean;
113
- email: string;
114
- up: number;
115
- down: number;
116
- expiryTime: number | null;
117
- total: number;
118
- reset: number;
119
- }
120
-
121
- export interface SystemStats {
122
- cpu: number;
123
- cpuCores: number;
124
- logicalPro: number;
125
- cpuSpeedMhz: number;
126
- mem: {
127
- current: number;
128
- total: number;
129
- };
130
- swap: {
131
- current: number;
132
- total: number;
133
- }
134
- disk: {
135
- current: number;
136
- total: number;
137
- };
138
- xray: {
139
- state: boolean;
140
- errorMsg: string;
141
- version: string;
142
- };
143
- uptime: number;
144
- loads: number[];
145
- tcpCount: number;
146
- udpCount: number;
147
- netIO: {
148
- up: number;
149
- down: number;
150
- };
151
- netTraffic: {
152
- up: number;
153
- down: number;
154
- };
155
- publicIP: {
156
- ipv4: string;
157
- ipv6: string;
158
- }
159
- appStats: {
160
- threads: number;
161
- mem: number;
162
- uptime: number;
163
- }
164
- }
165
-
166
- export interface RealityInboundOptions {
167
- remark: string;
168
- port?: number;
169
- dest?: string;
170
- serverNames?: string[];
171
- privateKey?: string;
172
- publicKey?: string;
173
- shortIds?: string[];
174
- fingerprint?: string;
175
- listenIP?: string;
176
- expiryTime?: number;
177
- }
178
-
179
- export interface ClientOptions {
180
- id?: string;
181
- email?: string;
182
- totalGB?: number;
183
- expiryTime?: number;
184
- tgId?: string;
185
- }