diff --git a/package-lock.json b/package-lock.json index 1ea38bf1e22..ce73c82cf2b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -81,7 +81,6 @@ "multiparty": "4.2.3", "nanospinner": "1.2.2", "netlify-redirector": "0.5.0", - "node-fetch": "3.3.2", "normalize-package-data": "7.0.1", "open": "10.2.0", "p-filter": "4.1.0", diff --git a/package.json b/package.json index 11e364d8c10..a4f834ef5db 100644 --- a/package.json +++ b/package.json @@ -128,7 +128,6 @@ "multiparty": "4.2.3", "nanospinner": "1.2.2", "netlify-redirector": "0.5.0", - "node-fetch": "3.3.2", "normalize-package-data": "7.0.1", "open": "10.2.0", "p-filter": "4.1.0", diff --git a/src/commands/functions/functions-create.ts b/src/commands/functions/functions-create.ts index 36f2bcec074..bead66ff354 100644 --- a/src/commands/functions/functions-create.ts +++ b/src/commands/functions/functions-create.ts @@ -10,7 +10,7 @@ import { OptionValues } from 'commander' import { findUp } from 'find-up' import fuzzy from 'fuzzy' import inquirer from 'inquirer' -import fetch from 'node-fetch' + import { createSpinner } from 'nanospinner' import { fileExistsAsync } from '../../lib/fs.js' @@ -386,7 +386,13 @@ const downloadFromURL = async function (command, options, argumentName, function const res = await fetch(downloadUrl) const finalName = path.basename(name, '.js') === functionName ? `${nameToUse}.js` : name const dest = fs.createWriteStream(path.join(fnFolder, finalName)) - res.body?.pipe(dest) + if (res.body) { + for await (const chunk of res.body) { + dest.write(chunk) + } + + dest.end() + } } catch (error_) { throw new Error(`Error while retrieving ${downloadUrl} ${error_}`) } diff --git a/src/commands/functions/functions-invoke.ts b/src/commands/functions/functions-invoke.ts index 04a4788a9b4..77ab52f54e7 100644 --- a/src/commands/functions/functions-invoke.ts +++ b/src/commands/functions/functions-invoke.ts @@ -4,7 +4,6 @@ import path from 'path' import { OptionValues } from 'commander' import inquirer from 'inquirer' -import fetch from 'node-fetch' import { APIError, NETLIFYDEVWARN, chalk, logAndThrowError, exit } from '../../utils/command-helpers.js' import { BACKGROUND, CLOCKWORK_USERAGENT, getFunctions } from '../../utils/functions/index.js' diff --git a/src/lib/geo-location.ts b/src/lib/geo-location.ts index 49ff1878cb4..b16b1f4428b 100644 --- a/src/lib/geo-location.ts +++ b/src/lib/geo-location.ts @@ -1,4 +1,3 @@ -import fetch from 'node-fetch' import { type Geolocation, mockLocation } from '@netlify/dev-utils' const API_URL = 'https://netlifind.netlify.app' diff --git a/src/utils/live-tunnel.ts b/src/utils/live-tunnel.ts index 4708bd41647..39918666deb 100644 --- a/src/utils/live-tunnel.ts +++ b/src/utils/live-tunnel.ts @@ -1,6 +1,5 @@ import { platform } from 'process' -import fetch from 'node-fetch' import pWaitFor from 'p-wait-for' import { v4 as uuidv4 } from 'uuid' diff --git a/src/utils/read-repo-url.ts b/src/utils/read-repo-url.ts index 84fb40b7061..0793c74a110 100644 --- a/src/utils/read-repo-url.ts +++ b/src/utils/read-repo-url.ts @@ -1,7 +1,5 @@ import URL from 'url' -import fetch from 'node-fetch' - // supported repo host types const GITHUB = 'GitHub' diff --git a/src/utils/sites/utils.ts b/src/utils/sites/utils.ts index b60111a4b8a..75240df6307 100644 --- a/src/utils/sites/utils.ts +++ b/src/utils/sites/utils.ts @@ -1,4 +1,3 @@ -import fetch from 'node-fetch' import execa from 'execa' import { GitHubRepoResponse, logAndThrowError } from '../command-helpers.js' diff --git a/src/utils/telemetry/request.ts b/src/utils/telemetry/request.ts index e3c2bfb2b83..93481134642 100644 --- a/src/utils/telemetry/request.ts +++ b/src/utils/telemetry/request.ts @@ -2,8 +2,6 @@ // to run as a detached process import process from 'process' -import fetch from 'node-fetch' - import getPackageJson from '../get-cli-package-json.js' const { name, version } = await getPackageJson() diff --git a/tests/integration/commands/deploy/deploy.test.ts b/tests/integration/commands/deploy/deploy.test.ts index f3ddcd489e2..8e95a16abab 100644 --- a/tests/integration/commands/deploy/deploy.test.ts +++ b/tests/integration/commands/deploy/deploy.test.ts @@ -4,7 +4,7 @@ import { fileURLToPath } from 'url' import { load } from 'cheerio' import execa from 'execa' -import fetch from 'node-fetch' + import { afterAll, beforeAll, describe, expect, test } from 'vitest' import { callCli } from '../../utils/call-cli.js' diff --git a/tests/integration/commands/dev/dev-forms-and-redirects.test.ts b/tests/integration/commands/dev/dev-forms-and-redirects.test.ts index 12e6d0726ac..3b73f734284 100644 --- a/tests/integration/commands/dev/dev-forms-and-redirects.test.ts +++ b/tests/integration/commands/dev/dev-forms-and-redirects.test.ts @@ -4,9 +4,8 @@ import path from 'path' import type { HandlerEvent } from '@netlify/functions' import js from 'dedent' -import FormData from 'form-data' import getPort from 'get-port' -import fetch from 'node-fetch' + import { describe, test } from 'vitest' import { withDevServer } from '../../utils/dev-server.js' @@ -113,7 +112,7 @@ describe.concurrent('commands/dev-forms-and-redirects', () => { data: { ip: '::ffff:127.0.0.1', some: 'thing', - user_agent: 'node-fetch', + user_agent: 'node', }, human_fields: { Some: 'thing', @@ -316,7 +315,7 @@ describe.concurrent('commands/dev-forms-and-redirects', () => { await builder.build() await withDevServer({ cwd: builder.directory }, async (server) => { - const response = await fetch(`${server.url}/foo.html`, { follow: 0 }) + const response = await fetch(`${server.url}/foo.html`, { redirect: 'manual' }) t.expect(response).not.toHaveProperty('headers.location') t.expect(await response.text()).toEqual('

