@simplysm/service-server 13.0.0-beta.45 → 13.0.0-beta.47

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.
Files changed (85) hide show
  1. package/README.md +84 -32
  2. package/dist/auth/auth-token-payload.js.map +0 -1
  3. package/dist/auth/jwt-manager.js.map +0 -1
  4. package/dist/core/define-service.d.ts +67 -0
  5. package/dist/core/define-service.d.ts.map +1 -0
  6. package/dist/core/define-service.js +70 -0
  7. package/dist/core/define-service.js.map +6 -0
  8. package/dist/core/service-executor.d.ts.map +1 -1
  9. package/dist/core/service-executor.js +12 -13
  10. package/dist/core/service-executor.js.map +1 -2
  11. package/dist/index.d.ts +1 -2
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +1 -2
  14. package/dist/index.js.map +1 -2
  15. package/dist/legacy/v1-auto-update-handler.d.ts +3 -2
  16. package/dist/legacy/v1-auto-update-handler.d.ts.map +1 -1
  17. package/dist/legacy/v1-auto-update-handler.js +3 -3
  18. package/dist/legacy/v1-auto-update-handler.js.map +1 -2
  19. package/dist/protocol/protocol-wrapper.js.map +0 -1
  20. package/dist/service-server.d.ts +3 -3
  21. package/dist/service-server.d.ts.map +1 -1
  22. package/dist/service-server.js +18 -7
  23. package/dist/service-server.js.map +1 -2
  24. package/dist/services/auto-update-service.d.ts +4 -4
  25. package/dist/services/auto-update-service.d.ts.map +1 -1
  26. package/dist/services/auto-update-service.js +5 -5
  27. package/dist/services/auto-update-service.js.map +1 -2
  28. package/dist/services/crypto-service.d.ts +4 -5
  29. package/dist/services/crypto-service.d.ts.map +1 -1
  30. package/dist/services/crypto-service.js +8 -11
  31. package/dist/services/crypto-service.js.map +1 -2
  32. package/dist/services/orm-service.d.ts +5 -9
  33. package/dist/services/orm-service.d.ts.map +1 -1
  34. package/dist/services/orm-service.js +122 -171
  35. package/dist/services/orm-service.js.map +1 -2
  36. package/dist/services/smtp-service.d.ts +6 -5
  37. package/dist/services/smtp-service.d.ts.map +1 -1
  38. package/dist/services/smtp-service.js +22 -19
  39. package/dist/services/smtp-service.js.map +1 -2
  40. package/dist/transport/http/http-request-handler.js.map +0 -1
  41. package/dist/transport/http/static-file-handler.js.map +0 -1
  42. package/dist/transport/http/upload-handler.js.map +0 -1
  43. package/dist/transport/socket/service-socket.js.map +0 -1
  44. package/dist/transport/socket/websocket-handler.d.ts +2 -3
  45. package/dist/transport/socket/websocket-handler.d.ts.map +1 -1
  46. package/dist/transport/socket/websocket-handler.js +2 -2
  47. package/dist/transport/socket/websocket-handler.js.map +1 -2
  48. package/dist/types/server-options.d.ts +2 -3
  49. package/dist/types/server-options.d.ts.map +1 -1
  50. package/dist/types/server-options.js.map +0 -1
  51. package/dist/utils/config-manager.js.map +0 -1
  52. package/dist/workers/service-protocol.worker.js.map +0 -1
  53. package/docs/authentication.md +35 -39
  54. package/docs/built-in-services.md +9 -9
  55. package/docs/server.md +68 -54
  56. package/docs/transport.md +7 -9
  57. package/package.json +7 -6
  58. package/src/auth/auth-token-payload.ts +6 -0
  59. package/src/auth/jwt-manager.ts +44 -0
  60. package/src/core/define-service.ts +159 -0
  61. package/src/core/service-executor.ts +68 -0
  62. package/src/index.ts +37 -0
  63. package/src/legacy/v1-auto-update-handler.ts +67 -0
  64. package/src/protocol/protocol-wrapper.ts +75 -0
  65. package/src/service-server.ts +249 -0
  66. package/src/services/auto-update-service.ts +53 -0
  67. package/src/services/crypto-service.ts +36 -0
  68. package/src/services/orm-service.ts +176 -0
  69. package/src/services/smtp-service.ts +59 -0
  70. package/src/transport/http/http-request-handler.ts +69 -0
  71. package/src/transport/http/static-file-handler.ts +66 -0
  72. package/src/transport/http/upload-handler.ts +87 -0
  73. package/src/transport/socket/service-socket.ts +136 -0
  74. package/src/transport/socket/websocket-handler.ts +180 -0
  75. package/src/types/server-options.ts +14 -0
  76. package/src/utils/config-manager.ts +70 -0
  77. package/src/workers/service-protocol.worker.ts +15 -0
  78. package/dist/auth/auth.decorators.d.ts +0 -19
  79. package/dist/auth/auth.decorators.d.ts.map +0 -1
  80. package/dist/auth/auth.decorators.js +0 -46
  81. package/dist/auth/auth.decorators.js.map +0 -7
  82. package/dist/core/service-base.d.ts +0 -19
  83. package/dist/core/service-base.d.ts.map +0 -1
  84. package/dist/core/service-base.js +0 -47
  85. package/dist/core/service-base.js.map +0 -7
package/README.md CHANGED
@@ -14,17 +14,18 @@ pnpm add @simplysm/service-server
14
14
 
15
15
  ## Main Modules
16
16
 
17
- ### Core Classes
17
+ ### Core Functions and Classes
18
18
 
