@iblai/web-utils 0.2.1 → 1.0.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/README.md +504 -0
- package/dist/data-layer/src/features/chat-files/api-slice.d.ts +185 -0
- package/dist/data-layer/src/features/chat-files/types.d.ts +32 -0
- package/dist/data-layer/src/features/core/api-slice.d.ts +419 -61
- package/dist/data-layer/src/features/core/constants.d.ts +3 -0
- package/dist/data-layer/src/features/core/custom-api-slice.d.ts +50 -50
- package/dist/data-layer/src/features/core/custom-public-image-asset-api-slice.d.ts +333 -0
- package/dist/data-layer/src/features/core/types.d.ts +33 -0
- package/dist/data-layer/src/features/credentials/api-slice.d.ts +62 -39
- package/dist/data-layer/src/features/mentor/api-slice.d.ts +980 -188
- package/dist/data-layer/src/features/notifications/constants.d.ts +6 -0
- package/dist/data-layer/src/features/notifications/custom-api-slice.d.ts +43 -43
- package/dist/data-layer/src/features/notifications/types.d.ts +25 -2
- package/dist/data-layer/src/index.d.ts +3 -0
- package/dist/index.d.ts +425 -66
- package/dist/index.esm.js +999 -109
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1030 -107
- package/dist/index.js.map +1 -1
- package/dist/package.json +4 -2
- package/dist/web-utils/src/constants/chat.d.ts +8 -0
- package/dist/web-utils/src/features/files/filesSlice.d.ts +20 -0
- package/dist/web-utils/src/features/index.d.ts +1 -0
- package/dist/web-utils/src/hooks/chat/use-advanced-chat.d.ts +6 -4
- package/dist/web-utils/src/hooks/chat/use-chat-v2.d.ts +11 -1
- package/dist/web-utils/src/index.d.ts +2 -0
- package/dist/web-utils/src/index.web.d.ts +14 -12
- package/dist/web-utils/src/providers/auth-provider.d.ts +9 -1
- package/dist/web-utils/src/providers/tenant-provider.d.ts +2 -1
- package/dist/web-utils/src/services/__tests__/file-upload.test.d.ts +1 -0
- package/dist/web-utils/src/services/file-upload.d.ts +60 -0
- package/dist/web-utils/src/services/index.d.ts +1 -0
- package/dist/web-utils/src/types/file-upload.d.ts +62 -0
- package/dist/web-utils/src/types/index.d.ts +1 -0
- package/dist/web-utils/src/utils/auth.d.ts +180 -0
- package/dist/web-utils/src/utils/index.d.ts +1 -0
- package/dist/web-utils/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
package/README.md
ADDED
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
# @iblai/web-utils
|
|
2
|
+
|
|
3
|
+
A collection of React hooks, utilities, and providers for IBL AI web applications.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @iblai/web-utils
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
The web-utils package provides:
|
|
14
|
+
- **Authentication utilities** for cross-SPA auth flows
|
|
15
|
+
- **React hooks** for chat, subscriptions, and time tracking
|
|
16
|
+
- **Context providers** for auth, tenant, and mentor management
|
|
17
|
+
- **Utility functions** for common operations
|
|
18
|
+
- **TypeScript types** for type-safe development
|
|
19
|
+
|
|
20
|
+
## Authentication Utilities
|
|
21
|
+
|
|
22
|
+
### Redirect to Auth SPA
|
|
23
|
+
|
|
24
|
+
Redirect users to the authentication SPA for login:
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import { redirectToAuthSpa, isLoggedIn } from '@iblai/web-utils';
|
|
28
|
+
|
|
29
|
+
function LoginButton() {
|
|
30
|
+
const handleLogin = () => {
|
|
31
|
+
redirectToAuthSpa({
|
|
32
|
+
authUrl: 'https://auth.example.com',
|
|
33
|
+
appName: 'mentor',
|
|
34
|
+
platformKey: 'my-tenant',
|
|
35
|
+
redirectTo: window.location.href,
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
if (isLoggedIn()) {
|
|
40
|
+
return <div>Already logged in</div>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return <button onClick={handleLogin}>Log In</button>;
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Handle Logout
|
|
48
|
+
|
|
49
|
+
Complete logout with cookie cleanup and cross-SPA synchronization:
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
import { handleLogout } from '@iblai/web-utils';
|
|
53
|
+
|
|
54
|
+
function LogoutButton() {
|
|
55
|
+
const handleClick = () => {
|
|
56
|
+
handleLogout({
|
|
57
|
+
authUrl: 'https://auth.example.com',
|
|
58
|
+
appName: 'mentor',
|
|
59
|
+
callback: () => {
|
|
60
|
+
console.log('Logged out successfully');
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
return <button onClick={handleClick}>Log Out</button>;
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Join Tenant Flow
|
|
70
|
+
|
|
71
|
+
Redirect users to signup/join a specific tenant:
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
import { redirectToAuthSpaJoinTenant } from '@iblai/web-utils';
|
|
75
|
+
|
|
76
|
+
function SignupButton() {
|
|
77
|
+
const handleSignup = () => {
|
|
78
|
+
redirectToAuthSpaJoinTenant(
|
|
79
|
+
'https://auth.example.com',
|
|
80
|
+
'my-tenant',
|
|
81
|
+
'https://app.example.com/welcome'
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
return <button onClick={handleSignup}>Sign Up</button>;
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Get Join URL
|
|
90
|
+
|
|
91
|
+
Get the signup URL without redirecting:
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
import { getAuthSpaJoinUrl } from '@iblai/web-utils';
|
|
95
|
+
|
|
96
|
+
function ShareInviteLink() {
|
|
97
|
+
const inviteUrl = getAuthSpaJoinUrl(
|
|
98
|
+
'https://auth.example.com',
|
|
99
|
+
'my-tenant',
|
|
100
|
+
'https://app.example.com/welcome'
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<div>
|
|
105
|
+
<p>Share this link:</p>
|
|
106
|
+
<input value={inviteUrl} readOnly />
|
|
107
|
+
</div>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Check Login Status
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
import { isLoggedIn, getPlatformKey } from '@iblai/web-utils';
|
|
116
|
+
|
|
117
|
+
function Header() {
|
|
118
|
+
const loggedIn = isLoggedIn();
|
|
119
|
+
const tenantKey = getPlatformKey(window.location.href);
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<header>
|
|
123
|
+
{loggedIn ? `Logged in to ${tenantKey}` : 'Please log in'}
|
|
124
|
+
</header>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Context Providers
|
|
130
|
+
|
|
131
|
+
### Auth Provider
|
|
132
|
+
|
|
133
|
+
Manage authentication state across your app:
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
import { AuthProvider, useAuthContext } from '@iblai/web-utils';
|
|
137
|
+
|
|
138
|
+
function App() {
|
|
139
|
+
return (
|
|
140
|
+
<AuthProvider>
|
|
141
|
+
<YourApp />
|
|
142
|
+
</AuthProvider>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function UserInfo() {
|
|
147
|
+
const { isAuthenticated, user, logout } = useAuthContext();
|
|
148
|
+
|
|
149
|
+
if (!isAuthenticated) {
|
|
150
|
+
return <div>Not logged in</div>;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return (
|
|
154
|
+
<div>
|
|
155
|
+
<p>Welcome, {user.name}</p>
|
|
156
|
+
<button onClick={logout}>Logout</button>
|
|
157
|
+
</div>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Tenant Provider
|
|
163
|
+
|
|
164
|
+
Manage tenant/platform context:
|
|
165
|
+
|
|
166
|
+
```tsx
|
|
167
|
+
import { TenantProvider, useTenantContext } from '@iblai/web-utils';
|
|
168
|
+
|
|
169
|
+
function App() {
|
|
170
|
+
return (
|
|
171
|
+
<TenantProvider>
|
|
172
|
+
<YourApp />
|
|
173
|
+
</TenantProvider>
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function TenantInfo() {
|
|
178
|
+
const { tenant, setTenant } = useTenantContext();
|
|
179
|
+
|
|
180
|
+
return (
|
|
181
|
+
<div>
|
|
182
|
+
<h2>Current Tenant: {tenant?.name}</h2>
|
|
183
|
+
<p>Key: {tenant?.key}</p>
|
|
184
|
+
</div>
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Mentor Provider
|
|
190
|
+
|
|
191
|
+
Manage mentor context for AI chat applications:
|
|
192
|
+
|
|
193
|
+
```tsx
|
|
194
|
+
import { MentorProvider, useMentorContext } from '@iblai/web-utils';
|
|
195
|
+
|
|
196
|
+
function App() {
|
|
197
|
+
return (
|
|
198
|
+
<MentorProvider>
|
|
199
|
+
<YourApp />
|
|
200
|
+
</MentorProvider>
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function MentorInfo() {
|
|
205
|
+
const { mentor, setMentor } = useMentorContext();
|
|
206
|
+
|
|
207
|
+
return (
|
|
208
|
+
<div>
|
|
209
|
+
<h2>Active Mentor: {mentor?.name}</h2>
|
|
210
|
+
<p>ID: {mentor?.id}</p>
|
|
211
|
+
</div>
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## React Hooks
|
|
217
|
+
|
|
218
|
+
### Advanced Chat Hook
|
|
219
|
+
|
|
220
|
+
Manage AI chat conversations with advanced features:
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
import { useAdvancedChat } from '@iblai/web-utils';
|
|
224
|
+
|
|
225
|
+
function ChatInterface() {
|
|
226
|
+
const {
|
|
227
|
+
messages,
|
|
228
|
+
sendMessage,
|
|
229
|
+
isStreaming,
|
|
230
|
+
stopGeneration,
|
|
231
|
+
sessionId,
|
|
232
|
+
} = useAdvancedChat({
|
|
233
|
+
wsUrl: 'wss://api.example.com/chat',
|
|
234
|
+
wsToken: 'your-token',
|
|
235
|
+
mentorId: 'mentor-123',
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
const handleSend = (text: string) => {
|
|
239
|
+
sendMessage({
|
|
240
|
+
content: text,
|
|
241
|
+
sessionId,
|
|
242
|
+
});
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
return (
|
|
246
|
+
<div>
|
|
247
|
+
<MessageList messages={messages} />
|
|
248
|
+
{isStreaming && <button onClick={stopGeneration}>Stop</button>}
|
|
249
|
+
<ChatInput onSend={handleSend} />
|
|
250
|
+
</div>
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Time Tracker Hook
|
|
256
|
+
|
|
257
|
+
Track user time spent in application:
|
|
258
|
+
|
|
259
|
+
```tsx
|
|
260
|
+
import { useTimeTracker } from '@iblai/web-utils';
|
|
261
|
+
|
|
262
|
+
function App() {
|
|
263
|
+
useTimeTracker({
|
|
264
|
+
endpoint: 'https://api.example.com/time-tracking',
|
|
265
|
+
token: 'your-token',
|
|
266
|
+
tenantKey: 'my-tenant',
|
|
267
|
+
mentorId: 'mentor-123',
|
|
268
|
+
interval: 60000, // Track every minute
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
return <YourApp />;
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Subscription Handler Hook
|
|
276
|
+
|
|
277
|
+
Manage subscription state and paywall logic:
|
|
278
|
+
|
|
279
|
+
```tsx
|
|
280
|
+
import { useSubscriptionHandler } from '@iblai/web-utils';
|
|
281
|
+
|
|
282
|
+
function FeatureGate({ children }) {
|
|
283
|
+
const {
|
|
284
|
+
isSubscribed,
|
|
285
|
+
showPaywall,
|
|
286
|
+
subscription,
|
|
287
|
+
} = useSubscriptionHandler({
|
|
288
|
+
tenantKey: 'my-tenant',
|
|
289
|
+
userId: 'user-123',
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
if (!isSubscribed && showPaywall) {
|
|
293
|
+
return <PaywallModal />;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return children;
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### External Pricing Plan Hook
|
|
301
|
+
|
|
302
|
+
Fetch and manage external pricing plans:
|
|
303
|
+
|
|
304
|
+
```tsx
|
|
305
|
+
import { useExternalPricingPlan } from '@iblai/web-utils';
|
|
306
|
+
|
|
307
|
+
function PricingPage() {
|
|
308
|
+
const {
|
|
309
|
+
pricingPlans,
|
|
310
|
+
isLoading,
|
|
311
|
+
error,
|
|
312
|
+
} = useExternalPricingPlan({
|
|
313
|
+
tenantKey: 'my-tenant',
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
if (isLoading) return <div>Loading pricing...</div>;
|
|
317
|
+
|
|
318
|
+
return (
|
|
319
|
+
<div>
|
|
320
|
+
{pricingPlans.map(plan => (
|
|
321
|
+
<PricingCard key={plan.id} plan={plan} />
|
|
322
|
+
))}
|
|
323
|
+
</div>
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Tenant Metadata Hook
|
|
329
|
+
|
|
330
|
+
Fetch tenant configuration and metadata:
|
|
331
|
+
|
|
332
|
+
```tsx
|
|
333
|
+
import { useTenantMetadata } from '@iblai/web-utils';
|
|
334
|
+
|
|
335
|
+
function TenantSettings() {
|
|
336
|
+
const { metadata, isLoading } = useTenantMetadata('my-tenant');
|
|
337
|
+
|
|
338
|
+
return (
|
|
339
|
+
<div>
|
|
340
|
+
<h1>{metadata?.name}</h1>
|
|
341
|
+
<p>{metadata?.description}</p>
|
|
342
|
+
<img src={metadata?.logo} alt="Logo" />
|
|
343
|
+
</div>
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## Utility Functions
|
|
349
|
+
|
|
350
|
+
### Cookie Management
|
|
351
|
+
|
|
352
|
+
```tsx
|
|
353
|
+
import {
|
|
354
|
+
setCookieForAuth,
|
|
355
|
+
deleteCookie,
|
|
356
|
+
clearCookies,
|
|
357
|
+
} from '@iblai/web-utils';
|
|
358
|
+
|
|
359
|
+
// Set auth cookie
|
|
360
|
+
setCookieForAuth('token', 'abc123', 7); // 7 days
|
|
361
|
+
|
|
362
|
+
// Delete specific cookie
|
|
363
|
+
deleteCookie('token');
|
|
364
|
+
|
|
365
|
+
// Clear all auth cookies
|
|
366
|
+
clearCookies(['token', 'refresh_token']);
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Iframe Detection
|
|
370
|
+
|
|
371
|
+
```tsx
|
|
372
|
+
import { isInIframe, sendMessageToParentWebsite } from '@iblai/web-utils';
|
|
373
|
+
|
|
374
|
+
if (isInIframe()) {
|
|
375
|
+
// Send message to parent window
|
|
376
|
+
sendMessageToParentWebsite({
|
|
377
|
+
type: 'LOGGED_IN',
|
|
378
|
+
userId: 'user-123',
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### Time Utilities
|
|
384
|
+
|
|
385
|
+
```tsx
|
|
386
|
+
import { getTimeAgo, useDayJs } from '@iblai/web-utils';
|
|
387
|
+
|
|
388
|
+
// Get relative time
|
|
389
|
+
const timeAgo = getTimeAgo('2024-01-01T00:00:00Z');
|
|
390
|
+
// Returns: "2 months ago"
|
|
391
|
+
|
|
392
|
+
// Use Day.js in components
|
|
393
|
+
function DateDisplay({ date }) {
|
|
394
|
+
const dayjs = useDayJs();
|
|
395
|
+
return <span>{dayjs(date).format('MMM D, YYYY')}</span>;
|
|
396
|
+
}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Profile Utilities
|
|
400
|
+
|
|
401
|
+
```tsx
|
|
402
|
+
import { getInitials } from '@iblai/web-utils';
|
|
403
|
+
|
|
404
|
+
function Avatar({ name }) {
|
|
405
|
+
const initials = getInitials(name);
|
|
406
|
+
// "John Doe" => "JD"
|
|
407
|
+
|
|
408
|
+
return <div className="avatar">{initials}</div>;
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Validation
|
|
413
|
+
|
|
414
|
+
```tsx
|
|
415
|
+
import { isAlphaNumeric32 } from '@iblai/web-utils';
|
|
416
|
+
|
|
417
|
+
const isValid = isAlphaNumeric32('abc123XYZ');
|
|
418
|
+
// Validates alphanumeric strings up to 32 chars
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
## TypeScript Support
|
|
422
|
+
|
|
423
|
+
All utilities and hooks are fully typed:
|
|
424
|
+
|
|
425
|
+
```tsx
|
|
426
|
+
import type {
|
|
427
|
+
RedirectToAuthSpaOptions,
|
|
428
|
+
HandleLogoutOptions,
|
|
429
|
+
AuthContextType,
|
|
430
|
+
TenantContextType,
|
|
431
|
+
Message,
|
|
432
|
+
ChatState,
|
|
433
|
+
} from '@iblai/web-utils';
|
|
434
|
+
|
|
435
|
+
const authOptions: RedirectToAuthSpaOptions = {
|
|
436
|
+
authUrl: 'https://auth.example.com',
|
|
437
|
+
appName: 'mentor',
|
|
438
|
+
platformKey: 'my-tenant',
|
|
439
|
+
};
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
## Advanced Features
|
|
443
|
+
|
|
444
|
+
### Custom Metadata Loading
|
|
445
|
+
|
|
446
|
+
```tsx
|
|
447
|
+
import { loadMetadataConfig } from '@iblai/web-utils';
|
|
448
|
+
|
|
449
|
+
const metadata = await loadMetadataConfig('my-tenant', {
|
|
450
|
+
endpoint: 'https://api.example.com/metadata',
|
|
451
|
+
headers: {
|
|
452
|
+
'Authorization': 'Bearer token',
|
|
453
|
+
},
|
|
454
|
+
});
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### File Upload with S3
|
|
458
|
+
|
|
459
|
+
```tsx
|
|
460
|
+
import { requestPresignedUrl, uploadToS3 } from '@iblai/web-utils';
|
|
461
|
+
|
|
462
|
+
async function uploadFile(file: File) {
|
|
463
|
+
// Get presigned URL
|
|
464
|
+
const { url, fields } = await requestPresignedUrl({
|
|
465
|
+
fileName: file.name,
|
|
466
|
+
fileType: file.type,
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
// Upload to S3
|
|
470
|
+
await uploadToS3(url, fields, file, {
|
|
471
|
+
onProgress: (percent) => {
|
|
472
|
+
console.log(`Upload progress: ${percent}%`);
|
|
473
|
+
},
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
## Contributing
|
|
479
|
+
|
|
480
|
+
We welcome contributions! Please read our [contributing guidelines](CONTRIBUTING.md).
|
|
481
|
+
|
|
482
|
+
## Development
|
|
483
|
+
|
|
484
|
+
### Building
|
|
485
|
+
|
|
486
|
+
```bash
|
|
487
|
+
pnpm build
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### Testing
|
|
491
|
+
|
|
492
|
+
```bash
|
|
493
|
+
pnpm test
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### Type Checking
|
|
497
|
+
|
|
498
|
+
```bash
|
|
499
|
+
pnpm typecheck
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
## License
|
|
503
|
+
|
|
504
|
+
ISC
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import type { FileUploadURLRequest, FileUploadURLResponse } from './types';
|
|
2
|
+
export declare const chatFilesApiSlice: import("@reduxjs/toolkit/query").Api<import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, {
|
|
3
|
+
/**
|
|
4
|
+
* Get presigned S3 URL for file upload
|
|
5
|
+
* POST /api/ai-mentor/orgs/{org}/users/{userId}/chat/files/upload-url/
|
|
6
|
+
*/
|
|
7
|
+
getFileUploadUrl: import("@reduxjs/toolkit/query").MutationDefinition<{
|
|
8
|
+
org: string;
|
|
9
|
+
userId: string;
|
|
10
|
+
requestBody: FileUploadURLRequest;
|
|
11
|
+
}, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, never, FileUploadURLResponse, "chatFilesApiSlice", unknown>;
|
|
12
|
+
}, "chatFilesApiSlice", never, typeof import("@reduxjs/toolkit/query").coreModuleName | typeof import("@reduxjs/toolkit/dist/query/react").reactHooksModuleName>;
|
|
13
|
+
export declare const useGetFileUploadUrlMutation: <R extends Record<string, any> = ({
|
|
14
|
+
requestId?: undefined;
|
|
15
|
+
status: import("@reduxjs/toolkit/query").QueryStatus.uninitialized;
|
|
16
|
+
data?: undefined;
|
|
17
|
+
error?: undefined;
|
|
18
|
+
endpointName?: string;
|
|
19
|
+
startedTimeStamp?: undefined;
|
|
20
|
+
fulfilledTimeStamp?: undefined;
|
|
21
|
+
} & {
|
|
22
|
+
status: import("@reduxjs/toolkit/query").QueryStatus.uninitialized;
|
|
23
|
+
isUninitialized: true;
|
|
24
|
+
isLoading: false;
|
|
25
|
+
isSuccess: false;
|
|
26
|
+
isError: false;
|
|
27
|
+
}) | ({
|
|
28
|
+
status: import("@reduxjs/toolkit/query").QueryStatus.fulfilled;
|
|
29
|
+
} & Omit<{
|
|
30
|
+
requestId: string;
|
|
31
|
+
data?: FileUploadURLResponse | undefined;
|
|
32
|
+
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
33
|
+
endpointName: string;
|
|
34
|
+
startedTimeStamp: number;
|
|
35
|
+
fulfilledTimeStamp?: number;
|
|
36
|
+
}, "data" | "fulfilledTimeStamp"> & Required<Pick<{
|
|
37
|
+
requestId: string;
|
|
38
|
+
data?: FileUploadURLResponse | undefined;
|
|
39
|
+
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
40
|
+
endpointName: string;
|
|
41
|
+
startedTimeStamp: number;
|
|
42
|
+
fulfilledTimeStamp?: number;
|
|
43
|
+
}, "data" | "fulfilledTimeStamp">> & {
|
|
44
|
+
error: undefined;
|
|
45
|
+
} & {
|
|
46
|
+
status: import("@reduxjs/toolkit/query").QueryStatus.fulfilled;
|
|
47
|
+
isUninitialized: false;
|
|
48
|
+
isLoading: false;
|
|
49
|
+
isSuccess: true;
|
|
50
|
+
isError: false;
|
|
51
|
+
}) | ({
|
|
52
|
+
status: import("@reduxjs/toolkit/query").QueryStatus.pending;
|
|
53
|
+
} & {
|
|
54
|
+
requestId: string;
|
|
55
|
+
data?: FileUploadURLResponse | undefined;
|
|
56
|
+
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
57
|
+
endpointName: string;
|
|
58
|
+
startedTimeStamp: number;
|
|
59
|
+
fulfilledTimeStamp?: number;
|
|
60
|
+
} & {
|
|
61
|
+
data?: undefined;
|
|
62
|
+
} & {
|
|
63
|
+
status: import("@reduxjs/toolkit/query").QueryStatus.pending;
|
|
64
|
+
isUninitialized: false;
|
|
65
|
+
isLoading: true;
|
|
66
|
+
isSuccess: false;
|
|
67
|
+
isError: false;
|
|
68
|
+
}) | ({
|
|
69
|
+
status: import("@reduxjs/toolkit/query").QueryStatus.rejected;
|
|
70
|
+
} & Omit<{
|
|
71
|
+
requestId: string;
|
|
72
|
+
data?: FileUploadURLResponse | undefined;
|
|
73
|
+
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
74
|
+
endpointName: string;
|
|
75
|
+
startedTimeStamp: number;
|
|
76
|
+
fulfilledTimeStamp?: number;
|
|
77
|
+
}, "error"> & Required<Pick<{
|
|
78
|
+
requestId: string;
|
|
79
|
+
data?: FileUploadURLResponse | undefined;
|
|
80
|
+
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
81
|
+
endpointName: string;
|
|
82
|
+
startedTimeStamp: number;
|
|
83
|
+
fulfilledTimeStamp?: number;
|
|
84
|
+
}, "error">> & {
|
|
85
|
+
status: import("@reduxjs/toolkit/query").QueryStatus.rejected;
|
|
86
|
+
isUninitialized: false;
|
|
87
|
+
isLoading: false;
|
|
88
|
+
isSuccess: false;
|
|
89
|
+
isError: true;
|
|
90
|
+
})>(options?: {
|
|
91
|
+
selectFromResult?: ((state: ({
|
|
92
|
+
requestId?: undefined;
|
|
93
|
+
status: import("@reduxjs/toolkit/query").QueryStatus.uninitialized;
|
|
94
|
+
data?: undefined;
|
|
95
|
+
error?: undefined;
|
|
96
|
+
endpointName?: string;
|
|
97
|
+
startedTimeStamp?: undefined;
|
|
98
|
+
fulfilledTimeStamp?: undefined;
|
|
99
|
+
} & {
|
|
100
|
+
status: import("@reduxjs/toolkit/query").QueryStatus.uninitialized;
|
|
101
|
+
isUninitialized: true;
|
|
102
|
+
isLoading: false;
|
|
103
|
+
isSuccess: false;
|
|
104
|
+
isError: false;
|
|
105
|
+
}) | ({
|
|
106
|
+
status: import("@reduxjs/toolkit/query").QueryStatus.fulfilled;
|
|
107
|
+
} & Omit<{
|
|
108
|
+
requestId: string;
|
|
109
|
+
data?: FileUploadURLResponse | undefined;
|
|
110
|
+
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
111
|
+
endpointName: string;
|
|
112
|
+
startedTimeStamp: number;
|
|
113
|
+
fulfilledTimeStamp?: number;
|
|
114
|
+
}, "data" | "fulfilledTimeStamp"> & Required<Pick<{
|
|
115
|
+
requestId: string;
|
|
116
|
+
data?: FileUploadURLResponse | undefined;
|
|
117
|
+
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
118
|
+
endpointName: string;
|
|
119
|
+
startedTimeStamp: number;
|
|
120
|
+
fulfilledTimeStamp?: number;
|
|
121
|
+
}, "data" | "fulfilledTimeStamp">> & {
|
|
122
|
+
error: undefined;
|
|
123
|
+
} & {
|
|
124
|
+
status: import("@reduxjs/toolkit/query").QueryStatus.fulfilled;
|
|
125
|
+
isUninitialized: false;
|
|
126
|
+
isLoading: false;
|
|
127
|
+
isSuccess: true;
|
|
128
|
+
isError: false;
|
|
129
|
+
}) | ({
|
|
130
|
+
status: import("@reduxjs/toolkit/query").QueryStatus.pending;
|
|
131
|
+
} & {
|
|
132
|
+
requestId: string;
|
|
133
|
+
data?: FileUploadURLResponse | undefined;
|
|
134
|
+
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
135
|
+
endpointName: string;
|
|
136
|
+
startedTimeStamp: number;
|
|
137
|
+
fulfilledTimeStamp?: number;
|
|
138
|
+
} & {
|
|
139
|
+
data?: undefined;
|
|
140
|
+
} & {
|
|
141
|
+
status: import("@reduxjs/toolkit/query").QueryStatus.pending;
|
|
142
|
+
isUninitialized: false;
|
|
143
|
+
isLoading: true;
|
|
144
|
+
isSuccess: false;
|
|
145
|
+
isError: false;
|
|
146
|
+
}) | ({
|
|
147
|
+
status: import("@reduxjs/toolkit/query").QueryStatus.rejected;
|
|
148
|
+
} & Omit<{
|
|
149
|
+
requestId: string;
|
|
150
|
+
data?: FileUploadURLResponse | undefined;
|
|
151
|
+
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
152
|
+
endpointName: string;
|
|
153
|
+
startedTimeStamp: number;
|
|
154
|
+
fulfilledTimeStamp?: number;
|
|
155
|
+
}, "error"> & Required<Pick<{
|
|
156
|
+
requestId: string;
|
|
157
|
+
data?: FileUploadURLResponse | undefined;
|
|
158
|
+
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
159
|
+
endpointName: string;
|
|
160
|
+
startedTimeStamp: number;
|
|
161
|
+
fulfilledTimeStamp?: number;
|
|
162
|
+
}, "error">> & {
|
|
163
|
+
status: import("@reduxjs/toolkit/query").QueryStatus.rejected;
|
|
164
|
+
isUninitialized: false;
|
|
165
|
+
isLoading: false;
|
|
166
|
+
isSuccess: false;
|
|
167
|
+
isError: true;
|
|
168
|
+
})) => R) | undefined;
|
|
169
|
+
fixedCacheKey?: string;
|
|
170
|
+
} | undefined) => readonly [(arg: {
|
|
171
|
+
org: string;
|
|
172
|
+
userId: string;
|
|
173
|
+
requestBody: FileUploadURLRequest;
|
|
174
|
+
}) => import("@reduxjs/toolkit/query").MutationActionCreatorResult<import("@reduxjs/toolkit/query").MutationDefinition<{
|
|
175
|
+
org: string;
|
|
176
|
+
userId: string;
|
|
177
|
+
requestBody: FileUploadURLRequest;
|
|
178
|
+
}, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, never, FileUploadURLResponse, "chatFilesApiSlice", unknown>>, import("@reduxjs/toolkit/query").TSHelpersNoInfer<R> & {
|
|
179
|
+
originalArgs?: {
|
|
180
|
+
org: string;
|
|
181
|
+
userId: string;
|
|
182
|
+
requestBody: FileUploadURLRequest;
|
|
183
|
+
} | undefined;
|
|
184
|
+
reset: () => void;
|
|
185
|
+
}];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local type definitions for file upload API
|
|
3
|
+
* These mirror the backend API types
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Request for generating presigned upload URL
|
|
7
|
+
*/
|
|
8
|
+
export interface FileUploadURLRequest {
|
|
9
|
+
/** Chat session ID */
|
|
10
|
+
session_id: string;
|
|
11
|
+
/** Original filename */
|
|
12
|
+
file_name: string;
|
|
13
|
+
/** MIME type of the file */
|
|
14
|
+
content_type: string;
|
|
15
|
+
/** File size in bytes */
|
|
16
|
+
file_size: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Response with presigned upload URL
|
|
20
|
+
*/
|
|
21
|
+
export interface FileUploadURLResponse {
|
|
22
|
+
/** Presigned S3 upload URL */
|
|
23
|
+
upload_url: string;
|
|
24
|
+
/** S3 object key for the uploaded file */
|
|
25
|
+
file_key: string;
|
|
26
|
+
/** Unique identifier for the ChatFile record */
|
|
27
|
+
file_id: string;
|
|
28
|
+
/** URL expiration time in seconds */
|
|
29
|
+
expires_in: number;
|
|
30
|
+
/** HTTP method to use for upload (PUT or POST) */
|
|
31
|
+
upload_method?: string;
|
|
32
|
+
}
|