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.js CHANGED
@@ -30,13 +30,672 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
+ CreateEnrichmentParametersFormat: () => CreateEnrichmentParametersFormat,
34
+ CreateWebsetSearchParametersBehaviour: () => CreateWebsetSearchParametersBehaviour,
35
+ EventType: () => EventType,
36
+ Exa: () => Exa2,
37
+ ExaError: () => ExaError,
38
+ HttpStatusCode: () => HttpStatusCode,
39
+ WebhookStatus: () => WebhookStatus,
40
+ WebsetEnrichmentFormat: () => WebsetEnrichmentFormat,
41
+ WebsetEnrichmentStatus: () => WebsetEnrichmentStatus,
42
+ WebsetEnrichmentsClient: () => WebsetEnrichmentsClient,
43
+ WebsetItemEvaluationSatisfied: () => WebsetItemEvaluationSatisfied,
44
+ WebsetItemSource: () => WebsetItemSource,
45
+ WebsetItemsClient: () => WebsetItemsClient,
46
+ WebsetSearchCanceledReason: () => WebsetSearchCanceledReason,
47
+ WebsetSearchStatus: () => WebsetSearchStatus,
48
+ WebsetSearchesClient: () => WebsetSearchesClient,
49
+ WebsetStatus: () => WebsetStatus,
50
+ WebsetWebhooksClient: () => WebsetWebhooksClient,
51
+ WebsetsClient: () => WebsetsClient,
33
52
  default: () => src_default
34
53
  });
35
54
  module.exports = __toCommonJS(src_exports);
36
55
  var import_cross_fetch = __toESM(require("cross-fetch"));