19
+ - [`createServiceServer`](#basic-server-configuration) - Factory function for creating a ServiceServer instance
19
20
  - [`ServiceServer`](docs/server.md#serviceserver) - Main server class. Creates Fastify instance and configures routes/plugins
20
- - [`ServiceBase`](docs/server.md#custom-service-definition) - Service base abstract class. All custom services must inherit from this
21
+ - [`defineService`](#custom-services) - Defines a service with a factory function pattern
21
22
  - `ServiceExecutor` - Internal executor that handles service method discovery, auth checks, and execution
22
23
 
23
24
  ### Authentication
24
25
 
25
- - [`Authorize`](docs/authentication.md#authorize-decorator) - Stage 3 decorator. Sets authentication permissions at class or method level
26
+ - [`auth`](#authentication) - Function wrapper that sets authentication permissions at service or method level
27
+ - [`getServiceAuthPermissions`](#authentication) - Queries auth permissions for a service or method (used internally by `ServiceExecutor`)
26
28
  - [`JwtManager`](docs/authentication.md#jwtmanager) - JWT token generation/verification/decoding based on jose library (HS256, 12-hour expiration)
27
- - [`getAuthPermissions`](docs/authentication.md#getauthpermissions) - Queries auth permissions for a service class/method (used internally by `ServiceExecutor`)
28
29
  - [`AuthTokenPayload`](docs/authentication.md#authtokenpayload) - JWT payload interface (includes `roles`, `data`)
29
30
 
30
31
  ### Transport Layer - WebSocket
@@ -62,9 +63,9 @@ pnpm add @simplysm/service-server
62
63
  ### Basic Server Configuration
63
64
 
64
65
  ```typescript
65
- import { ServiceServer } from "@simplysm/service-server";
66
+ import { createServiceServer } from "@simplysm/service-server";
66
67
 
67
- const server = new ServiceServer({
68
+ const server = createServiceServer({
68
69
  port: 8080,
69
70
  rootPath: "/app/data",
70
71
  services: [MyService],
@@ -92,43 +93,94 @@ See [`ServiceServerOptions`](docs/server.md#server-options-serviceserveroptions)
92
93
 
93
94
  ### Custom Services
94
95
 
95
- Services are defined by inheriting from `ServiceBase`. Service methods are called via RPC from the client.
96
+ Services are defined using the `defineService` function. Service methods are called via RPC from the client.
96
97
 
97
98
  ```typescript
98
- import { ServiceBase } from "@simplysm/service-server";
99
+ import { defineService } from "@simplysm/service-server";
99
100
 
100
- class MyService extends ServiceBase {
101
- async hello(name: string): Promise<string> {
101
+ export const MyService = defineService("MyService", (ctx) => ({
102
+ hello: async (name: string): Promise<string> => {
102
103
  return `Hello, ${name}!`;
103
- }
104
+ },
104
105
 
105
- async getServerTime(): Promise<Date> {
106
+ getServerTime: async (): Promise<Date> => {
106
107
  return new Date();
107
- }
108
- }
108
+ },
109
+ }));
110
+
111
+ // Export type for client-side type sharing
112
+ export type MyServiceMethods = import("@simplysm/service-server").ServiceMethods<typeof MyService>;
109
113
  ```
110
114
 
111
- See [Custom Service Definition](docs/server.md#custom-service-definition) for more details on `ServiceBase` properties and methods.
115
+ #### ServiceContext
116
+
117
+ The `ctx` parameter provides access to server resources:
118
+
119
+ - `ctx.server` - ServiceServer instance
120
+ - `ctx.socket` - ServiceSocket instance (WebSocket only, undefined for HTTP)
121
+ - `ctx.http` - HTTP request/reply objects (HTTP only, undefined for WebSocket)
122
+ - `ctx.authInfo` - Authentication info (set via JWT token)
123
+ - `ctx.clientName` - Client identifier
124
+ - `ctx.getConfig(name)` - Get server config by name
112
125
 
113
126
  ### Authentication
114
127
 
115
- Use the `@Authorize()` decorator to set authentication requirements:
128
+ Use the `auth()` wrapper to set authentication requirements at service or method level:
116
129
 
117
130
  ```typescript
118
- import { ServiceBase, Authorize } from "@simplysm/service-server";
131
+ import { defineService, auth } from "@simplysm/service-server";
119
132
 
120
- @Authorize()
121
- class UserService extends ServiceBase<{ userId: number; role: string }> {
122
- async getProfile(): Promise<unknown> {
123
- const userId = this.authInfo?.userId;
133
+ interface UserAuthInfo {
134
+ userId: number;
135
+ role: string;
136
+ }
137
+
138
+ // Service-level auth: all methods require authentication
139
+ export const UserService = defineService("UserService", auth((ctx) => ({
140
+ getProfile: async (): Promise<unknown> => {
141
+ const userId = (ctx.authInfo as UserAuthInfo)?.userId;
124
142
  // ...
125
- }
143
+ },
126
144
 
127
- @Authorize(["admin"])
128
- async deleteUser(targetId: number): Promise<void> {
145
+ deleteUser: auth(["admin"], async (targetId: number): Promise<void> => {
129
146
  // Only users with admin role can call
130
- }
131
- }
147
+ }),
148
+ })));
149
+
150
+ export type UserServiceMethods = import("@simplysm/service-server").ServiceMethods<typeof UserService>;
151
+ ```
152
+
153
+ #### Auth Patterns
154
+
155
+ **Method-level auth only:**
156
+ ```typescript
157
+ export const MyService = defineService("MyService", (ctx) => ({
158
+ publicMethod: async (): Promise<void> => {
159
+ // No auth required
160
+ },
161
+
162
+ protectedMethod: auth(async (): Promise<void> => {
163
+ // Auth required
164
+ }),
165
+
166
+ adminMethod: auth(["admin"], async (): Promise<void> => {
167
+ // Auth + admin role required
168
+ }),
169
+ }));
170
+ ```
171
+
172
+ **Service-level auth with method override:**
173
+ ```typescript
174
+ // All methods require authentication by default
175
+ export const SecureService = defineService("SecureService", auth((ctx) => ({
176
+ normalMethod: async (): Promise<void> => {
177
+ // Auth required (inherited from service level)
178
+ },
179
+
180
+ adminMethod: auth(["admin"], async (): Promise<void> => {
181
+ // Auth + admin role required
182
+ }),
183
+ })));
132
184
  ```
133
185
 
134
186
  See [Authentication](docs/authentication.md) for JWT token management and permission handling.
@@ -166,14 +218,12 @@ See [File Upload](docs/transport.md#file-upload) for more details.
166
218
  Publish real-time events to connected WebSocket clients:
167
219
 
168
220
  ```typescript
169
- import { ServiceEventListener } from "@simplysm/service-common";
221
+ import { defineEvent } from "@simplysm/service-common";
170
222
 
171
- class OrderUpdatedEvent extends ServiceEventListener<
223
+ export const OrderUpdatedEvent = defineEvent<
172
224
  { orderId: number },
173
225
  { status: string }
174
- > {
175
- readonly eventName = "OrderUpdatedEvent";
176
- }
226
+ >("OrderUpdatedEvent");
177
227
 
178
228
  await server.emitEvent(
179
229
  OrderUpdatedEvent,
@@ -196,7 +246,9 @@ The package provides several built-in services:
196
246
  Register them like any other service:
197
247
 
198
248
  ```typescript
199
- const server = new ServiceServer({
249
+ import { createServiceServer, OrmService, CryptoService, SmtpService } from "@simplysm/service-server";
250
+
251
+ const server = createServiceServer({
200
252
  port: 8080,
201
253
  rootPath: "/app/data",
202
254
  auth: { jwtSecret: "secret" },
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": [],
4
- "sourcesContent": [],
5
4
  "mappings": "",
6
5
  "names": []
7
6
  }
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/auth/jwt-manager.ts"],
4
- "sourcesContent": ["import type { ServiceServer } from \"../service-server\";\nimport * as jose from \"jose\";\nimport type { AuthTokenPayload } from \"./auth-token-payload\";\n\nexport class JwtManager<TAuthInfo = unknown> {\n constructor(private readonly _server: ServiceServer<TAuthInfo>) {}\n\n async sign(payload: AuthTokenPayload<TAuthInfo>): Promise<string> {\n const jwtSecret = this._server.options.auth?.jwtSecret;\n if (jwtSecret == null) throw new Error(\"JWT Secret\uC774 \uC815\uC758\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.\");\n\n const secret = new TextEncoder().encode(jwtSecret);\n\n return new jose.SignJWT(payload)\n .setProtectedHeader({ alg: \"HS256\" })\n .setIssuedAt()\n .setExpirationTime(\"12h\")\n .sign(secret);\n }\n\n async verify(token: string): Promise<AuthTokenPayload<TAuthInfo>> {\n const jwtSecret = this._server.options.auth?.jwtSecret;\n if (jwtSecret == null) throw new Error(\"JWT Secret\uC774 \uC815\uC758\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.\");\n\n const secret = new TextEncoder().encode(jwtSecret);\n\n try {\n const { payload } = await jose.jwtVerify(token, secret);\n return payload as AuthTokenPayload<TAuthInfo>;\n } catch (err) {\n if (err != null && typeof err === \"object\" && \"code\" in err && err.code === \"ERR_JWT_EXPIRED\") {\n throw new Error(\"\uD1A0\uD070\uC774 \uB9CC\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\");\n }\n throw new Error(\"\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD1A0\uD070\uC785\uB2C8\uB2E4.\");\n }\n }\n\n decode(token: string): AuthTokenPayload<TAuthInfo> {\n const jwtSecret = this._server.options.auth?.jwtSecret;\n if (jwtSecret == null) throw new Error(\"JWT Secret\uC774 \uC815\uC758\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.\");\n\n return jose.decodeJwt(token) as AuthTokenPayload<TAuthInfo>;\n }\n}\n"],
5
4
  "mappings": "AACA,YAAY,UAAU;AAGf,MAAM,WAAgC;AAAA,EAC3C,YAA6B,SAAmC;AAAnC;AAAA,EAAoC;AAAA,EAEjE,MAAM,KAAK,SAAuD;AAChE,UAAM,YAAY,KAAK,QAAQ,QAAQ,MAAM;AAC7C,QAAI,aAAa,KAAM,OAAM,IAAI,MAAM,2EAAyB;AAEhE,UAAM,SAAS,IAAI,YAAY,EAAE,OAAO,SAAS;AAEjD,WAAO,IAAI,KAAK,QAAQ,OAAO,EAC5B,mBAAmB,EAAE,KAAK,QAAQ,CAAC,EACnC,YAAY,EACZ,kBAAkB,KAAK,EACvB,KAAK,MAAM;AAAA,EAChB;AAAA,EAEA,MAAM,OAAO,OAAqD;AAChE,UAAM,YAAY,KAAK,QAAQ,QAAQ,MAAM;AAC7C,QAAI,aAAa,KAAM,OAAM,IAAI,MAAM,2EAAyB;AAEhE,UAAM,SAAS,IAAI,YAAY,EAAE,OAAO,SAAS;AAEjD,QAAI;AACF,YAAM,EAAE,QAAQ,IAAI,MAAM,KAAK,UAAU,OAAO,MAAM;AACtD,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,UAAI,OAAO,QAAQ,OAAO,QAAQ,YAAY,UAAU,OAAO,IAAI,SAAS,mBAAmB;AAC7F,cAAM,IAAI,MAAM,gEAAc;AAAA,MAChC;AACA,YAAM,IAAI,MAAM,uEAAgB;AAAA,IAClC;AAAA,EACF;AAAA,EAEA,OAAO,OAA4C;AACjD,UAAM,YAAY,KAAK,QAAQ,QAAQ,MAAM;AAC7C,QAAI,aAAa,KAAM,OAAM,IAAI,MAAM,2EAAyB;AAEhE,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B;AACF;",
6
5
  "names": []
7
6
  }
@@ -0,0 +1,67 @@
1
+ import type { ServiceServer } from "../service-server";
2
+ import type { ServiceSocket } from "../transport/socket/service-socket";
3
+ import type { AuthTokenPayload } from "../auth/auth-token-payload";
4
+ export interface ServiceContext<TAuthInfo = unknown> {
5
+ server: ServiceServer<TAuthInfo>;
6
+ socket?: ServiceSocket;
7
+ http?: {
8
+ clientName: string;
9
+ authTokenPayload?: AuthTokenPayload<TAuthInfo>;
10
+ };
11
+ /** V1 legacy context (auto-update only) */
12
+ legacy?: {
13
+ clientName?: string;
14
+ };
15
+ get authInfo(): TAuthInfo | undefined;
16
+ get clientName(): string | undefined;
17
+ get clientPath(): string | undefined;
18
+ getConfig<T>(section: string): Promise<T>;
19
+ }
20
+ export declare function createServiceContext<TAuthInfo = unknown>(server: ServiceServer<TAuthInfo>, socket?: ServiceSocket, http?: {
21
+ clientName: string;
22
+ authTokenPayload?: AuthTokenPayload<TAuthInfo>;
23
+ }, legacy?: {
24
+ clientName?: string;
25
+ }): ServiceContext<TAuthInfo>;
26
+ /** Read auth permissions from an auth()-wrapped function. Returns undefined if not wrapped. */
27
+ export declare function getServiceAuthPermissions(fn: Function): string[] | undefined;
28
+ /**
29
+ * Auth wrapper for service factories and methods.
30
+ *
31
+ * - Service-level: `auth((ctx) => ({ ... }))` — all methods require login
32
+ * - Service-level with roles: `auth(["admin"], (ctx) => ({ ... }))`
33
+ * - Method-level: `auth(() => result)` — this method requires login
34
+ * - Method-level with roles: `auth(["admin"], () => result)`
35
+ */
36
+ export declare function auth<T extends (...args: any[]) => any>(fn: T): T;
37
+ export declare function auth<T extends (...args: any[]) => any>(permissions: string[], fn: T): T;
38
+ export interface ServiceDefinition<TMethods = Record<string, (...args: any[]) => any>> {
39
+ name: string;
40
+ factory: (ctx: ServiceContext) => TMethods;
41
+ authPermissions?: string[];
42
+ }
43
+ /**
44
+ * Define a service with a name and factory function.
45
+ *
46
+ * @example
47
+ * // Basic service
48
+ * const HealthService = defineService("Health", (ctx) => ({
49
+ * check: () => ({ status: "ok" }),
50
+ * }));
51
+ *
52
+ * // Service with auth
53
+ * const UserService = defineService("User", auth((ctx) => ({
54
+ * getProfile: () => ctx.authInfo,
55
+ * adminOnly: auth(["admin"], () => "admin"),
56
+ * })));
57
+ */
58
+ export declare function defineService<TMethods extends Record<string, (...args: any[]) => any>>(name: string, factory: (ctx: ServiceContext) => TMethods): ServiceDefinition<TMethods>;
59
+ /**
60
+ * Extract method signatures from a ServiceDefinition for client-side type sharing.
61
+ *
62
+ * @example
63
+ * export type UserServiceType = ServiceMethods<typeof UserService>;
64
+ * // Client: client.getService<UserServiceType>("User");
65
+ */
66
+ export type ServiceMethods<T> = T extends ServiceDefinition<infer M> ? M : never;
67
+ //# sourceMappingURL=define-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-service.d.ts","sourceRoot":"","sources":["../../src/core/define-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAOnE,MAAM,WAAW,cAAc,CAAC,SAAS,GAAG,OAAO;IACjD,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,IAAI,CAAC,EAAE;QACL,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;KAChD,CAAC;IAEF,2CAA2C;IAC3C,MAAM,CAAC,EAAE;QACP,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IAEF,IAAI,QAAQ,IAAI,SAAS,GAAG,SAAS,CAAC;IACtC,IAAI,UAAU,IAAI,MAAM,GAAG,SAAS,CAAC;IACrC,IAAI,UAAU,IAAI,MAAM,GAAG,SAAS,CAAC;IACrC,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC3C;AAED,wBAAgB,oBAAoB,CAAC,SAAS,GAAG,OAAO,EACtD,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,EAChC,MAAM,CAAC,EAAE,aAAa,EACtB,IAAI,CAAC,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAA;CAAE,EAC7E,MAAM,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/B,cAAc,CAAC,SAAS,CAAC,CAkD3B;AAMD,+FAA+F;AAC/F,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,EAAE,GAAG,SAAS,CAE5E;AAED;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;AAClE,wBAAgB,IAAI,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;AAczF,MAAM,WAAW,iBAAiB,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;IACnF,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,QAAQ,CAAC;IAC3C,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,EACpF,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,QAAQ,GACzC,iBAAiB,CAAC,QAAQ,CAAC,CAM7B;AAID;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,CAAC,SAAS,iBAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { objMerge } from "@simplysm/core-common";
2
+ import { ConfigManager } from "../utils/config-manager.js";
3
+ import path from "path";
4
+ function createServiceContext(server, socket, http, legacy) {
5
+ return {
6
+ server,
7
+ socket,
8
+ http,
9
+ legacy,
10
+ get authInfo() {
11
+ return socket?.authTokenPayload?.data ?? http?.authTokenPayload?.data;
12
+ },
13
+ get clientName() {
14
+ const name = socket?.clientName ?? http?.clientName ?? legacy?.clientName;
15
+ if (name == null) return void 0;
16
+ if (name === "" || name.includes("..") || name.includes("/") || name.includes("\\")) {
17
+ throw new Error(`\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD074\uB77C\uC774\uC5B8\uD2B8 \uBA85\uC785\uB2C8\uB2E4: ${name}`);
18
+ }
19
+ return name;
20
+ },
21
+ get clientPath() {
22
+ const name = this.clientName;
23
+ return name == null ? void 0 : path.resolve(server.options.rootPath, "www", name);
24
+ },
25
+ async getConfig(section) {
26
+ let configParent = {};
27
+ const rootFilePath = path.resolve(server.options.rootPath, ".config.json");
28
+ const rootConfig = await ConfigManager.getConfig(rootFilePath);
29
+ if (rootConfig != null) {
30
+ configParent = rootConfig;
31
+ }
32
+ const targetPath = this.clientPath;
33
+ if (targetPath != null) {
34
+ const clientFilePath = path.resolve(targetPath, ".config.json");
35
+ const clientConfig = await ConfigManager.getConfig(clientFilePath);
36
+ if (clientConfig != null) {
37
+ configParent = objMerge(configParent, clientConfig);
38
+ }
39
+ }
40
+ const config = configParent[section];
41
+ if (config == null) throw new Error(`\uC124\uC815 \uC139\uC158\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${section}`);
42
+ return config;
43
+ }
44
+ };
45
+ }
46
+ const AUTH_PERMISSIONS = /* @__PURE__ */ Symbol("authPermissions");
47
+ function getServiceAuthPermissions(fn) {
48
+ return fn[AUTH_PERMISSIONS];
49
+ }
50
+ function auth(permissionsOrFn, maybeFn) {
51
+ const permissions = Array.isArray(permissionsOrFn) ? permissionsOrFn : [];
52
+ const fn = Array.isArray(permissionsOrFn) ? maybeFn : permissionsOrFn;
53
+ const wrapper = (...args) => fn(...args);
54
+ wrapper[AUTH_PERMISSIONS] = permissions;
55
+ return wrapper;
56
+ }
57
+ function defineService(name, factory) {
58
+ return {
59
+ name,
60
+ factory,
61
+ authPermissions: getServiceAuthPermissions(factory)
62
+ };
63
+ }
64
+ export {
65
+ auth,
66
+ createServiceContext,
67
+ defineService,
68
+ getServiceAuthPermissions
69
+ };
70
+ //# sourceMappingURL=define-service.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/core/define-service.ts"],
4
+ "mappings": "AAGA,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;AAC9B,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,IACpE;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,kGAAuB,IAAI,EAAE;AAAA,MAC/C;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,cAAc,UAA6B,YAAY;AAChF,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,cAAc,UAA6B,cAAc;AACpF,YAAI,gBAAgB,MAAM;AACxB,yBAAe,SAAS,cAAc,YAAY;AAAA,QACpD;AAAA,MACF;AAEA,YAAM,SAAS,aAAa,OAAO;AACnC,UAAI,UAAU,KAAM,OAAM,IAAI,MAAM,iFAAqB,OAAO,EAAE;AAClE,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAIA,MAAM,mBAAmB,uBAAO,iBAAiB;AAG1C,SAAS,0BAA0B,IAAoC;AAC5E,SAAQ,GAA0C,gBAAgB;AACpE;AAYO,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
+ "names": []
6
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"service-executor.d.ts","sourceRoot":"","sources":["../../src/core/service-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAGnE,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,aAAa;IAE7C,SAAS,CAAC,GAAG,EAAE;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,OAAO,EAAE,CAAC;QAClB,MAAM,CAAC,EAAE,aAAa,CAAC;QACvB,IAAI,CAAC,EAAE;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;SAAE,CAAC;KACpE,GAAG,OAAO,CAAC,OAAO,CAAC;CAuDrB"}
1
+ {"version":3,"file":"service-executor.d.ts","sourceRoot":"","sources":["../../src/core/service-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAGnE,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,aAAa;IAE7C,SAAS,CAAC,GAAG,EAAE;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,OAAO,EAAE,CAAC;QAClB,MAAM,CAAC,EAAE,aAAa,CAAC;QACvB,IAAI,CAAC,EAAE;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;SAAE,CAAC;KACpE,GAAG,OAAO,CAAC,OAAO,CAAC;CAqDrB"}
@@ -1,11 +1,11 @@
1
- import { getAuthPermissions } from "../auth/auth.decorators.js";
1
+ import { createServiceContext, getServiceAuthPermissions } from "./define-service.js";
2
2
  class ServiceExecutor {
3
3
  constructor(_server) {
4
4
  this._server = _server;
5
5
  }
6
6
  async runMethod(def) {
7
- const ServiceClass = this._server.options.services.find((item) => item.name === def.serviceName);
8
- if (ServiceClass == null) {
7
+ const serviceDef = this._server.options.services.find((item) => item.name === def.serviceName);
8
+ if (serviceDef == null) {
9
9
  throw new Error(`\uC11C\uBE44\uC2A4[${def.serviceName}]\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`);
10
10
  }
11
11
  const clientName = def.socket?.clientName ?? def.http?.clientName;
@@ -14,8 +14,15 @@ class ServiceExecutor {
14
14
  throw new Error(`[Security] \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD074\uB77C\uC774\uC5B8\uD2B8\uBA85\uC785\uB2C8\uB2E4: ${clientName}`);
15
15
  }
16
16
  }
17
+ const ctx = createServiceContext(this._server, def.socket, def.http);
18
+ const methods = serviceDef.factory(ctx);
19
+ const method = methods[def.methodName];
20
+ if (typeof method !== "function") {
21
+ throw new Error(`\uBA54\uC18C\uB4DC[${def.serviceName}.${def.methodName}]\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`);
22
+ }
17
23
  if (this._server.options.auth != null) {
18
- const requiredPerms = getAuthPermissions(ServiceClass, def.methodName);
24
+ const methodPerms = getServiceAuthPermissions(method);
25
+ const requiredPerms = methodPerms ?? serviceDef.authPermissions;
19
26
  if (requiredPerms != null) {
20
27
  const authTokenPayload = def.socket?.authTokenPayload ?? def.http?.authTokenPayload;
21
28
  if (authTokenPayload == null) {
@@ -29,15 +36,7 @@ class ServiceExecutor {
29
36
  }
30
37
  }
31
38
  }
32
- const service = new ServiceClass();
33
- service.server = this._server;
34
- service.socket = def.socket;
35
- service.http = def.http;
36
- const method = service[def.methodName];
37
- if (typeof method !== "function") {
38
- throw new Error(`\uBA54\uC18C\uB4DC[${def.serviceName}.${def.methodName}]\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`);
39
- }
40
- return await method.apply(service, def.params);
39
+ return await method(...def.params);
41
40
  }
42
41
  }
43
42
  export {
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/core/service-executor.ts"],
4
- "sourcesContent": ["import type { ServiceServer } from \"../service-server\";\nimport type { ServiceSocket } from \"../transport/socket/service-socket\";\nimport type { AuthTokenPayload } from \"../auth/auth-token-payload\";\nimport { getAuthPermissions } from \"../auth/auth.decorators\";\n\nexport class ServiceExecutor {\n constructor(private readonly _server: ServiceServer) {}\n\n async runMethod(def: {\n serviceName: string;\n methodName: string;\n params: unknown[];\n socket?: ServiceSocket;\n http?: { clientName: string; authTokenPayload?: AuthTokenPayload };\n }): Promise<unknown> {\n // \uC11C\uBE44\uC2A4 \uD074\uB798\uC2A4 \uCC3E\uAE30\n const ServiceClass = this._server.options.services.find((item) => item.name === def.serviceName);\n\n if (ServiceClass == null) {\n throw new Error(`\uC11C\uBE44\uC2A4[${def.serviceName}]\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`);\n }\n\n // \uC694\uCCAD \uAC80\uC99D (Gatekeeper)\n const clientName = def.socket?.clientName ?? def.http?.clientName;\n if (clientName != null) {\n if (clientName.includes(\"..\") || clientName.includes(\"/\") || clientName.includes(\"\\\\\")) {\n throw new Error(`[Security] \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD074\uB77C\uC774\uC5B8\uD2B8\uBA85\uC785\uB2C8\uB2E4: ${clientName}`);\n }\n }\n\n // \uC778\uC99D\uAC80\uC0AC\n if (this._server.options.auth != null) {\n // \uBA54\uC18C\uB4DC \uB808\uBCA8 \u2192 \uD074\uB798\uC2A4 \uB808\uBCA8 \uC21C\uC73C\uB85C \uAD8C\uD55C \uD655\uC778\n const requiredPerms = getAuthPermissions(ServiceClass, def.methodName);\n\n // \uAD8C\uD55C \uC124\uC815\uC774 \uC788\uC73C\uBA74 \uC778\uC99D \uD544\uC694\n if (requiredPerms != null) {\n const authTokenPayload = def.socket?.authTokenPayload ?? def.http?.authTokenPayload;\n\n // \uAD8C\uD55C\uC774 \uD544\uC694\uD55C\uB370 \uC778\uC99D\uC815\uBCF4\uAC00 \uC5C6\uC73C\uBA74 \uC5D0\uB7EC\n if (authTokenPayload == null) {\n throw new Error(\"\uB85C\uADF8\uC778\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.\");\n }\n\n // \uAD8C\uD55C \uBAA9\uB85D \uCCB4\uD06C (\uBE48 \uBC30\uC5F4\uC774\uBA74 \uB85C\uADF8\uC778\uB9CC \uCCB4\uD06C)\n if (requiredPerms.length > 0) {\n const hasPerm = requiredPerms.some((perm) => authTokenPayload.roles.includes(perm));\n if (!hasPerm) {\n throw new Error(\"\uAD8C\uD55C\uC774 \uBD80\uC871\uD569\uB2C8\uB2E4.\");\n }\n }\n }\n }\n\n // \uC11C\uBE44\uC2A4 \uC778\uC2A4\uD134\uC2A4 \uC0DD\uC131 (Context \uC8FC\uC785)\n const service = new ServiceClass();\n service.server = this._server;\n service.socket = def.socket;\n service.http = def.http;\n\n // \uBA54\uC18C\uB4DC \uCC3E\uAE30\n const method = (service as unknown as Record<string, unknown>)[def.methodName];\n if (typeof method !== \"function\") {\n throw new Error(`\uBA54\uC18C\uB4DC[${def.serviceName}.${def.methodName}]\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`);\n }\n\n // \uC2E4\uD589\n return await method.apply(service, def.params);\n }\n}\n"],
5
- "mappings": "AAGA,SAAS,0BAA0B;AAE5B,MAAM,gBAAgB;AAAA,EAC3B,YAA6B,SAAwB;AAAxB;AAAA,EAAyB;AAAA,EAEtD,MAAM,UAAU,KAMK;AAEnB,UAAM,eAAe,KAAK,QAAQ,QAAQ,SAAS,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,WAAW;AAE/F,QAAI,gBAAgB,MAAM;AACxB,YAAM,IAAI,MAAM,sBAAO,IAAI,WAAW,uDAAe;AAAA,IACvD;AAGA,UAAM,aAAa,IAAI,QAAQ,cAAc,IAAI,MAAM;AACvD,QAAI,cAAc,MAAM;AACtB,UAAI,WAAW,SAAS,IAAI,KAAK,WAAW,SAAS,GAAG,KAAK,WAAW,SAAS,IAAI,GAAG;AACtF,cAAM,IAAI,MAAM,4GAAiC,UAAU,EAAE;AAAA,MAC/D;AAAA,IACF;AAGA,QAAI,KAAK,QAAQ,QAAQ,QAAQ,MAAM;AAErC,YAAM,gBAAgB,mBAAmB,cAAc,IAAI,UAAU;AAGrE,UAAI,iBAAiB,MAAM;AACzB,cAAM,mBAAmB,IAAI,QAAQ,oBAAoB,IAAI,MAAM;AAGnE,YAAI,oBAAoB,MAAM;AAC5B,gBAAM,IAAI,MAAM,0DAAa;AAAA,QAC/B;AAGA,YAAI,cAAc,SAAS,GAAG;AAC5B,gBAAM,UAAU,cAAc,KAAK,CAAC,SAAS,iBAAiB,MAAM,SAAS,IAAI,CAAC;AAClF,cAAI,CAAC,SAAS;AACZ,kBAAM,IAAI,MAAM,oDAAY;AAAA,UAC9B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,UAAU,IAAI,aAAa;AACjC,YAAQ,SAAS,KAAK;AACtB,YAAQ,SAAS,IAAI;AACrB,YAAQ,OAAO,IAAI;AAGnB,UAAM,SAAU,QAA+C,IAAI,UAAU;AAC7E,QAAI,OAAO,WAAW,YAAY;AAChC,YAAM,IAAI,MAAM,sBAAO,IAAI,WAAW,IAAI,IAAI,UAAU,uDAAe;AAAA,IACzE;AAGA,WAAO,MAAM,OAAO,MAAM,SAAS,IAAI,MAAM;AAAA,EAC/C;AACF;",
4
+ "mappings": "AAGA,SAAS,sBAAsB,iCAAiC;AAEzD,MAAM,gBAAgB;AAAA,EAC3B,YAA6B,SAAwB;AAAxB;AAAA,EAAyB;AAAA,EAEtD,MAAM,UAAU,KAMK;AAEnB,UAAM,aAAa,KAAK,QAAQ,QAAQ,SAAS,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,WAAW;AAE7F,QAAI,cAAc,MAAM;AACtB,YAAM,IAAI,MAAM,sBAAO,IAAI,WAAW,uDAAe;AAAA,IACvD;AAGA,UAAM,aAAa,IAAI,QAAQ,cAAc,IAAI,MAAM;AACvD,QAAI,cAAc,MAAM;AACtB,UAAI,WAAW,SAAS,IAAI,KAAK,WAAW,SAAS,GAAG,KAAK,WAAW,SAAS,IAAI,GAAG;AACtF,cAAM,IAAI,MAAM,4GAAiC,UAAU,EAAE;AAAA,MAC/D;AAAA,IACF;AAGA,UAAM,MAAM,qBAAqB,KAAK,SAAS,IAAI,QAAQ,IAAI,IAAI;AAGnE,UAAM,UAAU,WAAW,QAAQ,GAAG;AAGtC,UAAM,SAAU,QAAoC,IAAI,UAAU;AAClE,QAAI,OAAO,WAAW,YAAY;AAChC,YAAM,IAAI,MAAM,sBAAO,IAAI,WAAW,IAAI,IAAI,UAAU,uDAAe;AAAA,IACzE;AAGA,QAAI,KAAK,QAAQ,QAAQ,QAAQ,MAAM;AAErC,YAAM,cAAc,0BAA0B,MAAM;AACpD,YAAM,gBAAgB,eAAe,WAAW;AAEhD,UAAI,iBAAiB,MAAM;AACzB,cAAM,mBAAmB,IAAI,QAAQ,oBAAoB,IAAI,MAAM;AAEnE,YAAI,oBAAoB,MAAM;AAC5B,gBAAM,IAAI,MAAM,0DAAa;AAAA,QAC/B;AAEA,YAAI,cAAc,SAAS,GAAG;AAC5B,gBAAM,UAAU,cAAc,KAAK,CAAC,SAAS,iBAAiB,MAAM,SAAS,IAAI,CAAC;AAClF,cAAI,CAAC,SAAS;AACZ,kBAAM,IAAI,MAAM,oDAAY;AAAA,UAC9B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,WAAO,MAAM,OAAO,GAAG,IAAI,MAAM;AAAA,EACnC;AACF;",
6
5
  "names": []
7
6
  }
package/dist/index.d.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  export * from "./types/server-options";
2
- export * from "./auth/auth.decorators";
3
2
  export * from "./auth/auth-token-payload";
4
3
  export * from "./auth/jwt-manager";
5
- export * from "./core/service-base";
4
+ export * from "./core/define-service";
6
5
  export * from "./core/service-executor";
7
6
  export * from "./transport/socket/websocket-handler";
8
7
  export * from "./transport/socket/service-socket";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,wBAAwB,CAAC;AAGvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AAGnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AAGxC,cAAc,sCAAsC,CAAC;AACrD,cAAc,mCAAmC,CAAC;AAGlD,cAAc,uCAAuC,CAAC;AACtD,cAAc,iCAAiC,CAAC;AAChD,cAAc,sCAAsC,CAAC;AAGrD,cAAc,6BAA6B,CAAC;AAG5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAG/C,cAAc,wBAAwB,CAAC;AAGvC,cAAc,iCAAiC,CAAC;AAGhD,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,wBAAwB,CAAC;AAGvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AAGnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AAGxC,cAAc,sCAAsC,CAAC;AACrD,cAAc,mCAAmC,CAAC;AAGlD,cAAc,uCAAuC,CAAC;AACtD,cAAc,iCAAiC,CAAC;AAChD,cAAc,sCAAsC,CAAC;AAGrD,cAAc,6BAA6B,CAAC;AAG5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAG/C,cAAc,wBAAwB,CAAC;AAGvC,cAAc,iCAAiC,CAAC;AAGhD,cAAc,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -1,8 +1,7 @@
1
1
  export * from "./types/server-options.js";
2
- export * from "./auth/auth.decorators.js";
3
2
  export * from "./auth/auth-token-payload.js";
4
3
  export * from "./auth/jwt-manager.js";
5
- export * from "./core/service-base.js";
4
+ export * from "./core/define-service.js";
6
5
  export * from "./core/service-executor.js";
7
6
  export * from "./transport/socket/websocket-handler.js";
8
7
  export * from "./transport/socket/service-socket.js";
package/dist/index.js.map CHANGED
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["// Types\nexport * from \"./types/server-options\";\n\n// Auth\nexport * from \"./auth/auth.decorators\";\nexport * from \"./auth/auth-token-payload\";\nexport * from \"./auth/jwt-manager\";\n\n// Core\nexport * from \"./core/service-base\";\nexport * from \"./core/service-executor\";\n\n// Transport - Socket\nexport * from \"./transport/socket/websocket-handler\";\nexport * from \"./transport/socket/service-socket\";\n\n// Transport - HTTP\nexport * from \"./transport/http/http-request-handler\";\nexport * from \"./transport/http/upload-handler\";\nexport * from \"./transport/http/static-file-handler\";\n\n// Protocol\nexport * from \"./protocol/protocol-wrapper\";\n\n// Services\nexport * from \"./services/orm-service\";\nexport * from \"./services/crypto-service\";\nexport * from \"./services/smtp-service\";\nexport * from \"./services/auto-update-service\";\n\n// Utils\nexport * from \"./utils/config-manager\";\n\n// Legacy\nexport * from \"./legacy/v1-auto-update-handler\";\n\n// Main\nexport * from \"./service-server\";\n"],
5
- "mappings": "AACA,cAAc;AAGd,cAAc;AACd,cAAc;AACd,cAAc;AAGd,cAAc;AACd,cAAc;AAGd,cAAc;AACd,cAAc;AAGd,cAAc;AACd,cAAc;AACd,cAAc;AAGd,cAAc;AAGd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAGd,cAAc;AAGd,cAAc;AAGd,cAAc;",
4
+ "mappings": "AACA,cAAc;AAGd,cAAc;AACd,cAAc;AAGd,cAAc;AACd,cAAc;AAGd,cAAc;AACd,cAAc;AAGd,cAAc;AACd,cAAc;AACd,cAAc;AAGd,cAAc;AAGd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAGd,cAAc;AAGd,cAAc;AAGd,cAAc;",
6
5
  "names": []
7
6
  }
@@ -1,8 +1,9 @@
1
1
  import type { WebSocket } from "ws";
2
- import type { AutoUpdateService } from "../services/auto-update-service";
3
2
  /**
4
3
  * V1 레거시 클라이언트 처리 (auto-update만 지원)
5
4
  * 다른 모든 요청은 업그레이드 유도 에러를 반환합니다.
6
5
  */
7
- export declare function handleV1Connection(socket: WebSocket, autoUpdateService: AutoUpdateService): void;
6
+ export declare function handleV1Connection(socket: WebSocket, autoUpdateMethods: {
7
+ getLastVersion: (platform: string) => Promise<any>;
8
+ }, clientNameSetter?: (clientName: string | undefined) => void): void;
8
9
  //# sourceMappingURL=v1-auto-update-handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"v1-auto-update-handler.d.ts","sourceRoot":"","sources":["../../src/legacy/v1-auto-update-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAmBzE;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,iBAAiB,QAuCzF"}
1
+ {"version":3,"file":"v1-auto-update-handler.d.ts","sourceRoot":"","sources":["../../src/legacy/v1-auto-update-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAmBpC;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,EACjB,iBAAiB,EAAE;IAAE,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;CAAE,EACzE,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,QAwC5D"}
@@ -1,13 +1,13 @@
1
1
  import consola from "consola";
2
2
  const logger = consola.withTag("service-server:V1AutoUpdateHandler");
3
- function handleV1Connection(socket, autoUpdateService) {
3
+ function handleV1Connection(socket, autoUpdateMethods, clientNameSetter) {
4
4
  socket.send(JSON.stringify({ name: "connected" }));
5
5
  socket.on("message", (data) => {
6
6
  try {
7
7
  const msg = JSON.parse(data.toString());
8
8
  if (msg.command === "SdAutoUpdateService.getLastVersion") {
9
- autoUpdateService.legacy = { clientName: msg.clientName };
10
- const result = autoUpdateService.getLastVersion(msg.params[0]);
9
+ clientNameSetter?.(msg.clientName);
10
+ const result = autoUpdateMethods.getLastVersion(msg.params[0]);
11
11
  const response = {
12
12
  name: "response",
13
13
  reqUuid: msg.uuid,
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/legacy/v1-auto-update-handler.ts"],
4
- "sourcesContent": ["import type { WebSocket } from \"ws\";\nimport type { AutoUpdateService } from \"../services/auto-update-service\";\nimport consola from \"consola\";\n\nconst logger = consola.withTag(\"service-server:V1AutoUpdateHandler\");\n\ninterface IV1Request {\n uuid: string;\n command: string;\n params: unknown[];\n clientName?: string;\n}\n\ninterface IV1Response {\n name: \"response\";\n reqUuid: string;\n state: \"success\" | \"error\";\n body: unknown;\n}\n\n/**\n * V1 \uB808\uAC70\uC2DC \uD074\uB77C\uC774\uC5B8\uD2B8 \uCC98\uB9AC (auto-update\uB9CC \uC9C0\uC6D0)\n * \uB2E4\uB978 \uBAA8\uB4E0 \uC694\uCCAD\uC740 \uC5C5\uADF8\uB808\uC774\uB4DC \uC720\uB3C4 \uC5D0\uB7EC\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4.\n */\nexport function handleV1Connection(socket: WebSocket, autoUpdateService: AutoUpdateService) {\n // \uC5F0\uACB0 \uC644\uB8CC \uC54C\uB9BC\n socket.send(JSON.stringify({ name: \"connected\" }));\n\n socket.on(\"message\", (data) => {\n try {\n const msg = JSON.parse(data.toString()) as IV1Request;\n\n // SdAutoUpdateService.getLastVersion\uB9CC \uD5C8\uC6A9\n if (msg.command === \"SdAutoUpdateService.getLastVersion\") {\n // legacy \uCEE8\uD14D\uC2A4\uD2B8 \uC124\uC815\n autoUpdateService.legacy = { clientName: msg.clientName };\n\n const result = autoUpdateService.getLastVersion(msg.params[0] as string);\n\n const response: IV1Response = {\n name: \"response\",\n reqUuid: msg.uuid,\n state: \"success\",\n body: result,\n };\n socket.send(JSON.stringify(response));\n } else {\n // \uB2E4\uB978 \uBAA8\uB4E0 \uC694\uCCAD\uC740 \uC5C5\uADF8\uB808\uC774\uB4DC \uC720\uB3C4\n const response: IV1Response = {\n name: \"response\",\n reqUuid: msg.uuid,\n state: \"error\",\n body: {\n message: \"\uC571 \uC5C5\uB370\uC774\uD2B8\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.\",\n code: \"UPGRADE_REQUIRED\",\n },\n };\n socket.send(JSON.stringify(response));\n }\n } catch (err) {\n logger.warn(\"V1 \uBA54\uC2DC\uC9C0 \uCC98\uB9AC \uC624\uB958\", err);\n }\n });\n}\n"],
5
- "mappings": "AAEA,OAAO,aAAa;AAEpB,MAAM,SAAS,QAAQ,QAAQ,oCAAoC;AAoB5D,SAAS,mBAAmB,QAAmB,mBAAsC;AAE1F,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,0BAAkB,SAAS,EAAE,YAAY,IAAI,WAAW;AAExD,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,mDAAgB,GAAG;AAAA,IACjC;AAAA,EACF,CAAC;AACH;",
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,mDAAgB,GAAG;AAAA,IACjC;AAAA,EACF,CAAC;AACH;",
6
5
  "names": []
7
6
  }
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/protocol/protocol-wrapper.ts"],
4
- "sourcesContent": ["import type { Bytes } from \"@simplysm/core-common\";\nimport { Worker, type WorkerProxy } from \"@simplysm/core-node\";\nimport type { ServiceMessageDecodeResult, ServiceMessage } from \"@simplysm/service-common\";\nimport { ServiceProtocol } from \"@simplysm/service-common\";\nimport type * as ServiceProtocolWorkerModule from \"../workers/service-protocol.worker\";\n\nexport class ProtocolWrapper {\n // \uC6CC\uCEE4 \uC2A4\uB808\uB4DC (\uBB34\uAC70\uC6B4 \uC791\uC5C5\uC6A9, Static Lazy Singleton)\n private static _worker?: WorkerProxy<typeof ServiceProtocolWorkerModule>;\n private static get worker() {\n if (this._worker == null) {\n this._worker = Worker.create<typeof ServiceProtocolWorkerModule>(\n import.meta.resolve(\"../workers/service-protocol.worker\"),\n {\n resourceLimits: { maxOldGenerationSizeMb: 4096 },\n },\n );\n }\n return this._worker;\n }\n\n // \uBA54\uC778 \uC2A4\uB808\uB4DC\uC6A9 \uD504\uB85C\uD1A0\uCF5C \uC778\uC2A4\uD134\uC2A4 (\uAC00\uBCBC\uC6B4 \uC791\uC5C5\uC6A9)\n private readonly _protocol = new ServiceProtocol();\n\n // \uAE30\uC900\uAC12 \uC124\uC815\n private readonly _SIZE_THRESHOLD = 30 * 1024; // 30KB\n\n /**\n * \uBA54\uC2DC\uC9C0 \uC778\uCF54\uB529 (\uC790\uB3D9 \uBD84\uAE30 \uCC98\uB9AC)\n */\n async encode(uuid: string, message: ServiceMessage): Promise<{ chunks: Bytes[]; totalSize: number }> {\n if (this._shouldUseWorkerForEncode(message)) {\n return ProtocolWrapper.worker.encode(uuid, message);\n } else {\n return this._protocol.encode(uuid, message);\n }\n }\n\n /**\n * \uBA54\uC2DC\uC9C0 \uB514\uCF54\uB529 (\uC790\uB3D9 \uBD84\uAE30 \uCC98\uB9AC)\n */\n async decode(bytes: Bytes): Promise<ServiceMessageDecodeResult<ServiceMessage>> {\n const totalSize = bytes.length;\n if (totalSize > this._SIZE_THRESHOLD) {\n return ProtocolWrapper.worker.decode(bytes);\n } else {\n return this._protocol.decode(bytes);\n }\n }\n\n /**\n * \uC6CC\uCEE4 \uC0AC\uC6A9 \uC5EC\uBD80 \uD310\uB2E8 \uB85C\uC9C1 (Encode)\n */\n private _shouldUseWorkerForEncode(msg: ServiceMessage): boolean {\n if (!(\"body\" in msg)) return false;\n\n const body = msg.body;\n\n // Uint8Array: \uD06C\uAE30 \uD655\uC778\n if (body instanceof Uint8Array) {\n return true;\n }\n\n // Array: \uAE38\uC774 \uD655\uC778 (ORM \uACB0\uACFC \uB4F1)\n if (Array.isArray(body)) {\n return body.length > 0 && body.some((item) => item instanceof Uint8Array);\n }\n\n return false;\n }\n\n dispose() {\n this._protocol.dispose();\n }\n}\n"],
5
4
  "mappings": "AACA,SAAS,cAAgC;AAEzC,SAAS,uBAAuB;AAGzB,MAAM,gBAAgB;AAAA;AAAA,EAE3B,OAAe;AAAA,EACf,WAAmB,SAAS;AAC1B,QAAI,KAAK,WAAW,MAAM;AACxB,WAAK,UAAU,OAAO;AAAA,QACpB,YAAY,QAAQ,oCAAoC;AAAA,QACxD;AAAA,UACE,gBAAgB,EAAE,wBAAwB,KAAK;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGiB,YAAY,IAAI,gBAAgB;AAAA;AAAA,EAGhC,kBAAkB,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,EAKxC,MAAM,OAAO,MAAc,SAA0E;AACnG,QAAI,KAAK,0BAA0B,OAAO,GAAG;AAC3C,aAAO,gBAAgB,OAAO,OAAO,MAAM,OAAO;AAAA,IACpD,OAAO;AACL,aAAO,KAAK,UAAU,OAAO,MAAM,OAAO;AAAA,IAC5C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,OAAmE;AAC9E,UAAM,YAAY,MAAM;AACxB,QAAI,YAAY,KAAK,iBAAiB;AACpC,aAAO,gBAAgB,OAAO,OAAO,KAAK;AAAA,IAC5C,OAAO;AACL,aAAO,KAAK,UAAU,OAAO,KAAK;AAAA,IACpC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,0BAA0B,KAA8B;AAC9D,QAAI,EAAE,UAAU,KAAM,QAAO;AAE7B,UAAM,OAAO,IAAI;AAGjB,QAAI,gBAAgB,YAAY;AAC9B,aAAO;AAAA,IACT;AAGA,QAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,aAAO,KAAK,SAAS,KAAK,KAAK,KAAK,CAAC,SAAS,gBAAgB,UAAU;AAAA,IAC1E;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,UAAU;AACR,SAAK,UAAU,QAAQ;AAAA,EACzB;AACF;",
6
5
  "names": []
7
6
  }
@@ -1,5 +1,4 @@
1
- import type { ServiceEventListener } from "@simplysm/service-common";
2
- import type { Type } from "@simplysm/core-common";
1
+ import type { ServiceEventDef } from "@simplysm/service-common";
3
2
  import { EventEmitter } from "@simplysm/core-common";
4
3
  import type { FastifyInstance } from "fastify";
5
4
  import type { AuthTokenPayload } from "./auth/auth-token-payload";
@@ -21,9 +20,10 @@ export declare class ServiceServer<TAuthInfo = unknown> extends EventEmitter<{
21
20
  listen(): Promise<void>;
22
21
  close(): Promise<void>;
23
22
  broadcastReload(clientName: string | undefined, changedFileSet: Set<string>): Promise<void>;
24
- emitEvent<T extends ServiceEventListener<unknown, unknown>>(eventType: Type<T>, infoSelector: (item: T["$info"]) => boolean, data: T["$data"]): Promise<void>;
23
+ emitEvent<TInfo, TData>(eventDef: ServiceEventDef<TInfo, TData>, infoSelector: (item: TInfo) => boolean, data: TData): Promise<void>;
25
24
  generateAuthToken(payload: AuthTokenPayload<TAuthInfo>): Promise<string>;
26
25
  verifyAuthToken(token: string): Promise<AuthTokenPayload<TAuthInfo>>;
27
26
  private _registerGracefulShutdown;
28
27
  }
28
+ export declare function createServiceServer<TAuthInfo = unknown>(options: ServiceServerOptions): ServiceServer<TAuthInfo>;
29
29
  //# sourceMappingURL=service-server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"service-server.d.ts","sourceRoot":"","sources":["../src/service-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAIrE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAA4B,YAAY,EAAO,MAAM,uBAAuB,CAAC;AACpF,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AAa/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAOnE,qBAAa,aAAa,CAAC,SAAS,GAAG,OAAO,CAAE,SAAQ,YAAY,CAAC;IACnE,KAAK,EAAE,IAAI,CAAC;IACZ,KAAK,EAAE,IAAI,CAAC;CACb,CAAC;IAcY,QAAQ,CAAC,OAAO,EAAE,oBAAoB;IAblD,MAAM,UAAS;IAEf,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA6B;IAC9D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAmC;IAExD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAkE;IACtG,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA+B;IAClE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAsC;IAErE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0D;IAErF,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;gBAEb,OAAO,EAAE,oBAAoB;IAY5C,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IA2HvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC;IAK3E,SAAS,CAAC,CAAC,SAAS,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,EAC9D,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,EAClB,YAAY,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,OAAO,EAC3C,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC;IAKZ,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,CAAC,SAAS,CAAC;IAItD,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAI1E,OAAO,CAAC,yBAAyB;CAyBlC"}
1
+ {"version":3,"file":"service-server.d.ts","sourceRoot":"","sources":["../src/service-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAIhE,OAAO,EAA4B,YAAY,EAAO,MAAM,uBAAuB,CAAC;AACpF,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AAa/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAOnE,qBAAa,aAAa,CAAC,SAAS,GAAG,OAAO,CAAE,SAAQ,YAAY,CAAC;IACnE,KAAK,EAAE,IAAI,CAAC;IACZ,KAAK,EAAE,IAAI,CAAC;CACb,CAAC;IAcY,QAAQ,CAAC,OAAO,EAAE,oBAAoB;IAblD,MAAM,UAAS;IAEf,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA6B;IAC9D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAmC;IAExD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAkE;IACtG,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA+B;IAClE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAsC;IAErE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0D;IAErF,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;gBAEb,OAAO,EAAE,oBAAoB;IAY5C,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAsIvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC;IAK3E,SAAS,CAAC,KAAK,EAAE,KAAK,EAC1B,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,EACvC,YAAY,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,EACtC,IAAI,EAAE,KAAK;IAKP,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,CAAC,SAAS,CAAC;IAItD,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAI1E,OAAO,CAAC,yBAAyB;CAyBlC;AAED,wBAAgB,mBAAmB,CAAC,SAAS,GAAG,OAAO,EAAE,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAAC,SAAS,CAAC,CAEhH"}
@@ -14,7 +14,7 @@ import { UploadHandler } from "./transport/http/upload-handler.js";
14
14
  import { WebSocketHandler } from "./transport/socket/websocket-handler.js";
15
15
  import { JwtManager } from "./auth/jwt-manager.js";
16
16
  import { handleV1Connection } from "./legacy/v1-auto-update-handler.js";
17
- import { AutoUpdateService } from "./services/auto-update-service.js";
17
+ import { createServiceContext } from "./core/define-service.js";
18
18
  import consola from "consola";
19
19
  const logger = consola.withTag("service-server:ServiceServer");
20
20
  class ServiceServer extends EventEmitter {
@@ -91,9 +91,16 @@ class ServiceServer extends EventEmitter {
91
91
  }
92
92
  this._wsHandler.addSocket(socket, clientId, clientName, req);
93
93
  } else {
94
- const autoUpdateService = new AutoUpdateService();
95
- autoUpdateService.server = this;
96
- handleV1Connection(socket, autoUpdateService);
94
+ const autoUpdateDef = this.options.services.find((s) => s.name === "AutoUpdate");
95
+ if (autoUpdateDef == null) {
96
+ socket.close(1008, "AutoUpdate service not configured");
97
+ return;
98
+ }
99
+ const legacyCtx = createServiceContext(this, void 0, void 0, {});
100
+ const autoUpdateMethods = autoUpdateDef.factory(legacyCtx);
101
+ handleV1Connection(socket, autoUpdateMethods, (name) => {
102
+ legacyCtx.legacy = { clientName: name };
103
+ });
97
104
  }
98
105
  };
99
106
  this.fastify.get("/", { websocket: true }, onWebSocketConnected.bind(this));
@@ -127,8 +134,8 @@ class ServiceServer extends EventEmitter {
127
134
  logger.debug("\uC11C\uBC84\uB0B4 \uBAA8\uB4E0 \uD074\uB77C\uC774\uC5B8\uD2B8 RELOAD \uBA85\uB839 \uC804\uC1A1");
128
135
  await this._wsHandler.broadcastReload(clientName, changedFileSet);
129
136
  }
130
- async emitEvent(eventType, infoSelector, data) {
131
- await this._wsHandler.emitToServer(eventType, infoSelector, data);
137
+ async emitEvent(eventDef, infoSelector, data) {
138
+ await this._wsHandler.emitToServer(eventDef, infoSelector, data);
132
139
  }
133
140
  async generateAuthToken(payload) {
134
141
  return this._jwt.sign(payload);
@@ -159,7 +166,11 @@ class ServiceServer extends EventEmitter {
159
166
  process.on("SIGTERM", () => shutdownHandler("SIGTERM"));
160
167
  }
161
168
  }
169
+ function createServiceServer(options) {
170
+ return new ServiceServer(options);
171
+ }
162
172
  export {
163
- ServiceServer
173
+ ServiceServer,
174
+ createServiceServer
164
175
  };
165
176
  //# sourceMappingURL=service-server.js.map