@remnawave/backend-contract 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,5 +5,6 @@ export * from './inbounds';
5
5
  export * from './keygen';
6
6
  export * from './nodes';
7
7
  export * from './subscription';
8
+ export * from './system';
8
9
  export * from './users';
9
10
  export * from './xray';
@@ -0,0 +1,5 @@
1
+ export const SYSTEM_CONTROLLER = 'system' as const;
2
+
3
+ export const SYSTEM_ROUTES = {
4
+ STATS: 'stats',
5
+ } as const;
package/api/routes.ts CHANGED
@@ -70,4 +70,7 @@ export const REST_API = {
70
70
  DELETE: (uuid: string) =>
71
71
  `${ROOT}/${CONTROLLERS.HOSTS_CONTROLLER}/${CONTROLLERS.HOSTS_ROUTES.DELETE}/${uuid}`,
72
72
  },
73
+ SYSTEM: {
74
+ STATS: `${ROOT}/${CONTROLLERS.SYSTEM_CONTROLLER}/${CONTROLLERS.SYSTEM_ROUTES.STATS}`,
75
+ },
73
76
  } as const;
@@ -21,5 +21,6 @@ __exportStar(require("./inbounds"), exports);
21
21
  __exportStar(require("./keygen"), exports);
22
22
  __exportStar(require("./nodes"), exports);
23
23
  __exportStar(require("./subscription"), exports);
24
+ __exportStar(require("./system"), exports);
24
25
  __exportStar(require("./users"), exports);
25
26
  __exportStar(require("./xray"), exports);
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SYSTEM_ROUTES = exports.SYSTEM_CONTROLLER = void 0;
4
+ exports.SYSTEM_CONTROLLER = 'system';
5
+ exports.SYSTEM_ROUTES = {
6
+ STATS: 'stats',
7
+ };
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
25
35
  Object.defineProperty(exports, "__esModule", { value: true });
26
36
  exports.REST_API = exports.ROOT = void 0;
27
37
  const CONTROLLERS = __importStar(require("./controllers"));
@@ -78,4 +88,7 @@ exports.REST_API = {
78
88
  UPDATE_MANY: `${exports.ROOT}/${CONTROLLERS.HOSTS_CONTROLLER}/${CONTROLLERS.HOSTS_ROUTES.UPDATE_MANY}`,
79
89
  DELETE: (uuid) => `${exports.ROOT}/${CONTROLLERS.HOSTS_CONTROLLER}/${CONTROLLERS.HOSTS_ROUTES.DELETE}/${uuid}`,
80
90
  },
91
+ SYSTEM: {
92
+ STATS: `${exports.ROOT}/${CONTROLLERS.SYSTEM_CONTROLLER}/${CONTROLLERS.SYSTEM_ROUTES.STATS}`,
93
+ },
81
94
  };
@@ -21,5 +21,6 @@ __exportStar(require("./inbounds"), exports);
21
21
  __exportStar(require("./keygen"), exports);
22
22
  __exportStar(require("./nodes"), exports);
23
23
  __exportStar(require("./subscription"), exports);
24
+ __exportStar(require("./system"), exports);
24
25
  __exportStar(require("./users"), exports);
25
26
  __exportStar(require("./xray"), exports);
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GetStatsCommand = void 0;
4
+ const zod_1 = require("zod");
5
+ const api_1 = require("../../api");
6
+ const constants_1 = require("../../constants");
7
+ var GetStatsCommand;
8
+ (function (GetStatsCommand) {
9
+ GetStatsCommand.url = api_1.REST_API.SYSTEM.STATS;
10
+ GetStatsCommand.ResponseSchema = zod_1.z.object({
11
+ response: zod_1.z.object({
12
+ cpu: zod_1.z.object({
13
+ cores: zod_1.z.number(),
14
+ physicalCores: zod_1.z.number(),
15
+ }),
16
+ memory: zod_1.z.object({
17
+ total: zod_1.z.number(),
18
+ free: zod_1.z.number(),
19
+ used: zod_1.z.number(),
20
+ active: zod_1.z.number(),
21
+ available: zod_1.z.number(),
22
+ }),
23
+ uptime: zod_1.z.number(),
24
+ timestamp: zod_1.z.number(),
25
+ users: zod_1.z.object({
26
+ onlineLastMinute: zod_1.z.number(),
27
+ statusCounts: zod_1.z.record(zod_1.z.enum(Object.values(constants_1.USERS_STATUS)), zod_1.z.number()),
28
+ totalUsers: zod_1.z.number(),
29
+ totalTrafficBytes: zod_1.z.string(),
30
+ }),
31
+ }),
32
+ });
33
+ })(GetStatsCommand || (exports.GetStatsCommand = GetStatsCommand = {}));
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./get-stats.command"), exports);
@@ -7,6 +7,16 @@ const users_schema_1 = require("../../models/users.schema");
7
7
  var GetAllUsersCommand;
