Skip to content

feat(cli-core): migrate HTTP request layer to get-it v9#1534

Open
stipsan wants to merge 23 commits into
mainfrom
cursor/upgrade-get-it-v9-28de
Open

feat(cli-core): migrate HTTP request layer to get-it v9#1534
stipsan wants to merge 23 commits into
mainfrom
cursor/upgrade-get-it-v9-28de

Conversation

@stipsan

@stipsan stipsan commented Jul 15, 2026

Copy link
Copy Markdown
Member

Description

Upgrade @sanity/cli-core from get-it v8 to v9 (now 9.3.0) and migrate the request layer to the new fetch-based API.

@sanity/cli-core/request now uses get-it v9-style options (headers, httpErrors, debug, middleware, structured timeout, etc.) on createRequester, and re-exports the v9 helpers used by CLI consumers (HttpError, TimeoutError, response types, retry / debug, nodeReadableFromWeb()).

Call sites in @sanity/cli and @sanity/cli-build were updated for the v9 response shape (status / Headers), as: 'stream' | 'text', and redirect: 'manual' — including the new sanity api service that landed on main against the v8 API.

What to review

  • packages/@sanity/cli-core/src/request/createRequester.tsCreateRequesterOptions derives from get-it's RequesterOptions; User-Agent overrides detected case-insensitively
  • Backup downloads use 9.3.0's structured timeout: {headers: 15s, total: false} (fresh per-retry headers deadline, no custom middleware) plus the 3-minute idle-read timer; destinations are deferred until a response arrives
  • services/api.ts migrated to v9: httpErrors: false + as: 'text', Headers access, status/statusText, and URLSearchParams to preserve repeated query params
  • Dataset import streaming has no request timeout (timeout: false); getUrlHeaders / GraphQL and dependency version comparison unchanged from earlier revisions
  • Public export surface of @sanity/cli-core/request; cli-test request mock re-exports get-it's real HttpError / TimeoutError
  • Shared Vitest setup forces globalThis.fetch for createRequester so nock can intercept (get-it v9 Node entry uses undici with a private dispatcher)
  • downloadStream tests run entirely on get-it/mock: streamBody() / streamStall() for stalled bodies, toHaveBeenCancelled() for cancellation, respondPersist({delay}) + fake timers for per-attempt deadlines
  • get-it added to minimumReleaseAgeExclude (first-party, matching the existing @sanity/* pattern)

Testing

  • Unit tests for createRequester (incl. case-insensitive User-Agent and get-it option passthrough), nodeReadableFromWeb, backup stream timeout/cancellation/deferred-destination behavior, and the nock-based sanity api command suite
  • Backup download + dataset import tests updated for v9 transport
  • GraphQL deploy integration suites pass across supported Ubuntu/Windows and Node matrices
  • pnpm check:types, pnpm check:lint, pnpm check:deps, and pnpm build:cli pass

Notes for release

N/A

Open in Web Open in Cursor 

cursoragent and others added 2 commits July 15, 2026 21:31
Replace the get-it v8 middleware stack in @sanity/cli-core/request with the
fetch-based v9 createRequester API, and update CLI consumers for the new
response shape, streaming, and redirect options.
@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Stats — @sanity/cli

Compared against main (643f3d47)

@sanity/cli

Metric Value vs main (643f3d4)
Internal (raw) 2.2 KB -
Internal (gzip) 838 B -
Bundled (raw) 11.20 MB -
Bundled (gzip) 2.11 MB -
Import time 682ms -2ms, -0.3%

bin:sanity

Metric Value vs main (643f3d4)
Internal (raw) 782 B -
Internal (gzip) 423 B -
Bundled (raw) 9.90 MB -
Bundled (gzip) 1.78 MB -
Import time 1.64s +13ms, +0.8%

🗺️ View treemap · Artifacts

Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

📦 Bundle Stats — @sanity/cli-core

Compared against main (643f3d47)

Metric Value vs main (643f3d4)
Internal (raw) 114.1 KB -
Internal (gzip) 29.2 KB -
Bundled (raw) 21.76 MB -
Bundled (gzip) 3.46 MB -
Import time 599ms -8ms, -1.3%

🗺️ View treemap · Artifacts

Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

📦 Bundle Stats — @sanity/cli-build

Compared against main (643f3d47)

@sanity/cli-build/_internal/build

Metric Value vs main (643f3d4)
Internal (raw) 113.1 KB -94 B, -0.1%
Internal (gzip) 28.6 KB -33 B, -0.1%
Bundled (raw) 17.61 MB -140.6 KB, -0.8%
Bundled (gzip) 3.52 MB -39.0 KB, -1.1%
Import time 888ms +7ms, +0.8%

@sanity/cli-build/_internal/env

Metric Value vs main (643f3d4)
Internal (raw) 1.8 KB -
Internal (gzip) 644 B -
Bundled (raw) 1.31 MB -
Bundled (gzip) 333.8 KB -
Import time 100ms +1ms, +1.3%

@sanity/cli-build/_internal/extract

Metric Value vs main (643f3d4)
Internal (raw) 8.6 KB -
Internal (gzip) 2.7 KB -
Bundled (raw) 155.0 KB -
Bundled (gzip) 39.5 KB -
Import time 189ms +2ms, +1.2%

🗺️ ./_internal/env · ./_internal/extract · @sanity/cli-build:./_internal/build treemap too large to embed · Artifacts

Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

📦 Bundle Stats — create-sanity

Compared against main (643f3d47)

Metric Value vs main (643f3d4)
Internal (raw) 908 B -
Internal (gzip) 483 B -
Bundled (raw) 931 B -
Bundled (gzip) 491 B -
Import time ❌ ChildProcess denied: node -
Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

@socket-security

socket-security Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​get-it@​9.3.07610010098100

View full report

Force global fetch in backup download tests so nock can intercept undici,
and mock nodeReadableFromWeb in dataset import tests.
@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Coverage Delta

File Statements
packages/@sanity/cli-build/src/util/compareDependencyVersions.ts 100.0% (±0%)
packages/@sanity/cli-core/src/request/createRequester.ts 100.0% (±0%)
packages/@sanity/cli-core/src/request/nodeReadableFromWeb.ts 87.5% (new)
packages/@sanity/cli/src/actions/backup/downloadAsset.ts 100.0% (±0%)
packages/@sanity/cli/src/actions/backup/downloadDocument.ts 100.0% (±0%)
packages/@sanity/cli/src/actions/backup/downloadStream.ts 100.0% (new)
packages/@sanity/cli/src/commands/datasets/import.ts 87.7% (±0%)
packages/@sanity/cli/src/services/api.ts 89.5% (- 4.3%)
packages/@sanity/cli/src/services/getUrlHeaders.ts 66.7% (±0%)
packages/@sanity/cli/src/services/graphql.ts 61.9% (±0%)

Comparing 10 changed files against main @ d9887459fcf9e1c98ff4df06c0af7f0798f68e3f

Overall Coverage

Metric Coverage
Statements 78.5% (+ 0.1%)
Branches 70.1% (+ 0.0%)
Functions 73.7% (+ 0.2%)
Lines 78.9% (+ 0.1%)

get-it v9's Node fetch uses undici with a private dispatcher, so nock
cannot intercept createRequester traffic. Force globalThis.fetch in the
shared Vitest setup so GraphQL deploy and other nock-based suites work.
The dependency bump and request-layer migration should not force major
versions; majors were only inferred from the breaking bang in the PR title.
@cursor cursor Bot changed the title feat(cli-core)!: migrate HTTP request layer to get-it v9 feat(cli-core): migrate HTTP request layer to get-it v9 Jul 16, 2026
@stipsan
stipsan marked this pull request as ready for review July 17, 2026 08:50
@stipsan
stipsan requested a review from a team as a code owner July 17, 2026 08:50
Comment thread packages/@sanity/cli-core/src/request/nodeReadableFromWeb.ts
Comment thread packages/@sanity/cli/src/actions/backup/downloadAsset.ts
Cancel web response bodies when Node streams end early.

Restore separate response and idle read timeouts for backup downloads.
Cancel the reader directly when a Node stream is destroyed so pending reads cannot block cleanup.
Destroy destination streams when requests fail before body streaming begins.
Comment thread packages/@sanity/cli-core/src/request/nodeReadableFromWeb.ts
Comment thread packages/@sanity/cli/src/actions/backup/downloadStream.ts
Give each Node fetch attempt its own response timeout.

Guard pending read teardown from cancellation races.
Comment thread .changeset/pr-1534.md
Comment thread packages/@sanity/cli/src/actions/backup/downloadAsset.ts Outdated
Apply the response deadline as inner middleware.

Retries get fresh timers while tests can inject global fetch.
…-v9-28de

# Conflicts:
#	packages/@sanity/cli/src/commands/datasets/import.ts
Comment thread packages/@sanity/cli/src/commands/datasets/import.ts
rexxars
rexxars previously approved these changes Jul 18, 2026

@rexxars rexxars left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks good, just left some comments and potential room for improvemnts

Comment thread packages/@sanity/cli-core/src/request/createRequester.ts Outdated
Comment thread packages/@sanity/cli-test/src/mocks/cli-core/request.ts Outdated
Comment thread .changeset/pr-1534.md
Comment thread packages/@sanity/cli/src/actions/backup/downloadAsset.ts Outdated
Comment thread packages/@sanity/cli/src/actions/backup/downloadStream.test.ts
Comment thread packages/@sanity/cli-core/src/request/createRequester.ts Outdated
Comment thread packages/@sanity/cli/src/actions/backup/downloadStream.ts Outdated
Detect User-Agent overrides case-insensitively.

Derive CreateRequesterOptions from get-it RequesterOptions.

Re-export the real get-it HttpError from the cli-test request mock.

Defer backup download destinations until a response arrives.

Disable the request timeout for streamed dataset imports.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR upgrades the CLI monorepo’s HTTP layer by migrating @sanity/cli-core/request from get-it v8 to get-it v9 (fetch-based), updating downstream call sites to the v9 response shape/streaming API, and introducing shared helpers for Web↔Node stream interop and more robust backup streaming.

Changes:

  • Migrate @sanity/cli-core/request to get-it v9 (createRequester options shape, exported types/helpers, and new nodeReadableFromWeb()).
  • Update CLI/CLI-build consumers for v9 semantics (as: 'stream', redirect: 'manual', Headers access, etc.).
  • Refactor backup downloads to a shared downloadStream() with per-attempt connection timeout + rolling read timeout, plus new tests.

Reviewed changes

Copilot reviewed 22 out of 23 changed files in this pull request and generated no comments.

Show a summary per file
File Description
pnpm-lock.yaml Updates lockfile for get-it v9 and related dependency graph changes.
packages/@sanity/eslint-config-cli/eslint.config.mjs Allows ReadableStream usage for Node engines required by get-it v9.
packages/@sanity/cli/test/setup.ts Mocks createRequester in tests to use globalThis.fetch for HTTP interception.
packages/@sanity/cli/src/services/graphql.ts Updates error handling to use HttpError from the new request layer.
packages/@sanity/cli/src/services/getUrlHeaders.ts Migrates HEAD request handling to v9 redirect/Headers behavior.
packages/@sanity/cli/src/commands/datasets/import.ts Updates dataset import source streaming to v9 as: 'stream' + Web→Node conversion.
packages/@sanity/cli/src/commands/datasets/tests/import.test.ts Adjusts request mocks for the new stream conversion helper.
packages/@sanity/cli/src/actions/backup/downloadStream.ts Adds shared backup streaming helper with retry + timeouts + deferred destination creation.
packages/@sanity/cli/src/actions/backup/downloadStream.test.ts Adds unit coverage for streaming, timeouts, retries, and cancellation behavior.
packages/@sanity/cli/src/actions/backup/downloadDocument.ts Refactors document download to use downloadStream() and returns string content.
packages/@sanity/cli/src/actions/backup/downloadAsset.ts Refactors asset download to use downloadStream() and simplify piping logic.
packages/@sanity/cli-test/src/mocks/cli-core/request.ts Updates request mocks for v9 exports and preserves HttpError instanceof behavior.
packages/@sanity/cli-test/package.json Adds get-it v9 as a dependency to support the mock’s re-export.
packages/@sanity/cli-core/src/request/nodeReadableFromWeb.ts Introduces Web ReadableStream → Node Readable adapter for v9 streaming responses.
packages/@sanity/cli-core/src/request/createRequester.ts Reworks requester creation around get-it v9 options + default headers/debug behavior.
packages/@sanity/cli-core/src/request/tests/nodeReadableFromWeb.test.ts Adds tests for stream conversion and cancellation/error propagation.
packages/@sanity/cli-core/src/request/tests/createRequester.test.ts Updates tests for v9 createRequester behavior, passthrough options, and header logic.
packages/@sanity/cli-core/src/_exports/request.ts Updates the public export surface to v9 types/helpers and middleware still available.
packages/@sanity/cli-core/README.md Updates documented exports to match the new request API surface.
packages/@sanity/cli-core/package.json Bumps get-it dependency to ^9.1.0.
packages/@sanity/cli-build/src/util/compareDependencyVersions.ts Updates HEAD request logic for v9 response shape and redirect handling.
packages/@sanity/cli-build/src/util/tests/compareDependencyVersions.test.ts Updates mocks to match v9 Headers + status response shape.
.changeset/pr-1534.md Adds changeset entries for the migration across affected packages.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Replace the hand-rolled requester mock with createMockFetch and vitest matchers.

Keep custom fetch stubs for stalled streaming bodies and cancellation spies.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1ff4e7b. Configure here.

Comment thread packages/@sanity/cli/src/actions/backup/downloadDocument.ts
Adopt structured {headers, total} timeouts for backup downloads.

Drive download stream tests fully through get-it/mock streamBody().

Migrate the new api service off removed v8 request options.

@rexxars rexxars left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sweet. Thanks for also help prove the mocks/api gaps in get-it v9!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants