@ragbits/api-client 1.3.0 → 1.4.0-dev.202512050236

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.
@@ -1,5 +1,6 @@
1
1
  import { http, HttpResponse } from 'msw'
2
2
  import { defaultConfigResponse } from '../utils'
3
+ import { ChatResponse } from '../../src'
3
4
 
4
5
  export const handlers = [
5
6
  // Config endpoint with conditional error handling
@@ -65,11 +66,14 @@ export const handlers = [
65
66
 
66
67
  const stream = new ReadableStream({
67
68
  start(controller) {
68
- const messages = [
69
- { type: 'text', content: 'Hello there!' },
70
- { type: 'text', content: 'How can I help you?' },
71
- { type: 'message_id', content: 'msg-123' },
72
- { type: 'conversation_id', content: 'conv-456' },
69
+ const messages: ChatResponse[] = [
70
+ { type: 'text', content: { text: 'Hello there!' } },
71
+ { type: 'text', content: { text: 'How can I help you?' } },
72
+ { type: 'message_id', content: { message_id: 'msg-123' } },
73
+ {
74
+ type: 'conversation_id',
75
+ content: { conversation_id: 'conv-456' },
76
+ },
73
77
  ]
74
78
 
75
79
  messages.forEach((message, index) => {
@@ -5,23 +5,6 @@
5
5
  */
6
6
  import type { RJSFSchema } from '@rjsf/utils';
7
7
  export type TypeFrom<T> = T[keyof T];
8
- /**
9
- * Represents the ChatResponseType enum
10
- */
11
- export declare const ChatResponseType: {
12
- readonly Text: "text";
13
- readonly Reference: "reference";
14
- readonly StateUpdate: "state_update";
15
- readonly MessageId: "message_id";
16
- readonly ConversationId: "conversation_id";
17
- readonly LiveUpdate: "live_update";
18
- readonly FollowupMessages: "followup_messages";
19
- readonly Image: "image";
20
- readonly ChunkedContent: "chunked_content";
21
- readonly ClearMessage: "clear_message";
22
- readonly Usage: "usage";
23
- };
24
- export type ChatResponseType = TypeFrom<typeof ChatResponseType>;
25
8
  /**
26
9
  * Represents the FeedbackType enum
27
10
  */
@@ -47,6 +30,18 @@ export declare const MessageRole: {
47
30
  readonly System: "system";
48
31
  };
49
32
  export type MessageRole = TypeFrom<typeof MessageRole>;
33
+ /**
34
+ * Represents the TaskStatus enum
35
+ */
36
+ export declare const TaskStatus: {
37
+ readonly Pending: "pending";
38
+ readonly InProgress: "in_progress";
39
+ readonly Completed: "completed";
40
+ readonly Failed: "failed";
41
+ readonly Cancelled: "cancelled";
42
+ readonly Retrying: "retrying";
43
+ };
44
+ export type TaskStatus = TypeFrom<typeof TaskStatus>;
50
45
  /**
51
46
  * Represents the AuthType enum
52
47
  */
@@ -65,6 +60,12 @@ export interface ChatContext {
65
60
  };
66
61
  user: User | null;
67
62
  session_id: string | null;
63
+ /**
64
+ * List of confirmed/declined tools from the frontend
65
+ */
66
+ confirmed_tools: {
67
+ [k: string]: unknown;
68
+ }[] | null;
68
69
  [k: string]: unknown;
69
70
  }
70
71
  /**
@@ -99,6 +100,12 @@ export interface LiveUpdateContent {
99
100
  export interface Message {
100
101
  role: MessageRole;
101
102
  content: string;
103
+ /**
104
+ * Extra information about the message
105
+ */
106
+ extra: {
107
+ [k: string]: unknown;
108
+ } | null;
102
109
  }
103
110
  /**
104
111
  * Represents a document used as reference for the response.
@@ -147,6 +154,83 @@ export interface MessageUsage {
147
154
  completion_tokens: number;
148
155
  total_tokens: number;
149
156
  }
157
+ /**
158
+ * Simple task representation.
159
+ */
160
+ export interface Task {
161
+ id: string;
162
+ description: string;
163
+ /**
164
+ * Task status options.
165
+ */
166
+ status: 'pending' | 'in_progress' | 'completed' | 'failed' | 'cancelled' | 'retrying';
167
+ order: number;
168
+ summary: string | null;
169
+ parent_id: string | null;
170
+ full_response: string | null;
171
+ dependencies: string[];
172
+ }
173
+ /**
174
+ * Represents a tool confirmation request sent to the user.
175
+ */
176
+ export interface ConfirmationRequest {
177
+ confirmation_id: string;
178
+ tool_name: string;
179
+ tool_description: string;
180
+ arguments: {
181
+ [k: string]: unknown;
182
+ };
183
+ }
184
+ /**
185
+ * Text content wrapper.
186
+ */
187
+ export interface TextContent {
188
+ text: string;
189
+ }
190
+ /**
191
+ * Message ID content wrapper.
192
+ */
193
+ export interface MessageIdContent {
194
+ message_id: string;
195
+ }
196
+ /**
197
+ * Conversation ID content wrapper.
198
+ */
199
+ export interface ConversationIdContent {
200
+ conversation_id: string;
201
+ }
202
+ /**
203
+ * Conversation summary content wrapper.
204
+ */
205
+ export interface ConversationSummaryContent {
206
+ summary: string;
207
+ }
208
+ /**
209
+ * Followup messages content wrapper.
210
+ */
211
+ export interface FollowupMessagesContent {
212
+ messages: string[];
213
+ }
214
+ /**
215
+ * Usage statistics content wrapper.
216
+ */
217
+ export interface UsageContent {
218
+ usage: {
219
+ [k: string]: MessageUsage;
220
+ };
221
+ }
222
+ /**
223
+ * Todo item content wrapper.
224
+ */
225
+ export interface TodoItemContent {
226
+ task: Task;
227
+ }
228
+ /**
229
+ * Confirmation request content wrapper.
230
+ */
231
+ export interface ConfirmationRequestContent {
232
+ confirmation_request: ConfirmationRequest;
233
+ }
150
234
  /**
151
235
  * Customization for the header section of the UI.
152
236
  */
@@ -263,7 +347,7 @@ export interface ChatRequest {
263
347
  };
264
348
  }
265
349
  /**
266
- * Request body for feedback submission
350
+ * Request body for feedback submission.
267
351
  */
268
352
  export interface FeedbackRequest {
269
353
  /**
@@ -378,7 +462,7 @@ export interface User {
378
462
  */
379
463
  export interface TextChatResponse {
380
464
  type: 'text';
381
- content: string;
465
+ content: TextContent;
382
466
  }
383
467
  export interface ReferenceChatResponse {
384
468
  type: 'reference';
@@ -386,11 +470,11 @@ export interface ReferenceChatResponse {
386
470
  }
387
471
  export interface MessageIdChatResponse {
388
472
  type: 'message_id';
389
- content: string;
473
+ content: MessageIdContent;
390
474
  }
391
475
  export interface ConversationIdChatResponse {
392
476
  type: 'conversation_id';
393
- content: string;
477
+ content: ConversationIdContent;
394
478
  }
395
479
  export interface StateUpdateChatResponse {
396
480
  type: 'state_update';
@@ -402,19 +486,31 @@ export interface LiveUpdateChatResponse {
402
486
  }
403
487
  export interface FollowupMessagesChatResponse {
404
488
  type: 'followup_messages';
405
- content: string[];
489
+ content: FollowupMessagesContent;
406
490
  }
407
491
  export interface ImageChatResponse {
408
492
  type: 'image';
409
493
  content: Image;
410
494
  }
411
- export interface ClearMessageResponse {
412
- type: 'clear_message';
413
- content: never;
414
- }
415
495
  export interface MessageUsageChatResponse {
416
496
  type: 'usage';
417
- content: Record<string, MessageUsage>;
497
+ content: UsageContent;
498
+ }
499
+ export interface ClearMessageChatResponse {
500
+ type: 'clear_message';
501
+ content: unknown;
502
+ }
503
+ export interface TodoItemChatResonse {
504
+ type: 'todo_item';
505
+ content: TodoItemContent;
506
+ }
507
+ export interface ConversationSummaryResponse {
508
+ type: 'conversation_summary';
509
+ content: ConversationSummaryContent;
510
+ }
511
+ export interface ConfirmationRequestChatResponse {
512
+ type: 'confirmation_request';
513
+ content: ConfirmationRequestContent;
418
514
  }
419
515
  export interface ChunkedChatResponse {
420
516
  type: 'chunked_content';
@@ -423,4 +519,4 @@ export interface ChunkedChatResponse {
423
519
  /**
424
520
  * Typed chat response union
425
521
  */
426
- export type ChatResponse = TextChatResponse | ReferenceChatResponse | MessageIdChatResponse | ConversationIdChatResponse | StateUpdateChatResponse | LiveUpdateChatResponse | FollowupMessagesChatResponse | ImageChatResponse | ClearMessageResponse | MessageUsageChatResponse;
522
+ export type ChatResponse = TextChatResponse | ReferenceChatResponse | MessageIdChatResponse | ConversationIdChatResponse | StateUpdateChatResponse | LiveUpdateChatResponse | FollowupMessagesChatResponse | ImageChatResponse | MessageUsageChatResponse | ClearMessageChatResponse | TodoItemChatResonse | ConversationSummaryResponse | ConfirmationRequestChatResponse;
package/dist/index.cjs CHANGED
@@ -21,28 +21,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  AuthType: () => AuthType,
24
- ChatResponseType: () => ChatResponseType,
25
24
  FeedbackType: () => FeedbackType,
26
25
  LiveUpdateType: () => LiveUpdateType,
27
26
  MessageRole: () => MessageRole,
28
- RagbitsClient: () => RagbitsClient
27
+ RagbitsClient: () => RagbitsClient,
28
+ TaskStatus: () => TaskStatus
29
29
  });
30
30
  module.exports = __toCommonJS(index_exports);
31
31
 
32
32
  // src/autogen.types.ts
33
- var ChatResponseType = {
34
- Text: "text",
35
- Reference: "reference",
36
- StateUpdate: "state_update",
37
- MessageId: "message_id",
38
- ConversationId: "conversation_id",
39
- LiveUpdate: "live_update",
40
- FollowupMessages: "followup_messages",
41
- Image: "image",
42
- ChunkedContent: "chunked_content",
43
- ClearMessage: "clear_message",
44
- Usage: "usage"
45
- };
46
33
  var FeedbackType = {
47
34
  Like: "like",
48
35
  Dislike: "dislike"
@@ -56,6 +43,14 @@ var MessageRole = {
56
43
  Assistant: "assistant",
57
44
  System: "system"
58
45
  };
46
+ var TaskStatus = {
47
+ Pending: "pending",
48
+ InProgress: "in_progress",
49
+ Completed: "completed",
50
+ Failed: "failed",
51
+ Cancelled: "cancelled",
52
+ Retrying: "retrying"
53
+ };
59
54
  var AuthType = {
60
55
  Credentials: "credentials"
61
56
  };
@@ -125,10 +120,13 @@ var RagbitsClient = class {
125
120
  * @param endpoint - API endpoint path
126
121
  * @param options - Typed request options for the specific endpoint
127
122
  */
128
- async makeRequest(endpoint, options) {
123
+ async makeRequest(endpoint, ...args) {
124
+ const options = args[0];
129
125
  const {
130
126
  method = "GET",
131
127
  body,
128
+ pathParams,
129
+ queryParams,
132
130
  headers = {},
133
131
  ...restOptions
134
132
  } = options || {};
@@ -136,15 +134,32 @@ var RagbitsClient = class {
136
134
  method,
137
135
  headers,
138
136
  ...restOptions
139
- // This will include signal and other fetch options
140
137
  };
141
138
  if (body && method !== "GET") {
142
139
  requestOptions.body = typeof body === "string" ? body : JSON.stringify(body);
143
140
  }
144
- const response = await this._makeRequest(
145
- this._buildApiUrl(endpoint.toString()),
146
- requestOptions
147
- );
141
+ let url = endpoint.toString();
142
+ if (pathParams) {
143
+ url = url.replace(/:([^/]+)/g, (_, paramName) => {
144
+ if (paramName in pathParams) {
145
+ const value = pathParams[paramName];
146
+ return encodeURIComponent(String(value));
147
+ } else {
148
+ throw new Error(`Path parameter ${paramName} is required`);
149
+ }
150
+ });
151
+ }
152
+ if (queryParams && Object.keys(queryParams).length > 0) {
153
+ const searchParams = new URLSearchParams();
154
+ for (const [key, value] of Object.entries(queryParams)) {
155
+ if (value !== void 0 && value !== null) {
156
+ searchParams.append(key, String(value));
157
+ }
158
+ }
159
+ url += `?${searchParams.toString()}`;
160
+ }
161
+ url = this._buildApiUrl(url);
162
+ const response = await this._makeRequest(url, requestOptions);
148
163
  return response.json();
149
164
  }
150
165
  /**
@@ -179,11 +194,14 @@ var RagbitsClient = class {
179
194
  const parsedData = JSON.parse(
180
195
  jsonString
181
196
  );
182
- if (parsedData.type === ChatResponseType.ChunkedContent) {
197
+ if (parsedData.type === "chunked_content") {
183
198
  this.handleChunkedContent(parsedData, callbacks);
184
199
  continue;
185
200
  }
186
201
  await callbacks.onMessage(parsedData);
202
+ await new Promise(
203
+ (resolve) => setTimeout(resolve, 0)
204
+ );
187
205
  } catch (parseError) {
188
206
  console.error("Error parsing JSON:", parseError);
189
207
  await callbacks.onError(
@@ -292,9 +310,9 @@ var RagbitsClient = class {
292
310
  console.error("\u274C Invalid base64 data: ", e);
293
311
  await callbacks.onError(new Error("Error reading stream"));
294
312
  }
295
- if (contentType === ChatResponseType.Image) {
313
+ if (contentType === "image") {
296
314
  const completeImageResponse = {
297
- type: ChatResponseType.Image,
315
+ type: "image",
298
316
  content: {
299
317
  id,
300
318
  url: `${imageInfo.mimeType},${completeBase64}`
@@ -308,9 +326,9 @@ var RagbitsClient = class {
308
326
  // Annotate the CommonJS export names for ESM import in node:
309
327
  0 && (module.exports = {
310
328
  AuthType,
311
- ChatResponseType,
312
329
  FeedbackType,
313
330
  LiveUpdateType,
314
331
  MessageRole,
315
- RagbitsClient
332
+ RagbitsClient,
333
+ TaskStatus
316
334
  });
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ClientConfig, StreamCallbacks, BaseApiEndpoints, EndpointDefinition, EndpointResponse, RequestOptions, BaseStreamingEndpoints, EndpointRequest } from './types';
1
+ import type { ClientConfig, StreamCallbacks, BaseApiEndpoints, EndpointDefinition, EndpointResponse, BaseStreamingEndpoints, EndpointRequest, MakeRequestOptions } from './types';
2
2
  /**
3
3
  * Client for communicating with the Ragbits API
4
4
  */
@@ -30,8 +30,8 @@ export declare class RagbitsClient {
30
30
  * @param options - Typed request options for the specific endpoint
31
31
  */
32
32
  makeRequest<Endpoints extends {
33
- [K in keyof Endpoints]: EndpointDefinition;
34
- } = BaseApiEndpoints, URL extends keyof Endpoints = keyof Endpoints>(endpoint: URL, options?: RequestOptions<URL, Endpoints>): Promise<EndpointResponse<URL, Endpoints>>;
33
+ [K in keyof Endpoints]: EndpointDefinition<any, any, any, any>;
34
+ } = BaseApiEndpoints, URL extends keyof Endpoints = keyof Endpoints>(endpoint: URL, ...args: MakeRequestOptions<URL, Endpoints>): Promise<EndpointResponse<URL, Endpoints>>;
35
35
  /**
36
36
  * Method for streaming requests to known endpoints only
37
37
  * @param endpoint - Streaming endpoint path
@@ -40,7 +40,7 @@ export declare class RagbitsClient {
40
40
  * @param signal - Optional AbortSignal for cancelling the request
41
41
  */
42
42
  makeStreamRequest<Endpoints extends {
43
- [K in keyof Endpoints]: EndpointDefinition;
43
+ [K in keyof Endpoints]: EndpointDefinition<any, any, any, any>;
44
44
  } = BaseStreamingEndpoints, URL extends keyof Endpoints = keyof Endpoints>(endpoint: URL, data: EndpointRequest<URL, Endpoints>, callbacks: StreamCallbacks<EndpointResponse<URL, Endpoints>>, signal?: AbortSignal, customHeaders?: Record<string, string>): () => void;
45
45
  private normalizeHeaders;
46
46
  private handleChunkedContent;
package/dist/index.js CHANGED
@@ -1,17 +1,4 @@
1
1
  // src/autogen.types.ts
2
- var ChatResponseType = {
3
- Text: "text",
4
- Reference: "reference",
5
- StateUpdate: "state_update",
6
- MessageId: "message_id",
7
- ConversationId: "conversation_id",
8
- LiveUpdate: "live_update",
9
- FollowupMessages: "followup_messages",
10
- Image: "image",
11
- ChunkedContent: "chunked_content",
12
- ClearMessage: "clear_message",
13
- Usage: "usage"
14
- };
15
2
  var FeedbackType = {
16
3
  Like: "like",
17
4
  Dislike: "dislike"
@@ -25,6 +12,14 @@ var MessageRole = {
25
12
  Assistant: "assistant",
26
13
  System: "system"
27
14
  };
15
+ var TaskStatus = {
16
+ Pending: "pending",
17
+ InProgress: "in_progress",
18
+ Completed: "completed",
19
+ Failed: "failed",
20
+ Cancelled: "cancelled",
21
+ Retrying: "retrying"
22
+ };
28
23
  var AuthType = {
29
24
  Credentials: "credentials"
30
25
  };
@@ -94,10 +89,13 @@ var RagbitsClient = class {
94
89
  * @param endpoint - API endpoint path
95
90
  * @param options - Typed request options for the specific endpoint
96
91
  */
97
- async makeRequest(endpoint, options) {
92
+ async makeRequest(endpoint, ...args) {
93
+ const options = args[0];
98
94
  const {
99
95
  method = "GET",
100
96
  body,
97
+ pathParams,
98
+ queryParams,
101
99
  headers = {},
102
100
  ...restOptions
103
101
  } = options || {};
@@ -105,15 +103,32 @@ var RagbitsClient = class {
105
103
  method,
106
104
  headers,
107
105
  ...restOptions
108
- // This will include signal and other fetch options
109
106
  };
110
107
  if (body && method !== "GET") {
111
108
  requestOptions.body = typeof body === "string" ? body : JSON.stringify(body);
112
109
  }
113
- const response = await this._makeRequest(
114
- this._buildApiUrl(endpoint.toString()),
115
- requestOptions
116
- );
110
+ let url = endpoint.toString();
111
+ if (pathParams) {
112
+ url = url.replace(/:([^/]+)/g, (_, paramName) => {
113
+ if (paramName in pathParams) {
114
+ const value = pathParams[paramName];
115
+ return encodeURIComponent(String(value));
116
+ } else {
117
+ throw new Error(`Path parameter ${paramName} is required`);
118
+ }
119
+ });
120
+ }
121
+ if (queryParams && Object.keys(queryParams).length > 0) {
122
+ const searchParams = new URLSearchParams();
123
+ for (const [key, value] of Object.entries(queryParams)) {
124
+ if (value !== void 0 && value !== null) {
125
+ searchParams.append(key, String(value));
126
+ }
127
+ }
128
+ url += `?${searchParams.toString()}`;
129
+ }
130
+ url = this._buildApiUrl(url);
131
+ const response = await this._makeRequest(url, requestOptions);
117
132
  return response.json();
118
133
  }
119
134
  /**
@@ -148,11 +163,14 @@ var RagbitsClient = class {
148
163
  const parsedData = JSON.parse(
149
164
  jsonString
150
165
  );
151
- if (parsedData.type === ChatResponseType.ChunkedContent) {
166
+ if (parsedData.type === "chunked_content") {
152
167
  this.handleChunkedContent(parsedData, callbacks);
153
168
  continue;
154
169
  }
155
170
  await callbacks.onMessage(parsedData);
171
+ await new Promise(
172
+ (resolve) => setTimeout(resolve, 0)
173
+ );
156
174
  } catch (parseError) {
157
175
  console.error("Error parsing JSON:", parseError);
158
176
  await callbacks.onError(
@@ -261,9 +279,9 @@ var RagbitsClient = class {
261
279
  console.error("\u274C Invalid base64 data: ", e);
262
280
  await callbacks.onError(new Error("Error reading stream"));
263
281
  }
264
- if (contentType === ChatResponseType.Image) {
282
+ if (contentType === "image") {
265
283
  const completeImageResponse = {
266
- type: ChatResponseType.Image,
284
+ type: "image",
267
285
  content: {
268
286
  id,
269
287
  url: `${imageInfo.mimeType},${completeBase64}`
@@ -276,9 +294,9 @@ var RagbitsClient = class {
276
294
  };
277
295
  export {
278
296
  AuthType,
279
- ChatResponseType,
280
297
  FeedbackType,
281
298
  LiveUpdateType,
282
299
  MessageRole,
283
- RagbitsClient
300
+ RagbitsClient,
301
+ TaskStatus
284
302
  };
package/dist/types.d.ts CHANGED
@@ -20,10 +20,12 @@ export interface StreamCallbacks<T, E = Error> {
20
20
  onError: (error: E) => void | Promise<void>;
21
21
  onClose?: () => void | Promise<void>;
22
22
  }
23
- export interface EndpointDefinition<Req = any, Res = any> {
23
+ export interface EndpointDefinition<Req = any, Res = any, PathParams = never, QueryParams = never> {
24
24
  method: string;
25
25
  request: Req;
26
26
  response: Res;
27
+ pathParams: PathParams;
28
+ queryParams: QueryParams;
27
29
  }
28
30
  /**
29
31
  * Base predefined API endpoint definitions with their request/response types
@@ -33,6 +35,7 @@ export interface BaseApiEndpoints {
33
35
  '/api/feedback': EndpointDefinition<FeedbackRequest, FeedbackResponse>;
34
36
  '/api/auth/login': EndpointDefinition<LoginRequest, LoginResponse>;
35
37
  '/api/auth/logout': EndpointDefinition<LogoutRequest, GenericResponse>;
38
+ '/api/theme': EndpointDefinition<never, string>;
36
39
  }
37
40
  /**
38
41
  * Streaming API endpoint definitions with their request/stream response types
@@ -44,34 +47,86 @@ export interface BaseStreamingEndpoints {
44
47
  * Extract endpoint paths as a union type
45
48
  */
46
49
  export type EndpointPath<Endpoints extends {
47
- [K in keyof Endpoints]: EndpointDefinition;
50
+ [K in keyof Endpoints]: EndpointDefinition<any, any, any, any>;
48
51
  }> = keyof Endpoints;
49
52
  /**
50
53
  * Extract request type for a specific API endpoint
51
54
  */
52
55
  export type EndpointRequest<URL extends keyof Endpoints, Endpoints extends {
53
- [K in keyof Endpoints]: EndpointDefinition;
56
+ [K in keyof Endpoints]: EndpointDefinition<any, any, any, any>;
54
57
  }> = Endpoints[URL]['request'];
55
58
  /**
56
59
  * Extract response type for a specific API endpoint
57
60
  */
58
61
  export type EndpointResponse<URL extends keyof Endpoints, Endpoints extends {
59
- [K in keyof Endpoints]: EndpointDefinition;
62
+ [K in keyof Endpoints]: EndpointDefinition<any, any, any, any>;
60
63
  }> = Endpoints[URL]['response'];
61
64
  /**
62
65
  * Extract HTTP method for a specific API endpoint
63
66
  */
64
67
  export type EndpointMethod<URL extends keyof Endpoints, Endpoints extends {
65
- [K in keyof Endpoints]: EndpointDefinition;
68
+ [K in keyof Endpoints]: EndpointDefinition<any, any, any, any>;
66
69
  }> = Endpoints[URL]['method'];
67
70
  /**
68
- * Generic request options for API endpoints with typed methods and body
71
+ * Check if an object type has any required properties
72
+ * - {} extends T means all properties are optional → false
73
+ * - {} doesn't extend T means at least one property is required → true
69
74
  */
70
- export interface RequestOptions<URL extends keyof Endpoints, Endpoints extends {
71
- [K in keyof Endpoints]: EndpointDefinition;
72
- }> {
75
+ export type HasRequiredKeys<T> = [T] extends [never] ? false : {} extends T ? false : true;
76
+ /**
77
+ * Generic request options for API endpoints with typed methods, path params, query params, and body
78
+ * - pathParams is REQUIRED when PathParams is not never
79
+ * - queryParams is REQUIRED when it has required keys inside
80
+ * - queryParams is OPTIONAL when all keys are optional or it's never
81
+ * - body is REQUIRED when it's a specific type (not never, not undefined)
82
+ * - body is OPTIONAL when it's never or undefined
83
+ */
84
+ export type RequestOptions<URL extends keyof Endpoints, Endpoints extends {
85
+ [K in keyof Endpoints]: EndpointDefinition<any, any, any, any>;
86
+ }> = {
73
87
  method?: Endpoints[URL]['method'];
74
- body?: Endpoints[URL]['request'] extends never ? undefined : Endpoints[URL]['request'];
75
88
  headers?: Record<string, string>;
76
89
  signal?: AbortSignal;
77
- }
90
+ } & (Endpoints[URL]['pathParams'] extends never ? {
91
+ pathParams?: never;
92
+ } : {
93
+ pathParams: Endpoints[URL]['pathParams'];
94
+ }) & (Endpoints[URL]['queryParams'] extends never ? {
95
+ queryParams?: never;
96
+ } : HasRequiredKeys<Endpoints[URL]['queryParams']> extends true ? {
97
+ queryParams: Endpoints[URL]['queryParams'];
98
+ } : {
99
+ queryParams?: Endpoints[URL]['queryParams'];
100
+ }) & // All properties optional
101
+ (Endpoints[URL]['request'] extends never ? {
102
+ body?: never;
103
+ } : Endpoints[URL]['request'] extends undefined ? {
104
+ body?: Endpoints[URL]['request'];
105
+ } : {
106
+ body: Endpoints[URL]['request'];
107
+ });
108
+ /**
109
+ * Check if a type is not never and not undefined
110
+ */
111
+ export type IsRequired<T> = [T] extends [never] ? false : T extends undefined ? false : true;
112
+ /**
113
+ * Check if an endpoint has any required parameters
114
+ * Returns true if any of these conditions are met:
115
+ * - pathParams is defined (not never), OR
116
+ * - queryParams has any required keys inside, OR
117
+ * - body/request is required (not never, not undefined)
118
+ */
119
+ export type HasRequiredParams<URL extends keyof Endpoints, Endpoints extends {
120
+ [K in keyof Endpoints]: EndpointDefinition<any, any, any, any>;
121
+ }> = Endpoints[URL]['pathParams'] extends never ? HasRequiredKeys<Endpoints[URL]['queryParams']> extends true ? true : IsRequired<Endpoints[URL]['request']> : true;
122
+ /**
123
+ * Conditional options parameter for makeRequest
124
+ * - Required if endpoint has:
125
+ * - pathParams, OR
126
+ * - queryParams with specific type (not undefined), OR
127
+ * - body with specific type (not undefined)
128
+ * - Optional otherwise
129
+ */
130
+ export type MakeRequestOptions<URL extends keyof Endpoints, Endpoints extends {
131
+ [K in keyof Endpoints]: EndpointDefinition<any, any, any, any>;
132
+ }> = HasRequiredParams<URL, Endpoints> extends true ? [options: RequestOptions<URL, Endpoints>] : [options?: RequestOptions<URL, Endpoints>];
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@ragbits/api-client",
3
- "version": "1.3.0",
3
+ "version": "1.4.0-dev.202512050236",
4
4
  "description": "JavaScript client for the Ragbits API",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/deepsense-ai/ragbits"
8
- },
8
+ },
9
9
  "main": "dist/index.cjs",
10
10
  "module": "dist/index.js",
11
11
  "types": "dist/index.d.ts",
@@ -40,7 +40,7 @@
40
40
  "@rjsf/utils": "^5.24.12",
41
41
  "@testing-library/jest-dom": "^6.4.0",
42
42
  "@types/node": "^20.0.0",
43
- "@vitest/coverage-v8": "^1.6.0",
43
+ "@vitest/coverage-v8": "^4.0.7",
44
44
  "eslint": "^9.17.0",
45
45
  "globals": "^15.14.0",
46
46
  "msw": "^2.0.0",
@@ -48,6 +48,6 @@
48
48
  "tsup": "^8.0.0",
49
49
  "typescript": "^5.0.0",
50
50
  "typescript-eslint": "^8.18.2",
51
- "vitest": "^1.6.0"
51
+ "vitest": "^4.0.7"
52
52
  }
53
53
  }