@simplysm/service-server 13.0.99 → 14.0.1

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 (83) hide show
  1. package/dist/auth/auth-token-payload.js +2 -1
  2. package/dist/auth/auth-token-payload.js.map +1 -6
  3. package/dist/auth/jwt-manager.js +21 -21
  4. package/dist/auth/jwt-manager.js.map +1 -6
  5. package/dist/core/define-service.d.ts +12 -12
  6. package/dist/core/define-service.d.ts.map +1 -1
  7. package/dist/core/define-service.js +77 -63
  8. package/dist/core/define-service.js.map +1 -6
  9. package/dist/core/service-executor.d.ts.map +1 -1
  10. package/dist/core/service-executor.js +42 -32
  11. package/dist/core/service-executor.js.map +1 -6
  12. package/dist/index.d.ts +0 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +11 -2
  15. package/dist/index.js.map +1 -6
  16. package/dist/legacy/v1-auto-update-handler.d.ts +2 -2
  17. package/dist/legacy/v1-auto-update-handler.js +42 -35
  18. package/dist/legacy/v1-auto-update-handler.js.map +1 -6
  19. package/dist/protocol/protocol-wrapper.d.ts +9 -9
  20. package/dist/protocol/protocol-wrapper.js +64 -46
  21. package/dist/protocol/protocol-wrapper.js.map +1 -6
  22. package/dist/service-server.d.ts +2 -0
  23. package/dist/service-server.d.ts.map +1 -1
  24. package/dist/service-server.js +187 -165
  25. package/dist/service-server.js.map +1 -6
  26. package/dist/services/auto-update-service.js +35 -34
  27. package/dist/services/auto-update-service.js.map +1 -6
  28. package/dist/services/orm-service.js +114 -120
  29. package/dist/services/orm-service.js.map +1 -6
  30. package/dist/transport/http/http-request-handler.d.ts.map +1 -1
  31. package/dist/transport/http/http-request-handler.js +58 -46
  32. package/dist/transport/http/http-request-handler.js.map +1 -6
  33. package/dist/transport/http/static-file-handler.js +42 -39
  34. package/dist/transport/http/static-file-handler.js.map +1 -6
  35. package/dist/transport/http/upload-handler.d.ts.map +1 -1
  36. package/dist/transport/http/upload-handler.js +60 -55
  37. package/dist/transport/http/upload-handler.js.map +1 -6
  38. package/dist/transport/socket/service-socket.d.ts +13 -13
  39. package/dist/transport/socket/service-socket.js +132 -108
  40. package/dist/transport/socket/service-socket.js.map +1 -6
  41. package/dist/transport/socket/websocket-handler.d.ts +10 -10
  42. package/dist/transport/socket/websocket-handler.d.ts.map +1 -1
  43. package/dist/transport/socket/websocket-handler.js +154 -139
  44. package/dist/transport/socket/websocket-handler.js.map +1 -6
  45. package/dist/types/server-options.d.ts +1 -1
  46. package/dist/types/server-options.d.ts.map +1 -1
  47. package/dist/types/server-options.js +2 -1
  48. package/dist/types/server-options.js.map +1 -6
  49. package/dist/utils/config-manager.js +48 -46
  50. package/dist/utils/config-manager.js.map +1 -6
  51. package/dist/workers/service-protocol.worker.js +8 -11
  52. package/dist/workers/service-protocol.worker.js.map +1 -6
  53. package/package.json +12 -14
  54. package/src/auth/jwt-manager.ts +2 -2
  55. package/src/core/define-service.ts +19 -19
  56. package/src/core/service-executor.ts +23 -17
  57. package/src/index.ts +10 -12
  58. package/src/legacy/v1-auto-update-handler.ts +10 -10
  59. package/src/protocol/protocol-wrapper.ts +16 -16
  60. package/src/service-server.ts +52 -39
  61. package/src/services/auto-update-service.ts +1 -1
  62. package/src/services/orm-service.ts +7 -7
  63. package/src/transport/http/http-request-handler.ts +16 -10
  64. package/src/transport/http/static-file-handler.ts +8 -8
  65. package/src/transport/http/upload-handler.ts +16 -9
  66. package/src/transport/socket/service-socket.ts +22 -22
  67. package/src/transport/socket/websocket-handler.ts +59 -60
  68. package/src/types/server-options.ts +1 -1
  69. package/src/utils/config-manager.ts +11 -11
  70. package/README.md +0 -163
  71. package/dist/services/smtp-client-service.d.ts +0 -8
  72. package/dist/services/smtp-client-service.d.ts.map +0 -1
  73. package/dist/services/smtp-client-service.js +0 -46
  74. package/dist/services/smtp-client-service.js.map +0 -6
  75. package/docs/auth.md +0 -59
  76. package/docs/core.md +0 -133
  77. package/docs/server.md +0 -126
  78. package/docs/services.md +0 -58
  79. package/docs/transport.md +0 -164
  80. package/src/services/smtp-client-service.ts +0 -59
  81. package/tests/define-service.spec.ts +0 -66
  82. package/tests/orm-service.spec.ts +0 -83
  83. package/tests/service-executor.spec.ts +0 -114
