@microsoft/webiq 0.1.7 → 1.0.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
@@ -332,9 +332,31 @@ var APIStatusError = class _APIStatusError extends WebIQError {
332
332
  this.name = "APIStatusError";
333
333
  this.statusCode = statusCode;
334
334
  this.body = options?.body;
335
- this.requestId = options?.requestId;
336
- this.traceId = options?.traceId;
337
335
  Object.setPrototypeOf(this, _APIStatusError.prototype);
336
+ this.requestId = options?.requestId ?? this.stringField("requestId");
337
+ this.traceId = options?.traceId ?? this.stringField("traceId");
338
+ }
339
+ stringField(name) {
340
+ if (this.body && typeof this.body === "object" && name in this.body) {
341
+ const value = this.body[name];
342
+ return typeof value === "string" ? value : void 0;
343
+ }
344
+ return void 0;
345
+ }
346
+ get errorCode() {
347
+ return this.stringField("errorCode");
348
+ }
349
+ get errorCategory() {
350
+ return this.stringField("errorCategory");
351
+ }
352
+ get userMessage() {
353
+ return this.stringField("userMessage");
354
+ }
355
+ get technicalDetails() {
356
+ return this.stringField("technicalDetails");
357
+ }
358
+ get retryAfter() {
359
+ return this.stringField("retryAfter");
338
360
  }
339
361
  };
340
362
  var RateLimitError = class _RateLimitError extends APIStatusError {
@@ -351,6 +373,20 @@ var RateLimitError = class _RateLimitError extends APIStatusError {
351
373
  return void 0;
352
374
  }
353
375
  };
