diff --git a/.changeset/sharp-flies-cheat.md b/.changeset/sharp-flies-cheat.md new file mode 100644 index 0000000000..6c66232ff0 --- /dev/null +++ b/.changeset/sharp-flies-cheat.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-common': patch +'@backstage/plugin-catalog-graphql': patch +--- + +Move to using node-fetch internally instead of cross-fetch diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 7fb2de0fe0..275ffa5d93 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -46,7 +46,6 @@ "compression": "^1.7.4", "concat-stream": "^2.0.0", "cors": "^2.8.5", - "cross-fetch": "^3.0.6", "dockerode": "^3.3.1", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -64,6 +63,7 @@ "minimist": "^1.2.5", "morgan": "^1.10.0", "node-abort-controller": "^3.0.1", + "node-fetch": "^2.6.1", "raw-body": "^2.4.1", "selfsigned": "^1.10.7", "stoppable": "^1.1.0", diff --git a/packages/backend-common/src/reading/AzureUrlReader.ts b/packages/backend-common/src/reading/AzureUrlReader.ts index 82d1192b17..37d97b8941 100644 --- a/packages/backend-common/src/reading/AzureUrlReader.ts +++ b/packages/backend-common/src/reading/AzureUrlReader.ts @@ -22,7 +22,7 @@ import { getAzureRequestOptions, ScmIntegrations, } from '@backstage/integration'; -import fetch from 'cross-fetch'; +import fetch, { Response } from 'node-fetch'; import { Minimatch } from 'minimatch'; import { Readable } from 'stream'; import { NotFoundError, NotModifiedError } from '@backstage/errors'; @@ -72,7 +72,13 @@ export class AzureUrlReader implements UrlReader { try { response = await fetch(builtUrl, { ...getAzureRequestOptions(this.integration.config), - ...(signal && { signal }), + // TODO(freben): The signal cast is there because pre-3.x versions of + // node-fetch have a very slightly deviating AbortSignal type signature. + // The difference does not affect us in practice however. The cast can + // be removed after we support ESM for CLI dependencies and migrate to + // version 3 of node-fetch. + // https://github.com/backstage/backstage/issues/8242 + ...(signal && { signal: signal as any }), }); } catch (e) { throw new Error(`Unable to read ${url}, ${e}`); @@ -123,7 +129,13 @@ export class AzureUrlReader implements UrlReader { ...getAzureRequestOptions(this.integration.config, { Accept: 'application/zip', }), - ...(signal && { signal }), + // TODO(freben): The signal cast is there because pre-3.x versions of + // node-fetch have a very slightly deviating AbortSignal type signature. + // The difference does not affect us in practice however. The cast can be + // removed after we support ESM for CLI dependencies and migrate to + // version 3 of node-fetch. + // https://github.com/backstage/backstage/issues/8242 + ...(signal && { signal: signal as any }), }); if (!archiveAzureResponse.ok) { const message = `Failed to read tree from ${url}, ${archiveAzureResponse.status} ${archiveAzureResponse.statusText}`; diff --git a/packages/backend-common/src/reading/BitbucketUrlReader.ts b/packages/backend-common/src/reading/BitbucketUrlReader.ts index c1a113a50d..b0e8056370 100644 --- a/packages/backend-common/src/reading/BitbucketUrlReader.ts +++ b/packages/backend-common/src/reading/BitbucketUrlReader.ts @@ -23,7 +23,7 @@ import { getBitbucketRequestOptions, ScmIntegrations, } from '@backstage/integration'; -import fetch from 'cross-fetch'; +import fetch, { Response } from 'node-fetch'; import parseGitUrl from 'git-url-parse'; import { trimEnd } from 'lodash'; import { Minimatch } from 'minimatch'; @@ -94,7 +94,13 @@ export class BitbucketUrlReader implements UrlReader { try { response = await fetch(bitbucketUrl.toString(), { ...requestOptions, - ...(signal && { signal }), + // TODO(freben): The signal cast is there because pre-3.x versions of + // node-fetch have a very slightly deviating AbortSignal type signature. + // The difference does not affect us in practice however. The cast can be + // removed after we support ESM for CLI dependencies and migrate to + // version 3 of node-fetch. + // https://github.com/backstage/backstage/issues/8242 + ...(signal && { signal: signal as any }), }); } catch (e) { throw new Error(`Unable to read ${url}, ${e}`); diff --git a/packages/backend-common/src/reading/FetchUrlReader.ts b/packages/backend-common/src/reading/FetchUrlReader.ts index d82b1f7f52..7090d26d35 100644 --- a/packages/backend-common/src/reading/FetchUrlReader.ts +++ b/packages/backend-common/src/reading/FetchUrlReader.ts @@ -15,7 +15,7 @@ */ import { NotFoundError, NotModifiedError } from '@backstage/errors'; -import fetch from 'cross-fetch'; +import fetch, { Response } from 'node-fetch'; import { ReaderFactory, ReadTreeResponse, @@ -86,7 +86,13 @@ export class FetchUrlReader implements UrlReader { headers: { ...(options?.etag && { 'If-None-Match': options.etag }), }, - signal: options?.signal, + // TODO(freben): The signal cast is there because pre-3.x versions of + // node-fetch have a very slightly deviating AbortSignal type signature. + // The difference does not affect us in practice however. The cast can + // be removed after we support ESM for CLI dependencies and migrate to + // version 3 of node-fetch. + // https://github.com/backstage/backstage/issues/8242 + signal: options?.signal as any, }); } catch (e) { throw new Error(`Unable to read ${url}, ${e}`); diff --git a/packages/backend-common/src/reading/GithubUrlReader.ts b/packages/backend-common/src/reading/GithubUrlReader.ts index 755e0f17e6..d0fbf6d8ae 100644 --- a/packages/backend-common/src/reading/GithubUrlReader.ts +++ b/packages/backend-common/src/reading/GithubUrlReader.ts @@ -21,7 +21,7 @@ import { ScmIntegrations, } from '@backstage/integration'; import { RestEndpointMethodTypes } from '@octokit/rest'; -import fetch from 'cross-fetch'; +import fetch, { RequestInit, Response } from 'node-fetch'; import parseGitUrl from 'git-url-parse'; import { Minimatch } from 'minimatch'; import { Readable } from 'stream'; @@ -110,7 +110,13 @@ export class GithubUrlReader implements UrlReader { ...(options?.etag && { 'If-None-Match': options.etag }), Accept: 'application/vnd.github.v3.raw', }, - signal: options?.signal, + // TODO(freben): The signal cast is there because pre-3.x versions of + // node-fetch have a very slightly deviating AbortSignal type signature. + // The difference does not affect us in practice however. The cast can + // be removed after we support ESM for CLI dependencies and migrate to + // version 3 of node-fetch. + // https://github.com/backstage/backstage/issues/8242 + signal: options?.signal as any, }); } catch (e) { throw new Error(`Unable to read ${url}, ${e}`); @@ -165,7 +171,13 @@ export class GithubUrlReader implements UrlReader { repoDetails.repo.archive_url, commitSha, filepath, - { headers, signal: options?.signal }, + // TODO(freben): The signal cast is there because pre-3.x versions of + // node-fetch have a very slightly deviating AbortSignal type signature. + // The difference does not affect us in practice however. The cast can be + // removed after we support ESM for CLI dependencies and migrate to + // version 3 of node-fetch. + // https://github.com/backstage/backstage/issues/8242 + { headers, signal: options?.signal as any }, options, ); } @@ -189,7 +201,7 @@ export class GithubUrlReader implements UrlReader { repoDetails.repo.archive_url, commitSha, filepath, - { headers, signal: options?.signal }, + { headers, signal: options?.signal as any }, ); return { files, etag: commitSha }; diff --git a/packages/backend-common/src/reading/GitlabUrlReader.ts b/packages/backend-common/src/reading/GitlabUrlReader.ts index 128aed3c85..2444e317a7 100644 --- a/packages/backend-common/src/reading/GitlabUrlReader.ts +++ b/packages/backend-common/src/reading/GitlabUrlReader.ts @@ -20,7 +20,7 @@ import { GitLabIntegration, ScmIntegrations, } from '@backstage/integration'; -import fetch from 'cross-fetch'; +import fetch, { Response } from 'node-fetch'; import parseGitUrl from 'git-url-parse'; import { Minimatch } from 'minimatch'; import { Readable } from 'stream'; @@ -76,7 +76,13 @@ export class GitlabUrlReader implements UrlReader { ...getGitLabRequestOptions(this.integration.config).headers, ...(etag && { 'If-None-Match': etag }), }, - ...(signal && { signal }), + // TODO(freben): The signal cast is there because pre-3.x versions of + // node-fetch have a very slightly deviating AbortSignal type signature. + // The difference does not affect us in practice however. The cast can be + // removed after we support ESM for CLI dependencies and migrate to + // version 3 of node-fetch. + // https://github.com/backstage/backstage/issues/8242 + ...(signal && { signal: signal as any }), }); } catch (e) { throw new Error(`Unable to read ${url}, ${e}`); @@ -145,7 +151,13 @@ export class GitlabUrlReader implements UrlReader { ).toString(), { ...getGitLabRequestOptions(this.integration.config), - ...(signal && { signal }), + // TODO(freben): The signal cast is there because pre-3.x versions of + // node-fetch have a very slightly deviating AbortSignal type signature. + // The difference does not affect us in practice however. The cast can + // be removed after we support ESM for CLI dependencies and migrate to + // version 3 of node-fetch. + // https://github.com/backstage/backstage/issues/8242 + ...(signal && { signal: signal as any }), }, ); if (!commitsGitlabResponse.ok) { @@ -169,7 +181,13 @@ export class GitlabUrlReader implements UrlReader { )}/repository/archive?sha=${branch}`, { ...getGitLabRequestOptions(this.integration.config), - ...(signal && { signal }), + // TODO(freben): The signal cast is there because pre-3.x versions of + // node-fetch have a very slightly deviating AbortSignal type signature. + // The difference does not affect us in practice however. The cast can + // be removed after we support ESM for CLI dependencies and migrate to + // version 3 of node-fetch. + // https://github.com/backstage/backstage/issues/8242 + ...(signal && { signal: signal as any }), }, ); if (!archiveGitLabResponse.ok) { diff --git a/plugins/catalog-graphql/package.json b/plugins/catalog-graphql/package.json index a7070a1634..44c820858d 100644 --- a/plugins/catalog-graphql/package.json +++ b/plugins/catalog-graphql/package.json @@ -36,10 +36,10 @@ "@backstage/types": "^0.1.1", "@graphql-modules/core": "^0.7.17", "apollo-server": "^2.16.1", - "cross-fetch": "^3.0.6", "graphql": "^15.3.0", "graphql-tag": "^2.11.0", "graphql-type-json": "^0.3.2", + "node-fetch": "^2.6.1", "winston": "^3.2.1" }, "devDependencies": { diff --git a/plugins/catalog-graphql/src/service/client.ts b/plugins/catalog-graphql/src/service/client.ts index 4328a5bd5a..8d517fcbd6 100644 --- a/plugins/catalog-graphql/src/service/client.ts +++ b/plugins/catalog-graphql/src/service/client.ts @@ -15,7 +15,7 @@ */ import { Entity, EntityMeta } from '@backstage/catalog-model'; -import fetch from 'cross-fetch'; +import fetch from 'node-fetch'; import { JsonObject } from '@backstage/types'; export interface ReaderEntityMeta extends EntityMeta { @@ -26,11 +26,14 @@ export interface ReaderEntityMeta extends EntityMeta { annotations: Record; labels: Record; } + export interface ReaderEntity extends Entity { metadata: JsonObject & ReaderEntityMeta; } + export class CatalogClient { constructor(private baseUrl: string) {} + async list(): Promise { const res = await fetch(`${this.baseUrl}/catalog/entities`); if (!res.ok) { @@ -39,7 +42,7 @@ export class CatalogClient { throw new Error(await res.text()); } - const entities: ReaderEntity[] = await res.json(); + const entities = (await res.json()) as ReaderEntity[]; return entities; } }