@ragbits/api-client 1.4.0-dev.202512050236 → 1.4.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.
@@ -30,23 +30,12 @@ export declare const MessageRole: {
30
30
  readonly System: "system";
31
31
  };
32
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>;
45
33
  /**
46
34
  * Represents the AuthType enum
47
35
  */
48
36
  export declare const AuthType: {
49
37
  readonly Credentials: "credentials";
38
+ readonly Oauth2: "oauth2";
50
39
  };
51
40
  export type AuthType = TypeFrom<typeof AuthType>;
52
41
  /**
@@ -61,11 +50,9 @@ export interface ChatContext {
61
50
  user: User | null;
62
51
  session_id: string | null;
63
52
  /**
64
- * List of confirmed/declined tools from the frontend
53
+ * User's timezone in IANA format (e.g., 'Europe/Warsaw', 'America/New_York')
65
54
  */
66
- confirmed_tools: {
67
- [k: string]: unknown;
68
- }[] | null;
55
+ timezone: string | null;
69
56
  [k: string]: unknown;
70
57
  }
71
58
  /**
@@ -154,33 +141,6 @@ export interface MessageUsage {
154
141
  completion_tokens: number;
155
142
  total_tokens: number;
156
143
  }
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
144
  /**
185
145
  * Text content wrapper.
186
146
  */
@@ -220,16 +180,10 @@ export interface UsageContent {
220
180
  };
221
181
  }
222
182
  /**
223
- * Todo item content wrapper.
224
- */
225
- export interface TodoItemContent {
226
- task: Task;
227
- }
228
- /**
229
- * Confirmation request content wrapper.
183
+ * Error content wrapper for displaying error messages to users.
230
184
  */