376
+ var BadRequestError = class _BadRequestError extends APIStatusError {
377
+ constructor(statusCode, message, options) {
378
+ super(statusCode, message, options);
379
+ this.name = "BadRequestError";
380
+ Object.setPrototypeOf(this, _BadRequestError.prototype);
381
+ }
382
+ };
383
+ var NotFoundError = class _NotFoundError extends APIStatusError {
384
+ constructor(statusCode, message, options) {
385
+ super(statusCode, message, options);
386
+ this.name = "NotFoundError";
387
+ Object.setPrototypeOf(this, _NotFoundError.prototype);
388
+ }
389
+ };
354
390
  var AuthenticationError = class _AuthenticationError extends APIStatusError {
355
391
  constructor(statusCode, message, options) {
356
392
  super(statusCode, message, options);
@@ -398,7 +434,7 @@ var RetryPolicy = class {
398
434
  this.maxRetries = options?.maxRetries ?? 2;
399
435
  this.baseDelaySeconds = options?.baseDelaySeconds ?? 0.25;
400
436
  this.maxDelaySeconds = options?.maxDelaySeconds ?? 4;
401
- this.retryOnStatus = new Set(options?.retryOnStatus ?? [408, 500, 502, 503, 504]);
437
+ this.retryOnStatus = new Set(options?.retryOnStatus ?? [408, 500, 502, 520, 523, 524]);
402
438
  }
403
439
  /**
404
440
  * Compute the delay before the next retry attempt.
@@ -409,7 +445,7 @@ var RetryPolicy = class {
409
445
  */
410
446
  computeDelay(attempt, retryAfter) {
411
447
  if (retryAfter !== void 0) {
412
- return Math.min(retryAfter, this.maxDelaySeconds);
448
+ return retryAfter;
413
449
  }
414
450
  const delay = Math.random() * this.baseDelaySeconds * Math.pow(2, attempt - 1);
415
451
  return Math.min(delay, this.maxDelaySeconds);
@@ -421,8 +457,24 @@ var RetryPolicy = class {
421
457
  return this.retryOnStatus.has(statusCode);
422
458
  }
423
459
  };
424
- function sleep(seconds) {
425
- return new Promise((resolve) => setTimeout(resolve, seconds * 1e3));
460
+ async function sleep(seconds, signal) {
461
+ let remainingMs = seconds * 1e3;
462
+ do {
463
+ signal?.throwIfAborted();
464
+ const delayMs = Math.min(remainingMs, 2147483647);
465
+ await new Promise((resolve, reject) => {
466
+ const onAbort = () => {
467
+ clearTimeout(timer);
468
+ reject(signal?.reason ?? new DOMException("Request aborted", "AbortError"));
469
+ };
470
+ const timer = setTimeout(() => {
471
+ signal?.removeEventListener("abort", onAbort);
472
+ resolve();
473
+ }, delayMs);
474
+ signal?.addEventListener("abort", onAbort, { once: true });
475
+ });
476
+ remainingMs -= delayMs;
477
+ } while (remainingMs > 0);
426
478
  }
427
479
 
428
480
  // src/telemetry.ts
@@ -467,15 +519,18 @@ function extractMetadata(body, headers) {
467
519
  }
468
520
  var HttpTransport = class {
469
521
  baseUrl;
522
+ appId;
470
523
  auth;
471
524
  telemetry;
472
525
  retry;
473
526
  timeout;
474
527
  fetchFn;
475
528
  activeControllers = /* @__PURE__ */ new Set();
529
+ closeController = new AbortController();
476
530
  closed = false;
477
531
  constructor(options) {
478
532
  this.baseUrl = options.baseUrl.replace(/\/$/, "");
533
+ this.appId = options.appId;
479
534
  this.auth = options.auth;
480
535
  this.telemetry = options.telemetryHook;
481
536
  this.retry = options.retry ?? new RetryPolicy();
@@ -484,7 +539,19 @@ var HttpTransport = class {
484
539
  }
485
540
  async request(options) {
486
541
  const { method, path, json, signal: callerSignal } = options;
542
+ const retrySignal = callerSignal ? AbortSignal.any([callerSignal, this.closeController.signal]) : this.closeController.signal;
487
543
  const effectiveTimeout = options.timeout ?? this.timeout;
544
+ let url = `${this.baseUrl}${path}`;
545
+ if (this.appId) {
546
+ const fragmentIndex = url.indexOf("#");
547
+ const fragment = fragmentIndex < 0 ? "" : url.slice(fragmentIndex);
548
+ const target = fragmentIndex < 0 ? url : url.slice(0, fragmentIndex);
549
+ const queryIndex = target.indexOf("?");
550
+ const pathname = queryIndex < 0 ? target : target.slice(0, queryIndex);
551
+ const params = new URLSearchParams(queryIndex < 0 ? "" : target.slice(queryIndex + 1));
552
+ params.set("appid", this.appId);
553
+ url = `${pathname}?${params.toString()}${fragment}`;
554
+ }
488
555
  let attempt = 0;
489
556
  while (true) {
490
557
  if (this.closed) {
@@ -503,7 +570,7 @@ var HttpTransport = class {
503
570
  const fetchSignal = callerSignal ? AbortSignal.any([callerSignal, abortController.signal]) : abortController.signal;
504
571
  let response;
505
572
  try {
506
- response = await this.fetchFn(`${this.baseUrl}${path}`, {
573
+ response = await this.fetchFn(url, {
507
574
  method,
508
575
  headers: {
509
576
  "Content-Type": "application/json",
@@ -538,11 +605,13 @@ var HttpTransport = class {
538
605
  traceId,
539
606
  retryAfter,
540
607
  elapsedMs: elapsed,
608
+ responseSizeBytes: responseText ? new TextEncoder().encode(responseText).length : 0,
541
609
  errorBody: response.status >= 400 ? body : void 0
542
610
  })
543
611
  );
544
612
  if (response.status === 401) {
545
- throw new AuthenticationError(response.status, "Unauthorized", {
613
+ const message = body && typeof body === "object" && "userMessage" in body ? String(body.userMessage) : "Unauthorized";
614
+ throw new AuthenticationError(response.status, message, {
546
615
  body,
547
616
  requestId,
548
617
  traceId
@@ -563,9 +632,17 @@ var HttpTransport = class {
563
632
  }
564
633
  if (this.retry.shouldRetry(response.status) && attempt <= this.retry.maxRetries) {
565
634
  const delay = this.retry.computeDelay(attempt, parseRetryAfter(retryAfter));
566
- await sleep(delay);
635
+ await sleep(delay, retrySignal);
567
636
  continue;
568
637
  }
638
+ if (response.status === 400) {
639
+ const message = body && typeof body === "object" && "userMessage" in body ? String(body.userMessage) : "Bad request";
640
+ throw new BadRequestError(response.status, message, { body, requestId, traceId });
641
+ }
642
+ if (response.status === 404) {
643
+ const message = body && typeof body === "object" && "userMessage" in body ? String(body.userMessage) : "Not found";
644
+ throw new NotFoundError(response.status, message, { body, requestId, traceId });
645
+ }
569
646
  if (response.status >= 400) {
570
647
  const message = body && typeof body === "object" && "userMessage" in body ? String(body.userMessage) : `HTTP ${response.status}`;
571
648
  throw new APIStatusError(response.status, message, { body, requestId, traceId });
@@ -595,7 +672,7 @@ var HttpTransport = class {
595
672
  });
596
673
  }
597
674
  if (attempt <= this.retry.maxRetries) {
598
- await sleep(this.retry.computeDelay(attempt));
675
+ await sleep(this.retry.computeDelay(attempt), retrySignal);
599
676
  continue;
600
677
  }
601
678
  throw new APIConnectionError(
@@ -607,13 +684,293 @@ var HttpTransport = class {
607
684
  }
608
685
  async close() {
609
686
  this.closed = true;
687
+ this.closeController.abort(new APIConnectionError("Transport is closed"));
610
688
  Array.from(this.activeControllers).forEach((controller) => controller.abort());
611
689
  this.activeControllers.clear();
612
690
  }
613
691
  };
614
692
 
693
+ // src/feedback.ts
694
+ var FeedbackError = class extends Error {
695
+ constructor(code, message, statusCode) {
696
+ super(message);
697
+ this.code = code;
698
+ this.statusCode = statusCode;
699
+ this.name = new.target.name;
700
+ }
701
+ code;
702
+ statusCode;
703
+ };
704
+ var InvalidFeedbackInputError = class extends FeedbackError {
705
+ constructor(message = "Invalid feedback input.", code = "invalid_feedback_input") {
706
+ super(code, message);
707
+ }
708
+ };
709
+ var MissingInstrumentationError = class extends FeedbackError {
710
+ constructor() {
711
+ super("missing_citation_base", "Citation instrumentation is unavailable.");
712
+ }
713
+ };
714
+ var InvalidInstrumentationSuffixError = class extends FeedbackError {
715
+ constructor(code = "malformed_instrumentation_suffix") {
716
+ super(code, "Every cited result requires a valid instrumentation suffix.");
717
+ }
718
+ };
719
+ var FeedbackConnectionError = class extends FeedbackError {
720
+ constructor() {
721
+ super("feedback_connection", "Feedback request failed.");
722
+ }
723
+ };
724
+ var FeedbackTimeoutError = class extends FeedbackError {
725
+ constructor() {
726
+ super("feedback_timeout", "Feedback request timed out.");
727
+ }
728
+ };
729
+ var FeedbackCancelledError = class extends FeedbackError {
730
+ constructor() {
731
+ super("feedback_cancelled", "Feedback request was cancelled.");
732
+ }
733
+ };
734
+ var FeedbackHttpError = class extends FeedbackError {
735
+ constructor(statusCode) {
736
+ super("feedback_http", "Feedback endpoint returned an unsuccessful response.", statusCode);
737
+ }
738
+ };
739
+ var FeedbackNavigationError = class extends FeedbackError {
740
+ constructor() {
741
+ super("feedback_navigation", "Feedback navigation failed.");
742
+ }
743
+ };
744
+ function isPresent(value) {
745
+ return typeof value === "string" && value.trim().length > 0;
746
+ }
747
+ function buildClickPingUrl(response, result) {
748
+ if (isPresent(result.clickUrl) || !isPresent(response.instrumentationClickBase) || !isPresent(result.instrumentationSuffix)) {
749
+ return null;
750
+ }
751
+ return response.instrumentationClickBase + result.instrumentationSuffix;
752
+ }
753
+ function prepareClick(response, result) {
754
+ if (isPresent(result.clickUrl)) {
755
+ return { kind: "redirect", navigationUrl: result.clickUrl, pingUrl: null };
756
+ }
757
+ if (!isPresent(result.url)) {
758
+ throw new InvalidFeedbackInputError(
759
+ "A non-empty url or clickUrl is required to prepare a click.",
760
+ "missing_navigation_url"
761
+ );
762
+ }
763
+ const pingUrl = buildClickPingUrl(response, result);
764
+ return {
765
+ kind: pingUrl === null ? "untracked" : "ping",
766
+ navigationUrl: result.url,
767
+ pingUrl
768
+ };
769
+ }
770
+ function buildCitationPingUrl(response, results) {
771
+ const base = response.instrumentationCitationBase;
772
+ if (!isPresent(base)) {
773
+ throw new MissingInstrumentationError();
774
+ }
775
+ if (results.length === 0) {
776
+ throw new InvalidFeedbackInputError(
777
+ "At least one cited result is required.",
778
+ "empty_citation_results"
779
+ );
780
+ }
781
+ const payload = results.map((result) => {
782
+ const suffix = result.instrumentationSuffix;
783
+ if (!isPresent(suffix)) {
784
+ throw new InvalidInstrumentationSuffixError("missing_instrumentation_suffix");
785
+ }
786
+ const comma = suffix.indexOf(",");
787
+ const appNamespace = comma < 0 ? "" : suffix.slice(0, comma);
788
+ const key = comma < 0 ? "" : suffix.slice(comma + 1);
789
+ if (!isPresent(appNamespace) || !isPresent(key)) {
790
+ throw new InvalidInstrumentationSuffixError();
791
+ }
792
+ return { T: "CI.Info", FID: "LLM", Name: "citation", AppNS: appNamespace, K: key };
793
+ });
794
+ return base + encodeURIComponent(JSON.stringify(payload)).replace(
795
+ /[!'()*]/g,
796
+ (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`
797
+ );
798
+ }
799
+
800
+ // src/feedback-client.ts
801
+ var MAX_FEEDBACK_TIMEOUT = 2147483647;
802
+ var DefaultFeedbackSender = class {
803
+ async send(url, options) {
804
+ const init = {
805
+ method: "GET",
806
+ credentials: "omit",
807
+ redirect: "error",
808
+ referrerPolicy: "no-referrer",
809
+ cache: "no-store",
810
+ signal: options?.signal
811
+ };
812
+ const response = await globalThis.fetch(url, init);
813
+ await response.body?.cancel();
814
+ return { status: response.status };
815
+ }
816
+ };
817
+ function record(value) {
818
+ return typeof value === "object" && value !== null && !Array.isArray(value);
819
+ }
820
+ function validateFields(value, fields) {
821
+ if (!record(value) || fields.some((key) => value[key] != null && typeof value[key] !== "string")) {
822
+ throw new InvalidFeedbackInputError();
823
+ }
824
+ }
825
+ function validate(options) {
826
+ if (!record(options)) throw new InvalidFeedbackInputError();
827
+ validateFields(options.response, ["instrumentationClickBase", "instrumentationCitationBase"]);
828
+ if (!["citation", "click"].includes(options.type) || !Array.isArray(options.events) || options.events.length === 0 || options.type === "click" && options.events.length !== 1 || options.navigation !== void 0 && !["auto", "manual"].includes(options.navigation) || options.navigationPolicy !== void 0 && !["always", "on-feedback-success"].includes(options.navigationPolicy) || options.failureMode !== void 0 && !["collect", "throw"].includes(options.failureMode) || options.signal !== void 0 && (!record(options.signal) || typeof options.signal.aborted !== "boolean" || typeof options.signal.addEventListener !== "function" || typeof options.signal.removeEventListener !== "function") || options.timeout !== void 0 && (!Number.isFinite(options.timeout) || options.timeout <= 0 || options.timeout > MAX_FEEDBACK_TIMEOUT)) {
829
+ throw new InvalidFeedbackInputError();
830
+ }
831
+ for (const event of options.events) {
832
+ if (!record(event) || "type" in event) throw new InvalidFeedbackInputError();
833
+ if (options.type === "citation") {
834
+ if ("result" in event || !Array.isArray(event.results) || event.results.length === 0) {
835
+ throw new InvalidFeedbackInputError();
836
+ }
837
+ for (const result of event.results) {
838
+ validateFields(result, ["url", "clickUrl", "instrumentationSuffix"]);
839
+ }
840
+ } else {
841
+ if ("results" in event) throw new InvalidFeedbackInputError();
842
+ validateFields(event.result, ["url", "clickUrl", "instrumentationSuffix"]);
843
+ }
844
+ }
845
+ }
846
+ function validateHttpUrl(url) {
847
+ let parsed;
848
+ try {
849
+ parsed = new URL(url);
850
+ } catch {
851
+ throw new InvalidFeedbackInputError("Feedback requires an absolute HTTP(S) URL.");
852
+ }
853
+ if (!["https:", "http:"].includes(parsed.protocol) || parsed.username || parsed.password) {
854
+ throw new InvalidFeedbackInputError(
855
+ "Feedback requires an absolute HTTP(S) URL without credentials."
856
+ );
857
+ }
858
+ }
859
+ function browserNavigation() {
860
+ const runtime = globalThis;
861
+ const location = record(runtime) ? runtime.location : void 0;
862
+ if (record(location) && typeof location.assign === "function") {
863
+ const assign = location.assign.bind(location);
864
+ return {
865
+ navigate: (url) => {
866
+ assign(url);
867
+ }
868
+ };
869
+ }
870
+ return void 0;
871
+ }
872
+ var FeedbackClient = class {
873
+ sender;
874
+ navigator;
875
+ constructor(options = {}) {
876
+ this.sender = options.sender ?? new DefaultFeedbackSender();
877
+ this.navigator = options.navigationHandler ?? browserNavigation();
878
+ }
879
+ async pushEvents(options) {
880
+ validate(options);
881
+ let outcome;
882
+ let requestUrl;
883
+ if (options.type === "citation") {
884
+ const results = options.events.flatMap((event) => [...event.results]);
885
+ requestUrl = buildCitationPingUrl(options.response, results);
886
+ outcome = {
887
+ type: "citation",
888
+ feedbackStatus: "submitted",
889
+ navigationStatus: "not-applicable",
890
+ resultCount: results.length
891
+ };
892
+ } else {
893
+ const prepared = prepareClick(options.response, options.events[0].result);
894
+ validateHttpUrl(prepared.navigationUrl);
895
+ requestUrl = prepared.pingUrl ?? void 0;
896
+ outcome = {
897
+ type: "click",
898
+ clickMode: prepared.kind,
899
+ feedbackStatus: prepared.kind === "redirect" ? "pending-navigation" : prepared.kind === "ping" ? "submitted" : "not-instrumented",
900
+ navigationStatus: "required",
901
+ navigationUrl: prepared.navigationUrl
902
+ };
903
+ }
904
+ if (requestUrl !== void 0) validateHttpUrl(requestUrl);
905
+ if (options.signal?.aborted) throw new FeedbackCancelledError();
906
+ if (requestUrl !== void 0) {
907
+ try {
908
+ await this.send(requestUrl, options);
909
+ } catch (error) {
910
+ outcome.feedbackStatus = "failed";
911
+ outcome.feedbackError = error instanceof FeedbackError ? error : new FeedbackConnectionError();
912
+ }
913
+ }
914
+ if (outcome.type === "click") {
915
+ if (outcome.feedbackError && options.navigationPolicy === "on-feedback-success") {
916
+ outcome.navigationStatus = "blocked";
917
+ } else if (options.navigation !== "manual" && this.navigator) {
918
+ try {
919
+ await this.navigator.navigate(outcome.navigationUrl);
920
+ outcome.navigationStatus = "navigated";
921
+ if (outcome.clickMode === "redirect") outcome.feedbackStatus = "dispatched";
922
+ } catch {
923
+ outcome.navigationStatus = "failed";
924
+ outcome.navigationError = new FeedbackNavigationError();
925
+ }
926
+ }
927
+ }
928
+ if (options.failureMode === "throw") {
929
+ const error = outcome.feedbackError ?? (outcome.type === "click" ? outcome.navigationError : void 0);
930
+ if (error) throw error;
931
+ }
932
+ return {
933
+ outcomes: [outcome],
934
+ submittedEventCount: outcome.feedbackStatus === "submitted" ? outcome.type === "citation" ? outcome.resultCount : 1 : 0,
935
+ dispatchedEventCount: outcome.feedbackStatus === "dispatched" ? 1 : 0,
936
+ requestCount: requestUrl === void 0 ? 0 : 1,
937
+ navigated: outcome.navigationStatus === "navigated"
938
+ };
939
+ }
940
+ async send(url, options) {
941
+ const controller = new AbortController();
942
+ const timeout = options.timeout ?? 1e4;
943
+ let timer;
944
+ let onAbort;
945
+ const stopped = new Promise((_, reject) => {
946
+ onAbort = () => {
947
+ reject(new FeedbackCancelledError());
948
+ controller.abort();
949
+ };
950
+ options.signal?.addEventListener("abort", onAbort, { once: true });
951
+ timer = setTimeout(() => {
952
+ reject(new FeedbackTimeoutError());
953
+ controller.abort();
954
+ }, timeout);
955
+ });
956
+ try {
957
+ const response = await Promise.race([
958
+ this.sender.send(url, { signal: controller.signal, timeout }),
959
+ stopped
960
+ ]);
961
+ if (!Number.isInteger(response.status)) throw new FeedbackConnectionError();
962
+ if (response.status < 200 || response.status >= 300)
963
+ throw new FeedbackHttpError(response.status);
964
+ } finally {
965
+ clearTimeout(timer);
966
+ if (onAbort) options.signal?.removeEventListener("abort", onAbort);
967
+ }
968
+ }
969
+ };
970
+
615
971
  // src/client.ts
616
972
  var WebIQClient = class {
973
+ feedback;
617
974
  /** Web search resource */
618
975
  web;
619
976
  /** News search resource */
@@ -639,6 +996,7 @@ var WebIQClient = class {
639
996
  const retry = options.retry instanceof RetryPolicy ? options.retry : options.retry ? new RetryPolicy(options.retry) : new RetryPolicy();
640
997
  this._transport = new HttpTransport({
641
998
  baseUrl: options.baseUrl ?? "https://api.microsoft.ai/v3",
999
+ appId: options.appId,
642
1000
  auth: this._auth,
643
1001
  telemetryHook: options.telemetryHook,
644
1002
  retry,
@@ -650,6 +1008,7 @@ var WebIQClient = class {
650
1008
  this.videos = new VideosResource(this._transport);
651
1009
  this.images = new ImagesResource(this._transport);
652
1010
  this.browse = new BrowseResource(this._transport);
1011
+ this.feedback = new FeedbackClient(options.feedback);
653
1012
  }
654
1013
  /**
655
1014
  * Close the client and release resources.
@@ -719,6 +1078,15 @@ var LiveCrawlMode = /* @__PURE__ */ ((LiveCrawlMode2) => {
719
1078
  return LiveCrawlMode2;
720
1079
  })(LiveCrawlMode || {});
721
1080
 
1081
+ // src/generated-otc/models/RiskLevel.ts
1082
+ var RiskLevel = /* @__PURE__ */ ((RiskLevel2) => {
1083
+ RiskLevel2["LOW"] = "low";
1084
+ RiskLevel2["MODERATE"] = "moderate";
1085
+ RiskLevel2["HIGH"] = "high";
1086
+ RiskLevel2["VERY_HIGH"] = "veryHigh";
1087
+ return RiskLevel2;
1088
+ })(RiskLevel || {});
1089
+
722
1090
  // src/generated-otc/models/SafeSearch.ts
723
1091
  var SafeSearch = /* @__PURE__ */ ((SafeSearch2) => {
724
1092
  SafeSearch2["OFF"] = "off";
@@ -726,6 +1094,14 @@ var SafeSearch = /* @__PURE__ */ ((SafeSearch2) => {
726
1094
  return SafeSearch2;
727
1095
  })(SafeSearch || {});
728
1096
 
1097
+ // src/generated-otc/models/SourceQuality.ts
1098
+ var SourceQuality = /* @__PURE__ */ ((SourceQuality2) => {
1099
+ SourceQuality2["INSUFFICIENT"] = "insufficient";
1100
+ SourceQuality2["ADEQUATE"] = "adequate";
1101
+ SourceQuality2["PREFERRED"] = "preferred";
1102
+ return SourceQuality2;
1103
+ })(SourceQuality || {});
1104
+
729
1105
  // src/generated-otc/models/VideoDuration.ts
730
1106
  var VideoDuration = /* @__PURE__ */ ((VideoDuration2) => {
731
1107
  VideoDuration2["SHORT"] = "short";
@@ -747,31 +1123,49 @@ exports.APIConnectionError = APIConnectionError;
747
1123
  exports.APIStatusError = APIStatusError;
748
1124
  exports.ApiKeyAuth = ApiKeyAuth;
749
1125
  exports.AuthenticationError = AuthenticationError;
1126
+ exports.BadRequestError = BadRequestError;
750
1127
  exports.BrowseContentFormat = BrowseContentFormat;
751
1128
  exports.BrowseResource = BrowseResource;
752
1129
  exports.ContentFormat = ContentFormat;
753
1130
  exports.ContentTier = ContentTier;
754
1131
  exports.DEFAULT_SCOPE = DEFAULT_SCOPE;
755
1132
  exports.DEFAULT_TIMEOUT = DEFAULT_TIMEOUT;
1133
+ exports.DefaultFeedbackSender = DefaultFeedbackSender;
756
1134
  exports.EntraIDAuth = EntraIDAuth;
1135
+ exports.FeedbackCancelledError = FeedbackCancelledError;
1136
+ exports.FeedbackClient = FeedbackClient;
1137
+ exports.FeedbackConnectionError = FeedbackConnectionError;
1138
+ exports.FeedbackError = FeedbackError;
1139
+ exports.FeedbackHttpError = FeedbackHttpError;
1140
+ exports.FeedbackNavigationError = FeedbackNavigationError;
1141
+ exports.FeedbackTimeoutError = FeedbackTimeoutError;
757
1142
  exports.HttpTransport = HttpTransport;
758
1143
  exports.ImageAspectRatio = ImageAspectRatio;
759
1144
  exports.ImageColor = ImageColor;
760
1145
  exports.ImageSize = ImageSize;
761
1146
  exports.ImagesResource = ImagesResource;
1147
+ exports.InvalidFeedbackInputError = InvalidFeedbackInputError;
1148
+ exports.InvalidInstrumentationSuffixError = InvalidInstrumentationSuffixError;
762
1149
  exports.LiveCrawlMode = LiveCrawlMode;
1150
+ exports.MissingInstrumentationError = MissingInstrumentationError;
763
1151
  exports.NewsResource = NewsResource;
1152
+ exports.NotFoundError = NotFoundError;
764
1153
  exports.PermissionDeniedError = PermissionDeniedError;
765
1154
  exports.RateLimitError = RateLimitError;
766
1155
  exports.RetryPolicy = RetryPolicy;
1156
+ exports.RiskLevel = RiskLevel;
767
1157
  exports.SafeSearch = SafeSearch;
1158
+ exports.SourceQuality = SourceQuality;
768
1159
  exports.VideoDuration = VideoDuration;
769
1160
  exports.VideoResolution = VideoResolution;
770
1161
  exports.VideosResource = VideosResource;
771
1162
  exports.WebIQClient = WebIQClient;
772
1163
  exports.WebIQError = WebIQError;
773
1164
  exports.WebResource = WebResource;
1165
+ exports.buildCitationPingUrl = buildCitationPingUrl;
1166
+ exports.buildClickPingUrl = buildClickPingUrl;
774
1167
  exports.createAuth = createAuth;
775
1168
  exports.createClient = createClient;
776
1169
  exports.createTelemetryEvent = createTelemetryEvent;
1170
+ exports.prepareClick = prepareClick;
777
1171
  exports.safeCall = safeCall;