Repository navigation
feat(client): Pick each request's base URL from its path with resolveBaseUrl - #130
Merged
Merged
Conversation
…BaseUrl Add a resolveBaseUrl option to the generated client. It runs once per request, before the URL is built, and gets the configured base URL, the path and query, and the org and project the path targets (parseApiPathScope). Hosts use it to send org-scoped requests to the org's region or server. parseApiPathScope moves to a dependency-free module so the generated client can use it; api-path.ts re-exports it. Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
sentry-junior
Bot
requested review from
MathurAditya724 and
betegon
as code owners
November 5, 2026 12:29
BYK
approved these changes
Nov 5, 2026
2 tasks done
This was referenced Nov 5, 2026
Open
sentry-junior Bot
added a commit
to getsentry/toolkit
that referenced
this pull request
Nov 5, 2026
1.29.0 ships Config.resolveBaseUrl (getsentry/sentry-api-schema#130), which getOrgSdkConfig() now passes.
BYK
added a commit
that referenced
this pull request
Nov 5, 2026
Follow-up to [this review comment](#130 (comment)) on #130. It's the same refactor as getsentry/toolkit#1939, which made the CLI's generators run in one process. Before this PR, `build.mjs` ran each of the 12 scripts in `scripts/` as its own `node` process with `execSync`. Six of them loaded TypeScript and five parsed the 6 MB spec, each one starting over. Several also had their own copies of the same patch helpers. ## What changes - **One process:** each script exports `emit()` and does no work at import time. `build.mjs` lists the steps in their old order, imports each one and runs its `emit`. - **Specs parsed once:** `normalizeSpec` now also returns the spec it writes. `build.mjs` passes `{ normalizedSpec, sourceSpec }` to every step, so no step reads a spec from disk. - Steps that used to fall back to `openapi-derefed.json` when `openapi-normalized.json` was missing don't need to anymore; that fallback was only for running a script on its own. - No step changes either spec. - **Shared helpers:** the new `lib/generated-source.mjs` has `replaceOnce`, `update`, `parse`, `edit` and `srcPath`. The scripts import them instead of keeping their own copies. - `replaceOnce` is the stricter version from `generate-response-contract.mjs`: it takes a string or a RegExp and reports how many matches it found. - `make-tree-shakeable.mjs` now uses it instead of its own loop. Most of each script's diff is the new indentation from wrapping its body in `emit`; [hide whitespace](https://github.com/getsentry/sentry-api-schema/pull/131/files?w=1) to see the actual changes. I didn't indent lines inside template literals, so the generated text didn't change. ## Verification - With a clean `pnpm build`, every file in `src/` and `dist/` is byte-identical to `main`'s (`diff -r`). - `pnpm typecheck` passes, and so do all 632 tests in `pnpm test`. - The step phase (from the first patch through `make-tree-shakeable`) took 19.1 s and 19.5 s on `main`, and 16.1 s and 13.5 s on this branch, in one sandbox. The whole build is about 54 s, and Hey API code generation and `tsc --emitDeclarationOnly` still take most of it. <!-- junior-request-attribution:start --> via @BYK. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:local%3Aweb%3Aad43917b182be622bccdd8f7 --> -- [View Session in Sentry](https://sentry.sentry.io/explore/conversations/local%3Aweb%3Aad43917b182be622bccdd8f7/?project=4510944073809921) <!-- junior-session-footer:end --> Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: BYK <126780+BYK@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This adds a per-request base URL hook to the generated client, so a host can send each org-scoped request to the org's region or server before the URL is built. Follow-up to #129, which gave
CredentialProvider.currentthe path's scope. That only helps pick a credential for a URL that's already built.What changes
Config.resolveBaseUrl(typesBaseUrlRequestandBaseUrlResolver, exported from the root). It receives{ baseUrl, url, scope? }:baseUrlis the configured base URL, or''when none is set.urlis the built path and query.scopeisparseApiPathScope(url), and is left out for unscoped paths.Its result replaces
baseUrlfor that one request, with trailing slashes removed. It runs once per request, includingprepareRequest, afterrequestValidatorand before request interceptors. A per-callresolveBaseUrlreplaces the configured one. If it throws, the request rejects with that error unchanged andfetchis never called.The new step lives in
scripts/generate-base-url-resolver.mjs. It patches the pinned Fetch client in the same waygenerate-request-preparation.mjsdoes.parseApiPathScopemoves tolib/api-client/api-path-scope.ts, a module with no imports, so the generated client can use it without bundlingerrors.ts.api-path.tsre-exports it, so the public API doesn't change.The host still owns region discovery, caching, and trust. The client only asks the host which base URL to use.
Consumer
The toolkit CLI will use this to replace
resolveOrgRegioncalls at each call site and thegetDefaultSdkConfig({ path })workaround from getsentry/toolkit#1978. I built that change against a local build of this branch. CLItsc, lint, and the affected tests pass.Tests
test/base-url-resolution.test.tscovers:scopekey.prepareRequestURLs are resolved, including when nobaseUrlis configured.pnpm build,pnpm typecheck, andpnpm test(632 tests) pass.via @BYK.
--
View Session in Sentry