56
+
57
+ // src/errors.ts
58
+ var HttpStatusCode = /* @__PURE__ */ ((HttpStatusCode2) => {
59
+ HttpStatusCode2[HttpStatusCode2["BadRequest"] = 400] = "BadRequest";
60
+ HttpStatusCode2[HttpStatusCode2["NotFound"] = 404] = "NotFound";
61
+ HttpStatusCode2[HttpStatusCode2["Unauthorized"] = 401] = "Unauthorized";
62
+ HttpStatusCode2[HttpStatusCode2["Forbidden"] = 403] = "Forbidden";
63
+ HttpStatusCode2[HttpStatusCode2["TooManyRequests"] = 429] = "TooManyRequests";
64
+ HttpStatusCode2[HttpStatusCode2["RequestTimeout"] = 408] = "RequestTimeout";
65
+ HttpStatusCode2[HttpStatusCode2["InternalServerError"] = 500] = "InternalServerError";
66
+ HttpStatusCode2[HttpStatusCode2["ServiceUnavailable"] = 503] = "ServiceUnavailable";
67
+ return HttpStatusCode2;
68
+ })(HttpStatusCode || {});
69
+ var ExaError = class extends Error {
70
+ /**
71
+ * Create a new ExaError
72
+ * @param message Error message
73
+ * @param statusCode HTTP status code
74
+ * @param timestamp ISO timestamp from API
75
+ * @param path Path that caused the error
76
+ */
77
+ constructor(message, statusCode, timestamp, path) {
78
+ super(message);
79
+ this.name = "ExaError";
80
+ this.statusCode = statusCode;
81
+ this.timestamp = timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
82
+ this.path = path;
83
+ }
84
+ };
85
+
86
+ // src/websets/base.ts
87
+ var WebsetsBaseClient = class {
88
+ /**
89
+ * Initialize a new Websets base client
90
+ * @param client The Exa client instance
91
+ */
92
+ constructor(client) {
93
+ this.client = client;
94
+ }
95
+ /**
96
+ * Make a request to the Websets API
97
+ * @param endpoint The endpoint path
98
+ * @param method The HTTP method
99
+ * @param data Optional request body data
100
+ * @param params Optional query parameters
101
+ * @returns The response JSON
102
+ * @throws ExaError with API error details if the request fails
103
+ */
104
+ async request(endpoint, method = "POST", data, params) {
105
+ return this.client.request(`/websets${endpoint}`, method, data, params);
106
+ }
107
+ /**
108
+ * Helper to build pagination parameters
109
+ * @param pagination The pagination parameters
110
+ * @returns QueryParams object with pagination parameters
111
+ */
112
+ buildPaginationParams(pagination) {
113
+ const params = {};
114
+ if (!pagination)
115
+ return params;
116
+ if (pagination.cursor)
117
+ params.cursor = pagination.cursor;
118
+ if (pagination.limit)
119
+ params.limit = pagination.limit;
120
+ return params;
121
+ }
122
+ };
123
+
124
+ // src/websets/enrichments.ts
125
+ var WebsetEnrichmentsClient = class extends WebsetsBaseClient {
126
+ /**
127
+ * Create an Enrichment for a Webset
128
+ * @param websetId The ID of the Webset
129
+ * @param params The enrichment parameters
130
+ * @returns The created Webset Enrichment
131
+ */
132
+ async create(websetId, params) {
133
+ return this.request(
134
+ `/v0/websets/${websetId}/enrichments`,
135
+ "POST",
136
+ params
137
+ );
138
+ }
139
+ /**
140
+ * Get an Enrichment by ID
141
+ * @param websetId The ID of the Webset
142
+ * @param id The ID of the Enrichment
143
+ * @returns The Webset Enrichment
144
+ */
145
+ async get(websetId, id) {
146
+ return this.request(
147
+ `/v0/websets/${websetId}/enrichments/${id}`,
148
+ "GET"
149
+ );
150
+ }
151
+ /**
152
+ * Delete an Enrichment
153
+ * @param websetId The ID of the Webset
154
+ * @param id The ID of the Enrichment
155
+ * @returns The deleted Webset Enrichment
156
+ */
157
+ async delete(websetId, id) {
158
+ return this.request(
159
+ `/v0/websets/${websetId}/enrichments/${id}`,
160
+ "DELETE"
161
+ );
162
+ }
163
+ /**
164
+ * Cancel a running Enrichment
165
+ * @param websetId The ID of the Webset
166
+ * @param id The ID of the Enrichment
167
+ * @returns The canceled Webset Enrichment
168
+ */
169
+ async cancel(websetId, id) {
170
+ return this.request(
171
+ `/v0/websets/${websetId}/enrichments/${id}/cancel`,
172
+ "POST"
173
+ );
174
+ }
175
+ };
176
+
177
+ // src/websets/events.ts
178
+ var EventsClient = class extends WebsetsBaseClient {
179
+ /**
180
+ * Initialize a new Events client
181
+ * @param client The Exa client instance
182
+ */
183
+ constructor(client) {
184
+ super(client);
185
+ }
186
+ /**
187
+ * List all Events
188
+ * @param options Optional filtering and pagination options
189
+ * @returns The list of Events
190
+ */
191
+ async list(options) {
192
+ const params = {
193
+ cursor: options?.cursor,
194
+ limit: options?.limit,
195
+ types: options?.types
196
+ };
197
+ return this.request(
198
+ "/v0/events",
199
+ "GET",
200
+ void 0,
201
+ params
202
+ );
203
+ }
204
+ /**
205
+ * Get an Event by ID
206
+ * @param id The ID of the Event
207
+ * @returns The Event
208
+ */
209
+ async get(id) {
210
+ return this.request(`/v0/events/${id}`, "GET");
211
+ }
212
+ };
213
+
214
+ // src/websets/items.ts
215
+ var WebsetItemsClient = class extends WebsetsBaseClient {
216
+ /**
217
+ * List all Items for a Webset
218
+ * @param websetId The ID of the Webset
219
+ * @param params - Optional pagination parameters
220
+ * @returns A promise that resolves with the list of Items
221
+ */
222
+ list(websetId, params) {
223
+ const queryParams = this.buildPaginationParams(params);
224
+ return this.request(
225
+ `/v0/websets/${websetId}/items`,
226
+ "GET",
227
+ void 0,
228
+ queryParams
229
+ );
230
+ }
231
+ /**
232
+ * Iterate through all Items in a Webset, handling pagination automatically
233
+ * @param websetId The ID of the Webset
234
+ * @param options Pagination options
235
+ * @returns Async generator of Webset Items
236
+ */
237
+ async *listAll(websetId, options) {
238
+ let cursor = void 0;
239
+ const pageOptions = options ? { ...options } : {};
240
+ while (true) {
241
+ pageOptions.cursor = cursor;
242
+ const response = await this.list(websetId, pageOptions);
243
+ for (const item of response.data) {
244
+ yield item;
245
+ }
246
+ if (!response.hasMore || !response.nextCursor) {
247
+ break;
248
+ }
249
+ cursor = response.nextCursor;
250
+ }
251
+ }
252
+ /**
253
+ * Collect all items from a Webset into an array
254
+ * @param websetId The ID of the Webset
255
+ * @param options Pagination options
256
+ * @returns Promise resolving to an array of all Webset Items
257
+ */
258
+ async getAll(websetId, options) {
259
+ const items = [];
260
+ for await (const item of this.listAll(websetId, options)) {
261
+ items.push(item);
262
+ }
263
+ return items;
264
+ }
265
+ /**
266
+ * Get an Item by ID
267
+ * @param websetId The ID of the Webset
268
+ * @param id The ID of the Item
269
+ * @returns The Webset Item
270
+ */
271
+ async get(websetId, id) {
272
+ return this.request(
273
+ `/v0/websets/${websetId}/items/${id}`,
274
+ "GET"
275
+ );
276
+ }
277
+ /**
278
+ * Delete an Item
279
+ * @param websetId The ID of the Webset
280
+ * @param id The ID of the Item
281
+ * @returns The deleted Webset Item
282
+ */
283
+ async delete(websetId, id) {
284
+ return this.request(
285
+ `/v0/websets/${websetId}/items/${id}`,
286
+ "DELETE"
287
+ );
288
+ }
289
+ };
290
+
291
+ // src/websets/openapi.ts
292
+ var CreateEnrichmentParametersFormat = /* @__PURE__ */ ((CreateEnrichmentParametersFormat2) => {
293
+ CreateEnrichmentParametersFormat2["text"] = "text";
294
+ CreateEnrichmentParametersFormat2["date"] = "date";
295
+ CreateEnrichmentParametersFormat2["number"] = "number";
296
+ CreateEnrichmentParametersFormat2["options"] = "options";
297
+ CreateEnrichmentParametersFormat2["email"] = "email";
298
+ CreateEnrichmentParametersFormat2["phone"] = "phone";
299
+ return CreateEnrichmentParametersFormat2;
300
+ })(CreateEnrichmentParametersFormat || {});
301
+ var CreateWebsetSearchParametersBehaviour = /* @__PURE__ */ ((CreateWebsetSearchParametersBehaviour2) => {
302
+ CreateWebsetSearchParametersBehaviour2["override"] = "override";
303
+ return CreateWebsetSearchParametersBehaviour2;
304
+ })(CreateWebsetSearchParametersBehaviour || {});
305
+ var EventType = /* @__PURE__ */ ((EventType2) => {
306
+ EventType2["webset_created"] = "webset.created";
307
+ EventType2["webset_deleted"] = "webset.deleted";
308
+ EventType2["webset_paused"] = "webset.paused";
309
+ EventType2["webset_idle"] = "webset.idle";
310
+ EventType2["webset_search_created"] = "webset.search.created";
311
+ EventType2["webset_search_canceled"] = "webset.search.canceled";
312
+ EventType2["webset_search_completed"] = "webset.search.completed";
313
+ EventType2["webset_search_updated"] = "webset.search.updated";
314
+ EventType2["webset_export_created"] = "webset.export.created";
315
+ EventType2["webset_export_completed"] = "webset.export.completed";
316
+ EventType2["webset_item_created"] = "webset.item.created";
317
+ EventType2["webset_item_enriched"] = "webset.item.enriched";
318
+ return EventType2;
319
+ })(EventType || {});
320
+ var WebhookStatus = /* @__PURE__ */ ((WebhookStatus2) => {
321
+ WebhookStatus2["active"] = "active";
322
+ WebhookStatus2["inactive"] = "inactive";
323
+ return WebhookStatus2;
324
+ })(WebhookStatus || {});
325
+ var WebsetStatus = /* @__PURE__ */ ((WebsetStatus2) => {
326
+ WebsetStatus2["idle"] = "idle";
327
+ WebsetStatus2["running"] = "running";
328
+ WebsetStatus2["paused"] = "paused";
329
+ return WebsetStatus2;
330
+ })(WebsetStatus || {});
331
+ var WebsetEnrichmentStatus = /* @__PURE__ */ ((WebsetEnrichmentStatus2) => {
332
+ WebsetEnrichmentStatus2["pending"] = "pending";
333
+ WebsetEnrichmentStatus2["canceled"] = "canceled";
334
+ WebsetEnrichmentStatus2["completed"] = "completed";
335
+ return WebsetEnrichmentStatus2;
336
+ })(WebsetEnrichmentStatus || {});
337
+ var WebsetEnrichmentFormat = /* @__PURE__ */ ((WebsetEnrichmentFormat2) => {
338
+ WebsetEnrichmentFormat2["text"] = "text";
339
+ WebsetEnrichmentFormat2["date"] = "date";
340
+ WebsetEnrichmentFormat2["number"] = "number";
341
+ WebsetEnrichmentFormat2["options"] = "options";
342
+ WebsetEnrichmentFormat2["email"] = "email";
343
+ WebsetEnrichmentFormat2["phone"] = "phone";
344
+ return WebsetEnrichmentFormat2;
345
+ })(WebsetEnrichmentFormat || {});
346
+ var WebsetItemSource = /* @__PURE__ */ ((WebsetItemSource2) => {
347
+ WebsetItemSource2["search"] = "search";
348
+ return WebsetItemSource2;
349
+ })(WebsetItemSource || {});
350
+ var WebsetItemEvaluationSatisfied = /* @__PURE__ */ ((WebsetItemEvaluationSatisfied2) => {
351
+ WebsetItemEvaluationSatisfied2["yes"] = "yes";
352
+ WebsetItemEvaluationSatisfied2["no"] = "no";
353
+ WebsetItemEvaluationSatisfied2["unclear"] = "unclear";
354
+ return WebsetItemEvaluationSatisfied2;
355
+ })(WebsetItemEvaluationSatisfied || {});
356
+ var WebsetSearchCanceledReason = /* @__PURE__ */ ((WebsetSearchCanceledReason2) => {
357
+ WebsetSearchCanceledReason2["webset_deleted"] = "webset_deleted";
358
+ WebsetSearchCanceledReason2["webset_canceled"] = "webset_canceled";
359
+ return WebsetSearchCanceledReason2;
360
+ })(WebsetSearchCanceledReason || {});
361
+ var WebsetSearchStatus = /* @__PURE__ */ ((WebsetSearchStatus2) => {
362
+ WebsetSearchStatus2["created"] = "created";
363
+ WebsetSearchStatus2["running"] = "running";
364
+ WebsetSearchStatus2["completed"] = "completed";
365
+ WebsetSearchStatus2["canceled"] = "canceled";
366
+ return WebsetSearchStatus2;
367
+ })(WebsetSearchStatus || {});
368
+
369
+ // src/websets/searches.ts
370
+ var WebsetSearchesClient = class extends WebsetsBaseClient {
371
+ /**
372
+ * Create a new Search for the Webset
373
+ * @param websetId The ID of the Webset
374
+ * @param params The search parameters
375
+ * @returns The created Webset Search
376
+ */
377
+ async create(websetId, params) {
378
+ return this.request(
379
+ `/v0/websets/${websetId}/searches`,
380
+ "POST",
381
+ params
382
+ );
383
+ }
384
+ /**
385
+ * Get a Search by ID
386
+ * @param websetId The ID of the Webset
387
+ * @param id The ID of the Search
388
+ * @returns The Webset Search
389
+ */
390
+ async get(websetId, id) {
391
+ return this.request(
392
+ `/v0/websets/${websetId}/searches/${id}`,
393
+ "GET"
394
+ );
395
+ }
396
+ /**
397
+ * Cancel a running Search
398
+ * @param websetId The ID of the Webset
399
+ * @param id The ID of the Search
400
+ * @returns The canceled Webset Search
401
+ */
402
+ async cancel(websetId, id) {
403
+ return this.request(
404
+ `/v0/websets/${websetId}/searches/${id}/cancel`,
405
+ "POST"
406
+ );
407
+ }
408
+ };
409
+
410
+ // src/websets/webhooks.ts
411
+ var WebsetWebhooksClient = class extends WebsetsBaseClient {
412
+ /**
413
+ * Create a Webhook
414
+ * @param params The webhook parameters
415
+ * @returns The created Webhook
416
+ */
417
+ async create(params) {
418
+ return this.request("/v0/webhooks", "POST", params);
419
+ }
420
+ /**
421
+ * Get a Webhook by ID
422
+ * @param id The ID of the Webhook
423
+ * @returns The Webhook
424
+ */
425
+ async get(id) {
426
+ return this.request(`/v0/webhooks/${id}`, "GET");
427
+ }
428
+ /**
429
+ * List all Webhooks
430
+ * @param options Pagination options
431
+ * @returns The list of Webhooks
432
+ */
433
+ async list(options) {
434
+ const params = this.buildPaginationParams(options);
435
+ return this.request(
436
+ "/v0/webhooks",
437
+ "GET",
438
+ void 0,
439
+ params
440
+ );
441
+ }
442
+ /**
443
+ * Iterate through all Webhooks, handling pagination automatically
444
+ * @param options Pagination options
445
+ * @returns Async generator of Webhooks
446
+ */
447
+ async *listAll(options) {
448
+ let cursor = void 0;
449
+ const pageOptions = options ? { ...options } : {};
450
+ while (true) {
451
+ pageOptions.cursor = cursor;
452
+ const response = await this.list(pageOptions);
453
+ for (const webhook of response.data) {
454
+ yield webhook;
455
+ }
456
+ if (!response.hasMore || !response.nextCursor) {
457
+ break;
458
+ }
459
+ cursor = response.nextCursor;
460
+ }
461
+ }
462
+ /**
463
+ * Collect all Webhooks into an array
464
+ * @param options Pagination options
465
+ * @returns Promise resolving to an array of all Webhooks
466
+ */
467
+ async getAll(options) {
468
+ const webhooks = [];
469
+ for await (const webhook of this.listAll(options)) {
470
+ webhooks.push(webhook);
471
+ }
472
+ return webhooks;
473
+ }
474
+ /**
475
+ * Update a Webhook
476
+ * @param id The ID of the Webhook
477
+ * @param params The webhook update parameters (events, metadata, url)
478
+ * @returns The updated Webhook
479
+ */
480
+ async update(id, params) {
481
+ return this.request(`/v0/webhooks/${id}`, "PATCH", params);
482
+ }
483
+ /**
484
+ * Delete a Webhook
485
+ * @param id The ID of the Webhook
486
+ * @returns The deleted Webhook
487
+ */
488
+ async delete(id) {
489
+ return this.request(`/v0/webhooks/${id}`, "DELETE");
490
+ }
491
+ /**
492
+ * List all attempts for a Webhook
493
+ * @param id The ID of the Webhook
494
+ * @param options Pagination and filtering options
495
+ * @returns The list of Webhook attempts
496
+ */
497
+ async listAttempts(id, options) {
498
+ const params = {
499
+ cursor: options?.cursor,
500
+ limit: options?.limit,
501
+ eventType: options?.eventType
502
+ };
503
+ return this.request(
504
+ `/v0/webhooks/${id}/attempts`,
505
+ "GET",
506
+ void 0,
507
+ params
508
+ );
509
+ }
510
+ /**
511
+ * Iterate through all attempts for a Webhook, handling pagination automatically
512
+ * @param id The ID of the Webhook
513
+ * @param options Pagination and filtering options
514
+ * @returns Async generator of Webhook attempts
515
+ */
516
+ async *listAllAttempts(id, options) {
517
+ let cursor = void 0;
518
+ const pageOptions = options ? { ...options } : {};
519
+ while (true) {
520
+ pageOptions.cursor = cursor;
521
+ const response = await this.listAttempts(id, pageOptions);
522
+ for (const attempt of response.data) {
523
+ yield attempt;
524
+ }
525
+ if (!response.hasMore || !response.nextCursor) {
526
+ break;
527
+ }
528
+ cursor = response.nextCursor;
529
+ }
530
+ }
531
+ /**
532
+ * Collect all attempts for a Webhook into an array
533
+ * @param id The ID of the Webhook
534
+ * @param options Pagination and filtering options
535
+ * @returns Promise resolving to an array of all Webhook attempts
536
+ */
537
+ async getAllAttempts(id, options) {
538
+ const attempts = [];
539
+ for await (const attempt of this.listAllAttempts(id, options)) {
540
+ attempts.push(attempt);
541
+ }
542
+ return attempts;
543
+ }
544
+ };
545
+
546
+ // src/websets/client.ts
547
+ var WebsetsClient = class extends WebsetsBaseClient {
548
+ /**
549
+ * Initialize a new Websets client
550
+ * @param client The Exa client instance
551
+ */
552
+ constructor(client) {
553
+ super(client);
554
+ this.events = new EventsClient(client);
555
+ this.items = new WebsetItemsClient(client);
556
+ this.searches = new WebsetSearchesClient(client);
557
+ this.enrichments = new WebsetEnrichmentsClient(client);
558
+ this.webhooks = new WebsetWebhooksClient(client);
559
+ }
560
+ /**
561
+ * Create a new Webset
562
+ * @param params The Webset creation parameters
563
+ * @returns The created Webset
564
+ */
565
+ async create(params) {
566
+ return this.request("/v0/websets", "POST", params);
567
+ }
568
+ /**
569
+ * Get a Webset by ID
570
+ * @param id The ID of the Webset
571
+ * @param expand Optional array of relations to expand
572
+ * @returns The Webset
573
+ */
574
+ async get(id, expand) {
575
+ const params = {};
576
+ if (expand) {
577
+ params.expand = expand;
578
+ }
579
+ return this.request(
580
+ `/v0/websets/${id}`,
581
+ "GET",
582
+ void 0,
583
+ params
584
+ );
585
+ }
586
+ /**
587
+ * List all Websets
588
+ * @param options Pagination options (filtering by status is not supported by API)
589
+ * @returns The list of Websets
590
+ */
591
+ async list(options) {
592
+ const params = this.buildPaginationParams(options);
593
+ return this.request(
594
+ "/v0/websets",
595
+ "GET",
596
+ void 0,
597
+ params
598
+ );
599
+ }
600
+ /**
601
+ * Iterate through all Websets, handling pagination automatically
602
+ * @param options Pagination options
603
+ * @returns Async generator of Websets
604
+ */
605
+ async *listAll(options) {
606
+ let cursor = void 0;
607
+ const pageOptions = options ? { ...options } : {};
608
+ while (true) {
609
+ pageOptions.cursor = cursor;
610
+ const response = await this.list(pageOptions);
611
+ for (const webset of response.data) {
612
+ yield webset;
613
+ }
614
+ if (!response.hasMore || !response.nextCursor) {
615
+ break;
616
+ }
617
+ cursor = response.nextCursor;
618
+ }
619
+ }
620
+ /**
621
+ * Collect all Websets into an array
622
+ * @param options Pagination options
623
+ * @returns Promise resolving to an array of all Websets
624
+ */
625
+ async getAll(options) {
626
+ const websets = [];
627
+ for await (const webset of this.listAll(options)) {
628
+ websets.push(webset);
629
+ }
630
+ return websets;
631
+ }
632
+ /**
633
+ * Update a Webset
634
+ * @param id The ID of the Webset
635
+ * @param params The Webset update parameters
636
+ * @returns The updated Webset
637
+ */
638
+ async update(id, params) {
639
+ return this.request(`/v0/websets/${id}`, "POST", params);
640
+ }
641
+ /**
642
+ * Delete a Webset
643
+ * @param id The ID of the Webset
644
+ * @returns The deleted Webset
645
+ */
646
+ async delete(id) {
647
+ return this.request(`/v0/websets/${id}`, "DELETE");
648
+ }
649
+ /**
650
+ * Cancel a running Webset
651
+ * @param id The ID or external ID of the Webset
652
+ * @returns The canceled Webset (as returned by the API)
653
+ */
654
+ async cancel(id) {
655
+ return this.request(`/v0/websets/${id}/cancel`, "POST");
656
+ }
657
+ /**
658
+ * Wait until a Webset is idle
659
+ * @param id The ID of the Webset
660
+ * @param options Configuration options for timeout and polling
661
+ * @returns The Webset once it becomes idle
662
+ * @throws Error if the Webset does not become idle within the timeout
663
+ */
664
+ async waitUntilIdle(id, options) {
665
+ let timeout;
666
+ let pollInterval = 1e3;
667
+ let onPoll;
668
+ if (typeof options === "number") {
669
+ timeout = options;
670
+ } else if (options) {
671
+ timeout = options.timeout;
672
+ pollInterval = options.pollInterval || 1e3;
673
+ onPoll = options.onPoll;
674
+ }
675
+ const startTime = Date.now();
676
+ while (true) {
677
+ const webset = await this.get(id);
678
+ if (onPoll) {
679
+ onPoll(webset.status);
680
+ }
681
+ if (webset.status === "idle" /* idle */) {
682
+ return webset;
683
+ }
684
+ if (timeout && Date.now() - startTime > timeout) {
685
+ throw new ExaError(
686
+ `Webset ${id} did not reach idle state within ${timeout}ms. Current status: ${webset.status}`,
687
+ 408 /* RequestTimeout */
688
+ );
689
+ }
690
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
691
+ }
692
+ }
693
+ };
694
+
695
+ // src/index.ts
37
696
  var fetchImpl = typeof global !== "undefined" && global.fetch ? global.fetch : import_cross_fetch.default;
