turbodesk-livechat-react-native 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +91 -0
  3. package/dist/api/conversation-api.d.ts +16 -0
  4. package/dist/api/conversation-api.d.ts.map +1 -0
  5. package/dist/api/conversation-api.js +44 -0
  6. package/dist/api/conversation-api.js.map +1 -0
  7. package/dist/api/file-api.d.ts +5 -0
  8. package/dist/api/file-api.d.ts.map +1 -0
  9. package/dist/api/file-api.js +15 -0
  10. package/dist/api/file-api.js.map +1 -0
  11. package/dist/api/widget-api.d.ts +4 -0
  12. package/dist/api/widget-api.d.ts.map +1 -0
  13. package/dist/api/widget-api.js +15 -0
  14. package/dist/api/widget-api.js.map +1 -0
  15. package/dist/axios/axios.d.ts +32 -0
  16. package/dist/axios/axios.d.ts.map +1 -0
  17. package/dist/axios/axios.js +120 -0
  18. package/dist/axios/axios.js.map +1 -0
  19. package/dist/core/config.d.ts +17 -0
  20. package/dist/core/config.d.ts.map +1 -0
  21. package/dist/core/config.js +42 -0
  22. package/dist/core/config.js.map +1 -0
  23. package/dist/core/http-client.d.ts +33 -0
  24. package/dist/core/http-client.d.ts.map +1 -0
  25. package/dist/core/http-client.js +104 -0
  26. package/dist/core/http-client.js.map +1 -0
  27. package/dist/core/identity.d.ts +7 -0
  28. package/dist/core/identity.d.ts.map +1 -0
  29. package/dist/core/identity.js +62 -0
  30. package/dist/core/identity.js.map +1 -0
  31. package/dist/core/visitor-params.d.ts +15 -0
  32. package/dist/core/visitor-params.d.ts.map +1 -0
  33. package/dist/core/visitor-params.js +45 -0
  34. package/dist/core/visitor-params.js.map +1 -0
  35. package/dist/hooks/use-conversations.d.ts +12 -0
  36. package/dist/hooks/use-conversations.d.ts.map +1 -0
  37. package/dist/hooks/use-conversations.js +177 -0
  38. package/dist/hooks/use-conversations.js.map +1 -0
  39. package/dist/hooks/use-live-chat.d.ts +30 -0
  40. package/dist/hooks/use-live-chat.d.ts.map +1 -0
  41. package/dist/hooks/use-live-chat.js +52 -0
  42. package/dist/hooks/use-live-chat.js.map +1 -0
  43. package/dist/hooks/use-messages.d.ts +11 -0
  44. package/dist/hooks/use-messages.d.ts.map +1 -0
  45. package/dist/hooks/use-messages.js +185 -0
  46. package/dist/hooks/use-messages.js.map +1 -0
  47. package/dist/hooks/use-send-message.d.ts +22 -0
  48. package/dist/hooks/use-send-message.d.ts.map +1 -0
  49. package/dist/hooks/use-send-message.js +125 -0
  50. package/dist/hooks/use-send-message.js.map +1 -0
  51. package/dist/index.d.ts +49 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +97 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/navigation/LiveChatPanel.d.ts +5 -0
  56. package/dist/navigation/LiveChatPanel.d.ts.map +1 -0
  57. package/dist/navigation/LiveChatPanel.js +81 -0
  58. package/dist/navigation/LiveChatPanel.js.map +1 -0
  59. package/dist/navigation/panel-router-context.d.ts +22 -0
  60. package/dist/navigation/panel-router-context.d.ts.map +1 -0
  61. package/dist/navigation/panel-router-context.js +42 -0
  62. package/dist/navigation/panel-router-context.js.map +1 -0
  63. package/dist/navigation/router-types.d.ts +2 -0
  64. package/dist/navigation/router-types.d.ts.map +1 -0
  65. package/dist/navigation/router-types.js +3 -0
  66. package/dist/navigation/router-types.js.map +1 -0
  67. package/dist/provider/LiveChatContext.d.ts +4 -0
  68. package/dist/provider/LiveChatContext.d.ts.map +1 -0
  69. package/dist/provider/LiveChatContext.js +35 -0
  70. package/dist/provider/LiveChatContext.js.map +1 -0
  71. package/dist/provider/LiveChatProvider.d.ts +3 -0
  72. package/dist/provider/LiveChatProvider.d.ts.map +1 -0
  73. package/dist/provider/LiveChatProvider.js +308 -0
  74. package/dist/provider/LiveChatProvider.js.map +1 -0
  75. package/dist/provider/types.d.ts +42 -0
  76. package/dist/provider/types.d.ts.map +1 -0
  77. package/dist/provider/types.js +3 -0
  78. package/dist/provider/types.js.map +1 -0
  79. package/dist/realtime/ws-client.d.ts +51 -0
  80. package/dist/realtime/ws-client.d.ts.map +1 -0
  81. package/dist/realtime/ws-client.js +322 -0
  82. package/dist/realtime/ws-client.js.map +1 -0
  83. package/dist/ui/components/AssigneeAvatar.d.ts +12 -0
  84. package/dist/ui/components/AssigneeAvatar.d.ts.map +1 -0
  85. package/dist/ui/components/AssigneeAvatar.js +58 -0
  86. package/dist/ui/components/AssigneeAvatar.js.map +1 -0
  87. package/dist/ui/components/Avatar.d.ts +10 -0
  88. package/dist/ui/components/Avatar.d.ts.map +1 -0
  89. package/dist/ui/components/Avatar.js +76 -0
  90. package/dist/ui/components/Avatar.js.map +1 -0
  91. package/dist/ui/components/ConversationHeader.d.ts +10 -0
  92. package/dist/ui/components/ConversationHeader.d.ts.map +1 -0
  93. package/dist/ui/components/ConversationHeader.js +90 -0
  94. package/dist/ui/components/ConversationHeader.js.map +1 -0
  95. package/dist/ui/components/ConversationListScreen.d.ts +9 -0
  96. package/dist/ui/components/ConversationListScreen.d.ts.map +1 -0
  97. package/dist/ui/components/ConversationListScreen.js +350 -0
  98. package/dist/ui/components/ConversationListScreen.js.map +1 -0
  99. package/dist/ui/components/ConversationScreen.d.ts +8 -0
  100. package/dist/ui/components/ConversationScreen.d.ts.map +1 -0
  101. package/dist/ui/components/ConversationScreen.js +235 -0
  102. package/dist/ui/components/ConversationScreen.js.map +1 -0
  103. package/dist/ui/components/HomeScreen.d.ts +6 -0
  104. package/dist/ui/components/HomeScreen.d.ts.map +1 -0
  105. package/dist/ui/components/HomeScreen.js +133 -0
  106. package/dist/ui/components/HomeScreen.js.map +1 -0
  107. package/dist/ui/components/LivechatMessageRenderer.d.ts +17 -0
  108. package/dist/ui/components/LivechatMessageRenderer.d.ts.map +1 -0
  109. package/dist/ui/components/LivechatMessageRenderer.js +122 -0
  110. package/dist/ui/components/LivechatMessageRenderer.js.map +1 -0
  111. package/dist/ui/components/LogMessage.d.ts +5 -0
  112. package/dist/ui/components/LogMessage.d.ts.map +1 -0
  113. package/dist/ui/components/LogMessage.js +83 -0
  114. package/dist/ui/components/LogMessage.js.map +1 -0
  115. package/dist/ui/components/MessageBubble.d.ts +15 -0
  116. package/dist/ui/components/MessageBubble.d.ts.map +1 -0
  117. package/dist/ui/components/MessageBubble.js +84 -0
  118. package/dist/ui/components/MessageBubble.js.map +1 -0
  119. package/dist/ui/components/MessageComposer.d.ts +31 -0
  120. package/dist/ui/components/MessageComposer.d.ts.map +1 -0
  121. package/dist/ui/components/MessageComposer.js +295 -0
  122. package/dist/ui/components/MessageComposer.js.map +1 -0
  123. package/dist/ui/components/WsStatusStrip.d.ts +2 -0
  124. package/dist/ui/components/WsStatusStrip.d.ts.map +1 -0
  125. package/dist/ui/components/WsStatusStrip.js +103 -0
  126. package/dist/ui/components/WsStatusStrip.js.map +1 -0
  127. package/dist/ui/icons.d.ts +22 -0
  128. package/dist/ui/icons.d.ts.map +1 -0
  129. package/dist/ui/icons.js +71 -0
  130. package/dist/ui/icons.js.map +1 -0
  131. package/dist/ui/theme.d.ts +72 -0
  132. package/dist/ui/theme.d.ts.map +1 -0
  133. package/dist/ui/theme.js +170 -0
  134. package/dist/ui/theme.js.map +1 -0
  135. package/docs/backend-contract.md +392 -0
  136. package/docs/migration-notes.md +32 -0
  137. package/package.json +60 -0
  138. package/src/api/conversation-api.ts +71 -0
  139. package/src/api/file-api.ts +14 -0
  140. package/src/api/widget-api.ts +12 -0
  141. package/src/axios/axios.ts +159 -0
  142. package/src/core/config.ts +54 -0
  143. package/src/core/http-client.ts +136 -0
  144. package/src/core/identity.ts +68 -0
  145. package/src/core/visitor-params.ts +48 -0
  146. package/src/hooks/use-conversations.ts +181 -0
  147. package/src/hooks/use-live-chat.ts +84 -0
  148. package/src/hooks/use-messages.ts +188 -0
  149. package/src/hooks/use-send-message.ts +159 -0
  150. package/src/index.ts +114 -0
  151. package/src/navigation/LiveChatPanel.tsx +118 -0
  152. package/src/navigation/panel-router-context.tsx +89 -0
  153. package/src/navigation/router-types.ts +1 -0
  154. package/src/provider/LiveChatContext.ts +33 -0
  155. package/src/provider/LiveChatProvider.tsx +380 -0
  156. package/src/provider/types.ts +57 -0
  157. package/src/realtime/ws-client.ts +369 -0
  158. package/src/types/react-native-svg.d.ts +10 -0
  159. package/src/ui/components/AssigneeAvatar.tsx +102 -0
  160. package/src/ui/components/Avatar.tsx +110 -0
  161. package/src/ui/components/ConversationHeader.tsx +202 -0
  162. package/src/ui/components/ConversationListScreen.tsx +454 -0
  163. package/src/ui/components/ConversationScreen.tsx +362 -0
  164. package/src/ui/components/HomeScreen.tsx +278 -0
  165. package/src/ui/components/LivechatMessageRenderer.tsx +268 -0
  166. package/src/ui/components/LogMessage.tsx +88 -0
  167. package/src/ui/components/MessageBubble.tsx +148 -0
  168. package/src/ui/components/MessageComposer.tsx +461 -0
  169. package/src/ui/components/WsStatusStrip.tsx +123 -0
  170. package/src/ui/icons.tsx +111 -0
  171. package/src/ui/theme.ts +237 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,30 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@turbodev/livechat-react-native` will be documented in this file.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
6
+ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+ A breaking API change = major bump.
8
+
9
+ ---
10
+
11
+ ## [Unreleased]
12
+
13
+ ## [0.1.0-alpha.0] — 2026-05-02
14
+
15
+ ### Added
16
+ - **LiveChatProvider** — root context provider with widgetId, apiBaseUrl, userToken, authCallback, visitorProfile, theme props
17
+ - **Core HTTP client** — native fetch wrapper with Bearer auth, 401 token refresh, 403 handling
18
+ - **WsClient** — WebSocket class with exponential backoff (1 s → 30 s), subscribe/unsubscribe, wildcard (*) support, AppState + NetInfo lifecycle hooks
19
+ - **API layer** — widgetApi (widget config), conversationApi (list/get/messages/send/markRead/unread), fileApi (presign)
20
+ - **Identity module** — anonymous device userId via AsyncStorage with UUID generation fallback
21
+ - **useLiveChat** — connection state, unread count, open/close, show/hide, setToken, logout
22
+ - **useConversations** — paginated list, real-time WS merge (new message, intervened, resolved, unassigned, transferred)
23
+ - **useMessages** — paginated messages, load older, real-time append, markAsRead
24
+ - **useSendMessage** — send text or attachment, returns conversationId (new conversation support)
25
+ - **UI Kit** — ConversationListScreen, ConversationScreen, ConversationHeader, MessageBubble, MessageComposer, Avatar
26
+ - **Theme system** — ThemeConfig with colors/fontSizes/spacing/borderRadius, mergeTheme helper
27
+ - **Example app** — Guest mode + Token mode demo with navigation
28
+
29
+ ### Notes
30
+ - v0.1.0-alpha: core + hooks + basic UI kit. APIs may change before v1.0.
package/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # turbodesk-livechat-react-native
2
+
3
+ A React Native SDK for embedding live chat into any mobile app. Uses the same backend as the web widget (`turbodev-livchat-widget`) — same REST endpoints, same WebSocket events.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install turbodesk-livechat-react-native
9
+ # peer deps
10
+ npm install @react-native-async-storage/async-storage @react-native-community/netinfo
11
+ ```
12
+
13
+ ## Quick start
14
+
15
+ ```tsx
16
+ import { LiveChatProvider, ConversationListScreen, ConversationScreen } from "turbodesk-livechat-react-native";
17
+
18
+ export default function App() {
19
+ return (
20
+ <LiveChatProvider widgetId="your-widget-id" apiBaseUrl="https://api.example.com">
21
+ <YourNavigator />
22
+ </LiveChatProvider>
23
+ );
24
+ }
25
+ ```
26
+
27
+ ### Use ready-made screens
28
+
29
+ ```tsx
30
+ // In your navigator:
31
+ <Stack.Screen name="ChatList" component={ConversationListScreen} />
32
+ <Stack.Screen name="Chat" component={ConversationScreen} />
33
+ ```
34
+
35
+ ### Use headless hooks (custom UI)
36
+
37
+ ```tsx
38
+ import { useConversations, useMessages, useSendMessage } from "turbodesk-livechat-react-native";
39
+
40
+ function MyChatList() {
41
+ const { list, loading, refresh } = useConversations();
42
+ // render your own UI
43
+ }
44
+ ```
45
+
46
+ ### Auth refresh (token mode)
47
+
48
+ ```tsx
49
+ <LiveChatProvider
50
+ widgetId="..."
51
+ apiBaseUrl="..."
52
+ userToken={myToken}
53
+ authCallback={async () => {
54
+ const fresh = await refreshMyToken();
55
+ return fresh;
56
+ }}
57
+ >
58
+ ```
59
+
60
+ ## Provider props
61
+
62
+ | Prop | Type | Required | Description |
63
+ |---|---|---|---|
64
+ | `widgetId` | `string` | Yes | Widget identifier from the dashboard |
65
+ | `apiBaseUrl` | `string` | Yes | Base URL of your backend (no trailing slash) |
66
+ | `userId` | `string` | No | Optional stable user id (guest mode) |
67
+ | `userToken` | `string` | No | JWT / session token for authenticated users |
68
+ | `authCallback` | `() => Promise<string \| null>` | No | Called on 401 to refresh the token |
69
+ | `visitorProfile` | `{ name?, email?, phone? }` | No | Pre-fill visitor metadata |
70
+ | `theme` | `ThemeConfig` | No | Override default theme colors/spacing |
71
+
72
+ ## Hooks
73
+
74
+ - `useLiveChat()` — connection state, unread count, open/close, setToken, logout
75
+ - `useConversations()` — paginated conversation list + real-time updates
76
+ - `useMessages(conversationId)` — message list, load older, real-time append
77
+ - `useSendMessage()` — send text or attachment
78
+
79
+ ## Troubleshooting
80
+
81
+ **WebSocket not connecting** — Check `apiBaseUrl` is `https://` (SDK converts to `wss://` automatically). Ensure the server allows the widget origin.
82
+
83
+ **CORS errors** — REST calls are made from the mobile device, not a browser, so CORS doesn't apply. If you see network errors, verify `apiBaseUrl` is reachable from the device.
84
+
85
+ **Invalid widgetId** — The SDK will log a warning and show `embedLoadState = "error"`. Double-check the widgetId from your dashboard.
86
+
87
+ **Unread count stuck** — Make sure `markAsRead` is called when the user opens a conversation (the UI screens do this automatically).
88
+
89
+ ## Release notes
90
+
91
+ See [CHANGELOG.md](./CHANGELOG.md).
@@ -0,0 +1,16 @@
1
+ import { type RequestOptions } from "../axios/axios";
2
+ export declare const conversationApi: {
3
+ getConversationCount: (params?: RequestOptions["params"]) => Promise<any>;
4
+ getTotalUnread: (options?: RequestOptions) => Promise<any>;
5
+ getConversations: (options?: RequestOptions) => Promise<any>;
6
+ getConversation: (conversationId: string, options?: RequestOptions) => Promise<any>;
7
+ /**
8
+ * Visitor message entrypoint (`POST /api/v1/livechat/messages`).
9
+ * If `conversationId` is absent in the body, the server creates a new conversation
10
+ * for the resolved contact.
11
+ */
12
+ sendVisitorMessage: (data: any, options?: RequestOptions) => Promise<any>;
13
+ getMessages: (conversationId: string, options?: RequestOptions) => Promise<any>;
14
+ markMessageAsRead: (conversationId: string, options?: RequestOptions) => Promise<any>;
15
+ };
16
+ //# sourceMappingURL=conversation-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation-api.d.ts","sourceRoot":"","sources":["../../src/api/conversation-api.ts"],"names":[],"mappings":"AAAA,OAAqB,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAInE,eAAO,MAAM,eAAe;oCACY,cAAc,CAAC,QAAQ,CAAC;+BAQ7B,cAAc;iCAQZ,cAAc;sCAQT,MAAM,YAAY,cAAc;IAQxE;;;;OAIG;+BAC8B,GAAG,YAAY,cAAc;kCAS1B,MAAM,YAAY,cAAc;wCASlD,MAAM,YACZ,cAAc;CAS3B,CAAC"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.conversationApi = void 0;
7
+ const axios_1 = __importDefault(require("../axios/axios"));
8
+ const apiClient = (0, axios_1.default)();
9
+ exports.conversationApi = {
10
+ getConversationCount: async (params) => {
11
+ const response = await apiClient.get(`api/v1/livechat/conversations/count`, params ? { params } : undefined);
12
+ return response.data;
13
+ },
14
+ getTotalUnread: async (options) => {
15
+ const response = await apiClient.get(`api/v1/livechat/unread`, options);
16
+ return response.data;
17
+ },
18
+ getConversations: async (options) => {
19
+ const response = await apiClient.get(`api/v1/livechat/conversations`, options);
20
+ return response.data;
21
+ },
22
+ getConversation: async (conversationId, options) => {
23
+ const response = await apiClient.get(`api/v1/livechat/conversations/${conversationId}`, options);
24
+ return response.data;
25
+ },
26
+ /**
27
+ * Visitor message entrypoint (`POST /api/v1/livechat/messages`).
28
+ * If `conversationId` is absent in the body, the server creates a new conversation
29
+ * for the resolved contact.
30
+ */
31
+ sendVisitorMessage: async (data, options) => {
32
+ const response = await apiClient.post(`api/v1/livechat/messages`, data, options);
33
+ return response.data;
34
+ },
35
+ getMessages: async (conversationId, options) => {
36
+ const response = await apiClient.get(`api/v1/livechat/conversations/${conversationId}/messages`, options);
37
+ return response.data;
38
+ },
39
+ markMessageAsRead: async (conversationId, options) => {
40
+ const response = await apiClient.put(`api/v1/livechat/conversations/${conversationId}/read`, {}, options);
41
+ return response.data;
42
+ },
43
+ };
44
+ //# sourceMappingURL=conversation-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation-api.js","sourceRoot":"","sources":["../../src/api/conversation-api.ts"],"names":[],"mappings":";;;;;;AAAA,2DAAmE;AAEnE,MAAM,SAAS,GAAG,IAAA,eAAY,GAAE,CAAC;AAEpB,QAAA,eAAe,GAAG;IAC7B,oBAAoB,EAAE,KAAK,EAAE,MAAiC,EAAE,EAAE;QAChE,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,CAClC,qCAAqC,EACrC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAChC,CAAC;QACF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,cAAc,EAAE,KAAK,EAAE,OAAwB,EAAE,EAAE;QACjD,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,CAClC,wBAAwB,EACxB,OAAO,CACR,CAAC;QACF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,gBAAgB,EAAE,KAAK,EAAE,OAAwB,EAAE,EAAE;QACnD,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,CAClC,+BAA+B,EAC/B,OAAO,CACR,CAAC;QACF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,eAAe,EAAE,KAAK,EAAE,cAAsB,EAAE,OAAwB,EAAE,EAAE;QAC1E,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,CAClC,iCAAiC,cAAc,EAAE,EACjD,OAAO,CACR,CAAC;QACF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED;;;;OAIG;IACH,kBAAkB,EAAE,KAAK,EAAE,IAAS,EAAE,OAAwB,EAAE,EAAE;QAChE,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,IAAI,CACnC,0BAA0B,EAC1B,IAAI,EACJ,OAAO,CACR,CAAC;QACF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,WAAW,EAAE,KAAK,EAAE,cAAsB,EAAE,OAAwB,EAAE,EAAE;QACtE,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,CAClC,iCAAiC,cAAc,WAAW,EAC1D,OAAO,CACR,CAAC;QACF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,iBAAiB,EAAE,KAAK,EACtB,cAAsB,EACtB,OAAwB,EACxB,EAAE;QACF,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,CAClC,iCAAiC,cAAc,OAAO,EACtD,EAAE,EACF,OAAO,CACR,CAAC;QACF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;CACF,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { type RequestOptions } from "../axios/axios";
2
+ export declare const fileApi: {
3
+ getFileUrl: (params: any, options?: RequestOptions) => Promise<unknown>;
4
+ };
5
+ //# sourceMappingURL=file-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-api.d.ts","sourceRoot":"","sources":["../../src/api/file-api.ts"],"names":[],"mappings":"AAAA,OAAqB,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAInE,eAAO,MAAM,OAAO;yBACS,GAAG,YAAY,cAAc;CAQzD,CAAC"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.fileApi = void 0;
7
+ const axios_1 = __importDefault(require("../axios/axios"));
8
+ const apiClient = (0, axios_1.default)();
9
+ exports.fileApi = {
10
+ getFileUrl: async (params, options) => {
11
+ const response = await apiClient.post(`/api/v1/livechat/files/presign`, params, options);
12
+ return response.data;
13
+ },
14
+ };
15
+ //# sourceMappingURL=file-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-api.js","sourceRoot":"","sources":["../../src/api/file-api.ts"],"names":[],"mappings":";;;;;;AAAA,2DAAmE;AAEnE,MAAM,SAAS,GAAG,IAAA,eAAY,GAAE,CAAC;AAEpB,QAAA,OAAO,GAAG;IACrB,UAAU,EAAE,KAAK,EAAE,MAAW,EAAE,OAAwB,EAAE,EAAE;QAC1D,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,IAAI,CACnC,gCAAgC,EAChC,MAAM,EACN,OAAO,CACR,CAAC;QACF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;CACF,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare const widgetApi: {
2
+ getWidget: (widgetId: string) => Promise<any>;
3
+ };
4
+ //# sourceMappingURL=widget-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget-api.d.ts","sourceRoot":"","sources":["../../src/api/widget-api.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,SAAS;0BACQ,MAAM;CAMnC,CAAC"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.widgetApi = void 0;
7
+ const axios_1 = __importDefault(require("../axios/axios"));
8
+ const apiClient = (0, axios_1.default)();
9
+ exports.widgetApi = {
10
+ getWidget: async (widgetId) => {
11
+ const response = await apiClient.get(`api/v1/public/livechat/${widgetId}/config`);
12
+ return response.data;
13
+ },
14
+ };
15
+ //# sourceMappingURL=widget-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget-api.js","sourceRoot":"","sources":["../../src/api/widget-api.ts"],"names":[],"mappings":";;;;;;AAAA,2DAA0C;AAE1C,MAAM,SAAS,GAAG,IAAA,eAAY,GAAE,CAAC;AAEpB,QAAA,SAAS,GAAG;IACvB,SAAS,EAAE,KAAK,EAAE,QAAgB,EAAE,EAAE;QACpC,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,CAClC,0BAA0B,QAAQ,SAAS,CAC5C,CAAC;QACF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;CACF,CAAC"}
@@ -0,0 +1,32 @@
1
+ export declare function setApiBaseUrl(url: string): void;
2
+ export declare function getApiBaseUrl(): string;
3
+ export declare function setTokenGetter(fn: () => string | null | undefined): void;
4
+ export type RequestOptions = {
5
+ headers?: Record<string, string>;
6
+ params?: Record<string, string | number | boolean | undefined | null>;
7
+ signal?: AbortSignal;
8
+ };
9
+ type AuthRefreshFn = () => Promise<string | null | undefined>;
10
+ type OnTokenRefreshedFn = (token: string | null | undefined) => void;
11
+ export declare function registerAuthRefresh(callback: AuthRefreshFn, onTokenRefreshed: OnTokenRefreshedFn): void;
12
+ export declare function unregisterAuthRefresh(): void;
13
+ export type ApiClient = {
14
+ get: <T>(path: string, options?: RequestOptions) => Promise<{
15
+ data: T;
16
+ }>;
17
+ post: <T>(path: string, body?: unknown, options?: RequestOptions) => Promise<{
18
+ data: T;
19
+ }>;
20
+ put: <T>(path: string, body?: unknown, options?: RequestOptions) => Promise<{
21
+ data: T;
22
+ }>;
23
+ patch: <T>(path: string, body?: unknown, options?: RequestOptions) => Promise<{
24
+ data: T;
25
+ }>;
26
+ delete: <T>(path: string, options?: RequestOptions) => Promise<{
27
+ data: T;
28
+ }>;
29
+ };
30
+ declare const getApiClient: () => ApiClient;
31
+ export default getApiClient;
32
+ //# sourceMappingURL=axios.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"axios.d.ts","sourceRoot":"","sources":["../../src/axios/axios.ts"],"names":[],"mappings":"AAGA,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,QAExC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,QAEjE;AAQD,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC;IACtE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAgCF,KAAK,aAAa,GAAG,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAC9D,KAAK,kBAAkB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,KAAK,IAAI,CAAC;AAKrE,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,aAAa,EACvB,gBAAgB,EAAE,kBAAkB,QAIrC;AAED,wBAAgB,qBAAqB,SAGpC;AAkED,MAAM,MAAM,SAAS,GAAG;IACtB,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IACzE,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IAC1F,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IACzF,KAAK,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IAC3F,MAAM,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;CAC7E,CAAC;AAUF,QAAA,MAAM,YAAY,QAAO,SAAmB,CAAC;AAE7C,eAAe,YAAY,CAAC"}
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setApiBaseUrl = setApiBaseUrl;
4
+ exports.getApiBaseUrl = getApiBaseUrl;
5
+ exports.setTokenGetter = setTokenGetter;
6
+ exports.registerAuthRefresh = registerAuthRefresh;
7
+ exports.unregisterAuthRefresh = unregisterAuthRefresh;
8
+ let _apiBaseUrl = "";
9
+ let _getToken = null;
10
+ function setApiBaseUrl(url) {
11
+ _apiBaseUrl = url.replace(/\/+$/, "");
12
+ }
13
+ function getApiBaseUrl() {
14
+ return _apiBaseUrl;
15
+ }
16
+ function setTokenGetter(fn) {
17
+ _getToken = fn;
18
+ }
19
+ const joinUrl = (baseURL, path) => {
20
+ const base = baseURL.replace(/\/+$/, "");
21
+ const p = path.replace(/^\/+/, "");
22
+ return `${base}/${p}`;
23
+ };
24
+ const appendSearchParams = (absoluteUrl, params) => {
25
+ if (!params)
26
+ return absoluteUrl;
27
+ const entries = Object.entries(params).filter(([, v]) => v !== undefined && v !== null);
28
+ if (entries.length === 0)
29
+ return absoluteUrl;
30
+ const sep = absoluteUrl.includes("?") ? "&" : "?";
31
+ const qs = entries
32
+ .map(([k, v]) => encodeURIComponent(k) + "=" + encodeURIComponent(String(v)))
33
+ .join("&");
34
+ return absoluteUrl + sep + qs;
35
+ };
36
+ const parseBody = async (res) => {
37
+ var _a;
38
+ const ct = (_a = res.headers.get("content-type")) !== null && _a !== void 0 ? _a : "";
39
+ if (ct.includes("application/json")) {
40
+ const text = await res.text();
41
+ if (!text)
42
+ return null;
43
+ try {
44
+ return JSON.parse(text);
45
+ }
46
+ catch {
47
+ return text;
48
+ }
49
+ }
50
+ return res.text();
51
+ };
52
+ let _authRefreshCallback = null;
53
+ let _onTokenRefreshed = null;
54
+ function registerAuthRefresh(callback, onTokenRefreshed) {
55
+ _authRefreshCallback = callback;
56
+ _onTokenRefreshed = onTokenRefreshed;
57
+ }
58
+ function unregisterAuthRefresh() {
59
+ _authRefreshCallback = null;
60
+ _onTokenRefreshed = null;
61
+ }
62
+ async function request(method, path, body, options, isRetry = false) {
63
+ var _a;
64
+ const baseURL = getApiBaseUrl();
65
+ const url = appendSearchParams(joinUrl(baseURL, path), options === null || options === void 0 ? void 0 : options.params);
66
+ const token = (_a = _getToken === null || _getToken === void 0 ? void 0 : _getToken()) !== null && _a !== void 0 ? _a : null;
67
+ const headers = {
68
+ Accept: "application/json",
69
+ ...options === null || options === void 0 ? void 0 : options.headers,
70
+ };
71
+ if (token !== null) {
72
+ headers.Authorization = `Bearer ${token}`;
73
+ }
74
+ if (body !== undefined && method !== "GET" && method !== "DELETE") {
75
+ headers["Content-Type"] = "application/json";
76
+ }
77
+ let res;
78
+ try {
79
+ res = await fetch(url, {
80
+ method,
81
+ headers,
82
+ signal: options === null || options === void 0 ? void 0 : options.signal,
83
+ body: body !== undefined && method !== "GET" && method !== "DELETE"
84
+ ? JSON.stringify(body)
85
+ : undefined,
86
+ });
87
+ }
88
+ catch {
89
+ throw Object.assign(new Error("Network error"), {
90
+ response: { status: 0, data: null },
91
+ });
92
+ }
93
+ if (res.status === 401 && !isRetry && _authRefreshCallback) {
94
+ const newToken = await _authRefreshCallback();
95
+ _onTokenRefreshed === null || _onTokenRefreshed === void 0 ? void 0 : _onTokenRefreshed(newToken !== null && newToken !== void 0 ? newToken : null);
96
+ return request(method, path, body, options, true);
97
+ }
98
+ if (res.status === 401 || res.status === 403) {
99
+ throw Object.assign(new Error(res.status === 401 ? "Unauthorized" : "Forbidden"), {
100
+ response: { status: res.status, data: null },
101
+ });
102
+ }
103
+ const data = (await parseBody(res));
104
+ if (!res.ok) {
105
+ throw Object.assign(new Error(`HTTP ${res.status}`), {
106
+ response: { status: res.status, data },
107
+ });
108
+ }
109
+ return { data };
110
+ }
111
+ const client = {
112
+ get: (path, options) => request("GET", path, undefined, options),
113
+ post: (path, body, options) => request("POST", path, body, options),
114
+ put: (path, body, options) => request("PUT", path, body, options),
115
+ patch: (path, body, options) => request("PATCH", path, body, options),
116
+ delete: (path, options) => request("DELETE", path, undefined, options),
117
+ };
118
+ const getApiClient = () => client;
119
+ exports.default = getApiClient;
120
+ //# sourceMappingURL=axios.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"axios.js","sourceRoot":"","sources":["../../src/axios/axios.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { LiveChatProviderProps } from "../provider/types";
2
+ export type RuntimeConfig = {
3
+ widgetId: string;
4
+ apiBaseUrl: string;
5
+ userId?: string;
6
+ userToken?: string;
7
+ authCallback?: () => Promise<string | null | undefined>;
8
+ visitorProfile?: {
9
+ name?: string;
10
+ email?: string;
11
+ phone?: string;
12
+ };
13
+ };
14
+ export declare function normalizeBaseUrl(url: string): string;
15
+ export declare function buildWsBaseUrl(apiBaseUrl: string): string;
16
+ export declare function resolveConfig(props: LiveChatProviderProps): Promise<RuntimeConfig>;
17
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG/D,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACxD,cAAc,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACpE,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAIzD;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,aAAa,CAAC,CA6BxB"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeBaseUrl = normalizeBaseUrl;
4
+ exports.buildWsBaseUrl = buildWsBaseUrl;
5
+ exports.resolveConfig = resolveConfig;
6
+ const identity_1 = require("./identity");
7
+ function normalizeBaseUrl(url) {
8
+ return url.replace(/\/+$/, "");
9
+ }
10
+ function buildWsBaseUrl(apiBaseUrl) {
11
+ return normalizeBaseUrl(apiBaseUrl)
12
+ .replace(/^https:\/\//i, "wss://")
13
+ .replace(/^http:\/\//i, "ws://");
14
+ }
15
+ async function resolveConfig(props) {
16
+ var _a, _b, _c, _d, _e;
17
+ const widgetId = (_a = props.widgetId) === null || _a === void 0 ? void 0 : _a.trim();
18
+ if (!widgetId)
19
+ throw new Error("[LiveChat] widgetId is required");
20
+ const base = normalizeBaseUrl(props.apiBaseUrl);
21
+ const token = (_b = props.userToken) === null || _b === void 0 ? void 0 : _b.trim();
22
+ if (token) {
23
+ return {
24
+ widgetId,
25
+ apiBaseUrl: base,
26
+ userId: (_d = (_c = props.userId) === null || _c === void 0 ? void 0 : _c.trim()) !== null && _d !== void 0 ? _d : "",
27
+ userToken: token,
28
+ authCallback: props.authCallback,
29
+ visitorProfile: props.visitorProfile,
30
+ };
31
+ }
32
+ const userId = ((_e = props.userId) === null || _e === void 0 ? void 0 : _e.trim()) || (await (0, identity_1.getOrCreateDeviceUserId)(widgetId));
33
+ return {
34
+ widgetId,
35
+ apiBaseUrl: base,
36
+ userId,
37
+ userToken: undefined,
38
+ authCallback: props.authCallback,
39
+ visitorProfile: props.visitorProfile,
40
+ };
41
+ }
42
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":";;AAYA,4CAEC;AAED,wCAIC;AAED,sCA+BC;AApDD,yCAAqD;AAWrD,SAAgB,gBAAgB,CAAC,GAAW;IAC1C,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACjC,CAAC;AAED,SAAgB,cAAc,CAAC,UAAkB;IAC/C,OAAO,gBAAgB,CAAC,UAAU,CAAC;SAChC,OAAO,CAAC,cAAc,EAAE,QAAQ,CAAC;SACjC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;AACrC,CAAC;AAEM,KAAK,UAAU,aAAa,CACjC,KAA4B;;IAE5B,MAAM,QAAQ,GAAG,MAAA,KAAK,CAAC,QAAQ,0CAAE,IAAI,EAAE,CAAC;IACxC,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IAElE,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,MAAA,KAAK,CAAC,SAAS,0CAAE,IAAI,EAAE,CAAC;IAEtC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO;YACL,QAAQ;YACR,UAAU,EAAE,IAAI;YAChB,MAAM,EAAE,MAAA,MAAA,KAAK,CAAC,MAAM,0CAAE,IAAI,EAAE,mCAAI,EAAE;YAClC,SAAS,EAAE,KAAK;YAChB,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,cAAc,EAAE,KAAK,CAAC,cAAc;SACrC,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GACV,CAAA,MAAA,KAAK,CAAC,MAAM,0CAAE,IAAI,EAAE,KAAI,CAAC,MAAM,IAAA,kCAAuB,EAAC,QAAQ,CAAC,CAAC,CAAC;IAEpE,OAAO;QACL,QAAQ;QACR,UAAU,EAAE,IAAI;QAChB,MAAM;QACN,SAAS,EAAE,SAAS;QACpB,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,cAAc,EAAE,KAAK,CAAC,cAAc;KACrC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,33 @@
1
+ export type RequestOptions = {
2
+ headers?: Record<string, string>;
3
+ params?: Record<string, string | number | boolean | undefined | null>;
4
+ signal?: AbortSignal;
5
+ };
6
+ type AuthRefreshFn = () => Promise<string | null | undefined>;
7
+ type OnTokenRefreshedFn = (token: string | null | undefined) => void;
8
+ export declare function configureHttpClient(opts: {
9
+ apiBaseUrl: string;
10
+ getToken: () => string | null | undefined;
11
+ }): void;
12
+ export declare function registerAuthRefresh(callback: AuthRefreshFn, onTokenRefreshed: OnTokenRefreshedFn): void;
13
+ export declare function unregisterAuthRefresh(): void;
14
+ export type ApiClient = {
15
+ get: <T>(path: string, options?: RequestOptions) => Promise<{
16
+ data: T;
17
+ }>;
18
+ post: <T>(path: string, body?: unknown, options?: RequestOptions) => Promise<{
19
+ data: T;
20
+ }>;
21
+ put: <T>(path: string, body?: unknown, options?: RequestOptions) => Promise<{
22
+ data: T;
23
+ }>;
24
+ patch: <T>(path: string, body?: unknown, options?: RequestOptions) => Promise<{
25
+ data: T;
26
+ }>;
27
+ delete: <T>(path: string, options?: RequestOptions) => Promise<{
28
+ data: T;
29
+ }>;
30
+ };
31
+ export declare const apiClient: ApiClient;
32
+ export {};
33
+ //# sourceMappingURL=http-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../src/core/http-client.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC;IACtE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,KAAK,aAAa,GAAG,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAC9D,KAAK,kBAAkB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,KAAK,IAAI,CAAC;AAOrE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CAC3C,GAAG,IAAI,CAGP;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,aAAa,EACvB,gBAAgB,EAAE,kBAAkB,GACnC,IAAI,CAGN;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C;AAwFD,MAAM,MAAM,SAAS,GAAG;IACtB,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IACzE,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IAC1F,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IACzF,KAAK,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IAC3F,MAAM,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;CAC7E,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,SAMvB,CAAC"}
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.apiClient = void 0;
4
+ exports.configureHttpClient = configureHttpClient;
5
+ exports.registerAuthRefresh = registerAuthRefresh;
6
+ exports.unregisterAuthRefresh = unregisterAuthRefresh;
7
+ let _apiBaseUrl = "";
8
+ let _getToken = null;
9
+ let _authRefreshCallback = null;
10
+ let _onTokenRefreshed = null;
11
+ function configureHttpClient(opts) {
12
+ _apiBaseUrl = opts.apiBaseUrl.replace(/\/+$/, "");
13
+ _getToken = opts.getToken;
14
+ }
15
+ function registerAuthRefresh(callback, onTokenRefreshed) {
16
+ _authRefreshCallback = callback;
17
+ _onTokenRefreshed = onTokenRefreshed;
18
+ }
19
+ function unregisterAuthRefresh() {
20
+ _authRefreshCallback = null;
21
+ _onTokenRefreshed = null;
22
+ }
23
+ function joinUrl(base, p) {
24
+ return base.replace(/\/+$/, "") + "/" + p.replace(/^\/+/, "");
25
+ }
26
+ function appendSearchParams(absoluteUrl, params) {
27
+ if (!params)
28
+ return absoluteUrl;
29
+ const entries = Object.entries(params).filter(([, v]) => v !== undefined && v !== null);
30
+ if (entries.length === 0)
31
+ return absoluteUrl;
32
+ const sep = absoluteUrl.includes("?") ? "&" : "?";
33
+ const qs = entries
34
+ .map(([k, v]) => encodeURIComponent(k) + "=" + encodeURIComponent(String(v)))
35
+ .join("&");
36
+ return absoluteUrl + sep + qs;
37
+ }
38
+ async function parseBody(res) {
39
+ var _a;
40
+ const ct = (_a = res.headers.get("content-type")) !== null && _a !== void 0 ? _a : "";
41
+ if (ct.includes("application/json")) {
42
+ const text = await res.text();
43
+ if (!text)
44
+ return null;
45
+ try {
46
+ return JSON.parse(text);
47
+ }
48
+ catch {
49
+ return text;
50
+ }
51
+ }
52
+ return res.text();
53
+ }
54
+ async function doRequest(method, path, body, options, isRetry) {
55
+ var _a;
56
+ const baseURL = _apiBaseUrl;
57
+ const url = appendSearchParams(joinUrl(baseURL, path), options === null || options === void 0 ? void 0 : options.params);
58
+ const token = (_a = _getToken === null || _getToken === void 0 ? void 0 : _getToken()) !== null && _a !== void 0 ? _a : null;
59
+ const headers = {
60
+ Accept: "application/json",
61
+ ...options === null || options === void 0 ? void 0 : options.headers,
62
+ };
63
+ if (token)
64
+ headers.Authorization = "Bearer " + token;
65
+ if (body !== undefined && method !== "GET" && method !== "DELETE") {
66
+ headers["Content-Type"] = "application/json";
67
+ }
68
+ let res;
69
+ try {
70
+ res = await fetch(url, {
71
+ method,
72
+ headers,
73
+ signal: options === null || options === void 0 ? void 0 : options.signal,
74
+ body: body !== undefined && method !== "GET" && method !== "DELETE"
75
+ ? JSON.stringify(body) : undefined,
76
+ });
77
+ }
78
+ catch {
79
+ const err = Object.assign(new Error("Network error"), { response: { status: 0, data: null } });
80
+ throw err;
81
+ }
82
+ if (res.status === 401 && !isRetry && _authRefreshCallback) {
83
+ const newToken = await _authRefreshCallback();
84
+ _onTokenRefreshed === null || _onTokenRefreshed === void 0 ? void 0 : _onTokenRefreshed(newToken !== null && newToken !== void 0 ? newToken : null);
85
+ return doRequest(method, path, body, options, true);
86
+ }
87
+ if (res.status === 401 || res.status === 403) {
88
+ const msg = res.status === 401 ? "Unauthorized" : "Forbidden";
89
+ throw Object.assign(new Error(msg), { response: { status: res.status, data: null } });
90
+ }
91
+ const data = (await parseBody(res));
92
+ if (!res.ok) {
93
+ throw Object.assign(new Error("HTTP " + res.status), { response: { status: res.status, data } });
94
+ }
95
+ return { data };
96
+ }
97
+ exports.apiClient = {
98
+ get: (path, options) => doRequest("GET", path, undefined, options, false),
99
+ post: (path, body, options) => doRequest("POST", path, body, options, false),
100
+ put: (path, body, options) => doRequest("PUT", path, body, options, false),
101
+ patch: (path, body, options) => doRequest("PATCH", path, body, options, false),
102
+ delete: (path, options) => doRequest("DELETE", path, undefined, options, false),
103
+ };
104
+ //# sourceMappingURL=http-client.js.map