foo') }) diff --git a/tests/integration/commands/dev/dev-miscellaneous.test.ts b/tests/integration/commands/dev/dev-miscellaneous.test.ts index 709645b353c..90107e37b83 100644 --- a/tests/integration/commands/dev/dev-miscellaneous.test.ts +++ b/tests/integration/commands/dev/dev-miscellaneous.test.ts @@ -1,4 +1,3 @@ -import events from 'node:events' import { Buffer } from 'buffer' import path from 'path' import { platform } from 'process' @@ -8,7 +7,7 @@ import { setProperty } from 'dot-prop' import execa, { ExecaError } from 'execa' import getAvailablePort from 'get-port' import jwt from 'jsonwebtoken' -import fetch from 'node-fetch' + import { type TestContext, describe, test } from 'vitest' import type { HandlerEvent, HandlerContext } from '@netlify/functions' import type { Context as EdgeHandlerContext } from '@netlify/edge-functions' @@ -595,12 +594,17 @@ describe.concurrent('commands/dev-miscellaneous', () => { const stream = res.body expect(stream).not.toBeNull() + if (!stream) throw new Error('Expected a readable stream') let numberOfChunks = 0 - stream!.on('data', () => { + + const reader = stream.getReader() + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + while (true) { + const { done } = await reader.read() + if (done) break numberOfChunks += 1 - }) - await events.once(stream!, 'end') + } // streamed responses arrive in more than one batch expect(numberOfChunks).not.toBe(1) diff --git a/tests/integration/commands/dev/dev.config.test.ts b/tests/integration/commands/dev/dev.config.test.ts index e6aa6984b68..08cdf6ab1b0 100644 --- a/tests/integration/commands/dev/dev.config.test.ts +++ b/tests/integration/commands/dev/dev.config.test.ts @@ -1,11 +1,9 @@ import { Buffer } from 'node:buffer' import { version } from 'node:process' -import events from 'node:events' import type { HandlerEvent } from '@netlify/functions' -import FormData from 'form-data' import getPort from 'get-port' -import fetch from 'node-fetch' + import { gte } from 'semver' import { describe, test } from 'vitest' @@ -437,9 +435,8 @@ describe.concurrent('commands/dev/config', () => { await withDevServer({ cwd: builder.directory }, async (server) => { const form = new FormData() form.append('some', 'thing') - - const expectedBoundary = form.getBoundary() - const expectedResponseBody = form.getBuffer().toString('base64') + const rsp = new Response(form) + const expectedResponseBody = Buffer.from(await rsp.text()).toString('base64') const response = await fetch(`${server.url}/api/echo?ding=dong`, { method: 'POST', @@ -448,8 +445,10 @@ describe.concurrent('commands/dev/config', () => { const body = await response.json() t.expect(body).toHaveProperty('headers.host', `${server.host}:${server.port.toString()}`) - t.expect(body).toHaveProperty('headers.content-type', `multipart/form-data;boundary=${expectedBoundary}`) - t.expect(body).toHaveProperty('headers.content-length', '164') + t.expect((body as { headers: { 'content-type': string } }).headers['content-type']).toMatch( + /^multipart\/form-data; ?boundary=.+/, + ) + t.expect(body).toHaveProperty('headers.content-length', '126') t.expect(body).toHaveProperty('httpMethod', 'POST') t.expect(body).toHaveProperty('isBase64Encoded', true) t.expect(body).toHaveProperty('path', '/api/echo') @@ -521,15 +520,12 @@ describe.concurrent('commands/dev/config', () => { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const body = res.body! - body.on('data', (chunk: Buffer) => { + for await (const chunk of body) { const now = Date.now() - t.expect(now > lastTimestamp).toBe(true) - lastTimestamp = now - chunks.push(chunk.toString()) - }) - await events.once(body, 'end') + chunks.push(Buffer.from(chunk).toString()) + } t.expect(chunks).toStrictEqual(['one', 'two', 'three']) }) diff --git a/tests/integration/commands/dev/dev.test.ts b/tests/integration/commands/dev/dev.test.ts index 498a2be85cc..be38c864974 100644 --- a/tests/integration/commands/dev/dev.test.ts +++ b/tests/integration/commands/dev/dev.test.ts @@ -6,7 +6,7 @@ import process from 'process' import js from 'dedent' import jwt, { type JwtPayload } from 'jsonwebtoken' -import fetch from 'node-fetch' + import { describe, test } from 'vitest' import { withDevServer } from '../../utils/dev-server.js' @@ -243,7 +243,7 @@ describe.concurrent('command/dev', () => { 'Content-Type': 'application/x-www-form-urlencoded', }, body: 'param=value', - follow: 0, + redirect: 'manual', }) const postBody = await postResponse.json() t.expect(postBody).toHaveProperty('body', { param: 'value' }) @@ -311,7 +311,7 @@ describe.concurrent('command/dev', () => { 'Content-Type': 'application/x-www-form-urlencoded', }, body: 'param=value', - follow: 0, + redirect: 'manual', }), ]) const getBody = await getResponse.json() @@ -348,7 +348,7 @@ describe.concurrent('command/dev', () => { await withDevServer({ cwd: builder.directory }, async (server) => { const [response1, response2] = await Promise.all([ - fetch(`${server.url}/api/ping`, { follow: 0, redirect: 'manual' }), + fetch(`${server.url}/api/ping`, { redirect: 'manual' }), fetch(`${server.url}/api/ping`), ]) const response2Body = await response2.json() @@ -417,7 +417,7 @@ describe.concurrent('command/dev', () => { const response = await fetch(`${server.url}/api/echo`, { method: 'POST', body: 'param=value', - follow: 0, + redirect: 'manual', }) // Method Not Allowed diff --git a/tests/integration/commands/dev/edge-functions.test.ts b/tests/integration/commands/dev/edge-functions.test.ts index ab4683a8423..107ba7fdd6f 100644 --- a/tests/integration/commands/dev/edge-functions.test.ts +++ b/tests/integration/commands/dev/edge-functions.test.ts @@ -3,7 +3,7 @@ import { rename } from 'fs/promises' import { join } from 'path' import execa from 'execa' -import fetch from 'node-fetch' + import { describe, expect, test } from 'vitest' import { withDevServer } from '../../utils/dev-server.js' diff --git a/tests/integration/commands/dev/images.test.ts b/tests/integration/commands/dev/images.test.ts index 57e5a82e2aa..ff19626bd96 100644 --- a/tests/integration/commands/dev/images.test.ts +++ b/tests/integration/commands/dev/images.test.ts @@ -2,7 +2,6 @@ import fs from 'fs' import path from 'path' -import fetch from 'node-fetch' import { describe, test } from 'vitest' import { withDevServer } from '../../utils/dev-server.js' diff --git a/tests/integration/commands/dev/redirects.test.ts b/tests/integration/commands/dev/redirects.test.ts index 74f3315ee9e..d122f54d58f 100644 --- a/tests/integration/commands/dev/redirects.test.ts +++ b/tests/integration/commands/dev/redirects.test.ts @@ -1,4 +1,3 @@ -import fetch from 'node-fetch' import { describe, expect, test } from 'vitest' import { withDevServer } from '../../utils/dev-server.js' diff --git a/tests/integration/commands/dev/responses.dev.test.ts b/tests/integration/commands/dev/responses.dev.test.ts index 3ac82e477e7..519a6795cd5 100644 --- a/tests/integration/commands/dev/responses.dev.test.ts +++ b/tests/integration/commands/dev/responses.dev.test.ts @@ -2,7 +2,7 @@ import path from 'path' import type { HandlerEvent } from '@netlify/functions' -import fetch from 'node-fetch' + import { describe, test } from 'vitest' import { withDevServer } from '../../utils/dev-server.js' diff --git a/tests/integration/commands/dev/scheduled-functions.test.ts b/tests/integration/commands/dev/scheduled-functions.test.ts index d2063cf48d4..ce90edcfbd9 100644 --- a/tests/integration/commands/dev/scheduled-functions.test.ts +++ b/tests/integration/commands/dev/scheduled-functions.test.ts @@ -1,7 +1,7 @@ import { describe, expect, test } from 'vitest' import { FixtureTestContext, setupFixtureTests } from '../../utils/fixture.js' -import fetch from 'node-fetch' + import { pause } from '../../utils/pause.js' describe('scheduled functions', async () => { diff --git a/tests/integration/commands/functions-invoke/functions-invoke.test.ts b/tests/integration/commands/functions-invoke/functions-invoke.test.ts index 206ab20fbab..88f8e5f1e9a 100644 --- a/tests/integration/commands/functions-invoke/functions-invoke.test.ts +++ b/tests/integration/commands/functions-invoke/functions-invoke.test.ts @@ -1,4 +1,3 @@ -import fetch from 'node-fetch' import { describe, test } from 'vitest' import { FixtureTestContext, setupFixtureTests } from '../../utils/fixture.js' diff --git a/tests/integration/commands/functions-serve/functions-serve.test.ts b/tests/integration/commands/functions-serve/functions-serve.test.ts index d18f00fe775..2ac2182668b 100644 --- a/tests/integration/commands/functions-serve/functions-serve.test.ts +++ b/tests/integration/commands/functions-serve/functions-serve.test.ts @@ -2,7 +2,7 @@ import { killProcess } from '@netlify/dev-utils' import js from 'dedent' import execa from 'execa' import getPort from 'get-port' -import fetch from 'node-fetch' + import { describe, test } from 'vitest' import waitPort from 'wait-port' diff --git a/tests/integration/commands/functions-with-args/functions-with-args.test.ts b/tests/integration/commands/functions-with-args/functions-with-args.test.ts index 8279b23aa01..4854bc4b3ca 100644 --- a/tests/integration/commands/functions-with-args/functions-with-args.test.ts +++ b/tests/integration/commands/functions-with-args/functions-with-args.test.ts @@ -2,7 +2,7 @@ import path from 'node:path' import { fileURLToPath } from 'node:url' import type { HandlerEvent } from '@netlify/functions' -import fetch from 'node-fetch' + import { describe, test } from 'vitest' import js from 'dedent' import ts from 'dedent' diff --git a/tests/integration/framework-detection.test.ts b/tests/integration/framework-detection.test.ts index fe32530e507..a6ca693999a 100644 --- a/tests/integration/framework-detection.test.ts +++ b/tests/integration/framework-detection.test.ts @@ -1,5 +1,5 @@ import execa from 'execa' -import fetch from 'node-fetch' + import { describe, test } from 'vitest' import { cliPath } from './utils/cli-path.js' diff --git a/tests/integration/frameworks/hugo.test.ts b/tests/integration/frameworks/hugo.test.ts index d0bb720c6dc..b1921e7a265 100644 --- a/tests/integration/frameworks/hugo.test.ts +++ b/tests/integration/frameworks/hugo.test.ts @@ -1,7 +1,6 @@ import { expect, test } from 'vitest' import { FixtureTestContext, setupFixtureTests } from '../utils/fixture.js' -import fetch from 'node-fetch' setupFixtureTests('hugo-site', { devServer: true }, () => { test('should not infinite redirect when -d flag is passed', async ({ devServer }) => { diff --git a/tests/integration/rules-proxy.test.ts b/tests/integration/rules-proxy.test.ts index e70e76df639..c4247c02d22 100644 --- a/tests/integration/rules-proxy.test.ts +++ b/tests/integration/rules-proxy.test.ts @@ -6,7 +6,6 @@ import { afterAll, beforeAll, describe, expect, test } from 'vitest' import { createRewriter, getWatchers } from '../../src/utils/rules-proxy.js' -import fetch from 'node-fetch' import { createSiteBuilder, SiteBuilder } from './utils/site-builder.js' describe('rules-proxy', () => { diff --git a/tests/integration/serve/functions-go.test.ts b/tests/integration/serve/functions-go.test.ts index 9126467ca21..96526536b89 100644 --- a/tests/integration/serve/functions-go.test.ts +++ b/tests/integration/serve/functions-go.test.ts @@ -1,4 +1,3 @@ -import fetch from 'node-fetch' import { describe, test } from 'vitest' import { tryAndLogOutput, withDevServer } from '../utils/dev-server.js' diff --git a/tests/integration/serve/functions-rust.test.ts b/tests/integration/serve/functions-rust.test.ts index bc16040acfe..f8644e336d4 100644 --- a/tests/integration/serve/functions-rust.test.ts +++ b/tests/integration/serve/functions-rust.test.ts @@ -1,4 +1,3 @@ -import fetch from 'node-fetch' import { test } from 'vitest' import { tryAndLogOutput, withDevServer } from '../utils/dev-server.js' diff --git a/tests/unit/lib/functions/server.test.ts b/tests/unit/lib/functions/server.test.ts index fd3ba16e8d0..4371eea0806 100644 --- a/tests/unit/lib/functions/server.test.ts +++ b/tests/unit/lib/functions/server.test.ts @@ -6,7 +6,7 @@ import { join } from 'node:path' import { LocalState } from '@netlify/dev-utils' import express from 'express' -import fetch from 'node-fetch' + import { afterAll, beforeAll, describe, expect, test, vi } from 'vitest' import { FunctionsRegistry } from '../../../../src/lib/functions/registry.js' diff --git a/tests/unit/utils/gh-auth.test.ts b/tests/unit/utils/gh-auth.test.ts index 1186308ee8a..4a5fa294e80 100644 --- a/tests/unit/utils/gh-auth.test.ts +++ b/tests/unit/utils/gh-auth.test.ts @@ -1,5 +1,5 @@ import { fibonacci } from 'backoff' -import fetch from 'node-fetch' + import { afterAll, describe, expect, test, vi } from 'vitest' import { authWithNetlify } from '../../../src/utils/gh-auth.js'