@remnawave/xtls-sdk 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,29 @@
1
- # XTLS API SDK
1
+ # XTLS SDK
2
2
 
3
- A TypeScript SDK for interacting with Xray server statistics via gRPC.
3
+ ![GitHub top language](https://img.shields.io/github/languages/top/remnawave/xtls-sdk)
4
+ ![GitHub Repo stars](https://img.shields.io/github/stars/remnawave/xtls-sdk)
4
5
 
5
- This package provides a simple and type-safe way to retrieve various statistics from your Xray server, including system stats, user stats, and connection information.
6
+ ![npm version](https://img.shields.io/npm/v/@remnawave/xtls-sdk)
7
+ ![GitHub Tag](https://img.shields.io/github/v/tag/remnawave/xtls-sdk)
8
+
9
+ ![Build Status](https://img.shields.io/github/actions/workflow/status/remnawave/xtls-sdk/.github/workflows/deploy-lib.yml)
10
+ ![Downloads](https://img.shields.io/npm/dt/@remnawave/xtls-sdk)
11
+ ![License](https://img.shields.io/npm/l/@remnawave/xtls-sdk)
12
+ ![NPM Last Update](https://img.shields.io/npm/last-update/%40remnawave%2Fxtls-sdk)
13
+
14
+ ![Known Vulnerabilities](https://snyk.io/test/github/remnawave/xtls-sdk/badge.svg)
15
+ ![Coverage Status](https://img.shields.io/codecov/c/github/remnawave/xtls-sdk)
16
+
17
+ A TypeScript SDK for interacting with XRAY (XTLS) Core via gRPC API. This package provides a type-safe interface for managing and monitoring your XRAY server, including statistics, user management, and connection information.
18
+
19
+ ## Features
20
+
21
+ - 🔒 Type-safe API interactions
22
+ - 📊 Comprehensive statistics monitoring
23
+ - 👥 User management capabilities
24
+ - 🔄 Connection monitoring
25
+ - ⚡ Async/Promise-based API
26
+ - 📝 Detailed error handling
6
27
 
7
28
  ## Installation
8
29
 
@@ -10,95 +31,185 @@ This package provides a simple and type-safe way to retrieve various statistics
10
31
  npm install @remnawave/xtls-sdk
11
32
  # or
12
33
  yarn add @remnawave/xtls-sdk
34
+ # or
35
+ pnpm add @remnawave/xtls-sdk
13
36
  ```
14
37
 
15
- ## Usage
16
-
17
- ### Basic Setup
38
+ ## Quick Start
18
39
 
19
40
  ```typescript
20
41
  import { XtlsApi } from '@remnawave/xtls-sdk';
21
42
 
22
- // Create a new instance
23
- const xtlsApi = new XtlsApi('127.0.0.1', '8080');
43
+ // Initialize the API client
44
+ const api = new XtlsApi('127.0.0.1', '10085');
45
+
46
+ // Example: Get system statistics
47
+ const stats = await api.stats.getSysStats();
48
+ if (stats.isOk) {
49
+ console.log('System Stats:', stats.data);
50
+ }
51
+ ```
52
+
53
+ ## Core Features
54
+
55
+ ### Statistics Management
56
+
57
+ ```typescript
58
+ // System Statistics
59
+ const sysStats = await api.stats.getSysStats();
60
+
61
+ // User Statistics
62
+ const userStats = await api.stats.getUserStats('username');
63
+ const allUsers = await api.stats.getAllUsersStats();
64
+ const isOnline = await api.stats.getUserOnlineStatus('username');
65
+
66
+ // Traffic Statistics
67
+ const inbounds = await api.stats.getAllInboundsStats();
68
+ const outbounds = await api.stats.getAllOutboundsStats();
24
69
  ```
25
70
 
26
- ### Examples
71
+ ### Response Handling
27
72
 
28
- #### Get System Statistics
73
+ All API methods return a standardized response format:
29
74
 
30
75
  ```typescript
31
- const response = await xtlsApi.stats.getSysStats();
76
+ interface ISdkResponse<T> {
77
+ isOk: boolean;
78
+ data?: T;
79
+ message?: string;
80
+ code?: string;
81
+ }
82
+ ```
83
+
84
+ Example usage:
85
+
86
+ ```typescript
87
+ const response = await api.stats.getSysStats();
32
88
 
33
89
  if (response.isOk) {
34
- console.log('System Stats:', response.data);
90
+ // Success case
91
+ console.log('Stats:', response.data);
35
92
  } else {
36
- console.error('Error:', response.message);
93
+ // Error case
94
+ console.error(`Error ${response.code}: ${response.message}`);
37
95
  }
38
96
  ```
39
97
 
40
- #### Get User Statistics
98
+ ### Reset Options
99
+
100
+ Many methods support statistics reset functionality:
41
101
 
42
102
  ```typescript
43
- // Get stats for all users
44
- const allUsers = await xtlsApi.stats.getAllUsersStats();
103
+ // Get stats and reset counters
104
+ const stats = await api.stats.getUserStats('username', true);
105
+ ```
45
106
 
46
- // Get stats for a specific user
47
- const userStats = await xtlsApi.stats.getUserStats('username123');
107
+ ## API Reference
48
108
 
49
- // Check if a user is online
50
- const onlineStatus = await xtlsApi.stats.getUserOnlineStatus('username123');
51
- ```
109
+ ### XtlsApi
52
110
 
53
- #### Connection Statistics
111
+ Main client class for interacting with the XRAY server.
54
112
 
55
113
  ```typescript
56
- // Get all inbound connection stats
57
- const inbounds = await xtlsApi.stats.getAllInboundsStats();
114
+ const api = new XtlsApi(ip: string, port: string);
115
+ ```
58
116
 
59
- // Get specific inbound stats
60
- const inbound = await xtlsApi.stats.getInboundStats('http_in');
117
+ ### HandlerService
61
118
 
62
- // Get all outbound connection stats
63
- const outbounds = await xtlsApi.stats.getAllOutboundsStats();
119
+ Service for managing inbound handlers and their users.
64
120
 
65
- // Get specific outbound stats
66
- const outbound = await xtlsApi.stats.getOutboundStats('http_out');
67
- ```
121
+ #### User Management Methods
68
122
 
69
- ### Reset Statistics
123
+ | Method | Description | Parameters |
124
+ | ------------------------------------------- | -------------------------------- | -------------------------------------------------------- |
125
+ | `getInboundUsers(tag: string)` | Get all users from an inbound | `tag`: Inbound handler tag |
126
+ | `getInboundUsersCount(tag: string)` | Get count of users in an inbound | `tag`: Inbound handler tag |
127
+ | `removeUser(tag: string, username: string)` | Remove a user from an inbound | `tag`: Inbound handler tag<br>`username`: User to remove |
70
128
 
71
- Most methods support an optional `reset` parameter to clear statistics after retrieval:
129
+ #### Add User Methods
130
+
131
+ | Method | Description | Parameters |
132
+ | ------------------------------------------------------- | ------------------------- | ---------------------------------------------------------------- |
133
+ | `addTrojanUser(data: IAddTrojanUser)` | Add Trojan user | `data`: { tag, username, password, level } |
134
+ | `addVlessUser(data: IAddVlessUser)` | Add VLESS user | `data`: { tag, username, uuid, flow, level } |
135
+ | `addShadowsocksUser(data: IAddShadowsocksUser)` | Add Shadowsocks user | `data`: { tag, username, password, cipherType, ivCheck, level } |
136
+ | `addShadowsocks2022User(data: IAddShadowsocks2022User)` | Add Shadowsocks 2022 user | `data`: { tag, username, key, level } |
137
+ | `addSocksUser(data: IAddSocksUser)` | Add SOCKS user | `data`: { tag, username, socks_username, socks_password, level } |
138
+ | `addHttpUser(data: IAddHttpUser)` | Add HTTP user | `data`: { tag, username, http_username, http_password, level } |
139
+
140
+ Example usage:
72
141
 
73
142
  ```typescript
74
- // Get and reset user stats
75
- const stats = await xtlsApi.stats.getUserStats('username123', true);
143
+ // Get all users in an inbound
144
+ const users = await api.handler.getInboundUsers('main-inbound');
145
+ if (users.isOk) {
146
+ console.log('Users:', users.data.users);
147
+ }
148
+
149
+ // Add a new Trojan user
150
+ const newUser = await api.handler.addTrojanUser({
151
+ tag: 'main-inbound',
152
+ username: 'user@example.com',
153
+ password: 'secure-password',
154
+ level: 0,
155
+ });
156
+
157
+ // Remove a user
158
+ const removed = await api.handler.removeUser('main-inbound', 'user@example.com');
159
+
160
+ // Get user count
161
+ const count = await api.handler.getInboundUsersCount('main-inbound');
162
+ if (count.isOk) {
163
+ console.log('Total users:', count.data);
164
+ }
76
165
  ```
77
166
 
78
- ## API Reference
167
+ ### StatsService
79
168
 
80
- ### XtlsApi
169
+ Statistics management service.
81
170
 
82
- - `constructor(ip: string, port: string)`: Creates a new XtlsApi instance
171
+ | Method | Description | Parameters |
172
+ | ----------------------------------------------------- | -------------------------------- | ---------------------------------------------------------------- |
173
+ | `getSysStats()` | Get system statistics | None |
174
+ | `getAllUsersStats(reset?: boolean)` | Get all users' statistics | `reset`: Reset stats after retrieval |
175
+ | `getUserStats(username: string, reset?: boolean)` | Get specific user statistics | `username`: Target user<br>`reset`: Reset stats after retrieval |
176
+ | `getUserOnlineStatus(username: string)` | Check user online status | `username`: Target user |
177
+ | `getAllInboundsStats(reset?: boolean)` | Get all inbound statistics | `reset`: Reset stats after retrieval |
178
+ | `getInboundStats(inbound: string, reset?: boolean)` | Get specific inbound statistics | `inbound`: Inbound tag<br>`reset`: Reset stats after retrieval |
179
+ | `getAllOutboundsStats(reset?: boolean)` | Get all outbound statistics | `reset`: Reset stats after retrieval |
180
+ | `getOutboundStats(outbound: string, reset?: boolean)` | Get specific outbound statistics | `outbound`: Outbound tag<br>`reset`: Reset stats after retrieval |
83
181
 
84
- ### StatsService
182
+ ## Error Handling
183
+
184
+ The SDK provides detailed error information through the response object:
185
+
186
+ ```typescript
187
+ try {
188
+ const response = await api.stats.getUserStats('username');
189
+ if (!response.isOk) {
190
+ console.error(`Operation failed: ${response.message}`);
191
+ console.error(`Error code: ${response.code}`);
192
+ }
193
+ } catch (error) {
194
+ console.error('Unexpected error:', error);
195
+ }
196
+ ```
197
+
198
+ # Contributors
85
199
 
86
- - `getSysStats()`: Get system statistics
87
- - `getAllUsersStats(reset?: boolean)`: Get statistics for all users
88
- - `getUserStats(username: string, reset?: boolean)`: Get statistics for a specific user
89
- - `getUserOnlineStatus(username: string)`: Check if a user is currently online
90
- - `getAllInboundsStats(reset?: boolean)`: Get statistics for all inbound connections
91
- - `getInboundStats(inbound: string, reset?: boolean)`: Get statistics for a specific inbound connection
92
- - `getAllOutboundsStats(reset?: boolean)`: Get statistics for all outbound connections
93
- - `getOutboundStats(outbound: string, reset?: boolean)`: Get statistics for a specific outbound connection
200
+ We ❤️‍🔥 contributors! If you'd like to contribute, please check out our [Contributing Guidelines](CONTRIBUTING.md) and feel free to submit a pull request or open an issue.
94
201
 
95
- All methods return a Promise with an `ISdkResponse` type that includes:
202
+ Check [open issues](https://github.com/remnawave/xtls-sdk/issues) to help the progress of this project.
96
203
 
97
- - `isOk`: Boolean indicating success/failure
98
- - `data`: The requested statistics (when successful)
99
- - `message`: Error message (when unsuccessful)
100
- - `code`: Error code (when unsuccessful)
204
+ <p align="center">
205
+ Thanks to the all contributors who have helped improve XTLS SDK:
206
+ </p>
207
+ <p align="center">
208
+ <a href="https://github.com/remnawave/xtls-sdk/graphs/contributors">
209
+ <img src="https://contrib.rocks/image?repo=remnawave/xtls-sdk" />
210
+ </a>
211
+ </p>
101
212
 
102
213
  ## License
103
214
 
104
- MIT
215
+ MIT License - see the [LICENSE](LICENSE) file for details.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=stats.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.spec.d.ts","sourceRoot":"","sources":["../../tests/stats.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const index_1 = require("../index");
4
+ describe('StatsService', () => {
5
+ const validIp = '127.0.0.1';
6
+ const validPort = '8080';
7
+ let api;
8
+ beforeEach(() => {
9
+ api = new index_1.XtlsApi(validIp, validPort);
10
+ });
11
+ describe('System Stats', () => {
12
+ it('should get system stats', async () => {
13
+ const response = await api.stats.getSysStats();
14
+ expect(response.isOk).toBe(true);
15
+ if (response.isOk) {
16
+ expect(response.data).toBeDefined();
17
+ }
18
+ });
19
+ });
20
+ describe('User Stats', () => {
21
+ const testUsername = 'testUser';
22
+ it('should get all users stats', async () => {
23
+ const response = await api.stats.getAllUsersStats();
24
+ expect(response.isOk).toBe(true);
25
+ if (response.isOk) {
26
+ expect(Array.isArray(response.data?.users)).toBe(true);
27
+ }
28
+ });
29
+ it('should get all users stats with reset', async () => {
30
+ const response = await api.stats.getAllUsersStats(true);
31
+ expect(response.isOk).toBe(true);
32
+ });
33
+ it('should get specific user stats', async () => {
34
+ const response = await api.stats.getUserStats(testUsername);
35
+ expect(response.isOk).toBe(true);
36
+ });
37
+ it('should get user online status', async () => {
38
+ const response = await api.stats.getUserOnlineStatus(testUsername);
39
+ expect(response.isOk).toBe(true);
40
+ if (response.isOk) {
41
+ expect(typeof response.data?.online).toBe('boolean');
42
+ }
43
+ });
44
+ });
45
+ describe('Inbound Stats', () => {
46
+ const testInbound = 'testInbound';
47
+ it('should get all inbounds stats', async () => {
48
+ const response = await api.stats.getAllInboundsStats();
49
+ expect(response.isOk).toBe(true);
50
+ if (response.isOk) {
51
+ expect(Array.isArray(response.data?.inbounds)).toBe(true);
52
+ }
53
+ });
54
+ it('should get specific inbound stats', async () => {
55
+ const response = await api.stats.getInboundStats(testInbound);
56
+ expect(response.isOk).toBe(true);
57
+ });
58
+ it('should get all inbounds stats with reset', async () => {
59
+ const response = await api.stats.getAllInboundsStats(true);
60
+ expect(response.isOk).toBe(true);
61
+ });
62
+ });
63
+ describe('Outbound Stats', () => {
64
+ const testOutbound = 'testOutbound';
65
+ it('should get all outbounds stats', async () => {
66
+ const response = await api.stats.getAllOutboundsStats();
67
+ expect(response.isOk).toBe(true);
68
+ if (response.isOk) {
69
+ expect(Array.isArray(response.data?.outbounds)).toBe(true);
70
+ }
71
+ });
72
+ it('should get specific outbound stats', async () => {
73
+ const response = await api.stats.getOutboundStats(testOutbound);
74
+ expect(response.isOk).toBe(true);
75
+ });
76
+ it('should get all outbounds stats with reset', async () => {
77
+ const response = await api.stats.getAllOutboundsStats(true);
78
+ expect(response.isOk).toBe(true);
79
+ });
80
+ });
81
+ afterEach(async () => {
82
+ if (api?.channel) {
83
+ await api.channel.close();
84
+ }
85
+ });
86
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnawave/xtls-sdk",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "A Typescript SDK for XRAY (XTLS) Core GRPC Api",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -9,11 +9,37 @@
9
9
  ],
10
10
  "scripts": {
11
11
  "prepublish": "rm -rf build && tsc",
12
- "build": "tsc"
12
+ "build": "tsc",
13
+ "test": "jest",
14
+ "test:watch": "jest --watch"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/remnawave/xtls-sdk.git"
19
+ },
20
+ "homepage": "https://github.com/remnawave/xtls-sdk#readme",
21
+ "bugs": {
22
+ "url": "https://github.com/remnawave/xtls-sdk/issues"
13
23
  },
14
24
  "author": "Remnawave",
15
25
  "license": "MIT",
16
- "keywords": [],
26
+ "keywords": [
27
+ "xtls",
28
+ "grpc",
29
+ "sdk",
30
+ "xray core api",
31
+ "typescript",
32
+ "xray",
33
+ "xray-core",
34
+ "api",
35
+ "client",
36
+ "network",
37
+ "proxy",
38
+ "protocol",
39
+ "trojan",
40
+ "vless",
41
+ "vmess"
42
+ ],
17
43
  "dependencies": {
18
44
  "long": "^5.2.3",
19
45
  "nice-grpc": "^2.1.10",
@@ -21,8 +47,29 @@
21
47
  "tar": "^7.4.3"
22
48
  },
23
49
  "devDependencies": {
50
+ "@types/jest": "^29.5.2",
24
51
  "@types/node": "^22.9.0",
25
52
  "grpc-tools": "^1.12.4",
26
- "ts-proto": "^2.2.7"
53
+ "ts-jest": "^29.1.0",
54
+ "jest": "^29.5.0",
55
+ "ts-proto": "^2.2.7",
56
+ "typescript": "^5.6.3"
57
+ },
58
+ "jest": {
59
+ "moduleFileExtensions": [
60
+ "js",
61
+ "json",
62
+ "ts"
63
+ ],
64
+ "rootDir": ".",
65
+ "testRegex": ".*\\.spec\\.ts$",
66
+ "transform": {
67
+ "^.+\\.(t|j)s$": "ts-jest"
68
+ },
69
+ "collectCoverageFrom": [
70
+ "**/*.(t|j)s"
71
+ ],
72
+ "coverageDirectory": "./coverage",
73
+ "testEnvironment": "node"
27
74
  }
28
75
  }