@bisibility/sdk 0.6.1 → 0.7.2

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/client.js CHANGED
@@ -1,7 +1,9 @@
1
- import { BisibilityApiError, BisibilityConfigurationError, BisibilityNetworkError, BisibilityResponseError, } from "./errors.js";
1
+ import { BISIBILITY_API_VERSION, BISIBILITY_API_VERSION_HEADER, UNSUPPORTED_API_VERSION_PROBLEM_TYPE, } from "./api-version.js";
2
+ import { BisibilityApiError, BisibilityApiVersionError, BisibilityConfigurationError, BisibilityNetworkError, BisibilityResponseError, isUnsupportedApiVersionProblem, } from "./errors.js";
2
3
  import { iterateCursorPagination } from "./pagination.js";
3
4
  import { validatePublicIdRequest, validatePublicIdResponse } from "./public-id-contract.js";
4
5
  import { isPublicIdOfType } from "./public-id.js";
6
+ import { installResourceNamespaces } from "./resources.js";
5
7
  import { SDK_VERSION } from "./version.js";
6
8
  const DEFAULT_BASE_URL = "https://bisibility.com/api/v1";
7
9
  const DEFAULT_MAX_RETRIES = 2;
@@ -41,6 +43,24 @@ function stringOrUndefined(value) {
41
43
  function numberOrUndefined(value) {
42
44
  return typeof value === "number" ? value : undefined;
43
45
  }
46
+ function apiVersionErrorDetails(problem) {
47
+ if (!problem?.errors || typeof problem.errors !== "object") {
48
+ return {
49
+ declaredApiVersion: BISIBILITY_API_VERSION,
50
+ serverApiVersions: [],
51
+ };
52
+ }
53
+ const errors = problem.errors;
54
+ const serverApiVersions = Array.isArray(errors.apiVersions)
55
+ ? errors.apiVersions.filter((version) => typeof version === "string")
56
+ : [];
57
+ return {
58
+ declaredApiVersion: typeof errors.declaredApiVersion === "string"
59
+ ? errors.declaredApiVersion
60
+ : BISIBILITY_API_VERSION,
61
+ serverApiVersions,
62
+ };
63
+ }
44
64
  function problemFromJson(value) {
45
65
  if (!value || typeof value !== "object") {
46
66
  return undefined;
@@ -163,7 +183,8 @@ function validateCredential(value) {
163
183
  }
164
184
  }
165
185
  export class BisibilityClient {
166
- #apiKey;
186
+ #apiVersionPreflight;
187
+ #authorizationToken;
167
188
  #defaultHeaders;
168
189
  #fetchImpl;
169
190
  #maxRetries;
@@ -174,27 +195,55 @@ export class BisibilityClient {
174
195
  if (config.projectId !== undefined && !isPublicIdOfType(config.projectId, "prj")) {
175
196
  throw new BisibilityConfigurationError("projectId must match prj_[a-z][a-z0-9]{23}.");
176
197
  }
198
+ if (config.apiKey !== undefined && config.accessToken !== undefined) {
199
+ throw new BisibilityConfigurationError("apiKey and accessToken are mutually exclusive. Pass only one credential.");
200
+ }
177
201
  validateCredential(config.apiKey);
178
- this.#apiKey = config.apiKey;
202
+ this.#authorizationToken = config.accessToken ?? config.apiKey;
179
203
  this.baseUrl = normalizeBaseUrl(config.baseUrl);
180
204
  this.#defaultHeaders = config.headers;
181
205
  this.#fetchImpl = config.fetch;
182
206
  this.#maxRetries = validatedMaxRetries(config.maxRetries);
183
207
  this.#projectId = config.projectId;
184
208
  this.#timeout = validatedTimeout(config.timeout);
209
+ installResourceNamespaces(this);
185
210
  }
211
+ /** @deprecated Use `client.system.getHealth()`. */
186
212
  getHealth(options) {
187
- return this.request("GET", "/health", { ...options, auth: false });
213
+ return this.request("GET", "/health", {
214
+ ...options,
215
+ acceptedStatuses: [503],
216
+ auth: false,
217
+ });
218
+ }
219
+ /** @deprecated Use `client.system.getLiveness()`. */
220
+ getLiveness(options) {
221
+ return this.request("GET", "/liveness", { ...options, auth: false });
222
+ }
223
+ /** @deprecated Use `client.system.getReadiness()`. */
224
+ getReadiness(options) {
225
+ return this.request("GET", "/readiness", {
226
+ ...options,
227
+ acceptedStatuses: [503],
228
+ auth: false,
229
+ });
188
230
  }
231
+ /** @deprecated Use `client.system.getOpenApi()`. */
189
232
  getOpenApi(options) {
190
233
  return this.request("GET", "/openapi.json", { ...options, auth: false });
191
234
  }
192
- getCapabilities(options) {
193
- return this.request("GET", "/capabilities", {
235
+ /** @deprecated Use `client.system.getCapabilities()`. */
236
+ async getCapabilities(options) {
237
+ const response = await this.request("GET", "/capabilities", {
194
238
  ...options,
195
239
  auth: false,
240
+ skipApiVersionPreflight: true,
196
241
  });
242
+ this.assertApiVersionCompatible(response);
243
+ this.#apiVersionPreflight ??= Promise.resolve();
244
+ return response;
197
245
  }
246
+ /** @deprecated Use `client.system.getLlmsText()`. */
198
247
  getLlmsText(options) {
199
248
  return this.request("GET", "/llms.txt", {
200
249
  ...options,
@@ -202,12 +251,14 @@ export class BisibilityClient {
202
251
  parseAs: "text",
203
252
  });
204
253
  }
254
+ /** @deprecated Use `client.pricing.getRates()`. */
205
255
  getProviderRates(options) {
206
256
  return this.request("GET", "/provider-rates", {
207
257
  ...options,
208
258
  auth: false,
209
259
  });
210
260
  }
261
+ /** @deprecated Use `client.pricing.estimate()`. */
211
262
  getCostEstimate(input, options) {
212
263
  return this.request("GET", "/cost-estimate", {
213
264
  ...options,
@@ -223,6 +274,7 @@ export class BisibilityClient {
223
274
  },
224
275
  });
225
276
  }
277
+ /** @deprecated Use `client.locations.search()`. */
226
278
  searchLocations(input, options) {
227
279
  return this.request("GET", "/locations/search", {
228
280
  ...options,
@@ -233,48 +285,60 @@ export class BisibilityClient {
233
285
  },
234
286
  });
235
287
  }
288
+ /** @deprecated Use `client.account.get()`. */
236
289
  getMe(options) {
237
290
  return this.request("GET", "/me", options);
238
291
  }
292
+ /** @deprecated Use `client.account.update()`. */
239
293
  updateMe(input, options) {
240
294
  return this.request("PATCH", "/me", { ...options, body: input });
241
295
  }
296
+ /** @deprecated Use `client.account.tokens.list()`. */
242
297
  listMyTokens(options) {
243
298
  return this.request("GET", "/me/tokens", options);
244
299
  }
300
+ /** @deprecated Use `client.account.tokens.create()`. */
245
301
  createMyToken(input, options) {
246
302
  return this.request("POST", "/me/tokens", {
247
303
  ...options,
248
304
  body: input,
249
305
  });
250
306
  }
307
+ /** @deprecated Use `client.account.tokens.revoke()`. */
251
308
  revokeMyToken(tokenId, options) {
252
309
  return this.request("DELETE", `/me/tokens/${encodedPathSegment(tokenId)}`, options);
253
310
  }
311
+ /** @deprecated Use `client.projects.list()`. */
254
312
  listProjects(options) {
255
313
  return this.request("GET", "/projects", options);
256
314
  }
315
+ /** @deprecated Use `client.projects.create()`. */
257
316
  createProject(input, options) {
258
317
  return this.request("POST", "/projects", {
259
318
  ...options,
260
319
  body: input,
261
320
  });
262
321
  }
322
+ /** @deprecated Use `client.projects.get()`. */
263
323
  getProject(projectId, options) {
264
324
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}`, options);
265
325
  }
326
+ /** @deprecated Use `client.projects.update()`. */
266
327
  updateProject(projectId, input, options) {
267
328
  return this.request("PATCH", `/projects/${encodedPathSegment(projectId)}`, {
268
329
  ...options,
269
330
  body: input,
270
331
  });
271
332
  }
333
+ /** @deprecated Use `client.projects.delete()`. */
272
334
  deleteProject(projectId, options) {
273
335
  return this.request("DELETE", `/projects/${encodedPathSegment(projectId)}`, options);
274
336
  }
337
+ /** @deprecated Use `client.projects.getDefaults()`. */
275
338
  getProjectDefaults(projectId, options) {
276
339
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/defaults`, options);
277
340
  }
341
+ /** @deprecated Use `client.analytics.overview.get()`. */
278
342
  getProjectOverview(projectId, options, requestOptions) {
279
343
  const filters = options ?? {};
280
344
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/overview`, {
@@ -286,12 +350,15 @@ export class BisibilityClient {
286
350
  },
287
351
  });
288
352
  }
353
+ /** @deprecated Use `client.keywords.match()`. */
289
354
  matchProjectKeywords(projectId, input, requestOptions) {
290
355
  return this.request("POST", `/projects/${encodedPathSegment(projectId)}/keyword-matches`, { ...requestOptions, body: input });
291
356
  }
357
+ /** @deprecated Use `client.projects.updateDefaults()`. */
292
358
  updateProjectDefaults(projectId, input, options) {
293
359
  return this.request("PATCH", `/projects/${encodedPathSegment(projectId)}/defaults`, { ...options, body: input });
294
360
  }
361
+ /** @deprecated Use `client.apiKeys.list()`. */
295
362
  listApiKeys(options, requestOptions) {
296
363
  const pagination = options ?? {};
297
364
  return this.request("GET", "/api-keys", {
@@ -302,15 +369,19 @@ export class BisibilityClient {
302
369
  },
303
370
  });
304
371
  }
372
+ /** @deprecated Use `client.apiKeys.iterate()`. */
305
373
  iterateApiKeys(options = {}, requestOptions) {
306
374
  return iterateCursorPagination((pageOptions) => this.listApiKeys(pageOptions, requestOptions), options);
307
375
  }
376
+ /** @deprecated Use `client.apiKeys.create()`. */
308
377
  createApiKey(input, options) {
309
378
  return this.request("POST", "/api-keys", { ...options, body: input });
310
379
  }
380
+ /** @deprecated Use `client.apiKeys.revoke()`. */
311
381
  revokeApiKey(keyId, options) {
312
382
  return this.request("DELETE", `/api-keys/${encodedPathSegment(keyId)}`, options);
313
383
  }
384
+ /** @deprecated Use `client.apiKeys.list({ projectId })`. */
314
385
  listProjectApiKeys(projectId, options, requestOptions) {
315
386
  const pagination = options ?? {};
316
387
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/api-keys`, {
@@ -321,12 +392,15 @@ export class BisibilityClient {
321
392
  },
322
393
  });
323
394
  }
395
+ /** @deprecated Use `client.apiKeys.iterate({ projectId })`. */
324
396
  iterateProjectApiKeys(projectId, options = {}, requestOptions) {
325
397
  return iterateCursorPagination((pageOptions) => this.listProjectApiKeys(projectId, pageOptions, requestOptions), options);
326
398
  }
399
+ /** @deprecated Use `client.apiKeys.create(input, { projectId })`. */
327
400
  createProjectApiKey(projectId, input, options) {
328
401
  return this.request("POST", `/projects/${encodedPathSegment(projectId)}/api-keys`, { ...options, body: input });
329
402
  }
403
+ /** @deprecated Use `client.webhooks.list()`. */
330
404
  listWebhooks(projectId, options, requestOptions) {
331
405
  const pagination = options ?? {};
332
406
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/webhooks`, {
@@ -337,21 +411,26 @@ export class BisibilityClient {
337
411
  },
338
412
  });
339
413
  }
414
+ /** @deprecated Use `client.webhooks.iterate()`. */
340
415
  iterateWebhooks(projectId, options = {}, requestOptions) {
341
416
  return iterateCursorPagination((pageOptions) => this.listWebhooks(projectId, pageOptions, requestOptions), options);
342
417
  }
418
+ /** @deprecated Use `client.webhooks.create()`. */
343
419
  createWebhook(projectId, input, options) {
344
420
  return this.request("POST", `/projects/${encodedPathSegment(projectId)}/webhooks`, {
345
421
  ...options,
346
422
  body: input,
347
423
  });
348
424
  }
425
+ /** @deprecated Use `client.webhooks.update()`. */
349
426
  updateWebhook(projectId, webhookId, input, options) {
350
427
  return this.request("PATCH", `/projects/${encodedPathSegment(projectId)}/webhooks/${encodedPathSegment(webhookId)}`, { ...options, body: input });
351
428
  }
429
+ /** @deprecated Use `client.webhooks.delete()`. */
352
430
  deleteWebhook(projectId, webhookId, options) {
353
431
  return this.request("DELETE", `/projects/${encodedPathSegment(projectId)}/webhooks/${encodedPathSegment(webhookId)}`, options);
354
432
  }
433
+ /** @deprecated Use `client.keywords.list()`. */
355
434
  listKeywords(projectId, options, requestOptions) {
356
435
  const filters = options ?? {};
357
436
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/keywords`, {
@@ -371,30 +450,38 @@ export class BisibilityClient {
371
450
  },
372
451
  });
373
452
  }
453
+ /** @deprecated Use `client.keywords.iterate()`. */
374
454
  iterateKeywords(projectId, options = {}, requestOptions) {
375
455
  return iterateCursorPagination((pageOptions) => this.listKeywords(projectId, pageOptions, requestOptions), options);
376
456
  }
457
+ /** @deprecated Use `client.keywords.add()`. */
377
458
  addKeywords(projectId, input, options) {
378
459
  return this.request("POST", `/projects/${encodedPathSegment(projectId)}/keywords`, { ...options, body: input });
379
460
  }
461
+ /** @deprecated Use `client.keywords.get()`. */
380
462
  getKeyword(keywordId, options) {
381
463
  return this.request("GET", `/keywords/${encodedPathSegment(keywordId)}`, options);
382
464
  }
465
+ /** @deprecated Use `client.keywords.update()`. */
383
466
  updateKeyword(keywordId, input, options) {
384
467
  return this.request("PATCH", `/keywords/${encodedPathSegment(keywordId)}`, {
385
468
  ...options,
386
469
  body: input,
387
470
  });
388
471
  }
472
+ /** @deprecated Use `client.keywords.setTargetUrl()`. */
389
473
  setKeywordTargetUrl(keywordId, targetUrl, options) {
390
474
  return this.updateKeyword(keywordId, { target_url: targetUrl }, options);
391
475
  }
476
+ /** @deprecated Use `client.keywords.delete()`. */
392
477
  deleteKeyword(keywordId, options) {
393
478
  return this.requestOrUndefined("DELETE", `/keywords/${encodedPathSegment(keywordId)}`, options);
394
479
  }
480
+ /** @deprecated Use `client.keywords.bulkUpdate()`. */
395
481
  bulkUpdateKeywords(input, options) {
396
482
  return this.request("POST", "/keywords/bulk", { ...options, body: input });
397
483
  }
484
+ /** @deprecated Use `client.keywords.suggestions.list()`. */
398
485
  listRankedKeywordSuggestions(projectId, options, requestOptions) {
399
486
  const filters = options ?? {};
400
487
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/ranked-keyword-suggestions`, {
@@ -410,6 +497,7 @@ export class BisibilityClient {
410
497
  /**
411
498
  * Research keywords from one seed. This operation requires API write scope because a cache
412
499
  * miss can spend the project's provider budget. Use `estimateOnly` for a free dry run.
500
+ * @deprecated Use `client.keywords.research()`.
413
501
  */
414
502
  researchKeywords(projectId, options, requestOptions) {
415
503
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/keyword-research`, {
@@ -430,6 +518,7 @@ export class BisibilityClient {
430
518
  * Analyze backlinks. This operation requires API write scope because a cache miss can spend the
431
519
  * project's provider budget. Use `estimateOnly` (`estimate_only` on the wire) for a free dry
432
520
  * run.
521
+ * @deprecated Use `client.backlinks.analyze()`.
433
522
  */
434
523
  analyzeBacklinks(projectId, options, requestOptions) {
435
524
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/backlinks`, {
@@ -449,6 +538,7 @@ export class BisibilityClient {
449
538
  /**
450
539
  * Load more rows into an unexpired backlinks snapshot. This operation requires API write scope
451
540
  * and spends provider budget.
541
+ * @deprecated Use `client.backlinks.extendSnapshot()`.
452
542
  */
453
543
  loadMoreBacklinkRows(projectId, options, requestOptions) {
454
544
  return this.request("POST", `/projects/${encodedPathSegment(projectId)}/backlinks/rows`, {
@@ -464,10 +554,12 @@ export class BisibilityClient {
464
554
  /**
465
555
  * Hydrate keyword metrics. This operation requires API write scope because cache misses can
466
556
  * spend the project's provider budget. Use `estimate_only` for a free dry run.
557
+ * @deprecated Use `client.keywords.metrics.get()`.
467
558
  */
468
559
  getKeywordMetrics(projectId, input, options) {
469
560
  return this.request("POST", `/projects/${encodedPathSegment(projectId)}/keyword-metrics`, { ...options, body: input });
470
561
  }
562
+ /** @deprecated Use `client.rankChecks.history.export()`. */
471
563
  exportRankHistory(projectId, options = {}, requestOptions) {
472
564
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/exports/rank-history`, {
473
565
  ...requestOptions,
@@ -482,15 +574,19 @@ export class BisibilityClient {
482
574
  },
483
575
  });
484
576
  }
577
+ /** @deprecated Use `client.rankChecks.history.iterate()`. */
485
578
  iterateRankHistoryExport(projectId, options = {}, requestOptions) {
486
579
  return iterateCursorPagination((pageOptions) => this.exportRankHistory(projectId, { ...options, ...pageOptions, format: "json" }, requestOptions), options);
487
580
  }
581
+ /** @deprecated Use `client.sitemapMonitors.list()`. */
488
582
  listSitemapMonitors(projectId, options) {
489
583
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/sitemap-monitors`, options);
490
584
  }
585
+ /** @deprecated Use `client.sitemapMonitors.update()`. */
491
586
  updateSitemapMonitor(projectId, monitorId, input, options) {
492
587
  return this.request("PATCH", `/projects/${encodedPathSegment(projectId)}/sitemap-monitors/${encodedPathSegment(monitorId)}`, { ...options, body: input });
493
588
  }
589
+ /** @deprecated Use `client.rankChecks.list()`. */
494
590
  listRankChecks(keywordId, options, requestOptions) {
495
591
  const filters = options ?? {};
496
592
  return this.request("GET", `/keywords/${encodedPathSegment(keywordId)}/rank-checks`, {
@@ -504,9 +600,11 @@ export class BisibilityClient {
504
600
  },
505
601
  });
506
602
  }
603
+ /** @deprecated Use `client.rankChecks.iterate()`. */
507
604
  iterateRankChecks(keywordId, options = {}, requestOptions) {
508
605
  return iterateCursorPagination((pageOptions) => this.listRankChecks(keywordId, pageOptions, requestOptions), options);
509
606
  }
607
+ /** @deprecated Use `client.rankChecks.run()`. */
510
608
  runRankCheck(keywordId, input, options) {
511
609
  const { async: runAsync, ...requestOptions } = options ?? {};
512
610
  const body = input && Object.keys(input).length ? input : undefined;
@@ -516,12 +614,15 @@ export class BisibilityClient {
516
614
  ...(runAsync ? { query: { async: "true" } } : {}),
517
615
  });
518
616
  }
617
+ /** @deprecated Use `client.rankChecks.getResult()`. */
519
618
  getRankCheckResult(checkId, options) {
520
619
  return this.request("GET", `/rank-checks/${encodedPathSegment(checkId)}`, options);
521
620
  }
621
+ /** @deprecated Use `client.signals.create()`. */
522
622
  createSignal(input, options) {
523
623
  return this.request("POST", "/signals", { ...options, body: input });
524
624
  }
625
+ /** @deprecated Use `client.signals.list()`. */
525
626
  listSignals(projectId, options, requestOptions) {
526
627
  const filters = options ?? {};
527
628
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/signals`, {
@@ -536,9 +637,11 @@ export class BisibilityClient {
536
637
  },
537
638
  });
538
639
  }
640
+ /** @deprecated Use `client.signals.iterate()`. */
539
641
  iterateSignals(projectId, options = {}, requestOptions) {
540
642
  return iterateCursorPagination((pageOptions) => this.listSignals(projectId, pageOptions, requestOptions), options);
541
643
  }
644
+ /** @deprecated Use `client.analytics.traffic.list()`. */
542
645
  listTrafficSnapshots(projectId, options, requestOptions) {
543
646
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/analytics/traffic-snapshots`, {
544
647
  ...requestOptions,
@@ -551,6 +654,7 @@ export class BisibilityClient {
551
654
  },
552
655
  });
553
656
  }
657
+ /** @deprecated Use `client.analytics.searchPerformance.list()`. */
554
658
  listSearchPerformanceQueryStats(projectId, options, requestOptions) {
555
659
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/analytics/query-stats`, {
556
660
  ...requestOptions,
@@ -563,9 +667,11 @@ export class BisibilityClient {
563
667
  },
564
668
  });
565
669
  }
670
+ /** @deprecated Use `client.analytics.traffic.sync()`. */
566
671
  syncProjectTraffic(projectId, options) {
567
672
  return this.request("POST", `/projects/${encodedPathSegment(projectId)}/analytics/sync`, options);
568
673
  }
674
+ /** @deprecated Use `client.alertRules.list()`. */
569
675
  listAlertRules(projectId, options, requestOptions) {
570
676
  const pagination = options ?? {};
571
677
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/alert-rules`, {
@@ -576,21 +682,26 @@ export class BisibilityClient {
576
682
  },
577
683
  });
578
684
  }
685
+ /** @deprecated Use `client.alertRules.iterate()`. */
579
686
  iterateAlertRules(projectId, options = {}, requestOptions) {
580
687
  return iterateCursorPagination((pageOptions) => this.listAlertRules(projectId, pageOptions, requestOptions), options);
581
688
  }
689
+ /** @deprecated Use `client.alertRules.create()`. */
582
690
  createAlertRule(projectId, input, options) {
583
691
  return this.request("POST", `/projects/${encodedPathSegment(projectId)}/alert-rules`, { ...options, body: input });
584
692
  }
693
+ /** @deprecated Use `client.alertRules.update()`. */
585
694
  updateAlertRule(ruleId, input, options) {
586
695
  return this.request("PATCH", `/alert-rules/${encodedPathSegment(ruleId)}`, {
587
696
  ...options,
588
697
  body: input,
589
698
  });
590
699
  }
700
+ /** @deprecated Use `client.alertRules.delete()`. */
591
701
  deleteAlertRule(ruleId, options) {
592
702
  return this.request("DELETE", `/alert-rules/${encodedPathSegment(ruleId)}`, options);
593
703
  }
704
+ /** @deprecated Use `client.alerts.list()`. */
594
705
  listTriggeredAlerts(projectId, options, requestOptions) {
595
706
  const pagination = options ?? {};
596
707
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/triggered-alerts`, {
@@ -601,15 +712,19 @@ export class BisibilityClient {
601
712
  },
602
713
  });
603
714
  }
715
+ /** @deprecated Use `client.alerts.iterate()`. */
604
716
  iterateTriggeredAlerts(projectId, options = {}, requestOptions) {
605
717
  return iterateCursorPagination((pageOptions) => this.listTriggeredAlerts(projectId, pageOptions, requestOptions), options);
606
718
  }
719
+ /** @deprecated Use `client.alerts.mute()`. */
607
720
  muteTriggeredAlert(projectId, alertId, options) {
608
721
  return this.request("POST", `/projects/${encodedPathSegment(projectId)}/triggered-alerts/${encodedPathSegment(alertId)}/mute`, options);
609
722
  }
723
+ /** @deprecated Use `client.alerts.markAllRead({ projectId })`. */
610
724
  markProjectAlertsRead(projectId, options) {
611
725
  return this.request("POST", `/projects/${encodedPathSegment(projectId)}/triggered-alerts/mark-read`, options);
612
726
  }
727
+ /** @deprecated Use `client.team.members.list()`. */
613
728
  listTeamMembers(projectId, options, requestOptions) {
614
729
  const pagination = options ?? {};
615
730
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/team/members`, {
@@ -620,9 +735,11 @@ export class BisibilityClient {
620
735
  },
621
736
  });
622
737
  }
738
+ /** @deprecated Use `client.team.members.iterate()`. */
623
739
  iterateTeamMembers(projectId, options = {}, requestOptions) {
624
740
  return iterateCursorPagination((pageOptions) => this.listTeamMembers(projectId, pageOptions, requestOptions), options);
625
741
  }
742
+ /** @deprecated Use `client.team.invites.list()`. */
626
743
  listTeamInvites(projectId, options, requestOptions) {
627
744
  const pagination = options ?? {};
628
745
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/team/invites`, {
@@ -633,27 +750,35 @@ export class BisibilityClient {
633
750
  },
634
751
  });
635
752
  }
753
+ /** @deprecated Use `client.team.invites.iterate()`. */
636
754
  iterateTeamInvites(projectId, options = {}, requestOptions) {
637
755
  return iterateCursorPagination((pageOptions) => this.listTeamInvites(projectId, pageOptions, requestOptions), options);
638
756
  }
757
+ /** @deprecated Use `client.team.invites.create()`. */
639
758
  createTeamInvite(projectId, input, options) {
640
759
  return this.request("POST", `/projects/${encodedPathSegment(projectId)}/team/invites`, { ...options, body: input });
641
760
  }
761
+ /** @deprecated Use `client.team.invites.revoke({ id, projectId })`. */
642
762
  revokeTeamInvite(projectId, inviteId, options) {
643
763
  return this.request("DELETE", `/projects/${encodedPathSegment(projectId)}/team/invites/${encodedPathSegment(inviteId)}`, options);
644
764
  }
765
+ /** @deprecated Use `client.team.invites.revoke(id)`. */
645
766
  revokeTeamInviteById(inviteId, options) {
646
767
  return this.request("DELETE", `/team/invites/${encodedPathSegment(inviteId)}`, options);
647
768
  }
769
+ /** @deprecated Use `client.team.invites.resend()`. */
648
770
  resendTeamInvite(projectId, inviteId, options) {
649
771
  return this.request("POST", `/projects/${encodedPathSegment(projectId)}/team/invites/${encodedPathSegment(inviteId)}/resend`, options);
650
772
  }
773
+ /** @deprecated Use `client.team.members.updateRole()`. */
651
774
  updateTeamMemberRole(projectId, memberId, input, options) {
652
775
  return this.request("PATCH", `/projects/${encodedPathSegment(projectId)}/team/members/${encodedPathSegment(memberId)}`, { ...options, body: input });
653
776
  }
777
+ /** @deprecated Use `client.team.members.remove()`. */
654
778
  removeTeamMember(projectId, memberId, options) {
655
779
  return this.request("DELETE", `/projects/${encodedPathSegment(projectId)}/team/members/${encodedPathSegment(memberId)}`, options);
656
780
  }
781
+ /** @deprecated Use `client.providers.list()`. */
657
782
  listProviders(projectId, options, requestOptions) {
658
783
  const pagination = options ?? {};
659
784
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/providers`, {
@@ -664,36 +789,47 @@ export class BisibilityClient {
664
789
  },
665
790
  });
666
791
  }
792
+ /** @deprecated Use `client.providers.iterate()`. */
667
793
  iterateProviders(projectId, options = {}, requestOptions) {
668
794
  return iterateCursorPagination((pageOptions) => this.listProviders(projectId, pageOptions, requestOptions), options);
669
795
  }
796
+ /** @deprecated Use `client.providers.connect()`. */
670
797
  connectProvider(projectId, providerId, input = {}, options) {
671
798
  return this.request("POST", `/projects/${encodedPathSegment(projectId)}/providers/${encodedPathSegment(providerId)}/connect`, { ...options, body: bodyOrUndefined(input) });
672
799
  }
800
+ /** @deprecated Use `client.providers.test()`. */
673
801
  testProviderConnection(projectId, providerId, input = {}, options) {
674
802
  return this.request("POST", `/projects/${encodedPathSegment(projectId)}/providers/${encodedPathSegment(providerId)}/test`, { ...options, body: bodyOrUndefined(input) });
675
803
  }
804
+ /** @deprecated Use `client.providers.updateSettings()`. */
676
805
  updateProviderSettings(projectId, providerId, input, options) {
677
806
  return this.request("PATCH", `/projects/${encodedPathSegment(projectId)}/providers/${encodedPathSegment(providerId)}`, { ...options, body: input });
678
807
  }
808
+ /** @deprecated Use `client.providers.setEnabled()`. */
679
809
  setProviderEnabled(projectId, providerId, enabled, options) {
680
810
  return this.updateProviderSettings(projectId, providerId, { enabled }, options);
681
811
  }
812
+ /** @deprecated Use `client.providers.setEnabled(projectId, providerId, true)`. */
682
813
  enableProvider(projectId, providerId, options) {
683
814
  return this.setProviderEnabled(projectId, providerId, true, options);
684
815
  }
816
+ /** @deprecated Use `client.providers.setEnabled(projectId, providerId, false)`. */
685
817
  disableProvider(projectId, providerId, options) {
686
818
  return this.setProviderEnabled(projectId, providerId, false, options);
687
819
  }
820
+ /** @deprecated Use `client.providers.setPriority()`. */
688
821
  setProviderPriority(projectId, providerId, priority, options) {
689
822
  return this.updateProviderSettings(projectId, providerId, { priority }, options);
690
823
  }
824
+ /** @deprecated Use `client.providers.setPrimary()`. */
691
825
  setPrimaryProvider(projectId, providerId, primary = true, options) {
692
826
  return this.updateProviderSettings(projectId, providerId, { primary }, options);
693
827
  }
828
+ /** @deprecated Use `client.providers.disconnect()`. */
694
829
  disconnectProvider(projectId, providerId, options) {
695
830
  return this.request("DELETE", `/projects/${encodedPathSegment(projectId)}/providers/${encodedPathSegment(providerId)}`, options);
696
831
  }
832
+ /** @deprecated Use `client.savedViews.list()`. */
697
833
  listSavedViews(projectId, options, requestOptions) {
698
834
  const pagination = options ?? {};
699
835
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/saved-views`, {
@@ -705,18 +841,50 @@ export class BisibilityClient {
705
841
  },
706
842
  });
707
843
  }