38
697
  var HeadersImpl = typeof global !== "undefined" && global.Headers ? global.Headers : import_cross_fetch.Headers;
39
- var Exa = class {
698
+ var Exa2 = class {
40
699
  /**
41
700
  * Helper method to separate out the contents-specific options from the rest.
42
701
  */
@@ -87,8 +746,9 @@ var Exa = class {
87
746
  if (!apiKey) {
88
747
  apiKey = process.env.EXASEARCH_API_KEY;
89
748
  if (!apiKey) {
90
- throw new Error(
91
- "API key must be provided as an argument or as an environment variable (EXASEARCH_API_KEY)"
749
+ throw new ExaError(
750
+ "API key must be provided as an argument or as an environment variable (EXASEARCH_API_KEY)",
751
+ 401 /* Unauthorized */
92
752
  );
93
753
  }
94
754
  }
@@ -97,31 +757,61 @@ var Exa = class {
97
757
  "Content-Type": "application/json",
98
758
  "User-Agent": "exa-node 1.4.0"
99
759
  });
760
+ this.websets = new WebsetsClient(this);
100
761
  }
101
762
  /**
102
763
  * Makes a request to the Exa API.
103
764
  * @param {string} endpoint - The API endpoint to call.
104
765
  * @param {string} method - The HTTP method to use.
105
766
  * @param {any} [body] - The request body for POST requests.
767
+ * @param {Record<string, any>} [params] - The query parameters.
106
768
  * @returns {Promise<any>} The response from the API.
769
+ * @throws {ExaError} When any API request fails with structured error information
107
770
  */
108
- async request(endpoint, method, body) {
109
- const response = await fetchImpl(this.baseURL + endpoint, {
771
+ async request(endpoint, method, body, params) {
772
+ let url = this.baseURL + endpoint;
773
+ if (params && Object.keys(params).length > 0) {
774
+ const searchParams = new URLSearchParams();
775
+ for (const [key, value] of Object.entries(params)) {
776
+ if (Array.isArray(value)) {
777
+ for (const item of value) {
778
+ searchParams.append(key, item);
779
+ }
780
+ } else if (value !== void 0) {
781
+ searchParams.append(key, String(value));
782
+ }
783
+ }
784
+ url += `?${searchParams.toString()}`;
785
+ }
786
+ const response = await fetchImpl(url, {
110
787
  method,
111
788
  headers: this.headers,
112
789
  body: body ? JSON.stringify(body) : void 0
113
790
  });
114
791
  if (!response.ok) {
115
- const message = (await response.json()).error;
116
- throw new Error(
117
- `Request failed with status ${response.status}. ${message}`
792
+ const errorData = await response.json();
793
+ if (!errorData.statusCode) {
794
+ errorData.statusCode = response.status;
795
+ }
796
+ if (!errorData.timestamp) {
797
+ errorData.timestamp = (/* @__PURE__ */ new Date()).toISOString();
798
+ }
799
+ if (!errorData.path) {
800
+ errorData.path = endpoint;
801
+ }
802
+ const message = errorData.error || "Unknown error";
803
+ throw new ExaError(
804
+ message,
805
+ response.status,
806
+ errorData.timestamp,
807
+ errorData.path
118
808
  );
119
809
  }
120
810
  return await response.json();
121
811
  }
122
812
  /**
123
813
  * Performs a search with an Exa prompt-engineered query.
124
- *
814
+ *
125
815
  * @param {string} query - The query string.
126
816
  * @param {RegularSearchOptions} [options] - Additional search options
127
817
  * @returns {Promise<SearchResponse<{}>>} A list of relevant search results.
@@ -131,7 +821,7 @@ var Exa = class {
131
821
  }
132
822
  /**
133
823
  * Performs a search with an Exa prompt-engineered query and returns the contents of the documents.
134
- *
824
+ *
135
825
  * @param {string} query - The query string.
136
826
  * @param {RegularSearchOptions & T} [options] - Additional search + contents options
137
827
  * @returns {Promise<SearchResponse<T>>} A list of relevant search results with requested contents.
@@ -175,7 +865,10 @@ var Exa = class {
175
865
  */
176
866
  async getContents(urls, options) {
177
867
  if (!urls || Array.isArray(urls) && urls.length === 0) {
178
- throw new Error("Must provide at least one URL");
868
+ throw new ExaError(
869
+ "Must provide at least one URL",
870
+ 400 /* BadRequest */
871
+ );
179
872
  }
180
873
  let requestUrls;
181
874
  if (typeof urls === "string") {
@@ -196,7 +889,7 @@ var Exa = class {
196
889
  * @param {string} query - The question or query to answer.
197
890
  * @param {AnswerOptions} [options] - Additional options for answer generation.
198
891
  * @returns {Promise<AnswerResponse>} The generated answer and source references.
199
- *
892
+ *
200
893
  * Example with systemPrompt:
201
894
  * ```ts
202
895
  * const answer = await exa.answer("What is quantum computing?", {
@@ -205,7 +898,7 @@ var Exa = class {
205
898
  * systemPrompt: "Answer in a technical manner suitable for experts."
206
899
  * });
207
900
  * ```
208
- *
901
+ *
209
902
  * Note: For streaming responses, use the `streamAnswer` method:
210
903
  * ```ts
211
904
  * for await (const chunk of exa.streamAnswer(query)) {
@@ -215,8 +908,9 @@ var Exa = class {
215
908
  */
216
909
  async answer(query, options) {
217
910
  if (options?.stream) {
218
- throw new Error(
219
- "For streaming responses, please use streamAnswer() instead:\n\nfor await (const chunk of exa.streamAnswer(query)) {\n // Handle chunks\n}"
911
+ throw new ExaError(
912
+ "For streaming responses, please use streamAnswer() instead:\n\nfor await (const chunk of exa.streamAnswer(query)) {\n // Handle chunks\n}",
913
+ 400 /* BadRequest */
220
914
  );
221
915
  }
222
916
  const requestBody = {
@@ -236,7 +930,7 @@ var Exa = class {
236
930
  *
237
931
  * Example usage:
238
932
  * ```ts
239
- * for await (const chunk of exa.streamAnswer("What is quantum computing?", {
933
+ * for await (const chunk of exa.streamAnswer("What is quantum computing?", {
240
934
  * text: false,
241
935
  * systemPrompt: "Answer in a concise manner suitable for beginners."
242
936
  * })) {
@@ -262,13 +956,15 @@ var Exa = class {
262
956
  });
263
957
  if (!response.ok) {
264
958
  const message = await response.text();
265
- throw new Error(
266
- `Request failed with status ${response.status}. ${message}`
267
- );
959
+ throw new ExaError(message, response.status, (/* @__PURE__ */ new Date()).toISOString());
268
960
  }
269
961
  const reader = response.body?.getReader();
270
962
  if (!reader) {
271
- throw new Error("No response body available for streaming.");
963
+ throw new ExaError(
964
+ "No response body available for streaming.",
965
+ 500,
966
+ (/* @__PURE__ */ new Date()).toISOString()
967
+ );
272
968
  }
273
969
  const decoder = new TextDecoder();
274
970
  let buffer = "";
@@ -335,5 +1031,27 @@ var Exa = class {
335
1031
  return { content, citations };
336
1032
  }
337
1033
  };
338
- var src_default = Exa;
1034
+ var src_default = Exa2;
1035
+ // Annotate the CommonJS export names for ESM import in node:
1036
+ 0 && (module.exports = {
1037
+ CreateEnrichmentParametersFormat,
1038
+ CreateWebsetSearchParametersBehaviour,
1039
+ EventType,
1040
+ Exa,
1041
+ ExaError,
1042
+ HttpStatusCode,
1043
+ WebhookStatus,
1044
+ WebsetEnrichmentFormat,
1045
+ WebsetEnrichmentStatus,
1046
+ WebsetEnrichmentsClient,
1047
+ WebsetItemEvaluationSatisfied,
1048
+ WebsetItemSource,
1049
+ WebsetItemsClient,
1050
+ WebsetSearchCanceledReason,
1051
+ WebsetSearchStatus,
1052
+ WebsetSearchesClient,
1053
+ WebsetStatus,
1054
+ WebsetWebhooksClient,
1055
+ WebsetsClient
1056
+ });
339
1057
  //# sourceMappingURL=index.js.map