8
8
  (function (GetAllUsersCommand) {
9
9
  GetAllUsersCommand.url = api_1.REST_API.USERS.GET_ALL;
10
+ GetAllUsersCommand.SortableFields = [
11
+ 'username',
12
+ 'status',
13
+ 'expireAt',
14
+ 'createdAt',
15
+ 'onlineAt',
16
+ 'usedTrafficBytes',
17
+ 'trafficLimitBytes',
18
+ ];
19
+ GetAllUsersCommand.SearchableFields = ['username', 'shortUuid', 'subscriptionUuid', 'uuid'];
10
20
  GetAllUsersCommand.RequestQuerySchema = zod_1.z.object({
11
21
  limit: zod_1.z
12
22
  .string()
@@ -16,8 +26,15 @@ var GetAllUsersCommand;
16
26
  .string()
17
27
  .default('0')
18
28
  .transform((val) => parseInt(val)),
29
+ orderBy: zod_1.z.enum(GetAllUsersCommand.SortableFields).default('createdAt'),
30
+ orderDir: zod_1.z.enum(['asc', 'desc']).default('desc'),
31
+ search: zod_1.z.string().optional(),
32
+ searchBy: zod_1.z.enum(GetAllUsersCommand.SearchableFields).default('username'),
19
33
  });
20
34
  GetAllUsersCommand.ResponseSchema = zod_1.z.object({
21
- response: zod_1.z.array(users_schema_1.UsersSchema),
35
+ response: zod_1.z.object({
36
+ users: zod_1.z.array(users_schema_1.UsersSchema),
37
+ total: zod_1.z.number(),
38
+ }),
22
39
  });
23
40
  })(GetAllUsersCommand || (exports.GetAllUsersCommand = GetAllUsersCommand = {}));
@@ -233,4 +233,9 @@ exports.ERRORS = {
233
233
  message: 'Delete host error',
234
234
  httpCode: 500,
235
235
  },
236
+ GET_USER_STATS_ERROR: {
237
+ code: 'A048',
238
+ message: 'Get user stats error',
239
+ httpCode: 500,
240
+ },
236
241
  };
package/commands/index.ts CHANGED
@@ -5,5 +5,6 @@ export * from './inbounds';
5
5
  export * from './keygen';
6
6
  export * from './nodes';
7
7
  export * from './subscription';
8
+ export * from './system';
8
9
  export * from './users';
9
10
  export * from './xray';
@@ -0,0 +1,36 @@
1
+ import { z } from 'zod';
2
+ import { REST_API } from '../../api';
3
+ import { USERS_STATUS } from '../../constants';
4
+
5
+ export namespace GetStatsCommand {
6
+ export const url = REST_API.SYSTEM.STATS;
7
+
8
+ export const ResponseSchema = z.object({
9
+ response: z.object({
10
+ cpu: z.object({
11
+ cores: z.number(),
12
+ physicalCores: z.number(),
13
+ }),
14
+ memory: z.object({
15
+ total: z.number(),
16
+ free: z.number(),
17
+ used: z.number(),
18
+ active: z.number(),
19
+ available: z.number(),
20
+ }),
21
+ uptime: z.number(),
22
+ timestamp: z.number(),
23
+ users: z.object({
24
+ onlineLastMinute: z.number(),
25
+ statusCounts: z.record(
26
+ z.enum(Object.values(USERS_STATUS) as [string, ...string[]]),
27
+ z.number(),
28
+ ),
29
+ totalUsers: z.number(),
30
+ totalTrafficBytes: z.string(),
31
+ }),
32
+ }),
33
+ });
34
+
35
+ export type Response = z.infer<typeof ResponseSchema>;
36
+ }
@@ -0,0 +1 @@
1
+ export * from './get-stats.command';
@@ -5,6 +5,21 @@ import { UsersSchema } from '../../models/users.schema';
5
5
  export namespace GetAllUsersCommand {
6
6
  export const url = REST_API.USERS.GET_ALL;
7
7
 
8
+ export const SortableFields = [
9
+ 'username',
10
+ 'status',
11
+ 'expireAt',
12
+ 'createdAt',
13
+ 'onlineAt',
14
+ 'usedTrafficBytes',
15
+ 'trafficLimitBytes',
16
+ ] as const;
17
+
18
+ export const SearchableFields = ['username', 'shortUuid', 'subscriptionUuid', 'uuid'] as const;
19
+
20
+ export type SortableField = (typeof SortableFields)[number];
21
+ export type SearchableField = (typeof SearchableFields)[number];
22
+
8
23
  export const RequestQuerySchema = z.object({
9
24
  limit: z
10
25
  .string()
@@ -14,12 +29,21 @@ export namespace GetAllUsersCommand {
14
29
  .string()
15
30
  .default('0')
16
31
  .transform((val) => parseInt(val)),
32
+ orderBy: z.enum(SortableFields).default('createdAt'),
33
+ orderDir: z.enum(['asc', 'desc']).default('desc'),
34
+ search: z.string().optional(),
35
+ searchBy: z.enum(SearchableFields).default('username'),
17
36
  });
18
37
 
38
+ // !TODO: add searchBy validation
39
+
19
40
  export type RequestQuery = z.infer<typeof RequestQuerySchema>;
20
41
 
21
42
  export const ResponseSchema = z.object({
22
- response: z.array(UsersSchema),
43
+ response: z.object({
44
+ users: z.array(UsersSchema),
45
+ total: z.number(),
46
+ }),
23
47
  });
24
48
 
25
49
  export type Response = z.infer<typeof ResponseSchema>;
@@ -230,4 +230,9 @@ export const ERRORS = {
230
230
  message: 'Delete host error',
231
231
  httpCode: 500,
232
232
  },
233
+ GET_USER_STATS_ERROR: {
234
+ code: 'A048',
235
+ message: 'Get user stats error',
236
+ httpCode: 500,
237
+ },
233
238
  } as const;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnawave/backend-contract",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "A contract library for Remnawave",
5
5
  "main": "index.js",
6
6
  "scripts": {