844
+ /** @deprecated Use `client.savedViews.iterate()`. */
708
845
  iterateSavedViews(projectId, options = {}, requestOptions) {
709
846
  return iterateCursorPagination((pageOptions) => this.listSavedViews(projectId, pageOptions, requestOptions), options);
710
847
  }
848
+ /** @deprecated Use `client.savedViews.create()`. */
711
849
  createSavedView(projectId, input, options) {
712
850
  return this.request("POST", `/projects/${encodedPathSegment(projectId)}/saved-views`, { ...options, body: input });
713
851
  }
852
+ /** @deprecated Use `client.savedViews.delete({ id, projectId })`. */
714
853
  deleteSavedView(projectId, viewId, options) {
715
854
  return this.request("DELETE", `/projects/${encodedPathSegment(projectId)}/saved-views/${encodedPathSegment(viewId)}`, options);
716
855
  }
856
+ /** @deprecated Use `client.savedViews.delete(id)`. */
717
857
  deleteSavedViewById(viewId, options) {
718
858
  return this.request("DELETE", `/saved-views/${encodedPathSegment(viewId)}`, options);
719
859
  }
860
+ /** @deprecated Use `client.keywords.saved.list()` instead. */
861
+ listSavedKeywords(projectId, options, requestOptions) {
862
+ const pagination = options ?? {};
863
+ return this.request("GET", `/projects/${encodedPathSegment(projectId)}/saved-keywords`, {
864
+ ...requestOptions,
865
+ query: {
866
+ ...(pagination.cursor === undefined ? {} : { cursor: pagination.cursor }),
867
+ ...(pagination.limit === undefined ? {} : { limit: pagination.limit }),
868
+ },
869
+ });
870
+ }
871
+ /** @deprecated Use `client.keywords.saved.iterate()` instead. */
872
+ iterateSavedKeywords(projectId, options = {}, requestOptions) {
873
+ return iterateCursorPagination((pageOptions) => this.listSavedKeywords(projectId, pageOptions, requestOptions), options);
874
+ }
875
+ /**
876
+ * Saves keywords for later without putting them under rank tracking.
877
+ * Keywords already tracked or already saved come back as `skipped`.
878
+ * @deprecated Use `client.keywords.saved.create()` instead.
879
+ */
880
+ createSavedKeywords(projectId, input, options) {
881
+ return this.request("POST", `/projects/${encodedPathSegment(projectId)}/saved-keywords`, { ...options, body: input });
882
+ }
883
+ /** @deprecated Use `client.keywords.saved.delete()` instead. */
884
+ deleteSavedKeyword(projectId, savedKeywordId, options) {
885
+ return this.request("DELETE", `/projects/${encodedPathSegment(projectId)}/saved-keywords/${encodedPathSegment(savedKeywordId)}`, options);
886
+ }
887
+ /** @deprecated Use `client.competitors.list()`. */
720
888
  listCompetitors(projectId, options, requestOptions) {
721
889
  const pagination = options ?? {};
722
890
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/competitors`, {
@@ -727,24 +895,31 @@ export class BisibilityClient {
727
895
  },
728
896
  });
729
897
  }
898
+ /** @deprecated Use `client.competitors.iterate()`. */
730
899
  iterateCompetitors(projectId, options = {}, requestOptions) {
731
900
  return iterateCursorPagination((pageOptions) => this.listCompetitors(projectId, pageOptions, requestOptions), options);
732
901
  }
902
+ /** @deprecated Use `client.competitors.add()`. */
733
903
  addCompetitor(projectId, input, options) {
734
904
  return this.request("POST", `/projects/${encodedPathSegment(projectId)}/competitors`, { ...options, body: input });
735
905
  }
906
+ /** @deprecated Use `client.competitors.remove({ id, projectId })`. */
736
907
  removeCompetitor(projectId, competitorId, options) {
737
908
  return this.request("DELETE", `/projects/${encodedPathSegment(projectId)}/competitors/${encodedPathSegment(competitorId)}`, options);
738
909
  }
910
+ /** @deprecated Use `client.competitors.remove(id)`. */
739
911
  removeCompetitorById(competitorId, options) {
740
912
  return this.request("DELETE", `/competitors/${encodedPathSegment(competitorId)}`, options);
741
913
  }
914
+ /** @deprecated Use `client.notificationSettings.get()`. */
742
915
  getNotificationPreferences(projectId, options) {
743
916
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/notification-preferences`, options);
744
917
  }
