diff --git a/.changeset/sixty-shirts-rescue.md b/.changeset/sixty-shirts-rescue.md new file mode 100644 index 0000000000..b6c1443eea --- /dev/null +++ b/.changeset/sixty-shirts-rescue.md @@ -0,0 +1,41 @@ +--- +'@backstage/plugin-auth-backend-module-cloudflare-access-provider': patch +'@backstage/plugin-auth-backend-module-bitbucket-server-provider': patch +'@backstage/plugin-search-backend-module-stack-overflow-collator': patch +'@backstage/plugin-scaffolder-backend-module-bitbucket-server': patch +'@backstage/plugin-scaffolder-backend-module-bitbucket-cloud': patch +'@backstage/plugin-catalog-backend-module-bitbucket-server': patch +'@backstage/plugin-auth-backend-module-microsoft-provider': patch +'@backstage/plugin-auth-backend-module-aws-alb-provider': patch +'@backstage/plugin-scaffolder-backend-module-bitbucket': patch +'@backstage/plugin-scaffolder-backend-module-gerrit': patch +'@backstage/plugin-scaffolder-backend-module-sentry': patch +'@backstage/plugin-catalog-backend-module-puppetdb': patch +'@backstage/plugin-scaffolder-backend-module-gitea': patch +'@backstage/plugin-catalog-backend-module-msgraph': patch +'@backstage/plugin-search-backend-module-techdocs': patch +'@backstage/plugin-catalog-backend-module-gerrit': patch +'@backstage/plugin-catalog-backend-module-gitlab': patch +'@backstage/plugin-search-backend-module-explore': patch +'@backstage/plugin-catalog-backend-module-azure': patch +'@backstage/plugin-notifications-backend': patch +'@backstage/plugin-notifications-node': patch +'@backstage/plugin-permission-backend': patch +'@backstage/backend-app-api': patch +'@backstage/plugin-devtools-backend': patch +'@backstage/plugin-techdocs-backend': patch +'@backstage/plugin-catalog-backend': patch +'@backstage/plugin-signals-backend': patch +'@backstage/config-loader': patch +'@backstage/plugin-proxy-backend': patch +'@backstage/plugin-auth-backend': patch +'@backstage/create-app': patch +'@backstage/plugin-app-backend': patch +'@backstage/plugin-auth-node': patch +'@backstage/cli': patch +'@backstage/backend-defaults': patch +'@backstage/plugin-catalog-backend-module-github': patch +'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch +--- + +Use native fetch instead of node-fetch diff --git a/contrib/scaffolder/template-testing-dry-run.md b/contrib/scaffolder/template-testing-dry-run.md index 70e0c572ab..12c4210ed6 100644 --- a/contrib/scaffolder/template-testing-dry-run.md +++ b/contrib/scaffolder/template-testing-dry-run.md @@ -26,7 +26,6 @@ import { readFile, writeFile } from 'node:fs/promises'; import { gzipSync } from 'node:zlib'; import { ensureDir } from 'fs-extra'; import { program } from 'commander'; -import fetch from 'node-fetch'; import ora from 'ora'; import readdir from 'recursive-readdir'; import { parse } from 'yaml'; diff --git a/docs/backend-system/core-services/discovery.md b/docs/backend-system/core-services/discovery.md index 455e398d8b..4324edbbf9 100644 --- a/docs/backend-system/core-services/discovery.md +++ b/docs/backend-system/core-services/discovery.md @@ -16,7 +16,6 @@ import { coreServices, createBackendPlugin, } from '@backstage/backend-plugin-api'; -import { fetch } from 'node-fetch'; createBackendPlugin({ pluginId: 'example', diff --git a/docs/backend-system/core-services/scheduler.md b/docs/backend-system/core-services/scheduler.md index e4c67a1199..154878ddfc 100644 --- a/docs/backend-system/core-services/scheduler.md +++ b/docs/backend-system/core-services/scheduler.md @@ -16,7 +16,6 @@ import { coreServices, createBackendPlugin, } from '@backstage/backend-plugin-api'; -import { fetch } from 'node-fetch'; createBackendPlugin({ pluginId: 'example', diff --git a/docs/plugins/integrating-search-into-plugins.md b/docs/plugins/integrating-search-into-plugins.md index 05d07feb08..e51b4cfefa 100644 --- a/docs/plugins/integrating-search-into-plugins.md +++ b/docs/plugins/integrating-search-into-plugins.md @@ -106,15 +106,12 @@ Imagine your FAQs can be retrieved at the URL `https://backstage.example.biz/faq Below we provide an example implementation of how the FAQ collator factory could look like using our new document type, placed in the `plugins/search-backend-module-faq-snippets-collator/src/factory.ts` file: ```ts -import fetch from 'node-fetch'; import { Readable } from 'stream'; - import { LoggerService, RootConfigService, } from '@backstage/backend-plugin-api'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; - import { FaqSnippetDocument } from './types'; const DEFAULT_BASE_URL = 'https://backstage.example.biz/faq-snippets'; diff --git a/package.json b/package.json index 400abeada2..741632db02 100644 --- a/package.json +++ b/package.json @@ -49,9 +49,9 @@ "storybook": "yarn ./storybook run storybook", "techdocs-cli": "node scripts/techdocs-cli.js", "techdocs-cli:dev": "cross-env TECHDOCS_CLI_DEV_MODE=true node scripts/techdocs-cli.js", - "test": "backstage-cli repo test", - "test:all": "backstage-cli repo test --coverage", - "test:e2e": "playwright test", + "test": "NODE_OPTIONS=--no-node-snapshot backstage-cli repo test", + "test:all": "NODE_OPTIONS=--no-node-snapshot backstage-cli repo test --coverage", + "test:e2e": "NODE_OPTIONS=--no-node-snapshot playwright test", "tsc": "tsc", "tsc:full": "backstage-cli repo clean && tsc --skipLibCheck false --incremental false" }, diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index d8c774c805..02adf569e3 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -71,7 +71,6 @@ "minimatch": "^9.0.0", "minimist": "^1.2.5", "morgan": "^1.10.0", - "node-fetch": "^2.7.0", "node-forge": "^1.3.1", "path-to-regexp": "^8.0.0", "selfsigned": "^2.0.0", diff --git a/packages/backend-defaults/report-urlReader.api.md b/packages/backend-defaults/report-urlReader.api.md index 4813643d68..efe4a9ae47 100644 --- a/packages/backend-defaults/report-urlReader.api.md +++ b/packages/backend-defaults/report-urlReader.api.md @@ -415,17 +415,29 @@ export interface ReadTreeResponseFactory { } // @public -export type ReadTreeResponseFactoryOptions = { - stream: Readable; - subpath?: string; - etag: string; - filter?: ( - path: string, - info?: { - size: number; - }, - ) => boolean; -}; +export type ReadTreeResponseFactoryOptions = + | { + stream: Readable; + subpath?: string; + etag: string; + filter?: ( + path: string, + info?: { + size: number; + }, + ) => boolean; + } + | { + response: Response; + subpath?: string; + etag?: string; + filter?: ( + path: string, + info?: { + size: number; + }, + ) => boolean; + }; // @public export class ReadUrlResponseFactory { @@ -437,6 +449,9 @@ export class ReadUrlResponseFactory { stream: Readable, options?: ReadUrlResponseFactoryFromStreamOptions, ): Promise; + static fromResponse( + response: Response, + ): Promise; } // @public diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.ts index 50513fcdcc..b46e7c20cd 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.ts @@ -32,9 +32,7 @@ import { ScmIntegrations, AzureIntegration, } from '@backstage/integration'; -import fetch, { Response } from 'node-fetch'; import { Minimatch } from 'minimatch'; -import { Readable } from 'stream'; import { NotFoundError, NotModifiedError } from '@backstage/errors'; import { ReadTreeResponseFactory, ReaderFactory } from './types'; import { ReadUrlResponseFactory } from './ReadUrlResponseFactory'; @@ -101,7 +99,7 @@ export class AzureUrlReader implements UrlReaderService { // for private repos when PAT is not valid, Azure API returns a http status code 203 with sign in page html if (response.ok && response.status !== 203) { - return ReadUrlResponseFactory.fromNodeJSReadable(response.body); + return ReadUrlResponseFactory.fromResponse(response); } const message = `${url} could not be read as ${builtUrl}, ${response.status} ${response.statusText}`; @@ -172,7 +170,7 @@ export class AzureUrlReader implements UrlReaderService { } return await this.deps.treeResponseFactory.fromZipArchive({ - stream: Readable.from(archiveAzureResponse.body), + response: archiveAzureResponse, etag: commitSha, filter, subpath, diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.ts index b7b733867e..f6742c7423 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.ts @@ -32,14 +32,11 @@ import { getBitbucketCloudRequestOptions, ScmIntegrations, } from '@backstage/integration'; -import fetch, { Response } from 'node-fetch'; import parseGitUrl from 'git-url-parse'; import { trimEnd } from 'lodash'; import { Minimatch } from 'minimatch'; -import { Readable } from 'stream'; import { ReaderFactory, ReadTreeResponseFactory } from './types'; import { ReadUrlResponseFactory } from './ReadUrlResponseFactory'; -import { parseLastModified } from './util'; /** * Implements a {@link @backstage/backend-plugin-api#UrlReaderService} for files from Bitbucket Cloud. @@ -116,12 +113,7 @@ export class BitbucketCloudUrlReader implements UrlReaderService { } if (response.ok) { - return ReadUrlResponseFactory.fromNodeJSReadable(response.body, { - etag: response.headers.get('ETag') ?? undefined, - lastModifiedAt: parseLastModified( - response.headers.get('Last-Modified'), - ), - }); + return ReadUrlResponseFactory.fromResponse(response); } const message = `${url} could not be read as ${bitbucketUrl}, ${response.status} ${response.statusText}`; @@ -159,7 +151,7 @@ export class BitbucketCloudUrlReader implements UrlReaderService { } return await this.deps.treeResponseFactory.fromTarArchive({ - stream: Readable.from(archiveResponse.body), + response: archiveResponse, subpath: filepath, etag: lastCommitShortHash, filter: options?.filter, diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.ts index 332e300cb8..c37cb59308 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.ts @@ -31,14 +31,11 @@ import { getBitbucketServerRequestOptions, ScmIntegrations, } from '@backstage/integration'; -import fetch, { Response } from 'node-fetch'; import parseGitUrl from 'git-url-parse'; import { trimEnd } from 'lodash'; import { Minimatch } from 'minimatch'; -import { Readable } from 'stream'; import { ReaderFactory, ReadTreeResponseFactory } from './types'; import { ReadUrlResponseFactory } from './ReadUrlResponseFactory'; -import { parseLastModified } from './util'; /** * Implements a {@link @backstage/backend-plugin-api#UrlReaderService} for files from Bitbucket Server APIs. @@ -107,12 +104,7 @@ export class BitbucketServerUrlReader implements UrlReaderService { } if (response.ok) { - return ReadUrlResponseFactory.fromNodeJSReadable(response.body, { - etag: response.headers.get('ETag') ?? undefined, - lastModifiedAt: parseLastModified( - response.headers.get('Last-Modified'), - ), - }); + return ReadUrlResponseFactory.fromResponse(response); } const message = `${url} could not be read as ${bitbucketUrl}, ${response.status} ${response.statusText}`; @@ -150,7 +142,7 @@ export class BitbucketServerUrlReader implements UrlReaderService { } return await this.deps.treeResponseFactory.fromTarArchive({ - stream: Readable.from(archiveResponse.body), + response: archiveResponse, subpath: filepath, etag: lastCommitShortHash, filter: options?.filter, diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.ts index 55d676ed91..c12998509e 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.ts @@ -32,15 +32,12 @@ import { getBitbucketRequestOptions, ScmIntegrations, } from '@backstage/integration'; -import fetch, { Response } from 'node-fetch'; import parseGitUrl from 'git-url-parse'; import { trimEnd } from 'lodash'; import { Minimatch } from 'minimatch'; -import { Readable } from 'stream'; import { LoggerService } from '@backstage/backend-plugin-api'; import { ReaderFactory, ReadTreeResponseFactory } from './types'; import { ReadUrlResponseFactory } from './ReadUrlResponseFactory'; -import { parseLastModified } from './util'; /** * Implements a {@link @backstage/backend-plugin-api#UrlReaderService} for files from Bitbucket v1 and v2 APIs, such @@ -127,12 +124,7 @@ export class BitbucketUrlReader implements UrlReaderService { } if (response.ok) { - return ReadUrlResponseFactory.fromNodeJSReadable(response.body, { - etag: response.headers.get('ETag') ?? undefined, - lastModifiedAt: parseLastModified( - response.headers.get('Last-Modified'), - ), - }); + return ReadUrlResponseFactory.fromResponse(response); } const message = `${url} could not be read as ${bitbucketUrl}, ${response.status} ${response.statusText}`; @@ -170,7 +162,7 @@ export class BitbucketUrlReader implements UrlReaderService { } return await this.deps.treeResponseFactory.fromTarArchive({ - stream: Readable.from(archiveBitbucketResponse.body), + response: archiveBitbucketResponse, subpath: filepath, etag: lastCommitShortHash, filter: options?.filter, diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/FetchUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/FetchUrlReader.ts index 55041cf036..0e5a279c4d 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/FetchUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/FetchUrlReader.ts @@ -22,11 +22,9 @@ import { UrlReaderServiceSearchResponse, } from '@backstage/backend-plugin-api'; import { NotFoundError, NotModifiedError } from '@backstage/errors'; -import fetch, { Response } from 'node-fetch'; import { ReaderFactory } from './types'; import path from 'path'; import { ReadUrlResponseFactory } from './ReadUrlResponseFactory'; -import { parseLastModified } from './util'; const isInRange = (num: number, [start, end]: [number, number]) => { return num >= start && num <= end; @@ -150,12 +148,7 @@ export class FetchUrlReader implements UrlReaderService { } if (response.ok) { - return ReadUrlResponseFactory.fromNodeJSReadable(response.body, { - etag: response.headers.get('ETag') ?? undefined, - lastModifiedAt: parseLastModified( - response.headers.get('Last-Modified'), - ), - }); + return ReadUrlResponseFactory.fromResponse(response); } const message = `could not read ${url}, ${response.status} ${response.statusText}`; diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.ts index d8471c43f3..502c2d2ff9 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.ts @@ -32,7 +32,6 @@ import { ScmIntegrations, } from '@backstage/integration'; import { ReaderFactory, ReadTreeResponseFactory } from './types'; -import fetch, { Response } from 'node-fetch'; import { ReadUrlResponseFactory } from './ReadUrlResponseFactory'; import { AuthenticationError, @@ -149,7 +148,7 @@ export class GiteaUrlReader implements UrlReaderService { const parsedUri = parseGiteaUrl(this.integration.config, url); return this.deps.treeResponseFactory.fromTarArchive({ - stream: Readable.from(response.body), + response: response, subpath: parsedUri.path, etag: lastCommitHash, filter: options?.filter, diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts index f5050cca5e..c1d8c02a53 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts @@ -34,11 +34,8 @@ import { import parseGitUrl from 'git-url-parse'; import { trimEnd, trimStart } from 'lodash'; import { Minimatch } from 'minimatch'; -import fetch, { Response } from 'node-fetch'; -import { Readable } from 'stream'; import { ReadUrlResponseFactory } from './ReadUrlResponseFactory'; import { ReadTreeResponseFactory, ReaderFactory } from './types'; -import { parseLastModified } from './util'; /** * Implements a {@link @backstage/backend-plugin-api#UrlReaderService} for files on GitLab. @@ -101,12 +98,7 @@ export class GitlabUrlReader implements UrlReaderService { } if (response.ok) { - return ReadUrlResponseFactory.fromNodeJSReadable(response.body, { - etag: response.headers.get('ETag') ?? undefined, - lastModifiedAt: parseLastModified( - response.headers.get('Last-Modified'), - ), - }); + return ReadUrlResponseFactory.fromResponse(response); } const message = `${url} could not be read as ${builtUrl}, ${response.status} ${response.statusText}`; @@ -228,7 +220,7 @@ export class GitlabUrlReader implements UrlReaderService { } return await this.deps.treeResponseFactory.fromTarArchive({ - stream: Readable.from(archiveGitLabResponse.body), + response: archiveGitLabResponse, subpath: filepath, etag: commitSha, filter: options?.filter, diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/ReadUrlResponseFactory.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/ReadUrlResponseFactory.ts index ecc1bd6101..1f4f297c5a 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/ReadUrlResponseFactory.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/ReadUrlResponseFactory.ts @@ -19,6 +19,7 @@ import { UrlReaderServiceReadUrlResponse } from '@backstage/backend-plugin-api'; import getRawBody from 'raw-body'; import { Readable } from 'stream'; import { ReadUrlResponseFactoryFromStreamOptions } from './types'; +import { parseLastModified, responseToReadable } from './util'; /** * Utility class for UrlReader implementations to create valid ReadUrlResponse @@ -28,7 +29,7 @@ import { ReadUrlResponseFactoryFromStreamOptions } from './types'; */ export class ReadUrlResponseFactory { /** - * Resolves a ReadUrlResponse from a Readable stream. + * Resolves a UrlReaderServiceReadUrlResponse from a Readable stream. */ static async fromReadable( stream: Readable, @@ -64,7 +65,7 @@ export class ReadUrlResponseFactory { } /** - * Resolves a ReadUrlResponse from an old-style NodeJS.ReadableStream. + * Resolves a UrlReaderServiceReadUrlResponse from an old-style NodeJS.ReadableStream. */ static async fromNodeJSReadable( oldStyleStream: NodeJS.ReadableStream, @@ -73,4 +74,21 @@ export class ReadUrlResponseFactory { const readable = Readable.from(oldStyleStream); return ReadUrlResponseFactory.fromReadable(readable, options); } + + /** + * Resolves a UrlReaderServiceReadUrlResponse from a native fetch response body. + */ + static async fromResponse( + response: Response, + ): Promise { + const etag = response.headers.get('etag') || undefined; + const lastModifiedAt = parseLastModified( + response.headers.get('last-modified'), + ); + + return ReadUrlResponseFactory.fromReadable(responseToReadable(response), { + etag, + lastModifiedAt, + }); + } } diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/ReadTreeResponseFactory.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/ReadTreeResponseFactory.ts index 1973b2158f..a8f187d7b8 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/ReadTreeResponseFactory.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/ReadTreeResponseFactory.ts @@ -15,6 +15,7 @@ */ import os from 'os'; +import { Readable } from 'stream'; import { Config } from '@backstage/config'; import { ReadTreeResponseFactoryOptions, @@ -25,6 +26,7 @@ import { TarArchiveResponse } from './TarArchiveResponse'; import { ZipArchiveResponse } from './ZipArchiveResponse'; import { ReadableArrayResponse } from './ReadableArrayResponse'; import { UrlReaderServiceReadTreeResponse } from '@backstage/backend-plugin-api'; +import { responseToReadable } from '../util'; export class DefaultReadTreeResponseFactory implements ReadTreeResponseFactory { static create(options: { config: Config }): DefaultReadTreeResponseFactory { @@ -41,11 +43,21 @@ export class DefaultReadTreeResponseFactory implements ReadTreeResponseFactory { stripFirstDirectory?: boolean; }, ): Promise { + let stream: Readable; + let etag: string; + if ('stream' in options) { + stream = options.stream; + etag = options.etag; + } else { + stream = responseToReadable(options.response); + etag = (options.etag ?? options.response.headers.get('etag')) || ''; + } + return new TarArchiveResponse( - options.stream, + stream, options.subpath ?? '', this.workDir, - options.etag, + etag, options.filter, options.stripFirstDirectory ?? true, ); @@ -54,11 +66,21 @@ export class DefaultReadTreeResponseFactory implements ReadTreeResponseFactory { async fromZipArchive( options: ReadTreeResponseFactoryOptions, ): Promise { + let stream: Readable; + let etag: string; + if ('stream' in options) { + stream = options.stream; + etag = options.etag; + } else { + stream = responseToReadable(options.response); + etag = (options.etag ?? options.response.headers.get('etag')) || ''; + } + return new ZipArchiveResponse( - options.stream, + stream, options.subpath ?? '', this.workDir, - options.etag, + etag, options.filter, ); } diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/types.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/types.ts index 5afbed178f..f8f03a6f3b 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/types.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/types.ts @@ -60,17 +60,28 @@ export type ReadUrlResponseFactoryFromStreamOptions = { * * @public */ -export type ReadTreeResponseFactoryOptions = { - // A binary stream of a tar archive. - stream: Readable; - // If unset, the files at the root of the tree will be read. - // subpath must not contain the name of the top level directory. - subpath?: string; - // etag of the blob - etag: string; - // Filter passed on from the ReadTreeOptions - filter?: (path: string, info?: { size: number }) => boolean; -}; +export type ReadTreeResponseFactoryOptions = + | { + // A binary stream of a tar archive. + stream: Readable; + // If unset, the files at the root of the tree will be read. + // subpath must not contain the name of the top level directory. + subpath?: string; + // etag of the blob + etag: string; + // Filter passed on from the ReadTreeOptions + filter?: (path: string, info?: { size: number }) => boolean; + } + | { + /** A response from a fetch request */ + response: Response; + /** If unset, the files at the root of the tree will be read. Subpath must not contain the name of the top level directory. */ + subpath?: string; + /** etag of the blob, to optionally override what the response header may or may not say */ + etag?: string; + /** Filter passed on from the ReadTreeOptions */ + filter?: (path: string, info?: { size: number }) => boolean; + }; /** * Options that control {@link ReadTreeResponseFactory.fromReadableArray} diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/util.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/util.ts index 3d65c2c527..bd19feef2d 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/util.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/util.ts @@ -14,10 +14,47 @@ * limitations under the License. */ -export function parseLastModified(value: string | null | undefined) { +import { PassThrough, Readable } from 'stream'; +import { ReadableStream as WebReadableStream } from 'stream/web'; + +export function parseLastModified( + value: string | null | undefined, +): Date | undefined { if (!value) { return undefined; } - return new Date(value); + try { + const result = new Date(value); + result.toISOString(); // triggers exception if input was invalid + return result; + } catch { + return undefined; + } +} + +export function responseToReadable(response: Response): Readable { + return response.body + ? Readable.from(toWeb(response.body)) + : new PassThrough().end(); +} + +// The NodeJS ReadableStream is that fetch returns is super basic and not even +// iterable. This function converts it to the smarter, iterable stream/web +// variant instead. +export function toWeb( + responseBody: ReadableStream, +): WebReadableStream { + const reader = responseBody.getReader(); + return new WebReadableStream({ + async pull(controller) { + const { value, done } = await reader.read(); + if (value) { + controller.enqueue(value); + } + if (done) { + controller.close(); + } + }, + }); } diff --git a/packages/backend-defaults/src/entrypoints/userInfo/DefaultUserInfoService.ts b/packages/backend-defaults/src/entrypoints/userInfo/DefaultUserInfoService.ts index 83bbba89b7..21f8de5631 100644 --- a/packages/backend-defaults/src/entrypoints/userInfo/DefaultUserInfoService.ts +++ b/packages/backend-defaults/src/entrypoints/userInfo/DefaultUserInfoService.ts @@ -22,7 +22,6 @@ import { } from '@backstage/backend-plugin-api'; import { ResponseError } from '@backstage/errors'; import { decodeJwt } from 'jose'; -import fetch from 'node-fetch'; import { toInternalBackstageCredentials } from '../auth/helpers'; export type Options = { diff --git a/packages/cli/package.json b/packages/cli/package.json index a0be58af83..0e2d49c02c 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -122,7 +122,6 @@ "lodash": "^4.17.21", "mini-css-extract-plugin": "^2.4.2", "minimatch": "^9.0.0", - "node-fetch": "^2.7.0", "node-libs-browser": "^2.2.1", "npm-packlist": "^5.0.0", "ora": "^5.3.0", diff --git a/packages/cli/src/commands/create-github-app/index.ts b/packages/cli/src/commands/create-github-app/index.ts index 681b471c91..105a6b4c24 100644 --- a/packages/cli/src/commands/create-github-app/index.ts +++ b/packages/cli/src/commands/create-github-app/index.ts @@ -20,7 +20,6 @@ import { stringify as stringifyYaml } from 'yaml'; import inquirer, { Question, Answers } from 'inquirer'; import { paths } from '../../lib/paths'; import { GithubCreateAppServer } from './GithubCreateAppServer'; -import fetch from 'node-fetch'; import openBrowser from 'react-dev-utils/openBrowser'; // This is an experimental command that at this point does not support GitHub Enterprise diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index 835807742c..6af437f0d8 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -49,7 +49,6 @@ "json-schema-traverse": "^1.0.0", "lodash": "^4.17.21", "minimist": "^1.2.5", - "node-fetch": "^2.7.0", "typescript-json-schema": "^0.65.0", "yaml": "^2.0.0" }, diff --git a/packages/config-loader/src/sources/RemoteConfigSource.ts b/packages/config-loader/src/sources/RemoteConfigSource.ts index 1492cd4d28..d8fa07d708 100644 --- a/packages/config-loader/src/sources/RemoteConfigSource.ts +++ b/packages/config-loader/src/sources/RemoteConfigSource.ts @@ -21,7 +21,6 @@ import { durationToMilliseconds, } from '@backstage/types'; import isEqual from 'lodash/isEqual'; -import fetch from 'node-fetch'; import { ConfigTransformer, createConfigTransformer } from './transform'; import { AsyncConfigSourceGenerator, @@ -137,7 +136,7 @@ export class RemoteConfigSource implements ConfigSource { async #load(signal?: AbortSignal): Promise { const res = await fetch(this.#url, { - signal: signal as import('node-fetch').RequestInit['signal'], + signal: signal as RequestInit['signal'], }); if (!res.ok) { throw await ResponseError.fromResponse(res); diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 1a88929fda..449c32a25e 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -49,7 +49,6 @@ "fs-extra": "^11.2.0", "handlebars": "^4.7.3", "inquirer": "^8.2.0", - "node-fetch": "^2.7.0", "ora": "^5.3.0", "recursive-readdir": "^2.2.2" }, @@ -61,7 +60,7 @@ "@types/inquirer": "^8.1.3", "@types/node": "^20.16.0", "@types/recursive-readdir": "^2.2.0", - "msw": "^1.0.0", + "msw": "^2.0.0", "nodemon": "^3.0.1" } } diff --git a/packages/create-app/src/lib/tasks.test.ts b/packages/create-app/src/lib/tasks.test.ts index 41c20854be..27c5765a12 100644 --- a/packages/create-app/src/lib/tasks.test.ts +++ b/packages/create-app/src/lib/tasks.test.ts @@ -33,7 +33,7 @@ import { createMockDirectory, registerMswTestHooks, } from '@backstage/backend-test-utils'; -import { rest } from 'msw'; +import { http, HttpResponse, delay } from 'msw'; import { setupServer } from 'msw/node'; jest.spyOn(Task, 'log').mockReturnValue(undefined); @@ -402,12 +402,10 @@ describe('tasks', () => { it('should fetch the yarn.lock seed file', async () => { worker.use( - rest.get( + http.get( 'https://raw.githubusercontent.com/backstage/backstage/master/packages/create-app/seed-yarn.lock', - (_, res, ctx) => - res( - ctx.status(200), - ctx.text(`# the-lockfile-header + () => + HttpResponse.text(`# the-lockfile-header // some comments // in the file @@ -418,7 +416,6 @@ describe('tasks', () => { "@backstage/cli@1.0.0": some info `), - ), ), ); @@ -438,9 +435,9 @@ describe('tasks', () => { it('should fail gracefully', async () => { worker.use( - rest.get( + http.get( 'https://raw.githubusercontent.com/backstage/backstage/master/packages/create-app/seed-yarn.lock', - (_, res, ctx) => res(ctx.status(404)), + () => new HttpResponse(null, { status: 404 }), ), ); @@ -453,9 +450,9 @@ describe('tasks', () => { it('should time out if it takes too long to fetch', async () => { worker.use( - rest.get( + http.get( 'https://raw.githubusercontent.com/backstage/backstage/master/packages/create-app/seed-yarn.lock', - (_, res, ctx) => res(ctx.delay(5000)), + () => delay(5000), ), ); diff --git a/packages/create-app/src/lib/tasks.ts b/packages/create-app/src/lib/tasks.ts index a47f5f2cb9..51308275a6 100644 --- a/packages/create-app/src/lib/tasks.ts +++ b/packages/create-app/src/lib/tasks.ts @@ -25,7 +25,6 @@ import { resolve as resolvePath, relative as relativePath, } from 'path'; -import fetch from 'node-fetch'; import { exec as execCb } from 'child_process'; import { packageVersions } from './versions'; import { promisify } from 'util'; diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index db1bee0146..7a3cba64d3 100644 --- a/plugins/app-backend/package.json +++ b/plugins/app-backend/package.json @@ -83,7 +83,6 @@ "@backstage/cli": "workspace:^", "@backstage/types": "workspace:^", "@types/supertest": "^2.0.8", - "node-fetch": "^2.7.0", "supertest": "^7.0.0" }, "configSchema": "config.d.ts" diff --git a/plugins/app-backend/src/service/appPlugin.test.ts b/plugins/app-backend/src/service/appPlugin.test.ts index fbb0747a64..068405c19c 100644 --- a/plugins/app-backend/src/service/appPlugin.test.ts +++ b/plugins/app-backend/src/service/appPlugin.test.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import fetch from 'node-fetch'; import { createMockDirectory, mockServices, diff --git a/plugins/auth-backend-module-aws-alb-provider/package.json b/plugins/auth-backend-module-aws-alb-provider/package.json index dbb3b28222..eff1e3e4dc 100644 --- a/plugins/auth-backend-module-aws-alb-provider/package.json +++ b/plugins/auth-backend-module-aws-alb-provider/package.json @@ -42,8 +42,7 @@ "@backstage/plugin-auth-backend": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", "jose": "^5.0.0", - "node-cache": "^5.1.2", - "node-fetch": "^2.7.0" + "node-cache": "^5.1.2" }, "devDependencies": { "@backstage/backend-test-utils": "workspace:^", diff --git a/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts b/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts index 24026e2c9c..5d06de60a0 100644 --- a/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts +++ b/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { KeyObject } from 'crypto'; import * as crypto from 'crypto'; import { JWTHeaderParameters, decodeJwt } from 'jose'; import NodeCache from 'node-cache'; -import fetch from 'node-fetch'; import { PassportProfile, ProfileInfo } from '@backstage/plugin-auth-node'; import { AuthenticationError } from '@backstage/errors'; diff --git a/plugins/auth-backend-module-bitbucket-server-provider/package.json b/plugins/auth-backend-module-bitbucket-server-provider/package.json index 65b8d15aec..171ec272d2 100644 --- a/plugins/auth-backend-module-bitbucket-server-provider/package.json +++ b/plugins/auth-backend-module-bitbucket-server-provider/package.json @@ -36,7 +36,6 @@ "dependencies": { "@backstage/backend-plugin-api": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", - "node-fetch": "^2.7.0", "passport": "^0.7.0", "passport-oauth2": "^1.6.1" }, diff --git a/plugins/auth-backend-module-bitbucket-server-provider/src/helpers.ts b/plugins/auth-backend-module-bitbucket-server-provider/src/helpers.ts index fc16253b27..26b45d1f6d 100644 --- a/plugins/auth-backend-module-bitbucket-server-provider/src/helpers.ts +++ b/plugins/auth-backend-module-bitbucket-server-provider/src/helpers.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import fetch from 'node-fetch'; import { PassportProfile } from '@backstage/plugin-auth-node'; export async function fetchProfile(options: { diff --git a/plugins/auth-backend-module-cloudflare-access-provider/package.json b/plugins/auth-backend-module-cloudflare-access-provider/package.json index d487292dd1..ca8e3c373d 100644 --- a/plugins/auth-backend-module-cloudflare-access-provider/package.json +++ b/plugins/auth-backend-module-cloudflare-access-provider/package.json @@ -39,8 +39,7 @@ "@backstage/errors": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", "express": "^4.18.2", - "jose": "^5.0.0", - "node-fetch": "^2.7.0" + "jose": "^5.0.0" }, "devDependencies": { "@backstage/backend-defaults": "workspace:^", diff --git a/plugins/auth-backend-module-cloudflare-access-provider/src/helpers.ts b/plugins/auth-backend-module-cloudflare-access-provider/src/helpers.ts index 3077258dd6..64f79f113a 100644 --- a/plugins/auth-backend-module-cloudflare-access-provider/src/helpers.ts +++ b/plugins/auth-backend-module-cloudflare-access-provider/src/helpers.ts @@ -23,7 +23,6 @@ import { } from '@backstage/errors'; import express from 'express'; import { createRemoteJWKSet, jwtVerify } from 'jose'; -import fetch, { Headers } from 'node-fetch'; import { CACHE_PREFIX, CF_JWT_HEADER, @@ -87,8 +86,7 @@ export class AuthHelper { // Only throw if both are not provided by Cloudflare Access since either // can be used. throw new AuthenticationError( - `Missing ${this.jwtHeaderName} and - ${this.authorizationCookieName} from Cloudflare Access`, + `Missing ${this.jwtHeaderName} and ${this.authorizationCookieName} from Cloudflare Access`, ); } diff --git a/plugins/auth-backend-module-microsoft-provider/package.json b/plugins/auth-backend-module-microsoft-provider/package.json index 728738cca8..6ccad4a6b9 100644 --- a/plugins/auth-backend-module-microsoft-provider/package.json +++ b/plugins/auth-backend-module-microsoft-provider/package.json @@ -38,7 +38,6 @@ "@backstage/plugin-auth-node": "workspace:^", "express": "^4.18.2", "jose": "^5.0.0", - "node-fetch": "^2.7.0", "passport-microsoft": "^1.0.0" }, "devDependencies": { diff --git a/plugins/auth-backend-module-microsoft-provider/src/strategy.ts b/plugins/auth-backend-module-microsoft-provider/src/strategy.ts index 910bd85d1d..3a89b19c87 100644 --- a/plugins/auth-backend-module-microsoft-provider/src/strategy.ts +++ b/plugins/auth-backend-module-microsoft-provider/src/strategy.ts @@ -16,7 +16,6 @@ import { PassportProfile } from '@backstage/plugin-auth-node'; import { decodeJwt } from 'jose'; -import fetch from 'node-fetch'; import { Strategy as MicrosoftStrategy } from 'passport-microsoft'; export class ExtendedMicrosoftStrategy extends MicrosoftStrategy { @@ -103,9 +102,9 @@ export class ExtendedMicrosoftStrategy extends MicrosoftStrategy { }, }, ); - const data = await res.buffer(); + const data = await res.arrayBuffer(); - return `data:image/jpeg;base64,${data.toString('base64')}`; + return `data:image/jpeg;base64,${Buffer.from(data).toString('base64')}`; } catch (error) { return undefined; } diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 276c135093..99f520a5f6 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -89,7 +89,6 @@ "minimatch": "^9.0.0", "morgan": "^1.10.0", "node-cache": "^5.1.2", - "node-fetch": "^2.7.0", "openid-client": "^5.2.1", "passport": "^0.7.0", "passport-auth0": "^1.4.3", diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index 00731aeb08..74509b3085 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -49,7 +49,6 @@ "express": "^4.17.1", "jose": "^5.0.0", "lodash": "^4.17.21", - "node-fetch": "^2.7.0", "passport": "^0.7.0", "winston": "^3.2.1", "zod": "^3.22.4", diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index 58127f1bd7..6e3939e3c7 100644 --- a/plugins/catalog-backend-module-azure/package.json +++ b/plugins/catalog-backend-module-azure/package.json @@ -58,7 +58,6 @@ "@backstage/integration": "workspace:^", "@backstage/plugin-catalog-common": "workspace:^", "@backstage/plugin-catalog-node": "workspace:^", - "node-fetch": "^2.7.0", "uuid": "^11.0.0" }, "devDependencies": { diff --git a/plugins/catalog-backend-module-azure/src/lib/azure.ts b/plugins/catalog-backend-module-azure/src/lib/azure.ts index 3bdff90110..0b0d89c15b 100644 --- a/plugins/catalog-backend-module-azure/src/lib/azure.ts +++ b/plugins/catalog-backend-module-azure/src/lib/azure.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import fetch from 'node-fetch'; import { AzureDevOpsCredentialsProvider, AzureIntegrationConfig, diff --git a/plugins/catalog-backend-module-bitbucket-server/package.json b/plugins/catalog-backend-module-bitbucket-server/package.json index 06333e4583..1f8f8ae8e8 100644 --- a/plugins/catalog-backend-module-bitbucket-server/package.json +++ b/plugins/catalog-backend-module-bitbucket-server/package.json @@ -56,8 +56,6 @@ "@backstage/errors": "workspace:^", "@backstage/integration": "workspace:^", "@backstage/plugin-catalog-node": "workspace:^", - "@types/node-fetch": "^2.5.12", - "node-fetch": "^2.7.0", "uuid": "^11.0.0" }, "devDependencies": { diff --git a/plugins/catalog-backend-module-bitbucket-server/report.api.md b/plugins/catalog-backend-module-bitbucket-server/report.api.md index b2a0a9368a..0da9b78139 100644 --- a/plugins/catalog-backend-module-bitbucket-server/report.api.md +++ b/plugins/catalog-backend-module-bitbucket-server/report.api.md @@ -11,7 +11,6 @@ import { EntityProvider } from '@backstage/plugin-catalog-node'; import { EntityProviderConnection } from '@backstage/plugin-catalog-node'; import { LocationSpec } from '@backstage/plugin-catalog-node'; import { LoggerService } from '@backstage/backend-plugin-api'; -import { Response as Response_2 } from 'node-fetch'; import { SchedulerService } from '@backstage/backend-plugin-api'; import { SchedulerServiceTaskRunner } from '@backstage/backend-plugin-api'; @@ -27,7 +26,7 @@ export class BitbucketServerClient { projectKey: string; repo: string; path: string; - }): Promise; + }): Promise; // (undocumented) getRepository(options: { projectKey: string; diff --git a/plugins/catalog-backend-module-bitbucket-server/src/lib/BitbucketServerClient.ts b/plugins/catalog-backend-module-bitbucket-server/src/lib/BitbucketServerClient.ts index b5baf66afd..ee2caf7ffd 100644 --- a/plugins/catalog-backend-module-bitbucket-server/src/lib/BitbucketServerClient.ts +++ b/plugins/catalog-backend-module-bitbucket-server/src/lib/BitbucketServerClient.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import fetch, { Request, Response } from 'node-fetch'; import { BitbucketServerIntegrationConfig, getBitbucketServerRequestOptions, diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index 1a09a17e36..a70cc478a1 100644 --- a/plugins/catalog-backend-module-gerrit/package.json +++ b/plugins/catalog-backend-module-gerrit/package.json @@ -53,7 +53,6 @@ "@backstage/integration": "workspace:^", "@backstage/plugin-catalog-node": "workspace:^", "fs-extra": "^11.2.0", - "node-fetch": "^2.7.0", "uuid": "^11.0.0" }, "devDependencies": { diff --git a/plugins/catalog-backend-module-gerrit/src/providers/GerritEntityProvider.ts b/plugins/catalog-backend-module-gerrit/src/providers/GerritEntityProvider.ts index bd03b90c52..2bd5b4e3ce 100644 --- a/plugins/catalog-backend-module-gerrit/src/providers/GerritEntityProvider.ts +++ b/plugins/catalog-backend-module-gerrit/src/providers/GerritEntityProvider.ts @@ -22,7 +22,6 @@ import { LocationSpec, locationSpecToLocationEntity, } from '@backstage/plugin-catalog-node'; -import fetch, { Response } from 'node-fetch'; import { GerritIntegration, getGerritProjectsApiUrl, diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index 0407bd1f9c..ef8c40c75d 100644 --- a/plugins/catalog-backend-module-github/package.json +++ b/plugins/catalog-backend-module-github/package.json @@ -66,7 +66,6 @@ "git-url-parse": "^15.0.0", "lodash": "^4.17.21", "minimatch": "^9.0.0", - "node-fetch": "^2.7.0", "uuid": "^11.0.0" }, "devDependencies": { @@ -74,7 +73,7 @@ "@backstage/cli": "workspace:^", "@types/lodash": "^4.14.151", "luxon": "^3.0.0", - "msw": "^1.0.0" + "msw": "^2.0.0" }, "configSchema": "config.d.ts" } diff --git a/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts b/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts index 29c8cbc66d..d3be18f489 100644 --- a/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts +++ b/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts @@ -39,7 +39,7 @@ import { mockServices, } from '@backstage/backend-test-utils'; import { setupServer } from 'msw/node'; -import { rest } from 'msw'; +import { http, HttpResponse } from 'msw'; import { ConfigReader } from '@backstage/config'; const server = setupServer(); @@ -67,10 +67,9 @@ describe('GithubLocationAnalyzer', () => { beforeEach(() => { server.use( - rest.post('http://localhost:7007/locations', async (_, res, ctx) => { - return res( - ctx.status(201), - ctx.json({ + http.post('http://localhost:7007/locations', () => + HttpResponse.json( + { location: 'test', exists: false, entities: [ @@ -100,9 +99,10 @@ describe('GithubLocationAnalyzer', () => { }, }, ], - }), - ); - }), + }, + { status: 201 }, + ), + ), ); octokit.repos.get.mockResolvedValue({ diff --git a/plugins/catalog-backend-module-github/src/lib/github.test.ts b/plugins/catalog-backend-module-github/src/lib/github.test.ts index 9eae9e1161..cbe8d8c525 100644 --- a/plugins/catalog-backend-module-github/src/lib/github.test.ts +++ b/plugins/catalog-backend-module-github/src/lib/github.test.ts @@ -17,7 +17,7 @@ import { registerMswTestHooks } from '@backstage/backend-test-utils'; import { GroupEntity, UserEntity } from '@backstage/catalog-model'; import { graphql as graphqlOctokit } from '@octokit/graphql'; -import { graphql as graphqlMsw } from 'msw'; +import { graphql as graphqlMsw, HttpResponse } from 'msw'; import { setupServer } from 'msw/node'; import { TeamTransformer, UserTransformer } from './defaultTransformers'; import { @@ -33,14 +33,13 @@ import { createRemoveEntitiesOperation, createReplaceEntitiesOperation, } from './github'; -import fetch from 'node-fetch'; describe('github', () => { - const graphql = graphqlOctokit.defaults({ request: { fetch } }); - const server = setupServer(); registerMswTestHooks(server); + const graphql = graphqlOctokit.defaults({}); + describe('getOrganizationUsers using defaultUserMapper', () => { it('reads members', async () => { const input: QueryResponse = { @@ -73,7 +72,7 @@ describe('github', () => { }; server.use( - graphqlMsw.query('users', (_req, res, ctx) => res(ctx.data(input))), + graphqlMsw.query('users', () => HttpResponse.json({ data: input })), ); await expect( @@ -136,7 +135,7 @@ describe('github', () => { }; server.use( - graphqlMsw.query('users', (_req, res, ctx) => res(ctx.data(input))), + graphqlMsw.query('users', () => HttpResponse.json({ data: input })), ); await expect( @@ -180,7 +179,7 @@ describe('github', () => { }; server.use( - graphqlMsw.query('users', (_req, res, ctx) => res(ctx.data(input))), + graphqlMsw.query('users', () => HttpResponse.json({ data: input })), ); const users = await getOrganizationUsers( @@ -255,7 +254,7 @@ describe('github', () => { }; server.use( - graphqlMsw.query('teams', (_req, res, ctx) => res(ctx.data(input))), + graphqlMsw.query('teams', () => HttpResponse.json({ data: input })), ); await expect(getOrganizationTeams(graphql, 'a')).resolves.toEqual(output); @@ -355,7 +354,7 @@ describe('github', () => { }; server.use( - graphqlMsw.query('teams', (_req, res, ctx) => res(ctx.data(input))), + graphqlMsw.query('teams', () => HttpResponse.json({ data: input })), ); await expect( @@ -435,7 +434,7 @@ describe('github', () => { }; server.use( - graphqlMsw.query('teams', (_req, res, ctx) => res(ctx.data(input))), + graphqlMsw.query('teams', () => HttpResponse.json({ data: input })), ); const teams = await getOrganizationTeams( @@ -471,7 +470,7 @@ describe('github', () => { }; server.use( - graphqlMsw.query('orgs', (_req, res, ctx) => res(ctx.data(input))), + graphqlMsw.query('orgs', () => HttpResponse.json({ data: input })), ); await expect(getOrganizationsFromUser(graphql, 'foo')).resolves.toEqual({ @@ -500,7 +499,7 @@ describe('github', () => { }; server.use( - graphqlMsw.query('members', (_req, res, ctx) => res(ctx.data(input))), + graphqlMsw.query('members', () => HttpResponse.json({ data: input })), ); await expect(getTeamMembers(graphql, 'a', 'b')).resolves.toEqual(output); @@ -587,8 +586,8 @@ describe('github', () => { }; server.use( - graphqlMsw.query('repositories', (_req, res, ctx) => - res(ctx.data(input)), + graphqlMsw.query('repositories', () => + HttpResponse.json({ data: input }), ), ); diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json index 237af6101a..321b9519ab 100644 --- a/plugins/catalog-backend-module-gitlab/package.json +++ b/plugins/catalog-backend-module-gitlab/package.json @@ -61,7 +61,6 @@ "@backstage/plugin-events-node": "workspace:^", "@gitbeaker/rest": "^40.0.3", "lodash": "^4.17.21", - "node-fetch": "^2.7.0", "uuid": "^11.0.0" }, "devDependencies": { diff --git a/plugins/catalog-backend-module-gitlab/src/lib/client.ts b/plugins/catalog-backend-module-gitlab/src/lib/client.ts index f2ce3d18f8..4003ee5ea7 100644 --- a/plugins/catalog-backend-module-gitlab/src/lib/client.ts +++ b/plugins/catalog-backend-module-gitlab/src/lib/client.ts @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { getGitLabRequestOptions, GitLabIntegrationConfig, } from '@backstage/integration'; -import fetch from 'node-fetch'; import { LoggerService } from '@backstage/backend-plugin-api'; - import { GitLabDescendantGroupsResponse, GitLabGroup, diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index ca89356a5e..f99175da59 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -58,9 +58,7 @@ "@backstage/plugin-catalog-common": "workspace:^", "@backstage/plugin-catalog-node": "workspace:^", "@microsoft/microsoft-graph-types": "^2.6.0", - "@types/node-fetch": "^2.5.12", "lodash": "^4.17.21", - "node-fetch": "^2.7.0", "p-limit": "^3.0.2", "qs": "^6.9.4", "uuid": "^11.0.0" diff --git a/plugins/catalog-backend-module-msgraph/report.api.md b/plugins/catalog-backend-module-msgraph/report.api.md index 35ae148a25..912ca16e85 100644 --- a/plugins/catalog-backend-module-msgraph/report.api.md +++ b/plugins/catalog-backend-module-msgraph/report.api.md @@ -17,7 +17,6 @@ import { LoggerService } from '@backstage/backend-plugin-api'; import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; import { OrganizationTransformer as OrganizationTransformer_2 } from '@backstage/plugin-catalog-backend-module-msgraph'; import { ProviderConfigTransformer as ProviderConfigTransformer_2 } from '@backstage/plugin-catalog-backend-module-msgraph'; -import { Response as Response_2 } from 'node-fetch'; import { SchedulerService } from '@backstage/backend-plugin-api'; import { SchedulerServiceTaskRunner } from '@backstage/backend-plugin-api'; import { SchedulerServiceTaskScheduleDefinition } from '@backstage/backend-plugin-api'; @@ -114,7 +113,7 @@ export class MicrosoftGraphClient { path: string, query?: ODataQuery, headers?: Record, - ): Promise; + ): Promise; requestCollection( path: string, query?: ODataQuery, @@ -124,7 +123,7 @@ export class MicrosoftGraphClient { url: string, headers?: Record, retryCount?: number, - ): Promise; + ): Promise; } // @public diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.ts index 2dc2a65135..aa2d735a07 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.ts @@ -20,7 +20,6 @@ import { ClientSecretCredential, } from '@azure/identity'; import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; -import fetch, { Response } from 'node-fetch'; import qs from 'qs'; import { MicrosoftGraphProviderConfig } from './config'; diff --git a/plugins/catalog-backend-module-puppetdb/package.json b/plugins/catalog-backend-module-puppetdb/package.json index e30db2ed1d..c4102d045d 100644 --- a/plugins/catalog-backend-module-puppetdb/package.json +++ b/plugins/catalog-backend-module-puppetdb/package.json @@ -61,7 +61,6 @@ "@backstage/types": "workspace:^", "lodash": "^4.17.21", "luxon": "^3.0.0", - "node-fetch": "^2.7.0", "uuid": "^11.0.0" }, "devDependencies": { diff --git a/plugins/catalog-backend-module-puppetdb/src/puppet/read.ts b/plugins/catalog-backend-module-puppetdb/src/puppet/read.ts index 18a6eb077f..891b19691a 100644 --- a/plugins/catalog-backend-module-puppetdb/src/puppet/read.ts +++ b/plugins/catalog-backend-module-puppetdb/src/puppet/read.ts @@ -18,7 +18,6 @@ import { PuppetDbEntityProviderConfig } from '../providers'; import { PuppetNode, ResourceTransformer } from './types'; import { ResourceEntity } from '@backstage/catalog-model'; import { defaultResourceTransformer } from './transformers'; -import fetch from 'node-fetch'; import { ResponseError } from '@backstage/errors'; import { ENDPOINT_FACTSETS } from './constants'; import { LoggerService } from '@backstage/backend-plugin-api'; diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 0d5590dc63..05a28fef4a 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -89,7 +89,6 @@ "lodash": "^4.17.21", "luxon": "^3.0.0", "minimatch": "^9.0.0", - "node-fetch": "^2.7.0", "p-limit": "^3.0.2", "prom-client": "^15.0.0", "uuid": "^11.0.0", diff --git a/plugins/devtools-backend/package.json b/plugins/devtools-backend/package.json index cbba88213b..19b28713ad 100644 --- a/plugins/devtools-backend/package.json +++ b/plugins/devtools-backend/package.json @@ -55,7 +55,6 @@ "express-promise-router": "^4.1.0", "fs-extra": "^11.0.0", "lodash": "^4.17.21", - "node-fetch": "^2.7.0", "ping": "^0.4.1", "semver": "^7.5.3", "yn": "^4.0.0" diff --git a/plugins/devtools-backend/src/api/DevToolsBackendApi.ts b/plugins/devtools-backend/src/api/DevToolsBackendApi.ts index ae687f3cb0..5ecc3327e0 100644 --- a/plugins/devtools-backend/src/api/DevToolsBackendApi.ts +++ b/plugins/devtools-backend/src/api/DevToolsBackendApi.ts @@ -24,9 +24,7 @@ import { ExternalDependencyStatus, PackageDependency, } from '@backstage/plugin-devtools-common'; - import { JsonObject } from '@backstage/types'; -import fetch from 'node-fetch'; import { findPaths } from '@backstage/cli-common'; import { getPackages } from '@manypkg/get-packages'; import ping from 'ping'; diff --git a/plugins/notifications-backend/package.json b/plugins/notifications-backend/package.json index cd00bc6de0..6d3c505a4d 100644 --- a/plugins/notifications-backend/package.json +++ b/plugins/notifications-backend/package.json @@ -53,7 +53,6 @@ "express": "^4.17.1", "express-promise-router": "^4.1.0", "knex": "^3.0.0", - "node-fetch": "^2.7.0", "uuid": "^11.0.0", "winston": "^3.2.1", "yn": "^4.0.0" diff --git a/plugins/notifications-node/package.json b/plugins/notifications-node/package.json index 5969807cac..8144c815c1 100644 --- a/plugins/notifications-node/package.json +++ b/plugins/notifications-node/package.json @@ -43,7 +43,6 @@ "@backstage/plugin-notifications-common": "workspace:^", "@backstage/plugin-signals-node": "workspace:^", "knex": "^3.0.0", - "node-fetch": "^2.7.0", "uuid": "^11.0.0" }, "devDependencies": { diff --git a/plugins/notifications-node/src/service/DefaultNotificationService.ts b/plugins/notifications-node/src/service/DefaultNotificationService.ts index 7a46e01689..8ea58f22d3 100644 --- a/plugins/notifications-node/src/service/DefaultNotificationService.ts +++ b/plugins/notifications-node/src/service/DefaultNotificationService.ts @@ -17,7 +17,6 @@ import { NotificationService } from './NotificationService'; import { AuthService, DiscoveryService } from '@backstage/backend-plugin-api'; import { NotificationPayload } from '@backstage/plugin-notifications-common'; -import fetch from 'node-fetch'; /** @public */ export type NotificationServiceOptions = { diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index cdc791db73..ea9f4a10eb 100644 --- a/plugins/permission-backend/package.json +++ b/plugins/permission-backend/package.json @@ -63,7 +63,6 @@ "express": "^4.17.1", "express-promise-router": "^4.1.0", "lodash": "^4.17.21", - "node-fetch": "^2.7.0", "yn": "^4.0.0", "zod": "^3.22.4" }, diff --git a/plugins/permission-backend/src/service/PermissionIntegrationClient.ts b/plugins/permission-backend/src/service/PermissionIntegrationClient.ts index 767c7e9dd1..21d2f66887 100644 --- a/plugins/permission-backend/src/service/PermissionIntegrationClient.ts +++ b/plugins/permission-backend/src/service/PermissionIntegrationClient.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import fetch from 'node-fetch'; import { z } from 'zod'; import { AuthorizeResult, diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index e959f68d9f..d2397f54d5 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -77,8 +77,7 @@ "@backstage/errors": "workspace:^", "@types/http-proxy-middleware": "^1.0.0", "@types/yup": "^0.32.0", - "msw": "^2.0.0", - "node-fetch": "^2.7.0" + "msw": "^2.0.0" }, "configSchema": "config.d.ts" } diff --git a/plugins/proxy-backend/src/service/router.config.test.ts b/plugins/proxy-backend/src/service/router.config.test.ts index be26ddb9bc..d862107e00 100644 --- a/plugins/proxy-backend/src/service/router.config.test.ts +++ b/plugins/proxy-backend/src/service/router.config.test.ts @@ -29,7 +29,6 @@ import { } from '@backstage/config-loader'; import { HttpResponse, http, passthrough } from 'msw'; import { setupServer } from 'msw/node'; -import fetch from 'node-fetch'; // this test is stored in its own file to work around the mocked // http-proxy-middleware module used in the main test file diff --git a/plugins/proxy-backend/src/service/router.credentials.test.ts b/plugins/proxy-backend/src/service/router.credentials.test.ts index a48b18e8e2..6d1f529b30 100644 --- a/plugins/proxy-backend/src/service/router.credentials.test.ts +++ b/plugins/proxy-backend/src/service/router.credentials.test.ts @@ -25,7 +25,6 @@ import { ResponseError } from '@backstage/errors'; import { JsonObject } from '@backstage/types'; import { HttpResponse, http, passthrough } from 'msw'; import { setupServer } from 'msw/node'; -import fetch from 'node-fetch'; // this test is stored in its own file to work around the mocked // http-proxy-middleware module used in the main test file diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/package.json b/plugins/scaffolder-backend-module-bitbucket-cloud/package.json index 448de9a886..ccb4af756f 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/package.json +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/package.json @@ -49,7 +49,6 @@ "@backstage/plugin-bitbucket-cloud-common": "workspace:^", "@backstage/plugin-scaffolder-node": "workspace:^", "fs-extra": "^11.2.0", - "node-fetch": "^2.7.0", "yaml": "^2.0.0" }, "devDependencies": { diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.ts b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.ts index 71eacea955..00c27f6a54 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.ts +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.ts @@ -22,7 +22,6 @@ import { getRepoSourceDirectory, parseRepoUrl, } from '@backstage/plugin-scaffolder-node'; -import fetch, { Response, RequestInit } from 'node-fetch'; import { Config } from '@backstage/config'; import { getAuthorizationHeader } from './helpers'; diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.ts b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.ts index c44fdcc824..8525774692 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.ts +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.ts @@ -16,7 +16,6 @@ import { examples } from './bitbucketCloudPipelinesRun.examples'; import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; -import fetch, { Response } from 'node-fetch'; import * as inputProps from './inputProperties'; import { ScmIntegrationRegistry } from '@backstage/integration'; import { getAuthorizationHeader } from './helpers'; diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPullRequest.ts b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPullRequest.ts index 99a78c7c26..c70089abc2 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPullRequest.ts +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPullRequest.ts @@ -24,7 +24,6 @@ import { cloneRepo, parseRepoUrl, } from '@backstage/plugin-scaffolder-node'; -import fetch, { RequestInit, Response } from 'node-fetch'; import { Config } from '@backstage/config'; import fs from 'fs-extra'; import { getAuthorizationHeader } from './helpers'; diff --git a/plugins/scaffolder-backend-module-bitbucket-server/package.json b/plugins/scaffolder-backend-module-bitbucket-server/package.json index 46806d4e52..4ac251e5ed 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/package.json +++ b/plugins/scaffolder-backend-module-bitbucket-server/package.json @@ -48,7 +48,6 @@ "@backstage/integration": "workspace:^", "@backstage/plugin-scaffolder-node": "workspace:^", "fs-extra": "^11.2.0", - "node-fetch": "^2.7.0", "yaml": "^2.0.0" }, "devDependencies": { diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.ts index 413984aff5..612d090547 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.ts +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.ts @@ -25,7 +25,6 @@ import { getRepoSourceDirectory, parseRepoUrl, } from '@backstage/plugin-scaffolder-node'; -import fetch, { Response, RequestInit } from 'node-fetch'; import { Config } from '@backstage/config'; import { examples } from './bitbucketServer.examples'; diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.ts index 69e9dfe7bf..5b00f15ac2 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.ts +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.ts @@ -27,7 +27,6 @@ import { cloneRepo, parseRepoUrl, } from '@backstage/plugin-scaffolder-node'; -import fetch, { RequestInit, Response } from 'node-fetch'; import { Config } from '@backstage/config'; import fs from 'fs-extra'; import { examples } from './bitbucketServerPullRequest.examples'; diff --git a/plugins/scaffolder-backend-module-bitbucket/package.json b/plugins/scaffolder-backend-module-bitbucket/package.json index 494f7cee0c..914539ba8e 100644 --- a/plugins/scaffolder-backend-module-bitbucket/package.json +++ b/plugins/scaffolder-backend-module-bitbucket/package.json @@ -50,7 +50,6 @@ "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "workspace:^", "@backstage/plugin-scaffolder-node": "workspace:^", "fs-extra": "^11.2.0", - "node-fetch": "^2.7.0", "yaml": "^2.0.0" }, "devDependencies": { diff --git a/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.ts index f1b45111b4..7a58efa10a 100644 --- a/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.ts @@ -25,7 +25,6 @@ import { getRepoSourceDirectory, parseRepoUrl, } from '@backstage/plugin-scaffolder-node'; -import fetch, { Response, RequestInit } from 'node-fetch'; import { Config } from '@backstage/config'; import { examples } from './bitbucket.examples'; diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/package.json b/plugins/scaffolder-backend-module-confluence-to-markdown/package.json index 8efa18b1b2..e3d9d61457 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/package.json +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/package.json @@ -53,7 +53,6 @@ "@backstage/plugin-scaffolder-node": "workspace:^", "fs-extra": "^11.2.0", "git-url-parse": "^15.0.0", - "node-fetch": "^2.7.0", "node-html-markdown": "^1.3.0", "yaml": "^2.0.0" }, diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/helpers.ts b/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/helpers.ts index 65992b10f3..bbc722b1d5 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/helpers.ts +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/helpers.ts @@ -17,7 +17,7 @@ import { Config } from '@backstage/config'; import { ResponseError, ConflictError, InputError } from '@backstage/errors'; import fs from 'fs-extra'; -import fetch, { Response } from 'node-fetch'; +import { Readable } from 'stream'; interface Links { webui: string; @@ -164,7 +164,9 @@ export const getAndWriteAttachments = async ( const writeStream = fs.createWriteStream( `${workspace}/${mkdocsDir}docs/img/${downloadTitle}`, ); - res.body.pipe(writeStream); + // TODO(freben): This cast is sketchy, but for some reason the node types don't quite line up here + // https://stackoverflow.com/questions/44672942/stream-response-to-file-using-fetch-api-and-fs-createwritestream/73879265#73879265 + Readable.fromWeb(res.body as any).pipe(writeStream); await new Promise((resolve, reject) => { writeStream.on('finish', () => { resolve(`${workspace}/${mkdocsDir}docs/img/${downloadTitle}`); diff --git a/plugins/scaffolder-backend-module-gerrit/package.json b/plugins/scaffolder-backend-module-gerrit/package.json index ff7120935e..67934f1fbf 100644 --- a/plugins/scaffolder-backend-module-gerrit/package.json +++ b/plugins/scaffolder-backend-module-gerrit/package.json @@ -47,7 +47,6 @@ "@backstage/errors": "workspace:^", "@backstage/integration": "workspace:^", "@backstage/plugin-scaffolder-node": "workspace:^", - "node-fetch": "^2.7.0", "yaml": "^2.0.0" }, "devDependencies": { diff --git a/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.ts index 102d48a706..db0ae2ba70 100644 --- a/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.ts +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.ts @@ -28,7 +28,6 @@ import { getRepoSourceDirectory, parseRepoUrl, } from '@backstage/plugin-scaffolder-node'; -import fetch, { Response, RequestInit } from 'node-fetch'; import { examples } from './gerrit.examples'; const createGerritProject = async ( diff --git a/plugins/scaffolder-backend-module-gitea/package.json b/plugins/scaffolder-backend-module-gitea/package.json index 32ce119552..475551ea50 100644 --- a/plugins/scaffolder-backend-module-gitea/package.json +++ b/plugins/scaffolder-backend-module-gitea/package.json @@ -47,7 +47,6 @@ "@backstage/errors": "workspace:^", "@backstage/integration": "workspace:^", "@backstage/plugin-scaffolder-node": "workspace:^", - "node-fetch": "^2.7.0", "yaml": "^2.0.0" }, "devDependencies": { diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts index 601a670237..6b29ff2a4c 100644 --- a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -30,7 +30,6 @@ import { } from '@backstage/plugin-scaffolder-node'; import { examples } from './gitea.examples'; import crypto from 'crypto'; -import fetch, { Response, RequestInit } from 'node-fetch'; const checkGiteaContentUrl = async ( config: GiteaIntegrationConfig, diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.examples.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.examples.test.ts index f69ee2beb7..3ad0237d76 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.examples.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.examples.test.ts @@ -13,17 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import yaml from 'yaml'; import { createGitlabProjectAccessTokenAction } from './gitlabProjectAccessTokenCreate'; // Adjust the import based on your project structure import { examples } from './gitlabProjectAccessTokenCreate.examples'; - import { DateTime } from 'luxon'; -jest.mock('node-fetch'); - const mockGitlabClient = { ProjectAccessTokens: { create: jest.fn(), diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.test.ts index f5f53c30ec..0cbc0fc122 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabProjectAccessTokenCreate.test.ts @@ -13,15 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { createGitlabProjectAccessTokenAction } from './gitlabProjectAccessTokenCreate'; // Adjust the import based on your project structure - import { DateTime } from 'luxon'; -jest.mock('node-fetch'); - const mockGitlabClient = { ProjectAccessTokens: { create: jest.fn(), diff --git a/plugins/scaffolder-backend-module-sentry/package.json b/plugins/scaffolder-backend-module-sentry/package.json index 8836867ebc..fd3853edf0 100644 --- a/plugins/scaffolder-backend-module-sentry/package.json +++ b/plugins/scaffolder-backend-module-sentry/package.json @@ -46,7 +46,6 @@ "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", "@backstage/plugin-scaffolder-node": "workspace:^", - "node-fetch": "^2.7.0", "yaml": "^2.3.3" }, "devDependencies": { diff --git a/plugins/scaffolder-backend-module-sentry/src/actions/createProject.ts b/plugins/scaffolder-backend-module-sentry/src/actions/createProject.ts index 686053b178..259b670f9e 100644 --- a/plugins/scaffolder-backend-module-sentry/src/actions/createProject.ts +++ b/plugins/scaffolder-backend-module-sentry/src/actions/createProject.ts @@ -17,7 +17,6 @@ import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import { InputError } from '@backstage/errors'; import { Config } from '@backstage/config'; -import fetch from 'node-fetch'; /** * Creates the `sentry:project:create` Scaffolder action. diff --git a/plugins/search-backend-module-explore/package.json b/plugins/search-backend-module-explore/package.json index 08a4f25a69..01846576e9 100644 --- a/plugins/search-backend-module-explore/package.json +++ b/plugins/search-backend-module-explore/package.json @@ -53,8 +53,7 @@ "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/plugin-search-backend-node": "workspace:^", - "@backstage/plugin-search-common": "workspace:^", - "node-fetch": "^2.7.0" + "@backstage/plugin-search-common": "workspace:^" }, "devDependencies": { "@backstage/backend-test-utils": "workspace:^", diff --git a/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.ts b/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.ts index da047fe8ab..bafbb9cbfe 100644 --- a/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.ts +++ b/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.ts @@ -29,7 +29,6 @@ import { DocumentCollatorFactory, IndexableDocument, } from '@backstage/plugin-search-common'; -import fetch from 'node-fetch'; import { Readable } from 'stream'; /** diff --git a/plugins/search-backend-module-stack-overflow-collator/package.json b/plugins/search-backend-module-stack-overflow-collator/package.json index 97e7ad0d95..7987bf964b 100644 --- a/plugins/search-backend-module-stack-overflow-collator/package.json +++ b/plugins/search-backend-module-stack-overflow-collator/package.json @@ -39,7 +39,6 @@ "@backstage/config": "workspace:^", "@backstage/plugin-search-backend-node": "workspace:^", "@backstage/plugin-search-common": "workspace:^", - "node-fetch": "^2.7.0", "qs": "^6.9.4" }, "devDependencies": { diff --git a/plugins/search-backend-module-stack-overflow-collator/src/collators/StackOverflowQuestionsCollatorFactory.ts b/plugins/search-backend-module-stack-overflow-collator/src/collators/StackOverflowQuestionsCollatorFactory.ts index 33ceb4f870..af9a2a852b 100644 --- a/plugins/search-backend-module-stack-overflow-collator/src/collators/StackOverflowQuestionsCollatorFactory.ts +++ b/plugins/search-backend-module-stack-overflow-collator/src/collators/StackOverflowQuestionsCollatorFactory.ts @@ -20,7 +20,7 @@ import { } from '@backstage/plugin-search-common'; import { Config } from '@backstage/config'; import { Readable } from 'stream'; -import fetch from 'node-fetch'; + import qs from 'qs'; import { LoggerService } from '@backstage/backend-plugin-api'; diff --git a/plugins/search-backend-module-techdocs/package.json b/plugins/search-backend-module-techdocs/package.json index 0f176d69ca..6627fff7e6 100644 --- a/plugins/search-backend-module-techdocs/package.json +++ b/plugins/search-backend-module-techdocs/package.json @@ -60,7 +60,6 @@ "@backstage/plugin-search-common": "workspace:^", "@backstage/plugin-techdocs-node": "workspace:^", "lodash": "^4.17.21", - "node-fetch": "^2.7.0", "p-limit": "^3.1.0" }, "devDependencies": { diff --git a/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.ts b/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.ts index 0b53b33b30..3a586fd306 100644 --- a/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.ts +++ b/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.ts @@ -34,7 +34,6 @@ import { catalogEntityReadPermission } from '@backstage/plugin-catalog-common/al import { Permission } from '@backstage/plugin-permission-common'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; import { TechDocsDocument } from '@backstage/plugin-techdocs-node'; -import fetch from 'node-fetch'; import pLimit from 'p-limit'; import { Readable } from 'stream'; import { TechDocsCollatorEntityTransformer } from './TechDocsCollatorEntityTransformer'; diff --git a/plugins/signals-backend/package.json b/plugins/signals-backend/package.json index dc75c9a70d..76fffc3c50 100644 --- a/plugins/signals-backend/package.json +++ b/plugins/signals-backend/package.json @@ -48,7 +48,6 @@ "express": "^4.17.1", "express-promise-router": "^4.1.0", "http-proxy-middleware": "^2.0.0", - "node-fetch": "^2.7.0", "uuid": "^11.0.0", "winston": "^3.2.1", "ws": "^8.18.0", diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 06f94aecf9..14aad6b279 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -77,7 +77,6 @@ "fs-extra": "^11.2.0", "knex": "^3.0.0", "lodash": "^4.17.21", - "node-fetch": "^2.7.0", "p-limit": "^3.1.0", "winston": "^3.2.1" }, @@ -85,7 +84,7 @@ "@backstage/backend-defaults": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", - "msw": "^1.0.0", + "msw": "^2.0.0", "supertest": "^7.0.0" }, "configSchema": "config.d.ts" diff --git a/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts b/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts index e010856792..c825f0dbb7 100644 --- a/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts +++ b/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts @@ -22,7 +22,7 @@ import { registerMswTestHooks, } from '@backstage/backend-test-utils'; import { setupServer } from 'msw/node'; -import { rest } from 'msw'; +import { http, HttpResponse } from 'msw'; import { ConfigReader } from '@backstage/config'; import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common'; import { DiscoveryService } from '@backstage/backend-plugin-api'; @@ -106,12 +106,12 @@ describe('TechDocs Collator', () => { }); worker.use( - rest.get( + http.get( 'http://test-backend/static/docs/default/Component/test-entity-with-docs/search/search_index.json', - (_, res, ctx) => res(ctx.status(200), ctx.json(mockSearchDocIndex)), + () => HttpResponse.json(mockSearchDocIndex), ), - rest.get('http://test-backend/entities', (_, res, ctx) => - res(ctx.status(200), ctx.json(expectedEntities)), + http.get('http://test-backend/entities', () => + HttpResponse.json(expectedEntities), ), ); }); @@ -164,12 +164,12 @@ describe('TechDocs Collator', () => { }); worker.use( - rest.get( + http.get( 'http://test-backend/static/docs/default/component/test-entity-with-docs/search/search_index.json', - (_, res, ctx) => res(ctx.status(200), ctx.json(mockSearchDocIndex)), + () => HttpResponse.json(mockSearchDocIndex), ), - rest.get('http://test-backend/entities', (_, res, ctx) => - res(ctx.status(200), ctx.json(expectedEntities)), + http.get('http://test-backend/entities', () => + HttpResponse.json(expectedEntities), ), ); }); diff --git a/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.ts b/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.ts index 635833676c..3e852971a9 100644 --- a/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.ts +++ b/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.ts @@ -21,7 +21,6 @@ import { RELATION_OWNED_BY, stringifyEntityRef, } from '@backstage/catalog-model'; -import fetch from 'node-fetch'; import unescape from 'lodash/unescape'; import { Logger } from 'winston'; import pLimit from 'p-limit'; diff --git a/plugins/techdocs-backend/src/service/DocsSynchronizer.test.ts b/plugins/techdocs-backend/src/service/DocsSynchronizer.test.ts index a611613716..bef5a9c433 100644 --- a/plugins/techdocs-backend/src/service/DocsSynchronizer.test.ts +++ b/plugins/techdocs-backend/src/service/DocsSynchronizer.test.ts @@ -27,28 +27,23 @@ import * as winston from 'winston'; import { TechDocsCache } from '../cache'; import { DocsBuilder, shouldCheckForUpdate } from '../DocsBuilder'; import { DocsSynchronizer, DocsSynchronizerSyncOpts } from './DocsSynchronizer'; -import { mockServices } from '@backstage/backend-test-utils'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; import { DiscoveryService } from '@backstage/backend-plugin-api'; +import { http, HttpResponse } from 'msw'; +import { setupServer } from 'msw/node'; jest.mock('../DocsBuilder'); jest.useFakeTimers(); -jest.mock('node-fetch', () => ({ - __esModule: true, - default: async () => { - return { - json: async () => { - return { - build_timestamp: 123, - }; - }, - }; - }, -})); - const MockedDocsBuilder = DocsBuilder as jest.MockedClass; describe('DocsSynchronizer', () => { + const worker = setupServer(); + registerMswTestHooks(worker); + const preparers: jest.Mocked = { register: jest.fn(), get: jest.fn(), @@ -101,6 +96,13 @@ describe('DocsSynchronizer', () => { scmIntegrations: ScmIntegrations.fromConfig(new ConfigReader({})), cache, }); + + worker.use( + http.get( + 'http://backstage.local/api/techdocs/static/docs/default/component/test/techdocs_metadata.json', + () => HttpResponse.json({ build_timestamp: 123 }), + ), + ); }); afterEach(() => { diff --git a/plugins/techdocs-backend/src/service/DocsSynchronizer.ts b/plugins/techdocs-backend/src/service/DocsSynchronizer.ts index e4b67e920e..a1375ec142 100644 --- a/plugins/techdocs-backend/src/service/DocsSynchronizer.ts +++ b/plugins/techdocs-backend/src/service/DocsSynchronizer.ts @@ -27,7 +27,6 @@ import { PreparerBuilder, PublisherBase, } from '@backstage/plugin-techdocs-node'; -import fetch from 'node-fetch'; import pLimit, { Limit } from 'p-limit'; import { PassThrough } from 'stream'; import * as winston from 'winston'; diff --git a/yarn.lock b/yarn.lock index 3561e7e0d0..ffc3c2dfde 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3481,7 +3481,6 @@ __metadata: minimist: ^1.2.5 morgan: ^1.10.0 msw: ^1.0.0 - node-fetch: ^2.7.0 node-forge: ^1.3.1 path-to-regexp: ^8.0.0 selfsigned: ^2.0.0 @@ -4054,7 +4053,6 @@ __metadata: mini-css-extract-plugin: ^2.4.2 minimatch: ^9.0.0 msw: ^1.0.0 - node-fetch: ^2.7.0 node-libs-browser: ^2.2.1 nodemon: ^3.0.1 npm-packlist: ^5.0.0 @@ -4161,7 +4159,6 @@ __metadata: lodash: ^4.17.21 minimist: ^1.2.5 msw: ^1.0.0 - node-fetch: ^2.7.0 typescript-json-schema: ^0.65.0 yaml: ^2.0.0 zen-observable: ^0.10.0 @@ -4590,8 +4587,7 @@ __metadata: fs-extra: ^11.2.0 handlebars: ^4.7.3 inquirer: ^8.2.0 - msw: ^1.0.0 - node-fetch: ^2.7.0 + msw: ^2.0.0 nodemon: ^3.0.1 ora: ^5.3.0 recursive-readdir: ^2.2.2 @@ -5107,7 +5103,6 @@ __metadata: knex: ^3.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - node-fetch: ^2.7.0 supertest: ^7.0.0 yn: ^4.0.0 languageName: unknown @@ -5265,7 +5260,6 @@ __metadata: jose: ^5.0.0 msw: ^2.0.8 node-cache: ^5.1.2 - node-fetch: ^2.7.0 languageName: unknown linkType: soft @@ -5315,7 +5309,6 @@ __metadata: "@backstage/plugin-auth-backend": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" "@types/passport-oauth2": ^1.4.15 - node-fetch: ^2.7.0 passport: ^0.7.0 passport-oauth2: ^1.6.1 supertest: ^7.0.0 @@ -5338,7 +5331,6 @@ __metadata: express: ^4.18.2 jose: ^5.0.0 msw: ^2.0.0 - node-fetch: ^2.7.0 node-mocks-http: ^1.0.0 uuid: ^11.0.0 languageName: unknown @@ -5438,7 +5430,6 @@ __metadata: express: ^4.18.2 jose: ^5.0.0 msw: ^1.0.0 - node-fetch: ^2.7.0 passport-microsoft: ^1.0.0 supertest: ^7.0.0 languageName: unknown @@ -5638,7 +5629,6 @@ __metadata: morgan: ^1.10.0 msw: ^1.0.0 node-cache: ^5.1.2 - node-fetch: ^2.7.0 openid-client: ^5.2.1 passport: ^0.7.0 passport-auth0: ^1.4.3 @@ -5701,7 +5691,6 @@ __metadata: jose: ^5.0.0 lodash: ^4.17.21 msw: ^1.0.0 - node-fetch: ^2.7.0 passport: ^0.7.0 supertest: ^7.0.0 uuid: ^11.0.0 @@ -5803,7 +5792,6 @@ __metadata: "@backstage/plugin-catalog-node": "workspace:^" luxon: ^3.0.0 msw: ^1.0.0 - node-fetch: ^2.7.0 uuid: ^11.0.0 languageName: unknown linkType: soft @@ -5861,10 +5849,8 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" - "@types/node-fetch": ^2.5.12 luxon: ^3.0.0 msw: ^1.0.0 - node-fetch: ^2.7.0 uuid: ^11.0.0 languageName: unknown linkType: soft @@ -5899,7 +5885,6 @@ __metadata: fs-extra: ^11.2.0 luxon: ^3.0.0 msw: ^1.0.0 - node-fetch: ^2.7.0 uuid: ^11.0.0 languageName: unknown linkType: soft @@ -5942,8 +5927,7 @@ __metadata: lodash: ^4.17.21 luxon: ^3.0.0 minimatch: ^9.0.0 - msw: ^1.0.0 - node-fetch: ^2.7.0 + msw: ^2.0.0 uuid: ^11.0.0 languageName: unknown linkType: soft @@ -5984,7 +5968,6 @@ __metadata: lodash: ^4.17.21 luxon: ^3.0.0 msw: ^1.0.0 - node-fetch: ^2.7.0 uuid: ^11.0.0 languageName: unknown linkType: soft @@ -6064,11 +6047,9 @@ __metadata: "@backstage/plugin-catalog-node": "workspace:^" "@microsoft/microsoft-graph-types": ^2.6.0 "@types/lodash": ^4.14.151 - "@types/node-fetch": ^2.5.12 lodash: ^4.17.21 luxon: ^3.0.0 msw: ^1.0.0 - node-fetch: ^2.7.0 p-limit: ^3.0.2 qs: ^6.9.4 uuid: ^11.0.0 @@ -6113,7 +6094,6 @@ __metadata: lodash: ^4.17.21 luxon: ^3.0.0 msw: ^1.0.0 - node-fetch: ^2.7.0 uuid: ^11.0.0 languageName: unknown linkType: soft @@ -6194,7 +6174,6 @@ __metadata: luxon: ^3.0.0 minimatch: ^9.0.0 msw: ^1.0.0 - node-fetch: ^2.7.0 p-limit: ^3.0.2 prom-client: ^15.0.0 supertest: ^7.0.0 @@ -6585,7 +6564,6 @@ __metadata: express-promise-router: ^4.1.0 fs-extra: ^11.0.0 lodash: ^4.17.21 - node-fetch: ^2.7.0 ping: ^0.4.1 semver: ^7.5.3 supertest: ^7.0.0 @@ -7125,7 +7103,6 @@ __metadata: express-promise-router: ^4.1.0 knex: ^3.0.0 msw: ^1.0.0 - node-fetch: ^2.7.0 supertest: ^7.0.0 uuid: ^11.0.0 winston: ^3.2.1 @@ -7157,7 +7134,6 @@ __metadata: "@backstage/test-utils": "workspace:^" knex: ^3.0.0 msw: ^1.0.0 - node-fetch: ^2.7.0 uuid: ^11.0.0 languageName: unknown linkType: soft @@ -7321,7 +7297,6 @@ __metadata: express-promise-router: ^4.1.0 lodash: ^4.17.21 msw: ^1.0.0 - node-fetch: ^2.7.0 supertest: ^7.0.0 yn: ^4.0.0 zod: ^3.22.4 @@ -7416,7 +7391,6 @@ __metadata: http-proxy-middleware: ^2.0.0 morgan: ^1.10.0 msw: ^2.0.0 - node-fetch: ^2.7.0 uuid: ^11.0.0 winston: ^3.2.1 yaml: ^2.0.0 @@ -7456,7 +7430,6 @@ __metadata: "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" fs-extra: ^11.2.0 msw: ^1.0.0 - node-fetch: ^2.7.0 yaml: ^2.0.0 languageName: unknown linkType: soft @@ -7475,7 +7448,6 @@ __metadata: "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" fs-extra: ^11.2.0 msw: ^1.0.0 - node-fetch: ^2.7.0 yaml: ^2.0.0 languageName: unknown linkType: soft @@ -7496,7 +7468,6 @@ __metadata: "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" fs-extra: ^11.2.0 msw: ^1.0.0 - node-fetch: ^2.7.0 yaml: ^2.0.0 languageName: unknown linkType: soft @@ -7517,7 +7488,6 @@ __metadata: fs-extra: ^11.2.0 git-url-parse: ^15.0.0 msw: ^1.0.0 - node-fetch: ^2.7.0 node-html-markdown: ^1.3.0 yaml: ^2.0.0 languageName: unknown @@ -7577,7 +7547,6 @@ __metadata: "@backstage/plugin-scaffolder-node": "workspace:^" "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" msw: ^1.0.0 - node-fetch: ^2.7.0 yaml: ^2.0.0 languageName: unknown linkType: soft @@ -7595,7 +7564,6 @@ __metadata: "@backstage/plugin-scaffolder-node": "workspace:^" "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" msw: ^1.0.0 - node-fetch: ^2.7.0 yaml: ^2.0.0 languageName: unknown linkType: soft @@ -7700,7 +7668,6 @@ __metadata: "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" "@backstage/types": "workspace:^" msw: ^2.0.0 - node-fetch: ^2.7.0 yaml: ^2.3.3 languageName: unknown linkType: soft @@ -8056,7 +8023,6 @@ __metadata: "@backstage/plugin-search-backend-node": "workspace:^" "@backstage/plugin-search-common": "workspace:^" msw: ^1.2.1 - node-fetch: ^2.7.0 languageName: unknown linkType: soft @@ -8088,7 +8054,6 @@ __metadata: "@backstage/plugin-search-backend-node": "workspace:^" "@backstage/plugin-search-common": "workspace:^" msw: ^1.2.1 - node-fetch: ^2.7.0 qs: ^6.9.4 languageName: unknown linkType: soft @@ -8112,7 +8077,6 @@ __metadata: "@backstage/plugin-techdocs-node": "workspace:^" lodash: ^4.17.21 msw: ^1.0.0 - node-fetch: ^2.7.0 p-limit: ^3.1.0 languageName: unknown linkType: soft @@ -8287,7 +8251,6 @@ __metadata: express-promise-router: ^4.1.0 http-proxy-middleware: ^2.0.0 msw: ^1.0.0 - node-fetch: ^2.7.0 supertest: ^7.0.0 uuid: ^11.0.0 winston: ^3.2.1 @@ -8436,8 +8399,7 @@ __metadata: fs-extra: ^11.2.0 knex: ^3.0.0 lodash: ^4.17.21 - msw: ^1.0.0 - node-fetch: ^2.7.0 + msw: ^2.0.0 p-limit: ^3.1.0 supertest: ^7.0.0 winston: ^3.2.1 @@ -19709,7 +19671,7 @@ __metadata: languageName: node linkType: hard -"@types/node-fetch@npm:^2.5.12, @types/node-fetch@npm:^2.6.4, @types/node-fetch@npm:^2.6.9": +"@types/node-fetch@npm:^2.6.4, @types/node-fetch@npm:^2.6.9": version: 2.6.12 resolution: "@types/node-fetch@npm:2.6.12" dependencies: