From cf39e4e84cb363fd87ed139ade35a10792eb19be Mon Sep 17 00:00:00 2001 From: Benjamin Janssens Date: Mon, 7 Jul 2025 13:53:30 +0200 Subject: [PATCH 1/4] feat(catalog): add analyze location endpoint to client Signed-off-by: Benjamin Janssens --- packages/catalog-client/package.json | 1 + packages/catalog-client/src/CatalogClient.ts | 25 ++++++++++++++++++++ packages/catalog-client/src/types/api.ts | 15 ++++++++++++ yarn.lock | 1 + 4 files changed, 42 insertions(+) diff --git a/packages/catalog-client/package.json b/packages/catalog-client/package.json index 93f45f8611..d5ac5f720e 100644 --- a/packages/catalog-client/package.json +++ b/packages/catalog-client/package.json @@ -55,6 +55,7 @@ }, "devDependencies": { "@backstage/cli": "workspace:^", + "@backstage/plugin-catalog-common": "workspace:^", "msw": "^1.0.0" } } diff --git a/packages/catalog-client/src/CatalogClient.ts b/packages/catalog-client/src/CatalogClient.ts index e69f6ad434..7d86eed95d 100644 --- a/packages/catalog-client/src/CatalogClient.ts +++ b/packages/catalog-client/src/CatalogClient.ts @@ -44,6 +44,10 @@ import { } from './types/api'; import { isQueryEntitiesInitialRequest, splitRefsIntoChunks } from './utils'; import { DefaultApiClient, TypedResponse } from './schema/openapi'; +import type { + AnalyzeLocationRequest, + AnalyzeLocationResponse, +} from '@backstage/plugin-catalog-common'; /** * A frontend and backend compatible client for communicating with the Backstage @@ -431,6 +435,27 @@ export class CatalogClient implements CatalogApi { }; } + /** + * {@inheritdoc CatalogApi.analyzeLocation} + */ + async analyzeLocation( + request: AnalyzeLocationRequest, + options?: CatalogRequestOptions, + ): Promise { + const response = await this.apiClient.analyzeLocation( + { + body: request, + }, + options, + ); + + if (response.status !== 200) { + throw await ResponseError.fromResponse(response); + } + + return response.json() as Promise; + } + // // Private methods // diff --git a/packages/catalog-client/src/types/api.ts b/packages/catalog-client/src/types/api.ts index c999b29390..28fe8bf276 100644 --- a/packages/catalog-client/src/types/api.ts +++ b/packages/catalog-client/src/types/api.ts @@ -16,6 +16,10 @@ import { CompoundEntityRef, Entity } from '@backstage/catalog-model'; import { SerializedError } from '@backstage/errors'; +import type { + AnalyzeLocationRequest, + AnalyzeLocationResponse, +} from '@backstage/plugin-catalog-common'; /** * This symbol can be used in place of a value when passed to filters in e.g. @@ -677,4 +681,15 @@ export interface CatalogApi { locationRef: string, options?: CatalogRequestOptions, ): Promise; + + /** + * Validate a given location. + * + * @param location - Request parameters + * @param options - Additional options + */ + analyzeLocation( + location: AnalyzeLocationRequest, + options?: CatalogRequestOptions, + ): Promise; } diff --git a/yarn.lock b/yarn.lock index 45962f279b..8d0f99bd8a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3872,6 +3872,7 @@ __metadata: "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/errors": "workspace:^" + "@backstage/plugin-catalog-common": "workspace:^" cross-fetch: "npm:^4.0.0" msw: "npm:^1.0.0" uri-template: "npm:^2.0.0" From 6b608e77bfb942dc84df6570aae01a83c56e2a63 Mon Sep 17 00:00:00 2001 From: Benjamin Janssens Date: Mon, 7 Jul 2025 13:57:26 +0200 Subject: [PATCH 2/4] chore(catalog): add changeset Signed-off-by: Benjamin Janssens --- .changeset/little-bugs-care.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/little-bugs-care.md diff --git a/.changeset/little-bugs-care.md b/.changeset/little-bugs-care.md new file mode 100644 index 0000000000..930cbd0e21 --- /dev/null +++ b/.changeset/little-bugs-care.md @@ -0,0 +1,5 @@ +--- +'@backstage/catalog-client': minor +--- + +Added the analyze-location endpoint to the CatalogClient From 3f4da3910d70b1cc0ce2fd95fbad9b28d22ae7de Mon Sep 17 00:00:00 2001 From: Benjamin Janssens Date: Mon, 7 Jul 2025 14:27:11 +0200 Subject: [PATCH 3/4] feat(catalog): update dependent plugins; generate api reports Signed-off-by: Benjamin Janssens --- .changeset/evil-forks-hang.md | 5 +++++ .changeset/long-grapes-glow.md | 5 +++++ .../catalog-client/report-testUtils.api.md | 6 ++++++ packages/catalog-client/report.api.md | 10 ++++++++++ .../src/testUtils/InMemoryCatalogClient.ts | 10 ++++++++++ plugins/catalog-node/report-testUtils.api.md | 7 +++++++ plugins/catalog-node/report.api.md | 5 +++++ plugins/catalog-node/src/catalogService.ts | 19 +++++++++++++++++++ .../src/testUtils/catalogServiceMock.ts | 1 + plugins/catalog-node/src/testUtils/types.ts | 9 +++++++++ .../src/testUtils/catalogApiMock.ts | 1 + 11 files changed, 78 insertions(+) create mode 100644 .changeset/evil-forks-hang.md create mode 100644 .changeset/long-grapes-glow.md diff --git a/.changeset/evil-forks-hang.md b/.changeset/evil-forks-hang.md new file mode 100644 index 0000000000..8258c904b9 --- /dev/null +++ b/.changeset/evil-forks-hang.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': minor +--- + +Added the analyzeLocation method to catalogApiMock diff --git a/.changeset/long-grapes-glow.md b/.changeset/long-grapes-glow.md new file mode 100644 index 0000000000..e0e805ed87 --- /dev/null +++ b/.changeset/long-grapes-glow.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-node': minor +--- + +Added the analyze-location endpoint to the CatalogService diff --git a/packages/catalog-client/report-testUtils.api.md b/packages/catalog-client/report-testUtils.api.md index bb6a8dd469..f5bcf55c53 100644 --- a/packages/catalog-client/report-testUtils.api.md +++ b/packages/catalog-client/report-testUtils.api.md @@ -5,6 +5,8 @@ ```ts import { AddLocationRequest } from '@backstage/catalog-client'; import { AddLocationResponse } from '@backstage/catalog-client'; +import type { AnalyzeLocationRequest } from '@backstage/plugin-catalog-common'; +import type { AnalyzeLocationResponse } from '@backstage/plugin-catalog-common'; import { CatalogApi } from '@backstage/catalog-client'; import { CompoundEntityRef } from '@backstage/catalog-model'; import { Entity } from '@backstage/catalog-model'; @@ -28,6 +30,10 @@ export class InMemoryCatalogClient implements CatalogApi { // (undocumented) addLocation(_location: AddLocationRequest): Promise; // (undocumented) + analyzeLocation( + _location: AnalyzeLocationRequest, + ): Promise; + // (undocumented) getEntities(request?: GetEntitiesRequest): Promise; // (undocumented) getEntitiesByRefs( diff --git a/packages/catalog-client/report.api.md b/packages/catalog-client/report.api.md index 0a37ed7e42..ebb0f5ac97 100644 --- a/packages/catalog-client/report.api.md +++ b/packages/catalog-client/report.api.md @@ -3,6 +3,8 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import type { AnalyzeLocationRequest } from '@backstage/plugin-catalog-common'; +import type { AnalyzeLocationResponse } from '@backstage/plugin-catalog-common'; import { CompoundEntityRef } from '@backstage/catalog-model'; import { Entity } from '@backstage/catalog-model'; import { SerializedError } from '@backstage/errors'; @@ -30,6 +32,10 @@ export interface CatalogApi { location: AddLocationRequest, options?: CatalogRequestOptions, ): Promise; + analyzeLocation( + location: AnalyzeLocationRequest, + options?: CatalogRequestOptions, + ): Promise; getEntities( request?: GetEntitiesRequest, options?: CatalogRequestOptions, @@ -103,6 +109,10 @@ export class CatalogClient implements CatalogApi { request: AddLocationRequest, options?: CatalogRequestOptions, ): Promise; + analyzeLocation( + request: AnalyzeLocationRequest, + options?: CatalogRequestOptions, + ): Promise; getEntities( request?: GetEntitiesRequest, options?: CatalogRequestOptions, diff --git a/packages/catalog-client/src/testUtils/InMemoryCatalogClient.ts b/packages/catalog-client/src/testUtils/InMemoryCatalogClient.ts index 746871a1b3..97663de922 100644 --- a/packages/catalog-client/src/testUtils/InMemoryCatalogClient.ts +++ b/packages/catalog-client/src/testUtils/InMemoryCatalogClient.ts @@ -44,6 +44,10 @@ import { import { NotFoundError, NotImplementedError } from '@backstage/errors'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { traverse } from '../../../../plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch'; +import type { + AnalyzeLocationRequest, + AnalyzeLocationResponse, +} from '@backstage/plugin-catalog-common'; function buildEntitySearch(entity: Entity) { const rows = traverse(entity); @@ -269,6 +273,12 @@ export class InMemoryCatalogClient implements CatalogApi { throw new NotImplementedError('Method not implemented.'); } + async analyzeLocation( + _location: AnalyzeLocationRequest, + ): Promise { + throw new NotImplementedError('Method not implemented.'); + } + #createEntityRefMap() { return new Map(this.#entities.map(e => [stringifyEntityRef(e), e])); } diff --git a/plugins/catalog-node/report-testUtils.api.md b/plugins/catalog-node/report-testUtils.api.md index 3098888fcb..3fa7057a99 100644 --- a/plugins/catalog-node/report-testUtils.api.md +++ b/plugins/catalog-node/report-testUtils.api.md @@ -5,6 +5,8 @@ ```ts import { AddLocationRequest } from '@backstage/catalog-client'; import { AddLocationResponse } from '@backstage/catalog-client'; +import { AnalyzeLocationRequest } from '@backstage/plugin-catalog-common'; +import { AnalyzeLocationResponse } from '@backstage/plugin-catalog-common'; import { CatalogApi } from '@backstage/catalog-client'; import { CatalogRequestOptions } from '@backstage/catalog-client'; import { CatalogService } from '@backstage/plugin-catalog-node'; @@ -35,6 +37,11 @@ export interface CatalogServiceMock extends CatalogService, CatalogApi { options?: CatalogServiceRequestOptions | CatalogRequestOptions, ): Promise; // (undocumented) + analyzeLocation( + location: AnalyzeLocationRequest, + options?: CatalogServiceRequestOptions | CatalogRequestOptions, + ): Promise; + // (undocumented) getEntities( request?: GetEntitiesRequest, options?: CatalogServiceRequestOptions | CatalogRequestOptions, diff --git a/plugins/catalog-node/report.api.md b/plugins/catalog-node/report.api.md index 807bcaa8d5..debafad5c4 100644 --- a/plugins/catalog-node/report.api.md +++ b/plugins/catalog-node/report.api.md @@ -125,6 +125,11 @@ export interface CatalogService { options: CatalogServiceRequestOptions, ): Promise; // (undocumented) + analyzeLocation( + location: AnalyzeLocationRequest, + options: CatalogServiceRequestOptions, + ): Promise; + // (undocumented) getEntities( request: GetEntitiesRequest | undefined, options: CatalogServiceRequestOptions, diff --git a/plugins/catalog-node/src/catalogService.ts b/plugins/catalog-node/src/catalogService.ts index 51bb1d92e5..9478c6b48a 100644 --- a/plugins/catalog-node/src/catalogService.ts +++ b/plugins/catalog-node/src/catalogService.ts @@ -42,6 +42,10 @@ import { ValidateEntityResponse, } from '@backstage/catalog-client'; import { CompoundEntityRef, Entity } from '@backstage/catalog-model'; +import { + AnalyzeLocationRequest, + AnalyzeLocationResponse, +} from '@backstage/plugin-catalog-common'; /** * @public @@ -132,6 +136,11 @@ export interface CatalogService { locationRef: string, options: CatalogServiceRequestOptions, ): Promise; + + analyzeLocation( + location: AnalyzeLocationRequest, + options: CatalogServiceRequestOptions, + ): Promise; } class DefaultCatalogService implements CatalogService { @@ -301,6 +310,16 @@ class DefaultCatalogService implements CatalogService { ); } + async analyzeLocation( + location: AnalyzeLocationRequest, + options: CatalogServiceRequestOptions, + ): Promise { + return this.#catalogApi.analyzeLocation( + location, + await this.#getOptions(options), + ); + } + async #getOptions( options: CatalogServiceRequestOptions, ): Promise { diff --git a/plugins/catalog-node/src/testUtils/catalogServiceMock.ts b/plugins/catalog-node/src/testUtils/catalogServiceMock.ts index ec469fc927..20e04e12b4 100644 --- a/plugins/catalog-node/src/testUtils/catalogServiceMock.ts +++ b/plugins/catalog-node/src/testUtils/catalogServiceMock.ts @@ -102,5 +102,6 @@ export namespace catalogServiceMock { removeLocationById: jest.fn(), getLocationByEntity: jest.fn(), validateEntity: jest.fn(), + analyzeLocation: jest.fn(), })); } diff --git a/plugins/catalog-node/src/testUtils/types.ts b/plugins/catalog-node/src/testUtils/types.ts index 6e6331a630..96380e9434 100644 --- a/plugins/catalog-node/src/testUtils/types.ts +++ b/plugins/catalog-node/src/testUtils/types.ts @@ -34,6 +34,10 @@ import { ValidateEntityResponse, } from '@backstage/catalog-client'; import { CompoundEntityRef, Entity } from '@backstage/catalog-model'; +import { + AnalyzeLocationRequest, + AnalyzeLocationResponse, +} from '@backstage/plugin-catalog-common'; import { CatalogService, CatalogServiceRequestOptions, @@ -126,4 +130,9 @@ export interface CatalogServiceMock extends CatalogService, CatalogApi { locationRef: string, options?: CatalogServiceRequestOptions | CatalogRequestOptions, ): Promise; + + analyzeLocation( + location: AnalyzeLocationRequest, + options?: CatalogServiceRequestOptions | CatalogRequestOptions, + ): Promise; } diff --git a/plugins/catalog-react/src/testUtils/catalogApiMock.ts b/plugins/catalog-react/src/testUtils/catalogApiMock.ts index 08520e2a9b..42c6b1004f 100644 --- a/plugins/catalog-react/src/testUtils/catalogApiMock.ts +++ b/plugins/catalog-react/src/testUtils/catalogApiMock.ts @@ -101,5 +101,6 @@ export namespace catalogApiMock { removeLocationById: jest.fn(), getLocationByEntity: jest.fn(), validateEntity: jest.fn(), + analyzeLocation: jest.fn(), })); } From c2b6098fda3c0d1923d3d746fc27b1fa0529bcf8 Mon Sep 17 00:00:00 2001 From: Benjamin Janssens Date: Tue, 22 Jul 2025 15:55:04 +0200 Subject: [PATCH 4/4] Update .changeset/evil-forks-hang.md Co-authored-by: Paul Schultz Signed-off-by: Benjamin Janssens --- .changeset/evil-forks-hang.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/evil-forks-hang.md b/.changeset/evil-forks-hang.md index 8258c904b9..f261c48c2b 100644 --- a/.changeset/evil-forks-hang.md +++ b/.changeset/evil-forks-hang.md @@ -2,4 +2,4 @@ '@backstage/plugin-catalog-react': minor --- -Added the analyzeLocation method to catalogApiMock +Added the `analyzeLocation` method to `catalogApiMock`