@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.
Files changed (38) hide show
  1. package/README.md +504 -0
  2. package/dist/data-layer/src/features/chat-files/api-slice.d.ts +185 -0
  3. package/dist/data-layer/src/features/chat-files/types.d.ts +32 -0
  4. package/dist/data-layer/src/features/core/api-slice.d.ts +419 -61
  5. package/dist/data-layer/src/features/core/constants.d.ts +3 -0
  6. package/dist/data-layer/src/features/core/custom-api-slice.d.ts +50 -50
  7. package/dist/data-layer/src/features/core/custom-public-image-asset-api-slice.d.ts +333 -0
  8. package/dist/data-layer/src/features/core/types.d.ts +33 -0
  9. package/dist/data-layer/src/features/credentials/api-slice.d.ts +62 -39
  10. package/dist/data-layer/src/features/mentor/api-slice.d.ts +980 -188
  11. package/dist/data-layer/src/features/notifications/constants.d.ts +6 -0
  12. package/dist/data-layer/src/features/notifications/custom-api-slice.d.ts +43 -43
  13. package/dist/data-layer/src/features/notifications/types.d.ts +25 -2
  14. package/dist/data-layer/src/index.d.ts +3 -0
  15. package/dist/index.d.ts +425 -66
  16. package/dist/index.esm.js +999 -109
  17. package/dist/index.esm.js.map +1 -1
  18. package/dist/index.js +1030 -107
  19. package/dist/index.js.map +1 -1
  20. package/dist/package.json +4 -2
  21. package/dist/web-utils/src/constants/chat.d.ts +8 -0
  22. package/dist/web-utils/src/features/files/filesSlice.d.ts +20 -0
  23. package/dist/web-utils/src/features/index.d.ts +1 -0
  24. package/dist/web-utils/src/hooks/chat/use-advanced-chat.d.ts +6 -4
  25. package/dist/web-utils/src/hooks/chat/use-chat-v2.d.ts +11 -1
  26. package/dist/web-utils/src/index.d.ts +2 -0
  27. package/dist/web-utils/src/index.web.d.ts +14 -12
  28. package/dist/web-utils/src/providers/auth-provider.d.ts +9 -1
  29. package/dist/web-utils/src/providers/tenant-provider.d.ts +2 -1
  30. package/dist/web-utils/src/services/__tests__/file-upload.test.d.ts +1 -0
  31. package/dist/web-utils/src/services/file-upload.d.ts +60 -0
  32. package/dist/web-utils/src/services/index.d.ts +1 -0
  33. package/dist/web-utils/src/types/file-upload.d.ts +62 -0
  34. package/dist/web-utils/src/types/index.d.ts +1 -0
  35. package/dist/web-utils/src/utils/auth.d.ts +180 -0
  36. package/dist/web-utils/src/utils/index.d.ts +1 -0
  37. package/dist/web-utils/tsconfig.tsbuildinfo +1 -1
  38. 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
+ }