918
+ /** @deprecated Use `client.notificationSettings.update()`. */
745
919
  updateNotificationPreferences(projectId, input, options) {
746
920
  return this.request("PATCH", `/projects/${encodedPathSegment(projectId)}/notification-preferences`, { ...options, body: input });
747
921
  }
922
+ /** @deprecated Use `client.imports.tokens.list()`. */
748
923
  listMigrationTokens(projectId, options, requestOptions) {
749
924
  const pagination = options ?? {};
750
925
  return this.request("GET", `/projects/${encodedPathSegment(projectId)}/migration-tokens`, {
@@ -755,36 +930,44 @@ export class BisibilityClient {
755
930
  },
756
931
  });
757
932
  }
933
+ /** @deprecated Use `client.imports.tokens.iterate()`. */
758
934
  iterateMigrationTokens(projectId, options = {}, requestOptions) {
759
935
  return iterateCursorPagination((pageOptions) => this.listMigrationTokens(projectId, pageOptions, requestOptions), options);
760
936
  }
937
+ /** @deprecated Use `client.imports.tokens.create()`. */
761
938
  mintMigrationToken(projectId, input = {}, options) {
762
939
  return this.request("POST", `/projects/${encodedPathSegment(projectId)}/migration-tokens`, { ...options, body: bodyOrUndefined(input) });
763
940
  }
941
+ /** @deprecated Use `client.imports.tokens.revoke({ id, projectId })`. */
764
942
  revokeMigrationToken(projectId, tokenId, options) {
765
943
  return this.request("DELETE", `/projects/${encodedPathSegment(projectId)}/migration-tokens/${encodedPathSegment(tokenId)}`, options);
766
944
  }
945
+ /** @deprecated Use `client.imports.tokens.revoke(id)`. */
767
946
  revokeMigrationTokenById(tokenId, options) {
768
947
  return this.request("DELETE", `/migration-tokens/${encodedPathSegment(tokenId)}`, options);
769
948
  }
949
+ /** @deprecated Use `client.imports.compatibility.get()`. */
770
950
  getCloudImportCompatibility(options) {
771
951
  return this.request("GET", "/cloud/import/compatibility", {
772
952
  ...options,
773
953
  auth: false,
774
954
  });
775
955
  }
956
+ /** @deprecated Use `client.imports.runFromExport()`. */
776
957
  importCloudExport(input, options) {
777
958
  return this.request("POST", "/cloud/import", {
778
959
  ...options,
779
960
  body: input,
780
961
  });
781
962
  }
963
+ /** @deprecated Use `client.imports.sessions.create()`. */
782
964
  createCloudImportSession(input, options) {
783
965
  return this.request("POST", "/cloud/import/sessions", {
784
966
  ...options,
785
967
  body: input,
786
968
  });
787
969
  }
