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