@manonero/chat-client-sdk 1.0.0-beta.1 → 1.0.0-beta.10
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 +384 -81
- package/dist/ChatClient.d.ts +67 -8
- package/dist/ChatClient.d.ts.map +1 -1
- package/dist/ChatClient.js +82 -9
- package/dist/ChatClient.js.map +1 -1
- package/dist/errors/ChatApiError.d.ts +21 -4
- package/dist/errors/ChatApiError.d.ts.map +1 -1
- package/dist/errors/ChatApiError.js +12 -6
- package/dist/errors/ChatApiError.js.map +1 -1
- package/dist/http/BotApi.d.ts +6 -13
- package/dist/http/BotApi.d.ts.map +1 -1
- package/dist/http/BotApi.js +4 -11
- package/dist/http/BotApi.js.map +1 -1
- package/dist/http/ConversationApi.d.ts +38 -5
- package/dist/http/ConversationApi.d.ts.map +1 -1
- package/dist/http/ConversationApi.js +55 -7
- package/dist/http/ConversationApi.js.map +1 -1
- package/dist/http/FileApi.d.ts +16 -4
- package/dist/http/FileApi.d.ts.map +1 -1
- package/dist/http/FileApi.js +29 -6
- package/dist/http/FileApi.js.map +1 -1
- package/dist/http/HttpClient.d.ts +20 -2
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/http/HttpClient.js +76 -14
- package/dist/http/HttpClient.js.map +1 -1
- package/dist/http/MessageApi.d.ts +2 -1
- package/dist/http/MessageApi.d.ts.map +1 -1
- package/dist/http/MessageApi.js +15 -3
- package/dist/http/MessageApi.js.map +1 -1
- package/dist/http/ProxyApi.d.ts +18 -2
- package/dist/http/ProxyApi.d.ts.map +1 -1
- package/dist/http/ProxyApi.js +33 -6
- package/dist/http/ProxyApi.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/realtime/ChatHubClient.d.ts +58 -1
- package/dist/realtime/ChatHubClient.d.ts.map +1 -1
- package/dist/realtime/ChatHubClient.js +202 -15
- package/dist/realtime/ChatHubClient.js.map +1 -1
- package/dist/realtime/NotificationHubClient.d.ts +43 -1
- package/dist/realtime/NotificationHubClient.d.ts.map +1 -1
- package/dist/realtime/NotificationHubClient.js +134 -29
- package/dist/realtime/NotificationHubClient.js.map +1 -1
- package/dist/realtime/ReconnectionManager.d.ts +2 -1
- package/dist/realtime/ReconnectionManager.d.ts.map +1 -1
- package/dist/realtime/ReconnectionManager.js +13 -3
- package/dist/realtime/ReconnectionManager.js.map +1 -1
- package/dist/types/auth.d.ts +2 -2
- package/dist/types/auth.d.ts.map +1 -1
- package/dist/types/block.d.ts +16 -1
- package/dist/types/block.d.ts.map +1 -1
- package/dist/types/block.js +30 -0
- package/dist/types/block.js.map +1 -1
- package/dist/types/bot.d.ts +2 -8
- package/dist/types/bot.d.ts.map +1 -1
- package/dist/types/chat-events.d.ts +25 -3
- package/dist/types/chat-events.d.ts.map +1 -1
- package/dist/types/common.d.ts +19 -0
- package/dist/types/common.d.ts.map +1 -1
- package/dist/types/conversation.d.ts +58 -8
- package/dist/types/conversation.d.ts.map +1 -1
- package/dist/types/message.d.ts +9 -5
- package/dist/types/message.d.ts.map +1 -1
- package/dist/types/notification-events.d.ts +34 -7
- package/dist/types/notification-events.d.ts.map +1 -1
- package/dist/types/participant.d.ts +2 -2
- package/dist/types/participant.d.ts.map +1 -1
- package/dist/types/signalr.d.ts +4 -1
- package/dist/types/signalr.d.ts.map +1 -1
- package/package.json +4 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// ConversationApi.ts — Conversation management endpoints
|
|
2
2
|
import { HttpClient } from './HttpClient.js';
|
|
3
|
+
import { ChatApiError } from '../errors/ChatApiError.js';
|
|
3
4
|
/**
|
|
4
5
|
* Conversation API client.
|
|
5
6
|
* All endpoints require JWT Bearer token.
|
|
@@ -55,18 +56,42 @@ export class ConversationApi {
|
|
|
55
56
|
}
|
|
56
57
|
/**
|
|
57
58
|
* DELETE /api/conversations/{id}
|
|
58
|
-
*
|
|
59
|
+
* Behavior depends on conversation type:
|
|
60
|
+
* - Group → leave (same as POST .../leave). Other participants remain.
|
|
61
|
+
* - OneToOne / Self → hide the conversation from this user's list (soft-delete, not a true delete).
|
|
59
62
|
*/
|
|
60
|
-
|
|
63
|
+
delete(id) {
|
|
61
64
|
return this.http.delete(`/api/conversations/${encodeURIComponent(id)}`);
|
|
62
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* POST /api/conversations/{id}/leave
|
|
68
|
+
* Leave a Group conversation explicitly (Group only).
|
|
69
|
+
* Returns 403 Forbidden if the conversation is not a Group.
|
|
70
|
+
*
|
|
71
|
+
* NOTE: `delete()` (DELETE) also performs the leave action for Group conversations and
|
|
72
|
+
* additionally hides OneToOne/Self conversations. Use this method when you need the
|
|
73
|
+
* strict Group-only semantic with explicit 403 feedback for non-Group conversations.
|
|
74
|
+
*/
|
|
75
|
+
leaveGroup(id) {
|
|
76
|
+
return this.http.post(`/api/conversations/${encodeURIComponent(id)}/leave`);
|
|
77
|
+
}
|
|
63
78
|
/**
|
|
64
79
|
* GET /api/conversations/one-to-one/{otherParticipantId}
|
|
65
80
|
* Find an existing OneToOne conversation with another participant.
|
|
66
|
-
*
|
|
81
|
+
*
|
|
82
|
+
* Server returns 404 Not Found when no such conversation exists; the SDK
|
|
83
|
+
* catches that case and resolves to `null` so callers can treat "not found"
|
|
84
|
+
* as a normal value instead of an exception. All other errors are rethrown.
|
|
67
85
|
*/
|
|
68
|
-
findOneToOne(otherParticipantId) {
|
|
69
|
-
|
|
86
|
+
async findOneToOne(otherParticipantId) {
|
|
87
|
+
try {
|
|
88
|
+
return await this.http.get(`/api/conversations/one-to-one/${encodeURIComponent(otherParticipantId)}`);
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
if (err instanceof ChatApiError && err.status === 404)
|
|
92
|
+
return null;
|
|
93
|
+
throw err;
|
|
94
|
+
}
|
|
70
95
|
}
|
|
71
96
|
/**
|
|
72
97
|
* POST /api/conversations/{id}/participants
|
|
@@ -102,8 +127,8 @@ export class ConversationApi {
|
|
|
102
127
|
* POST /api/conversations/{id}/read
|
|
103
128
|
* Mark a conversation as read up to the given messageId.
|
|
104
129
|
*/
|
|
105
|
-
markAsRead(id,
|
|
106
|
-
return this.http.post(`/api/conversations/${encodeURIComponent(id)}/read`,
|
|
130
|
+
markAsRead(id, request) {
|
|
131
|
+
return this.http.post(`/api/conversations/${encodeURIComponent(id)}/read`, request);
|
|
107
132
|
}
|
|
108
133
|
/**
|
|
109
134
|
* DELETE /api/conversations/{id}/read
|
|
@@ -112,5 +137,28 @@ export class ConversationApi {
|
|
|
112
137
|
markAsUnread(id) {
|
|
113
138
|
return this.http.delete(`/api/conversations/${encodeURIComponent(id)}/read`);
|
|
114
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* GET /api/conversations/{id}/media?kind={kind}&limit={limit}&cursor={cursor}
|
|
142
|
+
*
|
|
143
|
+
* List every media/link item that has appeared in the conversation, newest first.
|
|
144
|
+
*
|
|
145
|
+
* - `kind` — `all` (default), `attachment`, or `link` (case-insensitive on the wire).
|
|
146
|
+
* - `limit` — 1..100, default 50.
|
|
147
|
+
* - `cursor` — opaque `nextCursor` from a prior page.
|
|
148
|
+
*
|
|
149
|
+
* Participants only see items from messages created after they joined the
|
|
150
|
+
* conversation. Returns 403 if the caller is not a participant.
|
|
151
|
+
*/
|
|
152
|
+
getMedia(conversationId, params) {
|
|
153
|
+
const qs = new URLSearchParams();
|
|
154
|
+
if (params?.kind !== undefined)
|
|
155
|
+
qs.set('kind', params.kind);
|
|
156
|
+
if (params?.limit !== undefined)
|
|
157
|
+
qs.set('limit', String(params.limit));
|
|
158
|
+
if (params?.cursor !== undefined)
|
|
159
|
+
qs.set('cursor', params.cursor);
|
|
160
|
+
const q = qs.toString();
|
|
161
|
+
return this.http.get(`/api/conversations/${encodeURIComponent(conversationId)}/media${q ? `?${q}` : ''}`);
|
|
162
|
+
}
|
|
115
163
|
}
|
|
116
164
|
//# sourceMappingURL=ConversationApi.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConversationApi.js","sourceRoot":"","sources":["../../src/http/ConversationApi.ts"],"names":[],"mappings":"AAAA,yDAAyD;AAEzD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"ConversationApi.js","sourceRoot":"","sources":["../../src/http/ConversationApi.ts"],"names":[],"mappings":"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"}
|
package/dist/http/FileApi.d.ts
CHANGED
|
@@ -28,14 +28,26 @@ export declare class FileApi {
|
|
|
28
28
|
upload(uploadUrl: string, file: File | Blob, onProgress?: UploadProgressCallback): Promise<UploadResponse>;
|
|
29
29
|
/**
|
|
30
30
|
* Returns the absolute download URL for a given storageKey.
|
|
31
|
-
*
|
|
32
|
-
*
|
|
31
|
+
*
|
|
32
|
+
* Default download is public — no auth required:
|
|
33
|
+
* getDownloadUrl("01HXABCDEF/photo.jpg")
|
|
34
|
+
* → "{baseUrl}/api/files/01HXABCDEF/photo.jpg"
|
|
35
|
+
*
|
|
36
|
+
* Pass `signed` to build a signed URL (spec §8.3) when the server enforces
|
|
37
|
+
* controlled access. Both `expires` and `sig` must be supplied — typically
|
|
38
|
+
* forwarded from the upload-url response or another server-issued source.
|
|
39
|
+
* Server returns 400 Bad Request (title `Invalid Signature`) if the URL has
|
|
40
|
+
* been tampered with or has expired.
|
|
33
41
|
*/
|
|
34
|
-
getDownloadUrl(storageKey: string
|
|
42
|
+
getDownloadUrl(storageKey: string, signed?: {
|
|
43
|
+
expires: string;
|
|
44
|
+
sig: string;
|
|
45
|
+
}): string;
|
|
35
46
|
/**
|
|
36
47
|
* DELETE /api/files/{storageKey}
|
|
37
48
|
* Delete an uploaded file. Only the uploader can delete.
|
|
38
|
-
* storageKey may contain path separators (e.g. "01HXABCDEF/photo.jpg") —
|
|
49
|
+
* storageKey may contain path separators (e.g. "01HXABCDEF/photo.jpg") — `/`
|
|
50
|
+
* is preserved as a path delimiter; other special characters are percent-encoded.
|
|
39
51
|
*/
|
|
40
52
|
delete(storageKey: string): Promise<void>;
|
|
41
53
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileApi.d.ts","sourceRoot":"","sources":["../../src/http/FileApi.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EACV,sBAAsB,EACtB,uBAAuB,EACvB,cAAc,EACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEjE;;;;GAIG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;gBAEtB,IAAI,EAAE,UAAU;IAI5B;;;;OAIG;IACH,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAIlF;;;;;;;;;OASG;IACH,MAAM,CACJ,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,IAAI,GAAG,IAAI,EACjB,UAAU,CAAC,EAAE,sBAAsB,GAClC,OAAO,CAAC,cAAc,CAAC;IAS1B
|
|
1
|
+
{"version":3,"file":"FileApi.d.ts","sourceRoot":"","sources":["../../src/http/FileApi.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EACV,sBAAsB,EACtB,uBAAuB,EACvB,cAAc,EACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEjE;;;;GAIG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;gBAEtB,IAAI,EAAE,UAAU;IAI5B;;;;OAIG;IACH,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAIlF;;;;;;;;;OASG;IACH,MAAM,CACJ,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,IAAI,GAAG,IAAI,EACjB,UAAU,CAAC,EAAE,sBAAsB,GAClC,OAAO,CAAC,cAAc,CAAC;IAS1B;;;;;;;;;;;;OAYG;IACH,cAAc,CACZ,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GACxC,MAAM;IAOT;;;;;OAKG;IACH,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC;;;;OAIG;IACG,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,cAAc,CAAC;CAQ3F"}
|
package/dist/http/FileApi.js
CHANGED
|
@@ -37,19 +37,32 @@ export class FileApi {
|
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
39
39
|
* Returns the absolute download URL for a given storageKey.
|
|
40
|
-
*
|
|
41
|
-
*
|
|
40
|
+
*
|
|
41
|
+
* Default download is public — no auth required:
|
|
42
|
+
* getDownloadUrl("01HXABCDEF/photo.jpg")
|
|
43
|
+
* → "{baseUrl}/api/files/01HXABCDEF/photo.jpg"
|
|
44
|
+
*
|
|
45
|
+
* Pass `signed` to build a signed URL (spec §8.3) when the server enforces
|
|
46
|
+
* controlled access. Both `expires` and `sig` must be supplied — typically
|
|
47
|
+
* forwarded from the upload-url response or another server-issued source.
|
|
48
|
+
* Server returns 400 Bad Request (title `Invalid Signature`) if the URL has
|
|
49
|
+
* been tampered with or has expired.
|
|
42
50
|
*/
|
|
43
|
-
getDownloadUrl(storageKey) {
|
|
44
|
-
|
|
51
|
+
getDownloadUrl(storageKey, signed) {
|
|
52
|
+
const path = `/api/files/${encodeStorageKeyPath(storageKey)}`;
|
|
53
|
+
if (!signed)
|
|
54
|
+
return `${this.http.baseUrl}${path}`;
|
|
55
|
+
const qs = new URLSearchParams({ expires: signed.expires, sig: signed.sig });
|
|
56
|
+
return `${this.http.baseUrl}${path}?${qs.toString()}`;
|
|
45
57
|
}
|
|
46
58
|
/**
|
|
47
59
|
* DELETE /api/files/{storageKey}
|
|
48
60
|
* Delete an uploaded file. Only the uploader can delete.
|
|
49
|
-
* storageKey may contain path separators (e.g. "01HXABCDEF/photo.jpg") —
|
|
61
|
+
* storageKey may contain path separators (e.g. "01HXABCDEF/photo.jpg") — `/`
|
|
62
|
+
* is preserved as a path delimiter; other special characters are percent-encoded.
|
|
50
63
|
*/
|
|
51
64
|
delete(storageKey) {
|
|
52
|
-
return this.http.delete(`/api/files/${storageKey}`);
|
|
65
|
+
return this.http.delete(`/api/files/${encodeStorageKeyPath(storageKey)}`);
|
|
53
66
|
}
|
|
54
67
|
/**
|
|
55
68
|
* Convenience method: create upload URL then immediately upload the file.
|
|
@@ -65,4 +78,14 @@ export class FileApi {
|
|
|
65
78
|
return this.upload(uploadUrl, file, onProgress);
|
|
66
79
|
}
|
|
67
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Percent-encode each segment of a storage key while preserving `/` as the
|
|
83
|
+
* path separator. The server's catch-all route accepts the unencoded key it
|
|
84
|
+
* generated, but a key containing characters like spaces, `?`, `#`, or `%`
|
|
85
|
+
* would otherwise corrupt the URL. Pure pass-through (the previous behaviour)
|
|
86
|
+
* is preserved for the common case where keys are ULID/filename-safe.
|
|
87
|
+
*/
|
|
88
|
+
function encodeStorageKeyPath(storageKey) {
|
|
89
|
+
return storageKey.split('/').map(encodeURIComponent).join('/');
|
|
90
|
+
}
|
|
68
91
|
//# sourceMappingURL=FileApi.js.map
|
package/dist/http/FileApi.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileApi.js","sourceRoot":"","sources":["../../src/http/FileApi.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAQ7C;;;;GAIG;AACH,MAAM,OAAO,OAAO;IAGlB,YAAY,IAAgB;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACH,eAAe,CAAC,OAA+B;QAC7C,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAA0B,uBAAuB,EAAE,OAAO,CAAC,CAAC;IACnF,CAAC;IAED;;;;;;;;;OASG;IACH,MAAM,CACJ,SAAiB,EACjB,IAAiB,EACjB,UAAmC;QAEnC,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;QAChC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC9B,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAiB,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC7F,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,CAAiB,SAAS,EAAE,QAAQ,CAAC,CAAC;IACrE,CAAC;IAED
|
|
1
|
+
{"version":3,"file":"FileApi.js","sourceRoot":"","sources":["../../src/http/FileApi.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAQ7C;;;;GAIG;AACH,MAAM,OAAO,OAAO;IAGlB,YAAY,IAAgB;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACH,eAAe,CAAC,OAA+B;QAC7C,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAA0B,uBAAuB,EAAE,OAAO,CAAC,CAAC;IACnF,CAAC;IAED;;;;;;;;;OASG;IACH,MAAM,CACJ,SAAiB,EACjB,IAAiB,EACjB,UAAmC;QAEnC,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;QAChC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC9B,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAiB,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC7F,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,CAAiB,SAAS,EAAE,QAAQ,CAAC,CAAC;IACrE,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,cAAc,CACZ,UAAkB,EAClB,MAAyC;QAEzC,MAAM,IAAI,GAAG,cAAc,oBAAoB,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9D,IAAI,CAAC,MAAM;YAAE,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,CAAC;QAClD,MAAM,EAAE,GAAG,IAAI,eAAe,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;QAC7E,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC;IACxD,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,UAAkB;QACvB,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAO,cAAc,oBAAoB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAClF,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,UAAU,CAAC,IAAU,EAAE,UAAmC;QAC9D,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC;YAC/C,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,WAAW,EAAE,IAAI,CAAC,IAAI;YACtB,QAAQ,EAAE,IAAI,CAAC,IAAI;SACpB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IAClD,CAAC;CACF;AAED;;;;;;GAMG;AACH,SAAS,oBAAoB,CAAC,UAAkB;IAC9C,OAAO,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACjE,CAAC"}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import type { UploadProgressCallback } from '../types/common.js';
|
|
2
|
+
/** Default per-request timeout (ms) when none is supplied. */
|
|
3
|
+
export declare const DEFAULT_REQUEST_TIMEOUT_MS = 30000;
|
|
2
4
|
export interface HttpClientOptions {
|
|
3
5
|
baseUrl: string;
|
|
4
6
|
/** Returns the current JWT token, or null if not authenticated */
|
|
5
7
|
tokenProvider?: () => string | null;
|
|
8
|
+
/**
|
|
9
|
+
* Per-request timeout in milliseconds. Default 30000.
|
|
10
|
+
* Pass `null` to disable the timeout (uploads of large files may need this).
|
|
11
|
+
*/
|
|
12
|
+
requestTimeoutMs?: number | null;
|
|
6
13
|
}
|
|
7
14
|
/**
|
|
8
15
|
* Base HTTP client wrapping the Fetch API.
|
|
@@ -11,12 +18,15 @@ export interface HttpClientOptions {
|
|
|
11
18
|
* - Automatic Authorization: Bearer token injection via tokenProvider
|
|
12
19
|
* - JSON request/response serialization
|
|
13
20
|
* - Throws ChatApiError on non-OK responses
|
|
14
|
-
* - Handles empty responses (204 No Content, 200 with no body)
|
|
21
|
+
* - Handles empty responses (204 No Content, 200 with no body) — the SDK
|
|
22
|
+
* convention is to type T as `null` or `void` for empty-body endpoints
|
|
15
23
|
* - Multipart file upload with optional XHR-based upload progress
|
|
24
|
+
* - Per-request timeout via AbortController (configurable, default 30s)
|
|
16
25
|
*/
|
|
17
26
|
export declare class HttpClient {
|
|
18
27
|
readonly baseUrl: string;
|
|
19
28
|
private readonly tokenProvider;
|
|
29
|
+
private readonly requestTimeoutMs;
|
|
20
30
|
constructor(options: HttpClientOptions);
|
|
21
31
|
private buildUrl;
|
|
22
32
|
private buildHeaders;
|
|
@@ -24,9 +34,16 @@ export declare class HttpClient {
|
|
|
24
34
|
/**
|
|
25
35
|
* Parse response body safely.
|
|
26
36
|
* Returns null for 204 No Content or empty bodies.
|
|
37
|
+
* Wraps JSON parse failures in ChatApiError for consistency with the XHR path.
|
|
27
38
|
*/
|
|
28
39
|
private parseBody;
|
|
29
40
|
private handleResponse;
|
|
41
|
+
/**
|
|
42
|
+
* Run a fetch with an AbortController-based timeout.
|
|
43
|
+
* Throws ChatApiError(0, 'Timeout', ...) when the timeout fires before the
|
|
44
|
+
* response arrives. If `requestTimeoutMs` is null, fetch is used directly.
|
|
45
|
+
*/
|
|
46
|
+
private fetchWithTimeout;
|
|
30
47
|
get<T>(path: string, headers?: Record<string, string>): Promise<T>;
|
|
31
48
|
/**
|
|
32
49
|
* GET a plain-text response (e.g. /health/live which returns "Healthy").
|
|
@@ -35,7 +52,8 @@ export declare class HttpClient {
|
|
|
35
52
|
getText(path: string): Promise<string>;
|
|
36
53
|
post<T>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
37
54
|
patch<T>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
38
|
-
|
|
55
|
+
put<T>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
56
|
+
delete<T>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
39
57
|
/**
|
|
40
58
|
* POST with multipart/form-data — no explicit Content-Type header
|
|
41
59
|
* (browser sets it with the boundary automatically).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HttpClient.d.ts","sourceRoot":"","sources":["../../src/http/HttpClient.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEjE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"HttpClient.d.ts","sourceRoot":"","sources":["../../src/http/HttpClient.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEjE,8DAA8D;AAC9D,eAAO,MAAM,0BAA0B,QAAS,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IACpC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,UAAU;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsB;IACpD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAgB;gBAErC,OAAO,EAAE,iBAAiB;IAYtC,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,eAAe;IAQvB;;;;OAIG;YACW,SAAS;YAaT,cAAc;IAW5B;;;;OAIG;YACW,gBAAgB;IA6BxB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAQxE;;;OAGG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAWtC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IASnF,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IASpF,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IASlF,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAW3F;;;OAGG;IACG,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC;IASnE;;;;OAIG;IACH,wBAAwB,CAAC,CAAC,EACxB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,EAClB,UAAU,CAAC,EAAE,sBAAsB,GAClC,OAAO,CAAC,CAAC,CAAC;CA2Dd"}
|
package/dist/http/HttpClient.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// HttpClient.ts — Base HTTP client (fetch wrapper)
|
|
2
2
|
import { ChatApiError } from '../errors/ChatApiError.js';
|
|
3
|
+
/** Default per-request timeout (ms) when none is supplied. */
|
|
4
|
+
export const DEFAULT_REQUEST_TIMEOUT_MS = 30000;
|
|
3
5
|
/**
|
|
4
6
|
* Base HTTP client wrapping the Fetch API.
|
|
5
7
|
*
|
|
@@ -7,14 +9,18 @@ import { ChatApiError } from '../errors/ChatApiError.js';
|
|
|
7
9
|
* - Automatic Authorization: Bearer token injection via tokenProvider
|
|
8
10
|
* - JSON request/response serialization
|
|
9
11
|
* - Throws ChatApiError on non-OK responses
|
|
10
|
-
* - Handles empty responses (204 No Content, 200 with no body)
|
|
12
|
+
* - Handles empty responses (204 No Content, 200 with no body) — the SDK
|
|
13
|
+
* convention is to type T as `null` or `void` for empty-body endpoints
|
|
11
14
|
* - Multipart file upload with optional XHR-based upload progress
|
|
15
|
+
* - Per-request timeout via AbortController (configurable, default 30s)
|
|
12
16
|
*/
|
|
13
17
|
export class HttpClient {
|
|
14
18
|
constructor(options) {
|
|
15
19
|
// Strip trailing slash for consistent URL joining
|
|
16
20
|
this.baseUrl = options.baseUrl.replace(/\/$/, '');
|
|
17
21
|
this.tokenProvider = options.tokenProvider ?? (() => null);
|
|
22
|
+
this.requestTimeoutMs =
|
|
23
|
+
options.requestTimeoutMs === undefined ? DEFAULT_REQUEST_TIMEOUT_MS : options.requestTimeoutMs;
|
|
18
24
|
}
|
|
19
25
|
// ---------------------------------------------------------------------------
|
|
20
26
|
// Private helpers
|
|
@@ -49,6 +55,7 @@ export class HttpClient {
|
|
|
49
55
|
/**
|
|
50
56
|
* Parse response body safely.
|
|
51
57
|
* Returns null for 204 No Content or empty bodies.
|
|
58
|
+
* Wraps JSON parse failures in ChatApiError for consistency with the XHR path.
|
|
52
59
|
*/
|
|
53
60
|
async parseBody(response) {
|
|
54
61
|
if (response.status === 204)
|
|
@@ -56,21 +63,59 @@ export class HttpClient {
|
|
|
56
63
|
const text = await response.text();
|
|
57
64
|
if (!text || text.trim() === '')
|
|
58
65
|
return null;
|
|
59
|
-
|
|
66
|
+
try {
|
|
67
|
+
return JSON.parse(text);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
throw new ChatApiError(response.status, 'Parse Error', 'Failed to parse response JSON');
|
|
71
|
+
}
|
|
60
72
|
}
|
|
61
73
|
async handleResponse(response) {
|
|
62
74
|
if (!response.ok) {
|
|
63
75
|
throw await ChatApiError.fromResponse(response);
|
|
64
76
|
}
|
|
65
|
-
//
|
|
77
|
+
// Empty bodies (204 / empty 200) resolve as `null` cast to T. Public methods
|
|
78
|
+
// keep the `Promise<T>` signature; callers expecting an empty body should
|
|
79
|
+
// type T as `null` or `void` (see HttpClient.test.ts for the convention).
|
|
66
80
|
const result = await this.parseBody(response);
|
|
67
81
|
return result;
|
|
68
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Run a fetch with an AbortController-based timeout.
|
|
85
|
+
* Throws ChatApiError(0, 'Timeout', ...) when the timeout fires before the
|
|
86
|
+
* response arrives. If `requestTimeoutMs` is null, fetch is used directly.
|
|
87
|
+
*/
|
|
88
|
+
async fetchWithTimeout(input, init) {
|
|
89
|
+
const timeoutMs = this.requestTimeoutMs;
|
|
90
|
+
if (timeoutMs === null) {
|
|
91
|
+
return fetch(input, init);
|
|
92
|
+
}
|
|
93
|
+
const controller = new AbortController();
|
|
94
|
+
// Use an explicit flag instead of `controller.signal.aborted` so a network
|
|
95
|
+
// error that races with the timer firing is not misclassified as a timeout.
|
|
96
|
+
let timedOut = false;
|
|
97
|
+
const timer = setTimeout(() => {
|
|
98
|
+
timedOut = true;
|
|
99
|
+
controller.abort();
|
|
100
|
+
}, timeoutMs);
|
|
101
|
+
try {
|
|
102
|
+
return await fetch(input, { ...init, signal: controller.signal });
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
if (timedOut) {
|
|
106
|
+
throw new ChatApiError(0, 'Timeout', `Request timed out after ${timeoutMs}ms`);
|
|
107
|
+
}
|
|
108
|
+
throw err;
|
|
109
|
+
}
|
|
110
|
+
finally {
|
|
111
|
+
clearTimeout(timer);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
69
114
|
// ---------------------------------------------------------------------------
|
|
70
115
|
// Public methods
|
|
71
116
|
// ---------------------------------------------------------------------------
|
|
72
117
|
async get(path, headers) {
|
|
73
|
-
const response = await
|
|
118
|
+
const response = await this.fetchWithTimeout(this.buildUrl(path), {
|
|
74
119
|
method: 'GET',
|
|
75
120
|
headers: { ...this.buildAuthHeader(), ...headers },
|
|
76
121
|
});
|
|
@@ -81,7 +126,7 @@ export class HttpClient {
|
|
|
81
126
|
* Unlike get<T>(), this does not attempt JSON parsing.
|
|
82
127
|
*/
|
|
83
128
|
async getText(path) {
|
|
84
|
-
const response = await
|
|
129
|
+
const response = await this.fetchWithTimeout(this.buildUrl(path), {
|
|
85
130
|
method: 'GET',
|
|
86
131
|
headers: { ...this.buildAuthHeader() },
|
|
87
132
|
});
|
|
@@ -91,7 +136,7 @@ export class HttpClient {
|
|
|
91
136
|
return response.text();
|
|
92
137
|
}
|
|
93
138
|
async post(path, body, headers) {
|
|
94
|
-
const response = await
|
|
139
|
+
const response = await this.fetchWithTimeout(this.buildUrl(path), {
|
|
95
140
|
method: 'POST',
|
|
96
141
|
headers: { ...this.buildHeaders(headers) },
|
|
97
142
|
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
@@ -99,17 +144,28 @@ export class HttpClient {
|
|
|
99
144
|
return this.handleResponse(response);
|
|
100
145
|
}
|
|
101
146
|
async patch(path, body, headers) {
|
|
102
|
-
const response = await
|
|
147
|
+
const response = await this.fetchWithTimeout(this.buildUrl(path), {
|
|
103
148
|
method: 'PATCH',
|
|
104
149
|
headers: { ...this.buildHeaders(headers) },
|
|
105
150
|
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
106
151
|
});
|
|
107
152
|
return this.handleResponse(response);
|
|
108
153
|
}
|
|
109
|
-
async
|
|
110
|
-
const response = await
|
|
154
|
+
async put(path, body, headers) {
|
|
155
|
+
const response = await this.fetchWithTimeout(this.buildUrl(path), {
|
|
156
|
+
method: 'PUT',
|
|
157
|
+
headers: { ...this.buildHeaders(headers) },
|
|
158
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
159
|
+
});
|
|
160
|
+
return this.handleResponse(response);
|
|
161
|
+
}
|
|
162
|
+
async delete(path, body, headers) {
|
|
163
|
+
const response = await this.fetchWithTimeout(this.buildUrl(path), {
|
|
111
164
|
method: 'DELETE',
|
|
112
|
-
headers:
|
|
165
|
+
headers: body !== undefined
|
|
166
|
+
? { ...this.buildHeaders(headers) }
|
|
167
|
+
: { ...this.buildAuthHeader(), ...headers },
|
|
168
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
113
169
|
});
|
|
114
170
|
return this.handleResponse(response);
|
|
115
171
|
}
|
|
@@ -118,7 +174,7 @@ export class HttpClient {
|
|
|
118
174
|
* (browser sets it with the boundary automatically).
|
|
119
175
|
*/
|
|
120
176
|
async postFormData(path, formData) {
|
|
121
|
-
const response = await
|
|
177
|
+
const response = await this.fetchWithTimeout(this.buildUrl(path), {
|
|
122
178
|
method: 'POST',
|
|
123
179
|
headers: { ...this.buildAuthHeader() },
|
|
124
180
|
body: formData,
|
|
@@ -134,6 +190,10 @@ export class HttpClient {
|
|
|
134
190
|
return new Promise((resolve, reject) => {
|
|
135
191
|
const xhr = new XMLHttpRequest();
|
|
136
192
|
xhr.open('POST', this.buildUrl(path));
|
|
193
|
+
// Apply per-request timeout (null disables it)
|
|
194
|
+
if (this.requestTimeoutMs !== null) {
|
|
195
|
+
xhr.timeout = this.requestTimeoutMs;
|
|
196
|
+
}
|
|
137
197
|
const token = this.tokenProvider();
|
|
138
198
|
if (token) {
|
|
139
199
|
xhr.setRequestHeader('Authorization', `Bearer ${token}`);
|
|
@@ -148,6 +208,7 @@ export class HttpClient {
|
|
|
148
208
|
xhr.onload = () => {
|
|
149
209
|
if (xhr.status >= 200 && xhr.status < 300) {
|
|
150
210
|
if (xhr.status === 204 || !xhr.responseText || xhr.responseText.trim() === '') {
|
|
211
|
+
// Empty body — same convention as fetch path: cast null to T.
|
|
151
212
|
resolve(null);
|
|
152
213
|
}
|
|
153
214
|
else {
|
|
@@ -160,20 +221,21 @@ export class HttpClient {
|
|
|
160
221
|
}
|
|
161
222
|
}
|
|
162
223
|
else {
|
|
163
|
-
// Build a minimal Response-like object to reuse ChatApiError.fromResponse
|
|
224
|
+
// Build a minimal Response-like object to reuse ChatApiError.fromResponse.
|
|
225
|
+
// Use `.then(reject, reject)` so a thrown error from the parser is also surfaced.
|
|
164
226
|
const syntheticResponse = new Response(xhr.responseText, {
|
|
165
227
|
status: xhr.status,
|
|
166
228
|
statusText: xhr.statusText,
|
|
167
229
|
headers: { 'Content-Type': 'application/json' },
|
|
168
230
|
});
|
|
169
|
-
ChatApiError.fromResponse(syntheticResponse).then(reject
|
|
231
|
+
ChatApiError.fromResponse(syntheticResponse).then(reject, reject);
|
|
170
232
|
}
|
|
171
233
|
};
|
|
172
234
|
xhr.onerror = () => {
|
|
173
235
|
reject(new ChatApiError(0, 'Network Error', 'Request failed due to a network error'));
|
|
174
236
|
};
|
|
175
237
|
xhr.ontimeout = () => {
|
|
176
|
-
reject(new ChatApiError(0, 'Timeout',
|
|
238
|
+
reject(new ChatApiError(0, 'Timeout', `Request timed out after ${xhr.timeout}ms`));
|
|
177
239
|
};
|
|
178
240
|
xhr.send(formData);
|
|
179
241
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HttpClient.js","sourceRoot":"","sources":["../../src/http/HttpClient.ts"],"names":[],"mappings":"AAAA,mDAAmD;AAEnD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"HttpClient.js","sourceRoot":"","sources":["../../src/http/HttpClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -50,7 +50,8 @@ export declare class MessageApi {
|
|
|
50
50
|
/**
|
|
51
51
|
* POST /api/messages/{messageId}/recover
|
|
52
52
|
* Recover a soft-deleted message. Only available within 10 minutes of deletion.
|
|
53
|
-
* Returns
|
|
53
|
+
* Returns 204 No Content. Call GET /api/messages/{messageId} afterwards if
|
|
54
|
+
* you need the recovered MessageDto.
|
|
54
55
|
*/
|
|
55
56
|
recover(messageId: string): Promise<void>;
|
|
56
57
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageApi.d.ts","sourceRoot":"","sources":["../../src/http/MessageApi.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"MessageApi.d.ts","sourceRoot":"","sources":["../../src/http/MessageApi.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAGhE;;;GAGG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;gBAEtB,IAAI,EAAE,UAAU;IAI5B;;;OAGG;IACH,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,CAAC;IAa9E;;;;;;;OAOG;IACH,UAAU,CACR,cAAc,EAAE,MAAM,EACtB,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,GAAG,OAAO,CAAA;KAAE,GAC1E,OAAO,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAW7C;;;OAGG;IACH,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAQpF,oCAAoC;IACpC,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAI/C;;;;OAIG;IACH,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,CAAC;IAWzE;;;OAGG;IACH,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAM5E;;;;;OAKG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC;;;OAGG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM5D;;;;OAIG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAKhE"}
|
package/dist/http/MessageApi.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// MessageApi.ts — Message operation endpoints
|
|
2
2
|
import { HttpClient } from './HttpClient.js';
|
|
3
|
+
import { normalizeBlocksForSend } from '../types/block.js';
|
|
3
4
|
/**
|
|
4
5
|
* Message API client.
|
|
5
6
|
* All endpoints require JWT Bearer token.
|
|
@@ -13,7 +14,13 @@ export class MessageApi {
|
|
|
13
14
|
* Send a new message. Returns 201 Created with the full MessageDto.
|
|
14
15
|
*/
|
|
15
16
|
send(conversationId, request) {
|
|
16
|
-
|
|
17
|
+
// Spec §6: `$type` must be the first property in each block when sent to
|
|
18
|
+
// the server, otherwise the polymorphic deserializer rejects the payload.
|
|
19
|
+
const normalized = {
|
|
20
|
+
...request,
|
|
21
|
+
blocks: normalizeBlocksForSend(request.blocks),
|
|
22
|
+
};
|
|
23
|
+
return this.http.post(`/api/conversations/${encodeURIComponent(conversationId)}/messages`, normalized);
|
|
17
24
|
}
|
|
18
25
|
/**
|
|
19
26
|
* GET /api/conversations/{conversationId}/messages?limit={limit}&cursor={cursor}&direction={direction}
|
|
@@ -54,7 +61,11 @@ export class MessageApi {
|
|
|
54
61
|
* NOTE: REST uses { blocks, mentions } — different from SignalR ChatEditMessageRequest.
|
|
55
62
|
*/
|
|
56
63
|
edit(messageId, request) {
|
|
57
|
-
|
|
64
|
+
const normalized = {
|
|
65
|
+
...request,
|
|
66
|
+
blocks: normalizeBlocksForSend(request.blocks),
|
|
67
|
+
};
|
|
68
|
+
return this.http.patch(`/api/messages/${encodeURIComponent(messageId)}`, normalized);
|
|
58
69
|
}
|
|
59
70
|
/**
|
|
60
71
|
* DELETE /api/messages/{messageId}
|
|
@@ -66,7 +77,8 @@ export class MessageApi {
|
|
|
66
77
|
/**
|
|
67
78
|
* POST /api/messages/{messageId}/recover
|
|
68
79
|
* Recover a soft-deleted message. Only available within 10 minutes of deletion.
|
|
69
|
-
* Returns
|
|
80
|
+
* Returns 204 No Content. Call GET /api/messages/{messageId} afterwards if
|
|
81
|
+
* you need the recovered MessageDto.
|
|
70
82
|
*/
|
|
71
83
|
recover(messageId) {
|
|
72
84
|
return this.http.post(`/api/messages/${encodeURIComponent(messageId)}/recover`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageApi.js","sourceRoot":"","sources":["../../src/http/MessageApi.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"MessageApi.js","sourceRoot":"","sources":["../../src/http/MessageApi.ts"],"names":[],"mappings":"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"}
|
package/dist/http/ProxyApi.d.ts
CHANGED
|
@@ -31,11 +31,27 @@ export declare class ProxyApi {
|
|
|
31
31
|
* GET /api/proxy/{target}/{url}
|
|
32
32
|
* Forward a GET request to the target service.
|
|
33
33
|
*/
|
|
34
|
-
get<T>(target: string, url: string): Promise<T>;
|
|
34
|
+
get<T>(target: string, url: string, headers?: Record<string, string>): Promise<T>;
|
|
35
35
|
/**
|
|
36
36
|
* POST /api/proxy/{target}/{url}
|
|
37
37
|
* Forward a POST request with an optional JSON body to the target service.
|
|
38
38
|
*/
|
|
39
|
-
post<T>(target: string, url: string, body?: unknown): Promise<T>;
|
|
39
|
+
post<T>(target: string, url: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
40
|
+
/**
|
|
41
|
+
* PUT /api/proxy/{target}/{url}
|
|
42
|
+
* Forward a PUT request with an optional JSON body to the target service.
|
|
43
|
+
*/
|
|
44
|
+
put<T>(target: string, url: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
45
|
+
/**
|
|
46
|
+
* PATCH /api/proxy/{target}/{url}
|
|
47
|
+
* Forward a PATCH request with an optional JSON body to the target service.
|
|
48
|
+
*/
|
|
49
|
+
patch<T>(target: string, url: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
50
|
+
/**
|
|
51
|
+
* DELETE /api/proxy/{target}/{url}
|
|
52
|
+
* Forward a DELETE request to the target service.
|
|
53
|
+
*/
|
|
54
|
+
delete<T>(target: string, url: string, headers?: Record<string, string>): Promise<T>;
|
|
55
|
+
private buildPath;
|
|
40
56
|
}
|
|
41
57
|
//# sourceMappingURL=ProxyApi.d.ts.map
|