970
+ /** @deprecated Use `client.imports.sessions.uploadChunk()`. */
788
971
  uploadCloudImportChunk(sessionId, index, input, options) {
789
972
  const { contentEncoding, headers, ...requestOptions } = options ?? {};
790
973
  const mergedHeaders = new Headers(headers);
@@ -793,6 +976,7 @@ export class BisibilityClient {
793
976
  }
794
977
  return this.request("PUT", `/cloud/import/sessions/${encodedPathSegment(sessionId)}/chunks/${encodedPathSegment(String(index))}`, { ...requestOptions, body: input, headers: mergedHeaders });
795
978
  }
979
+ /** @deprecated Use `client.imports.sessions.finalize()`. */
796
980
  finalizeCloudImportSession(sessionId, options) {
797
981
  return this.request("POST", `/cloud/import/sessions/${encodedPathSegment(sessionId)}/finalize`, options);
798
982
  }
@@ -815,6 +999,70 @@ export class BisibilityClient {
815
999
  }
816
1000
  return absolute ? url.toString() : `${url.pathname}${url.search}`;
817
1001
  }
1002
+ assertApiVersionCompatible(response) {
1003
+ const advertised = response.apiVersions;
1004
+ if (advertised === undefined) {
1005
+ return;
1006
+ }
1007
+ if (!Array.isArray(advertised) || advertised.some((version) => typeof version !== "string")) {
1008
+ throw new BisibilityResponseError("Bisibility API returned invalid API version capabilities.", {
1009
+ body: JSON.stringify(response),
1010
+ cause: undefined,
1011
+ method: "GET",
1012
+ status: 200,
1013
+ url: this.buildUrl("/capabilities"),
1014
+ });
1015
+ }
1016
+ if (advertised.includes(BISIBILITY_API_VERSION)) {
1017
+ return;
1018
+ }
1019
+ const detail = `The declared API version ${BISIBILITY_API_VERSION} is not served by this server.`;
1020
+ const problem = {
1021
+ detail,
1022
+ errors: {
1023
+ apiVersions: advertised,
1024
+ declaredApiVersion: BISIBILITY_API_VERSION,
1025
+ },
1026
+ status: 409,
1027
+ title: "Unsupported API version",
1028
+ type: UNSUPPORTED_API_VERSION_PROBLEM_TYPE,
1029
+ };
1030
+ throw new BisibilityApiVersionError(detail, {
1031
+ body: JSON.stringify(problem),
1032
+ declaredApiVersion: BISIBILITY_API_VERSION,
1033
+ headers: new Headers(),
1034
+ method: "GET",
1035
+ problem,
1036
+ serverApiVersions: advertised,
1037
+ status: 409,
1038
+ url: this.buildUrl("/capabilities"),
1039
+ });
1040
+ }
1041
+ ensureApiVersionPreflight(signal, timeout) {
1042
+ if (this.#apiVersionPreflight === undefined) {
1043
+ const options = {
1044
+ auth: false,
1045
+ skipApiVersionPreflight: true,
1046
+ };
1047
+ if (signal !== undefined) {
1048
+ options.signal = signal;
1049
+ }
1050
+ if (timeout !== undefined) {
1051
+ options.timeout = timeout;
1052
+ }
1053
+ const pending = this.request("GET", "/capabilities", options).then((response) => {
1054
+ this.assertApiVersionCompatible(response);
1055
+ });
1056
+ const cached = pending.catch((error) => {
1057
+ if (!(error instanceof BisibilityApiVersionError) && this.#apiVersionPreflight === cached) {
1058
+ this.#apiVersionPreflight = undefined;
1059
+ }
1060
+ throw error;
1061
+ });
1062
+ this.#apiVersionPreflight = cached;
1063
+ }
1064
+ return this.#apiVersionPreflight;
1065
+ }
818
1066
  async request(method, path, options = {}) {
819
1067
  const statusRef = { status: 0 };
820
1068
  const result = await this.requestOrUndefined(method, path, options, statusRef);
@@ -841,8 +1089,8 @@ export class BisibilityClient {
841
1089
  if (!fetchImpl) {
842
1090
  throw new BisibilityConfigurationError("No fetch implementation is available. Pass fetch in BisibilityClient config.");
843
1091
  }
844
- if (options.auth !== false && !this.#apiKey) {
845
- throw new BisibilityConfigurationError("apiKey is required for this Bisibility API method.");
1092
+ if (options.auth !== false && !this.#authorizationToken) {
1093
+ throw new BisibilityConfigurationError("apiKey or accessToken is required for this Bisibility API method.");
846
1094
  }
847
1095
  const headers = mergeHeaders(this.#defaultHeaders, options.headers);
848
1096
  if (this.#projectId !== undefined && !headers.has("X-Bisibility-Project")) {
@@ -852,13 +1100,17 @@ export class BisibilityClient {
852
1100
  if (projectHeader !== null && !isPublicIdOfType(projectHeader, "prj")) {
853
1101
  throw new BisibilityConfigurationError("X-Bisibility-Project must match prj_[a-z][a-z0-9]{23}.");
854
1102
  }
1103
+ if (!options.skipApiVersionPreflight) {
1104
+ await this.ensureApiVersionPreflight(options.signal, options.timeout);
1105
+ }
855
1106
  if (options.auth !== false) {
856
- headers.set("Authorization", `Bearer ${this.#apiKey}`);
1107
+ headers.set("Authorization", `Bearer ${this.#authorizationToken}`);
857
1108
  }
858
1109
  if (options.idempotencyKey) {
859
1110
  headers.set("Idempotency-Key", options.idempotencyKey);
860
1111
  }
861
1112
  headers.set("X-Bisibility-Client", CLIENT_ID);
1113
+ headers.set(BISIBILITY_API_VERSION_HEADER, BISIBILITY_API_VERSION);
862
1114
  if (!headers.has("User-Agent")) {
863
1115
  try {
864
1116
  headers.set("User-Agent", CLIENT_ID);
@@ -903,7 +1155,7 @@ export class BisibilityClient {
903
1155
  await sleepForRetry(retryBackoffMs(attempt), options.signal, method, url);
904
1156
  continue;
905
1157
  }
906
- if (!response.ok) {
1158
+ if (!response.ok && !options.acceptedStatuses?.includes(response.status)) {
907
1159
  const error = await this.errorFromResponse(response, method, url);
908
1160
  if (retryable &&
909
1161
  attempt < this.#maxRetries &&
@@ -971,6 +1223,19 @@ export class BisibilityClient {
971
1223
  }
972
1224
  const problem = problemFromJson(parsed);
973
1225
  const message = problem?.detail || body || `Bisibility API request failed with status ${response.status}.`;
1226
+ if (response.status === 409 && isUnsupportedApiVersionProblem(problem)) {
1227
+ const details = apiVersionErrorDetails(problem);
1228
+ return new BisibilityApiVersionError(message, {
1229
+ body,
1230
+ declaredApiVersion: details.declaredApiVersion,
1231
+ headers,
1232
+ method,
1233
+ problem,
1234
+ serverApiVersions: details.serverApiVersions,
1235
+ status: response.status,
1236
+ url,
1237
+ });
1238
+ }
974
1239
  return new BisibilityApiError(message, {
975
1240
  body,
976
1241
  headers,