@simplysm/sd-claude 14.0.47 → 14.0.49
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/{claude/references/sd-simplysm14/sd-claude/usage.md → README.md} +2 -2
- package/claude/rules/sd-claude-rules.md +25 -10
- package/claude/rules/sd-options.md +11 -6
- package/claude/sd-subagent-start.sh +6 -0
- package/claude/settings.json +1 -12
- package/claude/skills/sd-check/SKILL.md +43 -12
- package/claude/skills/sd-claude-docs/SKILL.md +30 -58
- package/claude/skills/sd-claude-docs/references/package-claudemd.md +12 -0
- package/claude/skills/sd-claude-docs/references/package-doc-gen.md +26 -13
- package/claude/skills/sd-commit/SKILL.md +1 -1
- package/claude/skills/sd-debug/SKILL.md +5 -3
- package/claude/skills/sd-deliverable/SKILL.md +1 -1
- package/claude/skills/sd-dev/SKILL.md +14 -9
- package/claude/skills/sd-doc-extract/SKILL.md +8 -10
- package/claude/skills/sd-doc-extract/_common.py +8 -1
- package/claude/skills/sd-doc-extract/_extract_docx.py +74 -34
- package/claude/skills/sd-doc-extract/_extract_pdf.py +12 -1
- package/claude/skills/sd-doc-extract/_extract_pptx.py +103 -23
- package/claude/skills/sd-doc-extract/_extract_xlsb.py +93 -4
- package/claude/skills/sd-doc-extract/_extract_xlsx.py +98 -36
- package/claude/skills/sd-doc-extract/extract.py +22 -3
- package/claude/skills/sd-inner-clarify/SKILL.md +78 -0
- package/claude/skills/sd-inner-debug/SKILL.md +1 -1
- package/claude/skills/sd-inner-review/SKILL.md +13 -0
- package/claude/skills/sd-issue/SKILL.md +1 -1
- package/claude/skills/sd-outlook/SKILL.md +1 -1
- package/claude/skills/sd-plan/SKILL.md +50 -17
- package/claude/skills/sd-prompt/SKILL.md +180 -178
- package/claude/skills/sd-prompt/references/eval-runner.md +5 -30
- package/claude/skills/sd-prompt/references/sd-eval-env-template.md +23 -0
- package/claude/skills/sd-refactor/SKILL.md +2 -2
- package/claude/skills/sd-tdd/SKILL.md +45 -16
- package/claude/skills/sd-use/SKILL.md +84 -80
- package/claude/skills/sd-wbs/SKILL.md +84 -27
- package/{claude/references/sd-simplysm14/sd-claude/docs → docs}/assets.md +2 -3
- package/{claude/references/sd-simplysm14/sd-claude/docs → docs}/hooks.md +7 -6
- package/{claude/references/sd-simplysm14/sd-claude/docs → docs}/scripts.md +1 -9
- package/package.json +3 -2
- package/scripts/sync.mjs +4 -2
- package/claude/references/sd-simplysm14/angular/docs/bootstrap.md +0 -48
- package/claude/references/sd-simplysm14/angular/docs/directives.md +0 -236
- package/claude/references/sd-simplysm14/angular/docs/features.md +0 -379
- package/claude/references/sd-simplysm14/angular/docs/pipes.md +0 -32
- package/claude/references/sd-simplysm14/angular/docs/plugins.md +0 -37
- package/claude/references/sd-simplysm14/angular/docs/provider-types.md +0 -283
- package/claude/references/sd-simplysm14/angular/docs/providers.md +0 -379
- package/claude/references/sd-simplysm14/angular/docs/styling.md +0 -222
- package/claude/references/sd-simplysm14/angular/docs/type-utilities.md +0 -250
- package/claude/references/sd-simplysm14/angular/docs/ui-data.md +0 -275
- package/claude/references/sd-simplysm14/angular/docs/ui-form.md +0 -490
- package/claude/references/sd-simplysm14/angular/docs/ui-layout.md +0 -140
- package/claude/references/sd-simplysm14/angular/docs/ui-navigation.md +0 -273
- package/claude/references/sd-simplysm14/angular/docs/ui-overlay.md +0 -157
- package/claude/references/sd-simplysm14/angular/docs/ui-visual.md +0 -127
- package/claude/references/sd-simplysm14/angular/docs/utils.md +0 -295
- package/claude/references/sd-simplysm14/angular/usage.md +0 -489
- package/claude/references/sd-simplysm14/capacitor-plugin-auto-update/usage.md +0 -182
- package/claude/references/sd-simplysm14/capacitor-plugin-file-system/docs/file-operations.md +0 -154
- package/claude/references/sd-simplysm14/capacitor-plugin-file-system/docs/permissions.md +0 -84
- package/claude/references/sd-simplysm14/capacitor-plugin-file-system/docs/storage-paths.md +0 -107
- package/claude/references/sd-simplysm14/capacitor-plugin-file-system/docs/types.md +0 -83
- package/claude/references/sd-simplysm14/capacitor-plugin-file-system/usage.md +0 -133
- package/claude/references/sd-simplysm14/capacitor-plugin-intent/usage.md +0 -203
- package/claude/references/sd-simplysm14/capacitor-plugin-usb-storage/usage.md +0 -258
- package/claude/references/sd-simplysm14/core-browser/usage.md +0 -306
- package/claude/references/sd-simplysm14/core-common/docs/errors.md +0 -82
- package/claude/references/sd-simplysm14/core-common/docs/extensions.md +0 -167
- package/claude/references/sd-simplysm14/core-common/docs/features.md +0 -136
- package/claude/references/sd-simplysm14/core-common/docs/types.md +0 -245
- package/claude/references/sd-simplysm14/core-common/docs/utils.md +0 -591
- package/claude/references/sd-simplysm14/core-common/usage.md +0 -255
- package/claude/references/sd-simplysm14/core-node/docs/child-process.md +0 -182
- package/claude/references/sd-simplysm14/core-node/docs/features.md +0 -214
- package/claude/references/sd-simplysm14/core-node/docs/file-system.md +0 -509
- package/claude/references/sd-simplysm14/core-node/docs/file-watching.md +0 -139
- package/claude/references/sd-simplysm14/core-node/docs/logging.md +0 -180
- package/claude/references/sd-simplysm14/core-node/docs/path.md +0 -176
- package/claude/references/sd-simplysm14/core-node/docs/utilities-cpx.md +0 -194
- package/claude/references/sd-simplysm14/core-node/docs/utilities-fsx.md +0 -469
- package/claude/references/sd-simplysm14/core-node/docs/utilities-pathx.md +0 -151
- package/claude/references/sd-simplysm14/core-node/docs/worker-threads.md +0 -334
- package/claude/references/sd-simplysm14/core-node/docs/worker.md +0 -205
- package/claude/references/sd-simplysm14/core-node/usage.md +0 -259
- package/claude/references/sd-simplysm14/excel/docs/core-classes.md +0 -453
- package/claude/references/sd-simplysm14/excel/docs/types.md +0 -459
- package/claude/references/sd-simplysm14/excel/docs/utilities.md +0 -194
- package/claude/references/sd-simplysm14/excel/docs/wrapper.md +0 -73
- package/claude/references/sd-simplysm14/excel/usage.md +0 -134
- package/claude/references/sd-simplysm14/lint/usage.md +0 -130
- package/claude/references/sd-simplysm14/orm-common/docs/core.md +0 -188
- package/claude/references/sd-simplysm14/orm-common/docs/expression.md +0 -190
- package/claude/references/sd-simplysm14/orm-common/docs/models.md +0 -17
- package/claude/references/sd-simplysm14/orm-common/docs/query-builder.md +0 -97
- package/claude/references/sd-simplysm14/orm-common/docs/queryable-executable.md +0 -250
- package/claude/references/sd-simplysm14/orm-common/docs/schema-builders.md +0 -364
- package/claude/references/sd-simplysm14/orm-common/docs/types.md +0 -522
- package/claude/references/sd-simplysm14/orm-common/usage.md +0 -229
- package/claude/references/sd-simplysm14/orm-node/docs/connections.md +0 -137
- package/claude/references/sd-simplysm14/orm-node/docs/core.md +0 -131
- package/claude/references/sd-simplysm14/orm-node/docs/types.md +0 -173
- package/claude/references/sd-simplysm14/orm-node/usage.md +0 -143
- package/claude/references/sd-simplysm14/sd-cli/usage.md +0 -782
- package/claude/references/sd-simplysm14/service-client/docs/features.md +0 -217
- package/claude/references/sd-simplysm14/service-client/docs/main.md +0 -148
- package/claude/references/sd-simplysm14/service-client/docs/protocol.md +0 -53
- package/claude/references/sd-simplysm14/service-client/docs/transport.md +0 -131
- package/claude/references/sd-simplysm14/service-client/docs/types.md +0 -129
- package/claude/references/sd-simplysm14/service-client/usage.md +0 -202
- package/claude/references/sd-simplysm14/service-common/docs/app-structure.md +0 -175
- package/claude/references/sd-simplysm14/service-common/docs/events.md +0 -64
- package/claude/references/sd-simplysm14/service-common/docs/protocol.md +0 -331
- package/claude/references/sd-simplysm14/service-common/docs/service-types.md +0 -90
- package/claude/references/sd-simplysm14/service-common/docs/types.md +0 -19
- package/claude/references/sd-simplysm14/service-common/usage.md +0 -154
- package/claude/references/sd-simplysm14/service-server/docs/auth.md +0 -64
- package/claude/references/sd-simplysm14/service-server/docs/core.md +0 -174
- package/claude/references/sd-simplysm14/service-server/docs/legacy.md +0 -25
- package/claude/references/sd-simplysm14/service-server/docs/main.md +0 -88
- package/claude/references/sd-simplysm14/service-server/docs/protocol.md +0 -33
- package/claude/references/sd-simplysm14/service-server/docs/services.md +0 -94
- package/claude/references/sd-simplysm14/service-server/docs/transport-http.md +0 -93
- package/claude/references/sd-simplysm14/service-server/docs/transport-socket.md +0 -119
- package/claude/references/sd-simplysm14/service-server/docs/types.md +0 -36
- package/claude/references/sd-simplysm14/service-server/docs/utils.md +0 -22
- package/claude/references/sd-simplysm14/service-server/usage.md +0 -171
- package/claude/references/sd-simplysm14/storage/usage.md +0 -301
- package/claude/references/sd-simplysm14.md +0 -35
- package/claude/rules/sd-clarify.md +0 -23
- package/claude/sd-session-start.sh +0 -10
- /package/{claude/references/sd-simplysm14/sd-claude/docs → docs}/cli.md +0 -0
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
# @simplysm/service-client
|
|
2
|
-
|
|
3
|
-
WebSocket 기반 서비스 서버 클라이언트로, 서비스 호출, 실시간 이벤트 구독/발행, 파일 업로드/다운로드, ORM 원격 실행을 지원한다.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install @simplysm/service-client
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## API Overview
|
|
12
|
-
|
|
13
|
-
### Core Client
|
|
14
|
-
|
|
15
|
-
| API | Type | Description |
|
|
16
|
-
|-----|------|-------------|
|
|
17
|
-
| `ServiceClient` | class | WebSocket 서비스 클라이언트 최상위 파사드 (연결, RPC, 이벤트, 파일, ORM 통합) |
|
|
18
|
-
| `createServiceClient()` | function | ServiceClient 인스턴스 생성 팩토리 함수 |
|
|
19
|
-
| `ServiceProxy<T>` | type | 서비스 메서드 반환 타입을 Promise로 래핑하는 타입 변환기 |
|
|
20
|
-
|
|
21
|
-
→ See [docs/main.md](./docs/main.md) for details.
|
|
22
|
-
|
|
23
|
-
### Transport Layer
|
|
24
|
-
|
|
25
|
-
| API | Type | Description |
|
|
26
|
-
|-----|------|-------------|
|
|
27
|
-
| `SocketProvider` | interface | WebSocket 래퍼 인터페이스 (connect, close, send, on, off, heartbeat) |
|
|
28
|
-
| `createSocketProvider()` | function | SocketProvider 팩토리. 재연결 및 하트비트 관리 |
|
|
29
|
-
| `SocketProviderEvents` | interface | SocketProvider 이벤트 맵 (message, state) |
|
|
30
|
-
| `ServiceTransport` | interface | 요청-응답 매핑, progress 중계, 이벤트 디스패치 |
|
|
31
|
-
| `createServiceTransport()` | function | ServiceTransport 팩토리. SocketProvider와 ClientProtocolWrapper 조합 |
|
|
32
|
-
| `ServiceTransportEvents` | interface | ServiceTransport 이벤트 맵 (event) |
|
|
33
|
-
|
|
34
|
-
→ See [docs/transport.md](./docs/transport.md) for details.
|
|
35
|
-
|
|
36
|
-
### Protocol & Encoding
|
|
37
|
-
|
|
38
|
-
| API | Type | Description |
|
|
39
|
-
|-----|------|-------------|
|
|
40
|
-
| `ClientProtocolWrapper` | interface | 메시지 인코딩/디코딩 (30KB 이상 시 Web Worker 오프로드) |
|
|
41
|
-
| `createClientProtocolWrapper()` | function | ClientProtocolWrapper 팩토리. ServiceProtocol 래핑 |
|
|
42
|
-
|
|
43
|
-
→ See [docs/protocol.md](./docs/protocol.md) for details.
|
|
44
|
-
|
|
45
|
-
### Event Management
|
|
46
|
-
|
|
47
|
-
| API | Type | Description |
|
|
48
|
-
|-----|------|-------------|
|
|
49
|
-
| `EventClient` | interface | 서버 이벤트 구독/발행 관리 (재연결 시 자동 재구독) |
|
|
50
|
-
| `createEventClient()` | function | EventClient 팩토리. ServiceTransport 사용 |
|
|
51
|
-
| `ClientEventProxy<T>` | interface | 특정 이벤트에 대한 프록시 인터페이스 |
|
|
52
|
-
|
|
53
|
-
→ See [docs/features.md](./docs/features.md) for details.
|
|
54
|
-
|
|
55
|
-
### File Operations
|
|
56
|
-
|
|
57
|
-
| API | Type | Description |
|
|
58
|
-
|-----|------|-------------|
|
|
59
|
-
| `FileClient` | interface | 파일 업로드(POST)/다운로드(GET) 인터페이스 |
|
|
60
|
-
| `createFileClient()` | function | FileClient 팩토리. hostUrl과 clientName으로 생성 |
|
|
61
|
-
|
|
62
|
-
### ORM Remote Execution
|
|
63
|
-
|
|
64
|
-
| API | Type | Description |
|
|
65
|
-
|-----|------|-------------|
|
|
66
|
-
| `OrmClientConnector` | interface | DbContext 원격 트랜잭션 연결 헬퍼 |
|
|
67
|
-
| `createOrmClientConnector()` | function | OrmClientConnector 팩토리. ServiceClient 사용 |
|
|
68
|
-
| `OrmConnectOptions<T>` | interface | ORM 연결 설정 (DbClass, connOpt, dbContextOpt) |
|
|
69
|
-
| `OrmClientDbContextExecutor` | class | DbContextExecutor 구현체 (서버로 원격 호출) |
|
|
70
|
-
|
|
71
|
-
### Types & Utilities
|
|
72
|
-
|
|
73
|
-
| API | Type | Description |
|
|
74
|
-
|-----|------|-------------|
|
|
75
|
-
| `ServiceConnectionOptions` | interface | 서버 연결 옵션 (host, port, ssl, maxReconnectCount) |
|
|
76
|
-
| `ServiceProgress` | interface | progress 콜백 인터페이스 (request, response, server) |
|
|
77
|
-
| `ServiceProgressState` | interface | progress 상태 (uuid, totalSize, completedSize) |
|
|
78
|
-
| `BlobInput` | type | Blob \| Uint8Array \| ArrayBuffer \| string (Blob 생성자 허용 타입) |
|
|
79
|
-
| `FileCollection` | interface | FileList 호환 컬렉션 인터페이스 |
|
|
80
|
-
| `WorkerLike` | interface | Web Worker 호환 인터페이스 |
|
|
81
|
-
| `isWorkerSupported()` | function | Web Worker 지원 여부 확인 |
|
|
82
|
-
| `createBrowserWorker()` | function | Web Worker 인스턴스 생성 (미지원 환경이면 undefined) |
|
|
83
|
-
|
|
84
|
-
→ See [docs/types.md](./docs/types.md) for details.
|
|
85
|
-
|
|
86
|
-
## Usage Examples
|
|
87
|
-
|
|
88
|
-
### Basic Service Connection & RPC
|
|
89
|
-
|
|
90
|
-
```typescript
|
|
91
|
-
import { createServiceClient } from "@simplysm/service-client";
|
|
92
|
-
|
|
93
|
-
const client = createServiceClient("my-app", {
|
|
94
|
-
host: "localhost",
|
|
95
|
-
port: 3000,
|
|
96
|
-
ssl: false,
|
|
97
|
-
maxReconnectCount: 10, // 자동 재연결 (0으로 비활성화)
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
await client.connect();
|
|
101
|
-
await client.auth("jwt-token");
|
|
102
|
-
|
|
103
|
-
// 타입 안전한 서비스 프록시
|
|
104
|
-
const userSvc = client.getService<UserService>("User");
|
|
105
|
-
const users = await userSvc.getAll();
|
|
106
|
-
|
|
107
|
-
await client.close();
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### Event Subscription
|
|
111
|
-
|
|
112
|
-
```typescript
|
|
113
|
-
// 이벤트 리스너 등록 (selector로 필터링)
|
|
114
|
-
const listenerId = await client.addListener(
|
|
115
|
-
"user:created",
|
|
116
|
-
{ userId: 123 }, // info selector (서버와 공유되는 필터 정보)
|
|
117
|
-
async (data) => {
|
|
118
|
-
console.log("새 사용자:", data.name);
|
|
119
|
-
},
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
// 이벤트 발행 (특정 selector에 매칭하는 리스너에만 전송)
|
|
123
|
-
await client.emitEvent(
|
|
124
|
-
"user:created",
|
|
125
|
-
(info) => info.userId === 123,
|
|
126
|
-
{ name: "Alice", email: "alice@example.com" },
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
// 리스너 제거
|
|
130
|
-
await client.removeListener(listenerId);
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### File Upload & Download
|
|
134
|
-
|
|
135
|
-
```typescript
|
|
136
|
-
// 파일 업로드 (인증 필수)
|
|
137
|
-
const files = [
|
|
138
|
-
new File(["content"], "file.txt", { type: "text/plain" }),
|
|
139
|
-
];
|
|
140
|
-
const results = await client.uploadFile(files);
|
|
141
|
-
console.log("업로드 결과:", results);
|
|
142
|
-
|
|
143
|
-
// 파일 다운로드
|
|
144
|
-
const buffer = await client.downloadFileBuffer("/uploaded/file.txt");
|
|
145
|
-
console.log("다운로드 바이트:", buffer.length);
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### ORM Remote Execution
|
|
149
|
-
|
|
150
|
-
```typescript
|
|
151
|
-
import { createOrmClientConnector } from "@simplysm/service-client";
|
|
152
|
-
|
|
153
|
-
const connector = createOrmClientConnector(client);
|
|
154
|
-
|
|
155
|
-
const result = await connector.connect(
|
|
156
|
-
{
|
|
157
|
-
DbClass: MyDbContext,
|
|
158
|
-
connOpt: { configName: "main", username: "user", password: "pass" },
|
|
159
|
-
},
|
|
160
|
-
async (db) => {
|
|
161
|
-
return db.users.select().execute();
|
|
162
|
-
},
|
|
163
|
-
);
|
|
164
|
-
|
|
165
|
-
console.log("조회 결과:", result);
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
### Progress Tracking
|
|
169
|
-
|
|
170
|
-
```typescript
|
|
171
|
-
const progress = {
|
|
172
|
-
request: (state) => {
|
|
173
|
-
console.log(`요청 전송: ${state.completedSize}/${state.totalSize} bytes`);
|
|
174
|
-
},
|
|
175
|
-
response: (state) => {
|
|
176
|
-
console.log(`응답 수신: ${state.completedSize}/${state.totalSize} bytes`);
|
|
177
|
-
},
|
|
178
|
-
server: (state) => {
|
|
179
|
-
console.log(`서버 처리: ${state.completedSize}/${state.totalSize}`);
|
|
180
|
-
},
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
await client.send("Service", "method", [arg1, arg2], progress);
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
### Connection State & Events
|
|
187
|
-
|
|
188
|
-
```typescript
|
|
189
|
-
// 연결 상태 모니터링
|
|
190
|
-
client.on("state", (state) => {
|
|
191
|
-
console.log("연결 상태:", state); // "connected" | "closed" | "reconnecting"
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
client.on("request-progress", (state) => {
|
|
195
|
-
console.log(`요청 진행: ${state.completedSize}/${state.totalSize}`);
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
// 연결 확인
|
|
199
|
-
if (client.connected) {
|
|
200
|
-
console.log("서버에 연결됨");
|
|
201
|
-
}
|
|
202
|
-
```
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
# App Structure
|
|
2
|
-
|
|
3
|
-
## `AppStructureItem`
|
|
4
|
-
|
|
5
|
-
앱 구조 항목 유니언 타입. `children` 필드 유무로 그룹과 리프를 구분한다.
|
|
6
|
-
|
|
7
|
-
```typescript
|
|
8
|
-
export type AppStructureItem<TModule = unknown> =
|
|
9
|
-
| AppStructureGroupItem<TModule>
|
|
10
|
-
| AppStructureLeafItem<TModule>;
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
`TModule` 제네릭은 모듈 식별자 타입이다 (일반적으로 `string`).
|
|
14
|
-
|
|
15
|
-
## `AppStructureGroupItem`
|
|
16
|
-
|
|
17
|
-
자식을 가진 그룹 메뉴 항목. `children` 필드로 하위 항목을 재귀적으로 포함한다.
|
|
18
|
-
|
|
19
|
-
```typescript
|
|
20
|
-
export interface AppStructureGroupItem<TModule> {
|
|
21
|
-
code: string;
|
|
22
|
-
title: string;
|
|
23
|
-
modules?: TModule[];
|
|
24
|
-
requiredModules?: TModule[];
|
|
25
|
-
icon?: string;
|
|
26
|
-
children: AppStructureItem<TModule>[];
|
|
27
|
-
}
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
| Field | Type | Description |
|
|
31
|
-
|-------|------|-------------|
|
|
32
|
-
| `code` | `string` | 항목 코드 (권한 코드 체인에 사용) |
|
|
33
|
-
| `title` | `string` | 표시 이름 |
|
|
34
|
-
| `modules` | `TModule[]?` | 접근에 필요한 모듈 목록 (OR 조건: 하나라도 있으면 접근 가능) |
|
|
35
|
-
| `requiredModules` | `TModule[]?` | 접근에 필수인 모듈 목록 (AND 조건: 모두 있어야 접근 가능) |
|
|
36
|
-
| `icon` | `string?` | 아이콘 식별자 |
|
|
37
|
-
| `children` | `AppStructureItem<TModule>[]` | 하위 메뉴 항목 배열 |
|
|
38
|
-
|
|
39
|
-
## `AppStructureLeafItem`
|
|
40
|
-
|
|
41
|
-
말단 메뉴 항목. 실제 페이지 URL과 권한(perms)을 가진다.
|
|
42
|
-
|
|
43
|
-
```typescript
|
|
44
|
-
export interface AppStructureLeafItem<TModule> {
|
|
45
|
-
code: string;
|
|
46
|
-
title: string;
|
|
47
|
-
modules?: TModule[];
|
|
48
|
-
requiredModules?: TModule[];
|
|
49
|
-
perms?: ("use" | "edit")[];
|
|
50
|
-
subPerms?: AppStructureSubPermission<TModule>[];
|
|
51
|
-
icon?: string;
|
|
52
|
-
url?: string;
|
|
53
|
-
isNotMenu?: boolean;
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
| Field | Type | Description |
|
|
58
|
-
|-------|------|-------------|
|
|
59
|
-
| `code` | `string` | 항목 코드 |
|
|
60
|
-
| `title` | `string` | 표시 이름 |
|
|
61
|
-
| `modules` | `TModule[]?` | 접근에 필요한 모듈 목록 (OR 조건) |
|
|
62
|
-
| `requiredModules` | `TModule[]?` | 접근에 필수인 모듈 목록 (AND 조건) |
|
|
63
|
-
| `perms` | `("use" \| "edit")[]?` | 이 항목에 부여 가능한 권한 종류 |
|
|
64
|
-
| `subPerms` | `AppStructureSubPermission<TModule>[]?` | 하위 권한 정의 배열 |
|
|
65
|
-
| `icon` | `string?` | 아이콘 식별자 |
|
|
66
|
-
| `url` | `string?` | 페이지 URL |
|
|
67
|
-
| `isNotMenu` | `boolean?` | true이면 메뉴에 표시하지 않음 |
|
|
68
|
-
|
|
69
|
-
## `AppStructureSubPermission`
|
|
70
|
-
|
|
71
|
-
리프 항목의 하위 권한 정의. 각 하위 권한도 모듈 접근 제어를 가진다.
|
|
72
|
-
|
|
73
|
-
```typescript
|
|
74
|
-
export interface AppStructureSubPermission<TModule> {
|
|
75
|
-
code: string;
|
|
76
|
-
title: string;
|
|
77
|
-
modules?: TModule[];
|
|
78
|
-
requiredModules?: TModule[];
|
|
79
|
-
perms: ("use" | "edit")[];
|
|
80
|
-
}
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
| Field | Type | Description |
|
|
84
|
-
|-------|------|-------------|
|
|
85
|
-
| `code` | `string` | 하위 권한 코드 |
|
|
86
|
-
| `title` | `string` | 하위 권한 표시 이름 |
|
|
87
|
-
| `modules` | `TModule[]?` | 접근에 필요한 모듈 목록 (OR 조건) |
|
|
88
|
-
| `requiredModules` | `TModule[]?` | 접근에 필수인 모듈 목록 (AND 조건) |
|
|
89
|
-
| `perms` | `("use" \| "edit")[]` | 부여 가능한 권한 종류 |
|
|
90
|
-
|
|
91
|
-
## `FlatPermission`
|
|
92
|
-
|
|
93
|
-
트리를 플래트닝한 권한 결과. `getFlatPermissions()`의 반환 타입이다.
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
export interface FlatPermission<TModule = unknown> {
|
|
97
|
-
titleChain: string[];
|
|
98
|
-
codeChain: string[];
|
|
99
|
-
modulesChain: TModule[][];
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
| Field | Type | Description |
|
|
104
|
-
|-------|------|-------------|
|
|
105
|
-
| `titleChain` | `string[]` | 루트부터 현재 권한까지의 표시 이름 체인 (예: `[관리, 사용자]`) |
|
|
106
|
-
| `codeChain` | `string[]` | 루트부터 현재 권한까지의 코드 체인 (예: `[admin, user, use]`) |
|
|
107
|
-
| `modulesChain` | `TModule[][]` | 각 레벨에서 필요한 모듈 목록의 체인 |
|
|
108
|
-
|
|
109
|
-
## `isUsableModules`
|
|
110
|
-
|
|
111
|
-
단일 항목의 모듈 접근 가능 여부를 판단한다.
|
|
112
|
-
|
|
113
|
-
```typescript
|
|
114
|
-
export function isUsableModules<TModule>(
|
|
115
|
-
modules: TModule[] | undefined,
|
|
116
|
-
requiredModules: TModule[] | undefined,
|
|
117
|
-
usableModules: TModule[] | undefined,
|
|
118
|
-
): boolean;
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
| Parameter | Type | Description |
|
|
122
|
-
|-----------|------|-------------|
|
|
123
|
-
| `modules` | `TModule[] \| undefined` | OR 조건 모듈 목록. 하나라도 `usableModules`에 포함되면 통과 |
|
|
124
|
-
| `requiredModules` | `TModule[] \| undefined` | AND 조건 모듈 목록. 모두 `usableModules`에 포함되어야 통과 |
|
|
125
|
-
| `usableModules` | `TModule[] \| undefined` | 사용자가 보유한 활성 모듈 목록 |
|
|
126
|
-
|
|
127
|
-
반환: `modules`와 `requiredModules` 조건을 모두 만족하면 `true`.
|
|
128
|
-
|
|
129
|
-
- `modules`가 undefined이거나 빈 배열이면 OR 조건은 자동 통과
|
|
130
|
-
- `requiredModules`가 undefined이거나 빈 배열이면 AND 조건은 자동 통과
|
|
131
|
-
- `usableModules`가 undefined이면 `modules`가 있을 때 `false`
|
|
132
|
-
|
|
133
|
-
## `isUsableModulesChain`
|
|
134
|
-
|
|
135
|
-
모듈 체인 전체의 접근 가능 여부를 판단한다. 트리의 각 레벨에서 모듈 조건을 모두 만족해야 한다.
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
export function isUsableModulesChain<TModule>(
|
|
139
|
-
modulesChain: TModule[][],
|
|
140
|
-
requiredModulesChain: TModule[][],
|
|
141
|
-
usableModules: TModule[] | undefined,
|
|
142
|
-
): boolean;
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
| Parameter | Type | Description |
|
|
146
|
-
|-----------|------|-------------|
|
|
147
|
-
| `modulesChain` | `TModule[][]` | 각 레벨의 OR 조건 모듈 배열 |
|
|
148
|
-
| `requiredModulesChain` | `TModule[][]` | 각 레벨의 AND 조건 모듈 배열 |
|
|
149
|
-
| `usableModules` | `TModule[] \| undefined` | 사용자가 보유한 활성 모듈 목록 |
|
|
150
|
-
|
|
151
|
-
반환: 모든 레벨의 조건을 만족하면 `true`. 하나라도 실패하면 `false`.
|
|
152
|
-
|
|
153
|
-
## `getFlatPermissions`
|
|
154
|
-
|
|
155
|
-
앱 구조 트리를 BFS로 순회하며 모듈 조건을 필터링하여 `FlatPermission[]`으로 플래트닝한다.
|
|
156
|
-
|
|
157
|
-
```typescript
|
|
158
|
-
export function getFlatPermissions<TModule>(
|
|
159
|
-
items: AppStructureItem<TModule>[],
|
|
160
|
-
usableModules: TModule[] | undefined,
|
|
161
|
-
): FlatPermission<TModule>[];
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
| Parameter | Type | Description |
|
|
165
|
-
|-----------|------|-------------|
|
|
166
|
-
| `items` | `AppStructureItem<TModule>[]` | 앱 구조 트리의 최상위 항목 배열 |
|
|
167
|
-
| `usableModules` | `TModule[] \| undefined` | 사용자가 보유한 활성 모듈 목록. undefined이면 모듈 조건이 없는 항목만 포함 |
|
|
168
|
-
|
|
169
|
-
반환: 모듈 조건을 만족하는 모든 권한의 플랫 목록.
|
|
170
|
-
|
|
171
|
-
처리 로직:
|
|
172
|
-
1. BFS로 트리를 순회하며 각 레벨의 `modules`(OR)와 `requiredModules`(AND) 조건을 체크
|
|
173
|
-
2. 조건 미충족 항목은 하위 트리 전체를 건너뜀
|
|
174
|
-
3. `AppStructureLeafItem`의 `perms`를 `codeChain`에 추가하여 `FlatPermission` 생성
|
|
175
|
-
4. `subPerms`도 개별 모듈 조건을 체크하여 `FlatPermission`으로 변환
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# Events
|
|
2
|
-
|
|
3
|
-
## `ServiceEventDef`
|
|
4
|
-
|
|
5
|
-
`defineEvent()`로 생성된 이벤트 정의. `$info`와 `$data`는 런타임에서 사용되지 않는 타입 전용 마커다.
|
|
6
|
-
|
|
7
|
-
```typescript
|
|
8
|
-
export 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` | 이벤트 이름 |
|
|
18
|
-
| `$info` | `TInfo` | 타입 추출 전용 마커 (런타임에서 사용하지 않음). 이벤트 필터링 조건 타입 |
|
|
19
|
-
| `$data` | `TData` | 타입 추출 전용 마커 (런타임에서 사용하지 않음). 이벤트 페이로드 타입 |
|
|
20
|
-
|
|
21
|
-
`TInfo`와 `TData`는 제네릭 파라미터로, `defineEvent<TInfo, TData>()` 호출 시 지정된 타입이 할당된다. 기본값은 `unknown`.
|
|
22
|
-
|
|
23
|
-
## `defineEvent`
|
|
24
|
-
|
|
25
|
-
타입 안전한 서비스 이벤트를 정의하는 팩토리 함수.
|
|
26
|
-
|
|
27
|
-
```typescript
|
|
28
|
-
export function defineEvent<TInfo = unknown, TData = unknown>(
|
|
29
|
-
eventName: string,
|
|
30
|
-
): ServiceEventDef<TInfo, TData>;
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
| Parameter | Type | Description |
|
|
34
|
-
|-----------|------|-------------|
|
|
35
|
-
| `eventName` | `string` | 이벤트 이름 (고유해야 함) |
|
|
36
|
-
|
|
37
|
-
| Type Parameter | Default | Description |
|
|
38
|
-
|---------------|---------|-------------|
|
|
39
|
-
| `TInfo` | `unknown` | 이벤트 필터링 조건의 타입. 구독 시 필터로 사용 |
|
|
40
|
-
| `TData` | `unknown` | 이벤트 페이로드의 타입. 이벤트 발생/수신 시 데이터 타입 |
|
|
41
|
-
|
|
42
|
-
반환: `ServiceEventDef<TInfo, TData>` 인스턴스.
|
|
43
|
-
|
|
44
|
-
사용 예:
|
|
45
|
-
|
|
46
|
-
```typescript
|
|
47
|
-
// 서버에서 이벤트 정의 + 타입 export
|
|
48
|
-
export const OrderUpdated = defineEvent<{ orderId: number }, { status: string }>("OrderUpdated");
|
|
49
|
-
|
|
50
|
-
// 서버에서 이벤트 발생 — getEvent() 프록시 방식 (권장)
|
|
51
|
-
const orderEvt = server.getEvent<typeof OrderUpdated>("OrderUpdated");
|
|
52
|
-
await orderEvt.emit((info) => info.orderId === 123, { status: "shipped" });
|
|
53
|
-
|
|
54
|
-
// 클라이언트에서 구독 (import type으로 타입만 가져옴)
|
|
55
|
-
import type { OrderUpdated } from "@server-package";
|
|
56
|
-
const orderEvt = client.getEvent<typeof OrderUpdated>("OrderUpdated");
|
|
57
|
-
const key = await orderEvt.addListener({ orderId: 123 }, async (data) => {
|
|
58
|
-
// data.status는 string으로 타입 추론됨
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
// 직접 호출 방식 (하위 호환)
|
|
62
|
-
await server.emitEvent<typeof OrderUpdated>("OrderUpdated", (info) => info.orderId === 123, { status: "shipped" });
|
|
63
|
-
await client.addListener<typeof OrderUpdated>("OrderUpdated", { orderId: 123 }, async (data) => { ... });
|
|
64
|
-
```
|