Skip to content

fix(gax): remove node-fetch types and dependency - #9785

Open
aelmanaa wants to merge 1 commit into
googleapis:mainfrom
aelmanaa:fix/gax-drop-node-fetch-types
Open

aelmanaa wants to merge 1 commit into
googleapis:mainfrom
aelmanaa:fix/gax-drop-node-fetch-types

Conversation

@aelmanaa

Copy link
Copy Markdown

Removes the type-only node-fetch import from fallbackServiceStub, the follow-up gax-nodejs#1766 left for later ("In a follow-up we can remove node-fetch altogether"). The response of auth.fetch() is now typed as gaxios.GaxiosResponse, which is what google-auth-library 11 returns. Its body goes to pipeline() as a stream/web ReadableStream, a type-only import, with a comment on the two shapes it has at runtime. node-fetch is removed from google-gax's dependencies and from the gax entry in pnpm-lock.yaml.

google-gax never imported node-fetch at runtime. The compiled fallbackServiceStub.js is identical to main apart from one comment, and the declaration files are identical.

This doesn't remove node-fetch from users' dependency trees on its own. gaxios 8 still depends on it and loads it in Node.js, so it stays installed through google-auth-library and gcp-metadata until gaxios moves to native fetch (#9101, #8107).

Fixes #7679

fallbackServiceStub imported a Response type from node-fetch only to
type the response of auth.fetch(). Type it as gaxios.GaxiosResponse,
which google-auth-library returns, and pass the body to pipeline as a
stream/web ReadableStream. Remove node-fetch from google-gax's
dependencies. The compiled JavaScript is unchanged apart from a comment.

Fixes googleapis#7679

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@aelmanaa
aelmanaa requested a review from a team as a code owner October 30, 2026 21:09
@google-cla

google-cla Bot commented Oct 30, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@github-actions
github-actions Bot requested a review from danieljbruce October 30, 2026 21:10

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request removes the node-fetch dependency from the gax package, updating fallbackServiceStub.ts to use gaxios.GaxiosResponse and cast the response body to WebReadableStream. The feedback points out a potential runtime TypeError if response.body is null, and suggests validating its presence before passing it to pipeline.

Comment on lines 527 to +533
if (response.ok && rpc.responseStream) {
pipeline(
response.body as PipelineSource<unknown>,
// `GaxiosResponse` is typed as the DOM `Response`, but the body
// is a Node.js Readable when gaxios uses node-fetch and an async
// iterable web ReadableStream when it uses native fetch; either
// is a valid `pipeline` source in Node.js.
response.body as WebReadableStream,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

If response.body is null (which is possible according to the Response type definition, e.g., if the server returns an empty body or on certain network conditions), passing it directly to pipeline will cause a synchronous TypeError at runtime.

To prevent this and ensure robust error handling, we should check if response.body is present before calling pipeline. If it is missing, we can destroy the streamArrayParser with a GoogleError.

          if (response.ok && rpc.responseStream) {
            if (!response.body) {
              streamArrayParser.destroy(
                new GoogleError('Response body is empty')
              );
              return;
            }
            pipeline(
              // `GaxiosResponse` is typed as the DOM `Response`, but the body
              // is a Node.js Readable when gaxios uses node-fetch and an async
              // iterable web ReadableStream when it uses native fetch; either
              // is a valid `pipeline` source in Node.js.
              response.body as WebReadableStream,
References
  1. Always validate and reject missing or falsy arguments upfront before performing property checks, to prevent TypeErrors.

This branch has not been deployed

No deployments
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.

cleanup: finish removing node-fetch types from fallbackServiceStub

1 participant