exa-js 1.5.13 → 1.6.13

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/dist/index.mjs CHANGED
@@ -1,8 +1,648 @@
1
1
  // src/index.ts
2
2
  import fetch, { Headers } from "cross-fetch";
3
+
4
+ // src/errors.ts
5
+ var HttpStatusCode = /* @__PURE__ */ ((HttpStatusCode2) => {
6
+ HttpStatusCode2[HttpStatusCode2["BadRequest"] = 400] = "BadRequest";
7
+ HttpStatusCode2[HttpStatusCode2["NotFound"] = 404] = "NotFound";
8
+ HttpStatusCode2[HttpStatusCode2["Unauthorized"] = 401] = "Unauthorized";
9
+ HttpStatusCode2[HttpStatusCode2["Forbidden"] = 403] = "Forbidden";
10
+ HttpStatusCode2[HttpStatusCode2["TooManyRequests"] = 429] = "TooManyRequests";
11
+ HttpStatusCode2[HttpStatusCode2["RequestTimeout"] = 408] = "RequestTimeout";
12
+ HttpStatusCode2[HttpStatusCode2["InternalServerError"] = 500] = "InternalServerError";
13
+ HttpStatusCode2[HttpStatusCode2["ServiceUnavailable"] = 503] = "ServiceUnavailable";
14
+ return HttpStatusCode2;
15
+ })(HttpStatusCode || {});
16
+ var ExaError = class extends Error {
17
+ /**
18
+ * Create a new ExaError
19
+ * @param message Error message
20
+ * @param statusCode HTTP status code
21
+ * @param timestamp ISO timestamp from API
22
+ * @param path Path that caused the error
23
+ */
24
+ constructor(message, statusCode, timestamp, path) {
25
+ super(message);
26
+ this.name = "ExaError";
27
+ this.statusCode = statusCode;
28
+ this.timestamp = timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
29
+ this.path = path;
30
+ }
31
+ };
32
+
33
+ // src/websets/base.ts
34
+ var WebsetsBaseClient = class {
35
+ /**
36
+ * Initialize a new Websets base client
37
+ * @param client The Exa client instance
38
+ */
39
+ constructor(client) {
40
+ this.client = client;
41
+ }
42
+ /**
43
+ * Make a request to the Websets API
44
+ * @param endpoint The endpoint path
45
+ * @param method The HTTP method
46
+ * @param data Optional request body data
47
+ * @param params Optional query parameters
48
+ * @returns The response JSON
49
+ * @throws ExaError with API error details if the request fails
50
+ */
51
+ async request(endpoint, method = "POST", data, params) {
52
+ return this.client.request(`/websets${endpoint}`, method, data, params);
53
+ }
54
+ /**
55
+ * Helper to build pagination parameters
56
+ * @param pagination The pagination parameters
57
+ * @returns QueryParams object with pagination parameters
58
+ */
59
+ buildPaginationParams(pagination) {
60
+ const params = {};
61
+ if (!pagination)
62
+ return params;
63
+ if (pagination.cursor)
64
+ params.cursor = pagination.cursor;
65
+ if (pagination.limit)
66
+ params.limit = pagination.limit;
67
+ return params;
68
+ }
69
+ };
70
+
71
+ // src/websets/enrichments.ts
72
+ var WebsetEnrichmentsClient = class extends WebsetsBaseClient {
73
+ /**
74
+ * Create an Enrichment for a Webset
75
+ * @param websetId The ID of the Webset
76
+ * @param params The enrichment parameters
77
+ * @returns The created Webset Enrichment
78
+ */
79
+ async create(websetId, params) {
80
+ return this.request(
81
+ `/v0/websets/${websetId}/enrichments`,
82
+ "POST",
83
+ params
84
+ );
85
+ }
86
+ /**
87
+ * Get an Enrichment by ID
88
+ * @param websetId The ID of the Webset
89
+ * @param id The ID of the Enrichment
90
+ * @returns The Webset Enrichment
91
+ */
92
+ async get(websetId, id) {
93
+ return this.request(
94
+ `/v0/websets/${websetId}/enrichments/${id}`,
95
+ "GET"
96
+ );
97
+ }
98
+ /**
99
+ * Delete an Enrichment
100
+ * @param websetId The ID of the Webset
101
+ * @param id The ID of the Enrichment
102
+ * @returns The deleted Webset Enrichment
103
+ */
104
+ async delete(websetId, id) {
105
+ return this.request(
106
+ `/v0/websets/${websetId}/enrichments/${id}`,
107
+ "DELETE"
108
+ );
109
+ }
110
+ /**
111
+ * Cancel a running Enrichment
112
+ * @param websetId The ID of the Webset
113
+ * @param id The ID of the Enrichment
114
+ * @returns The canceled Webset Enrichment
115
+ */
116
+ async cancel(websetId, id) {
117
+ return this.request(
118
+ `/v0/websets/${websetId}/enrichments/${id}/cancel`,
119
+ "POST"
120
+ );
121
+ }
122
+ };
123
+
124
+ // src/websets/events.ts
125
+ var EventsClient = class extends WebsetsBaseClient {
126
+ /**
127
+ * Initialize a new Events client
128
+ * @param client The Exa client instance
129
+ */
130
+ constructor(client) {
131
+ super(client);
132
+ }
133
+ /**
134
+ * List all Events
135
+ * @param options Optional filtering and pagination options
136
+ * @returns The list of Events
137
+ */
138
+ async list(options) {
139
+ const params = {
140
+ cursor: options?.cursor,
141
+ limit: options?.limit,
142
+ types: options?.types
143
+ };
144
+ return this.request(
145
+ "/v0/events",
146
+ "GET",
147
+ void 0,
148
+ params
149
+ );
150
+ }
151
+ /**
152
+ * Get an Event by ID
153
+ * @param id The ID of the Event
154
+ * @returns The Event
155
+ */
156
+ async get(id) {
157
+ return this.request(`/v0/events/${id}`, "GET");
158
+ }
159
+ };
160
+
161
+ // src/websets/items.ts
162
+ var WebsetItemsClient = class extends WebsetsBaseClient {
163
+ /**
164
+ * List all Items for a Webset
165
+ * @param websetId The ID of the Webset
166
+ * @param params - Optional pagination parameters
167
+ * @returns A promise that resolves with the list of Items
168
+ */
169
+ list(websetId, params) {
170
+ const queryParams = this.buildPaginationParams(params);
171
+ return this.request(
172
+ `/v0/websets/${websetId}/items`,
173
+ "GET",
174
+ void 0,
175
+ queryParams
176
+ );
177
+ }
178
+ /**
179
+ * Iterate through all Items in a Webset, handling pagination automatically
180
+ * @param websetId The ID of the Webset
181
+ * @param options Pagination options
182
+ * @returns Async generator of Webset Items
183
+ */
184
+ async *listAll(websetId, options) {
185
+ let cursor = void 0;
186
+ const pageOptions = options ? { ...options } : {};
187
+ while (true) {
188
+ pageOptions.cursor = cursor;
189
+ const response = await this.list(websetId, pageOptions);
190
+ for (const item of response.data) {
191
+ yield item;
192
+ }
193
+ if (!response.hasMore || !response.nextCursor) {
194
+ break;
195
+ }
196
+ cursor = response.nextCursor;
197
+ }
198
+ }
199
+ /**
200
+ * Collect all items from a Webset into an array
201
+ * @param websetId The ID of the Webset
202
+ * @param options Pagination options
203
+ * @returns Promise resolving to an array of all Webset Items
204
+ */
205
+ async getAll(websetId, options) {
206
+ const items = [];
207
+ for await (const item of this.listAll(websetId, options)) {
208
+ items.push(item);
209
+ }
210
+ return items;
211
+ }
212
+ /**
213
+ * Get an Item by ID
214
+ * @param websetId The ID of the Webset
215
+ * @param id The ID of the Item
216
+ * @returns The Webset Item
217
+ */
218
+ async get(websetId, id) {
219
+ return this.request(
220
+ `/v0/websets/${websetId}/items/${id}`,
221
+ "GET"
222
+ );
223
+ }
224
+ /**
225
+ * Delete an Item
226
+ * @param websetId The ID of the Webset
227
+ * @param id The ID of the Item
228
+ * @returns The deleted Webset Item
229
+ */
230
+ async delete(websetId, id) {
231
+ return this.request(
232
+ `/v0/websets/${websetId}/items/${id}`,
233
+ "DELETE"
234
+ );
235
+ }
236
+ };
237
+
238
+ // src/websets/openapi.ts
239
+ var CreateEnrichmentParametersFormat = /* @__PURE__ */ ((CreateEnrichmentParametersFormat2) => {
240
+ CreateEnrichmentParametersFormat2["text"] = "text";
241
+ CreateEnrichmentParametersFormat2["date"] = "date";
242
+ CreateEnrichmentParametersFormat2["number"] = "number";
243
+ CreateEnrichmentParametersFormat2["options"] = "options";
244
+ CreateEnrichmentParametersFormat2["email"] = "email";
245
+ CreateEnrichmentParametersFormat2["phone"] = "phone";
246
+ return CreateEnrichmentParametersFormat2;
247
+ })(CreateEnrichmentParametersFormat || {});
248
+ var CreateWebsetSearchParametersBehaviour = /* @__PURE__ */ ((CreateWebsetSearchParametersBehaviour2) => {
249
+ CreateWebsetSearchParametersBehaviour2["override"] = "override";
250
+ return CreateWebsetSearchParametersBehaviour2;
251
+ })(CreateWebsetSearchParametersBehaviour || {});
252
+ var EventType = /* @__PURE__ */ ((EventType2) => {
253
+ EventType2["webset_created"] = "webset.created";
254
+ EventType2["webset_deleted"] = "webset.deleted";
255
+ EventType2["webset_paused"] = "webset.paused";
256
+ EventType2["webset_idle"] = "webset.idle";
257
+ EventType2["webset_search_created"] = "webset.search.created";
258
+ EventType2["webset_search_canceled"] = "webset.search.canceled";
259
+ EventType2["webset_search_completed"] = "webset.search.completed";
260
+ EventType2["webset_search_updated"] = "webset.search.updated";
261
+ EventType2["webset_export_created"] = "webset.export.created";
262
+ EventType2["webset_export_completed"] = "webset.export.completed";
263
+ EventType2["webset_item_created"] = "webset.item.created";
264
+ EventType2["webset_item_enriched"] = "webset.item.enriched";
265
+ return EventType2;
266
+ })(EventType || {});
267
+ var WebhookStatus = /* @__PURE__ */ ((WebhookStatus2) => {
268
+ WebhookStatus2["active"] = "active";
269
+ WebhookStatus2["inactive"] = "inactive";
270
+ return WebhookStatus2;
271
+ })(WebhookStatus || {});
272
+ var WebsetStatus = /* @__PURE__ */ ((WebsetStatus2) => {
273
+ WebsetStatus2["idle"] = "idle";
274
+ WebsetStatus2["running"] = "running";
275
+ WebsetStatus2["paused"] = "paused";
276
+ return WebsetStatus2;
277
+ })(WebsetStatus || {});
278
+ var WebsetEnrichmentStatus = /* @__PURE__ */ ((WebsetEnrichmentStatus2) => {
279
+ WebsetEnrichmentStatus2["pending"] = "pending";
280
+ WebsetEnrichmentStatus2["canceled"] = "canceled";
281
+ WebsetEnrichmentStatus2["completed"] = "completed";
282
+ return WebsetEnrichmentStatus2;
283
+ })(WebsetEnrichmentStatus || {});
284
+ var WebsetEnrichmentFormat = /* @__PURE__ */ ((WebsetEnrichmentFormat2) => {
285
+ WebsetEnrichmentFormat2["text"] = "text";
286
+ WebsetEnrichmentFormat2["date"] = "date";
287
+ WebsetEnrichmentFormat2["number"] = "number";
288
+ WebsetEnrichmentFormat2["options"] = "options";
289
+ WebsetEnrichmentFormat2["email"] = "email";
290
+ WebsetEnrichmentFormat2["phone"] = "phone";
291
+ return WebsetEnrichmentFormat2;
292
+ })(WebsetEnrichmentFormat || {});
293
+ var WebsetItemSource = /* @__PURE__ */ ((WebsetItemSource2) => {
294
+ WebsetItemSource2["search"] = "search";
295
+ return WebsetItemSource2;
296
+ })(WebsetItemSource || {});
297
+ var WebsetItemEvaluationSatisfied = /* @__PURE__ */ ((WebsetItemEvaluationSatisfied2) => {
298
+ WebsetItemEvaluationSatisfied2["yes"] = "yes";
299
+ WebsetItemEvaluationSatisfied2["no"] = "no";
300
+ WebsetItemEvaluationSatisfied2["unclear"] = "unclear";
301
+ return WebsetItemEvaluationSatisfied2;
302
+ })(WebsetItemEvaluationSatisfied || {});
303
+ var WebsetSearchCanceledReason = /* @__PURE__ */ ((WebsetSearchCanceledReason2) => {
304
+ WebsetSearchCanceledReason2["webset_deleted"] = "webset_deleted";
305
+ WebsetSearchCanceledReason2["webset_canceled"] = "webset_canceled";
306
+ return WebsetSearchCanceledReason2;
307
+ })(WebsetSearchCanceledReason || {});
308
+ var WebsetSearchStatus = /* @__PURE__ */ ((WebsetSearchStatus2) => {
309
+ WebsetSearchStatus2["created"] = "created";
310
+ WebsetSearchStatus2["running"] = "running";
311
+ WebsetSearchStatus2["completed"] = "completed";
312
+ WebsetSearchStatus2["canceled"] = "canceled";
313
+ return WebsetSearchStatus2;
314
+ })(WebsetSearchStatus || {});
315
+
316
+ // src/websets/searches.ts
317
+ var WebsetSearchesClient = class extends WebsetsBaseClient {
318
+ /**
319
+ * Create a new Search for the Webset
320
+ * @param websetId The ID of the Webset
321
+ * @param params The search parameters
322
+ * @returns The created Webset Search
323
+ */
324
+ async create(websetId, params) {
325
+ return this.request(
326
+ `/v0/websets/${websetId}/searches`,
327
+ "POST",
328
+ params
329
+ );
330
+ }
331
+ /**
332
+ * Get a Search by ID
333
+ * @param websetId The ID of the Webset
334
+ * @param id The ID of the Search
335
+ * @returns The Webset Search
336
+ */
337
+ async get(websetId, id) {
338
+ return this.request(
339
+ `/v0/websets/${websetId}/searches/${id}`,
340
+ "GET"
341
+ );
342
+ }
343
+ /**
344
+ * Cancel a running Search
345
+ * @param websetId The ID of the Webset
346
+ * @param id The ID of the Search
347
+ * @returns The canceled Webset Search
348
+ */
349
+ async cancel(websetId, id) {
350
+ return this.request(
351
+ `/v0/websets/${websetId}/searches/${id}/cancel`,
352
+ "POST"
353
+ );
354
+ }
355
+ };
356
+
357
+ // src/websets/webhooks.ts
358
+ var WebsetWebhooksClient = class extends WebsetsBaseClient {
359
+ /**
360
+ * Create a Webhook
361
+ * @param params The webhook parameters
362
+ * @returns The created Webhook
363
+ */
364
+ async create(params) {
365
+ return this.request("/v0/webhooks", "POST", params);
366
+ }
367
+ /**
368
+ * Get a Webhook by ID
369
+ * @param id The ID of the Webhook
370
+ * @returns The Webhook
371
+ */
372
+ async get(id) {
373
+ return this.request(`/v0/webhooks/${id}`, "GET");
374
+ }
375
+ /**
376
+ * List all Webhooks
377
+ * @param options Pagination options
378
+ * @returns The list of Webhooks
379
+ */
380
+ async list(options) {
381
+ const params = this.buildPaginationParams(options);
382
+ return this.request(
383
+ "/v0/webhooks",
384
+ "GET",
385
+ void 0,
386
+ params
387
+ );
388
+ }
389
+ /**
390
+ * Iterate through all Webhooks, handling pagination automatically
391
+ * @param options Pagination options
392
+ * @returns Async generator of Webhooks
393
+ */
394
+ async *listAll(options) {
395
+ let cursor = void 0;
396
+ const pageOptions = options ? { ...options } : {};
397
+ while (true) {
398
+ pageOptions.cursor = cursor;
399
+ const response = await this.list(pageOptions);
400
+ for (const webhook of response.data) {
401
+ yield webhook;
402
+ }
403
+ if (!response.hasMore || !response.nextCursor) {
404
+ break;
405
+ }
406
+ cursor = response.nextCursor;
407
+ }
408
+ }
409
+ /**
410
+ * Collect all Webhooks into an array
411
+ * @param options Pagination options
412
+ * @returns Promise resolving to an array of all Webhooks
413
+ */
414
+ async getAll(options) {
415
+ const webhooks = [];
416
+ for await (const webhook of this.listAll(options)) {
417
+ webhooks.push(webhook);
418
+ }
419
+ return webhooks;
420
+ }
421
+ /**
422
+ * Update a Webhook
423
+ * @param id The ID of the Webhook
424
+ * @param params The webhook update parameters (events, metadata, url)
425
+ * @returns The updated Webhook
426
+ */
427
+ async update(id, params) {
428
+ return this.request(`/v0/webhooks/${id}`, "PATCH", params);
429
+ }
430
+ /**
431
+ * Delete a Webhook
432
+ * @param id The ID of the Webhook
433
+ * @returns The deleted Webhook
434
+ */
435
+ async delete(id) {
436
+ return this.request(`/v0/webhooks/${id}`, "DELETE");
437
+ }
438
+ /**
439
+ * List all attempts for a Webhook
440
+ * @param id The ID of the Webhook
441
+ * @param options Pagination and filtering options
442
+ * @returns The list of Webhook attempts
443
+ */
444
+ async listAttempts(id, options) {
445
+ const params = {
446
+ cursor: options?.cursor,
447
+ limit: options?.limit,
448
+ eventType: options?.eventType
449
+ };
450
+ return this.request(
451
+ `/v0/webhooks/${id}/attempts`,
452
+ "GET",
453
+ void 0,
454
+ params
455
+ );
456
+ }
457
+ /**
458
+ * Iterate through all attempts for a Webhook, handling pagination automatically
459
+ * @param id The ID of the Webhook
460
+ * @param options Pagination and filtering options
461
+ * @returns Async generator of Webhook attempts
462
+ */
463
+ async *listAllAttempts(id, options) {
464
+ let cursor = void 0;
465
+ const pageOptions = options ? { ...options } : {};
466
+ while (true) {
467
+ pageOptions.cursor = cursor;
468
+ const response = await this.listAttempts(id, pageOptions);
469
+ for (const attempt of response.data) {
470
+ yield attempt;
471
+ }
472
+ if (!response.hasMore || !response.nextCursor) {
473
+ break;
474
+ }
475
+ cursor = response.nextCursor;
476
+ }
477
+ }
478
+ /**
479
+ * Collect all attempts for a Webhook into an array
480
+ * @param id The ID of the Webhook
481
+ * @param options Pagination and filtering options
482
+ * @returns Promise resolving to an array of all Webhook attempts
483
+ */
484
+ async getAllAttempts(id, options) {
485
+ const attempts = [];
486
+ for await (const attempt of this.listAllAttempts(id, options)) {
487
+ attempts.push(attempt);
488
+ }
489
+ return attempts;
490
+ }
491
+ };
492
+
493
+ // src/websets/client.ts
494
+ var WebsetsClient = class extends WebsetsBaseClient {
495
+ /**
496
+ * Initialize a new Websets client
497
+ * @param client The Exa client instance
498
+ */
499
+ constructor(client) {
500
+ super(client);
501
+ this.events = new EventsClient(client);
502
+ this.items = new WebsetItemsClient(client);
503
+ this.searches = new WebsetSearchesClient(client);
504
+ this.enrichments = new WebsetEnrichmentsClient(client);
505
+ this.webhooks = new WebsetWebhooksClient(client);
506
+ }
507
+ /**
508
+ * Create a new Webset
509
+ * @param params The Webset creation parameters
510
+ * @returns The created Webset
511
+ */
512
+ async create(params) {
513
+ return this.request("/v0/websets", "POST", params);
514
+ }
515
+ /**
516
+ * Get a Webset by ID
517
+ * @param id The ID of the Webset
518
+ * @param expand Optional array of relations to expand
519
+ * @returns The Webset
520
+ */
521
+ async get(id, expand) {
522
+ const params = {};
523
+ if (expand) {
524
+ params.expand = expand;
525
+ }
526
+ return this.request(
527
+ `/v0/websets/${id}`,
528
+ "GET",
529
+ void 0,
530
+ params
531
+ );
532
+ }
533
+ /**
534
+ * List all Websets
535
+ * @param options Pagination options (filtering by status is not supported by API)
536
+ * @returns The list of Websets
537
+ */
538
+ async list(options) {
539
+ const params = this.buildPaginationParams(options);
540
+ return this.request(
541
+ "/v0/websets",
542
+ "GET",
543
+ void 0,
544
+ params
545
+ );
546
+ }
547
+ /**
548
+ * Iterate through all Websets, handling pagination automatically
549
+ * @param options Pagination options
550
+ * @returns Async generator of Websets
551
+ */
552
+ async *listAll(options) {
553
+ let cursor = void 0;
554
+ const pageOptions = options ? { ...options } : {};
555
+ while (true) {
556
+ pageOptions.cursor = cursor;
557
+ const response = await this.list(pageOptions);
558
+ for (const webset of response.data) {
559
+ yield webset;
560
+ }
561
+ if (!response.hasMore || !response.nextCursor) {
562
+ break;
563
+ }
564
+ cursor = response.nextCursor;
565
+ }
566
+ }
567
+ /**
568
+ * Collect all Websets into an array
569
+ * @param options Pagination options
570
+ * @returns Promise resolving to an array of all Websets
571
+ */
572
+ async getAll(options) {
573
+ const websets = [];
574
+ for await (const webset of this.listAll(options)) {
575
+ websets.push(webset);
576
+ }
577
+ return websets;
578
+ }
579
+ /**
580
+ * Update a Webset
581
+ * @param id The ID of the Webset
582
+ * @param params The Webset update parameters
583
+ * @returns The updated Webset
584
+ */
585
+ async update(id, params) {
586
+ return this.request(`/v0/websets/${id}`, "POST", params);
587
+ }
588
+ /**
589
+ * Delete a Webset
590
+ * @param id The ID of the Webset
591
+ * @returns The deleted Webset
592
+ */
593
+ async delete(id) {
594
+ return this.request(`/v0/websets/${id}`, "DELETE");
595
+ }
596
+ /**
597
+ * Cancel a running Webset
598
+ * @param id The ID or external ID of the Webset
599
+ * @returns The canceled Webset (as returned by the API)
600
+ */
601
+ async cancel(id) {
602
+ return this.request(`/v0/websets/${id}/cancel`, "POST");
603
+ }
604
+ /**
605
+ * Wait until a Webset is idle
606
+ * @param id The ID of the Webset
607
+ * @param options Configuration options for timeout and polling
608
+ * @returns The Webset once it becomes idle
609
+ * @throws Error if the Webset does not become idle within the timeout
610
+ */
611
+ async waitUntilIdle(id, options) {
612
+ let timeout;
613
+ let pollInterval = 1e3;
614
+ let onPoll;
615
+ if (typeof options === "number") {
616
+ timeout = options;
617
+ } else if (options) {
618
+ timeout = options.timeout;
619
+ pollInterval = options.pollInterval || 1e3;
620
+ onPoll = options.onPoll;
621
+ }
622
+ const startTime = Date.now();
623
+ while (true) {
624
+ const webset = await this.get(id);
625
+ if (onPoll) {
626
+ onPoll(webset.status);
627
+ }
628
+ if (webset.status === "idle" /* idle */) {
629
+ return webset;
630
+ }
631
+ if (timeout && Date.now() - startTime > timeout) {
632
+ throw new ExaError(
633
+ `Webset ${id} did not reach idle state within ${timeout}ms. Current status: ${webset.status}`,
634
+ 408 /* RequestTimeout */
635
+ );
636
+ }
637
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
638
+ }
639
+ }
640
+ };
641
+
642
+ // src/index.ts
3
643
  var fetchImpl = typeof global !== "undefined" && global.fetch ? global.fetch : fetch;
4
644
  var HeadersImpl = typeof global !== "undefined" && global.Headers ? global.Headers : Headers;
5
- var Exa = class {
645
+ var Exa2 = class {
6
646
  /**
7
647
  * Helper method to separate out the contents-specific options from the rest.
8
648
  */
@@ -53,8 +693,9 @@ var Exa = class {
53
693
  if (!apiKey) {
54
694
  apiKey = process.env.EXASEARCH_API_KEY;
55
695
  if (!apiKey) {
56
- throw new Error(
57
- "API key must be provided as an argument or as an environment variable (EXASEARCH_API_KEY)"
696
+ throw new ExaError(
697
+ "API key must be provided as an argument or as an environment variable (EXASEARCH_API_KEY)",
698
+ 401 /* Unauthorized */
58
699
  );
59
700
  }
60
701
  }
@@ -63,31 +704,61 @@ var Exa = class {
63
704
  "Content-Type": "application/json",
64
705
  "User-Agent": "exa-node 1.4.0"
65
706
  });
707
+ this.websets = new WebsetsClient(this);
66
708
  }
67
709
  /**
68
710
  * Makes a request to the Exa API.
69
711
  * @param {string} endpoint - The API endpoint to call.
70
712
  * @param {string} method - The HTTP method to use.
71
713
  * @param {any} [body] - The request body for POST requests.
714
+ * @param {Record<string, any>} [params] - The query parameters.
72
715
  * @returns {Promise<any>} The response from the API.
716
+ * @throws {ExaError} When any API request fails with structured error information
73
717
  */
74
- async request(endpoint, method, body) {
75
- const response = await fetchImpl(this.baseURL + endpoint, {
718
+ async request(endpoint, method, body, params) {
719
+ let url = this.baseURL + endpoint;
720
+ if (params && Object.keys(params).length > 0) {
721
+ const searchParams = new URLSearchParams();
722
+ for (const [key, value] of Object.entries(params)) {
723
+ if (Array.isArray(value)) {
724
+ for (const item of value) {
725
+ searchParams.append(key, item);
726
+ }
727
+ } else if (value !== void 0) {
728
+ searchParams.append(key, String(value));
729
+ }
730
+ }
731
+ url += `?${searchParams.toString()}`;
732
+ }
733
+ const response = await fetchImpl(url, {
76
734
  method,
77
735
  headers: this.headers,
78
736
  body: body ? JSON.stringify(body) : void 0
79
737
  });
80
738
  if (!response.ok) {
81
- const message = (await response.json()).error;
82
- throw new Error(
83
- `Request failed with status ${response.status}. ${message}`
739
+ const errorData = await response.json();
740
+ if (!errorData.statusCode) {
741
+ errorData.statusCode = response.status;
742
+ }
743
+ if (!errorData.timestamp) {
744
+ errorData.timestamp = (/* @__PURE__ */ new Date()).toISOString();
745
+ }
746
+ if (!errorData.path) {
747
+ errorData.path = endpoint;
748
+ }
749
+ const message = errorData.error || "Unknown error";
750
+ throw new ExaError(
751
+ message,
752
+ response.status,
753
+ errorData.timestamp,
754
+ errorData.path
84
755
  );
85
756
  }
86
757
  return await response.json();
87
758
  }
88
759
  /**
89
760
  * Performs a search with an Exa prompt-engineered query.
90
- *
761
+ *
91
762
  * @param {string} query - The query string.
92
763
  * @param {RegularSearchOptions} [options] - Additional search options
93
764
  * @returns {Promise<SearchResponse<{}>>} A list of relevant search results.
@@ -97,7 +768,7 @@ var Exa = class {
97
768
  }
98
769
  /**
99
770
  * Performs a search with an Exa prompt-engineered query and returns the contents of the documents.
100
- *
771
+ *
101
772
  * @param {string} query - The query string.
102
773
  * @param {RegularSearchOptions & T} [options] - Additional search + contents options
103
774
  * @returns {Promise<SearchResponse<T>>} A list of relevant search results with requested contents.
@@ -141,7 +812,10 @@ var Exa = class {
141
812
  */
142
813
  async getContents(urls, options) {
143
814
  if (!urls || Array.isArray(urls) && urls.length === 0) {
144
- throw new Error("Must provide at least one URL");
815
+ throw new ExaError(
816
+ "Must provide at least one URL",
817
+ 400 /* BadRequest */
818
+ );
145
819
  }
146
820
  let requestUrls;
147
821
  if (typeof urls === "string") {
@@ -162,7 +836,7 @@ var Exa = class {
162
836
  * @param {string} query - The question or query to answer.
163
837
  * @param {AnswerOptions} [options] - Additional options for answer generation.
164
838
  * @returns {Promise<AnswerResponse>} The generated answer and source references.
165
- *
839
+ *
166
840
  * Example with systemPrompt:
167
841
  * ```ts
168
842
  * const answer = await exa.answer("What is quantum computing?", {
@@ -171,7 +845,7 @@ var Exa = class {
171
845
  * systemPrompt: "Answer in a technical manner suitable for experts."
172
846
  * });
173
847
  * ```
174
- *
848
+ *
175
849
  * Note: For streaming responses, use the `streamAnswer` method:
176
850
  * ```ts
177
851
  * for await (const chunk of exa.streamAnswer(query)) {
@@ -181,8 +855,9 @@ var Exa = class {
181
855
  */
182
856
  async answer(query, options) {
183
857
  if (options?.stream) {
184
- throw new Error(
185
- "For streaming responses, please use streamAnswer() instead:\n\nfor await (const chunk of exa.streamAnswer(query)) {\n // Handle chunks\n}"
858
+ throw new ExaError(
859
+ "For streaming responses, please use streamAnswer() instead:\n\nfor await (const chunk of exa.streamAnswer(query)) {\n // Handle chunks\n}",
860
+ 400 /* BadRequest */
186
861
  );
187
862
  }
188
863
  const requestBody = {
@@ -202,7 +877,7 @@ var Exa = class {
202
877
  *
203
878
  * Example usage:
204
879
  * ```ts
205
- * for await (const chunk of exa.streamAnswer("What is quantum computing?", {
880
+ * for await (const chunk of exa.streamAnswer("What is quantum computing?", {
206
881
  * text: false,
207
882
  * systemPrompt: "Answer in a concise manner suitable for beginners."
208
883
  * })) {
@@ -228,13 +903,15 @@ var Exa = class {
228
903
  });
229
904
  if (!response.ok) {
230
905
  const message = await response.text();
231
- throw new Error(
232
- `Request failed with status ${response.status}. ${message}`
233
- );
906
+ throw new ExaError(message, response.status, (/* @__PURE__ */ new Date()).toISOString());
234
907
  }
235
908
  const reader = response.body?.getReader();
236
909
  if (!reader) {
237
- throw new Error("No response body available for streaming.");
910
+ throw new ExaError(
911
+ "No response body available for streaming.",
912
+ 500,
913
+ (/* @__PURE__ */ new Date()).toISOString()
914
+ );
238
915
  }
239
916
  const decoder = new TextDecoder();
240
917
  let buffer = "";
@@ -301,8 +978,27 @@ var Exa = class {
301
978
  return { content, citations };
302
979
  }
303
980
  };
304
- var src_default = Exa;
981
+ var src_default = Exa2;
305
982
  export {
983
+ CreateEnrichmentParametersFormat,
984
+ CreateWebsetSearchParametersBehaviour,
985
+ EventType,
986
+ Exa2 as Exa,
987
+ ExaError,
988
+ HttpStatusCode,
989
+ WebhookStatus,
990
+ WebsetEnrichmentFormat,
991
+ WebsetEnrichmentStatus,
992
+ WebsetEnrichmentsClient,
993
+ WebsetItemEvaluationSatisfied,
994
+ WebsetItemSource,
995
+ WebsetItemsClient,
996
+ WebsetSearchCanceledReason,
997
+ WebsetSearchStatus,
998
+ WebsetSearchesClient,
999
+ WebsetStatus,
1000
+ WebsetWebhooksClient,
1001
+ WebsetsClient,
306
1002
  src_default as default
307
1003
  };
308
1004
  //# sourceMappingURL=index.mjs.map