@sentry/api 0.446.0 → 1.0.1

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.
@@ -1,38 +1,39 @@
1
1
  // src/api-client/errors.ts
2
2
  import { SentryApiError } from "@sentry/api";
3
-
4
- class UserInputError extends Error {
3
+ var UserInputError = class extends Error {
5
4
  constructor(message, options) {
6
5
  super(message, options);
7
6
  this.name = "UserInputError";
8
7
  }
9
- }
10
-
11
- class ConfigurationError extends Error {
8
+ };
9
+ var ConfigurationError = class extends Error {
12
10
  constructor(message, options) {
13
11
  super(message, options);
14
12
  this.name = "ConfigurationError";
15
13
  }
16
- }
17
-
18
- class ApiError extends SentryApiError {
19
- detail;
20
- responseBody;
21
- constructor(message, status, detail, responseBody) {
22
- super(status, responseBody, undefined, false, message);
14
+ };
15
+ var ApiError = class _ApiError extends SentryApiError {
16
+ constructor(message, status, detail, responseBody2) {
17
+ super(status, responseBody2, void 0, false, message);
23
18
  this.detail = detail;
24
- this.responseBody = responseBody;
19
+ this.responseBody = responseBody2;
25
20
  this.name = "ApiError";
26
- Object.setPrototypeOf(this, ApiError.prototype);
21
+ Object.setPrototypeOf(this, _ApiError.prototype);
27
22
  }
28
- }
29
-
30
- class ApiClientError extends ApiError {
31
- constructor(message, status, detail, responseBody) {
32
- super(message, status, detail, responseBody);
23
+ detail;
24
+ responseBody;
25
+ };
26
+ var ApiClientError = class _ApiClientError extends ApiError {
27
+ constructor(message, status, detail, responseBody2) {
28
+ super(message, status, detail, responseBody2);
33
29
  this.name = "ApiClientError";
34
- Object.setPrototypeOf(this, ApiClientError.prototype);
30
+ Object.setPrototypeOf(this, _ApiClientError.prototype);
35
31
  }
32
+ /**
33
+ * Convert to a user-friendly formatted message.
34
+ * Returns the standard format: "API error (status): message" or just "API error: message" if no status.
35
+ * For 404 errors, adds helpful context about checking parameters.
36
+ */
36
37
  toUserMessage() {
37
38
  const baseMessage = this.status ? `API error (${this.status}): ${this.message}` : `API error: ${this.message}`;
38
39
  if (this.status === 404) {
@@ -42,7 +43,9 @@ class ApiClientError extends ApiError {
42
43
  "resource does not exist",
43
44
  "resource not found"
44
45
  ];
45
- const isGeneric = genericMessages.some((msg) => this.message.toLowerCase() === msg || this.message.toLowerCase().includes("requested resource"));
46
+ const isGeneric = genericMessages.some(
47
+ (msg) => this.message.toLowerCase() === msg || this.message.toLowerCase().includes("requested resource")
48
+ );
46
49
  if (isGeneric) {
47
50
  return `${baseMessage}. Please verify that the organization, project, or resource ID is correct and that you have access to it.`;
48
51
  }
@@ -50,134 +53,160 @@ class ApiClientError extends ApiError {
50
53
  }
51
54
  return baseMessage;
52
55
  }
56
+ /**
57
+ * Check if this is a permission/authorization error (403)
58
+ */
53
59
  isPermissionError() {
54
60
  return this.status === 403;
55
61
  }
62
+ /**
63
+ * Check if this is a not found error (404)
64
+ */
56
65
  isNotFoundError() {
57
66
  return this.status === 404;
58
67
  }
68
+ /**
69
+ * Check if this is a validation error (400 or 422)
70
+ */
59
71
  isValidationError() {
60
72
  return this.status === 400 || this.status === 422;
61
73
  }
74
+ /**
75
+ * Check if this is an authentication error (401)
76
+ */
62
77
  isAuthenticationError() {
63
78
  return this.status === 401;
64
79
  }
80
+ /**
81
+ * Check if this is a rate limit error (429)
82
+ */
65
83
  isRateLimitError() {
66
84
  return this.status === 429;
67
85
  }
68
- }
69
-
70
- class ApiPermissionError extends ApiClientError {
71
- constructor(message, detail, responseBody) {
72
- super(message, 403, detail, responseBody);
86
+ };
87
+ var ApiPermissionError = class _ApiPermissionError extends ApiClientError {
88
+ constructor(message, detail, responseBody2) {
89
+ super(message, 403, detail, responseBody2);
73
90
  this.name = "ApiPermissionError";
74
- Object.setPrototypeOf(this, ApiPermissionError.prototype);
91
+ Object.setPrototypeOf(this, _ApiPermissionError.prototype);
75
92
  }
93
+ /**
94
+ * Check if this is the specific multi-project access error
95
+ */
76
96
  isMultiProjectAccessError() {
77
- return this.message.includes("multiple projects") || this.message.includes("multi project") || this.message.includes("multi-project") || this.message.includes("You do not have access to query across multiple projects");
97
+ return this.message.includes("multiple projects") || this.message.includes("multi project") || this.message.includes("multi-project") || this.message.includes(
98
+ "You do not have access to query across multiple projects"
99
+ );
78
100
  }
79
- }
80
-
81
- class ApiNotFoundError extends ApiClientError {
82
- resourceType;
83
- resourceId;
84
- constructor(message, detail, responseBody, resourceType, resourceId) {
85
- super(message, 404, detail, responseBody);
101
+ };
102
+ var ApiNotFoundError = class _ApiNotFoundError extends ApiClientError {
103
+ constructor(message, detail, responseBody2, resourceType, resourceId) {
104
+ super(message, 404, detail, responseBody2);
86
105
  this.resourceType = resourceType;
87
106
  this.resourceId = resourceId;
88
107
  this.name = "ApiNotFoundError";
89
- Object.setPrototypeOf(this, ApiNotFoundError.prototype);
108
+ Object.setPrototypeOf(this, _ApiNotFoundError.prototype);
90
109
  }
91
- }
92
-
93
- class ApiValidationError extends ApiClientError {
94
- validationErrors;
95
- constructor(message, status, detail, responseBody, validationErrors) {
96
- super(message, status, detail, responseBody);
110
+ resourceType;
111
+ resourceId;
112
+ };
113
+ var ApiValidationError = class _ApiValidationError extends ApiClientError {
114
+ constructor(message, status, detail, responseBody2, validationErrors) {
115
+ super(message, status, detail, responseBody2);
97
116
  this.validationErrors = validationErrors;
98
117
  this.name = "ApiValidationError";
99
- Object.setPrototypeOf(this, ApiValidationError.prototype);
118
+ Object.setPrototypeOf(this, _ApiValidationError.prototype);
100
119
  }
101
- }
102
-
103
- class ApiAuthenticationError extends ApiClientError {
104
- constructor(message, detail, responseBody) {
105
- super(message, 401, detail, responseBody);
120
+ validationErrors;
121
+ };
122
+ var ApiAuthenticationError = class _ApiAuthenticationError extends ApiClientError {
123
+ constructor(message, detail, responseBody2) {
124
+ super(message, 401, detail, responseBody2);
106
125
  this.name = "ApiAuthenticationError";
107
- Object.setPrototypeOf(this, ApiAuthenticationError.prototype);
126
+ Object.setPrototypeOf(this, _ApiAuthenticationError.prototype);
108
127
  }
109
- }
110
-
111
- class ApiRateLimitError extends ApiClientError {
112
- retryAfterMs;
113
- constructor(message, detail, responseBody, retryAfterMs) {
114
- super(message, 429, detail, responseBody);
128
+ };
129
+ var ApiRateLimitError = class _ApiRateLimitError extends ApiClientError {
130
+ constructor(message, detail, responseBody2, retryAfterMs) {
131
+ super(message, 429, detail, responseBody2);
115
132
  this.retryAfterMs = retryAfterMs;
116
133
  this.name = "ApiRateLimitError";
117
- Object.setPrototypeOf(this, ApiRateLimitError.prototype);
134
+ Object.setPrototypeOf(this, _ApiRateLimitError.prototype);
118
135
  }
136
+ retryAfterMs;
119
137
  toUserMessage() {
120
- if (this.retryAfterMs === undefined) {
138
+ if (this.retryAfterMs === void 0) {
121
139
  return `${super.toUserMessage()}. Retry in a few seconds.`;
122
140
  }
123
- const seconds = Math.max(1, Math.ceil(this.retryAfterMs / 1000));
141
+ const seconds = Math.max(1, Math.ceil(this.retryAfterMs / 1e3));
124
142
  return `${super.toUserMessage()}. Retry in ${seconds} second${seconds === 1 ? "" : "s"}.`;
125
143
  }
126
- }
127
-
128
- class ApiServerError extends ApiError {
129
- constructor(message, status, detail, responseBody) {
130
- super(message, status, detail, responseBody);
144
+ };
145
+ var ApiServerError = class _ApiServerError extends ApiError {
146
+ constructor(message, status, detail, responseBody2) {
147
+ super(message, status, detail, responseBody2);
131
148
  this.name = "ApiServerError";
132
- Object.setPrototypeOf(this, ApiServerError.prototype);
149
+ Object.setPrototypeOf(this, _ApiServerError.prototype);
133
150
  }
151
+ /**
152
+ * Check if this is a gateway/proxy error (502, 503, 504)
153
+ */
134
154
  isGatewayError() {
135
155
  return this.status === 502 || this.status === 503 || this.status === 504;
136
156
  }
157
+ /**
158
+ * Check if this is an internal server error (500)
159
+ */
137
160
  isInternalError() {
138
161
  return this.status === 500;
139
162
  }
140
- }
141
- function createApiError(message, status, detail, responseBody, retryAfterMs) {
163
+ };
164
+ function createApiError(message, status, detail, responseBody2, retryAfterMs) {
142
165
  let improvedMessage = message;
143
- if (message.includes("You do not have the multi project stream feature enabled") || message.includes("You cannot view events from multiple projects")) {
166
+ if (message.includes(
167
+ "You do not have the multi project stream feature enabled"
168
+ ) || message.includes("You cannot view events from multiple projects")) {
144
169
  improvedMessage = "You do not have access to query across multiple projects. Please select a project for your query.";
145
- return new ApiPermissionError(improvedMessage, detail, responseBody);
170
+ return new ApiPermissionError(improvedMessage, detail, responseBody2);
146
171
  }
147
172
  switch (status) {
148
173
  case 401:
149
- return new ApiAuthenticationError(message, detail, responseBody);
174
+ return new ApiAuthenticationError(message, detail, responseBody2);
150
175
  case 403:
151
- return new ApiPermissionError(message, detail, responseBody);
176
+ return new ApiPermissionError(message, detail, responseBody2);
152
177
  case 404:
153
- return new ApiNotFoundError(message, detail, responseBody);
178
+ return new ApiNotFoundError(message, detail, responseBody2);
154
179
  case 400:
155
180
  case 422: {
156
181
  let validationErrors;
157
- if (responseBody && typeof responseBody === "object" && "errors" in responseBody) {
158
- validationErrors = responseBody.errors;
182
+ if (responseBody2 && typeof responseBody2 === "object" && "errors" in responseBody2) {
183
+ validationErrors = responseBody2.errors;
159
184
  }
160
- return new ApiValidationError(message, status, detail, responseBody, validationErrors);
185
+ return new ApiValidationError(
186
+ message,
187
+ status,
188
+ detail,
189
+ responseBody2,
190
+ validationErrors
191
+ );
161
192
  }
162
193
  case 429:
163
- return new ApiRateLimitError(message, detail, responseBody, retryAfterMs);
194
+ return new ApiRateLimitError(message, detail, responseBody2, retryAfterMs);
164
195
  default:
165
196
  if (status >= 400 && status < 500) {
166
- return new ApiClientError(message, status, detail, responseBody);
197
+ return new ApiClientError(message, status, detail, responseBody2);
167
198
  }
168
199
  if (status >= 500 && status < 600) {
169
- return new ApiServerError(message, status, detail, responseBody);
200
+ return new ApiServerError(message, status, detail, responseBody2);
170
201
  }
171
- return new ApiError(message, status, detail, responseBody);
202
+ return new ApiError(message, status, detail, responseBody2);
172
203
  }
173
204
  }
174
205
  function isApiAuthenticationErrorDeep(error) {
175
206
  let current = error;
176
- for (let i = 0;i < 3; i++) {
177
- if (current instanceof ApiAuthenticationError)
178
- return true;
179
- if (!(current instanceof Error))
180
- return false;
207
+ for (let i = 0; i < 3; i++) {
208
+ if (current instanceof ApiAuthenticationError) return true;
209
+ if (!(current instanceof Error)) return false;
181
210
  current = current.cause;
182
211
  }
183
212
  return false;
@@ -204,7 +233,9 @@ function apiPath(strings, ...values) {
204
233
  const value = String(values[index]);
205
234
  const encoded = encodeApiPathSegment(value);
206
235
  if (encoded === null) {
207
- throw new UserInputError(`Invalid identifier "${value}": relative path segments are not allowed.`);
236
+ throw new UserInputError(
237
+ `Invalid identifier "${value}": relative path segments are not allowed.`
238
+ );
208
239
  }
209
240
  return acc + literal + encoded;
210
241
  }, "");
@@ -213,6 +244,7 @@ function withQuery(path, query) {
213
244
  const queryString = query.toString();
214
245
  return queryString ? `${path}?${queryString}` : path;
215
246
  }
247
+
216
248
  // src/api-client/auth-token.ts
217
249
  var INVALID_TOKEN_CHARACTER_PATTERN = /[^\x21-\x7e]/;
218
250
  var TOKEN_PADDING_PATTERN = /[\s\x00-\x1f\x7f]/;
@@ -235,6 +267,7 @@ function sentryBearerHeader(token) {
235
267
  const normalized = normalizeAuthToken(token);
236
268
  return normalized === null ? null : `Bearer ${normalized}`;
237
269
  }
270
+
238
271
  // src/api-client/core.ts
239
272
  import {
240
273
  createSentryClient,
@@ -259,9 +292,10 @@ function encodePageCursor(cursor, skip) {
259
292
  const next = skip > 0 ? NEXT_CURSOR_RE.exec(server) : null;
260
293
  return next ? `${next[1]}:${encodeSkip(skip)}` : server;
261
294
  }
262
- function decodePageCursor(raw, warn = () => {}) {
295
+ function decodePageCursor(raw, warn = () => {
296
+ }) {
263
297
  if (!raw) {
264
- return { cursor: undefined, skip: 0 };
298
+ return { cursor: void 0, skip: 0 };
265
299
  }
266
300
  if (raw.startsWith(CLI_CURSOR_PREFIX)) {
267
301
  return decodeCliCursor(raw, warn);
@@ -269,72 +303,86 @@ function decodePageCursor(raw, warn = () => {}) {
269
303
  const next = NEXT_CURSOR_RE.exec(raw);
270
304
  const cursor = next ? `${next[1]}:0` : raw;
271
305
  const position = {
272
- cursor: cursor === FIRST_PAGE_CURSOR ? undefined : cursor,
306
+ cursor: cursor === FIRST_PAGE_CURSOR ? void 0 : cursor,
273
307
  skip: next?.[2] ? decodeSkip(next[2]) : 0
274
308
  };
275
309
  const perPage = serverCursorPageSize(cursor);
276
- return perPage === undefined ? position : { ...position, perPage };
310
+ return perPage === void 0 ? position : { ...position, perPage };
277
311
  }
278
312
  function decodeCliCursor(raw, warn) {
279
313
  const [perPage, skip, ...server] = raw.slice(CLI_CURSOR_PREFIX.length).split("~");
280
314
  const position = {
281
315
  perPage: Number(perPage),
282
316
  skip: Number(skip),
283
- cursor: server.join("~") || undefined
317
+ cursor: server.join("~") || void 0
284
318
  };
285
319
  if (Number.isInteger(position.perPage) && position.perPage >= 1 && position.perPage <= API_MAX_PER_PAGE && Number.isInteger(position.skip) && position.skip >= 0) {
286
320
  return position;
287
321
  }
288
- warn("Ignoring an unreadable pagination cursor; starting from the first page.");
289
- return { cursor: undefined, skip: 0 };
290
- }
291
- function consumeCursorPage(page, position, limit = Number.POSITIVE_INFINITY) {
292
- const consumed = consumePage({ data: page.data, nextCursor: page.nextCursor || undefined }, { cursor: position.cursor, offset: position.skip }, limit);
322
+ warn(
323
+ "Ignoring an unreadable pagination cursor; starting from the first page."
324
+ );
325
+ return { cursor: void 0, skip: 0 };
326
+ }
327
+ function consumeCursorPage(page, position, limit2 = Number.POSITIVE_INFINITY) {
328
+ const consumed = consumePage(
329
+ { data: page.data, nextCursor: page.nextCursor || void 0 },
330
+ { cursor: position.cursor, offset: position.skip },
331
+ limit2
332
+ );
293
333
  return {
294
334
  ...page,
295
335
  data: consumed.data,
296
- nextCursor: consumed.position ? encodePageCursor(consumed.position.cursor, consumed.position.offset) : undefined
336
+ nextCursor: consumed.position ? encodePageCursor(consumed.position.cursor, consumed.position.offset) : void 0
297
337
  };
298
338
  }
299
339
  function serverCursorPageSize(cursor) {
300
340
  const value = Number(PAGE_NUMBER_CURSOR_RE.exec(cursor)?.[1]);
301
- return Number.isInteger(value) && value >= 1 && value <= API_MAX_PER_PAGE ? value : undefined;
341
+ return Number.isInteger(value) && value >= 1 && value <= API_MAX_PER_PAGE ? value : void 0;
302
342
  }
303
- function pageSizeForLimit(limit) {
304
- if (limit <= API_MAX_PER_PAGE) {
305
- return Math.max(1, limit);
343
+ function pageSizeForLimit(limit2) {
344
+ if (limit2 <= API_MAX_PER_PAGE) {
345
+ return Math.max(1, limit2);
306
346
  }
307
- return Math.ceil(limit / Math.ceil(limit / API_MAX_PER_PAGE));
347
+ return Math.ceil(limit2 / Math.ceil(limit2 / API_MAX_PER_PAGE));
308
348
  }
309
349
  async function paginate(options, fetchPage) {
310
- const { limit, maxPages, warn = () => {} } = options;
350
+ const { limit: limit2, maxPages, warn = () => {
351
+ } } = options;
311
352
  const position = decodePageCursor(options.cursor, warn);
312
- const perPage = position.perPage ?? pageSizeForLimit(limit + position.skip);
313
- const result = await paginateUpTo(async (cursor) => {
314
- const page = await fetchPage(perPage, cursor);
315
- return { data: page.data, nextCursor: page.nextCursor || undefined };
316
- }, {
317
- limit,
318
- maxPages,
319
- resume: {
320
- cursor: position.cursor,
321
- offset: position.skip,
322
- requestBudget: limit + position.skip
323
- }
324
- }, "paginate");
353
+ const perPage = position.perPage ?? pageSizeForLimit(limit2 + position.skip);
354
+ const result = await paginateUpTo(
355
+ async (cursor) => {
356
+ const page = await fetchPage(perPage, cursor);
357
+ return { data: page.data, nextCursor: page.nextCursor || void 0 };
358
+ },
359
+ {
360
+ limit: limit2,
361
+ maxPages,
362
+ resume: {
363
+ cursor: position.cursor,
364
+ offset: position.skip,
365
+ requestBudget: limit2 + position.skip
366
+ }
367
+ },
368
+ "paginate"
369
+ );
325
370
  return {
326
371
  data: result.data,
327
372
  ...result.continuation ? {
328
- nextCursor: encodePageCursor(result.continuation.cursor, result.continuation.offset)
373
+ nextCursor: encodePageCursor(
374
+ result.continuation.cursor,
375
+ result.continuation.offset
376
+ )
329
377
  } : {},
330
378
  stoppedAtPageCap: result.stopReason === "maxPages"
331
379
  };
332
380
  }
333
381
  async function fetchAllPages(fetchPage, parse, maxPages) {
334
382
  const items = [];
335
- const seen = new Set;
383
+ const seen = /* @__PURE__ */ new Set();
336
384
  let cursor;
337
- for (let page = 0;page < maxPages; page += 1) {
385
+ for (let page = 0; page < maxPages; page += 1) {
338
386
  const { data, nextCursor } = await fetchPage(cursor);
339
387
  const rows = parse(data);
340
388
  if (!rows) {
@@ -354,25 +402,25 @@ async function fetchAllPages(fetchPage, parse, maxPages) {
354
402
  }
355
403
 
356
404
  // src/api-client/retry.ts
357
- var IDEMPOTENT_METHODS = new Set([
405
+ var IDEMPOTENT_METHODS = /* @__PURE__ */ new Set([
358
406
  "GET",
359
407
  "HEAD",
360
408
  "OPTIONS"
361
409
  ]);
362
- var RETRYABLE_STATUSES = new Map([
410
+ var RETRYABLE_STATUSES = /* @__PURE__ */ new Map([
363
411
  [429, "any"],
364
412
  [500, "idempotent"],
365
413
  [502, "idempotent"],
366
414
  [503, "idempotent"],
367
415
  [504, "idempotent"]
368
416
  ]);
369
- var DATE_RESOLUTION_MS = 1000;
417
+ var DATE_RESOLUTION_MS = 1e3;
370
418
  function isIdempotentRequest(method, idempotent = false) {
371
419
  return idempotent || IDEMPOTENT_METHODS.has(method.toUpperCase());
372
420
  }
373
421
  function isRetryable(method, status, idempotent = false) {
374
- const replays = status === undefined ? "idempotent" : RETRYABLE_STATUSES.get(status);
375
- if (replays === undefined) {
422
+ const replays = status === void 0 ? "idempotent" : RETRYABLE_STATUSES.get(status);
423
+ if (replays === void 0) {
376
424
  return false;
377
425
  }
378
426
  return replays === "any" || isIdempotentRequest(method, idempotent);
@@ -381,19 +429,19 @@ function parseRetryDelayMs(status, headers, now = Date.now()) {
381
429
  const retryAfter = headers.get("retry-after")?.trim();
382
430
  if (retryAfter) {
383
431
  if (/^\d+$/.test(retryAfter)) {
384
- return Number(retryAfter) * 1000;
432
+ return Number(retryAfter) * 1e3;
385
433
  }
386
434
  const date = Date.parse(retryAfter);
387
- return Number.isNaN(date) ? undefined : delayUntil(date, headers, now);
435
+ return Number.isNaN(date) ? void 0 : delayUntil(date, headers, now);
388
436
  }
389
437
  if (status !== 429 || !isWindowLimited(headers)) {
390
- return;
438
+ return void 0;
391
439
  }
392
440
  const reset = Number(headers.get("x-sentry-rate-limit-reset"));
393
441
  if (!Number.isFinite(reset) || reset <= 0) {
394
- return;
442
+ return void 0;
395
443
  }
396
- return delayUntil(reset * 1000, headers, now);
444
+ return delayUntil(reset * 1e3, headers, now);
397
445
  }
398
446
  function nextRetryDelayMs({
399
447
  policy,
@@ -406,19 +454,19 @@ function nextRetryDelayMs({
406
454
  random = Math.random
407
455
  }) {
408
456
  if (attempt >= policy.maxRetries || !isRetryable(method, status, idempotent)) {
409
- return;
457
+ return void 0;
410
458
  }
411
459
  let delayMs;
412
- if (serverDelayMs !== undefined) {
460
+ if (serverDelayMs !== void 0) {
413
461
  if (serverDelayMs > policy.maxDelayMs) {
414
- return;
462
+ return void 0;
415
463
  }
416
464
  delayMs = serverDelayMs + random() * (policy.baseDelayMs / 2);
417
465
  } else {
418
466
  const step = Math.min(policy.baseDelayMs * 2 ** attempt, policy.maxDelayMs);
419
467
  delayMs = step / 2 + random() * (step / 2);
420
468
  }
421
- return waitedMs + delayMs > policy.maxTotalDelayMs ? undefined : delayMs;
469
+ return waitedMs + delayMs > policy.maxTotalDelayMs ? void 0 : delayMs;
422
470
  }
423
471
  function sleep(ms, signal) {
424
472
  return new Promise((resolve, reject) => {
@@ -453,9 +501,9 @@ function isWindowLimited(headers) {
453
501
  // src/api-client/response.ts
454
502
  function readDetail(json) {
455
503
  if (json === null || typeof json !== "object" || !("detail" in json)) {
456
- return;
504
+ return void 0;
457
505
  }
458
- return typeof json.detail === "string" ? json.detail : undefined;
506
+ return typeof json.detail === "string" ? json.detail : void 0;
459
507
  }
460
508
  function looksLikeHtml(text) {
461
509
  return text.includes("<!DOCTYPE") || text.includes("<html");
@@ -466,7 +514,7 @@ async function readErrorResponse(response) {
466
514
  try {
467
515
  text = await response.text();
468
516
  } catch {
469
- return { text: undefined, isHtml: false, retryAfterMs };
517
+ return { text: void 0, isHtml: false, retryAfterMs };
470
518
  }
471
519
  try {
472
520
  const json = JSON.parse(text);
@@ -494,24 +542,31 @@ async function readJsonResponse(response) {
494
542
  if (!contentType?.includes("application/json")) {
495
543
  const text = await response.text();
496
544
  if (contentType?.includes("text/html") || looksLikeHtml(text)) {
497
- throw new Error(`Expected JSON response but received HTML (${response.status} ${response.statusText}). This may indicate you're not authenticated, the URL is incorrect, or there's a server issue.`);
545
+ throw new Error(
546
+ `Expected JSON response but received HTML (${response.status} ${response.statusText}). This may indicate you're not authenticated, the URL is incorrect, or there's a server issue.`
547
+ );
498
548
  }
499
- throw new Error(`Expected JSON response but received ${contentType || "unknown content type"} ` + `(${response.status} ${response.statusText})`);
549
+ throw new Error(
550
+ `Expected JSON response but received ${contentType || "unknown content type"} (${response.status} ${response.statusText})`
551
+ );
500
552
  }
501
553
  try {
502
554
  return await response.json();
503
555
  } catch (error) {
504
- throw new Error(`Failed to parse JSON response: ${error instanceof Error ? error.message : String(error)}`);
556
+ throw new Error(
557
+ `Failed to parse JSON response: ${error instanceof Error ? error.message : String(error)}`
558
+ );
505
559
  }
506
560
  }
507
561
 
508
562
  // src/api-client/validate.ts
509
563
  var MAX_LISTED_ISSUES = 3;
510
564
  function issuePath(issue) {
511
- return (issue.path ?? []).map((segment) => String(typeof segment === "object" ? segment.key : segment)).join(".");
565
+ return (issue.path ?? []).map(
566
+ (segment) => String(typeof segment === "object" ? segment.key : segment)
567
+ ).join(".");
512
568
  }
513
-
514
- class ApiResponseValidationError extends Error {
569
+ var ApiResponseValidationError = class extends Error {
515
570
  issues;
516
571
  constructor(issues) {
517
572
  const listed = issues.slice(0, MAX_LISTED_ISSUES).map((issue) => {
@@ -523,7 +578,7 @@ class ApiResponseValidationError extends Error {
523
578
  this.name = "ApiResponseValidationError";
524
579
  this.issues = issues;
525
580
  }
526
- }
581
+ };
527
582
  function validateResponse(schema, data) {
528
583
  const result = schema["~standard"].validate(data);
529
584
  if (result instanceof Promise) {
@@ -548,7 +603,7 @@ var NETWORK_ERROR_MESSAGES = {
548
603
  ECONNRESET: "Connection reset. Try again in a moment."
549
604
  };
550
605
  var API_PREFIX = "/api/0";
551
- var CONFIGURATION_ERROR_CODES = new Set([
606
+ var CONFIGURATION_ERROR_CODES = /* @__PURE__ */ new Set([
552
607
  "ENOTFOUND",
553
608
  "EAI_AGAIN",
554
609
  "ECONNREFUSED",
@@ -560,7 +615,9 @@ function networkError(url, error) {
560
615
  rootCause = rootCause.cause;
561
616
  }
562
617
  const errorMessage = rootCause instanceof Error ? rootCause.message : String(rootCause);
563
- const errorCode = Object.keys(NETWORK_ERROR_MESSAGES).find((code) => errorMessage.includes(code));
618
+ const errorCode = Object.keys(NETWORK_ERROR_MESSAGES).find(
619
+ (code) => errorMessage.includes(code)
620
+ );
564
621
  const friendlyMessage = `Unable to connect to ${url} - ${errorCode ? NETWORK_ERROR_MESSAGES[errorCode] : errorMessage}`;
565
622
  if (errorCode && CONFIGURATION_ERROR_CODES.has(errorCode) || errorMessage.includes("Connect Timeout Error")) {
566
623
  return new ConfigurationError(friendlyMessage, { cause: error });
@@ -570,14 +627,20 @@ function networkError(url, error) {
570
627
  function errorFromResponse(logger, response, body, logExtra) {
571
628
  const { retryAfterMs } = body;
572
629
  const errorText = body.text ?? "";
573
- const bodyPreview = errorText.length > 256 ? `${errorText.slice(0, 253)}…` : errorText;
574
- if (body.parseError !== undefined) {
630
+ const bodyPreview = errorText.length > 256 ? `${errorText.slice(0, 253)}\u2026` : errorText;
631
+ if (body.parseError !== void 0) {
575
632
  if (body.isHtml) {
576
633
  logger.warn("Received HTML error page instead of JSON", {
577
634
  ...logExtra,
578
635
  parseErrorMessage: body.parseError
579
636
  });
580
- return createApiError(`Server error: Received HTML instead of JSON (${response.status} ${response.statusText}). This may indicate an invalid URL or server issue.`, response.status, errorText, undefined, retryAfterMs);
637
+ return createApiError(
638
+ `Server error: Received HTML instead of JSON (${response.status} ${response.statusText}). This may indicate an invalid URL or server issue.`,
639
+ response.status,
640
+ errorText,
641
+ void 0,
642
+ retryAfterMs
643
+ );
581
644
  }
582
645
  logger.warn("Failed to parse JSON error response", {
583
646
  ...logExtra,
@@ -585,8 +648,14 @@ function errorFromResponse(logger, response, body, logExtra) {
585
648
  parseErrorMessage: body.parseError
586
649
  });
587
650
  } else if (body.json) {
588
- if (body.detail !== undefined) {
589
- return createApiError(body.detail, response.status, body.detail, body.json, retryAfterMs);
651
+ if (body.detail !== void 0) {
652
+ return createApiError(
653
+ body.detail,
654
+ response.status,
655
+ body.detail,
656
+ body.json,
657
+ retryAfterMs
658
+ );
590
659
  }
591
660
  logger.warn("Failed to parse validated API error response", {
592
661
  ...logExtra,
@@ -594,8 +663,14 @@ function errorFromResponse(logger, response, body, logExtra) {
594
663
  validationErrorMessage: "Error response has no string detail"
595
664
  });
596
665
  }
597
- return createApiError(`API request failed: ${response.statusText}
598
- ${errorText}`, response.status, errorText, undefined, retryAfterMs);
666
+ return createApiError(
667
+ `API request failed: ${response.statusText}
668
+ ${errorText}`,
669
+ response.status,
670
+ errorText,
671
+ void 0,
672
+ retryAfterMs
673
+ );
599
674
  }
600
675
  function createApiClientCore({
601
676
  transport,
@@ -609,7 +684,9 @@ function createApiClientCore({
609
684
  ...headers()
610
685
  };
611
686
  if (typeof globalThis.fetch === "undefined") {
612
- throw new ConfigurationError("fetch is not available. Please use Node.js >= 18 or ensure fetch is available in your environment.");
687
+ throw new ConfigurationError(
688
+ "fetch is not available. Please use Node.js >= 18 or ensure fetch is available in your environment."
689
+ );
613
690
  }
614
691
  let response;
615
692
  try {
@@ -626,12 +703,17 @@ function createApiClientCore({
626
703
  if (response.ok || allowStatuses?.includes(response.status)) {
627
704
  return response;
628
705
  }
629
- throw errorFromResponse(logger, response, await readErrorResponse(response), {
630
- status: response.status,
631
- statusText: response.statusText,
632
- host: new URL(origin).host,
633
- path
634
- });
706
+ throw errorFromResponse(
707
+ logger,
708
+ response,
709
+ await readErrorResponse(response),
710
+ {
711
+ status: response.status,
712
+ statusText: response.statusText,
713
+ host: new URL(origin).host,
714
+ path
715
+ }
716
+ );
635
717
  }
636
718
  return {
637
719
  request,
@@ -646,9 +728,15 @@ function createApiClientCore({
646
728
  }
647
729
  const url = new URL(sdkRequest.url);
648
730
  if (url.origin !== base || url.pathname !== API_PREFIX.concat(expectedPath) || sdkRequest.method !== "GET") {
649
- throw new ConfigurationError("Unexpected SDK request target or method");
731
+ throw new ConfigurationError(
732
+ "Unexpected SDK request target or method"
733
+ );
650
734
  }
651
- const response = await request(origin, `${url.pathname.slice(API_PREFIX.length)}${url.search}`, { method: "GET", signal: sdkRequest.signal });
735
+ const response = await request(
736
+ origin,
737
+ `${url.pathname.slice(API_PREFIX.length)}${url.search}`,
738
+ { method: "GET", signal: sdkRequest.signal }
739
+ );
652
740
  const contentType = response.headers.get("content-type");
653
741
  if (!contentType?.includes("application/json")) {
654
742
  await readJsonResponse(response);
@@ -659,15 +747,17 @@ function createApiClientCore({
659
747
  }
660
748
  };
661
749
  }
662
- async function listPage(fetchPage, schema, limit, initialCursor) {
663
- if (!Number.isSafeInteger(limit) || limit < 1 || limit > API_MAX_PER_PAGE * MAX_LIST_PAGES) {
664
- throw new ApiValidationError(`limit must be an integer between 1 and ${API_MAX_PER_PAGE * MAX_LIST_PAGES}`);
750
+ async function listPage(fetchPage, schema, limit2, initialCursor) {
751
+ if (!Number.isSafeInteger(limit2) || limit2 < 1 || limit2 > API_MAX_PER_PAGE * MAX_LIST_PAGES) {
752
+ throw new ApiValidationError(
753
+ `limit must be an integer between 1 and ${API_MAX_PER_PAGE * MAX_LIST_PAGES}`
754
+ );
665
755
  }
666
756
  const items = [];
667
- const seenCursors = new Set;
668
- let cursor = initialCursor ?? undefined;
669
- for (let page = 0;page < MAX_LIST_PAGES; page += 1) {
670
- const perPage = Math.min(API_MAX_PER_PAGE, limit - items.length);
757
+ const seenCursors = /* @__PURE__ */ new Set();
758
+ let cursor = initialCursor ?? void 0;
759
+ for (let page = 0; page < MAX_LIST_PAGES; page += 1) {
760
+ const perPage = Math.min(API_MAX_PER_PAGE, limit2 - items.length);
671
761
  const { data, response } = await fetchPage(perPage, cursor);
672
762
  const rows = validateResponse(schema, data);
673
763
  if (rows.length > perPage) {
@@ -675,7 +765,7 @@ async function listPage(fetchPage, schema, limit, initialCursor) {
675
765
  }
676
766
  items.push(...rows);
677
767
  const nextCursor = nextPageCursor(response);
678
- if (items.length >= limit || !nextCursor) {
768
+ if (items.length >= limit2 || !nextCursor) {
679
769
  return { items, nextCursor };
680
770
  }
681
771
  if (seenCursors.has(nextCursor) || nextCursor === cursor) {
@@ -686,14 +776,19 @@ async function listPage(fetchPage, schema, limit, initialCursor) {
686
776
  }
687
777
  throw new Error("API pagination exceeded its page limit");
688
778
  }
779
+
689
780
  // src/api-client/idempotent-operations.ts
690
781
  function selectIdempotentWrites(operations) {
691
- return operations.filter((op) => op.idempotent && !isIdempotentRequest(op.method)).map((op) => ({ method: op.method, path: op.path })).sort((a, b) => a.path.localeCompare(b.path) || a.method.localeCompare(b.method));
782
+ return operations.filter((op) => op.idempotent && !isIdempotentRequest(op.method)).map((op) => ({ method: op.method, path: op.path })).sort(
783
+ (a, b) => a.path.localeCompare(b.path) || a.method.localeCompare(b.method)
784
+ );
692
785
  }
693
786
  var TEMPLATE_SEGMENT = /^\{[^/]+\}$/;
694
787
  var REGEXP_SPECIAL = /[.*+?^${}()|[\]\\]/g;
695
788
  function toMatcher({ method, path }) {
696
- const source = path.split("/").map((segment) => TEMPLATE_SEGMENT.test(segment) ? "[^/]+" : segment.replace(REGEXP_SPECIAL, "\\$&")).join("/");
789
+ const source = path.split("/").map(
790
+ (segment) => TEMPLATE_SEGMENT.test(segment) ? "[^/]+" : segment.replace(REGEXP_SPECIAL, "\\$&")
791
+ ).join("/");
697
792
  return { method: method.toUpperCase(), pattern: new RegExp(`^${source}$`) };
698
793
  }
699
794
  function createIdempotentOperationMatcher(operations) {
@@ -711,25 +806,39 @@ function createIdempotentOperationMatcher(operations) {
711
806
  const normalized = apiPath2.endsWith("/") ? apiPath2 : `${apiPath2}/`;
712
807
  const upper = method.toUpperCase();
713
808
  matchers ??= operations().map(toMatcher);
714
- return matchers.some((matcher) => matcher.method === upper && matcher.pattern.test(normalized));
809
+ return matchers.some(
810
+ (matcher) => matcher.method === upper && matcher.pattern.test(normalized)
811
+ );
715
812
  };
716
813
  }
814
+
717
815
  // src/api-client/response-cache/invalidation.ts
718
816
  var API_V0_SEGMENT = "/api/0/";
719
817
  var TRAILING_SLASH_RE = /\/$/;
720
818
  var SKIP_INVALIDATION_PATTERNS = [
819
+ // Sourcemap chunk upload + bundle assemble. Both are write-only in the
820
+ // sense that no GET endpoint reads cacheable state under these paths.
721
821
  /\/chunk-upload\//,
722
822
  /\/artifactbundle\/assemble\//
723
823
  ];
724
824
  var CROSS_ENDPOINT_RULES = [
825
+ // `POST teams/{org}/{team}/projects/` (create project in team) also
826
+ // invalidates the org project list at `organizations/{org}/projects/`.
725
827
  {
726
828
  match: /^teams\/([^/]+)\/[^/]+\/projects\/?$/,
727
829
  extra: ([, org]) => [`organizations/${org}/projects/`]
728
830
  },
831
+ // `DELETE projects/{org}/{project}/` also invalidates the org project list.
729
832
  {
730
833
  match: /^projects\/([^/]+)\/[^/]+\/?$/,
731
834
  extra: ([, org]) => [`organizations/${org}/projects/`]
732
835
  },
836
+ // Org-scoped issue mutations at `organizations/{org}/issues/{id}/`
837
+ // also affect the legacy global endpoint at `issues/{id}/`, which
838
+ // `getIssue()` hits under the control-silo base URL (potentially a
839
+ // DIFFERENT origin than the org's region URL). Must clear the
840
+ // legacy cache too, or subsequent `getIssue()` calls serve stale
841
+ // data.
733
842
  {
734
843
  match: /^organizations\/[^/]+\/issues\/([^/]+)\/?$/,
735
844
  extraAbsolute: ([, issueId], { apiBaseUrl }) => [
@@ -756,7 +865,7 @@ function computeInvalidationPrefixes(fullUrl, apiBaseUrl) {
756
865
  if (relPath === "") {
757
866
  return [];
758
867
  }
759
- const prefixes = new Set;
868
+ const prefixes = /* @__PURE__ */ new Set();
760
869
  for (const segments of ancestorSegments(relPath)) {
761
870
  prefixes.add(`${base}${segments}`);
762
871
  }
@@ -786,23 +895,26 @@ function* ancestorSegments(relPath) {
786
895
  }
787
896
  const parts = trimmed.split("/");
788
897
  const floor = parts.length > 2 ? 2 : 1;
789
- for (let i = parts.length;i >= floor; i--) {
898
+ for (let i = parts.length; i >= floor; i--) {
790
899
  yield `${parts.slice(0, i).join("/")}/`;
791
900
  }
792
901
  }
902
+
793
903
  // src/api-client/response-cache/keys.ts
794
- var encoder = new TextEncoder;
904
+ var encoder = new TextEncoder();
795
905
  function normalizeUrl(method, url) {
796
906
  const parsed = new URL(url);
797
- const sortedParams = new URLSearchParams([...parsed.searchParams.entries()].sort(([a], [b]) => {
798
- if (a < b) {
799
- return -1;
800
- }
801
- if (a > b) {
802
- return 1;
803
- }
804
- return 0;
805
- }));
907
+ const sortedParams = new URLSearchParams(
908
+ [...parsed.searchParams.entries()].sort(([a], [b]) => {
909
+ if (a < b) {
910
+ return -1;
911
+ }
912
+ if (a > b) {
913
+ return 1;
914
+ }
915
+ return 0;
916
+ })
917
+ );
806
918
  parsed.search = sortedParams.toString() ? `?${sortedParams.toString()}` : "";
807
919
  return `${method.toUpperCase()}|${parsed.toString()}`;
808
920
  }
@@ -811,15 +923,29 @@ async function buildCacheKey(method, url, identity) {
811
923
  throw new TypeError("A cache key needs a non-empty identity");
812
924
  }
813
925
  const normalized = normalizeUrl(method, url);
814
- const key = await crypto.subtle.importKey("raw", encoder.encode(identity), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
815
- const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(normalized));
816
- return Array.from(new Uint8Array(signature), (byte) => byte.toString(16).padStart(2, "0")).join("");
926
+ const key = await crypto.subtle.importKey(
927
+ "raw",
928
+ encoder.encode(identity),
929
+ { name: "HMAC", hash: "SHA-256" },
930
+ false,
931
+ ["sign"]
932
+ );
933
+ const signature = await crypto.subtle.sign(
934
+ "HMAC",
935
+ key,
936
+ encoder.encode(normalized)
937
+ );
938
+ return Array.from(
939
+ new Uint8Array(signature),
940
+ (byte) => byte.toString(16).padStart(2, "0")
941
+ ).join("");
817
942
  }
943
+
818
944
  // src/api-client/response-cache/memory-store.ts
819
945
  var MIB = 1024 * 1024;
820
946
  var ENTRY_OVERHEAD_BYTES = 1024;
821
947
  function limit(name, value, fallback) {
822
- if (value === undefined) {
948
+ if (value === void 0) {
823
949
  return fallback;
824
950
  }
825
951
  if (!(Number.isFinite(value) && value > 0)) {
@@ -834,7 +960,7 @@ function createMemoryStore(options = {}) {
834
960
  const maxBytes = limit("maxBytes", options.maxBytes, 24 * MIB);
835
961
  const maxEntryBytes = limit("maxEntryBytes", options.maxEntryBytes, MIB);
836
962
  const maxRawBytes = limit("maxRawBytes", options.maxRawBytes, 32 * MIB);
837
- const slots = new Map;
963
+ const slots = /* @__PURE__ */ new Map();
838
964
  let bytes = 0;
839
965
  function remove(key) {
840
966
  const slot = slots.get(key);
@@ -890,24 +1016,32 @@ function createMemoryStore(options = {}) {
890
1016
  }
891
1017
  };
892
1018
  }
1019
+
893
1020
  // src/api-client/response-cache/policy.ts
894
1021
  import CachePolicy from "http-cache-semantics";
895
1022
 
896
1023
  // src/api-client/response-cache/tiers.ts
897
1024
  var FALLBACK_TTL_MS = {
898
- stable: 5 * 60 * 1000,
899
- volatile: 60 * 1000,
1025
+ stable: 5 * 60 * 1e3,
1026
+ volatile: 60 * 1e3,
900
1027
  "no-cache": 0
901
1028
  };
902
1029
  var URL_TIER_PATTERNS = [
1030
+ // Polling endpoints where state changes rapidly
903
1031
  ["no-cache", [/\/(?:autofix|root-cause)\//]],
904
1032
  [
905
1033
  "volatile",
906
1034
  [
1035
+ // Issue endpoints: lists, detail views, and issue events such as
1036
+ // `/issues/{id}/events/latest/`
907
1037
  /\/issues\//,
908
1038
  /[?&]dataset=(?:logs|spans)/,
909
1039
  /\/trace-logs\//,
1040
+ // Full traces gain spans as they arrive
910
1041
  /\/trace\/[0-9a-f]{32}\//,
1042
+ // Project event details embed user reports (and `nextEventID`/
1043
+ // `previousEventID` unless collapsed), and reprocessing can change them
1044
+ // for the same ID
911
1045
  /\/projects\/[^/]+\/[^/]+\/events\/[^/?]+\/?(?:\?|$)/
912
1046
  ]
913
1047
  ]
@@ -922,13 +1056,13 @@ function classifyUrl(url) {
922
1056
  }
923
1057
 
924
1058
  // src/api-client/response-cache/policy.ts
925
- var REVALIDATION_WINDOW_MS = 24 * 60 * 60 * 1000;
1059
+ var REVALIDATION_WINDOW_MS = 24 * 60 * 60 * 1e3;
926
1060
  var POLICY_OPTIONS = {
927
1061
  shared: false,
928
1062
  cacheHeuristic: 0.1
929
1063
  };
930
1064
  var PRESERVED_HEADERS = ["link"];
931
- var encoder2 = new TextEncoder;
1065
+ var encoder2 = new TextEncoder();
932
1066
  function pickHeaders(headers) {
933
1067
  const result = {};
934
1068
  for (const name of PRESERVED_HEADERS) {
@@ -948,7 +1082,10 @@ async function policyRequestHeaders(headers) {
948
1082
  }
949
1083
  async function sha256Hex(value) {
950
1084
  const digest = await crypto.subtle.digest("SHA-256", encoder2.encode(value));
951
- return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
1085
+ return Array.from(
1086
+ new Uint8Array(digest),
1087
+ (byte) => byte.toString(16).padStart(2, "0")
1088
+ ).join("");
952
1089
  }
953
1090
  function headersToObject(headers) {
954
1091
  return Object.fromEntries(headers.entries());
@@ -968,12 +1105,12 @@ function isEntryFresh(policy, entry, request) {
968
1105
  }
969
1106
  function retentionMs(policy, tier) {
970
1107
  const freshMs = hasServerCacheDirectives(policy) ? policy.timeToLive() : FALLBACK_TTL_MS[tier];
971
- return policy.responseHeaders().etag === undefined ? freshMs : freshMs + REVALIDATION_WINDOW_MS;
1108
+ return policy.responseHeaders().etag === void 0 ? freshMs : freshMs + REVALIDATION_WINDOW_MS;
972
1109
  }
973
1110
  function buildResponseHeaders(policy, entry) {
974
1111
  const result = {};
975
1112
  for (const [name, value] of Object.entries(policy.responseHeaders())) {
976
- if (value !== undefined) {
1113
+ if (value !== void 0) {
977
1114
  result[name] = Array.isArray(value) ? value.join(", ") : value;
978
1115
  }
979
1116
  }
@@ -1030,7 +1167,9 @@ async function lookupResponse(options) {
1030
1167
  if (!entry) {
1031
1168
  return;
1032
1169
  }
1033
- const policy = CachePolicy.fromObject(entry.policy);
1170
+ const policy = CachePolicy.fromObject(
1171
+ entry.policy
1172
+ );
1034
1173
  const request = {
1035
1174
  url,
1036
1175
  method: "GET",
@@ -1059,11 +1198,15 @@ async function storeResponse(options) {
1059
1198
  if (!response.ok || tier === "no-cache") {
1060
1199
  return 0;
1061
1200
  }
1062
- const policy = new CachePolicy({
1063
- url,
1064
- method: "GET",
1065
- headers: await policyRequestHeaders(requestHeaders)
1066
- }, { status: response.status, headers: headersToObject(response.headers) }, POLICY_OPTIONS);
1201
+ const policy = new CachePolicy(
1202
+ {
1203
+ url,
1204
+ method: "GET",
1205
+ headers: await policyRequestHeaders(requestHeaders)
1206
+ },
1207
+ { status: response.status, headers: headersToObject(response.headers) },
1208
+ POLICY_OPTIONS
1209
+ );
1067
1210
  if (!policy.storable()) {
1068
1211
  return 0;
1069
1212
  }
@@ -1071,22 +1214,27 @@ async function storeResponse(options) {
1071
1214
  JSON.parse(text);
1072
1215
  const createdAt = Date.now();
1073
1216
  const body = await codec.encode(encoder2.encode(text));
1074
- await store.set(key, {
1075
- url,
1076
- identity,
1077
- tier,
1078
- status: response.status,
1079
- headers: pickHeaders(response.headers),
1080
- body,
1081
- policy: policy.toObject(),
1082
- createdAt
1083
- }, retentionMs(policy, tier));
1217
+ await store.set(
1218
+ key,
1219
+ {
1220
+ url,
1221
+ identity,
1222
+ tier,
1223
+ status: response.status,
1224
+ headers: pickHeaders(response.headers),
1225
+ body,
1226
+ policy: policy.toObject(),
1227
+ createdAt
1228
+ },
1229
+ retentionMs(policy, tier)
1230
+ );
1084
1231
  return body.bytes.byteLength;
1085
1232
  }
1233
+
1086
1234
  // src/api-client/time-params.ts
1087
1235
  function normalizeStatsPeriod(statsPeriod) {
1088
1236
  const normalized = statsPeriod?.trim();
1089
- return normalized || undefined;
1237
+ return normalized || void 0;
1090
1238
  }
1091
1239
  function defaultStatsPeriod({
1092
1240
  statsPeriod,
@@ -1099,7 +1247,9 @@ function defaultStatsPeriod({
1099
1247
  function parseStatsPeriod(statsPeriod) {
1100
1248
  const match = /^(\d+)([smhdw])$/.exec(statsPeriod);
1101
1249
  if (!match?.[2]) {
1102
- throw new ApiValidationError("statsPeriod must use a supported relative time format, such as `24h`, `7d`, or `2w`.");
1250
+ throw new ApiValidationError(
1251
+ "statsPeriod must use a supported relative time format, such as `24h`, `7d`, or `2w`."
1252
+ );
1103
1253
  }
1104
1254
  return {
1105
1255
  amount: Number(match[1]),
@@ -1108,10 +1258,14 @@ function parseStatsPeriod(statsPeriod) {
1108
1258
  }
1109
1259
  function applyTimeParams(queryParams, statsPeriod, start, end) {
1110
1260
  if (statsPeriod && (start || end)) {
1111
- throw new ApiValidationError("Cannot use both statsPeriod and start/end parameters. Use either statsPeriod for relative time or start/end for absolute time.");
1261
+ throw new ApiValidationError(
1262
+ "Cannot use both statsPeriod and start/end parameters. Use either statsPeriod for relative time or start/end for absolute time."
1263
+ );
1112
1264
  }
1113
1265
  if (start && !end || !start && end) {
1114
- throw new ApiValidationError("Both start and end parameters must be provided together for absolute time ranges.");
1266
+ throw new ApiValidationError(
1267
+ "Both start and end parameters must be provided together for absolute time ranges."
1268
+ );
1115
1269
  }
1116
1270
  if (statsPeriod) {
1117
1271
  queryParams.set("statsPeriod", statsPeriod);
@@ -1122,10 +1276,14 @@ function applyTimeParams(queryParams, statsPeriod, start, end) {
1122
1276
  }
1123
1277
  function applyStatsMixinTimeParams(queryParams, statsPeriod, start, end, resolutionSeconds) {
1124
1278
  if (statsPeriod && (start || end)) {
1125
- throw new ApiValidationError("Cannot use both statsPeriod and start/end parameters. Use either statsPeriod for relative time or start/end for absolute time.");
1279
+ throw new ApiValidationError(
1280
+ "Cannot use both statsPeriod and start/end parameters. Use either statsPeriod for relative time or start/end for absolute time."
1281
+ );
1126
1282
  }
1127
1283
  if (start && !end || !start && end) {
1128
- throw new ApiValidationError("Both start and end parameters must be provided together for absolute time ranges.");
1284
+ throw new ApiValidationError(
1285
+ "Both start and end parameters must be provided together for absolute time ranges."
1286
+ );
1129
1287
  }
1130
1288
  let since;
1131
1289
  let until;
@@ -1133,10 +1291,12 @@ function applyStatsMixinTimeParams(queryParams, statsPeriod, start, end, resolut
1133
1291
  const startMs = Date.parse(start);
1134
1292
  const endMs = Date.parse(end);
1135
1293
  if (!Number.isFinite(startMs) || !Number.isFinite(endMs)) {
1136
- throw new ApiValidationError("start and end parameters must be valid ISO 8601 date strings.");
1294
+ throw new ApiValidationError(
1295
+ "start and end parameters must be valid ISO 8601 date strings."
1296
+ );
1137
1297
  }
1138
- since = Math.floor(startMs / 1000);
1139
- until = Math.floor(endMs / 1000);
1298
+ since = Math.floor(startMs / 1e3);
1299
+ until = Math.floor(endMs / 1e3);
1140
1300
  } else {
1141
1301
  const period = statsPeriod ?? "24h";
1142
1302
  const { amount, unit } = parseStatsPeriod(period);
@@ -1158,31 +1318,34 @@ function applyStatsMixinTimeParams(queryParams, statsPeriod, start, end, resolut
1158
1318
  unitSeconds = 60 * 60 * 24 * 7;
1159
1319
  break;
1160
1320
  default:
1161
- throw new ApiValidationError("statsPeriod must use a supported relative time format, such as `24h`, `7d`, or `2w`.");
1321
+ throw new ApiValidationError(
1322
+ "statsPeriod must use a supported relative time format, such as `24h`, `7d`, or `2w`."
1323
+ );
1162
1324
  }
1163
- until = Math.floor(Date.now() / 1000);
1325
+ until = Math.floor(Date.now() / 1e3);
1164
1326
  since = until - amount * unitSeconds;
1165
1327
  }
1166
1328
  queryParams.set("since", String(since));
1167
1329
  queryParams.set("until", String(until));
1168
- if (resolutionSeconds !== undefined) {
1330
+ if (resolutionSeconds !== void 0) {
1169
1331
  queryParams.set("resolution", `${resolutionSeconds}s`);
1170
1332
  }
1171
1333
  }
1334
+
1172
1335
  // src/api-client/transport.ts
1173
- class ApiTimeoutError extends Error {
1336
+ var ApiTimeoutError = class extends Error {
1174
1337
  timeoutMs;
1175
1338
  idempotent;
1176
1339
  constructor(timeoutMs, idempotent) {
1177
- super(`Request timed out after ${Math.round(timeoutMs / 1000)}s`);
1340
+ super(`Request timed out after ${Math.round(timeoutMs / 1e3)}s`);
1178
1341
  this.name = "ApiTimeoutError";
1179
1342
  this.timeoutMs = timeoutMs;
1180
1343
  this.idempotent = idempotent;
1181
1344
  }
1182
- }
1345
+ };
1183
1346
  var MAX_REDIRECTS = 20;
1184
1347
  var ANONYMOUS = { token: "", identity: "" };
1185
- var validatedSources = new WeakMap;
1348
+ var validatedSources = /* @__PURE__ */ new WeakMap();
1186
1349
  function getValidatedResponseSource(response) {
1187
1350
  return validatedSources.get(response);
1188
1351
  }
@@ -1203,13 +1366,12 @@ function extractUrlPath(input) {
1203
1366
  return raw;
1204
1367
  }
1205
1368
  }
1206
-
1207
- class Rejection {
1208
- error;
1369
+ var Rejection = class {
1209
1370
  constructor(error) {
1210
1371
  this.error = error;
1211
1372
  }
1212
- }
1373
+ error;
1374
+ };
1213
1375
  function createApiTransport(config) {
1214
1376
  const { credentials, retry, logger } = config;
1215
1377
  const cache = credentials && config.cache;
@@ -1239,7 +1401,9 @@ function createApiTransport(config) {
1239
1401
  return typeof config.timeoutMs === "function" ? config.timeoutMs(url) : config.timeoutMs;
1240
1402
  }
1241
1403
  function buildHeaders(input, init, credential) {
1242
- const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : undefined));
1404
+ const headers = new Headers(
1405
+ init?.headers ?? (input instanceof Request ? input.headers : void 0)
1406
+ );
1243
1407
  config.prepareHeaders?.(headers, { input, credential });
1244
1408
  setAuthorization(headers, authorization(credential));
1245
1409
  if (config.userAgent && !headers.has("User-Agent")) {
@@ -1255,9 +1419,9 @@ function createApiTransport(config) {
1255
1419
  }
1256
1420
  }
1257
1421
  async function fetchOnce(input, init, signal, timeoutMs, mode) {
1258
- const controller = new AbortController;
1422
+ const controller = new AbortController();
1259
1423
  let timedOut = false;
1260
- const timer = timeoutMs === undefined ? undefined : setTimeout(() => {
1424
+ const timer = timeoutMs === void 0 ? void 0 : setTimeout(() => {
1261
1425
  timedOut = true;
1262
1426
  controller.abort();
1263
1427
  }, timeoutMs);
@@ -1288,7 +1452,9 @@ function createApiTransport(config) {
1288
1452
  }
1289
1453
  async function rejectRedirect(response, destination, credential) {
1290
1454
  cancelBody(response);
1291
- throw new Rejection(config.origins?.reject(destination, credential) ?? new Error(`Refusing to follow a redirect to ${destination}`));
1455
+ throw new Rejection(
1456
+ config.origins?.reject(destination, credential) ?? new Error(`Refusing to follow a redirect to ${destination}`)
1457
+ );
1292
1458
  }
1293
1459
  function trusts(url, credential, original) {
1294
1460
  return config.origins ? config.origins.trusts(url, credential) : url.origin === original.origin;
@@ -1305,7 +1471,10 @@ function createApiTransport(config) {
1305
1471
  try {
1306
1472
  next = new URL(location, request2.url);
1307
1473
  } catch (error) {
1308
- logger?.debug("Rejected malformed redirect location", error instanceof Error ? error.name : "unknown error");
1474
+ logger?.debug(
1475
+ "Rejected malformed redirect location",
1476
+ error instanceof Error ? error.name : "unknown error"
1477
+ );
1309
1478
  return await rejectRedirect(response, "<invalid host>", credential);
1310
1479
  }
1311
1480
  if (!trusts(next, credential, original)) {
@@ -1321,11 +1490,17 @@ function createApiTransport(config) {
1321
1490
  async function fetchValidated(input, init, headers, credential, timeoutMs, mode) {
1322
1491
  const original = new Request(input, init);
1323
1492
  const originalUrl = new URL(original.url);
1324
- const visited = new Set([redirectKey(originalUrl)]);
1493
+ const visited = /* @__PURE__ */ new Set([redirectKey(originalUrl)]);
1325
1494
  let request2 = original;
1326
1495
  let requestHeaders = new Headers(headers);
1327
- for (;; ) {
1328
- const result = await fetchOnce(request2.clone(), { headers: requestHeaders, redirect: "manual" }, init?.signal ?? original.signal, timeoutMs, mode);
1496
+ for (; ; ) {
1497
+ const result = await fetchOnce(
1498
+ request2.clone(),
1499
+ { headers: requestHeaders, redirect: "manual" },
1500
+ init?.signal ?? original.signal,
1501
+ timeoutMs,
1502
+ mode
1503
+ );
1329
1504
  if (!("response" in result) || !isRedirect(result.response.status)) {
1330
1505
  const origin = httpOrigin(request2.url);
1331
1506
  if ("response" in result && origin) {
@@ -1338,8 +1513,19 @@ function createApiTransport(config) {
1338
1513
  }
1339
1514
  const { response } = result;
1340
1515
  try {
1341
- const next = await nextRedirect(response, request2, credential, visited, originalUrl);
1342
- ({ request: request2, headers: requestHeaders } = await redirectRequest(request2, requestHeaders, next, response.status));
1516
+ const next = await nextRedirect(
1517
+ response,
1518
+ request2,
1519
+ credential,
1520
+ visited,
1521
+ originalUrl
1522
+ );
1523
+ ({ request: request2, headers: requestHeaders } = await redirectRequest(
1524
+ request2,
1525
+ requestHeaders,
1526
+ next,
1527
+ response.status
1528
+ ));
1343
1529
  } finally {
1344
1530
  cancelBody(response);
1345
1531
  }
@@ -1349,14 +1535,16 @@ function createApiTransport(config) {
1349
1535
  const { input, init, method, url, path, options } = sendArgs;
1350
1536
  let credential = credentials?.prepare ? await credentials.prepare(sendArgs.credential) : sendArgs.credential;
1351
1537
  const headers = buildHeaders(input, init, credential);
1352
- for (const [name, value] of Object.entries(sendArgs.conditionalHeaders ?? {})) {
1538
+ for (const [name, value] of Object.entries(
1539
+ sendArgs.conditionalHeaders ?? {}
1540
+ )) {
1353
1541
  headers.set(name, value);
1354
1542
  }
1355
1543
  const nextInput = await replayableInput(input, init);
1356
1544
  const timeoutMs = timeoutFor(url);
1357
1545
  const idempotent = options.idempotent === true || (config.isIdempotent?.(method, url) ?? false);
1358
1546
  const mode = options.responseBody ?? "stream";
1359
- const signal = init?.signal !== undefined ? init.signal : input instanceof Request ? input.signal : undefined;
1547
+ const signal = init?.signal !== void 0 ? init.signal : input instanceof Request ? input.signal : void 0;
1360
1548
  let refreshed = false;
1361
1549
  let waitedMs = 0;
1362
1550
  const retryDelay = (attempt, status, serverDelayMs) => nextRetryDelayMs({
@@ -1370,7 +1558,7 @@ function createApiTransport(config) {
1370
1558
  });
1371
1559
  async function onResponse(response, attempt) {
1372
1560
  if (response.status === 401) {
1373
- const next = refreshed || !credentials?.refresh ? undefined : await credentials.refresh(credential);
1561
+ const next = refreshed || !credentials?.refresh ? void 0 : await credentials.refresh(credential);
1374
1562
  if (!next) {
1375
1563
  return { action: "done", response };
1376
1564
  }
@@ -1383,9 +1571,12 @@ function createApiTransport(config) {
1383
1571
  cancelBody(response);
1384
1572
  return { action: "replay" };
1385
1573
  }
1386
- const serverDelayMs = parseRetryDelayMs(response.status, response.headers);
1574
+ const serverDelayMs = parseRetryDelayMs(
1575
+ response.status,
1576
+ response.headers
1577
+ );
1387
1578
  const delayMs = retryDelay(attempt, response.status, serverDelayMs);
1388
- if (delayMs !== undefined) {
1579
+ if (delayMs !== void 0) {
1389
1580
  cancelBody(response);
1390
1581
  return { action: "retry", delayMs };
1391
1582
  }
@@ -1411,11 +1602,11 @@ function createApiTransport(config) {
1411
1602
  if (fatal) {
1412
1603
  return { action: "throw", error: fatal };
1413
1604
  }
1414
- const delayMs = retryDelay(attempt, undefined, undefined);
1415
- if (delayMs !== undefined) {
1605
+ const delayMs = retryDelay(attempt, void 0, void 0);
1606
+ if (delayMs !== void 0) {
1416
1607
  return { action: "retry", delayMs };
1417
1608
  }
1418
- if (timedOutAfterMs === undefined) {
1609
+ if (timedOutAfterMs === void 0) {
1419
1610
  return { action: "throw", error: failed };
1420
1611
  }
1421
1612
  const replayable = isIdempotentRequest(method, idempotent);
@@ -1427,28 +1618,54 @@ function createApiTransport(config) {
1427
1618
  }) ?? new ApiTimeoutError(timedOutAfterMs, replayable)
1428
1619
  };
1429
1620
  }
1430
- for (let attempt = 0;; ) {
1621
+ for (let attempt = 0; ; ) {
1431
1622
  const { input: attemptInput, init: attemptInit } = nextInput();
1432
1623
  let outcome;
1433
1624
  try {
1434
- outcome = options.validateRedirects ? await fetchValidated(attemptInput, attemptInit, headers, credential, timeoutMs, mode) : await fetchOnce(attemptInput, { ...attemptInit, headers }, signal, timeoutMs, mode);
1625
+ outcome = options.validateRedirects ? await fetchValidated(
1626
+ attemptInput,
1627
+ attemptInit,
1628
+ headers,
1629
+ credential,
1630
+ timeoutMs,
1631
+ mode
1632
+ ) : await fetchOnce(
1633
+ attemptInput,
1634
+ { ...attemptInit, headers },
1635
+ signal,
1636
+ timeoutMs,
1637
+ mode
1638
+ );
1435
1639
  } catch (error) {
1436
1640
  outcome = { failed: error };
1437
1641
  }
1438
1642
  const result = "response" in outcome ? await onResponse(outcome.response, attempt) : onFailure(outcome, attempt);
1439
1643
  if (result.action === "done") {
1440
- storeInCache(method, url, sendArgs.credential.identity, headers, result.response);
1441
- await invalidateAfterWrite(method, url, sendArgs.credential.identity, result.response);
1644
+ storeInCache(
1645
+ method,
1646
+ url,
1647
+ sendArgs.credential.identity,
1648
+ headers,
1649
+ result.response
1650
+ );
1651
+ await invalidateAfterWrite(
1652
+ method,
1653
+ url,
1654
+ sendArgs.credential.identity,
1655
+ result.response
1656
+ );
1442
1657
  return result.response;
1443
1658
  }
1444
1659
  if (result.action === "throw") {
1445
1660
  throw result.error;
1446
1661
  }
1447
1662
  if (result.action === "replay") {
1448
- logger?.debug(`${method} ${path} → replay with a refreshed credential`);
1663
+ logger?.debug(`${method} ${path} \u2192 replay with a refreshed credential`);
1449
1664
  continue;
1450
1665
  }
1451
- logger?.debug(`${method} ${path} → retry ${attempt + 1}/${retry.maxRetries} after ${Math.round(result.delayMs)}ms`);
1666
+ logger?.debug(
1667
+ `${method} ${path} \u2192 retry ${attempt + 1}/${retry.maxRetries} after ${Math.round(result.delayMs)}ms`
1668
+ );
1452
1669
  await sleep(result.delayMs, signal);
1453
1670
  waitedMs += result.delayMs;
1454
1671
  attempt++;
@@ -1458,11 +1675,14 @@ function createApiTransport(config) {
1458
1675
  if (!cache || method !== "GET" || !response.ok) {
1459
1676
  return;
1460
1677
  }
1461
- cache.store({
1462
- url,
1463
- requestHeaders: { authorization: headers.get("Authorization") ?? "" },
1464
- identity
1465
- }, response.clone()).catch((error) => {
1678
+ cache.store(
1679
+ {
1680
+ url,
1681
+ requestHeaders: { authorization: headers.get("Authorization") ?? "" },
1682
+ identity
1683
+ },
1684
+ response.clone()
1685
+ ).catch((error) => {
1466
1686
  logger?.debug("Response cache write failed", error);
1467
1687
  });
1468
1688
  }
@@ -1488,9 +1708,11 @@ function createApiTransport(config) {
1488
1708
  url,
1489
1709
  requestHeaders: lookupHeaders(credential),
1490
1710
  identity: credential.identity
1491
- }) : undefined;
1711
+ }) : void 0;
1492
1712
  if (lookup?.kind === "hit") {
1493
- logger?.debug(`${method} ${path} → ${lookup.response.status} (cache hit, ${elapsed()}ms)`);
1713
+ logger?.debug(
1714
+ `${method} ${path} \u2192 ${lookup.response.status} (cache hit, ${elapsed()}ms)`
1715
+ );
1494
1716
  return lookup.response;
1495
1717
  }
1496
1718
  const sendArgs = { input, init, method, url, path, credential, options };
@@ -1501,12 +1723,14 @@ function createApiTransport(config) {
1501
1723
  if (lookup?.kind === "stale" && response.status === 304) {
1502
1724
  const revalidated = await lookup.revalidate(response);
1503
1725
  if (revalidated) {
1504
- logger?.debug(`${method} ${path} → 304 (revalidated cache entry, ${elapsed()}ms)`);
1726
+ logger?.debug(
1727
+ `${method} ${path} \u2192 304 (revalidated cache entry, ${elapsed()}ms)`
1728
+ );
1505
1729
  return revalidated;
1506
1730
  }
1507
1731
  response = await send(sendArgs);
1508
1732
  }
1509
- logger?.debug(`${method} ${path} → ${response.status} (${elapsed()}ms)`);
1733
+ logger?.debug(`${method} ${path} \u2192 ${response.status} (${elapsed()}ms)`);
1510
1734
  return response;
1511
1735
  };
1512
1736
  return config.span ? await config.span({ method, path }, run) : await run();
@@ -1514,7 +1738,7 @@ function createApiTransport(config) {
1514
1738
  return { request };
1515
1739
  }
1516
1740
  async function drainBody(response, signal) {
1517
- const drained = response.body?.pipeTo(new WritableStream);
1741
+ const drained = response.body?.pipeTo(new WritableStream());
1518
1742
  if (!drained) {
1519
1743
  return;
1520
1744
  }
@@ -1533,7 +1757,8 @@ async function drainBody(response, signal) {
1533
1757
  if (onAbort) {
1534
1758
  signal.removeEventListener("abort", onAbort);
1535
1759
  }
1536
- drained.catch(() => {});
1760
+ drained.catch(() => {
1761
+ });
1537
1762
  }
1538
1763
  }
1539
1764
  function isAbort(error, signal) {
@@ -1558,13 +1783,13 @@ async function replayableInput(input, init) {
1558
1783
  return () => ({ input, init });
1559
1784
  }
1560
1785
  function setAuthorization(headers, value) {
1561
- if (value !== undefined) {
1786
+ if (value !== void 0) {
1562
1787
  headers.set("Authorization", value);
1563
1788
  }
1564
1789
  }
1565
1790
  function httpOrigin(raw) {
1566
1791
  const url = new URL(raw);
1567
- return (url.protocol === "http:" || url.protocol === "https:") && !url.username && !url.password ? url.origin : undefined;
1792
+ return (url.protocol === "http:" || url.protocol === "https:") && !url.username && !url.password ? url.origin : void 0;
1568
1793
  }
1569
1794
  function isRedirect(status) {
1570
1795
  return [301, 302, 303, 307, 308].includes(status);
@@ -1583,65 +1808,65 @@ async function redirectRequest(request, requestHeaders, next, status) {
1583
1808
  headers.delete("content-type");
1584
1809
  headers.delete("transfer-encoding");
1585
1810
  }
1586
- const body = method === current && request.body ? await request.clone().arrayBuffer() : undefined;
1811
+ const body = method === current && request.body ? await request.clone().arrayBuffer() : void 0;
1587
1812
  return { request: new Request(next, { method, headers, body }), headers };
1588
1813
  }
1589
1814
  export {
1590
- withQuery,
1591
- validateResponse,
1592
- trimAuthToken,
1593
- storeResponse,
1594
- sleep,
1595
- sentryBearerHeader,
1596
- selectIdempotentWrites,
1597
- readJsonResponse,
1598
- readErrorResponse,
1599
- parseStatsPeriod,
1600
- parseRetryDelayMs,
1601
- paginate,
1602
- normalizeUrl,
1603
- normalizeStatsPeriod,
1604
- normalizeAuthToken,
1605
- nextRetryDelayMs,
1606
- nextPageCursor,
1607
- lookupResponse,
1608
- listPage,
1609
- isIdempotentRequest,
1610
- isApiAuthenticationErrorDeep,
1611
- getValidatedResponseSource,
1612
- fetchAllPages,
1613
- extractUrlPath,
1614
- extractInputUrl,
1615
- encodeApiPathSegment,
1616
- defaultStatsPeriod,
1617
- decodePageCursor,
1618
- createMemoryStore,
1619
- createIdempotentOperationMatcher,
1620
- createApiTransport,
1621
- createApiError,
1622
- createApiClientCore,
1623
- consumeCursorPage,
1624
- computeInvalidationPrefixes,
1625
- classifyUrl,
1626
- buildSentryApiUrl,
1627
- buildCacheKey,
1628
- applyTimeParams,
1629
- applyStatsMixinTimeParams,
1630
- apiPath,
1631
- UserInputError,
1632
- REVALIDATION_WINDOW_MS,
1633
- MAX_LIST_PAGES,
1634
- FALLBACK_TTL_MS,
1635
- ConfigurationError,
1636
- ApiValidationError,
1637
- ApiTimeoutError,
1638
- ApiServerError,
1639
- ApiResponseValidationError,
1640
- ApiRateLimitError,
1641
- ApiPermissionError,
1642
- ApiNotFoundError,
1643
- ApiError,
1644
- ApiClientError,
1815
+ API_MAX_PER_PAGE,
1645
1816
  ApiAuthenticationError,
1646
- API_MAX_PER_PAGE
1817
+ ApiClientError,
1818
+ ApiError,
1819
+ ApiNotFoundError,
1820
+ ApiPermissionError,
1821
+ ApiRateLimitError,
1822
+ ApiResponseValidationError,
1823
+ ApiServerError,
1824
+ ApiTimeoutError,
1825
+ ApiValidationError,
1826
+ ConfigurationError,
1827
+ FALLBACK_TTL_MS,
1828
+ MAX_LIST_PAGES,
1829
+ REVALIDATION_WINDOW_MS,
1830
+ UserInputError,
1831
+ apiPath,
1832
+ applyStatsMixinTimeParams,
1833
+ applyTimeParams,
1834
+ buildCacheKey,
1835
+ buildSentryApiUrl,
1836
+ classifyUrl,
1837
+ computeInvalidationPrefixes,
1838
+ consumeCursorPage,
1839
+ createApiClientCore,
1840
+ createApiError,
1841
+ createApiTransport,
1842
+ createIdempotentOperationMatcher,
1843
+ createMemoryStore,
1844
+ decodePageCursor,
1845
+ defaultStatsPeriod,
1846
+ encodeApiPathSegment,
1847
+ extractInputUrl,
1848
+ extractUrlPath,
1849
+ fetchAllPages,
1850
+ getValidatedResponseSource,
1851
+ isApiAuthenticationErrorDeep,
1852
+ isIdempotentRequest,
1853
+ listPage,
1854
+ lookupResponse,
1855
+ nextPageCursor,
1856
+ nextRetryDelayMs,
1857
+ normalizeAuthToken,
1858
+ normalizeStatsPeriod,
1859
+ normalizeUrl,
1860
+ paginate,
1861
+ parseRetryDelayMs,
1862
+ parseStatsPeriod,
1863
+ readErrorResponse,
1864
+ readJsonResponse,
1865
+ selectIdempotentWrites,
1866
+ sentryBearerHeader,
1867
+ sleep,
1868
+ storeResponse,
1869
+ trimAuthToken,
1870
+ validateResponse,
1871
+ withQuery
1647
1872
  };