231
- export interface ConfirmationRequestContent {
232
- confirmation_request: ConfirmationRequest;
185
+ export interface ErrorContent {
186
+ message: string;
233
187
  }
234
188
  /**
235
189
  * Customization for the header section of the UI.
@@ -304,6 +258,10 @@ export interface ConfigResponse {
304
258
  */
305
259
  customization: UICustomization | null;
306
260
  user_settings: UserSettings;
261
+ /**
262
+ * Flag indicating whether API supports file upload
263
+ */
264
+ supports_upload: boolean;
307
265
  /**
308
266
  * Debug mode flag
309
267
  */
@@ -327,6 +285,48 @@ export interface FeedbackResponse {
327
285
  */
328
286
  status: string;
329
287
  }
288
+ /**
289
+ * Response for OAuth2 authorization URL request
290
+ */
291
+ export interface OAuth2AuthorizeResponse {
292
+ /**
293
+ * URL to redirect user to for OAuth2 authorization
294
+ */
295
+ authorize_url: string;
296
+ /**
297
+ * State parameter for CSRF protection
298
+ */
299
+ state: string;
300
+ }
301
+ /**
302
+ * Configuration for an OAuth2 provider including visual configuration.
303
+ */
304
+ export interface OAuth2ProviderConfig {
305
+ /**
306
+ * Provider name (e.g., 'discord')
307
+ */
308
+ name: string;
309
+ /**
310
+ * Display name for the provider (e.g., 'Discord')
311
+ */
312
+ display_name: string | null;
313
+ /**
314
+ * Brand color for the provider (e.g., '#5865F2')
315
+ */
316
+ color: string | null;
317
+ /**
318
+ * Button background color (defaults to color)
319
+ */
320
+ button_color: string | null;
321
+ /**
322
+ * Button text color (defaults to white)
323
+ */
324
+ text_color: string | null;
325
+ /**
326
+ * SVG icon as string
327
+ */
328
+ icon_svg: string | null;
329
+ }
330
330
  /**
331
331
  * Client-side chat request interface.
332
332
  */
@@ -377,45 +377,30 @@ export interface AuthenticationConfig {
377
377
  * List of available authentication types
378
378
  */
379
379
  auth_types: AuthType[];
380
- }
381
- /**
382
- * Request body for user login
383
- */
384
- export interface CredentialsLoginRequest {
385
- /**
386
- * Username
387
- */
388
- username: string;
389
380
  /**
390
- * Password
381
+ * List of available OAuth2 providers
391
382
  */
392
- password: string;
383
+ oauth2_providers: OAuth2ProviderConfig[];
393
384
  }
394
385
  /**
395
- * Represents a JWT authentication jwt_token.
386
+ * Represents user login credentials.
396
387
  */
397
- export interface JWTToken {
398
- access_token: string;
399
- token_type: string;
400
- expires_in: number;
401
- refresh_token: string | null;
402
- user: User;
388
+ export interface UserCredentials {
389
+ username: string;
390
+ password: string;
403
391
  }
404
392
  /**
405
- * Request body for user login
393
+ * Represents user login credentials.
406
394
  */
407
395
  export interface LoginRequest {
408
- /**
409
- * Username
410
- */
411
396
  username: string;
412
- /**
413
- * Password
414
- */
415
397
  password: string;
416
398
  }
417
399
  /**
418
- * Response body for successful login
400
+ * Response body for login with session-based authentication.
401
+ *
402
+ * The session ID is set as an HTTP-only cookie by the backend.
403
+ * Frontend only receives user information.
419
404
  */
420
405
  export interface LoginResponse {
421
406
  /**
@@ -430,19 +415,6 @@ export interface LoginResponse {
430
415
  * Error message if login failed
431
416
  */
432
417
  error_message: string | null;
433
- /**
434
- * Access jwt_token
435
- */
436
- jwt_token: JWTToken | null;
437
- }
438
- /**
439
- * Request body for user logout
440
- */
441
- export interface LogoutRequest {
442
- /**
443
- * Session ID to logout
444
- */
445
- token: string;
446
418
  }
447
419
  /**
448
420
  * Represents an authenticated user.
@@ -500,17 +472,13 @@ export interface ClearMessageChatResponse {
500
472
  type: 'clear_message';
501
473
  content: unknown;
502
474
  }
503
- export interface TodoItemChatResonse {
504
- type: 'todo_item';
505
- content: TodoItemContent;
506
- }
507
475
  export interface ConversationSummaryResponse {
508
476
  type: 'conversation_summary';
509
477
  content: ConversationSummaryContent;
510
478
  }
511
- export interface ConfirmationRequestChatResponse {
512
- type: 'confirmation_request';
513
- content: ConfirmationRequestContent;
479
+ export interface ErrorChatResponse {
480
+ type: 'error';
481
+ content: ErrorContent;
514
482
  }
515
483
  export interface ChunkedChatResponse {
516
484
  type: 'chunked_content';
@@ -519,4 +487,4 @@ export interface ChunkedChatResponse {
519
487
  /**
520
488
  * Typed chat response union
521
489
  */
522
- export type ChatResponse = TextChatResponse | ReferenceChatResponse | MessageIdChatResponse | ConversationIdChatResponse | StateUpdateChatResponse | LiveUpdateChatResponse | FollowupMessagesChatResponse | ImageChatResponse | MessageUsageChatResponse | ClearMessageChatResponse | TodoItemChatResonse | ConversationSummaryResponse | ConfirmationRequestChatResponse;
490
+ export type ChatResponse = TextChatResponse | ReferenceChatResponse | MessageIdChatResponse | ConversationIdChatResponse | StateUpdateChatResponse | LiveUpdateChatResponse | FollowupMessagesChatResponse | ImageChatResponse | MessageUsageChatResponse | ClearMessageChatResponse | ConversationSummaryResponse | ErrorChatResponse;
package/dist/index.cjs CHANGED
@@ -24,8 +24,7 @@ __export(index_exports, {
24
24
  FeedbackType: () => FeedbackType,
25
25
  LiveUpdateType: () => LiveUpdateType,
26
26
  MessageRole: () => MessageRole,
27
- RagbitsClient: () => RagbitsClient,
28
- TaskStatus: () => TaskStatus
27
+ RagbitsClient: () => RagbitsClient
29
28
  });
30
29
  module.exports = __toCommonJS(index_exports);
31
30
 
@@ -43,16 +42,9 @@ var MessageRole = {
43
42
  Assistant: "assistant",
44
43
  System: "system"
45
44
  };
46
- var TaskStatus = {
47
- Pending: "pending",
48
- InProgress: "in_progress",
49
- Completed: "completed",
50
- Failed: "failed",
51
- Cancelled: "cancelled",
52
- Retrying: "retrying"
53
- };
54
45
  var AuthType = {
55
- Credentials: "credentials"
46
+ Credentials: "credentials",
47
+ Oauth2: "oauth2"
56
48
  };
57
49
 
58
50
  // src/index.ts
@@ -99,6 +91,9 @@ var RagbitsClient = class {
99
91
  const defaultHeaders = {
100
92
  "Content-Type": "application/json"
101
93
  };
94
+ if (options.body instanceof FormData) {
95
+ delete defaultHeaders["Content-Type"];
96
+ }
102
97
  const headers = {
103
98
  ...defaultHeaders,
104
99
  ...this.normalizeHeaders(options.headers)
@@ -106,7 +101,11 @@ var RagbitsClient = class {
106
101
  if (this.auth?.getToken) {
107
102
  headers["Authorization"] = `Bearer ${this.auth.getToken()}`;
108
103
  }
109
- const response = await fetch(url, { ...options, headers });
104
+ const response = await fetch(url, {
105
+ ...options,
106
+ headers,
107
+ ...this.auth?.credentials ? { credentials: this.auth?.credentials } : {}
108
+ });
110
109
  if (response.status === 401) {
111
110
  this.auth?.onUnauthorized?.();
112
111
  }
@@ -136,10 +135,17 @@ var RagbitsClient = class {
136
135
  ...restOptions
137
136
  };
138
137
  if (body && method !== "GET") {
139
- requestOptions.body = typeof body === "string" ? body : JSON.stringify(body);
138
+ if (body instanceof FormData) {
139
+ requestOptions.body = body;
140
+ if (requestOptions.headers && "Content-Type" in requestOptions.headers) {
141
+ delete requestOptions.headers["Content-Type"];
142
+ }
143
+ } else {
144
+ requestOptions.body = typeof body === "string" ? body : JSON.stringify(body);
145
+ }
140
146
  }
141
147
  let url = endpoint.toString();
142
- if (pathParams) {
148
+ if (pathParams && typeof pathParams === "object") {
143
149
  url = url.replace(/:([^/]+)/g, (_, paramName) => {
144
150
  if (paramName in pathParams) {
145
151
  const value = pathParams[paramName];
@@ -191,17 +197,19 @@ var RagbitsClient = class {
191
197
  if (!line.startsWith("data: ")) continue;
192
198
  try {
193
199
  const jsonString = line.replace("data: ", "").trim();
194
- const parsedData = JSON.parse(
195
- jsonString
196
- );
200
+ const parsedData = JSON.parse(jsonString);
201
+ if (!this.isChatResponse(parsedData)) {
202
+ console.warn(
203
+ "Received response that isn't ChatResponse, skipping.",
204
+ parsedData
205
+ );
206
+ continue;
207
+ }
197
208
  if (parsedData.type === "chunked_content") {
198
209
  this.handleChunkedContent(parsedData, callbacks);
199
210
  continue;
200
211
  }
201
212
  await callbacks.onMessage(parsedData);
202
- await new Promise(
203
- (resolve) => setTimeout(resolve, 0)
204
- );
205
213
  } catch (parseError) {
206
214
  console.error("Error parsing JSON:", parseError);
207
215
  await callbacks.onError(
@@ -238,7 +246,8 @@ var RagbitsClient = class {
238
246
  method: "POST",
239
247
  headers,
240
248
  body: JSON.stringify(data),
241
- signal
249
+ signal,
250
+ ...this.auth?.credentials ? { credentials: this.auth?.credentials } : {}
242
251
  }
243
252
  );
244
253
  if (response.status === 401) {
@@ -267,6 +276,9 @@ var RagbitsClient = class {
267
276
  isCancelled = true;
268
277
  };
269
278
  }
279
+ isChatResponse(response) {
280
+ return response !== null && typeof response === "object" && "type" in response && "content" in response;
281
+ }
270
282
  normalizeHeaders(init) {
271
283
  if (!init) return {};
272
284
  if (init instanceof Headers) {
@@ -329,6 +341,5 @@ var RagbitsClient = class {
329
341
  FeedbackType,
330
342
  LiveUpdateType,
331
343
  MessageRole,
332
- RagbitsClient,
333
- TaskStatus
344
+ RagbitsClient
334
345
  });
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ClientConfig, StreamCallbacks, BaseApiEndpoints, EndpointDefinition, EndpointResponse, BaseStreamingEndpoints, EndpointRequest, MakeRequestOptions } from './types';
1
+ import type { ClientConfig, StreamCallbacks, BaseApiEndpoints, EndpointResponse, BaseStreamingEndpoints, EndpointRequest, MakeRequestOptions, AnyEndpoints } from './types';
2
2
  /**
3
3
  * Client for communicating with the Ragbits API
4
4
  */
@@ -29,9 +29,7 @@ export declare class RagbitsClient {
29
29
  * @param endpoint - API endpoint path
30
30
  * @param options - Typed request options for the specific endpoint
31
31
  */
32
- makeRequest<Endpoints extends {
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>>;
32
+ makeRequest<Endpoints extends AnyEndpoints<Endpoints> = BaseApiEndpoints, URL extends keyof Endpoints = keyof Endpoints>(endpoint: URL, ...args: MakeRequestOptions<URL, Endpoints>): Promise<EndpointResponse<URL, Endpoints>>;
35
33
  /**
36
34
  * Method for streaming requests to known endpoints only
37
35
  * @param endpoint - Streaming endpoint path
@@ -39,9 +37,8 @@ export declare class RagbitsClient {
39
37
  * @param callbacks - Stream callbacks
40
38
  * @param signal - Optional AbortSignal for cancelling the request
41
39
  */
42
- makeStreamRequest<Endpoints extends {
43
- [K in keyof Endpoints]: EndpointDefinition<any, any, any, any>;
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;
40
+ makeStreamRequest<Endpoints extends AnyEndpoints<Endpoints> = 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;
41
+ private isChatResponse;
45
42
  private normalizeHeaders;
46
43
  private handleChunkedContent;
47
44
  }
package/dist/index.js CHANGED
@@ -12,16 +12,9 @@ var MessageRole = {
12
12
  Assistant: "assistant",
13
13
  System: "system"
14
14
  };
15
- var TaskStatus = {
16
- Pending: "pending",
17
- InProgress: "in_progress",
18
- Completed: "completed",
19
- Failed: "failed",
20
- Cancelled: "cancelled",
21
- Retrying: "retrying"
22
- };
23
15
  var AuthType = {
24
- Credentials: "credentials"
16
+ Credentials: "credentials",
17
+ Oauth2: "oauth2"
25
18
  };
26
19
 
27
20
  // src/index.ts
@@ -68,6 +61,9 @@ var RagbitsClient = class {
68
61
  const defaultHeaders = {
69
62
  "Content-Type": "application/json"
70
63
  };
64
+ if (options.body instanceof FormData) {
65
+ delete defaultHeaders["Content-Type"];
66
+ }
71
67
  const headers = {
72
68
  ...defaultHeaders,
73
69
  ...this.normalizeHeaders(options.headers)
@@ -75,7 +71,11 @@ var RagbitsClient = class {
75
71
  if (this.auth?.getToken) {
76
72
  headers["Authorization"] = `Bearer ${this.auth.getToken()}`;
77
73
  }
78
- const response = await fetch(url, { ...options, headers });
74
+ const response = await fetch(url, {
75
+ ...options,
76
+ headers,
77
+ ...this.auth?.credentials ? { credentials: this.auth?.credentials } : {}
78
+ });
79
79
  if (response.status === 401) {
80
80
  this.auth?.onUnauthorized?.();
81
81
  }
@@ -105,10 +105,17 @@ var RagbitsClient = class {
105
105
  ...restOptions
106
106
  };
107
107
  if (body && method !== "GET") {
108
- requestOptions.body = typeof body === "string" ? body : JSON.stringify(body);
108
+ if (body instanceof FormData) {
109
+ requestOptions.body = body;
110
+ if (requestOptions.headers && "Content-Type" in requestOptions.headers) {
111
+ delete requestOptions.headers["Content-Type"];
112
+ }
113
+ } else {
114
+ requestOptions.body = typeof body === "string" ? body : JSON.stringify(body);
115
+ }
109
116
  }
110
117
  let url = endpoint.toString();
111
- if (pathParams) {
118
+ if (pathParams && typeof pathParams === "object") {
112
119
  url = url.replace(/:([^/]+)/g, (_, paramName) => {
113
120
  if (paramName in pathParams) {
114
121
  const value = pathParams[paramName];
@@ -160,17 +167,19 @@ var RagbitsClient = class {
160
167
  if (!line.startsWith("data: ")) continue;
161
168
  try {
162
169
  const jsonString = line.replace("data: ", "").trim();
163
- const parsedData = JSON.parse(
164
- jsonString
165
- );
170
+ const parsedData = JSON.parse(jsonString);
171
+ if (!this.isChatResponse(parsedData)) {
172
+ console.warn(
173
+ "Received response that isn't ChatResponse, skipping.",
174
+ parsedData
175
+ );
176
+ continue;
177
+ }
166
178
  if (parsedData.type === "chunked_content") {
167
179
  this.handleChunkedContent(parsedData, callbacks);
168
180
  continue;
169
181
  }
170
182
  await callbacks.onMessage(parsedData);
171
- await new Promise(
172
- (resolve) => setTimeout(resolve, 0)
173
- );
174
183
  } catch (parseError) {
175
184
  console.error("Error parsing JSON:", parseError);
176
185
  await callbacks.onError(
@@ -207,7 +216,8 @@ var RagbitsClient = class {
207
216
  method: "POST",
208
217
  headers,
209
218
  body: JSON.stringify(data),
210
- signal
219
+ signal,
220
+ ...this.auth?.credentials ? { credentials: this.auth?.credentials } : {}
211
221
  }
212
222
  );
213
223
  if (response.status === 401) {
@@ -236,6 +246,9 @@ var RagbitsClient = class {
236
246
  isCancelled = true;
237
247
  };
238
248
  }
249
+ isChatResponse(response) {
250
+ return response !== null && typeof response === "object" && "type" in response && "content" in response;
251
+ }
239
252
  normalizeHeaders(init) {
240
253
  if (!init) return {};
241
254
  if (init instanceof Headers) {
@@ -297,6 +310,5 @@ export {
297
310
  FeedbackType,
298
311
  LiveUpdateType,
299
312
  MessageRole,
300
- RagbitsClient,
301
- TaskStatus
313
+ RagbitsClient
302
314
  };
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ConfigResponse, FeedbackRequest, FeedbackResponse, ChatRequest, ChatResponse, LogoutRequest, LoginRequest, LoginResponse } from './autogen.types';
1
+ import { ConfigResponse, FeedbackRequest, FeedbackResponse, ChatRequest, ChatResponse, LoginRequest, LoginResponse, User, OAuth2AuthorizeResponse } from './autogen.types';
2
2
  export interface GenericResponse {
3
3
  success: boolean;
4
4
  }
@@ -10,6 +10,7 @@ export interface ClientConfig {
10
10
  auth?: {
11
11
  getToken?: () => string;
12
12
  onUnauthorized?: () => Promise<void> | void;
13
+ credentials?: RequestCredentials;
13
14
  };
14
15
  }
15
16
  /**
@@ -20,7 +21,7 @@ export interface StreamCallbacks<T, E = Error> {
20
21
  onError: (error: E) => void | Promise<void>;
21
22
  onClose?: () => void | Promise<void>;
22
23
  }
23
- export interface EndpointDefinition<Req = any, Res = any, PathParams = never, QueryParams = never> {
24
+ export interface EndpointDefinition<Req = unknown, Res = unknown, PathParams = never, QueryParams = never> {
24
25
  method: string;
25
26
  request: Req;
26
27
  response: Res;
@@ -34,8 +35,16 @@ export interface BaseApiEndpoints {
34
35
  '/api/config': EndpointDefinition<never, ConfigResponse>;
35
36
  '/api/feedback': EndpointDefinition<FeedbackRequest, FeedbackResponse>;
36
37
  '/api/auth/login': EndpointDefinition<LoginRequest, LoginResponse>;
37
- '/api/auth/logout': EndpointDefinition<LogoutRequest, GenericResponse>;
38
+ '/api/auth/logout': EndpointDefinition<never, GenericResponse>;
39
+ '/api/auth/authorize/:provider': EndpointDefinition<never, OAuth2AuthorizeResponse, {
40
+ provider: string;
41
+ }>;
42
+ '/api/user': EndpointDefinition<never, User>;
38
43
  '/api/theme': EndpointDefinition<never, string>;
44
+ '/api/upload': EndpointDefinition<FormData, {
45
+ status: string;
46
+ filename: string;
47
+ }>;
39
48
  }
40
49
  /**
41
50
  * Streaming API endpoint definitions with their request/stream response types
@@ -43,36 +52,32 @@ export interface BaseApiEndpoints {
43
52
  export interface BaseStreamingEndpoints {
44
53
  '/api/chat': EndpointDefinition<ChatRequest, ChatResponse>;
45
54
  }
55
+ type AnyEndpointDefinition = EndpointDefinition<unknown, unknown, unknown, unknown>;
56
+ export type AnyEndpoints<T> = {
57
+ [K in keyof T]: AnyEndpointDefinition;
58
+ };
46
59
  /**
47
60
  * Extract endpoint paths as a union type
48
61
  */
49
- export type EndpointPath<Endpoints extends {
50
- [K in keyof Endpoints]: EndpointDefinition<any, any, any, any>;
51
- }> = keyof Endpoints;
62
+ export type EndpointPath<Endpoints extends AnyEndpoints<Endpoints>> = keyof Endpoints;
52
63
  /**
53
64
  * Extract request type for a specific API endpoint
54
65
  */
55
- export type EndpointRequest<URL extends keyof Endpoints, Endpoints extends {
56
- [K in keyof Endpoints]: EndpointDefinition<any, any, any, any>;
57
- }> = Endpoints[URL]['request'];
66
+ export type EndpointRequest<URL extends keyof Endpoints, Endpoints extends AnyEndpoints<Endpoints>> = Endpoints[URL]['request'];
58
67
  /**
59
68
  * Extract response type for a specific API endpoint
60
69
  */
61
- export type EndpointResponse<URL extends keyof Endpoints, Endpoints extends {
62
- [K in keyof Endpoints]: EndpointDefinition<any, any, any, any>;
63
- }> = Endpoints[URL]['response'];
70
+ export type EndpointResponse<URL extends keyof Endpoints, Endpoints extends AnyEndpoints<Endpoints>> = Endpoints[URL]['response'];
64
71
  /**
65
72
  * Extract HTTP method for a specific API endpoint
66
73
  */
67
- export type EndpointMethod<URL extends keyof Endpoints, Endpoints extends {
68
- [K in keyof Endpoints]: EndpointDefinition<any, any, any, any>;
69
- }> = Endpoints[URL]['method'];
74
+ export type EndpointMethod<URL extends keyof Endpoints, Endpoints extends AnyEndpoints<Endpoints>> = Endpoints[URL]['method'];
70
75
  /**
71
76
  * Check if an object type has any required properties
72
77
  * - {} extends T means all properties are optional → false
73
78
  * - {} doesn't extend T means at least one property is required → true
74
79
  */
75
- export type HasRequiredKeys<T> = [T] extends [never] ? false : {} extends T ? false : true;
80
+ export type HasRequiredKeys<T> = [T] extends [never] ? false : NonNullable<unknown> extends T ? false : true;
76
81
  /**
77
82
  * Generic request options for API endpoints with typed methods, path params, query params, and body
78
83
  * - pathParams is REQUIRED when PathParams is not never
@@ -81,9 +86,7 @@ export type HasRequiredKeys<T> = [T] extends [never] ? false : {} extends T ? fa
81
86
  * - body is REQUIRED when it's a specific type (not never, not undefined)
82
87
  * - body is OPTIONAL when it's never or undefined
83
88
  */
84
- export type RequestOptions<URL extends keyof Endpoints, Endpoints extends {
85
- [K in keyof Endpoints]: EndpointDefinition<any, any, any, any>;
86
- }> = {
89
+ export type RequestOptions<URL extends keyof Endpoints, Endpoints extends AnyEndpoints<Endpoints>> = {
87
90
  method?: Endpoints[URL]['method'];
88
91
  headers?: Record<string, string>;
89
92
  signal?: AbortSignal;
@@ -116,9 +119,7 @@ export type IsRequired<T> = [T] extends [never] ? false : T extends undefined ?
116
119
  * - queryParams has any required keys inside, OR
117
120
  * - body/request is required (not never, not undefined)
118
121
  */
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
+ export type HasRequiredParams<URL extends keyof Endpoints, Endpoints extends AnyEndpoints<Endpoints>> = Endpoints[URL]['pathParams'] extends never ? HasRequiredKeys<Endpoints[URL]['queryParams']> extends true ? true : IsRequired<Endpoints[URL]['request']> : true;
122
123
  /**
123
124
  * Conditional options parameter for makeRequest
124
125
  * - Required if endpoint has:
@@ -127,6 +128,5 @@ export type HasRequiredParams<URL extends keyof Endpoints, Endpoints extends {
127
128
  * - body with specific type (not undefined)
128
129
  * - Optional otherwise
129
130
  */
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>];
131
+ export type MakeRequestOptions<URL extends keyof Endpoints, Endpoints extends AnyEndpoints<Endpoints>> = HasRequiredParams<URL, Endpoints> extends true ? [options: RequestOptions<URL, Endpoints>] : [options?: RequestOptions<URL, Endpoints>];
132
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ragbits/api-client",
3
- "version": "1.4.0-dev.202512050236",
3
+ "version": "1.4.0",
4
4
  "description": "JavaScript client for the Ragbits API",
5
5
  "repository": {
6
6
  "type": "git",