@@ -5,12 +5,12 @@ import consola from "consola";
5
5
 
6
6
  const logger = consola.withTag("service-server:ConfigManager");
7
7
 
8
- // Value: Config object, Key: file path
8
+ // 값: 설정 객체, 키: 파일 경로
9
9
  const _cache = new LazyGcMap<string, unknown>({
10
- gcInterval: 10 * 60 * 1000, // Every 10 minutes
11
- expireTime: 60 * 60 * 1000, // Expire after 1 hour
10
+ gcInterval: 10 * 60 * 1000, // 10분마다
11
+ expireTime: 60 * 60 * 1000, // 1시간 만료
12
12
  onExpire: async (filePath) => {
13
- logger.debug(`Config cache expired and watcher released: ${path.basename(filePath)}`);
13
+ logger.debug(`설정 캐시 만료 워처 해제됨: ${path.basename(filePath)}`);
14
14
  await closeWatcher(filePath);
15
15
  },
16
16
  });
@@ -18,18 +18,18 @@ const _cache = new LazyGcMap<string, unknown>({
18
18
  const _watchers = new Map<string, FsWatcher>();
19
19
 
20
20
  export async function getConfig<TConfig>(filePath: string): Promise<TConfig | undefined> {
21
- // 1. Cache hit (time auto-renewed)
21
+ // 1. 캐시 히트 (시간 자동 갱신)
22
22
  if (_cache.has(filePath)) {
23
23
  return _cache.get(filePath) as TConfig;
24
24
  }
25
25
 
26
26
  if (!(await fsx.exists(filePath))) return undefined;
27
27
 
28
- // 2. Load and cache
28
+ // 2. 로드 캐시
29
29
  const config = await fsx.readJson(filePath);
30
30
  _cache.set(filePath, config);
31
31
 
32
- // 3. Register watcher
32
+ // 3. 워처 등록
33
33
  if (!_watchers.has(filePath)) {
34
34
  try {
35
35
  const watcher = await FsWatcher.watch([filePath]);
@@ -39,20 +39,20 @@ export async function getConfig<TConfig>(filePath: string): Promise<TConfig | un
39
39
  if (!(await fsx.exists(filePath))) {
40
40
  _cache.delete(filePath);
41
41
  await closeWatcher(filePath);
42
- logger.debug(`Config file deleted: ${path.basename(filePath)}`);
42
+ logger.debug(`설정 파일 삭제됨: ${path.basename(filePath)}`);
43
43
  return;
44
44
  }
45
45
 
46
46
  try {
47
47
  const newConfig = await fsx.readJson(filePath);
48
48
  _cache.set(filePath, newConfig);
49
- logger.debug(`Config file live-reloaded: ${path.basename(filePath)}`);
49
+ logger.debug(`설정 파일 실시간 리로드됨: ${path.basename(filePath)}`);
50
50
  } catch (err) {
51
- logger.warn(`Config file reload failed: ${filePath}`, err);
51
+ logger.warn(`설정 파일 리로드 실패: ${filePath}`, err);
52
52
  }
53
53
  });
54
54
  } catch (err) {
55
- logger.error(`Watch failed: ${filePath}`, err);
55
+ logger.error(`워치 실패: ${filePath}`, err);
56
56
  }
57
57
  }
58
58
 
package/README.md DELETED
@@ -1,163 +0,0 @@
1
- # @simplysm/service-server
2
-
3
- Simplysm package - service module (server)
4
-
5
- Fastify-based service server with WebSocket support, JWT authentication, and built-in ORM/SMTP/auto-update services. Works with `@simplysm/service-client` for client-server communication.
6
-
7
- ## Installation
8
-
9
- ```bash
10
- npm install @simplysm/service-server
11
- ```
12
-
13
- ## API Overview
14
-
15
- ### Types
16
- | API | Type | Description |
17
- |-----|------|-------------|
18
- | `ServiceServerOptions` | interface | Server config (rootPath, port, ssl, auth, services) |
19
-
20
- -> See [docs/server.md](./docs/server.md) for details.
21
-
22
- ### Auth
23
- | API | Type | Description |
24
- |-----|------|-------------|
25
- | `AuthTokenPayload` | interface | JWT payload with roles and custom data |
26
- | `signJwt` | function | Sign a JWT token (HS256, 12h expiry) |
27
- | `verifyJwt` | function | Verify and decode a JWT token |
28
- | `decodeJwt` | function | Decode JWT without verification |
29
-
30
- -> See [docs/auth.md](./docs/auth.md) for details.
31
-
32
- ### Core
33
- | API | Type | Description |
34
- |-----|------|-------------|
35
- | `ServiceContext` | interface | Context with server, socket, auth, config access |
36
- | `createServiceContext` | function | Create a service context |
37
- | `ServiceDefinition` | interface | Service definition (name, factory, auth) |
38
- | `defineService` | function | Define a service with name and factory |
39
- | `auth` | function | Auth wrapper for services/methods (login/roles) |
40
- | `getServiceAuthPermissions` | function | Read auth permissions from wrapped function |
41
- | `ServiceMethods` | type | Extract method types from ServiceDefinition |
42
- | `executeServiceMethod` | function | Execute service method with auth checks |
43
-
44
- -> See [docs/core.md](./docs/core.md) for details.
45
-
46
- ### Transport - Socket
47
- | API | Type | Description |
48
- |-----|------|-------------|
49
- | `WebSocketHandler` | interface | Multi-connection WebSocket manager |
50
- | `createWebSocketHandler` | function | Create WebSocket handler |
51
- | `ServiceSocket` | interface | Single WebSocket connection manager |
52
- | `createServiceSocket` | function | Create service socket |
53
-
54
- -> See [docs/transport.md](./docs/transport.md) for details.
55
-
56
- ### Transport - HTTP
57
- | API | Type | Description |
58
- |-----|------|-------------|
59
- | `handleHttpRequest` | function | Handle HTTP API requests |
60
- | `handleUpload` | function | Handle file upload (multipart) |
61
- | `handleStaticFile` | function | Serve static files from www/ |
62
-
63
- -> See [docs/transport.md](./docs/transport.md) for details.
64
-
65
- ### Protocol
66
- | API | Type | Description |
67
- |-----|------|-------------|
68
- | `ServerProtocolWrapper` | interface | Server protocol with worker thread offloading |
69
- | `createServerProtocolWrapper` | function | Create server protocol wrapper |
70
-
71
- -> See [docs/transport.md](./docs/transport.md) for details.
72
-
73
- ### Services
74
- | API | Type | Description |
75
- |-----|------|-------------|
76
- | `OrmService` | const | Built-in ORM service (DB connection, queries) |
77
- | `AutoUpdateService` | const | Built-in auto-update service |
78
- | `SmtpClientService` | const | Built-in SMTP email service |
79
-
80
- -> See [docs/services.md](./docs/services.md) for details.
81
-
82
- ### Utils
83
- | API | Type | Description |
84
- |-----|------|-------------|
85
- | `getConfig` | function | Read JSON config with caching and live-reload |
86
-
87
- -> See [docs/server.md](./docs/server.md) for details.
88
-
89
- ### Main
90
- | API | Type | Description |
91
- |-----|------|-------------|
92
- | `ServiceServer` | class | Main server (Fastify, WebSocket, auth, events) |
93
- | `createServiceServer` | function | Factory to create ServiceServer |
94
-
95
- -> See [docs/server.md](./docs/server.md) for details.
96
-
97
- ### Legacy
98
- | API | Type | Description |
99
- |-----|------|-------------|
100
- | `handleV1Connection` | function | V1 legacy client handler (auto-update only) |
101
-
102
- -> See [docs/server.md](./docs/server.md) for details.
103
-
104
- ## Usage Examples
105
-
106
- ### Basic Server Setup
107
-
108
- ```typescript
109
- import { createServiceServer, defineService, auth } from "@simplysm/service-server";
110
- import { OrmService, AutoUpdateService } from "@simplysm/service-server";
111
-
112
- // Define a custom service
113
- const HealthService = defineService("Health", (ctx) => ({
114
- check: () => ({ status: "ok", time: new Date().toISOString() }),
115
- }));
116
-
117
- // Define an authenticated service
118
- const UserService = defineService("User", auth((ctx) => ({
119
- getProfile: () => ctx.authInfo,
120
- adminOnly: auth(["admin"], () => "admin-only data"),
121
- })));
122
-
123
- // Create and start server
124
- const server = createServiceServer({
125
- rootPath: "/app",
126
- port: 3000,
127
- auth: { jwtSecret: "my-secret" },
128
- services: [HealthService, UserService, OrmService, AutoUpdateService],
129
- });
130
-
131
- await server.listen();
132
- ```
133
-
134
- ### JWT Authentication
135
-
136
- ```typescript
137
- import { signJwt, verifyJwt } from "@simplysm/service-server";
138
-
139
- // Sign token (in login handler)
140
- const token = await server.signAuthToken({
141
- roles: ["user", "admin"],
142
- data: { userId: 123, name: "John" },
143
- });
144
-
145
- // Verify token
146
- const payload = await server.verifyAuthToken(token);
147
- console.log(payload.data.name); // "John"
148
- ```
149
-
150
- ### Server-Side Event Emission
151
-
152
- ```typescript
153
- import { defineEvent } from "@simplysm/service-common";
154
-
155
- const OrderUpdated = defineEvent<{ orderId: number }, { status: string }>("OrderUpdated");
156
-
157
- // Emit to all listeners with matching orderId
158
- await server.emitEvent(
159
- OrderUpdated,
160
- (info) => info.orderId === 123,
161
- { status: "shipped" },
162
- );
163
- ```
@@ -1,8 +0,0 @@
1
- import { type ServiceMethods } from "../core/define-service";
2
- import type { SmtpClientSendByDefaultOption, SmtpClientSendOption } from "@simplysm/service-common";
3
- export declare const SmtpClientService: import("..").ServiceDefinition<{
4
- send(options: SmtpClientSendOption): Promise<string>;
5
- sendByConfig(configName: string, options: SmtpClientSendByDefaultOption): Promise<string>;
6
- }>;
7
- export type SmtpClientServiceType = ServiceMethods<typeof SmtpClientService>;
8
- //# sourceMappingURL=smtp-client-service.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"smtp-client-service.d.ts","sourceRoot":"","sources":["..\\..\\src\\services\\smtp-client-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,KAAK,EAEV,6BAA6B,EAC7B,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAElC,eAAO,MAAM,iBAAiB;kBACR,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC;6BA6B3B,MAAM,WAAW,6BAA6B,GAAG,OAAO,CAAC,MAAM,CAAC;EAkB9F,CAAC;AAEJ,MAAM,MAAM,qBAAqB,GAAG,cAAc,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
@@ -1,46 +0,0 @@
1
- import nodemailer from "nodemailer";
2
- import { defineService } from "../core/define-service.js";
3
- const SmtpClientService = defineService("SmtpClient", (ctx) => ({
4
- async send(options) {
5
- return new Promise((resolve, reject) => {
6
- const transport = nodemailer.createTransport({
7
- host: options.host,
8
- port: options.port,
9
- secure: options.secure,
10
- auth: options.user != null ? {
11
- user: options.user,
12
- pass: options.pass
13
- } : void 0,
14
- tls: {
15
- rejectUnauthorized: false
16
- }
17
- });
18
- transport.sendMail(options, (err, info) => {
19
- if (err) {
20
- reject(err);
21
- return;
22
- }
23
- resolve(info.messageId);
24
- });
25
- });
26
- },
27
- async sendByConfig(configName, options) {
28
- const config = (await ctx.getConfig("smtp"))[configName];
29
- if (config == null) {
30
- throw new Error(`SMTP config not found: ${configName}`);
31
- }
32
- return this.send({
33
- user: config.user,
34
- pass: config.pass,
35
- host: config.host,
36
- port: config.port,
37
- secure: config.secure,
38
- from: `"${config.senderName}" <${config.senderEmail ?? config.user}>`,
39
- ...options
40
- });
41
- }
42
- }));
43
- export {
44
- SmtpClientService
45
- };
46
- //# sourceMappingURL=smtp-client-service.js.map
@@ -1,6 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/services/smtp-client-service.ts"],
4
- "mappings": "AAAA,OAAO,gBAAgB;AACvB,SAAS,qBAA0C;AAO5C,MAAM,oBAAoB,cAAc,cAAc,CAAC,SAAS;AAAA,EACrE,MAAM,KAAK,SAAgD;AACzD,WAAO,IAAI,QAAgB,CAAC,SAAS,WAAW;AAC9C,YAAM,YAAY,WAAW,gBAAgB;AAAA,QAC3C,MAAM,QAAQ;AAAA,QACd,MAAM,QAAQ;AAAA,QACd,QAAQ,QAAQ;AAAA,QAChB,MACE,QAAQ,QAAQ,OACZ;AAAA,UACE,MAAM,QAAQ;AAAA,UACd,MAAM,QAAQ;AAAA,QAChB,IACA;AAAA,QACN,KAAK;AAAA,UACH,oBAAoB;AAAA,QACtB;AAAA,MACF,CAAC;AAED,gBAAU,SAAS,SAAuC,CAAC,KAAK,SAAS;AACvE,YAAI,KAAK;AACP,iBAAO,GAAG;AACV;AAAA,QACF;AAEA,gBAAQ,KAAK,SAAS;AAAA,MACxB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,aAAa,YAAoB,SAAyD;AAC9F,UAAM,UACJ,MAAM,IAAI,UAAgE,MAAM,GAChF,UAAU;AACZ,QAAI,UAAU,MAAM;AAClB,YAAM,IAAI,MAAM,0BAA0B,UAAU,EAAE;AAAA,IACxD;AAEA,WAAO,KAAK,KAAK;AAAA,MACf,MAAM,OAAO;AAAA,MACb,MAAM,OAAO;AAAA,MACb,MAAM,OAAO;AAAA,MACb,MAAM,OAAO;AAAA,MACb,QAAQ,OAAO;AAAA,MACf,MAAM,IAAI,OAAO,UAAU,MAAM,OAAO,eAAe,OAAO,IAAI;AAAA,MAClE,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AACF,EAAE;",
5
- "names": []
6
- }
package/docs/auth.md DELETED
@@ -1,59 +0,0 @@
1
- # Auth
2
-
3
- JWT-based authentication utilities using the `jose` library (HS256 algorithm).
4
-
5
- ## `AuthTokenPayload`
6
-
7
- JWT token payload with roles and custom data. Extends `JWTPayload` from `jose`.
8
-
9
- ```typescript
10
- interface AuthTokenPayload<TAuthInfo = unknown> extends JWTPayload {
11
- roles: string[];
12
- data: TAuthInfo;
13
- }
14
- ```
15
-
16
- | Field | Type | Description |
17
- |-------|------|-------------|
18
- | `roles` | `string[]` | User roles for permission checking |
19
- | `data` | `TAuthInfo` | Custom auth data (user info, etc.) |
20
-
21
- ## `signJwt`
22
-
23
- Sign a JWT token with HS256 algorithm. Token expires in 12 hours.
24
-
25
- ```typescript
26
- async function signJwt<TAuthInfo = unknown>(
27
- jwtSecret: string,
28
- payload: AuthTokenPayload<TAuthInfo>,
29
- ): Promise<string>;
30
- ```
31
-
32
- | Parameter | Type | Description |
33
- |-----------|------|-------------|
34
- | `jwtSecret` | `string` | Secret key for signing |
35
- | `payload` | `AuthTokenPayload<TAuthInfo>` | Token payload |
36
-
37
- ## `verifyJwt`
38
-
39
- Verify and decode a JWT token. Throws on expired or invalid tokens.
40
-
41
- ```typescript
42
- async function verifyJwt<TAuthInfo = unknown>(
43
- jwtSecret: string,
44
- token: string,
45
- ): Promise<AuthTokenPayload<TAuthInfo>>;
46
- ```
47
-
48
- | Parameter | Type | Description |
49
- |-----------|------|-------------|
50
- | `jwtSecret` | `string` | Secret key for verification |
51
- | `token` | `string` | JWT token string |
52
-
53
- ## `decodeJwt`
54
-
55
- Decode a JWT token without verification (for reading payload only).
56
-
57
- ```typescript
58
- function decodeJwt<TAuthInfo = unknown>(token: string): AuthTokenPayload<TAuthInfo>;
59
- ```
package/docs/core.md DELETED
@@ -1,133 +0,0 @@
1
- # Core
2
-
3
- ## `ServiceContext`
4
-
5
- Context object passed to service factory functions. Provides access to server, socket, auth info, and configuration.
6
-
7
- ```typescript
8
- interface ServiceContext<TAuthInfo = unknown> {
9
- server: ServiceServer<TAuthInfo>;
10
- socket?: ServiceSocket;
11
- http?: {
12
- clientName: string;
13
- authTokenPayload?: AuthTokenPayload<TAuthInfo>;
14
- };
15
- legacy?: {
16
- clientName?: string;
17
- };
18
-
19
- get authInfo(): TAuthInfo | undefined;
20
- get clientName(): string | undefined;
21
- get clientPath(): string | undefined;
22
- getConfig<T>(section: string): Promise<T>;
23
- }
24
- ```
25
-
26
- | Property | Type | Description |
27
- |----------|------|-------------|
28
- | `server` | `ServiceServer<TAuthInfo>` | Server instance |
29
- | `socket` | `ServiceSocket` | WebSocket connection (if via WebSocket) |
30
- | `http` | `object` | HTTP request info (if via HTTP) |
31
- | `legacy` | `object` | V1 legacy context (auto-update only) |
32
- | `authInfo` | `TAuthInfo \| undefined` | Authenticated user data |
33
- | `clientName` | `string \| undefined` | Client name |
34
- | `clientPath` | `string \| undefined` | Resolved client path on disk |
35
- | `getConfig()` | `<T>(section) => Promise<T>` | Read config from `.config.json` files |
36
-
37
- ## `createServiceContext`
38
-
39
- Create a service context instance.
40
-
41
- ```typescript
42
- function createServiceContext<TAuthInfo = unknown>(
43
- server: ServiceServer<TAuthInfo>,
44
- socket?: ServiceSocket,
45
- http?: { clientName: string; authTokenPayload?: AuthTokenPayload<TAuthInfo> },
46
- legacy?: { clientName?: string },
47
- ): ServiceContext<TAuthInfo>;
48
- ```
49
-
50
- ## `ServiceDefinition`
51
-
52
- Service definition object. Contains name, factory function, and optional auth permissions.
53
-
54
- ```typescript
55
- interface ServiceDefinition<TMethods = Record<string, (...args: any[]) => any>> {
56
- name: string;
57
- factory: (ctx: ServiceContext) => TMethods;
58
- authPermissions?: string[];
59
- }
60
- ```
61
-
62
- | Field | Type | Description |
63
- |-------|------|-------------|
64
- | `name` | `string` | Service name |
65
- | `factory` | `(ctx: ServiceContext) => TMethods` | Factory function that creates method object |
66
- | `authPermissions` | `string[]` | Required permissions (from `auth()` wrapper) |
67
-
68
- ## `defineService`
69
-
70
- Define a service with a name and factory function.
71
-
72
- ```typescript
73
- function defineService<TMethods extends Record<string, (...args: any[]) => any>>(
74
- name: string,
75
- factory: (ctx: ServiceContext) => TMethods,
76
- ): ServiceDefinition<TMethods>;
77
- ```
78
-
79
- | Parameter | Type | Description |
80
- |-----------|------|-------------|
81
- | `name` | `string` | Service name |
82
- | `factory` | `(ctx: ServiceContext) => TMethods` | Factory function |
83
-
84
- ## `auth`
85
-
86
- Auth wrapper for service factories and methods. Can be applied at service-level or method-level with optional role requirements.
87
-
88
- ```typescript
89
- function auth<TFunction extends (...args: any[]) => any>(fn: TFunction): TFunction;
90
- function auth<TFunction extends (...args: any[]) => any>(
91
- permissions: string[],
92
- fn: TFunction,
93
- ): TFunction;
94
- ```
95
-
96
- | Overload | Description |
97
- |----------|-------------|
98
- | `auth(fn)` | Require login (any authenticated user) |
99
- | `auth(["admin"], fn)` | Require specific roles |
100
-
101
- ## `getServiceAuthPermissions`
102
-
103
- Read auth permissions from an `auth()`-wrapped function. Returns `undefined` if not wrapped.
104
-
105
- ```typescript
106
- function getServiceAuthPermissions(fn: Function): string[] | undefined;
107
- ```
108
-
109
- ## `ServiceMethods`
110
-
111
- Extract method signatures from a `ServiceDefinition` for client-side type sharing.
112
-
113
- ```typescript
114
- type ServiceMethods<TDefinition> =
115
- TDefinition extends ServiceDefinition<infer M> ? M : never;
116
- ```
117
-
118
- ## `executeServiceMethod`
119
-
120
- Execute a service method with authentication and authorization checks.
121
-
122
- ```typescript
123
- async function executeServiceMethod(
124
- server: ServiceServer,
125
- def: {
126
- serviceName: string;
127
- methodName: string;
128
- params: unknown[];
129
- socket?: ServiceSocket;
130
- http?: { clientName: string; authTokenPayload?: AuthTokenPayload };
131
- },
132
- ): Promise<unknown>;
133
- ```
package/docs/server.md DELETED
@@ -1,126 +0,0 @@
1
- # Server
2
-
3
- ## `ServiceServerOptions`
4
-
5
- Configuration options for `ServiceServer`.
6
-
7
- ```typescript
8
- interface ServiceServerOptions {
9
- rootPath: string;
10
- port: number;
11
- ssl?: {
12
- pfxBytes: Uint8Array;
13
- passphrase: string;
14
- };
15
- auth?: {
16
- jwtSecret: string;
17
- };
18
- services: ServiceDefinition[];
19
- }
20
- ```
21
-
22
- | Field | Type | Description |
23
- |-------|------|-------------|
24
- | `rootPath` | `string` | Root path for static files, uploads, and config |
25
- | `port` | `number` | Server port |
26
- | `ssl` | `object` | SSL/TLS config (PFX certificate) |
27
- | `ssl.pfxBytes` | `Uint8Array` | PFX certificate bytes |
28
- | `ssl.passphrase` | `string` | Certificate passphrase |
29
- | `auth` | `object` | Authentication config |
30
- | `auth.jwtSecret` | `string` | JWT signing secret |
31
- | `services` | `ServiceDefinition[]` | Service definitions to register |
32
-
33
- ## `ServiceServer`
34
-
35
- Fastify-based service server with WebSocket support, JWT authentication, and built-in services. Extends `EventEmitter`.
36
-
37
- ```typescript
38
- class ServiceServer<TAuthInfo = unknown> extends EventEmitter<{
39
- ready: void;
40
- close: void;
41
- }> {
42
- isOpen: boolean;
43
- readonly fastify: FastifyInstance;
44
- readonly options: ServiceServerOptions;
45
-
46
- constructor(options: ServiceServerOptions);
47
-
48
- listen(): Promise<void>;
49
- close(): Promise<void>;
50
- broadcastReload(clientName: string | undefined, changedFileSet: Set<string>): Promise<void>;
51
- emitEvent<TInfo, TData>(
52
- eventDef: ServiceEventDef<TInfo, TData>,
53
- infoSelector: (item: TInfo) => boolean,
54
- data: TData,
55
- ): Promise<void>;
56
- signAuthToken(payload: AuthTokenPayload<TAuthInfo>): Promise<string>;
57
- verifyAuthToken(token: string): Promise<AuthTokenPayload<TAuthInfo>>;
58
- }
59
- ```
60
-
61
- | Property | Type | Description |
62
- |----------|------|-------------|
63
- | `isOpen` | `boolean` | Whether server is listening |
64
- | `fastify` | `FastifyInstance` | Underlying Fastify instance |
65
- | `options` | `ServiceServerOptions` | Server options |
66
-
67
- | Method | Description |
68
- |--------|-------------|
69
- | `listen()` | Start the server (registers plugins, routes, WebSocket, graceful shutdown) |
70
- | `close()` | Stop the server (close all connections) |
71
- | `broadcastReload()` | Broadcast reload to all connected clients |
72
- | `emitEvent()` | Emit event to matching clients |
73
- | `signAuthToken()` | Sign a JWT token |
74
- | `verifyAuthToken()` | Verify and decode a JWT token |
75
-
76
- ### Registered Routes
77
-
78
- | Route | Method | Description |
79
- |-------|--------|-------------|
80
- | `/api/:service/:method` | GET/POST | HTTP service method endpoint |
81
- | `/upload` | POST | File upload endpoint (multipart) |
82
- | `/ws` | WebSocket | WebSocket service endpoint (Protocol V2) |
83
- | `/` | WebSocket | WebSocket endpoint (V1 legacy + V2) |
84
- | `/*` | GET | Static file serving from `www/` |
85
-
86
- ### Registered Plugins
87
-
88
- - `@fastify/websocket` - WebSocket support
89
- - `@fastify/helmet` - Security headers (CSP, HSTS)
90
- - `@fastify/multipart` - File upload
91
- - `@fastify/static` - Static file serving
92
- - `@fastify/cors` - CORS support
93
-
94
- ## `createServiceServer`
95
-
96
- Factory function to create a `ServiceServer` instance.
97
-
98
- ```typescript
99
- function createServiceServer<TAuthInfo = unknown>(
100
- options: ServiceServerOptions,
101
- ): ServiceServer<TAuthInfo>;
102
- ```
103
-
104
- ## Utils
105
-
106
- ### `getConfig`
107
-
108
- Read JSON configuration from file with caching and live-reload via file watcher. Cache expires after 1 hour.
109
-
110
- ```typescript
111
- async function getConfig<TConfig>(filePath: string): Promise<TConfig | undefined>;
112
- ```
113
-
114
- ## Legacy
115
-
116
- ### `handleV1Connection`
117
-
118
- V1 legacy client handler. Only auto-update is supported; all other requests return an upgrade-required error.
119
-
120
- ```typescript
121
- function handleV1Connection(
122
- socket: WebSocket,
123
- autoUpdateMethods: { getLastVersion: (platform: string) => Promise<any> },
124
- clientNameSetter?: (clientName: string | undefined) => void,
125
- ): void;
126
- ```
package/docs/services.md DELETED
@@ -1,58 +0,0 @@
1
- # Built-in Services
2
-
3
- Pre-defined service definitions ready to use with `ServiceServer`.
4
-
5
- ## `OrmService`
6
-
7
- Server-side ORM service implementation. Requires authentication. Manages database connections per WebSocket socket (using `WeakMap`). Supports MySQL, MSSQL, and PostgreSQL via `@simplysm/orm-node`.
8
-
9
- ```typescript
10
- const OrmService: ServiceDefinition;
11
- ```
12
-
13
- Implements the `OrmService` interface from `@simplysm/service-common`:
14
-
15
- | Method | Description |
16
- |--------|-------------|
17
- | `getInfo()` | Get database dialect and connection info from config |
18
- | `connect()` | Open a new database connection, returns connection ID |
19
- | `close()` | Close a database connection |
20
- | `beginTransaction()` | Begin transaction |
21
- | `commitTransaction()` | Commit transaction |
22
- | `rollbackTransaction()` | Rollback transaction |
23
- | `executeParametrized()` | Execute parameterized SQL |
24
- | `executeDefs()` | Execute QueryDef array (builds SQL via QueryBuilder) |
25
- | `bulkInsert()` | Bulk insert records |
26
-
27
- **Note:** ORM service requires WebSocket connection (cannot be used over HTTP).
28
-
29
- ## `AutoUpdateService`
30
-
31
- Server-side auto-update service implementation. Scans the client's platform-specific `updates/` directory for version files.
32
-
33
- ```typescript
34
- const AutoUpdateService: ServiceDefinition;
35
- ```
36
-
37
- Implements the `AutoUpdateService` interface from `@simplysm/service-common`:
38
-
39
- | Method | Description |
40
- |--------|-------------|
41
- | `getLastVersion(platform)` | Find latest version file for platform (win32, android, etc.) |
42
-
43
- Supported platforms and file extensions:
44
- - `android`: `.apk` files
45
- - Other platforms: `.exe` files
46
-
47
- ## `SmtpClientService`
48
-
49
- Server-side SMTP email sending service. Uses `nodemailer` under the hood.
50
-
51
- ```typescript
52
- const SmtpClientService: ServiceDefinition;
53
- ```
54
-
55
- | Method | Description |
56
- |--------|-------------|
57
- | `send(options)` | Send email with full SMTP options |
58
- | `sendByDefault(options)` | Send email using server's default SMTP config |