@taco_tsinghua/graphnode-sdk 0.1.17 → 0.1.21
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 +91 -333
- package/dist/client.d.ts +24 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +34 -8
- package/dist/client.js.map +1 -1
- package/dist/endpoints/ai.d.ts +25 -30
- package/dist/endpoints/ai.d.ts.map +1 -1
- package/dist/endpoints/ai.js +220 -31
- package/dist/endpoints/ai.js.map +1 -1
- package/dist/endpoints/graph.d.ts +4 -1
- package/dist/endpoints/graph.d.ts.map +1 -1
- package/dist/endpoints/graph.js +10 -0
- package/dist/endpoints/graph.js.map +1 -1
- package/dist/endpoints/graphAi.d.ts +21 -0
- package/dist/endpoints/graphAi.d.ts.map +1 -1
- package/dist/endpoints/graphAi.js +24 -0
- package/dist/endpoints/graphAi.js.map +1 -1
- package/dist/endpoints/notification.d.ts +13 -0
- package/dist/endpoints/notification.d.ts.map +1 -1
- package/dist/endpoints/notification.js +17 -0
- package/dist/endpoints/notification.js.map +1 -1
- package/dist/endpoints/sync.d.ts +3 -1
- package/dist/endpoints/sync.d.ts.map +1 -1
- package/dist/endpoints/sync.js.map +1 -1
- package/dist/http-builder.d.ts +38 -0
- package/dist/http-builder.d.ts.map +1 -1
- package/dist/http-builder.js +43 -6
- package/dist/http-builder.js.map +1 -1
- package/dist/types/graph.d.ts +66 -0
- package/dist/types/graph.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/client.ts +140 -0
- package/src/config.ts +9 -0
- package/src/endpoints/agent.ts +171 -0
- package/src/endpoints/ai.ts +296 -0
- package/src/endpoints/auth.apple.ts +39 -0
- package/src/endpoints/auth.google.ts +39 -0
- package/src/endpoints/conversations.ts +362 -0
- package/src/endpoints/graph.ts +398 -0
- package/src/endpoints/graphAi.ts +111 -0
- package/src/endpoints/health.ts +40 -0
- package/src/endpoints/me.ts +97 -0
- package/src/endpoints/note.ts +351 -0
- package/src/endpoints/notification.ts +69 -0
- package/src/endpoints/sync.ts +71 -0
- package/src/http-builder.ts +290 -0
- package/src/index.ts +60 -0
- package/src/types/aiInput.ts +111 -0
- package/src/types/conversation.ts +51 -0
- package/src/types/graph.ts +201 -0
- package/src/types/graphAi.ts +21 -0
- package/src/types/me.ts +49 -0
- package/src/types/message.ts +40 -0
- package/src/types/note.ts +89 -0
- package/src/types/problem.ts +22 -0
- package/src/types/sync.ts +35 -0
package/README.md
CHANGED
|
@@ -1,381 +1,139 @@
|
|
|
1
|
-
# GraphNode
|
|
1
|
+
# GraphNode SDK for Frontend
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> **TACO 4기 - GraphNode 서비스 프론트엔드 연동 SDK**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
GraphNode 백엔드 API를 타입 안전(Type-Safe)하게 사용할 수 있도록 제공되는 공식 클라이언트 라이브러리입니다.
|
|
6
|
+
|
|
7
|
+
## 📦 설치 (Installation)
|
|
6
8
|
|
|
7
9
|
```bash
|
|
8
10
|
npm install @taco_tsinghua/graphnode-sdk
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
### Initialization
|
|
14
|
-
|
|
15
|
-
Create a client instance. The base URL is automatically configured to point to the GraphNode backend.
|
|
16
|
-
|
|
17
|
-
```typescript
|
|
18
|
-
import { createGraphNodeClient } from '@taco_tsinghua/graphnode-sdk';
|
|
19
|
-
|
|
20
|
-
// No need to pass baseUrl, it defaults to the internal constant
|
|
21
|
-
const client = createGraphNodeClient();
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
If you need to pass custom fetch options (e.g., for testing or specific environments):
|
|
13
|
+
*(현재는 모노레포 내부 패키지로 관리되고 있습니다.)*
|
|
25
14
|
|
|
26
|
-
|
|
27
|
-
const client = createGraphNodeClient({
|
|
28
|
-
// fetch: customFetch
|
|
29
|
-
});
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### API Usage Examples
|
|
33
|
-
|
|
34
|
-
The client is organized by API resources.
|
|
35
|
-
|
|
36
|
-
#### Health
|
|
37
|
-
|
|
38
|
-
Check the health of the API server.
|
|
39
|
-
|
|
40
|
-
```typescript
|
|
41
|
-
const health = await client.health.check();
|
|
42
|
-
console.log(health); // { ok: true }
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
#### Me (User Profile)
|
|
46
|
-
|
|
47
|
-
Get the profile of the currently authenticated user.
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
try {
|
|
51
|
-
const me = await client.me.getProfile();
|
|
52
|
-
console.log(me); // { id: '...', displayName: '...' }
|
|
53
|
-
} catch (error) {
|
|
54
|
-
console.error('Not authenticated');
|
|
55
|
-
}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
#### Conversations
|
|
59
|
-
|
|
60
|
-
**Create a single conversation:**
|
|
61
|
-
|
|
62
|
-
```typescript
|
|
63
|
-
const newConversation = await client.conversations.create({
|
|
64
|
-
id: 'client-generated-uuid-1',
|
|
65
|
-
title: 'My First Conversation',
|
|
66
|
-
});
|
|
67
|
-
console.log(newConversation);
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
**Bulk create multiple conversations:**
|
|
71
|
-
|
|
72
|
-
```typescript
|
|
73
|
-
const response = await client.conversations.bulkCreate({
|
|
74
|
-
conversations: [
|
|
75
|
-
{ id: 'bulk-uuid-1', title: 'Bulk Conversation 1' },
|
|
76
|
-
{
|
|
77
|
-
id: 'bulk-uuid-2',
|
|
78
|
-
title: 'Bulk Conversation 2 with messages',
|
|
79
|
-
messages: [{ id: 'msg-uuid-1', role: 'user', content: 'Hello!' }],
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
});
|
|
83
|
-
console.log(response.conversations); // Array of created conversations
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
**List all conversations:**
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
const conversations = await client.conversations.list();
|
|
90
|
-
console.log(conversations);
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
**Get a specific conversation:**
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
const conversation = await client.conversations.get('conversation-id-123');
|
|
97
|
-
console.log(conversation);
|
|
98
|
-
```
|
|
15
|
+
## 🚀 시작하기 (Getting Started)
|
|
99
16
|
|
|
100
|
-
|
|
17
|
+
### 클라이언트 초기화
|
|
101
18
|
|
|
102
|
-
|
|
19
|
+
API 요청을 보내기 위해 `GraphNodeClient`를 초기화해야 합니다. 기본적으로 서버와의 세션(Cookie) 인증을 사용하므로 `credentials: 'include'` 옵션이 내장되어 있습니다.
|
|
103
20
|
|
|
104
21
|
```typescript
|
|
105
|
-
|
|
106
|
-
id: 'message-uuid-456',
|
|
107
|
-
role: 'user',
|
|
108
|
-
content: 'Hello, this is a new message.',
|
|
109
|
-
});
|
|
110
|
-
console.log(newMessage);
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
#### Graph
|
|
22
|
+
import { createGraphNodeClient } from 'graphnode-sdk';
|
|
114
23
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
// Create a node
|
|
119
|
-
const node = await client.graph.createNode({
|
|
120
|
-
id: 1,
|
|
121
|
-
label: 'My Node',
|
|
122
|
-
type: 'concept',
|
|
123
|
-
properties: { color: 'red' },
|
|
24
|
+
// 기본 설정으로 클라이언트 생성 (localhost:3000 기준)
|
|
25
|
+
const client = createGraphNodeClient({
|
|
26
|
+
baseUrl: 'http://localhost:3000' // 배포 환경에 따라 URL 변경
|
|
124
27
|
});
|
|
125
|
-
|
|
126
|
-
// List nodes
|
|
127
|
-
const nodes = await client.graph.listNodes();
|
|
128
|
-
|
|
129
|
-
// Get node
|
|
130
|
-
const myNode = await client.graph.getNode(1);
|
|
131
|
-
|
|
132
|
-
// Update node
|
|
133
|
-
await client.graph.updateNode(1, { label: 'Updated Node' });
|
|
134
|
-
|
|
135
|
-
// Delete node
|
|
136
|
-
await client.graph.deleteNode(1);
|
|
137
|
-
|
|
138
|
-
// Delete node cascade (with edges)
|
|
139
|
-
await client.graph.deleteNodeCascade(1);
|
|
140
28
|
```
|
|
141
29
|
|
|
142
|
-
|
|
30
|
+
---
|
|
143
31
|
|
|
144
|
-
|
|
145
|
-
// Create an edge
|
|
146
|
-
const edge = await client.graph.createEdge({
|
|
147
|
-
source: 1,
|
|
148
|
-
target: 2,
|
|
149
|
-
relationship: 'related_to',
|
|
150
|
-
});
|
|
32
|
+
## 📚 API Reference
|
|
151
33
|
|
|
152
|
-
|
|
153
|
-
const edges = await client.graph.listEdges();
|
|
34
|
+
### 1. 인증 (Authentication)
|
|
154
35
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
36
|
+
| Method | Endpoint | Description | Status Codes |
|
|
37
|
+
| :--- | :--- | :--- | :--- |
|
|
38
|
+
| `client.me.getMe()` | `GET /v1/me` | 현재 로그인한 사용자 정보 조회 | `200` OK<br>`401` Unauth |
|
|
39
|
+
| `client.auth.google.getStartUrl()` | - | Google 로그인 시작 URL 반환 | - |
|
|
40
|
+
| `client.auth.apple.getStartUrl()` | - | Apple 로그인 시작 URL 반환 | - |
|
|
41
|
+
| `client.auth.logout()` | `POST /auth/logout` | 로그아웃 (세션 쿠키 삭제) | `204` Destroyed<br>`401` Unauth |
|
|
158
42
|
|
|
159
|
-
|
|
43
|
+
### 2. AI 대화 (AI Chat)
|
|
160
44
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
45
|
+
| Method | Endpoint | Description | Status Codes |
|
|
46
|
+
| :--- | :--- | :--- | :--- |
|
|
47
|
+
| `client.ai.createConversation()` | `POST /v1/ai/conversations` | 새로운 대화방 생성 | `201` Created<br>`400` Bad Request |
|
|
48
|
+
| `client.ai.listConversations()` | `GET /v1/ai/conversations` | 대화방 목록 조회 | `200` OK |
|
|
49
|
+
| `client.ai.chat(convId, dto)` | `POST /v1/ai/conversations/:id/chat` | 메시지 전송 (파일 첨부 가능) | `200` OK<br>`400` Bad Req<br>`401` Unauth<br>`502` Upstream |
|
|
50
|
+
| `openAgentChatStream()` | `POST /v1/agent/stream` | 실시간 에이전트 스트리밍 (SSE) | `200` OK (Stream) |
|
|
167
51
|
|
|
168
|
-
|
|
169
|
-
const clusters = await client.graph.listClusters();
|
|
52
|
+
### 3. 그래프 AI (Graph AI)
|
|
170
53
|
|
|
171
|
-
|
|
172
|
-
|
|
54
|
+
| Method | Endpoint | Description | Status Codes |
|
|
55
|
+
| :--- | :--- | :--- | :--- |
|
|
56
|
+
| `client.graphAi.generateGraph()` | `POST /v1/graph-ai/generate` | 그래프 생성 요청 (Async Task) | `202` Accepted<br>`401` Unauth<br>`409` Conflict |
|
|
57
|
+
| `client.graphAi.requestSummary()` | `POST /v1/graph-ai/summary` | 그래프 요약 생성 요청 (Async Task) | `202` Accepted<br>`401` Unauth<br>`409` Conflict |
|
|
58
|
+
| `client.graphAi.getSummary()` | `GET /v1/graph-ai/summary` | 생성된 그래프 요약 조회 | `200` OK<br>`404` Not Found |
|
|
173
59
|
|
|
174
|
-
|
|
175
|
-
await client.graph.deleteCluster('cluster-id');
|
|
60
|
+
### 4. 그래프 관리 (Graph Knowledge)
|
|
176
61
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
62
|
+
| Method | Endpoint | Description | Status Codes |
|
|
63
|
+
| :--- | :--- | :--- | :--- |
|
|
64
|
+
| `client.graph.listNodes()` | `GET /v1/graph/nodes` | 노드 목록 조회 | `200` OK<br>`401` Unauth |
|
|
65
|
+
| `client.graph.createNode()` | `POST /v1/graph/nodes` | 노드 생성 | `201` Created<br>`400` Bad Req |
|
|
66
|
+
| `client.graph.getNode(id)` | `GET /v1/graph/nodes/:id` | 노드 상세 조회 | `200` OK<br>`404` Not Found |
|
|
67
|
+
| `client.graph.updateNode()` | `PATCH /v1/graph/nodes/:id` | 노드 수정 | `204` Updated<br>`404` Not Found |
|
|
68
|
+
| `client.graph.deleteNode()` | `DELETE /v1/graph/nodes/:id` | 노드 삭제 | `204` Deleted<br>`401` Unauth |
|
|
69
|
+
| `client.graph.createEdge()` | `POST /v1/graph/edges` | 엣지 생성 | `201` Created<br>`400` Bad Req |
|
|
70
|
+
| `client.graph.getSnapshot()` | `GET /v1/graph/snapshot` | 전체 그래프 데이터 스냅샷 조회 | `200` OK<br>`401` Unauth |
|
|
180
71
|
|
|
181
|
-
|
|
72
|
+
### 5. 노트 관리 (Notes & Folders)
|
|
182
73
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
74
|
+
| Method | Endpoint | Description | Status Codes |
|
|
75
|
+
| :--- | :--- | :--- | :--- |
|
|
76
|
+
| `client.note.createFolder()` | `POST /v1/folders` | 폴더 생성 | `201` Created<br>`400` Bad Req |
|
|
77
|
+
| `client.note.createNote()` | `POST /v1/notes` | 노트 생성 | `201` Created<br>`400` Bad Req |
|
|
78
|
+
| `client.note.listNotes()` | `GET /v1/notes` | 노트 목록 조회 | `200` OK<br>`401` Unauth |
|
|
79
|
+
| `client.note.updateNote()` | `PATCH /v1/notes/:id` | 노트 수정 | `200` OK<br>`404` Not Found |
|
|
186
80
|
|
|
187
|
-
|
|
188
|
-
const snapshot = await client.graph.getSnapshot();
|
|
81
|
+
### 6. 동기화 (Sync)
|
|
189
82
|
|
|
190
|
-
|
|
191
|
-
await client.graph.saveSnapshot(snapshot);
|
|
192
|
-
```
|
|
83
|
+
오프라인 우선(Offline-first) 아키텍처 지원을 위한 변경사항 동기화 API.
|
|
193
84
|
|
|
194
|
-
|
|
85
|
+
| Method | Endpoint | Description | Status Codes |
|
|
86
|
+
| :--- | :--- | :--- | :--- |
|
|
87
|
+
| `client.sync.pull()` | `GET /v1/sync/pull` | 서버 변경사항 가져오기 | `200` OK<br>`400` Bad Req |
|
|
88
|
+
| `client.sync.push()` | `POST /v1/sync/push` | 클라이언트 변경사항 반영 | `200` OK<br>`400` Bad Req<br>`502` Upstream |
|
|
195
89
|
|
|
196
|
-
|
|
90
|
+
---
|
|
197
91
|
|
|
198
|
-
|
|
92
|
+
## 💡 주요 타입 정의 (Types)
|
|
199
93
|
|
|
94
|
+
### GraphSummaryDto
|
|
200
95
|
```typescript
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
96
|
+
interface GraphSummaryDto {
|
|
97
|
+
overview: {
|
|
98
|
+
total_conversations: number;
|
|
99
|
+
summary_text: string;
|
|
100
|
+
...
|
|
101
|
+
};
|
|
102
|
+
clusters: Array<{ name: string; insight_text: string; ... }>;
|
|
103
|
+
patterns: Array<{ pattern_type: string; description: string; ... }>;
|
|
104
|
+
connections: Array<{ source_cluster: string; target_cluster: string; ... }>;
|
|
105
|
+
recommendations: Array<{ title: string; priority: string; ... }>;
|
|
206
106
|
}
|
|
207
107
|
```
|
|
208
108
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
Directly sends conversation data (in ChatGPT export format) to the AI engine for graph generation. Useful for testing without existing DB data.
|
|
212
|
-
|
|
109
|
+
### SyncPushRequest
|
|
213
110
|
```typescript
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
update_time: 1678900100,
|
|
221
|
-
mapping: {
|
|
222
|
-
'msg-1': {
|
|
223
|
-
id: 'msg-1',
|
|
224
|
-
message: {
|
|
225
|
-
id: 'msg-1',
|
|
226
|
-
author: { role: 'user' },
|
|
227
|
-
content: { content_type: 'text', parts: ['Hello'] },
|
|
228
|
-
},
|
|
229
|
-
parent: null,
|
|
230
|
-
children: [],
|
|
231
|
-
},
|
|
232
|
-
},
|
|
233
|
-
},
|
|
234
|
-
];
|
|
235
|
-
|
|
236
|
-
const response = await client.graphAi.generateGraphTest(mockData);
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
#### Notes & Folders
|
|
240
|
-
|
|
241
|
-
**Notes:**
|
|
242
|
-
|
|
243
|
-
```typescript
|
|
244
|
-
// Create a note
|
|
245
|
-
const note = await client.note.createNote({
|
|
246
|
-
title: 'My Note',
|
|
247
|
-
content: '# Hello World',
|
|
248
|
-
folderId: null, // Optional
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
// List notes
|
|
252
|
-
const notes = await client.note.listNotes();
|
|
253
|
-
|
|
254
|
-
// Get note
|
|
255
|
-
const myNote = await client.note.getNote('note-id');
|
|
256
|
-
|
|
257
|
-
// Update note
|
|
258
|
-
const updatedNote = await client.note.updateNote('note-id', {
|
|
259
|
-
content: '# Updated Content',
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
// Delete note
|
|
263
|
-
await client.note.deleteNote('note-id');
|
|
111
|
+
interface SyncPushRequest {
|
|
112
|
+
conversations?: ConversationDto[];
|
|
113
|
+
messages?: MessageDto[];
|
|
114
|
+
notes?: NoteDto[];
|
|
115
|
+
folders?: FolderDto[];
|
|
116
|
+
}
|
|
264
117
|
```
|
|
265
118
|
|
|
266
|
-
|
|
119
|
+
---
|
|
267
120
|
|
|
268
|
-
|
|
269
|
-
// Create a folder
|
|
270
|
-
const folder = await client.note.createFolder({
|
|
271
|
-
name: 'My Folder',
|
|
272
|
-
parentId: null, // Optional
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
// List folders
|
|
276
|
-
const folders = await client.note.listFolders();
|
|
121
|
+
## 🛠️ Error Handling
|
|
277
122
|
|
|
278
|
-
|
|
279
|
-
const myFolder = await client.note.getFolder('folder-id');
|
|
280
|
-
|
|
281
|
-
// Update folder
|
|
282
|
-
const updatedFolder = await client.note.updateFolder('folder-id', {
|
|
283
|
-
name: 'Updated Folder Name',
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
// Delete folder
|
|
287
|
-
await client.note.deleteFolder('folder-id');
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
### Error Handling
|
|
291
|
-
|
|
292
|
-
The SDK uses a unified `HttpResponse` object for all API responses, eliminating the need for `try...catch` blocks for handling HTTP errors. Each API method returns a `Promise<HttpResponse<T>>`, which is a discriminated union type. You can check the `isSuccess` property to determine if the call was successful.
|
|
123
|
+
API 요청 실패 시 `HttpError`가 발생하며, 백엔드의 `ProblemDetails` 규격(`RFC 9457`)을 따릅니다.
|
|
293
124
|
|
|
294
125
|
```typescript
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
if (response.isSuccess) {
|
|
303
|
-
// Type-safe access to `data` and `statusCode`
|
|
304
|
-
console.log('Success:', response.data);
|
|
305
|
-
} else {
|
|
306
|
-
// Type-safe access to `error`
|
|
307
|
-
console.error('API Error:', response.error.message);
|
|
308
|
-
console.error('Status:', response.error.statusCode);
|
|
309
|
-
|
|
310
|
-
// The error body might contain RFC 9457 Problem Details
|
|
311
|
-
const problem = response.error.body as { title: string; detail: string };
|
|
312
|
-
if (problem) {
|
|
313
|
-
console.error('Problem Title:', problem.title);
|
|
314
|
-
console.error('Problem Detail:', problem.detail);
|
|
315
|
-
}
|
|
126
|
+
try {
|
|
127
|
+
await client.note.createNote({ ... });
|
|
128
|
+
} catch (err) {
|
|
129
|
+
if (err.name === 'HttpError') {
|
|
130
|
+
// 400 Bad Request 등의 경우
|
|
131
|
+
console.error('Status:', err.response.status);
|
|
132
|
+
console.error('Problem:', err.response.data); // { type, title, detail, ... }
|
|
316
133
|
}
|
|
317
134
|
}
|
|
318
135
|
```
|
|
319
136
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
#### 성공 코드 (General Success Codes)
|
|
325
|
-
|
|
326
|
-
- **`200 OK`**: 요청이 성공적으로 처리되었습니다. 응답 본문에 요청한 데이터가 포함됩니다. (예: `GET`, `PATCH`, `PUT`)
|
|
327
|
-
- **`201 Created`**: 리소스가 성공적으로 생성되었습니다. `Location` 헤더에 새 리소스의 URL이 포함되며, 본문에 생성된 리소스가 포함됩니다. (예: `POST`)
|
|
328
|
-
- **`204 No Content`**: 요청은 성공했으나 반환할 본문이 없습니다. (예: `DELETE`, 본문 없는 `PATCH`)
|
|
329
|
-
|
|
330
|
-
#### 에러 코드 (General Error Codes)
|
|
331
|
-
|
|
332
|
-
모든 에러 응답은 **RFC 9457 Problem Details** 형식(`application/problem+json`)을 따릅니다.
|
|
333
|
-
|
|
334
|
-
- **`400 Bad Request`**: 클라이언트 오류로 인해 서버가 요청을 처리할 수 없습니다(예: 잘못된 구문, 유효성 검사 실패). 응답 본문에 유효성 검사 실패에 대한 세부 정보가 포함됩니다.
|
|
335
|
-
- **`401 Unauthorized`**: 요청된 응답을 받으려면 인증이 필요합니다. 세션이 유효하지 않거나 만료된 경우 발생합니다.
|
|
336
|
-
- **`403 Forbidden`**: 클라이언트가 콘텐츠에 대한 접근 권한이 없습니다. 401과 달리 서버가 클라이언트의 신원을 알고 있습니다.
|
|
337
|
-
- **`404 Not Found`**: 서버가 요청한 리소스를 찾을 수 없습니다.
|
|
338
|
-
- **`409 Conflict`**: 요청이 서버의 현재 상태와 충돌할 때 전송됩니다(예: 이미 존재하는 리소스 생성).
|
|
339
|
-
- **`429 Too Many Requests`**: 사용자가 일정 시간 동안 너무 많은 요청을 보냈습니다("속도 제한").
|
|
340
|
-
- **`500 Internal Server Error`**: 서버가 처리 방법을 모르는 상황에 직면했습니다.
|
|
341
|
-
- **`502 Bad Gateway`**: 업스트림 오류. 외부 서비스(예: OpenAI, DB)가 유효하지 않은 응답을 반환했습니다.
|
|
342
|
-
- **`503 Service Unavailable`**: 서비스 불가. DB 연결 실패 등 일시적으로 서비스를 이용할 수 없습니다.
|
|
343
|
-
- **`504 Gateway Timeout`**: 업스트림 타임아웃. 외부 서비스의 응답이 지연되어 타임아웃이 발생했습니다.
|
|
344
|
-
|
|
345
|
-
#### 엔드포인트별 상태 코드 (Endpoint-Specific Status Codes)
|
|
346
|
-
|
|
347
|
-
| Endpoint | Method | Success Codes | Error Codes | Description |
|
|
348
|
-
| -------------------------------------- | -------- | ------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
349
|
-
| **/healthz** | `GET` | `200` | `503` | API 상태를 확인합니다. <br> `503`: DB 등 필수 의존성 서비스가 다운된 경우. |
|
|
350
|
-
| **/auth/logout** | `POST` | `204` | `401` | 사용자를 로그아웃하고 세션을 무효화합니다. <br> `401`: 이미 로그아웃되었거나 세션이 유효하지 않은 경우. |
|
|
351
|
-
| **/v1/me** | `GET` | `200` | `401` | 현재 사용자의 프로필을 조회합니다. <br> `401`: 로그인하지 않은 사용자. |
|
|
352
|
-
| **/v1/me/api-keys/{model}** | `GET` | `200` | `401`, `404` | 특정 모델의 API 키를 조회합니다. <br> `401`: 미인증. <br> `404`: 해당 모델의 키가 설정되지 않음. |
|
|
353
|
-
| | `PATCH` | `204` | `400`, `401` | API 키를 업데이트합니다. <br> `400`: 키 형식이 잘못됨. <br> `401`: 미인증. |
|
|
354
|
-
| | `DELETE` | `204` | `401` | API 키를 삭제합니다. <br> `401`: 미인증. |
|
|
355
|
-
| **/v1/ai/conversations** | `POST` | `201` | `400`, `401`, `409` | 새 대화를 생성합니다. <br> `400`: 제목 누락 등 입력값 오류. <br> `401`: 미인증. <br> `409`: 클라이언트가 제공한 ID가 이미 존재함. |
|
|
356
|
-
| | `GET` | `200` | `401` | 모든 대화를 조회합니다. <br> `401`: 미인증. |
|
|
357
|
-
| **/v1/ai/conversations/bulk** | `POST` | `201` | `400`, `401` | 대화를 일괄 생성합니다. <br> `400`: 배열 형식이 아니거나 데이터 오류. <br> `401`: 미인증. |
|
|
358
|
-
| **/v1/ai/conversations/{id}** | `GET` | `200` | `401`, `404` | 단일 대화를 조회합니다. <br> `401`: 미인증. <br> `404`: 대화를 찾을 수 없거나 삭제됨. |
|
|
359
|
-
| | `PATCH` | `200` | `400`, `401`, `404` | 대화를 업데이트합니다. <br> `400`: 입력값 오류. <br> `401`: 미인증. <br> `404`: 대화 없음. |
|
|
360
|
-
| | `DELETE` | `204` | `401`, `404` | 대화를 삭제합니다. <br> `401`: 미인증. <br> `404`: 대화 없음. |
|
|
361
|
-
| **/v1/ai/conversations/{id}/restore** | `POST` | `200` | `401`, `404` | 삭제된 대화를 복원합니다. <br> `401`: 미인증. <br> `404`: 삭제된 대화 기록을 찾을 수 없음. |
|
|
362
|
-
| **/v1/ai/conversations/{id}/messages** | `POST` | `201` | `400`, `401`, `404` | 대화에 메시지를 추가합니다. <br> `400`: 내용 누락 등. <br> `401`: 미인증. <br> `404`: 대화가 존재하지 않음. |
|
|
363
|
-
| **/v1/graph/nodes** | `POST` | `201` | `400`, `401`, `409` | 그래프 노드를 생성합니다. <br> `400`: 필수 필드 누락. <br> `401`: 미인증. <br> `409`: 노드 ID 중복. |
|
|
364
|
-
| | `GET` | `200` | `401` | 모든 그래프 노드를 조회합니다. <br> `401`: 미인증. |
|
|
365
|
-
| **/v1/graph/nodes/{id}** | `GET` | `200` | `401`, `404` | 단일 노드를 조회합니다. <br> `401`: 미인증. <br> `404`: 노드 없음. |
|
|
366
|
-
| | `PATCH` | `204` | `400`, `401`, `404` | 노드를 업데이트합니다. <br> `400`: 입력값 오류. <br> `401`: 미인증. <br> `404`: 노드 없음. |
|
|
367
|
-
| | `DELETE` | `204` | `401`, `404` | 노드를 삭제합니다. <br> `401`: 미인증. <br> `404`: 노드 없음. |
|
|
368
|
-
| **/v1/graph/edges** | `POST` | `201` | `400`, `401` | 그래프 엣지를 생성합니다. <br> `400`: Source/Target 노드 ID 오류. <br> `401`: 미인증. |
|
|
369
|
-
| | `GET` | `200` | `401` | 모든 그래프 엣지를 조회합니다. <br> `401`: 미인증. |
|
|
370
|
-
| | `DELETE` | `204` | `401`, `404` | 엣지를 삭제합니다. <br> `401`: 미인증. <br> `404`: 엣지 없음. |
|
|
371
|
-
| **/v1/notes** | `POST` | `201` | `400`, `401` | 노트를 생성합니다. <br> `400`: 제목/내용 누락. <br> `401`: 미인증. |
|
|
372
|
-
| | `GET` | `200` | `401` | 모든 노트를 조회합니다. <br> `401`: 미인증. |
|
|
373
|
-
| **/v1/notes/{id}** | `GET` | `200` | `401`, `404` | 단일 노트를 조회합니다. <br> `401`: 미인증. <br> `404`: 노트 없음. |
|
|
374
|
-
| | `PATCH` | `200` | `400`, `401`, `404` | 노트를 업데이트합니다. <br> `400`: 입력값 오류. <br> `401`: 미인증. <br> `404`: 노트 없음. |
|
|
375
|
-
| | `DELETE` | `204` | `401`, `404` | 노트를 삭제합니다. <br> `401`: 미인증. <br> `404`: 노트 없음. |
|
|
376
|
-
| **/v1/folders** | `POST` | `201` | `400`, `401` | 폴더를 생성합니다. <br> `400`: 이름 누락. <br> `401`: 미인증. |
|
|
377
|
-
| | `GET` | `200` | `401` | 모든 폴더를 조회합니다. <br> `401`: 미인증. |
|
|
378
|
-
| **/v1/sync/pull** | `GET` | `200` | `400`, `401` | 변경 사항을 가져옵니다. <br> `400`: `since` 파라미터 형식 오류. <br> `401`: 미인증. |
|
|
379
|
-
| **/v1/sync/push** | `POST` | `204` | `400`, `401`, `409` | 변경 사항을 푸시합니다. <br> `400`: 데이터 형식 오류. <br> `401`: 미인증. <br> `409`: 데이터 버전 충돌 (클라이언트가 구버전 데이터 수정 시도). |
|
|
380
|
-
| **/v1/graph-ai/generate** | `POST` | `202` | `401`, `409` | 그래프 생성 요청을 시작합니다. <br> `401`: 미인증. <br> `409`: 이미 진행 중인 작업이 있음. |
|
|
381
|
-
| **/v1/graph-ai/test/generate-json** | `POST` | `202` | `400` | [테스트용] JSON 기반 그래프 생성 요청. <br> `400`: JSON 형식이 잘못되었거나 필수 필드 누락. |
|
|
137
|
+
## 📝 License
|
|
138
|
+
|
|
139
|
+
This SDK is proprietary software of the TACO 4 Team.
|
package/dist/client.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { NoteApi } from './endpoints/note.js';
|
|
|
9
9
|
import { AppleAuthApi } from './endpoints/auth.apple.js';
|
|
10
10
|
import { SyncApi } from './endpoints/sync.js';
|
|
11
11
|
import { AiApi } from './endpoints/ai.js';
|
|
12
|
+
import { NotificationApi } from './endpoints/notification.js';
|
|
12
13
|
/**
|
|
13
14
|
* GraphNode 클라이언트 옵션
|
|
14
15
|
* @public
|
|
@@ -45,12 +46,33 @@ export declare class GraphNodeClient {
|
|
|
45
46
|
readonly appleAuth: AppleAuthApi;
|
|
46
47
|
readonly sync: SyncApi;
|
|
47
48
|
readonly ai: AiApi;
|
|
49
|
+
readonly notification: NotificationApi;
|
|
50
|
+
/**
|
|
51
|
+
* HTTP 요청 빌더 인스턴스.
|
|
52
|
+
* 모든 API 엔드포인트가 이 빌더를 공유하여 HTTP 요청을 수행합니다.
|
|
53
|
+
* @private
|
|
54
|
+
*/
|
|
48
55
|
private readonly rb;
|
|
56
|
+
/**
|
|
57
|
+
* 현재 설정된 Access Token (Bearer 토큰).
|
|
58
|
+
* 쿠키 인증 방식을 사용할 경우 null일 수 있습니다.
|
|
59
|
+
* @private
|
|
60
|
+
*/
|
|
49
61
|
private _accessToken;
|
|
62
|
+
/**
|
|
63
|
+
* GraphNodeClient 생성자.
|
|
64
|
+
* - 실행 환경(브라우저/Node.js)에 맞는 fetch 함수를 자동으로 감지하여 설정합니다.
|
|
65
|
+
* - 기본 API URL 및 공통 헤더 등 통신 옵션을 초기화합니다.
|
|
66
|
+
*
|
|
67
|
+
* @param opts 클라이언트 설정 옵션
|
|
68
|
+
*/
|
|
50
69
|
constructor(opts?: GraphNodeClientOptions);
|
|
51
70
|
/**
|
|
52
|
-
* Access Token을 설정합니다.
|
|
53
|
-
*
|
|
71
|
+
* Access Token을 동적으로 설정합니다.
|
|
72
|
+
* - 로그인 후 발급받은 토큰을 수동으로 설정하거나, 로그아웃 시 null로 초기화할 때 사용합니다.
|
|
73
|
+
* - 쿠키 기반 인증을 사용하는 경우, 이 함수를 호출하지 않아도(null 상태여도) 정상 동작합니다.
|
|
74
|
+
*
|
|
75
|
+
* @param token JWT Access Token 문자열 또는 null (초기화)
|
|
54
76
|
*/
|
|
55
77
|
setAccessToken(token: string | null): void;
|
|
56
78
|
}
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,cAAc,EAAkB,MAAM,mBAAmB,CAAC;AAE9F,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,cAAc,EAAkB,MAAM,mBAAmB,CAAC;AAE9F,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAQ,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE/D;;;;;;;GAOG;AACH,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,aAAa,CAAC;IAC7F,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,eAAe;IAC1B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,aAAa,EAAE,gBAAgB,CAAC;IACzC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,YAAY,EAAE,eAAe,CAAC;IAEvC;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAiB;IAEpC;;;;OAIG;IACH,OAAO,CAAC,YAAY,CAAuB;IAE3C;;;;;;OAMG;gBACS,IAAI,GAAE,sBAA2B;IA8C7C;;;;;;OAMG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAGpC;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,CAAC,EAAE,sBAAsB,GAAG,eAAe,CAEpF"}
|
package/dist/client.js
CHANGED
|
@@ -10,6 +10,7 @@ import { NoteApi } from './endpoints/note.js';
|
|
|
10
10
|
import { AppleAuthApi } from './endpoints/auth.apple.js';
|
|
11
11
|
import { SyncApi } from './endpoints/sync.js';
|
|
12
12
|
import { AiApi } from './endpoints/ai.js';
|
|
13
|
+
import { NotificationApi } from './endpoints/notification.js';
|
|
13
14
|
/**
|
|
14
15
|
* GraphNode API 클라이언트
|
|
15
16
|
* @public
|
|
@@ -25,28 +26,49 @@ import { AiApi } from './endpoints/ai.js';
|
|
|
25
26
|
* @property ai AI 채팅 API
|
|
26
27
|
*/
|
|
27
28
|
export class GraphNodeClient {
|
|
29
|
+
/**
|
|
30
|
+
* GraphNodeClient 생성자.
|
|
31
|
+
* - 실행 환경(브라우저/Node.js)에 맞는 fetch 함수를 자동으로 감지하여 설정합니다.
|
|
32
|
+
* - 기본 API URL 및 공통 헤더 등 통신 옵션을 초기화합니다.
|
|
33
|
+
*
|
|
34
|
+
* @param opts 클라이언트 설정 옵션
|
|
35
|
+
*/
|
|
28
36
|
constructor(opts = {}) {
|
|
37
|
+
/**
|
|
38
|
+
* 현재 설정된 Access Token (Bearer 토큰).
|
|
39
|
+
* 쿠키 인증 방식을 사용할 경우 null일 수 있습니다.
|
|
40
|
+
* @private
|
|
41
|
+
*/
|
|
29
42
|
this._accessToken = null;
|
|
43
|
+
// 1. fetch 함수 결정 전략
|
|
44
|
+
// 사용자가 opts.fetch로 직접 주입하지 않은 경우, 환경에 따라 적절한 기본 fetch를 찾습니다.
|
|
30
45
|
let fetchFn = opts.fetch;
|
|
31
46
|
if (!fetchFn) {
|
|
32
47
|
if (typeof window !== 'undefined' && window.fetch) {
|
|
33
|
-
//
|
|
34
|
-
// window.fetch
|
|
48
|
+
// [Browser / Electron Renderer 환경]
|
|
49
|
+
// window.fetch는 호출 시 'this'가 window여야 하므로 bind(window)가 필수입니다.
|
|
50
|
+
// 그냥 할당하면 "Illegal invocation" 에러가 발생할 수 있습니다.
|
|
35
51
|
fetchFn = window.fetch.bind(window);
|
|
36
52
|
}
|
|
37
53
|
else if (typeof globalThis !== 'undefined' && globalThis.fetch) {
|
|
38
|
-
//
|
|
54
|
+
// [Node.js 18+ / Bun / Deno 등 환경]
|
|
55
|
+
// 전역 스코프(globalThis)에 있는 fetch를 사용합니다.
|
|
39
56
|
fetchFn = globalThis.fetch.bind(globalThis);
|
|
40
57
|
}
|
|
41
58
|
}
|
|
42
59
|
this._accessToken = opts.accessToken ?? null;
|
|
43
|
-
//
|
|
60
|
+
// 2. RequestBuilder 초기화
|
|
61
|
+
// createRequestBuilder를 통해 내부적으로 사용할 HTTP 요청 처리기를 만듭니다.
|
|
62
|
+
// 여기서 accessToken을 '함수' 형태로 넘기는 이유는,
|
|
63
|
+
// 나중에 setAccessToken()으로 값이 바뀌었을 때, RequestBuilder가 최신 값을 참조할 수 있게 하기 위함입니다.
|
|
44
64
|
this.rb = createRequestBuilder({
|
|
45
65
|
baseUrl: GRAPHNODE_BASE_URL,
|
|
46
66
|
...opts,
|
|
47
|
-
fetch: fetchFn, //
|
|
48
|
-
accessToken: () => this._accessToken, // 동적 토큰
|
|
67
|
+
fetch: fetchFn, // 결정된 fetch 함수 주입
|
|
68
|
+
accessToken: () => this._accessToken, // [중요] 동적 토큰 참조를 위한 Getter 함수 전달
|
|
49
69
|
});
|
|
70
|
+
// 3. 각 API 모듈 초기화
|
|
71
|
+
// 각 모듈은 공유된 RequestBuilder(this.rb)를 사용하여 통신합니다.
|
|
50
72
|
this.health = new HealthApi(this.rb);
|
|
51
73
|
this.me = new MeApi(this.rb);
|
|
52
74
|
this.conversations = new ConversationsApi(this.rb);
|
|
@@ -57,10 +79,14 @@ export class GraphNodeClient {
|
|
|
57
79
|
this.appleAuth = new AppleAuthApi(GRAPHNODE_BASE_URL);
|
|
58
80
|
this.sync = new SyncApi(this.rb);
|
|
59
81
|
this.ai = new AiApi(this.rb);
|
|
82
|
+
this.notification = new NotificationApi(this.rb);
|
|
60
83
|
}
|
|
61
84
|
/**
|
|
62
|
-
* Access Token을 설정합니다.
|
|
63
|
-
*
|
|
85
|
+
* Access Token을 동적으로 설정합니다.
|
|
86
|
+
* - 로그인 후 발급받은 토큰을 수동으로 설정하거나, 로그아웃 시 null로 초기화할 때 사용합니다.
|
|
87
|
+
* - 쿠키 기반 인증을 사용하는 경우, 이 함수를 호출하지 않아도(null 상태여도) 정상 동작합니다.
|
|
88
|
+
*
|
|
89
|
+
* @param token JWT Access Token 문자열 또는 null (초기화)
|
|
64
90
|
*/
|
|
65
91
|
setAccessToken(token) {
|
|
66
92
|
this._accessToken = token;
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAuB,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC9F,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|