@simplysm/service-common 13.0.100 → 14.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +214 -92
- package/dist/define-event.d.ts +7 -7
- package/dist/define-event.d.ts.map +1 -1
- package/dist/define-event.js +21 -10
- package/dist/define-event.js.map +1 -6
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -6
- package/dist/protocol/create-service-protocol.d.ts +20 -20
- package/dist/protocol/create-service-protocol.d.ts.map +1 -1
- package/dist/protocol/create-service-protocol.js +150 -112
- package/dist/protocol/create-service-protocol.js.map +1 -6
- package/dist/protocol/protocol.types.d.ts +18 -26
- package/dist/protocol/protocol.types.d.ts.map +1 -1
- package/dist/protocol/protocol.types.js +16 -15
- package/dist/protocol/protocol.types.js.map +1 -6
- package/dist/service-types/auto-update-service.types.d.ts +5 -5
- package/dist/service-types/auto-update-service.types.js +2 -1
- package/dist/service-types/auto-update-service.types.js.map +1 -6
- package/dist/service-types/orm-service.types.d.ts +7 -5
- package/dist/service-types/orm-service.types.d.ts.map +1 -1
- package/dist/service-types/orm-service.types.js +2 -1
- package/dist/service-types/orm-service.types.js.map +1 -6
- package/dist/types.d.ts +5 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -1
- package/dist/types.js.map +1 -6
- package/package.json +9 -8
- package/src/define-event.ts +7 -7
- package/src/index.ts +4 -6
- package/src/protocol/create-service-protocol.ts +48 -40
- package/src/protocol/protocol.types.ts +35 -46
- package/src/service-types/auto-update-service.types.ts +5 -5
- package/src/service-types/orm-service.types.ts +5 -5
- package/src/types.ts +5 -5
- package/dist/service-types/smtp-client-service.types.d.ts +0 -38
- package/dist/service-types/smtp-client-service.types.d.ts.map +0 -1
- package/dist/service-types/smtp-client-service.types.js +0 -1
- package/dist/service-types/smtp-client-service.types.js.map +0 -6
- package/docs/events.md +0 -51
- package/docs/protocol.md +0 -252
- package/docs/service-types.md +0 -162
- package/src/service-types/smtp-client-service.types.ts +0 -41
- package/tests/define-event.spec.ts +0 -11
- package/tests/protocol/service-protocol.spec.ts +0 -251
package/src/define-event.ts
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* $info
|
|
2
|
+
* defineEvent()로 생성된 이벤트 정의.
|
|
3
|
+
* $info와 $data는 타입 전용 마커임 (런타임에서는 사용되지 않음).
|
|
4
4
|
*/
|
|
5
5
|
export interface ServiceEventDef<TInfo = unknown, TData = unknown> {
|
|
6
6
|
eventName: string;
|
|
7
|
-
/**
|
|
7
|
+
/** 타입 추출 전용 (런타임에서는 사용되지 않음) */
|
|
8
8
|
readonly $info: TInfo;
|
|
9
|
-
/**
|
|
9
|
+
/** 타입 추출 전용 (런타임에서는 사용되지 않음) */
|
|
10
10
|
readonly $data: TData;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* 타입 안전한 info와 data를 가진 서비스 이벤트를 정의한다.
|
|
15
15
|
*
|
|
16
16
|
* @example
|
|
17
17
|
* const OrderUpdated = defineEvent<{ orderId: number }, { status: string }>("OrderUpdated");
|
|
18
18
|
*
|
|
19
|
-
* //
|
|
19
|
+
* // 서버에서 이벤트 발생
|
|
20
20
|
* ctx.socket?.emitEvent(OrderUpdated, { orderId: 123 }, { status: "shipped" });
|
|
21
21
|
*
|
|
22
|
-
* //
|
|
22
|
+
* // 클라이언트에서 구독
|
|
23
23
|
* await client.addEventListener(OrderUpdated, { orderId: 123 }, (data) => {
|
|
24
24
|
* console.log(data.status); // typed
|
|
25
25
|
* });
|
package/src/index.ts
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
//
|
|
1
|
+
// 프로토콜
|
|
2
2
|
export * from "./protocol/protocol.types";
|
|
3
3
|
export * from "./protocol/create-service-protocol";
|
|
4
4
|
|
|
5
|
-
//
|
|
5
|
+
// 서비스 타입
|
|
6
6
|
export * from "./service-types/orm-service.types";
|
|
7
7
|
export * from "./service-types/auto-update-service.types";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
// Types
|
|
8
|
+
// 타입
|
|
11
9
|
export * from "./types";
|
|
12
10
|
|
|
13
|
-
//
|
|
11
|
+
// 정의
|
|
14
12
|
export * from "./define-event";
|
|
@@ -10,56 +10,56 @@ import {
|
|
|
10
10
|
import { PROTOCOL_CONFIG, type ServiceMessage } from "./protocol.types";
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* 서비스 프로토콜 인터페이스
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
* -
|
|
17
|
-
* -
|
|
18
|
-
* -
|
|
19
|
-
* -
|
|
15
|
+
* 바이너리 프로토콜 V2:
|
|
16
|
+
* - 헤더: 28바이트 (UUID 16 + TotalSize 8 + Index 4)
|
|
17
|
+
* - 본문: JSON
|
|
18
|
+
* - 자동 청킹: 3MB 초과 시 300KB 청크로 분할
|
|
19
|
+
* - 최대 메시지 크기: 100MB
|
|
20
20
|
*/
|
|
21
21
|
export interface ServiceProtocol {
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* 메시지를 인코딩한다 (필요 시 자동 분할)
|
|
24
24
|
*/
|
|
25
25
|
encode(uuid: string, message: ServiceMessage): { chunks: Bytes[]; totalSize: number };
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
28
|
+
* 메시지를 디코딩한다 (청크 패킷 자동 재조립)
|
|
29
29
|
*/
|
|
30
30
|
decode<T extends ServiceMessage>(bytes: Bytes): ServiceMessageDecodeResult<T>;
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
33
|
+
* 프로토콜 인스턴스를 해제한다.
|
|
34
34
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
35
|
+
* 내부 청크 누적기의 GC 타이머를 해제하고 메모리를 반환한다.
|
|
36
|
+
* 프로토콜 인스턴스가 더 이상 필요하지 않을 때 반드시 호출해야 한다.
|
|
37
37
|
*/
|
|
38
38
|
dispose(): void;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
|
-
*
|
|
42
|
+
* 메시지 디코딩 결과 타입 (유니언)
|
|
43
43
|
*
|
|
44
|
-
* - `type: "complete"`:
|
|
45
|
-
* - `type: "progress"`:
|
|
44
|
+
* - `type: "complete"`: 모든 청크를 수신하여 메시지 재조립이 완료됨
|
|
45
|
+
* - `type: "progress"`: 청크 메시지 진행 중 (일부 청크만 도착)
|
|
46
46
|
*/
|
|
47
47
|
export type ServiceMessageDecodeResult<TMessage extends ServiceMessage> =
|
|
48
48
|
| { type: "complete"; uuid: string; message: TMessage }
|
|
49
49
|
| { type: "progress"; uuid: string; totalSize: number; completedSize: number };
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
|
-
*
|
|
52
|
+
* 서비스 프로토콜 인코더/디코더를 생성한다
|
|
53
53
|
*
|
|
54
|
-
*
|
|
55
|
-
* -
|
|
56
|
-
* -
|
|
57
|
-
* -
|
|
58
|
-
* -
|
|
54
|
+
* 바이너리 프로토콜 V2:
|
|
55
|
+
* - 헤더: 28바이트 (UUID 16 + TotalSize 8 + Index 4)
|
|
56
|
+
* - 본문: JSON
|
|
57
|
+
* - 자동 청킹: 3MB 초과 시 300KB 청크로 분할
|
|
58
|
+
* - 최대 메시지 크기: 100MB
|
|
59
59
|
*/
|
|
60
60
|
export function createServiceProtocol(): ServiceProtocol {
|
|
61
61
|
// -------------------------------------------------------------------
|
|
62
|
-
//
|
|
62
|
+
// 상태
|
|
63
63
|
// -------------------------------------------------------------------
|
|
64
64
|
|
|
65
65
|
const accumulator = new LazyGcMap<
|
|
@@ -75,17 +75,17 @@ export function createServiceProtocol(): ServiceProtocol {
|
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
// -------------------------------------------------------------------
|
|
78
|
-
//
|
|
78
|
+
// 인코딩 헬퍼
|
|
79
79
|
// -------------------------------------------------------------------
|
|
80
80
|
|
|
81
81
|
/**
|
|
82
|
-
*
|
|
82
|
+
* 메시지 청크를 인코딩한다 (헤더 + 본문)
|
|
83
83
|
*
|
|
84
|
-
*
|
|
84
|
+
* 헤더 구조 (28바이트, Big Endian):
|
|
85
85
|
* ```
|
|
86
86
|
* Offset Size Field
|
|
87
87
|
* ------ ---- -----
|
|
88
|
-
* 0 16 UUID (
|
|
88
|
+
* 0 16 UUID (바이너리)
|
|
89
89
|
* 16 8 TotalSize (uint64)
|
|
90
90
|
* 24 4 Index (uint32)
|
|
91
91
|
* ```
|
|
@@ -110,14 +110,15 @@ export function createServiceProtocol(): ServiceProtocol {
|
|
|
110
110
|
headerBytes.byteOffset,
|
|
111
111
|
headerBytes.byteLength,
|
|
112
112
|
);
|
|
113
|
-
headerView.
|
|
113
|
+
headerView.setUint32(16, 0, false); // 상위 4바이트 = 0 (MAX_TOTAL_SIZE < 2^32)
|
|
114
|
+
headerView.setUint32(20, header.totalSize, false); // 하위 4바이트 = totalSize
|
|
114
115
|
headerView.setUint32(24, header.index, false);
|
|
115
116
|
|
|
116
117
|
return bytesU.concat([headerBytes, ...(bodyBytes ? [bodyBytes] : [])]);
|
|
117
118
|
}
|
|
118
119
|
|
|
119
120
|
// -------------------------------------------------------------------
|
|
120
|
-
//
|
|
121
|
+
// 공개 API
|
|
121
122
|
// -------------------------------------------------------------------
|
|
122
123
|
|
|
123
124
|
return {
|
|
@@ -127,20 +128,20 @@ export function createServiceProtocol(): ServiceProtocol {
|
|
|
127
128
|
|
|
128
129
|
const totalSize = msgBytes.length;
|
|
129
130
|
|
|
130
|
-
//
|
|
131
|
+
// 전체 크기 제한 확인 (우선 수행)
|
|
131
132
|
if (totalSize > PROTOCOL_CONFIG.MAX_TOTAL_SIZE) {
|
|
132
|
-
throw new ArgumentError("
|
|
133
|
+
throw new ArgumentError("메시지 크기가 제한을 초과했습니다.", {
|
|
133
134
|
totalSize,
|
|
134
135
|
maxSize: PROTOCOL_CONFIG.MAX_TOTAL_SIZE,
|
|
135
136
|
});
|
|
136
137
|
}
|
|
137
138
|
|
|
138
|
-
//
|
|
139
|
+
// 충분히 작으면 그대로 반환
|
|
139
140
|
if (totalSize <= PROTOCOL_CONFIG.SPLIT_MESSAGE_SIZE) {
|
|
140
141
|
return { chunks: [encodeChunk({ uuid, totalSize, index: 0 }, msgBytes)], totalSize };
|
|
141
142
|
}
|
|
142
143
|
|
|
143
|
-
//
|
|
144
|
+
// 청크로 분할
|
|
144
145
|
const chunks: Bytes[] = [];
|
|
145
146
|
let offset = 0;
|
|
146
147
|
let index = 0;
|
|
@@ -160,13 +161,13 @@ export function createServiceProtocol(): ServiceProtocol {
|
|
|
160
161
|
|
|
161
162
|
decode<T extends ServiceMessage>(bytes: Bytes): ServiceMessageDecodeResult<T> {
|
|
162
163
|
if (bytes.length < 28) {
|
|
163
|
-
throw new ArgumentError("
|
|
164
|
+
throw new ArgumentError("버퍼 크기가 헤더 크기보다 작습니다.", {
|
|
164
165
|
bufferSize: bytes.length,
|
|
165
166
|
minimumSize: 28,
|
|
166
167
|
});
|
|
167
168
|
}
|
|
168
169
|
|
|
169
|
-
// 1.
|
|
170
|
+
// 1. 헤더 읽기
|
|
170
171
|
|
|
171
172
|
// UUID
|
|
172
173
|
const uuidBytes = bytes.subarray(0, 16);
|
|
@@ -174,12 +175,12 @@ export function createServiceProtocol(): ServiceProtocol {
|
|
|
174
175
|
|
|
175
176
|
// TOTAL_SIZE, INDEX
|
|
176
177
|
const headerView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
177
|
-
const totalSize =
|
|
178
|
+
const totalSize = headerView.getUint32(20, false); // 하위 4바이트만 읽기
|
|
178
179
|
const index = headerView.getUint32(24, false);
|
|
179
180
|
|
|
180
|
-
//
|
|
181
|
+
// 전체 크기 제한 확인 (우선 수행)
|
|
181
182
|
if (totalSize > PROTOCOL_CONFIG.MAX_TOTAL_SIZE) {
|
|
182
|
-
throw new ArgumentError("
|
|
183
|
+
throw new ArgumentError("메시지 크기가 제한을 초과했습니다.", {
|
|
183
184
|
totalSize,
|
|
184
185
|
maxSize: PROTOCOL_CONFIG.MAX_TOTAL_SIZE,
|
|
185
186
|
});
|
|
@@ -193,7 +194,7 @@ export function createServiceProtocol(): ServiceProtocol {
|
|
|
193
194
|
chunks: [],
|
|
194
195
|
}));
|
|
195
196
|
if (accItem.chunks[index] == null) {
|
|
196
|
-
//
|
|
197
|
+
// 중복 패킷 방어
|
|
197
198
|
accItem.chunks[index] = bodyBytes;
|
|
198
199
|
accItem.completedSize += bodyBytes.length;
|
|
199
200
|
}
|
|
@@ -205,15 +206,15 @@ export function createServiceProtocol(): ServiceProtocol {
|
|
|
205
206
|
totalSize: totalSize,
|
|
206
207
|
completedSize: accItem.completedSize,
|
|
207
208
|
};
|
|
208
|
-
} else {
|
|
209
|
-
accumulator.delete(uuid); //
|
|
209
|
+
} else if (accItem.completedSize === accItem.totalSize) {
|
|
210
|
+
accumulator.delete(uuid); // 메모리 해제
|
|
210
211
|
|
|
211
212
|
const resultBytes = bytesU.concat(accItem.chunks.filterExists());
|
|
212
213
|
let messageArr: [string, unknown];
|
|
213
214
|
try {
|
|
214
215
|
messageArr = json.parse<[string, unknown]>(new TextDecoder().decode(resultBytes));
|
|
215
216
|
} catch (err) {
|
|
216
|
-
throw new ArgumentError("
|
|
217
|
+
throw new ArgumentError("메시지 디코딩에 실패했습니다.", { uuid, cause: err });
|
|
217
218
|
}
|
|
218
219
|
return {
|
|
219
220
|
type: "complete",
|
|
@@ -223,6 +224,13 @@ export function createServiceProtocol(): ServiceProtocol {
|
|
|
223
224
|
body: messageArr[1],
|
|
224
225
|
} as T,
|
|
225
226
|
};
|
|
227
|
+
} else {
|
|
228
|
+
accumulator.delete(uuid);
|
|
229
|
+
throw new ArgumentError("프로토콜 무결성 위반: completedSize가 totalSize를 초과했습니다.", {
|
|
230
|
+
uuid,
|
|
231
|
+
completedSize: accItem.completedSize,
|
|
232
|
+
totalSize: accItem.totalSize,
|
|
233
|
+
});
|
|
226
234
|
}
|
|
227
235
|
},
|
|
228
236
|
|
|
@@ -1,27 +1,26 @@
|
|
|
1
1
|
// ----------------------------------------------------------------------
|
|
2
|
-
//
|
|
2
|
+
// 프로토콜 상수
|
|
3
3
|
// ----------------------------------------------------------------------
|
|
4
4
|
|
|
5
|
-
/**
|
|
5
|
+
/** 서비스 프로토콜 설정 */
|
|
6
6
|
export const PROTOCOL_CONFIG = {
|
|
7
|
-
/**
|
|
7
|
+
/** 최대 메시지 크기 (100MB) */
|
|
8
8
|
MAX_TOTAL_SIZE: 100 * 1024 * 1024,
|
|
9
|
-
/**
|
|
9
|
+
/** 청킹 임계값 (3MB) */
|
|
10
10
|
SPLIT_MESSAGE_SIZE: 3 * 1024 * 1024,
|
|
11
|
-
/**
|
|
11
|
+
/** 청크 크기 (300KB) */
|
|
12
12
|
CHUNK_SIZE: 300 * 1024,
|
|
13
|
-
/** GC
|
|
13
|
+
/** GC 주기 (10초) */
|
|
14
14
|
GC_INTERVAL: 10 * 1000,
|
|
15
|
-
/**
|
|
15
|
+
/** 미완성 메시지 만료 시간 (60초) */
|
|
16
16
|
EXPIRE_TIME: 60 * 1000,
|
|
17
17
|
} as const;
|
|
18
18
|
|
|
19
19
|
// ----------------------------------------------------------------------
|
|
20
|
-
//
|
|
20
|
+
// 메시지 타입
|
|
21
21
|
// ----------------------------------------------------------------------
|
|
22
22
|
|
|
23
23
|
export type ServiceMessage =
|
|
24
|
-
| ServiceReloadMessage
|
|
25
24
|
| ServiceRequestMessage
|
|
26
25
|
| ServiceAuthMessage
|
|
27
26
|
| ServiceProgressMessage
|
|
@@ -34,10 +33,9 @@ export type ServiceMessage =
|
|
|
34
33
|
| ServiceEventMessage;
|
|
35
34
|
|
|
36
35
|
export type ServiceServerMessage =
|
|
37
|
-
| ServiceReloadMessage // Notification
|
|
38
36
|
| ServiceResponseMessage
|
|
39
37
|
| ServiceErrorMessage
|
|
40
|
-
| ServiceEventMessage; //
|
|
38
|
+
| ServiceEventMessage; // 알림
|
|
41
39
|
|
|
42
40
|
export type ServiceServerRawMessage = ServiceProgressMessage | ServiceServerMessage;
|
|
43
41
|
|
|
@@ -50,28 +48,19 @@ export type ServiceClientMessage =
|
|
|
50
48
|
| ServiceEmitEventMessage;
|
|
51
49
|
|
|
52
50
|
// ----------------------------------------------------------------------
|
|
53
|
-
//
|
|
51
|
+
// 시스템 (공통)
|
|
54
52
|
// ----------------------------------------------------------------------
|
|
55
53
|
|
|
56
|
-
/**
|
|
57
|
-
export interface ServiceReloadMessage {
|
|
58
|
-
name: "reload";
|
|
59
|
-
body: {
|
|
60
|
-
clientName: string | undefined; // Client name
|
|
61
|
-
changedFileSet: Set<string>; // Changed file list
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** Server: progress notification for received chunked message */
|
|
54
|
+
/** 서버: 수신된 청크 메시지의 진행 상태 알림 */
|
|
66
55
|
export interface ServiceProgressMessage {
|
|
67
56
|
name: "progress";
|
|
68
57
|
body: {
|
|
69
|
-
totalSize: number; //
|
|
70
|
-
completedSize: number; //
|
|
58
|
+
totalSize: number; // 전체 크기 (바이트)
|
|
59
|
+
completedSize: number; // 완료된 크기 (바이트)
|
|
71
60
|
};
|
|
72
61
|
}
|
|
73
62
|
|
|
74
|
-
/**
|
|
63
|
+
/** 서버: 에러 알림 */
|
|
75
64
|
export interface ServiceErrorMessage {
|
|
76
65
|
name: "error";
|
|
77
66
|
body: {
|
|
@@ -84,72 +73,72 @@ export interface ServiceErrorMessage {
|
|
|
84
73
|
};
|
|
85
74
|
}
|
|
86
75
|
|
|
87
|
-
/**
|
|
76
|
+
/** 클라이언트: 인증 메시지 */
|
|
88
77
|
export interface ServiceAuthMessage {
|
|
89
78
|
name: "auth";
|
|
90
|
-
body: string; //
|
|
79
|
+
body: string; // 토큰
|
|
91
80
|
}
|
|
92
81
|
|
|
93
82
|
// ----------------------------------------------------------------------
|
|
94
83
|
// Service.Method
|
|
95
84
|
// ----------------------------------------------------------------------
|
|
96
85
|
|
|
97
|
-
/**
|
|
86
|
+
/** 클라이언트: 서비스 메서드 요청 */
|
|
98
87
|
export interface ServiceRequestMessage {
|
|
99
88
|
name: `${string}.${string}`; // ${service}.${method}
|
|
100
|
-
body: unknown[]; //
|
|
89
|
+
body: unknown[]; // 매개변수
|
|
101
90
|
}
|
|
102
91
|
|
|
103
|
-
/**
|
|
92
|
+
/** 서버: 서비스 메서드 응답 */
|
|
104
93
|
export interface ServiceResponseMessage {
|
|
105
94
|
name: "response";
|
|
106
|
-
body?: unknown; //
|
|
95
|
+
body?: unknown; // 결과
|
|
107
96
|
}
|
|
108
97
|
|
|
109
98
|
// ----------------------------------------------------------------------
|
|
110
|
-
//
|
|
99
|
+
// 이벤트
|
|
111
100
|
// ----------------------------------------------------------------------
|
|
112
101
|
|
|
113
|
-
/**
|
|
102
|
+
/** 클라이언트: 이벤트 리스너 추가 */
|
|
114
103
|
export interface ServiceAddEventListenerMessage {
|
|
115
104
|
name: "evt:add";
|
|
116
105
|
body: {
|
|
117
|
-
key: string; //
|
|
118
|
-
name: string; //
|
|
119
|
-
info: unknown; //
|
|
106
|
+
key: string; // 리스너 키 (uuid) - removeEventListener에 필요
|
|
107
|
+
name: string; // 이벤트 이름 (Type.name)
|
|
108
|
+
info: unknown; // 이벤트 발생 시 필터링을 위한 추가 리스너 정보
|
|
120
109
|
};
|
|
121
110
|
}
|
|
122
111
|
|
|
123
|
-
/**
|
|
112
|
+
/** 클라이언트: 이벤트 리스너 제거 */
|
|
124
113
|
export interface ServiceRemoveEventListenerMessage {
|
|
125
114
|
name: "evt:remove";
|
|
126
115
|
body: {
|
|
127
|
-
key: string; //
|
|
116
|
+
key: string; // 리스너 키 (uuid)
|
|
128
117
|
};
|
|
129
118
|
}
|
|
130
119
|
|
|
131
|
-
/**
|
|
120
|
+
/** 클라이언트: 이벤트 리스너 정보 목록 요청 */
|
|
132
121
|
export interface ServiceGetEventListenerInfosMessage {
|
|
133
122
|
name: "evt:gets";
|
|
134
123
|
body: {
|
|
135
|
-
name: string; //
|
|
124
|
+
name: string; // 이벤트 이름
|
|
136
125
|
};
|
|
137
126
|
}
|
|
138
127
|
|
|
139
|
-
/**
|
|
128
|
+
/** 클라이언트: 이벤트 발생 */
|
|
140
129
|
export interface ServiceEmitEventMessage {
|
|
141
130
|
name: "evt:emit";
|
|
142
131
|
body: {
|
|
143
|
-
keys: string[]; //
|
|
144
|
-
data: unknown; //
|
|
132
|
+
keys: string[]; // 리스너 키 목록
|
|
133
|
+
data: unknown; // 데이터
|
|
145
134
|
};
|
|
146
135
|
}
|
|
147
136
|
|
|
148
|
-
/**
|
|
137
|
+
/** 서버: 이벤트 알림 */
|
|
149
138
|
export interface ServiceEventMessage {
|
|
150
139
|
name: "evt:on";
|
|
151
140
|
body: {
|
|
152
|
-
keys: string[]; //
|
|
153
|
-
data: unknown; //
|
|
141
|
+
keys: string[]; // 리스너 키 목록
|
|
142
|
+
data: unknown; // 데이터
|
|
154
143
|
};
|
|
155
144
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* 자동 업데이트 서비스 인터페이스
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* 클라이언트 애플리케이션의 최신 버전 정보를 조회한다.
|
|
5
5
|
*/
|
|
6
6
|
export interface AutoUpdateService {
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
* @param platform
|
|
10
|
-
* @returns
|
|
8
|
+
* 지정된 플랫폼의 최신 버전 정보를 조회한다.
|
|
9
|
+
* @param platform 대상 플랫폼 (예: "win32", "darwin", "linux")
|
|
10
|
+
* @returns 최신 버전 정보, 버전이 없으면 undefined
|
|
11
11
|
*/
|
|
12
12
|
getLastVersion(platform: string): Promise<
|
|
13
13
|
| {
|
|
@@ -7,10 +7,10 @@ import type {
|
|
|
7
7
|
} from "@simplysm/orm-common";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* ORM
|
|
10
|
+
* ORM 서비스 인터페이스
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* 데이터베이스 연결, 트랜잭션 관리, 쿼리 실행을 제공한다.
|
|
13
|
+
* MySQL, MSSQL, PostgreSQL을 지원한다.
|
|
14
14
|
*/
|
|
15
15
|
export interface OrmService {
|
|
16
16
|
getInfo(opt: DbConnOptions & { configName: string }): Promise<{
|
|
@@ -19,7 +19,7 @@ export interface OrmService {
|
|
|
19
19
|
schema?: string;
|
|
20
20
|
}>;
|
|
21
21
|
|
|
22
|
-
connect(opt:
|
|
22
|
+
connect(opt: DbConnOptions & { configName: string }): Promise<number>;
|
|
23
23
|
|
|
24
24
|
close(connId: number): Promise<void>;
|
|
25
25
|
|
|
@@ -45,5 +45,5 @@ export interface OrmService {
|
|
|
45
45
|
): Promise<void>;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
/**
|
|
48
|
+
/** 데이터베이스 연결 옵션 */
|
|
49
49
|
export type DbConnOptions = { configName?: string; config?: Record<string, unknown> };
|
package/src/types.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* 파일 업로드 결과
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* 서버에 업로드된 파일의 정보를 포함한다.
|
|
5
5
|
*/
|
|
6
6
|
export interface ServiceUploadResult {
|
|
7
|
-
/**
|
|
7
|
+
/** 서버 내 저장 경로 */
|
|
8
8
|
path: string;
|
|
9
|
-
/**
|
|
9
|
+
/** 원본 파일명 */
|
|
10
10
|
filename: string;
|
|
11
|
-
/**
|
|
11
|
+
/** 파일 크기 (바이트) */
|
|
12
12
|
size: number;
|
|
13
13
|
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
export interface SmtpClientSendAttachment {
|
|
2
|
-
filename: string;
|
|
3
|
-
content?: string | Uint8Array;
|
|
4
|
-
path?: any;
|
|
5
|
-
contentType?: string;
|
|
6
|
-
}
|
|
7
|
-
export interface SmtpClientSendByDefaultOption {
|
|
8
|
-
to: string;
|
|
9
|
-
cc?: string;
|
|
10
|
-
bcc?: string;
|
|
11
|
-
subject: string;
|
|
12
|
-
html: string;
|
|
13
|
-
attachments?: SmtpClientSendAttachment[];
|
|
14
|
-
}
|
|
15
|
-
export interface SmtpClientSendOption {
|
|
16
|
-
host: string;
|
|
17
|
-
port?: number;
|
|
18
|
-
secure?: boolean;
|
|
19
|
-
user?: string;
|
|
20
|
-
pass?: string;
|
|
21
|
-
from: string;
|
|
22
|
-
to: string;
|
|
23
|
-
cc?: string;
|
|
24
|
-
bcc?: string;
|
|
25
|
-
subject: string;
|
|
26
|
-
html: string;
|
|
27
|
-
attachments?: SmtpClientSendAttachment[];
|
|
28
|
-
}
|
|
29
|
-
export interface SmtpClientDefaultOptions {
|
|
30
|
-
senderName: string;
|
|
31
|
-
senderEmail?: string;
|
|
32
|
-
user?: string;
|
|
33
|
-
pass?: string;
|
|
34
|
-
host: string;
|
|
35
|
-
port?: number;
|
|
36
|
-
secure?: boolean;
|
|
37
|
-
}
|
|
38
|
-
//# sourceMappingURL=smtp-client-service.types.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"smtp-client-service.types.d.ts","sourceRoot":"","sources":["..\\..\\src\\service-types\\smtp-client-service.types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAC9B,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,6BAA6B;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAC1C;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAC1C;AAED,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=smtp-client-service.types.js.map
|
package/docs/events.md
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# Event Definition
|
|
2
|
-
|
|
3
|
-
## `ServiceEventDef`
|
|
4
|
-
|
|
5
|
-
Event definition created by `defineEvent()`. `$info` and `$data` are type-only markers (not used at runtime).
|
|
6
|
-
|
|
7
|
-
```typescript
|
|
8
|
-
interface ServiceEventDef<TInfo = unknown, TData = unknown> {
|
|
9
|
-
eventName: string;
|
|
10
|
-
readonly $info: TInfo;
|
|
11
|
-
readonly $data: TData;
|
|
12
|
-
}
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
| Field | Type | Description |
|
|
16
|
-
|-------|------|-------------|
|
|
17
|
-
| `eventName` | `string` | Event name |
|
|
18
|
-
| `$info` | `TInfo` | Type extraction only (listener filter info type) |
|
|
19
|
-
| `$data` | `TData` | Type extraction only (event data type) |
|
|
20
|
-
|
|
21
|
-
## `defineEvent`
|
|
22
|
-
|
|
23
|
-
Define a service event with type-safe info and data.
|
|
24
|
-
|
|
25
|
-
```typescript
|
|
26
|
-
function defineEvent<TInfo = unknown, TData = unknown>(
|
|
27
|
-
eventName: string,
|
|
28
|
-
): ServiceEventDef<TInfo, TData>;
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
| Parameter | Type | Description |
|
|
32
|
-
|-----------|------|-------------|
|
|
33
|
-
| `eventName` | `string` | Event name |
|
|
34
|
-
|
|
35
|
-
## `ServiceUploadResult`
|
|
36
|
-
|
|
37
|
-
File upload result. Contains information about a file uploaded to the server.
|
|
38
|
-
|
|
39
|
-
```typescript
|
|
40
|
-
interface ServiceUploadResult {
|
|
41
|
-
path: string;
|
|
42
|
-
filename: string;
|
|
43
|
-
size: number;
|
|
44
|
-
}
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
| Field | Type | Description |
|
|
48
|
-
|-------|------|-------------|
|
|
49
|
-
| `path` | `string` | Storage path on the server |
|
|
50
|
-
| `filename` | `string` | Original filename |
|
|
51
|
-
| `size` | `number` | File size (bytes) |
|