From 85fae91512e152c535d7162ffd238560d3c5fca5 Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Thu, 29 Oct 2026 19:56:13 +0000 Subject: [PATCH 1/2] ref(toolkit-core): Move pagination, cache, retry, and transport under api-client Generated by the ts-morph codemod move-transport-layer.mjs (script in the PR description), run from a scratch directory with ts-morph@28.0.0 installed: node move-transport-layer.mjs oxfmt It moves pagination.ts, api-retry.ts (now retry.ts), api-transport.ts (now transport.ts), and the response-cache policy modules into toolkit-core/src/api-client/, with their tests. The node:zlib codec stays at src/response-cache/codec.ts as a host-side module. It rewrites every importer, including the CLI and MCP package subpaths, and the toolkit-core exports. Co-Authored-By: BYK --- packages/cli/script/generate-api-schema.ts | 2 +- packages/cli/src/lib/api/infrastructure.ts | 2 +- packages/cli/src/lib/fetch-input.ts | 2 +- packages/cli/src/lib/response-cache-store.ts | 2 +- packages/cli/src/lib/response-cache.ts | 2 +- packages/cli/src/lib/sentry-client.ts | 6 +++--- .../cli/test/lib/response-cache-store.test.ts | 2 +- packages/mcp-core/src/api-client/client.ts | 4 ++-- packages/toolkit-core/package.json | 20 ++++--------------- .../src/{ => api-client}/pagination.test.ts | 0 .../src/{ => api-client}/pagination.ts | 0 .../{ => api-client}/response-cache/body.ts | 0 .../{ => api-client}/response-cache/index.ts | 0 .../response-cache/invalidation.test.ts | 0 .../response-cache/invalidation.ts | 0 .../response-cache/keys.test.ts | 0 .../{ => api-client}/response-cache/keys.ts | 0 .../response-cache/memory-store.test.ts | 5 ++++- .../response-cache/memory-store.ts | 0 .../response-cache/policy.property.test.ts | 0 .../response-cache/policy.test.ts | 2 +- .../{ => api-client}/response-cache/policy.ts | 0 .../{ => api-client}/response-cache/store.ts | 0 .../response-cache/tiers.test.ts | 0 .../{ => api-client}/response-cache/tiers.ts | 0 .../toolkit-core/src/api-client/response.ts | 2 +- .../retry.test.ts} | 2 +- .../src/{api-retry.ts => api-client/retry.ts} | 0 .../transport.test.ts} | 6 +++--- .../transport.ts} | 4 ++-- .../toolkit-core/src/response-cache/codec.ts | 11 ++++++++-- 31 files changed, 36 insertions(+), 38 deletions(-) rename packages/toolkit-core/src/{ => api-client}/pagination.test.ts (100%) rename packages/toolkit-core/src/{ => api-client}/pagination.ts (100%) rename packages/toolkit-core/src/{ => api-client}/response-cache/body.ts (100%) rename packages/toolkit-core/src/{ => api-client}/response-cache/index.ts (100%) rename packages/toolkit-core/src/{ => api-client}/response-cache/invalidation.test.ts (100%) rename packages/toolkit-core/src/{ => api-client}/response-cache/invalidation.ts (100%) rename packages/toolkit-core/src/{ => api-client}/response-cache/keys.test.ts (100%) rename packages/toolkit-core/src/{ => api-client}/response-cache/keys.ts (100%) rename packages/toolkit-core/src/{ => api-client}/response-cache/memory-store.test.ts (99%) rename packages/toolkit-core/src/{ => api-client}/response-cache/memory-store.ts (100%) rename packages/toolkit-core/src/{ => api-client}/response-cache/policy.property.test.ts (100%) rename packages/toolkit-core/src/{ => api-client}/response-cache/policy.test.ts (99%) rename packages/toolkit-core/src/{ => api-client}/response-cache/policy.ts (100%) rename packages/toolkit-core/src/{ => api-client}/response-cache/store.ts (100%) rename packages/toolkit-core/src/{ => api-client}/response-cache/tiers.test.ts (100%) rename packages/toolkit-core/src/{ => api-client}/response-cache/tiers.ts (100%) rename packages/toolkit-core/src/{api-retry.test.ts => api-client/retry.test.ts} (99%) rename packages/toolkit-core/src/{api-retry.ts => api-client/retry.ts} (100%) rename packages/toolkit-core/src/{api-transport.test.ts => api-client/transport.test.ts} (99%) rename packages/toolkit-core/src/{api-transport.ts => api-client/transport.ts} (99%) diff --git a/packages/cli/script/generate-api-schema.ts b/packages/cli/script/generate-api-schema.ts index 67762debf..702aeae92 100644 --- a/packages/cli/script/generate-api-schema.ts +++ b/packages/cli/script/generate-api-schema.ts @@ -9,7 +9,7 @@ import { mkdir, writeFile } from "node:fs/promises"; import { dirname } from "node:path"; import { operations } from "@sentry/api/operations"; -import { isIdempotentRequest } from "@sentry/toolkit-core/api-retry"; +import { isIdempotentRequest } from "@sentry/toolkit-core/api-client/retry"; import type { IdempotentOperation } from "../src/lib/idempotent-operations.js"; import { projectApiOperations } from "./lib/api-schema.js"; diff --git a/packages/cli/src/lib/api/infrastructure.ts b/packages/cli/src/lib/api/infrastructure.ts index 3d138c684..e288a5995 100644 --- a/packages/cli/src/lib/api/infrastructure.ts +++ b/packages/cli/src/lib/api/infrastructure.ts @@ -20,7 +20,7 @@ import { fetchAllPages as fetchEveryPage, type FetchAllPagesFailure, paginate as paginateFrom, -} from "@sentry/toolkit-core/pagination"; +} from "@sentry/toolkit-core/api-client/pagination"; // oxlint-disable-next-line sentry-cli/no-namespace-import -- Sentry SDK recommends namespace import import * as Sentry from "@sentry/node"; import { type GenericSchema, safeParse } from "valibot"; diff --git a/packages/cli/src/lib/fetch-input.ts b/packages/cli/src/lib/fetch-input.ts index 37d5c2d56..aa88fa2a9 100644 --- a/packages/cli/src/lib/fetch-input.ts +++ b/packages/cli/src/lib/fetch-input.ts @@ -3,4 +3,4 @@ * implementation; this path stays for CLI callers and tests. */ -export { extractInputUrl } from "@sentry/toolkit-core/api-transport"; +export { extractInputUrl } from "@sentry/toolkit-core/api-client/transport"; diff --git a/packages/cli/src/lib/response-cache-store.ts b/packages/cli/src/lib/response-cache-store.ts index 6112642d4..f2a5af561 100644 --- a/packages/cli/src/lib/response-cache-store.ts +++ b/packages/cli/src/lib/response-cache-store.ts @@ -35,7 +35,7 @@ import { type CacheStore, classifyUrl, FALLBACK_TTL_MS, -} from "@sentry/toolkit-core/response-cache"; +} from "@sentry/toolkit-core/api-client/response-cache"; import type { BodyEncoding } from "@sentry/toolkit-core/response-cache/codec"; import pLimit from "p-limit"; diff --git a/packages/cli/src/lib/response-cache.ts b/packages/cli/src/lib/response-cache.ts index a1724460c..e400e755b 100644 --- a/packages/cli/src/lib/response-cache.ts +++ b/packages/cli/src/lib/response-cache.ts @@ -22,7 +22,7 @@ import { classifyUrl, lookupResponse, storeResponse, -} from "@sentry/toolkit-core/response-cache"; +} from "@sentry/toolkit-core/api-client/response-cache"; import { createBodyCodec } from "@sentry/toolkit-core/response-cache/codec"; import { getIdentityFingerprint } from "./db/auth.js"; diff --git a/packages/cli/src/lib/sentry-client.ts b/packages/cli/src/lib/sentry-client.ts index 03a0c7bc1..0d7331691 100644 --- a/packages/cli/src/lib/sentry-client.ts +++ b/packages/cli/src/lib/sentry-client.ts @@ -10,15 +10,15 @@ import type { SentryClient } from "@sentry/api"; import { getTraceData } from "@sentry/node"; -import type { RetryPolicy } from "@sentry/toolkit-core/api-retry"; +import type { RetryPolicy } from "@sentry/toolkit-core/api-client/retry"; import { createApiTransport, extractUrlPath, getValidatedResponseSource, type ResponseBodyMode, type TransportCache, -} from "@sentry/toolkit-core/api-transport"; -import { computeInvalidationPrefixes } from "@sentry/toolkit-core/response-cache"; +} from "@sentry/toolkit-core/api-client/transport"; +import { computeInvalidationPrefixes } from "@sentry/toolkit-core/api-client/response-cache"; import { formatAuthHeader, normalizeAuthToken } from "./auth-header.js"; import { seedCompletions } from "./api/completion-seed.js"; import { maybeWarnEnvTokenIgnored } from "./auth-hint.js"; diff --git a/packages/cli/test/lib/response-cache-store.test.ts b/packages/cli/test/lib/response-cache-store.test.ts index d8c25b904..18c8cd06f 100644 --- a/packages/cli/test/lib/response-cache-store.test.ts +++ b/packages/cli/test/lib/response-cache-store.test.ts @@ -14,7 +14,7 @@ import { } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; -import type { CacheEntry } from "@sentry/toolkit-core/response-cache"; +import type { CacheEntry } from "@sentry/toolkit-core/api-client/response-cache"; import { afterEach, beforeEach, describe, expect, test } from "vitest"; import { createFileStore, diff --git a/packages/mcp-core/src/api-client/client.ts b/packages/mcp-core/src/api-client/client.ts index ded880082..693344d77 100644 --- a/packages/mcp-core/src/api-client/client.ts +++ b/packages/mcp-core/src/api-client/client.ts @@ -21,8 +21,8 @@ import { } from "@sentry/api"; import { buildSentryApiUrl } from "@sentry/toolkit-core/api-request"; import { sentryBearerHeader } from "@sentry/toolkit-core/auth-token"; -import type { RetryPolicy } from "@sentry/toolkit-core/api-retry"; -import { createApiTransport } from "@sentry/toolkit-core/api-transport"; +import type { RetryPolicy } from "@sentry/toolkit-core/api-client/retry"; +import { createApiTransport } from "@sentry/toolkit-core/api-client/transport"; import { z } from "zod"; import { DEFAULT_SEARCH_ISSUES_PERIOD } from "../constants"; import { ConfigurationError } from "../errors"; diff --git a/packages/toolkit-core/package.json b/packages/toolkit-core/package.json index c725b2117..1e2bc943f 100644 --- a/packages/toolkit-core/package.json +++ b/packages/toolkit-core/package.json @@ -11,14 +11,6 @@ "types": "./src/api-request.ts", "default": "./src/api-request.ts" }, - "./api-retry": { - "types": "./src/api-retry.ts", - "default": "./src/api-retry.ts" - }, - "./api-transport": { - "types": "./src/api-transport.ts", - "default": "./src/api-transport.ts" - }, "./api-path-segment": { "types": "./src/api-path-segment.ts", "default": "./src/api-path-segment.ts" @@ -47,10 +39,6 @@ "types": "./src/oauth-poll.ts", "default": "./src/oauth-poll.ts" }, - "./pagination": { - "types": "./src/pagination.ts", - "default": "./src/pagination.ts" - }, "./region-cache": { "types": "./src/region-cache.ts", "default": "./src/region-cache.ts" @@ -59,10 +47,6 @@ "types": "./src/resource-identity.ts", "default": "./src/resource-identity.ts" }, - "./response-cache": { - "types": "./src/response-cache/index.ts", - "default": "./src/response-cache/index.ts" - }, "./response-cache/codec": { "types": "./src/response-cache/codec.ts", "default": "./src/response-cache/codec.ts" @@ -79,6 +63,10 @@ "types": "./src/sentry-origin.ts", "default": "./src/sentry-origin.ts" }, + "./api-client/response-cache": { + "types": "./src/api-client/response-cache/index.ts", + "default": "./src/api-client/response-cache/index.ts" + }, "./api-client/*": { "types": "./src/api-client/*.ts", "default": "./src/api-client/*.ts" diff --git a/packages/toolkit-core/src/pagination.test.ts b/packages/toolkit-core/src/api-client/pagination.test.ts similarity index 100% rename from packages/toolkit-core/src/pagination.test.ts rename to packages/toolkit-core/src/api-client/pagination.test.ts diff --git a/packages/toolkit-core/src/pagination.ts b/packages/toolkit-core/src/api-client/pagination.ts similarity index 100% rename from packages/toolkit-core/src/pagination.ts rename to packages/toolkit-core/src/api-client/pagination.ts diff --git a/packages/toolkit-core/src/response-cache/body.ts b/packages/toolkit-core/src/api-client/response-cache/body.ts similarity index 100% rename from packages/toolkit-core/src/response-cache/body.ts rename to packages/toolkit-core/src/api-client/response-cache/body.ts diff --git a/packages/toolkit-core/src/response-cache/index.ts b/packages/toolkit-core/src/api-client/response-cache/index.ts similarity index 100% rename from packages/toolkit-core/src/response-cache/index.ts rename to packages/toolkit-core/src/api-client/response-cache/index.ts diff --git a/packages/toolkit-core/src/response-cache/invalidation.test.ts b/packages/toolkit-core/src/api-client/response-cache/invalidation.test.ts similarity index 100% rename from packages/toolkit-core/src/response-cache/invalidation.test.ts rename to packages/toolkit-core/src/api-client/response-cache/invalidation.test.ts diff --git a/packages/toolkit-core/src/response-cache/invalidation.ts b/packages/toolkit-core/src/api-client/response-cache/invalidation.ts similarity index 100% rename from packages/toolkit-core/src/response-cache/invalidation.ts rename to packages/toolkit-core/src/api-client/response-cache/invalidation.ts diff --git a/packages/toolkit-core/src/response-cache/keys.test.ts b/packages/toolkit-core/src/api-client/response-cache/keys.test.ts similarity index 100% rename from packages/toolkit-core/src/response-cache/keys.test.ts rename to packages/toolkit-core/src/api-client/response-cache/keys.test.ts diff --git a/packages/toolkit-core/src/response-cache/keys.ts b/packages/toolkit-core/src/api-client/response-cache/keys.ts similarity index 100% rename from packages/toolkit-core/src/response-cache/keys.ts rename to packages/toolkit-core/src/api-client/response-cache/keys.ts diff --git a/packages/toolkit-core/src/response-cache/memory-store.test.ts b/packages/toolkit-core/src/api-client/response-cache/memory-store.test.ts similarity index 99% rename from packages/toolkit-core/src/response-cache/memory-store.test.ts rename to packages/toolkit-core/src/api-client/response-cache/memory-store.test.ts index 38cae84c0..71fe9acba 100644 --- a/packages/toolkit-core/src/response-cache/memory-store.test.ts +++ b/packages/toolkit-core/src/api-client/response-cache/memory-store.test.ts @@ -1,5 +1,8 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { createBodyCodec, type EncodedBody } from "./codec.js"; +import { + createBodyCodec, + type EncodedBody, +} from "../../response-cache/codec.js"; import { buildCacheKey } from "./keys.js"; import { createMemoryStore, ENTRY_OVERHEAD_BYTES } from "./memory-store.js"; import type { CacheEntry } from "./store.js"; diff --git a/packages/toolkit-core/src/response-cache/memory-store.ts b/packages/toolkit-core/src/api-client/response-cache/memory-store.ts similarity index 100% rename from packages/toolkit-core/src/response-cache/memory-store.ts rename to packages/toolkit-core/src/api-client/response-cache/memory-store.ts diff --git a/packages/toolkit-core/src/response-cache/policy.property.test.ts b/packages/toolkit-core/src/api-client/response-cache/policy.property.test.ts similarity index 100% rename from packages/toolkit-core/src/response-cache/policy.property.test.ts rename to packages/toolkit-core/src/api-client/response-cache/policy.property.test.ts diff --git a/packages/toolkit-core/src/response-cache/policy.test.ts b/packages/toolkit-core/src/api-client/response-cache/policy.test.ts similarity index 99% rename from packages/toolkit-core/src/response-cache/policy.test.ts rename to packages/toolkit-core/src/api-client/response-cache/policy.test.ts index 34e473147..d86cce0a8 100644 --- a/packages/toolkit-core/src/response-cache/policy.test.ts +++ b/packages/toolkit-core/src/api-client/response-cache/policy.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { createBodyCodec } from "./codec.js"; +import { createBodyCodec } from "../../response-cache/codec.js"; import { createMemoryStore } from "./memory-store.js"; import { type CacheLookup, diff --git a/packages/toolkit-core/src/response-cache/policy.ts b/packages/toolkit-core/src/api-client/response-cache/policy.ts similarity index 100% rename from packages/toolkit-core/src/response-cache/policy.ts rename to packages/toolkit-core/src/api-client/response-cache/policy.ts diff --git a/packages/toolkit-core/src/response-cache/store.ts b/packages/toolkit-core/src/api-client/response-cache/store.ts similarity index 100% rename from packages/toolkit-core/src/response-cache/store.ts rename to packages/toolkit-core/src/api-client/response-cache/store.ts diff --git a/packages/toolkit-core/src/response-cache/tiers.test.ts b/packages/toolkit-core/src/api-client/response-cache/tiers.test.ts similarity index 100% rename from packages/toolkit-core/src/response-cache/tiers.test.ts rename to packages/toolkit-core/src/api-client/response-cache/tiers.test.ts diff --git a/packages/toolkit-core/src/response-cache/tiers.ts b/packages/toolkit-core/src/api-client/response-cache/tiers.ts similarity index 100% rename from packages/toolkit-core/src/response-cache/tiers.ts rename to packages/toolkit-core/src/api-client/response-cache/tiers.ts diff --git a/packages/toolkit-core/src/api-client/response.ts b/packages/toolkit-core/src/api-client/response.ts index 85c2e8b3f..fcf4cf363 100644 --- a/packages/toolkit-core/src/api-client/response.ts +++ b/packages/toolkit-core/src/api-client/response.ts @@ -3,7 +3,7 @@ * errors: the MCP to `ApiError` subclasses, the CLI to its exit-coded ones. */ -import { parseRetryDelayMs } from "../api-retry.js"; +import { parseRetryDelayMs } from "./retry.js"; /** What a failed response's body says, read once. */ export type ErrorResponseBody = { diff --git a/packages/toolkit-core/src/api-retry.test.ts b/packages/toolkit-core/src/api-client/retry.test.ts similarity index 99% rename from packages/toolkit-core/src/api-retry.test.ts rename to packages/toolkit-core/src/api-client/retry.test.ts index 99071ecff..9b7a9721b 100644 --- a/packages/toolkit-core/src/api-retry.test.ts +++ b/packages/toolkit-core/src/api-client/retry.test.ts @@ -5,7 +5,7 @@ import { parseRetryDelayMs, type RetryPolicy, sleep, -} from "./api-retry.js"; +} from "./retry.js"; const NOW = Date.UTC(2026, 0, 1, 12, 0, 0, 300); const NOW_SECONDS = Math.floor(NOW / 1000); diff --git a/packages/toolkit-core/src/api-retry.ts b/packages/toolkit-core/src/api-client/retry.ts similarity index 100% rename from packages/toolkit-core/src/api-retry.ts rename to packages/toolkit-core/src/api-client/retry.ts diff --git a/packages/toolkit-core/src/api-transport.test.ts b/packages/toolkit-core/src/api-client/transport.test.ts similarity index 99% rename from packages/toolkit-core/src/api-transport.test.ts rename to packages/toolkit-core/src/api-client/transport.test.ts index 471bce4e3..e8f9d621f 100644 --- a/packages/toolkit-core/src/api-transport.test.ts +++ b/packages/toolkit-core/src/api-client/transport.test.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from "vitest"; -import type { RetryPolicy } from "./api-retry.js"; +import type { RetryPolicy } from "./retry.js"; import { ApiTimeoutError, type ApiTransportOptions, @@ -7,14 +7,14 @@ import { getValidatedResponseSource, type TransportCache, type TransportCredential, -} from "./api-transport.js"; +} from "./transport.js"; import { buildCacheKey, createMemoryStore, lookupResponse, storeResponse, } from "./response-cache/index.js"; -import { createBodyCodec } from "./response-cache/codec.js"; +import { createBodyCodec } from "../response-cache/codec.js"; const URL_BASE = "https://us.sentry.io/api/0"; const ISSUES_URL = `${URL_BASE}/organizations/acme/issues/`; diff --git a/packages/toolkit-core/src/api-transport.ts b/packages/toolkit-core/src/api-client/transport.ts similarity index 99% rename from packages/toolkit-core/src/api-transport.ts rename to packages/toolkit-core/src/api-client/transport.ts index 6be6f5171..c9cc2dd88 100644 --- a/packages/toolkit-core/src/api-transport.ts +++ b/packages/toolkit-core/src/api-client/transport.ts @@ -16,8 +16,8 @@ import { parseRetryDelayMs, type RetryPolicy, sleep, -} from "./api-retry.js"; -import { sentryBearerHeader, trimAuthToken } from "./auth-token.js"; +} from "./retry.js"; +import { sentryBearerHeader, trimAuthToken } from "../auth-token.js"; import type { CacheLookup } from "./response-cache/policy.js"; type FetchInput = Request | string | URL; diff --git a/packages/toolkit-core/src/response-cache/codec.ts b/packages/toolkit-core/src/response-cache/codec.ts index 782910a27..1ab3a9d1d 100644 --- a/packages/toolkit-core/src/response-cache/codec.ts +++ b/packages/toolkit-core/src/response-cache/codec.ts @@ -11,9 +11,16 @@ // A namespace import, so a missing `zstdCompress` (Node < 22.15) is // `undefined` rather than a link error. import * as nodeZlib from "node:zlib"; -import type { BodyCodec, EncodedBody } from "./body.js"; +import type { + BodyCodec, + EncodedBody, +} from "../api-client/response-cache/body.js"; -export type { BodyCodec, BodyEncoding, EncodedBody } from "./body.js"; +export type { + BodyCodec, + BodyEncoding, + EncodedBody, +} from "../api-client/response-cache/body.js"; /** Bodies smaller than this are stored uncompressed. */ export const MIN_COMPRESSED_BYTES = 256; From 85df504bec82473418cd2ad36f9a4f2b41de2591 Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Thu, 29 Oct 2026 19:54:50 +0000 Subject: [PATCH 2/2] docs: Point comments and docs at the api-client module paths Comments in the CLI, MCP, and transport, the toolkit-core README, and api-patterns.md name the moved modules by their new api-client paths. Co-Authored-By: BYK --- docs/contributing/api-patterns.md | 8 ++++---- packages/cli/src/lib/api/infrastructure.ts | 2 +- packages/cli/src/lib/sentry-client.ts | 6 +++--- packages/mcp-core/src/api-client/client.ts | 2 +- packages/toolkit-core/README.md | 13 ++++++++----- packages/toolkit-core/src/api-client/transport.ts | 2 +- 6 files changed, 18 insertions(+), 15 deletions(-) diff --git a/docs/contributing/api-patterns.md b/docs/contributing/api-patterns.md index e22d86717..c35b6d52c 100644 --- a/docs/contributing/api-patterns.md +++ b/docs/contributing/api-patterns.md @@ -268,15 +268,15 @@ exit-coded `ApiError`. See ### Automatic Retries `SentryApiService` sends every request, including `@sentry/api` operations, -through the shared transport in `@sentry/toolkit-core/api-transport`, which +through the shared transport in `@sentry/toolkit-core/api-client/transport`, which retries failed requests using the shared policy in -`@sentry/toolkit-core/api-retry`. `SentryApiService` never retries on top, so +`@sentry/toolkit-core/api-client/retry`. `SentryApiService` never retries on top, so a request is retried by one layer only. This page describes the behavior; the values live only in code, so read them there instead of copying them here: - Which statuses retry, and for which methods: `RETRYABLE_STATUSES` in - [`api-retry.ts`](../../packages/toolkit-core/src/api-retry.ts). In short, a + [`retry.ts`](../../packages/toolkit-core/src/api-client/retry.ts). In short, a rate-limited request retries for any method, a transient server error only for an idempotent one, and other errors never. - How many retries and how long they may wait: `REQUEST_RETRY_POLICY` in @@ -305,7 +305,7 @@ Callers and tools need no changes: a retried request either resolves normally or throws the same error it would have thrown without retries. The CLI sends its requests through the shared transport in -`@sentry/toolkit-core/api-transport`, configured in +`@sentry/toolkit-core/api-client/transport`, configured in `packages/cli/src/lib/sentry-client.ts`. It follows the same shared rule; only the caps differ (`RETRY_POLICY`): the hosted MCP keeps its total wait short so a Workers request isn't held open, while the CLI can wait longer. The CLI also diff --git a/packages/cli/src/lib/api/infrastructure.ts b/packages/cli/src/lib/api/infrastructure.ts index e288a5995..16b3726b8 100644 --- a/packages/cli/src/lib/api/infrastructure.ts +++ b/packages/cli/src/lib/api/infrastructure.ts @@ -493,7 +493,7 @@ export async function autoPaginate( * This is the only supported way to build a limit-bounded list; the * `sentry-cli/no-manual-pagination` lint rule rejects hand-written loops * (#1458, #1608). Page sizing and resume-safe cursors live in - * `@sentry/toolkit-core/pagination`, shared with the MCP; this wrapper sets + * `@sentry/toolkit-core/api-client/pagination`, shared with the MCP; this wrapper sets * the CLI's page cap and default limit and logs the CLI's warnings. * * Callers own region resolution and query building inside `fetchPage`, and diff --git a/packages/cli/src/lib/sentry-client.ts b/packages/cli/src/lib/sentry-client.ts index 0d7331691..2eedf7189 100644 --- a/packages/cli/src/lib/sentry-client.ts +++ b/packages/cli/src/lib/sentry-client.ts @@ -87,7 +87,7 @@ const ENDPOINT_TIMEOUT_OVERRIDES: TimeoutOverride[] = [ /** * Caps for automatic retries. Which statuses and methods retry is the shared - * rule in `@sentry/toolkit-core/api-retry`. + * rule in `@sentry/toolkit-core/api-client/retry`. * * `maxDelayMs` caps the jittered backoff and the server-requested wait * (`Retry-After`, rate-limit reset); a longer server-requested wait is not @@ -331,7 +331,7 @@ async function withHttpSpan( /** * The CLI's transport options: stored credentials, host-scope checks, the * response cache, and the CLI's error classes. Retries, timeouts, the 401 - * refresh, and redirect validation are in `@sentry/toolkit-core/api-transport`. + * refresh, and redirect validation are in `@sentry/toolkit-core/api-client/transport`. */ function createCliTransport(credential: CredentialContext | undefined) { return createApiTransport({ @@ -391,7 +391,7 @@ function createCliTransport(credential: CredentialContext | undefined) { /** * Create a fetch function with authentication, timeout, retry, caching, and 401 refresh. * - * This wraps the native fetch with `@sentry/toolkit-core/api-transport`: + * This wraps the native fetch with `@sentry/toolkit-core/api-client/transport`: * - **Response caching** for GET requests (checked before hitting the network) * - Auth token injection (Bearer token) * - Request timeout via AbortController diff --git a/packages/mcp-core/src/api-client/client.ts b/packages/mcp-core/src/api-client/client.ts index 693344d77..ee799106a 100644 --- a/packages/mcp-core/src/api-client/client.ts +++ b/packages/mcp-core/src/api-client/client.ts @@ -316,7 +316,7 @@ type RequestOptions = { /** * Caps for automatic retries. Which statuses and methods are retried is the - * shared rule in `@sentry/toolkit-core/api-retry`. + * shared rule in `@sentry/toolkit-core/api-client/retry`. * * Sentry's per-endpoint limits are mostly per second ("Limit is 40 requests * in 1 seconds"), so a 429's reset is usually under a second away and two diff --git a/packages/toolkit-core/README.md b/packages/toolkit-core/README.md index 15b139282..840a605f5 100644 --- a/packages/toolkit-core/README.md +++ b/packages/toolkit-core/README.md @@ -6,7 +6,7 @@ builds bundle this private workspace package into their artifacts. The shared code validates and formats upstream bearer tokens, assembles Sentry API URLs, constructs OAuth device-flow form bodies, classifies RFC 8628 polling responses, advances retry intervals, decides when a Sentry API request may -be retried and how long to wait (`api-retry`), recognizes Sentry hostnames and +be retried and how long to wait (`api-client/retry`), recognizes Sentry hostnames and credential-safe SaaS HTTPS origins, encodes API path identifiers, parses Events field expressions the way the Sentry frontend does, parses search queries with the Sentry frontend grammar, resolves Events endpoint sorts so the sort column @@ -37,13 +37,16 @@ the one exception. rate-limit wait, and each host maps that to its own errors. `readJsonResponse` parses a successful body after checking its Content-Type. +- `pagination`, `retry`, `transport`, and `response-cache` are described in + the sections below. The `node:zlib` body codec stays outside, at + `response-cache/codec`, since browsers lack it. ## API transport -`api-transport` is the authenticated fetch both products send Sentry API +`api-client/transport` is the authenticated fetch both products send Sentry API requests through. `createApiTransport` sets the Authorization header, refreshes the credential once after a 401 and replays the request (any method, since the -endpoint never ran), times out each attempt, and retries through `api-retry`. +endpoint never ran), times out each attempt, and retries through `api-client/retry`. Request bodies are replayed on each attempt, including stream bodies. With `validateRedirects`, it follows redirects by hand, sends the credential only to origins the host trusts, and records the final origin for @@ -67,7 +70,7 @@ skips the cache, since entries are scoped to a credential. The MCP's ## Pagination -`pagination` walks Sentry list endpoints up to a row limit. `paginate` splits +`api-client/pagination` walks Sentry list endpoints up to a row limit. `paginate` splits the limit evenly over the fewest requests (at most 100 rows each), reuses the page size a page-number cursor encodes, and returns a cursor that resumes at the first row the caller has not received, even when the walk stopped inside @@ -84,7 +87,7 @@ CLI's `paginate` and `fetchAllPages` in ## Response cache -`response-cache` holds the cache policy for Sentry API GET responses. +`api-client/response-cache` holds the cache policy for Sentry API GET responses. `classifyUrl` puts a URL in a fallback TTL tier for responses without HTTP caching headers: `volatile` (60 seconds) for issues, project event details, full traces, and log and span queries; `no-cache` for autofix and root-cause diff --git a/packages/toolkit-core/src/api-client/transport.ts b/packages/toolkit-core/src/api-client/transport.ts index c9cc2dd88..6e994479f 100644 --- a/packages/toolkit-core/src/api-client/transport.ts +++ b/packages/toolkit-core/src/api-client/transport.ts @@ -4,7 +4,7 @@ * * Per request it sets the Authorization header, refreshes the credential once * after a 401 (any method), times out each attempt, retries through - * `api-retry`, replays request bodies, optionally follows redirects only to + * `retry`, replays request bodies, optionally follows redirects only to * trusted origins, and serves and invalidates cached GETs through an injected * cache. The host supplies credentials, header rules, error classes, logging, * and spans.