@simplysm/service-server 13.0.69 → 13.0.71
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 +48 -249
- package/dist/auth/jwt-manager.js +2 -2
- package/dist/auth/jwt-manager.js.map +1 -1
- package/dist/core/define-service.js +2 -2
- package/dist/core/define-service.js.map +1 -1
- package/dist/core/service-executor.js +5 -5
- package/dist/core/service-executor.js.map +1 -1
- package/dist/legacy/v1-auto-update-handler.d.ts +2 -2
- package/dist/legacy/v1-auto-update-handler.js +2 -2
- package/dist/legacy/v1-auto-update-handler.js.map +1 -1
- package/dist/service-server.js +11 -11
- package/dist/service-server.js.map +1 -1
- package/dist/services/auto-update-service.js +1 -1
- package/dist/services/auto-update-service.js.map +1 -1
- package/dist/services/orm-service.js +6 -6
- package/dist/services/orm-service.js.map +1 -1
- package/dist/transport/http/http-request-handler.js +1 -1
- package/dist/transport/http/http-request-handler.js.map +1 -1
- package/dist/transport/http/static-file-handler.js +3 -3
- package/dist/transport/http/upload-handler.js +2 -2
- package/dist/transport/http/upload-handler.js.map +1 -1
- package/dist/transport/socket/service-socket.js +2 -2
- package/dist/transport/socket/service-socket.js.map +1 -1
- package/dist/transport/socket/websocket-handler.d.ts.map +1 -1
- package/dist/transport/socket/websocket-handler.js +11 -9
- package/dist/transport/socket/websocket-handler.js.map +1 -1
- package/dist/utils/config-manager.js +7 -7
- package/dist/utils/config-manager.js.map +1 -1
- package/package.json +9 -9
- package/src/auth/jwt-manager.ts +2 -2
- package/src/core/define-service.ts +2 -2
- package/src/core/service-executor.ts +13 -13
- package/src/legacy/v1-auto-update-handler.ts +8 -8
- package/src/service-server.ts +28 -28
- package/src/services/auto-update-service.ts +1 -1
- package/src/services/orm-service.ts +6 -6
- package/src/transport/http/http-request-handler.ts +5 -5
- package/src/transport/http/static-file-handler.ts +7 -7
- package/src/transport/http/upload-handler.ts +3 -3
- package/src/transport/socket/service-socket.ts +4 -4
- package/src/transport/socket/websocket-handler.ts +12 -10
- package/src/utils/config-manager.ts +11 -11
- package/tests/define-service.spec.ts +85 -0
- package/tests/orm-service.spec.ts +83 -0
- package/tests/service-executor.spec.ts +114 -0
- package/docs/authentication.md +0 -114
- package/docs/built-in-services.md +0 -100
- package/docs/server.md +0 -374
- package/docs/transport.md +0 -273
package/README.md
CHANGED
|
@@ -1,279 +1,78 @@
|
|
|
1
1
|
# @simplysm/service-server
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Used together with `@simplysm/service-client` to configure WebSocket/HTTP communication between client and server.
|
|
3
|
+
Simplysm package - service module (server)
|
|
6
4
|
|
|
7
5
|
## Installation
|
|
8
6
|
|
|
9
|
-
```bash
|
|
10
|
-
npm install @simplysm/service-server
|
|
11
|
-
# or
|
|
12
7
|
pnpm add @simplysm/service-server
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## Main Modules
|
|
16
|
-
|
|
17
|
-
### Core Functions and Classes
|
|
18
|
-
|
|
19
|
-
- [`createServiceServer`](#basic-server-configuration) - Factory function for creating a `ServiceServer` instance
|
|
20
|
-
- [`ServiceServer`](docs/server.md#serviceserver) - Main server class. Creates a Fastify instance and configures routes/plugins
|
|
21
|
-
- [`defineService`](#custom-services) - Defines a service with a name and factory function
|
|
22
|
-
- [`ServiceContext`](docs/server.md#servicecontext) - Context object passed to service factory functions
|
|
23
|
-
- [`createServiceContext`](docs/server.md#createservicecontext) - Factory function that creates a `ServiceContext` (exported for advanced use)
|
|
24
|
-
- [`runServiceMethod`](docs/server.md#runservicemethod) - Dispatches a service method call with auth checks and execution
|
|
25
|
-
- [`ServiceDefinition`](docs/server.md#servicedefinition) - Type describing a registered service (name + factory + authPermissions)
|
|
26
|
-
- [`ServiceMethods`](docs/server.md#servicemethods) - Type utility that extracts method signatures from a `ServiceDefinition`
|
|
27
|
-
|
|
28
|
-
### Authentication
|
|
29
|
-
|
|
30
|
-
- [`auth`](#authentication) - Wrapper that sets authentication requirements at service or method level
|
|
31
|
-
- [`getServiceAuthPermissions`](docs/authentication.md#getserviceauthpermissions) - Reads auth permissions from an `auth()`-wrapped function
|
|
32
|
-
- [`signJwt`](docs/authentication.md#jwt-functions) - Generate a JWT token (HS256, 12-hour expiration)
|
|
33
|
-
- [`verifyJwt`](docs/authentication.md#jwt-functions) - Verify and decode a JWT token
|
|
34
|
-
- [`decodeJwt`](docs/authentication.md#jwt-functions) - Decode a JWT token without verification (synchronous)
|
|
35
|
-
- [`AuthTokenPayload`](docs/authentication.md#authtokenpayload) - JWT payload interface (includes `roles`, `data`)
|
|
36
|
-
|
|
37
|
-
### Transport Layer - WebSocket
|
|
38
|
-
|
|
39
|
-
- [`WebSocketHandler`](docs/transport.md#websockethandler) - Interface for managing multiple WebSocket connections, routing messages, and broadcasting events
|
|
40
|
-
- `createWebSocketHandler` - Factory function that creates a `WebSocketHandler` instance
|
|
41
|
-
- [`ServiceSocket`](docs/transport.md#servicesocket) - Interface wrapping a single WebSocket connection. Manages ping/pong, protocol encoding/decoding, event listener management
|
|
42
|
-
- `createServiceSocket` - Factory function that creates a `ServiceSocket` instance
|
|
43
|
-
|
|
44
|
-
### Transport Layer - HTTP
|
|
45
|
-
|
|
46
|
-
- `handleHttpRequest` - Handles service method calls via HTTP at `/api/:service/:method`
|
|
47
|
-
- `handleUpload` - Handles multipart file upload at `/upload` (auth required)
|
|
48
|
-
- `handleStaticFile` - Serves static files from `rootPath/www/`. Prevents path traversal and blocks hidden files
|
|
49
|
-
|
|
50
|
-
### Protocol
|
|
51
|
-
|
|
52
|
-
- [`ProtocolWrapper`](docs/transport.md#protocolwrapper) - Interface for message encoding/decoding. Messages over 30KB are processed in worker threads
|
|
53
|
-
- `createProtocolWrapper` - Factory function that creates a `ProtocolWrapper` instance
|
|
54
|
-
|
|
55
|
-
### Built-in Services
|
|
56
|
-
|
|
57
|
-
- [`OrmService`](docs/built-in-services.md#ormservice) - DB connection/transaction/query execution (WebSocket only, auth required)
|
|
58
|
-
- `OrmServiceType` - Type alias for `OrmService` method signatures (for client-side type sharing)
|
|
59
|
-
- [`AutoUpdateService`](docs/built-in-services.md#autoupdateservice) - App auto-update (provides latest version query and download path)
|
|
60
|
-
- `AutoUpdateServiceType` - Type alias for `AutoUpdateService` method signatures (for client-side type sharing)
|
|
61
|
-
|
|
62
|
-
### Utilities
|
|
63
|
-
|
|
64
|
-
- [`getConfig`](docs/server.md#getconfig) - JSON config file loading with caching and real-time file watching
|
|
65
|
-
|
|
66
|
-
### Legacy
|
|
67
|
-
|
|
68
|
-
- [`handleV1Connection`](docs/transport.md#legacy-handlev1connection) - V1 protocol client compatibility handling (supports auto-update only)
|
|
69
|
-
|
|
70
|
-
## Usage
|
|
71
|
-
|
|
72
|
-
### Basic Server Configuration
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
import { createServiceServer } from "@simplysm/service-server";
|
|
76
|
-
|
|
77
|
-
const server = createServiceServer({
|
|
78
|
-
port: 8080,
|
|
79
|
-
rootPath: "/app/data",
|
|
80
|
-
services: [MyService],
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
// Start server
|
|
84
|
-
await server.listen();
|
|
85
|
-
|
|
86
|
-
// Receive events
|
|
87
|
-
server.on("ready", () => {
|
|
88
|
-
console.log("Server ready");
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
server.on("close", () => {
|
|
92
|
-
console.log("Server closed");
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
// Close server
|
|
96
|
-
await server.close();
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### Server Options
|
|
100
8
|
|
|
101
|
-
|
|
9
|
+
## Source Index
|
|
102
10
|
|
|
103
|
-
###
|
|
11
|
+
### Types
|
|
104
12
|
|
|
105
|
-
|
|
13
|
+
| Source | Exports | Description | Test |
|
|
14
|
+
|--------|---------|-------------|------|
|
|
15
|
+
| `src/types/server-options.ts` | `ServiceServerOptions` | Configuration interface for the service server (port, SSL, auth, services) | - |
|
|
106
16
|
|
|
107
|
-
|
|
108
|
-
import { defineService } from "@simplysm/service-server";
|
|
17
|
+
### Auth
|
|
109
18
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
19
|
+
| Source | Exports | Description | Test |
|
|
20
|
+
|--------|---------|-------------|------|
|
|
21
|
+
| `src/auth/auth-token-payload.ts` | `AuthTokenPayload` | JWT payload interface extending JWTPayload with roles and auth data | - |
|
|
22
|
+
| `src/auth/jwt-manager.ts` | `signJwt`, `verifyJwt`, `decodeJwt` | Sign, verify, and decode HS256 JWT tokens using the jose library | - |
|
|
114
23
|
|
|
115
|
-
|
|
116
|
-
return new Date();
|
|
117
|
-
},
|
|
118
|
-
}));
|
|
24
|
+
### Core
|
|
119
25
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
26
|
+
| Source | Exports | Description | Test |
|
|
27
|
+
|--------|---------|-------------|------|
|
|
28
|
+
| `src/core/define-service.ts` | `ServiceContext`, `createServiceContext`, `getServiceAuthPermissions`, `auth`, `ServiceDefinition`, `defineService`, `ServiceMethods` | Define services with typed context, auth wrappers, and method type extraction | `define-service.spec.ts` |
|
|
29
|
+
| `src/core/service-executor.ts` | `runServiceMethod` | Resolve a service method call and enforce auth permission checks | `service-executor.spec.ts` |
|
|
123
30
|
|
|
124
|
-
|
|
31
|
+
### Transport - Socket
|
|
125
32
|
|
|
126
|
-
|
|
33
|
+
| Source | Exports | Description | Test |
|
|
34
|
+
|--------|---------|-------------|------|
|
|
35
|
+
| `src/transport/socket/websocket-handler.ts` | `WebSocketHandler`, `createWebSocketHandler` | Manage multiple WebSocket connections, route messages, and broadcast events | - |
|
|
36
|
+
| `src/transport/socket/service-socket.ts` | `ServiceSocket`, `createServiceSocket` | Manage a single WebSocket connection with protocol encoding and keep-alive | - |
|
|
127
37
|
|
|
128
|
-
|
|
129
|
-
- `ctx.socket` - ServiceSocket instance (WebSocket only, undefined for HTTP)
|
|
130
|
-
- `ctx.http` - HTTP request/reply objects (HTTP only, undefined for WebSocket)
|
|
131
|
-
- `ctx.authInfo` - Authentication info (set via JWT token)
|
|
132
|
-
- `ctx.clientName` - Client identifier
|
|
133
|
-
- `ctx.clientPath` - Resolved per-client directory path (`rootPath/www/{clientName}`)
|
|
134
|
-
- `ctx.getConfig(section)` - Get server config by section name
|
|
38
|
+
### Transport - HTTP
|
|
135
39
|
|
|
136
|
-
|
|
40
|
+
| Source | Exports | Description | Test |
|
|
41
|
+
|--------|---------|-------------|------|
|
|
42
|
+
| `src/transport/http/http-request-handler.ts` | `handleHttpRequest` | Handle HTTP GET/POST API requests with JWT auth and parameter parsing | - |
|
|
43
|
+
| `src/transport/http/upload-handler.ts` | `handleUpload` | Handle multipart file uploads with JWT auth and UUID-based storage | - |
|
|
44
|
+
| `src/transport/http/static-file-handler.ts` | `handleStaticFile` | Serve static files from the www directory with path traversal protection | - |
|
|
137
45
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
```typescript
|
|
141
|
-
import { defineService, auth } from "@simplysm/service-server";
|
|
142
|
-
|
|
143
|
-
interface UserAuthInfo {
|
|
144
|
-
userId: number;
|
|
145
|
-
role: string;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Service-level auth: all methods require authentication
|
|
149
|
-
export const UserService = defineService("User", auth((ctx) => ({
|
|
150
|
-
getProfile: async (): Promise<unknown> => {
|
|
151
|
-
const userId = (ctx.authInfo as UserAuthInfo)?.userId;
|
|
152
|
-
// ...
|
|
153
|
-
},
|
|
154
|
-
|
|
155
|
-
deleteUser: auth(["admin"], async (targetId: number): Promise<void> => {
|
|
156
|
-
// Only users with admin role can call
|
|
157
|
-
}),
|
|
158
|
-
})));
|
|
159
|
-
|
|
160
|
-
export type UserServiceMethods = import("@simplysm/service-server").ServiceMethods<typeof UserService>;
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
#### Auth Patterns
|
|
164
|
-
|
|
165
|
-
**Method-level auth only:**
|
|
166
|
-
```typescript
|
|
167
|
-
export const MyService = defineService("My", (ctx) => ({
|
|
168
|
-
publicMethod: async (): Promise<void> => {
|
|
169
|
-
// No auth required
|
|
170
|
-
},
|
|
171
|
-
|
|
172
|
-
protectedMethod: auth(async (): Promise<void> => {
|
|
173
|
-
// Auth required
|
|
174
|
-
}),
|
|
175
|
-
|
|
176
|
-
adminMethod: auth(["admin"], async (): Promise<void> => {
|
|
177
|
-
// Auth + admin role required
|
|
178
|
-
}),
|
|
179
|
-
}));
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
**Service-level auth with method override:**
|
|
183
|
-
```typescript
|
|
184
|
-
// All methods require authentication by default
|
|
185
|
-
export const SecureService = defineService("Secure", auth((ctx) => ({
|
|
186
|
-
normalMethod: async (): Promise<void> => {
|
|
187
|
-
// Auth required (inherited from service level)
|
|
188
|
-
},
|
|
189
|
-
|
|
190
|
-
adminMethod: auth(["admin"], async (): Promise<void> => {
|
|
191
|
-
// Auth + admin role required
|
|
192
|
-
}),
|
|
193
|
-
})));
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
See [Authentication](docs/authentication.md) for JWT token management and permission handling.
|
|
197
|
-
|
|
198
|
-
### HTTP/WebSocket Communication
|
|
199
|
-
|
|
200
|
-
Service methods can be called via HTTP or WebSocket:
|
|
201
|
-
|
|
202
|
-
```
|
|
203
|
-
GET /api/My/hello?json=["World"]
|
|
204
|
-
POST /api/My/hello
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
See [HTTP API Call](docs/transport.md#http-api-call) and [ServiceSocket](docs/transport.md#servicesocket) for transport layer details.
|
|
208
|
-
|
|
209
|
-
### File Upload
|
|
210
|
-
|
|
211
|
-
Upload files via multipart request to the `/upload` endpoint:
|
|
212
|
-
|
|
213
|
-
```typescript
|
|
214
|
-
const formData = new FormData();
|
|
215
|
-
formData.append("file", file);
|
|
216
|
-
|
|
217
|
-
const response = await fetch("/upload", {
|
|
218
|
-
method: "POST",
|
|
219
|
-
headers: { Authorization: `Bearer ${token}` },
|
|
220
|
-
body: formData,
|
|
221
|
-
});
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
See [File Upload](docs/transport.md#file-upload) for more details.
|
|
225
|
-
|
|
226
|
-
### Event Publishing
|
|
227
|
-
|
|
228
|
-
Publish real-time events to connected WebSocket clients:
|
|
229
|
-
|
|
230
|
-
```typescript
|
|
231
|
-
import { defineEvent } from "@simplysm/service-common";
|
|
232
|
-
|
|
233
|
-
export const OrderUpdatedEvent = defineEvent<
|
|
234
|
-
{ orderId: number },
|
|
235
|
-
{ status: string }
|
|
236
|
-
>("OrderUpdatedEvent");
|
|
237
|
-
|
|
238
|
-
await server.emitEvent(
|
|
239
|
-
OrderUpdatedEvent,
|
|
240
|
-
(info) => info.orderId === 123,
|
|
241
|
-
{ status: "completed" },
|
|
242
|
-
);
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
See [Real-time Event Publishing](docs/transport.md#real-time-event-publishing) for more details.
|
|
46
|
+
### Protocol
|
|
246
47
|
|
|
247
|
-
|
|
48
|
+
| Source | Exports | Description | Test |
|
|
49
|
+
|--------|---------|-------------|------|
|
|
50
|
+
| `src/protocol/protocol-wrapper.ts` | `ProtocolWrapper`, `createProtocolWrapper` | Encode/decode service messages with automatic worker thread offloading | - |
|
|
248
51
|
|
|
249
|
-
|
|
52
|
+
### Services
|
|
250
53
|
|
|
251
|
-
|
|
252
|
-
|
|
54
|
+
| Source | Exports | Description | Test |
|
|
55
|
+
|--------|---------|-------------|------|
|
|
56
|
+
| `src/services/orm-service.ts` | `OrmService`, `OrmServiceType` | Built-in service exposing ORM database operations over WebSocket | `orm-service.spec.ts` |
|
|
57
|
+
| `src/services/auto-update-service.ts` | `AutoUpdateService`, `AutoUpdateServiceType` | Built-in service for serving the latest app update package by platform | - |
|
|
253
58
|
|
|
254
|
-
|
|
59
|
+
### Utils
|
|
255
60
|
|
|
256
|
-
|
|
257
|
-
|
|
61
|
+
| Source | Exports | Description | Test |
|
|
62
|
+
|--------|---------|-------------|------|
|
|
63
|
+
| `src/utils/config-manager.ts` | `getConfig` | Load and cache JSON config files with live-reload via file watcher | - |
|
|
258
64
|
|
|
259
|
-
|
|
260
|
-
port: 8080,
|
|
261
|
-
rootPath: "/app/data",
|
|
262
|
-
auth: { jwtSecret: "secret" },
|
|
263
|
-
services: [OrmService],
|
|
264
|
-
});
|
|
265
|
-
```
|
|
65
|
+
### Legacy
|
|
266
66
|
|
|
267
|
-
|
|
67
|
+
| Source | Exports | Description | Test |
|
|
68
|
+
|--------|---------|-------------|------|
|
|
69
|
+
| `src/legacy/v1-auto-update-handler.ts` | `handleV1Connection` | Handle V1 legacy WebSocket clients for auto-update only | - |
|
|
268
70
|
|
|
269
|
-
|
|
270
|
-
- **CORS**: `@fastify/cors` plugin configures CORS
|
|
271
|
-
- **Path Traversal Prevention**: Static file handler and client name validation block `..`, `/`, `\` characters
|
|
272
|
-
- **Hidden File Blocking**: Files starting with `.` return a 403 response
|
|
273
|
-
- **Directory Trailing Slash Redirect**: Directory requests without a trailing slash are redirected to the same path with a trailing slash (standard web server behavior)
|
|
274
|
-
- **Graceful Shutdown**: Detects `SIGINT`/`SIGTERM` signals to safely close WebSocket connections and server (10-second timeout)
|
|
71
|
+
### Main
|
|
275
72
|
|
|
276
|
-
|
|
73
|
+
| Source | Exports | Description | Test |
|
|
74
|
+
|--------|---------|-------------|------|
|
|
75
|
+
| `src/service-server.ts` | `ServiceServer`, `createServiceServer` | Main Fastify-based HTTP/WebSocket server with routing and graceful shutdown | - |
|
|
277
76
|
|
|
278
77
|
## License
|
|
279
78
|
|
package/dist/auth/jwt-manager.js
CHANGED
|
@@ -10,9 +10,9 @@ async function verifyJwt(jwtSecret, token) {
|
|
|
10
10
|
return payload;
|
|
11
11
|
} catch (err) {
|
|
12
12
|
if (err != null && typeof err === "object" && "code" in err && err.code === "ERR_JWT_EXPIRED") {
|
|
13
|
-
throw new Error("
|
|
13
|
+
throw new Error("Token has expired.");
|
|
14
14
|
}
|
|
15
|
-
throw new Error("
|
|
15
|
+
throw new Error("Invalid token.");
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
function decodeJwt(token) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/auth/jwt-manager.ts"],
|
|
4
|
-
"mappings": "AAAA,YAAY,UAAU;AAGtB,eAAsB,QACpB,WACA,SACiB;AACjB,QAAM,SAAS,IAAI,YAAY,EAAE,OAAO,SAAS;AAEjD,SAAO,IAAI,KAAK,QAAQ,OAAO,EAC5B,mBAAmB,EAAE,KAAK,QAAQ,CAAC,EACnC,YAAY,EACZ,kBAAkB,KAAK,EACvB,KAAK,MAAM;AAChB;AAEA,eAAsB,UACpB,WACA,OACsC;AACtC,QAAM,SAAS,IAAI,YAAY,EAAE,OAAO,SAAS;AAEjD,MAAI;AACF,UAAM,EAAE,QAAQ,IAAI,MAAM,KAAK,UAAU,OAAO,MAAM;AACtD,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,QAAI,OAAO,QAAQ,OAAO,QAAQ,YAAY,UAAU,OAAO,IAAI,SAAS,mBAAmB;AAC7F,YAAM,IAAI,MAAM,
|
|
4
|
+
"mappings": "AAAA,YAAY,UAAU;AAGtB,eAAsB,QACpB,WACA,SACiB;AACjB,QAAM,SAAS,IAAI,YAAY,EAAE,OAAO,SAAS;AAEjD,SAAO,IAAI,KAAK,QAAQ,OAAO,EAC5B,mBAAmB,EAAE,KAAK,QAAQ,CAAC,EACnC,YAAY,EACZ,kBAAkB,KAAK,EACvB,KAAK,MAAM;AAChB;AAEA,eAAsB,UACpB,WACA,OACsC;AACtC,QAAM,SAAS,IAAI,YAAY,EAAE,OAAO,SAAS;AAEjD,MAAI;AACF,UAAM,EAAE,QAAQ,IAAI,MAAM,KAAK,UAAU,OAAO,MAAM;AACtD,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,QAAI,OAAO,QAAQ,OAAO,QAAQ,YAAY,UAAU,OAAO,IAAI,SAAS,mBAAmB;AAC7F,YAAM,IAAI,MAAM,oBAAoB;AAAA,IACtC;AACA,UAAM,IAAI,MAAM,gBAAgB;AAAA,EAClC;AACF;AAEO,SAAS,UAA+B,OAA4C;AACzF,SAAO,KAAK,UAAU,KAAK;AAC7B;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -14,7 +14,7 @@ function createServiceContext(server, socket, http, legacy) {
|
|
|
14
14
|
const name = socket?.clientName ?? http?.clientName ?? legacy?.clientName;
|
|
15
15
|
if (name == null) return void 0;
|
|
16
16
|
if (name === "" || name.includes("..") || name.includes("/") || name.includes("\\")) {
|
|
17
|
-
throw new Error(
|
|
17
|
+
throw new Error(`Invalid client name: ${name}`);
|
|
18
18
|
}
|
|
19
19
|
return name;
|
|
20
20
|
},
|
|
@@ -38,7 +38,7 @@ function createServiceContext(server, socket, http, legacy) {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
const config = configParent[section];
|
|
41
|
-
if (config == null) throw new Error(
|
|
41
|
+
if (config == null) throw new Error(`Configuration section not found: ${section}`);
|
|
42
42
|
return config;
|
|
43
43
|
}
|
|
44
44
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/core/define-service.ts"],
|
|
4
|
-
"mappings": "AAGA,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAC1B,OAAO,UAAU;AAuBV,SAAS,qBACd,QACA,QACA,MACA,QAC2B;AAC3B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAEA,IAAI,WAAkC;AACpC,aAAQ,QAAQ,kBAAkB,QAAQ,MAAM,kBAAkB;AAAA,IAGpE;AAAA,IAEA,IAAI,aAAiC;AACnC,YAAM,OAAO,QAAQ,cAAc,MAAM,cAAc,QAAQ;AAC/D,UAAI,QAAQ,KAAM,QAAO;AAEzB,UAAI,SAAS,MAAM,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,IAAI,GAAG;AACnF,cAAM,IAAI,MAAM,
|
|
4
|
+
"mappings": "AAGA,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAC1B,OAAO,UAAU;AAuBV,SAAS,qBACd,QACA,QACA,MACA,QAC2B;AAC3B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAEA,IAAI,WAAkC;AACpC,aAAQ,QAAQ,kBAAkB,QAAQ,MAAM,kBAAkB;AAAA,IAGpE;AAAA,IAEA,IAAI,aAAiC;AACnC,YAAM,OAAO,QAAQ,cAAc,MAAM,cAAc,QAAQ;AAC/D,UAAI,QAAQ,KAAM,QAAO;AAEzB,UAAI,SAAS,MAAM,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,IAAI,GAAG;AACnF,cAAM,IAAI,MAAM,wBAAwB,IAAI,EAAE;AAAA,MAChD;AAEA,aAAO;AAAA,IACT;AAAA,IAEA,IAAI,aAAiC;AACnC,YAAM,OAAO,KAAK;AAClB,aAAO,QAAQ,OAAO,SAAY,KAAK,QAAQ,OAAO,QAAQ,UAAU,OAAO,IAAI;AAAA,IACrF;AAAA,IAEA,MAAM,UAAa,SAA6B;AAC9C,UAAI,eAA8C,CAAC;AAEnD,YAAM,eAAe,KAAK,QAAQ,OAAO,QAAQ,UAAU,cAAc;AACzE,YAAM,aAAa,MAAM,UAA6B,YAAY;AAClE,UAAI,cAAc,MAAM;AACtB,uBAAe;AAAA,MACjB;AAEA,YAAM,aAAa,KAAK;AACxB,UAAI,cAAc,MAAM;AACtB,cAAM,iBAAiB,KAAK,QAAQ,YAAY,cAAc;AAC9D,cAAM,eAAe,MAAM,UAA6B,cAAc;AACtE,YAAI,gBAAgB,MAAM;AACxB,yBAAe,SAAS,cAAc,YAAY;AAAA,QACpD;AAAA,MACF;AAEA,YAAM,SAAS,aAAa,OAAO;AACnC,UAAI,UAAU,KAAM,OAAM,IAAI,MAAM,oCAAoC,OAAO,EAAE;AACjF,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAIA,MAAM,mBAAmB,uBAAO,iBAAiB;AAG1C,SAAS,0BAA0B,IAAoC;AAC5E,SAAQ,GAA0C,gBAAgB;AACpE;AAeO,SAAS,KAAK,iBAAsC,SAA8B;AACvF,QAAM,cAAc,MAAM,QAAQ,eAAe,IAAI,kBAAkB,CAAC;AACxE,QAAM,KAAK,MAAM,QAAQ,eAAe,IAAI,UAAW;AAGvD,QAAM,UAAU,IAAI,SAAoB,GAAG,GAAG,IAAI;AAClD,EAAC,QAA+C,gBAAgB,IAAI;AAEpE,SAAO;AACT;AAyBO,SAAS,cACd,MACA,SAC6B;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,iBAAiB,0BAA0B,OAAO;AAAA,EACpD;AACF;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -2,19 +2,19 @@ import { createServiceContext, getServiceAuthPermissions } from "./define-servic
|
|
|
2
2
|
async function runServiceMethod(server, def) {
|
|
3
3
|
const serviceDef = server.options.services.find((item) => item.name === def.serviceName);
|
|
4
4
|
if (serviceDef == null) {
|
|
5
|
-
throw new Error(
|
|
5
|
+
throw new Error(`Service [${def.serviceName}] not found.`);
|
|
6
6
|
}
|
|
7
7
|
const clientName = def.socket?.clientName ?? def.http?.clientName;
|
|
8
8
|
if (clientName != null) {
|
|
9
9
|
if (clientName.includes("..") || clientName.includes("/") || clientName.includes("\\")) {
|
|
10
|
-
throw new Error(`[Security]
|
|
10
|
+
throw new Error(`[Security] Invalid client name: ${clientName}`);
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
const ctx = createServiceContext(server, def.socket, def.http);
|
|
14
14
|
const methods = serviceDef.factory(ctx);
|
|
15
15
|
const method = methods[def.methodName];
|
|
16
16
|
if (typeof method !== "function") {
|
|
17
|
-
throw new Error(
|
|
17
|
+
throw new Error(`Method [${def.serviceName}.${def.methodName}] not found.`);
|
|
18
18
|
}
|
|
19
19
|
if (server.options.auth != null) {
|
|
20
20
|
const methodPerms = getServiceAuthPermissions(method);
|
|
@@ -22,12 +22,12 @@ async function runServiceMethod(server, def) {
|
|
|
22
22
|
if (requiredPerms != null) {
|
|
23
23
|
const authTokenPayload = def.socket?.authTokenPayload ?? def.http?.authTokenPayload;
|
|
24
24
|
if (authTokenPayload == null) {
|
|
25
|
-
throw new Error("
|
|
25
|
+
throw new Error("Login is required.");
|
|
26
26
|
}
|
|
27
27
|
if (requiredPerms.length > 0) {
|
|
28
28
|
const hasPerm = requiredPerms.some((perm) => authTokenPayload.roles.includes(perm));
|
|
29
29
|
if (!hasPerm) {
|
|
30
|
-
throw new Error("
|
|
30
|
+
throw new Error("Insufficient permissions.");
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/core/service-executor.ts"],
|
|
4
|
-
"mappings": "AAGA,SAAS,sBAAsB,iCAAiC;AAEhE,eAAsB,iBACpB,QACA,KAOkB;AAElB,QAAM,aAAa,OAAO,QAAQ,SAAS,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,WAAW;AAEvF,MAAI,cAAc,MAAM;AACtB,UAAM,IAAI,MAAM,
|
|
4
|
+
"mappings": "AAGA,SAAS,sBAAsB,iCAAiC;AAEhE,eAAsB,iBACpB,QACA,KAOkB;AAElB,QAAM,aAAa,OAAO,QAAQ,SAAS,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,WAAW;AAEvF,MAAI,cAAc,MAAM;AACtB,UAAM,IAAI,MAAM,YAAY,IAAI,WAAW,cAAc;AAAA,EAC3D;AAGA,QAAM,aAAa,IAAI,QAAQ,cAAc,IAAI,MAAM;AACvD,MAAI,cAAc,MAAM;AACtB,QAAI,WAAW,SAAS,IAAI,KAAK,WAAW,SAAS,GAAG,KAAK,WAAW,SAAS,IAAI,GAAG;AACtF,YAAM,IAAI,MAAM,mCAAmC,UAAU,EAAE;AAAA,IACjE;AAAA,EACF;AAGA,QAAM,MAAM,qBAAqB,QAAQ,IAAI,QAAQ,IAAI,IAAI;AAG7D,QAAM,UAAU,WAAW,QAAQ,GAAG;AAGtC,QAAM,SAAU,QAAoC,IAAI,UAAU;AAClE,MAAI,OAAO,WAAW,YAAY;AAChC,UAAM,IAAI,MAAM,WAAW,IAAI,WAAW,IAAI,IAAI,UAAU,cAAc;AAAA,EAC5E;AAGA,MAAI,OAAO,QAAQ,QAAQ,MAAM;AAE/B,UAAM,cAAc,0BAA0B,MAAM;AACpD,UAAM,gBAAgB,eAAe,WAAW;AAEhD,QAAI,iBAAiB,MAAM;AACzB,YAAM,mBAAmB,IAAI,QAAQ,oBAAoB,IAAI,MAAM;AAEnE,UAAI,oBAAoB,MAAM;AAC5B,cAAM,IAAI,MAAM,oBAAoB;AAAA,MACtC;AAEA,UAAI,cAAc,SAAS,GAAG;AAC5B,cAAM,UAAU,cAAc,KAAK,CAAC,SAAS,iBAAiB,MAAM,SAAS,IAAI,CAAC;AAClF,YAAI,CAAC,SAAS;AACZ,gBAAM,IAAI,MAAM,2BAA2B;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,SAAO,MAAM,OAAO,GAAG,IAAI,MAAM;AACnC;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { WebSocket } from "ws";
|
|
2
2
|
/**
|
|
3
|
-
* V1
|
|
4
|
-
*
|
|
3
|
+
* V1 legacy client handler (only auto-update supported).
|
|
4
|
+
* All other requests return an upgrade-required error.
|
|
5
5
|
*/
|
|
6
6
|
export declare function handleV1Connection(socket: WebSocket, autoUpdateMethods: {
|
|
7
7
|
getLastVersion: (platform: string) => Promise<any>;
|
|
@@ -21,14 +21,14 @@ function handleV1Connection(socket, autoUpdateMethods, clientNameSetter) {
|
|
|
21
21
|
reqUuid: msg.uuid,
|
|
22
22
|
state: "error",
|
|
23
23
|
body: {
|
|
24
|
-
message: "
|
|
24
|
+
message: "App upgrade is required.",
|
|
25
25
|
code: "UPGRADE_REQUIRED"
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
28
|
socket.send(JSON.stringify(response));
|
|
29
29
|
}
|
|
30
30
|
} catch (err) {
|
|
31
|
-
logger.warn("V1
|
|
31
|
+
logger.warn("V1 message processing error", err);
|
|
32
32
|
}
|
|
33
33
|
});
|
|
34
34
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/legacy/v1-auto-update-handler.ts"],
|
|
4
|
-
"mappings": "AACA,OAAO,aAAa;AAEpB,MAAM,SAAS,QAAQ,QAAQ,oCAAoC;AAoB5D,SAAS,mBACd,QACA,mBACA,kBACA;AAEA,SAAO,KAAK,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC,CAAC;AAEjD,SAAO,GAAG,WAAW,CAAC,SAAS;AAC7B,QAAI;AACF,YAAM,MAAM,KAAK,MAAM,KAAK,SAAS,CAAC;AAGtC,UAAI,IAAI,YAAY,sCAAsC;AAExD,2BAAmB,IAAI,UAAU;AAEjC,cAAM,SAAS,kBAAkB,eAAe,IAAI,OAAO,CAAC,CAAW;AAEvE,cAAM,WAAwB;AAAA,UAC5B,MAAM;AAAA,UACN,SAAS,IAAI;AAAA,UACb,OAAO;AAAA,UACP,MAAM;AAAA,QACR;AACA,eAAO,KAAK,KAAK,UAAU,QAAQ,CAAC;AAAA,MACtC,OAAO;AAEL,cAAM,WAAwB;AAAA,UAC5B,MAAM;AAAA,UACN,SAAS,IAAI;AAAA,UACb,OAAO;AAAA,UACP,MAAM;AAAA,YACJ,SAAS;AAAA,YACT,MAAM;AAAA,UACR;AAAA,QACF;AACA,eAAO,KAAK,KAAK,UAAU,QAAQ,CAAC;AAAA,MACtC;AAAA,IACF,SAAS,KAAK;AACZ,aAAO,KAAK,
|
|
4
|
+
"mappings": "AACA,OAAO,aAAa;AAEpB,MAAM,SAAS,QAAQ,QAAQ,oCAAoC;AAoB5D,SAAS,mBACd,QACA,mBACA,kBACA;AAEA,SAAO,KAAK,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC,CAAC;AAEjD,SAAO,GAAG,WAAW,CAAC,SAAS;AAC7B,QAAI;AACF,YAAM,MAAM,KAAK,MAAM,KAAK,SAAS,CAAC;AAGtC,UAAI,IAAI,YAAY,sCAAsC;AAExD,2BAAmB,IAAI,UAAU;AAEjC,cAAM,SAAS,kBAAkB,eAAe,IAAI,OAAO,CAAC,CAAW;AAEvE,cAAM,WAAwB;AAAA,UAC5B,MAAM;AAAA,UACN,SAAS,IAAI;AAAA,UACb,OAAO;AAAA,UACP,MAAM;AAAA,QACR;AACA,eAAO,KAAK,KAAK,UAAU,QAAQ,CAAC;AAAA,MACtC,OAAO;AAEL,cAAM,WAAwB;AAAA,UAC5B,MAAM;AAAA,UACN,SAAS,IAAI;AAAA,UACb,OAAO;AAAA,UACP,MAAM;AAAA,YACJ,SAAS;AAAA,YACT,MAAM;AAAA,UACR;AAAA,QACF;AACA,eAAO,KAAK,KAAK,UAAU,QAAQ,CAAC;AAAA,MACtC;AAAA,IACF,SAAS,KAAK;AACZ,aAAO,KAAK,+BAA+B,GAAG;AAAA,IAChD;AAAA,EACF,CAAC;AACH;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
package/dist/service-server.js
CHANGED
|
@@ -32,7 +32,7 @@ class ServiceServer extends EventEmitter {
|
|
|
32
32
|
_wsHandler;
|
|
33
33
|
fastify;
|
|
34
34
|
async listen() {
|
|
35
|
-
logger.info(
|
|
35
|
+
logger.info(`Server starting... ${env.VER ?? ""}`);
|
|
36
36
|
await this.fastify.register(fastifyWebsocket);
|
|
37
37
|
await this.fastify.register(fastifyHelmet, {
|
|
38
38
|
global: true,
|
|
@@ -123,23 +123,23 @@ class ServiceServer extends EventEmitter {
|
|
|
123
123
|
}
|
|
124
124
|
});
|
|
125
125
|
this.fastify.server.on("error", (err) => {
|
|
126
|
-
logger.error("HTTP
|
|
126
|
+
logger.error("HTTP server error", err);
|
|
127
127
|
});
|
|
128
128
|
await this.fastify.listen({ port: this.options.port, host: "0.0.0.0" });
|
|
129
129
|
this._registerGracefulShutdown();
|
|
130
130
|
this.isOpen = true;
|
|
131
|
-
logger.info(
|
|
131
|
+
logger.info(`Server started (port: ${this.options.port})`);
|
|
132
132
|
this.emit("ready");
|
|
133
133
|
}
|
|
134
134
|
async close() {
|
|
135
135
|
this._wsHandler.closeAll();
|
|
136
136
|
await this.fastify.close();
|
|
137
137
|
this.isOpen = false;
|
|
138
|
-
logger.debug("
|
|
138
|
+
logger.debug("Server closed");
|
|
139
139
|
this.emit("close");
|
|
140
140
|
}
|
|
141
141
|
async broadcastReload(clientName, changedFileSet) {
|
|
142
|
-
logger.debug("
|
|
142
|
+
logger.debug("Broadcasting RELOAD to all server clients");
|
|
143
143
|
await this._wsHandler.broadcastReload(clientName, changedFileSet);
|
|
144
144
|
}
|
|
145
145
|
async emitEvent(eventDef, infoSelector, data) {
|
|
@@ -147,30 +147,30 @@ class ServiceServer extends EventEmitter {
|
|
|
147
147
|
}
|
|
148
148
|
async generateAuthToken(payload) {
|
|
149
149
|
const jwtSecret = this.options.auth?.jwtSecret;
|
|
150
|
-
if (jwtSecret == null) throw new Error("JWT Secret
|
|
150
|
+
if (jwtSecret == null) throw new Error("JWT Secret is not defined.");
|
|
151
151
|
return signJwt(jwtSecret, payload);
|
|
152
152
|
}
|
|
153
153
|
async verifyAuthToken(token) {
|
|
154
154
|
const jwtSecret = this.options.auth?.jwtSecret;
|
|
155
|
-
if (jwtSecret == null) throw new Error("JWT Secret
|
|
155
|
+
if (jwtSecret == null) throw new Error("JWT Secret is not defined.");
|
|
156
156
|
return verifyJwt(jwtSecret, token);
|
|
157
157
|
}
|
|
158
158
|
_registerGracefulShutdown() {
|
|
159
159
|
const shutdownHandler = async (signal) => {
|
|
160
|
-
logger.info(`${signal}
|
|
160
|
+
logger.info(`${signal} signal received. Starting server shutdown...`);
|
|
161
161
|
const forceExitTimer = setTimeout(() => {
|
|
162
|
-
logger.error("
|
|
162
|
+
logger.error("Server shutdown timed out (10s). Forcing exit.");
|
|
163
163
|
process.exit(1);
|
|
164
164
|
}, 1e4);
|
|
165
165
|
try {
|
|
166
166
|
if (this.isOpen) {
|
|
167
167
|
await this.close();
|
|
168
168
|
}
|
|
169
|
-
logger.info("
|
|
169
|
+
logger.info("Server shut down gracefully.");
|
|
170
170
|
clearTimeout(forceExitTimer);
|
|
171
171
|
process.exit(0);
|
|
172
172
|
} catch (err) {
|
|
173
|
-
logger.error("
|
|
173
|
+
logger.error("Error during server shutdown", err);
|
|
174
174
|
process.exit(1);
|
|
175
175
|
}
|
|
176
176
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/service-server.ts"],
|
|
4
|
-
"mappings": "AACA,SAAS,wBAAwB;AACjC,SAAS,yBAAyB;AAClC,SAAS,wBAAwB;AACjC,SAAS,eAAe,WAAW,cAAc,WAAW;AAE5D,OAAO,aAAa;AACpB,OAAO,sBAAsB;AAC7B,OAAO,mBAAmB;AAC1B,OAAO,sBAAsB;AAC7B,OAAO,mBAAmB;AAC1B,OAAO,iBAAiB;AACxB,OAAO,UAAU;AACjB,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAC7B,SAAS,8BAA8B;AAEvC,SAAS,SAAS,iBAAiB;AAGnC,SAAS,0BAA0B;AACnC,SAAS,4BAA4B;AACrC,OAAO,aAAa;AAEpB,MAAM,SAAS,QAAQ,QAAQ,8BAA8B;AAEtD,MAAM,sBAA2C,aAGrD;AAAA,EAOD,YAAqB,SAA+B;AAClD,UAAM;AADa;AAKnB,UAAM,YAAY,QAAQ,MACtB,EAAE,KAAK,OAAO,KAAK,QAAQ,IAAI,QAAQ,GAAG,YAAY,QAAQ,IAAI,WAAW,IAC7E;AAEJ,SAAK,UAAU,QAAQ,EAAE,OAAO,UAAU,CAAC;AAE3C,SAAK,aAAa;AAAA,MAChB,CAAC,QAAQ,iBAAiB,MAAM,GAAG;AAAA,MACnC,QAAQ,MAAM;AAAA,IAChB;AAAA,EACF;AAAA,EArBA,SAAS;AAAA,EAEQ;AAAA,EAER;AAAA,EAmBT,MAAM,SAAwB;AAC5B,WAAO,KAAK,
|
|
4
|
+
"mappings": "AACA,SAAS,wBAAwB;AACjC,SAAS,yBAAyB;AAClC,SAAS,wBAAwB;AACjC,SAAS,eAAe,WAAW,cAAc,WAAW;AAE5D,OAAO,aAAa;AACpB,OAAO,sBAAsB;AAC7B,OAAO,mBAAmB;AAC1B,OAAO,sBAAsB;AAC7B,OAAO,mBAAmB;AAC1B,OAAO,iBAAiB;AACxB,OAAO,UAAU;AACjB,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAC7B,SAAS,8BAA8B;AAEvC,SAAS,SAAS,iBAAiB;AAGnC,SAAS,0BAA0B;AACnC,SAAS,4BAA4B;AACrC,OAAO,aAAa;AAEpB,MAAM,SAAS,QAAQ,QAAQ,8BAA8B;AAEtD,MAAM,sBAA2C,aAGrD;AAAA,EAOD,YAAqB,SAA+B;AAClD,UAAM;AADa;AAKnB,UAAM,YAAY,QAAQ,MACtB,EAAE,KAAK,OAAO,KAAK,QAAQ,IAAI,QAAQ,GAAG,YAAY,QAAQ,IAAI,WAAW,IAC7E;AAEJ,SAAK,UAAU,QAAQ,EAAE,OAAO,UAAU,CAAC;AAE3C,SAAK,aAAa;AAAA,MAChB,CAAC,QAAQ,iBAAiB,MAAM,GAAG;AAAA,MACnC,QAAQ,MAAM;AAAA,IAChB;AAAA,EACF;AAAA,EArBA,SAAS;AAAA,EAEQ;AAAA,EAER;AAAA,EAmBT,MAAM,SAAwB;AAC5B,WAAO,KAAK,sBAAsB,IAAI,OAAO,EAAE,EAAE;AAGjD,UAAM,KAAK,QAAQ,SAAS,gBAAgB;AAG5C,UAAM,KAAK,QAAQ,SAAS,eAAe;AAAA,MACzC,QAAQ;AAAA,MACR,uBAAuB;AAAA,QACrB,YAAY;AAAA,UACV,GAAG,cAAc,sBAAsB,qBAAqB;AAAA,UAC5D,eAAe,CAAC,UAAU,SAAS,SAAS,GAAG;AAAA,UAC/C,mBAAmB,CAAC,iBAAiB;AAAA,UACrC,cAAc,CAAC,UAAU,mBAAmB,SAAS,SAAS,GAAG;AAAA,UACjE,GAAI,KAAK,QAAQ,OAAO,OACpB,CAAC,IACD;AAAA,YACE,6BAA6B;AAAA,UAC/B;AAAA,QACN;AAAA,MACF;AAAA,MACA,MAAM,KAAK,QAAQ,OAAO;AAAA,MAC1B,yBAAyB,KAAK,QAAQ,OAAO;AAAA,MAC7C,oBAAoB;AAAA,IACtB,CAAC;AAGD,UAAM,KAAK,QAAQ,SAAS,gBAAgB;AAG5C,UAAM,KAAK,QAAQ,SAAS,eAAe;AAAA,MACzC,MAAM,KAAK,QAAQ,KAAK,QAAQ,UAAU,KAAK;AAAA,MAC/C,UAAU;AAAA,MACV,OAAO;AAAA,IACT,CAAC;AAGD,UAAM,KAAK,QAAQ,SAAS,aAAa;AAAA,MACvC,QAAQ,CAAC,SAAS,OAAO;AACvB,WAAG,MAAM,IAAI;AAAA,MACf;AAAA,MACA,gBAAgB,CAAC,gBAAgB,iBAAiB,kBAAkB;AAAA,MACpE,gBAAgB,CAAC,uBAAuB,gBAAgB;AAAA,IAC1D,CAAC;AAGD,SAAK,QAAQ;AAAA,MACX;AAAA,MACA,EAAE,SAAS,SAAS;AAAA,MACpB,CAAC,KAAK,MAAM,SAAS;AACnB,YAAI;AACF,gBAAM,OAAO,UAAU,IAAc;AACrC,eAAK,MAAM,IAAI;AAAA,QACjB,SAAS,KAAc;AACrB,gBAAM,QAAQ;AACd,gBAAM,aAAa;AACnB,eAAK,OAAO,MAAS;AAAA,QACvB;AAAA,MACF;AAAA,IACF;AAGA,SAAK,QAAQ,sBAAsB,MAAM,CAAC,SAAS,cAAc,IAAI,CAAC;AAGtE,SAAK,QAAQ,IAAI,yBAAyB,OAAO,KAAK,UAAU;AAC9D,YAAM;AAAA,QAAkB;AAAA,QAAK;AAAA,QAAO,KAAK,QAAQ,MAAM;AAAA,QAAW,CAAC,QACjE,iBAAiB,MAAM,GAAG;AAAA,MAC5B;AAAA,IACF,CAAC;AAGD,SAAK,QAAQ,IAAI,WAAW,OAAO,KAAK,UAAU;AAChD,YAAM,aAAa,KAAK,OAAO,KAAK,QAAQ,UAAU,KAAK,QAAQ,MAAM,SAAS;AAAA,IACpF,CAAC;AAGD,UAAM,uBAAuB,CAAC,QAAmB,QAAwB;AACvE,YAAM,EAAE,KAAK,UAAU,WAAW,IAAI,IAAI;AAM1C,UAAI,QAAQ,KAAK;AACf,YAAI,YAAY,QAAQ,cAAc,MAAM;AAC1C,iBAAO,MAAM,MAAM,wBAAwB;AAC3C;AAAA,QACF;AACA,aAAK,WAAW,UAAU,QAAQ,UAAU,YAAY,GAAG;AAAA,MAC7D,OAAO;AAEL,cAAM,gBAAgB,KAAK,QAAQ,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,YAAY;AAC/E,YAAI,iBAAiB,MAAM;AACzB,iBAAO,MAAM,MAAM,mCAAmC;AACtD;AAAA,QACF;AAEA,cAAM,YAAY,qBAAqB,MAAM,QAAW,QAAW,CAAC,CAAC;AACrE,cAAM,oBAAoB,cAAc,QAAQ,SAAS;AAIzD,2BAAmB,QAAQ,mBAAmB,CAAC,SAAS;AACtD,oBAAU,SAAS,EAAE,YAAY,KAAK;AAAA,QACxC,CAAC;AAAA,MACH;AAAA,IACF;AACA,SAAK,QAAQ,IAAI,KAAK,EAAE,WAAW,KAAK,GAAG,qBAAqB,KAAK,IAAI,CAAC;AAC1E,SAAK,QAAQ,IAAI,OAAO,EAAE,WAAW,KAAK,GAAG,qBAAqB,KAAK,IAAI,CAAC;AAG5E,SAAK,QAAQ,MAAM;AAAA,MACjB,QAAQ,CAAC,OAAO,QAAQ,OAAO,UAAU,SAAS,MAAM;AAAA,MACxD,KAAK;AAAA,MACL,SAAS,OAAO,KAAK,UAAU;AAC7B,cAAM,SAAS,IAAI,IAAI,IAAI,IAAI,KAAM,kBAAkB;AACvD,cAAM,UAAU,UAAU,OAAO,SAAS,MAAM,CAAC,CAAC;AAElD,cAAM,iBAAiB,KAAK,OAAO,KAAK,QAAQ,UAAU,OAAO;AAAA,MACnE;AAAA,IACF,CAAC;AAGD,SAAK,QAAQ,OAAO,GAAG,SAAS,CAAC,QAAQ;AACvC,aAAO,MAAM,qBAAqB,GAAG;AAAA,IACvC,CAAC;AAGD,UAAM,KAAK,QAAQ,OAAO,EAAE,MAAM,KAAK,QAAQ,MAAM,MAAM,UAAU,CAAC;AAGtE,SAAK,0BAA0B;AAE/B,SAAK,SAAS;AACd,WAAO,KAAK,yBAAyB,KAAK,QAAQ,IAAI,GAAG;AACzD,SAAK,KAAK,OAAO;AAAA,EACnB;AAAA,EAEA,MAAM,QAAuB;AAC3B,SAAK,WAAW,SAAS;AACzB,UAAM,KAAK,QAAQ,MAAM;AAEzB,SAAK,SAAS;AACd,WAAO,MAAM,eAAe;AAC5B,SAAK,KAAK,OAAO;AAAA,EACnB;AAAA,EAEA,MAAM,gBAAgB,YAAgC,gBAA6B;AACjF,WAAO,MAAM,2CAA2C;AACxD,UAAM,KAAK,WAAW,gBAAgB,YAAY,cAAc;AAAA,EAClE;AAAA,EAEA,MAAM,UACJ,UACA,cACA,MACA;AACA,UAAM,KAAK,WAAW,aAAa,UAAU,cAAc,IAAI;AAAA,EACjE;AAAA,EAEA,MAAM,kBAAkB,SAAsC;AAC5D,UAAM,YAAY,KAAK,QAAQ,MAAM;AACrC,QAAI,aAAa,KAAM,OAAM,IAAI,MAAM,4BAA4B;AAEnE,WAAO,QAAQ,WAAW,OAAO;AAAA,EACnC;AAAA,EAEA,MAAM,gBAAgB,OAAqD;AACzE,UAAM,YAAY,KAAK,QAAQ,MAAM;AACrC,QAAI,aAAa,KAAM,OAAM,IAAI,MAAM,4BAA4B;AAEnE,WAAO,UAAU,WAAW,KAAK;AAAA,EACnC;AAAA,EAEQ,4BAA4B;AAClC,UAAM,kBAAkB,OAAO,WAAmB;AAChD,aAAO,KAAK,GAAG,MAAM,+CAA+C;AAEpE,YAAM,iBAAiB,WAAW,MAAM;AACtC,eAAO,MAAM,gDAAgD;AAC7D,gBAAQ,KAAK,CAAC;AAAA,MAChB,GAAG,GAAK;AAER,UAAI;AACF,YAAI,KAAK,QAAQ;AACf,gBAAM,KAAK,MAAM;AAAA,QACnB;AACA,eAAO,KAAK,8BAA8B;AAC1C,qBAAa,cAAc;AAC3B,gBAAQ,KAAK,CAAC;AAAA,MAChB,SAAS,KAAK;AACZ,eAAO,MAAM,gCAAgC,GAAG;AAChD,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAEA,YAAQ,GAAG,UAAU,MAAM,gBAAgB,QAAQ,CAAC;AACpD,YAAQ,GAAG,WAAW,MAAM,gBAAgB,SAAS,CAAC;AAAA,EACxD;AACF;AAEO,SAAS,oBACd,SAC0B;AAC1B,SAAO,IAAI,cAAyB,OAAO;AAC7C;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -5,7 +5,7 @@ import { defineService } from "../core/define-service.js";
|
|
|
5
5
|
const AutoUpdateService = defineService("AutoUpdate", (ctx) => ({
|
|
6
6
|
async getLastVersion(platform) {
|
|
7
7
|
const clientPath = ctx.clientPath;
|
|
8
|
-
if (clientPath == null) throw new Error("
|
|
8
|
+
if (clientPath == null) throw new Error("Client path not found.");
|
|
9
9
|
if (!await fsExists(path.resolve(clientPath, platform, "updates"))) return void 0;
|
|
10
10
|
const updates = await fsReaddir(path.resolve(clientPath, platform, "updates"));
|
|
11
11
|
const versions = updates.map((item) => ({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/services/auto-update-service.ts"],
|
|
4
|
-
"mappings": "AAAA,OAAO,UAAU;AACjB,OAAO,YAAY;AACnB,SAAS,UAAU,WAAW,iBAAiB;AAC/C,SAAS,qBAA0C;AAE5C,MAAM,oBAAoB,cAAc,cAAc,CAAC,SAAS;AAAA,EACrE,MAAM,eAAe,UAMnB;AACA,UAAM,aAAa,IAAI;AACvB,QAAI,cAAc,KAAM,OAAM,IAAI,MAAM,
|
|
4
|
+
"mappings": "AAAA,OAAO,UAAU;AACjB,OAAO,YAAY;AACnB,SAAS,UAAU,WAAW,iBAAiB;AAC/C,SAAS,qBAA0C;AAE5C,MAAM,oBAAoB,cAAc,cAAc,CAAC,SAAS;AAAA,EACrE,MAAM,eAAe,UAMnB;AACA,UAAM,aAAa,IAAI;AACvB,QAAI,cAAc,KAAM,OAAM,IAAI,MAAM,wBAAwB;AAEhE,QAAI,CAAE,MAAM,SAAS,KAAK,QAAQ,YAAY,UAAU,SAAS,CAAC,EAAI,QAAO;AAE7E,UAAM,UAAU,MAAM,UAAU,KAAK,QAAQ,YAAY,UAAU,SAAS,CAAC;AAC7E,UAAM,WAAW,QACd,IAAI,CAAC,UAAU;AAAA,MACd,UAAU;AAAA,MACV,SAAS,KAAK,SAAS,MAAM,KAAK,QAAQ,IAAI,CAAC;AAAA,MAC/C,SAAS,KAAK,QAAQ,IAAI;AAAA,IAC5B,EAAE,EACD,OAAO,CAAC,SAAS;AAChB,UAAI,aAAa,WAAW;AAC1B,eAAO,KAAK,YAAY,UAAU,YAAY,KAAK,KAAK,OAAO;AAAA,MACjE,OAAO;AACL,eAAO,KAAK,YAAY,UAAU,YAAY,KAAK,KAAK,OAAO;AAAA,MACjE;AAAA,IACF,CAAC;AAEH,UAAM,UAAU,OAAO;AAAA,MACrB,SAAS,IAAI,CAAC,SAAS,KAAK,OAAO;AAAA,MACnC;AAAA,IACF;AAEA,QAAI,WAAW,KAAM,QAAO;AAE5B,UAAM,cAAc,SAAS,KAAK,CAAC,SAAS,KAAK,YAAY,OAAO;AACpE,QAAI,eAAe,KAAM,QAAO;AAEhC,UAAM,eACJ,MAAM,UAAU,IAAI,cAAc,IAAI,UAAU,WAAW,YAAY,QAAQ;AAEjF,WAAO;AAAA,MACL,SAAS,QAAQ,SAAS;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AACF,EAAE;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|