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.
- package/CHANGELOG.md +30 -0
- package/README.md +91 -0
- package/dist/api/conversation-api.d.ts +16 -0
- package/dist/api/conversation-api.d.ts.map +1 -0
- package/dist/api/conversation-api.js +44 -0
- package/dist/api/conversation-api.js.map +1 -0
- package/dist/api/file-api.d.ts +5 -0
- package/dist/api/file-api.d.ts.map +1 -0
- package/dist/api/file-api.js +15 -0
- package/dist/api/file-api.js.map +1 -0
- package/dist/api/widget-api.d.ts +4 -0
- package/dist/api/widget-api.d.ts.map +1 -0
- package/dist/api/widget-api.js +15 -0
- package/dist/api/widget-api.js.map +1 -0
- package/dist/axios/axios.d.ts +32 -0
- package/dist/axios/axios.d.ts.map +1 -0
- package/dist/axios/axios.js +120 -0
- package/dist/axios/axios.js.map +1 -0
- package/dist/core/config.d.ts +17 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +42 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/http-client.d.ts +33 -0
- package/dist/core/http-client.d.ts.map +1 -0
- package/dist/core/http-client.js +104 -0
- package/dist/core/http-client.js.map +1 -0
- package/dist/core/identity.d.ts +7 -0
- package/dist/core/identity.d.ts.map +1 -0
- package/dist/core/identity.js +62 -0
- package/dist/core/identity.js.map +1 -0
- package/dist/core/visitor-params.d.ts +15 -0
- package/dist/core/visitor-params.d.ts.map +1 -0
- package/dist/core/visitor-params.js +45 -0
- package/dist/core/visitor-params.js.map +1 -0
- package/dist/hooks/use-conversations.d.ts +12 -0
- package/dist/hooks/use-conversations.d.ts.map +1 -0
- package/dist/hooks/use-conversations.js +177 -0
- package/dist/hooks/use-conversations.js.map +1 -0
- package/dist/hooks/use-live-chat.d.ts +30 -0
- package/dist/hooks/use-live-chat.d.ts.map +1 -0
- package/dist/hooks/use-live-chat.js +52 -0
- package/dist/hooks/use-live-chat.js.map +1 -0
- package/dist/hooks/use-messages.d.ts +11 -0
- package/dist/hooks/use-messages.d.ts.map +1 -0
- package/dist/hooks/use-messages.js +185 -0
- package/dist/hooks/use-messages.js.map +1 -0
- package/dist/hooks/use-send-message.d.ts +22 -0
- package/dist/hooks/use-send-message.d.ts.map +1 -0
- package/dist/hooks/use-send-message.js +125 -0
- package/dist/hooks/use-send-message.js.map +1 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +97 -0
- package/dist/index.js.map +1 -0
- package/dist/navigation/LiveChatPanel.d.ts +5 -0
- package/dist/navigation/LiveChatPanel.d.ts.map +1 -0
- package/dist/navigation/LiveChatPanel.js +81 -0
- package/dist/navigation/LiveChatPanel.js.map +1 -0
- package/dist/navigation/panel-router-context.d.ts +22 -0
- package/dist/navigation/panel-router-context.d.ts.map +1 -0
- package/dist/navigation/panel-router-context.js +42 -0
- package/dist/navigation/panel-router-context.js.map +1 -0
- package/dist/navigation/router-types.d.ts +2 -0
- package/dist/navigation/router-types.d.ts.map +1 -0
- package/dist/navigation/router-types.js +3 -0
- package/dist/navigation/router-types.js.map +1 -0
- package/dist/provider/LiveChatContext.d.ts +4 -0
- package/dist/provider/LiveChatContext.d.ts.map +1 -0
- package/dist/provider/LiveChatContext.js +35 -0
- package/dist/provider/LiveChatContext.js.map +1 -0
- package/dist/provider/LiveChatProvider.d.ts +3 -0
- package/dist/provider/LiveChatProvider.d.ts.map +1 -0
- package/dist/provider/LiveChatProvider.js +308 -0
- package/dist/provider/LiveChatProvider.js.map +1 -0
- package/dist/provider/types.d.ts +42 -0
- package/dist/provider/types.d.ts.map +1 -0
- package/dist/provider/types.js +3 -0
- package/dist/provider/types.js.map +1 -0
- package/dist/realtime/ws-client.d.ts +51 -0
- package/dist/realtime/ws-client.d.ts.map +1 -0
- package/dist/realtime/ws-client.js +322 -0
- package/dist/realtime/ws-client.js.map +1 -0
- package/dist/ui/components/AssigneeAvatar.d.ts +12 -0
- package/dist/ui/components/AssigneeAvatar.d.ts.map +1 -0
- package/dist/ui/components/AssigneeAvatar.js +58 -0
- package/dist/ui/components/AssigneeAvatar.js.map +1 -0
- package/dist/ui/components/Avatar.d.ts +10 -0
- package/dist/ui/components/Avatar.d.ts.map +1 -0
- package/dist/ui/components/Avatar.js +76 -0
- package/dist/ui/components/Avatar.js.map +1 -0
- package/dist/ui/components/ConversationHeader.d.ts +10 -0
- package/dist/ui/components/ConversationHeader.d.ts.map +1 -0
- package/dist/ui/components/ConversationHeader.js +90 -0
- package/dist/ui/components/ConversationHeader.js.map +1 -0
- package/dist/ui/components/ConversationListScreen.d.ts +9 -0
- package/dist/ui/components/ConversationListScreen.d.ts.map +1 -0
- package/dist/ui/components/ConversationListScreen.js +350 -0
- package/dist/ui/components/ConversationListScreen.js.map +1 -0
- package/dist/ui/components/ConversationScreen.d.ts +8 -0
- package/dist/ui/components/ConversationScreen.d.ts.map +1 -0
- package/dist/ui/components/ConversationScreen.js +235 -0
- package/dist/ui/components/ConversationScreen.js.map +1 -0
- package/dist/ui/components/HomeScreen.d.ts +6 -0
- package/dist/ui/components/HomeScreen.d.ts.map +1 -0
- package/dist/ui/components/HomeScreen.js +133 -0
- package/dist/ui/components/HomeScreen.js.map +1 -0
- package/dist/ui/components/LivechatMessageRenderer.d.ts +17 -0
- package/dist/ui/components/LivechatMessageRenderer.d.ts.map +1 -0
- package/dist/ui/components/LivechatMessageRenderer.js +122 -0
- package/dist/ui/components/LivechatMessageRenderer.js.map +1 -0
- package/dist/ui/components/LogMessage.d.ts +5 -0
- package/dist/ui/components/LogMessage.d.ts.map +1 -0
- package/dist/ui/components/LogMessage.js +83 -0
- package/dist/ui/components/LogMessage.js.map +1 -0
- package/dist/ui/components/MessageBubble.d.ts +15 -0
- package/dist/ui/components/MessageBubble.d.ts.map +1 -0
- package/dist/ui/components/MessageBubble.js +84 -0
- package/dist/ui/components/MessageBubble.js.map +1 -0
- package/dist/ui/components/MessageComposer.d.ts +31 -0
- package/dist/ui/components/MessageComposer.d.ts.map +1 -0
- package/dist/ui/components/MessageComposer.js +295 -0
- package/dist/ui/components/MessageComposer.js.map +1 -0
- package/dist/ui/components/WsStatusStrip.d.ts +2 -0
- package/dist/ui/components/WsStatusStrip.d.ts.map +1 -0
- package/dist/ui/components/WsStatusStrip.js +103 -0
- package/dist/ui/components/WsStatusStrip.js.map +1 -0
- package/dist/ui/icons.d.ts +22 -0
- package/dist/ui/icons.d.ts.map +1 -0
- package/dist/ui/icons.js +71 -0
- package/dist/ui/icons.js.map +1 -0
- package/dist/ui/theme.d.ts +72 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +170 -0
- package/dist/ui/theme.js.map +1 -0
- package/docs/backend-contract.md +392 -0
- package/docs/migration-notes.md +32 -0
- package/package.json +60 -0
- package/src/api/conversation-api.ts +71 -0
- package/src/api/file-api.ts +14 -0
- package/src/api/widget-api.ts +12 -0
- package/src/axios/axios.ts +159 -0
- package/src/core/config.ts +54 -0
- package/src/core/http-client.ts +136 -0
- package/src/core/identity.ts +68 -0
- package/src/core/visitor-params.ts +48 -0
- package/src/hooks/use-conversations.ts +181 -0
- package/src/hooks/use-live-chat.ts +84 -0
- package/src/hooks/use-messages.ts +188 -0
- package/src/hooks/use-send-message.ts +159 -0
- package/src/index.ts +114 -0
- package/src/navigation/LiveChatPanel.tsx +118 -0
- package/src/navigation/panel-router-context.tsx +89 -0
- package/src/navigation/router-types.ts +1 -0
- package/src/provider/LiveChatContext.ts +33 -0
- package/src/provider/LiveChatProvider.tsx +380 -0
- package/src/provider/types.ts +57 -0
- package/src/realtime/ws-client.ts +369 -0
- package/src/types/react-native-svg.d.ts +10 -0
- package/src/ui/components/AssigneeAvatar.tsx +102 -0
- package/src/ui/components/Avatar.tsx +110 -0
- package/src/ui/components/ConversationHeader.tsx +202 -0
- package/src/ui/components/ConversationListScreen.tsx +454 -0
- package/src/ui/components/ConversationScreen.tsx +362 -0
- package/src/ui/components/HomeScreen.tsx +278 -0
- package/src/ui/components/LivechatMessageRenderer.tsx +268 -0
- package/src/ui/components/LogMessage.tsx +88 -0
- package/src/ui/components/MessageBubble.tsx +148 -0
- package/src/ui/components/MessageComposer.tsx +461 -0
- package/src/ui/components/WsStatusStrip.tsx +123 -0
- package/src/ui/icons.tsx +111 -0
- 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 @@
|
|
|
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 @@
|
|
|
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
|