exa-js 1.5.12 → 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,16 @@ 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
+ *
893
+ * Example with systemPrompt:
894
+ * ```ts
895
+ * const answer = await exa.answer("What is quantum computing?", {
896
+ * text: true,
897
+ * model: "exa-pro",
898
+ * systemPrompt: "Answer in a technical manner suitable for experts."
899
+ * });
900
+ * ```
901
+ *
200
902
  * Note: For streaming responses, use the `streamAnswer` method:
201
903
  * ```ts
202
904
  * for await (const chunk of exa.streamAnswer(query)) {
@@ -206,15 +908,17 @@ var Exa = class {
206
908
  */
207
909
  async answer(query, options) {
208
910
  if (options?.stream) {
209
- throw new Error(
210
- "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 */
211
914
  );
212
915
  }
213
916
  const requestBody = {
214
917
  query,
215
918
  stream: false,
216
919
  text: options?.text ?? false,
217
- model: options?.model ?? "exa"
920
+ model: options?.model ?? "exa",
921
+ systemPrompt: options?.systemPrompt
218
922
  };
219
923
  return await this.request("/answer", "POST", requestBody);
220
924
  }
@@ -226,7 +930,10 @@ var Exa = class {
226
930
  *
227
931
  * Example usage:
228
932
  * ```ts
229
- * for await (const chunk of exa.streamAnswer("What is quantum computing?", { text: false })) {
933
+ * for await (const chunk of exa.streamAnswer("What is quantum computing?", {
934
+ * text: false,
935
+ * systemPrompt: "Answer in a concise manner suitable for beginners."
936
+ * })) {
230
937
  * if (chunk.content) process.stdout.write(chunk.content);
231
938
  * if (chunk.citations) {
232
939
  * console.log("\nCitations: ", chunk.citations);
@@ -239,7 +946,8 @@ var Exa = class {
239
946
  query,
240
947
  text: options?.text ?? false,
241
948
  stream: true,
242
- model: options?.model ?? "exa"
949
+ model: options?.model ?? "exa",
950
+ systemPrompt: options?.systemPrompt
243
951
  };
244
952
  const response = await fetchImpl(this.baseURL + "/answer", {
245
953
  method: "POST",
@@ -248,13 +956,15 @@ var Exa = class {
248
956
  });
249
957
  if (!response.ok) {
250
958
  const message = await response.text();
251
- throw new Error(
252
- `Request failed with status ${response.status}. ${message}`
253
- );
959
+ throw new ExaError(message, response.status, (/* @__PURE__ */ new Date()).toISOString());
254
960
  }
255
961
  const reader = response.body?.getReader();
256
962
  if (!reader) {
257
- 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
+ );
258
968
  }
259
969
  const decoder = new TextDecoder();
260
970
  let buffer = "";
@@ -321,5 +1031,27 @@ var Exa = class {
321
1031
  return { content, citations };
322
1032
  }
323
1033
  };
324
- 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
+ });
325
1057
  //# sourceMappingURL=index.js.map