diff --git a/.changeset/rotten-melons-sleep.md b/.changeset/rotten-melons-sleep.md new file mode 100644 index 0000000000..c12e0a9669 --- /dev/null +++ b/.changeset/rotten-melons-sleep.md @@ -0,0 +1,15 @@ +--- +'@backstage/plugin-catalog-unprocessed-entities-common': patch +'@backstage/plugin-catalog-unprocessed-entities': patch +--- + +Moved types, API and client to the common package, allowing both frontend and +backend plugins to use the `CatalogUnprocessedEntitiesClient`. + +The following types, clients and interfaces have been deprecated and should be +imported from the `@backstage/plugin-catalog-unprocessed-entities-common` instead: +`CatalogUnprocessedEntitiesApi`, `CatalogUnprocessedEntitiesApiResponse`, `UnprocessedEntity`, +`UnprocessedEntityCache`, `UnprocessedEntityError`, `CatalogUnprocessedEntitiesClient`. + +All those types, clients and interfaces are re-exported temporarily in the +`@backstage/plugin-catalog-unprocessed-entities` package until cleaned up. diff --git a/plugins/catalog-unprocessed-entities-common/package.json b/plugins/catalog-unprocessed-entities-common/package.json index 49ead8da1b..68e1a23dd0 100644 --- a/plugins/catalog-unprocessed-entities-common/package.json +++ b/plugins/catalog-unprocessed-entities-common/package.json @@ -37,6 +37,8 @@ "test": "backstage-cli package test" }, "dependencies": { + "@backstage/catalog-model": "workspace:^", + "@backstage/errors": "workspace:^", "@backstage/plugin-permission-common": "workspace:^" }, "devDependencies": { diff --git a/plugins/catalog-unprocessed-entities-common/report.api.md b/plugins/catalog-unprocessed-entities-common/report.api.md index 03b316eebb..e373a3f45b 100644 --- a/plugins/catalog-unprocessed-entities-common/report.api.md +++ b/plugins/catalog-unprocessed-entities-common/report.api.md @@ -4,6 +4,53 @@ ```ts import { BasicPermission } from '@backstage/plugin-permission-common'; +import { Entity } from '@backstage/catalog-model'; + +// @public +export interface CatalogUnprocessedEntitiesApi { + delete( + entityId: string, + options?: UnprocessedEntitiesRequestOptions, + ): Promise; + failed( + options?: UnprocessedEntitiesRequestOptions, + ): Promise; + pending( + options?: UnprocessedEntitiesRequestOptions, + ): Promise; +} + +// @public +export type CatalogUnprocessedEntitiesApiResponse = { + entities: UnprocessedEntity[]; +}; + +// @public +export class CatalogUnprocessedEntitiesClient + implements CatalogUnprocessedEntitiesApi +{ + constructor( + discovery: { + getBaseUrl(pluginId: string): Promise; + }, + fetchApi?: { + fetch: typeof fetch; + }, + ); + // (undocumented) + delete( + entityId: string, + options?: UnprocessedEntitiesRequestOptions, + ): Promise; + // (undocumented) + failed( + options?: UnprocessedEntitiesRequestOptions, + ): Promise; + // (undocumented) + pending( + options?: UnprocessedEntitiesRequestOptions, + ): Promise; +} // @public export const unprocessedEntitiesDeletePermission: BasicPermission; @@ -12,4 +59,42 @@ export const unprocessedEntitiesDeletePermission: BasicPermission; export const unprocessedEntitiesPermissions: { unprocessedEntitiesDeletePermission: BasicPermission; }; + +// @public +export interface UnprocessedEntitiesRequestOptions { + // (undocumented) + token?: string; +} + +// @public +export type UnprocessedEntity = { + entity_id: string; + entity_ref: string; + unprocessed_entity: Entity; + unprocessed_hash?: string; + processed_entity?: Entity; + result_hash?: string; + cache?: UnprocessedEntityCache; + next_update_at: string | Date; + last_discovery_at: string | Date; + errors?: UnprocessedEntityError[]; + location_key?: string; +}; + +// @public +export type UnprocessedEntityCache = { + ttl: number; + cache: object; +}; + +// @public +export type UnprocessedEntityError = { + name: string; + message: string; + cause: { + name: string; + message: string; + stack: string; + }; +}; ``` diff --git a/plugins/catalog-unprocessed-entities-common/src/api/api.ts b/plugins/catalog-unprocessed-entities-common/src/api/api.ts new file mode 100644 index 0000000000..02b230aaec --- /dev/null +++ b/plugins/catalog-unprocessed-entities-common/src/api/api.ts @@ -0,0 +1,124 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { CatalogUnprocessedEntitiesApiResponse } from '../types'; +import { ResponseError } from '@backstage/errors'; + +/** + * Options you can pass into a catalog request for additional information. + * + * @public + */ +export interface UnprocessedEntitiesRequestOptions { + token?: string; +} + +/** + * Interface for the CatalogUnprocessedEntitiesApi. + * + * @public + */ +export interface CatalogUnprocessedEntitiesApi { + /** + * Returns a list of entities with state 'pending' + * + * @param options - Additional options + */ + pending( + options?: UnprocessedEntitiesRequestOptions, + ): Promise; + /** + * Returns a list of entities with state 'failed' + * + * @param options - Additional options + */ + failed( + options?: UnprocessedEntitiesRequestOptions, + ): Promise; + /** + * Deletes an entity from the refresh_state table + * + * @param entityId - The ID of the entity to delete + * @param options - Additional options + */ + delete( + entityId: string, + options?: UnprocessedEntitiesRequestOptions, + ): Promise; +} + +/** + * Default API implementation for the Catalog Unprocessed Entities plugin + * + * @public + */ +export class CatalogUnprocessedEntitiesClient + implements CatalogUnprocessedEntitiesApi +{ + private readonly discovery: { getBaseUrl(pluginId: string): Promise }; + private readonly fetchApi: { fetch: typeof fetch }; + + constructor( + discovery: { getBaseUrl(pluginId: string): Promise }, + fetchApi?: { fetch: typeof fetch }, + ) { + this.discovery = discovery; + this.fetchApi = fetchApi ?? { fetch }; + } + + private async fetch( + method: string, + path: string, + options?: UnprocessedEntitiesRequestOptions, + ): Promise { + const url = await this.discovery.getBaseUrl('catalog'); + const resp = await this.fetchApi.fetch(`${url}/${path}`, { + method, + headers: { + ...(options?.token ? { Authorization: `Bearer ${options.token}` } : {}), + }, + }); + + if (!resp.ok) { + throw await ResponseError.fromResponse(resp); + } + + return resp.status === 204 ? (resp as T) : await resp.json(); + } + + async pending( + options?: UnprocessedEntitiesRequestOptions, + ): Promise { + return await this.fetch('GET', 'entities/unprocessed/pending', options); + } + + async failed( + options?: UnprocessedEntitiesRequestOptions, + ): Promise { + return await this.fetch('GET', 'entities/unprocessed/failed', options); + } + + async delete( + entityId: string, + options?: UnprocessedEntitiesRequestOptions, + ): Promise { + await this.fetch( + 'DELETE', + `entities/unprocessed/delete/${entityId}`, + options, + ); + } +} diff --git a/plugins/catalog-unprocessed-entities-common/src/api/index.ts b/plugins/catalog-unprocessed-entities-common/src/api/index.ts new file mode 100644 index 0000000000..5b8bf17e1d --- /dev/null +++ b/plugins/catalog-unprocessed-entities-common/src/api/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './api'; diff --git a/plugins/catalog-unprocessed-entities-common/src/index.ts b/plugins/catalog-unprocessed-entities-common/src/index.ts index cd5a39c731..d11cb4fdb5 100644 --- a/plugins/catalog-unprocessed-entities-common/src/index.ts +++ b/plugins/catalog-unprocessed-entities-common/src/index.ts @@ -20,4 +20,6 @@ * @packageDocumentation */ +export * from './api'; export * from './permissions'; +export * from './types'; diff --git a/plugins/catalog-unprocessed-entities-common/src/types.ts b/plugins/catalog-unprocessed-entities-common/src/types.ts new file mode 100644 index 0000000000..d7af485e83 --- /dev/null +++ b/plugins/catalog-unprocessed-entities-common/src/types.ts @@ -0,0 +1,66 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Entity } from '@backstage/catalog-model'; + +/** + * Unprocessed entity data stored in the database. + * @public + */ +export type UnprocessedEntity = { + entity_id: string; + entity_ref: string; + unprocessed_entity: Entity; + unprocessed_hash?: string; + processed_entity?: Entity; + result_hash?: string; + cache?: UnprocessedEntityCache; + next_update_at: string | Date; + last_discovery_at: string | Date; // remove? + errors?: UnprocessedEntityError[]; + location_key?: string; +}; + +/** + * Unprocessed entity cache stored in the database. + * @public + */ +export type UnprocessedEntityCache = { + ttl: number; + cache: object; +}; + +/** + * Unprocessed entity error information stored in the database. + * @public + */ +export type UnprocessedEntityError = { + name: string; + message: string; + cause: { + name: string; + message: string; + stack: string; + }; +}; + +/** + * Response expected by the {@link CatalogUnprocessedEntitiesApi} + * + * @public + */ +export type CatalogUnprocessedEntitiesApiResponse = { + entities: UnprocessedEntity[]; +}; diff --git a/plugins/catalog-unprocessed-entities/package.json b/plugins/catalog-unprocessed-entities/package.json index a6e960367e..82ea2238bc 100644 --- a/plugins/catalog-unprocessed-entities/package.json +++ b/plugins/catalog-unprocessed-entities/package.json @@ -50,11 +50,11 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/catalog-model": "workspace:^", "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", "@backstage/errors": "workspace:^", "@backstage/frontend-plugin-api": "workspace:^", + "@backstage/plugin-catalog-unprocessed-entities-common": "workspace:^", "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.60", diff --git a/plugins/catalog-unprocessed-entities/report.api.md b/plugins/catalog-unprocessed-entities/report.api.md index adaf7af643..28b55b9a6d 100644 --- a/plugins/catalog-unprocessed-entities/report.api.md +++ b/plugins/catalog-unprocessed-entities/report.api.md @@ -5,24 +5,24 @@ ```ts import { ApiRef } from '@backstage/core-plugin-api'; import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { Entity } from '@backstage/catalog-model'; +import { CatalogUnprocessedEntitiesApi as CatalogUnprocessedEntitiesApi_2 } from '@backstage/plugin-catalog-unprocessed-entities-common'; +import { CatalogUnprocessedEntitiesApiResponse as CatalogUnprocessedEntitiesApiResponse_2 } from '@backstage/plugin-catalog-unprocessed-entities-common'; import { JSX as JSX_2 } from 'react/jsx-runtime'; import { RouteRef } from '@backstage/core-plugin-api'; +import type { UnprocessedEntity as UnprocessedEntity_2 } from '@backstage/plugin-catalog-unprocessed-entities-common'; +import type { UnprocessedEntityCache as UnprocessedEntityCache_2 } from '@backstage/plugin-catalog-unprocessed-entities-common'; +import type { UnprocessedEntityError as UnprocessedEntityError_2 } from '@backstage/plugin-catalog-unprocessed-entities-common'; -// @public -export interface CatalogUnprocessedEntitiesApi { - delete(entityId: string): Promise; - failed(): Promise; - pending(): Promise; -} +// @public @deprecated +export interface CatalogUnprocessedEntitiesApi + extends CatalogUnprocessedEntitiesApi_2 {} // @public export const catalogUnprocessedEntitiesApiRef: ApiRef; -// @public -export type CatalogUnprocessedEntitiesApiResponse = { - entities: UnprocessedEntity[]; -}; +// @public @deprecated +export type CatalogUnprocessedEntitiesApiResponse = + CatalogUnprocessedEntitiesApiResponse_2; // @public export const CatalogUnprocessedEntitiesPage: () => JSX_2.Element; @@ -38,37 +38,14 @@ export const catalogUnprocessedEntitiesPlugin: BackstagePlugin< // @public (undocumented) export const UnprocessedEntitiesContent: () => JSX_2.Element; -// @public -export type UnprocessedEntity = { - entity_id: string; - entity_ref: string; - unprocessed_entity: Entity; - unprocessed_hash?: string; - processed_entity?: Entity; - result_hash?: string; - cache?: UnprocessedEntityCache; - next_update_at: string | Date; - last_discovery_at: string | Date; - errors?: UnprocessedEntityError[]; - location_key?: string; -}; +// @public @deprecated +export type UnprocessedEntity = UnprocessedEntity_2; -// @public -export type UnprocessedEntityCache = { - ttl: number; - cache: object; -}; +// @public @deprecated +export type UnprocessedEntityCache = UnprocessedEntityCache_2; -// @public -export type UnprocessedEntityError = { - name: string; - message: string; - cause: { - name: string; - message: string; - stack: string; - }; -}; +// @public @deprecated +export type UnprocessedEntityError = UnprocessedEntityError_2; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/catalog-unprocessed-entities/src/api/index.ts b/plugins/catalog-unprocessed-entities/src/api/index.ts index 67daa81319..cec9bd29bd 100644 --- a/plugins/catalog-unprocessed-entities/src/api/index.ts +++ b/plugins/catalog-unprocessed-entities/src/api/index.ts @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { createApiRef } from '@backstage/core-plugin-api'; import { - DiscoveryApi, - createApiRef, - FetchApi, -} from '@backstage/core-plugin-api'; -import { ResponseError } from '@backstage/errors'; -import { UnprocessedEntity } from '../types'; + CatalogUnprocessedEntitiesApiResponse as CommonCatalogUnprocessedEntitiesApiResponse, + CatalogUnprocessedEntitiesApi as CommonCatalogUnprocessedEntitiesApi, + CatalogUnprocessedEntitiesClient as CommonCatalogUnprocessedEntitiesClient, +} from '@backstage/plugin-catalog-unprocessed-entities-common'; /** * {@link @backstage/core-plugin-api#ApiRef} for the {@link CatalogUnprocessedEntitiesApi} @@ -35,69 +34,24 @@ export const catalogUnprocessedEntitiesApiRef = * Response expected by the {@link CatalogUnprocessedEntitiesApi} * * @public + * @deprecated Use the type imported from `@backstage/plugin-catalog-unprocessed-entities-common` instead. */ -export type CatalogUnprocessedEntitiesApiResponse = { - entities: UnprocessedEntity[]; -}; +export type CatalogUnprocessedEntitiesApiResponse = + CommonCatalogUnprocessedEntitiesApiResponse; /** * Interface for the CatalogUnprocessedEntitiesApi. * * @public + * @deprecated Use the type imported from `@backstage/plugin-catalog-unprocessed-entities-common` instead. */ -export interface CatalogUnprocessedEntitiesApi { - /** - * Returns a list of entities with state 'pending' - */ - pending(): Promise; - /** - * Returns a list of entities with state 'failed' - */ - failed(): Promise; - /** - * Deletes an entity from the refresh_state table - */ - delete(entityId: string): Promise; -} +export interface CatalogUnprocessedEntitiesApi + extends CommonCatalogUnprocessedEntitiesApi {} /** * Default API implementation for the Catalog Unprocessed Entities plugin * * @public + * @deprecated Use the client imported from `@backstage/plugin-catalog-unprocessed-entities-common` instead. */ -export class CatalogUnprocessedEntitiesClient - implements CatalogUnprocessedEntitiesApi -{ - public discovery: DiscoveryApi; - public fetchApi: FetchApi; - - constructor(discovery: DiscoveryApi, fetchApi: FetchApi) { - this.discovery = discovery; - this.fetchApi = fetchApi; - } - - private async fetch(path: string, init?: RequestInit): Promise { - const url = await this.discovery.getBaseUrl('catalog'); - const resp = await this.fetchApi.fetch(`${url}/${path}`, init); - - if (!resp.ok) { - throw await ResponseError.fromResponse(resp); - } - - return resp.status === 204 ? (resp as T) : await resp.json(); - } - - async pending(): Promise { - return await this.fetch('entities/unprocessed/pending'); - } - - async failed(): Promise { - return await this.fetch('entities/unprocessed/failed'); - } - - async delete(entityId: string): Promise { - await this.fetch(`entities/unprocessed/delete/${entityId}`, { - method: 'DELETE', - }); - } -} +export class CatalogUnprocessedEntitiesClient extends CommonCatalogUnprocessedEntitiesClient {} diff --git a/plugins/catalog-unprocessed-entities/src/types.ts b/plugins/catalog-unprocessed-entities/src/types.ts index 65f21970f5..38b4b9dad7 100644 --- a/plugins/catalog-unprocessed-entities/src/types.ts +++ b/plugins/catalog-unprocessed-entities/src/types.ts @@ -13,45 +13,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Entity } from '@backstage/catalog-model'; +import type { + UnprocessedEntity as CommonUnprocessedEntity, + UnprocessedEntityCache as CommonUnprocessedEntityCache, + UnprocessedEntityError as CommonUnprocessedEntityError, +} from '@backstage/plugin-catalog-unprocessed-entities-common'; /** * Unprocessed entity data stored in the database. * @public + * @deprecated Use the type imported from `@backstage/plugin-catalog-unprocessed-entities-common` instead. */ -export type UnprocessedEntity = { - entity_id: string; - entity_ref: string; - unprocessed_entity: Entity; - unprocessed_hash?: string; - processed_entity?: Entity; - result_hash?: string; - cache?: UnprocessedEntityCache; - next_update_at: string | Date; - last_discovery_at: string | Date; // remove? - errors?: UnprocessedEntityError[]; - location_key?: string; -}; +export type UnprocessedEntity = CommonUnprocessedEntity; /** * Unprocessed entity cache stored in the database. * @public + * @deprecated Use the type imported from `@backstage/plugin-catalog-unprocessed-entities-common` instead. */ -export type UnprocessedEntityCache = { - ttl: number; - cache: object; -}; +export type UnprocessedEntityCache = CommonUnprocessedEntityCache; /** * Unprocessed entity error information stored in the database. * @public + * @deprecated Use the type imported from `@backstage/plugin-catalog-unprocessed-entities-common` instead. */ -export type UnprocessedEntityError = { - name: string; - message: string; - cause: { - name: string; - message: string; - stack: string; - }; -}; +export type UnprocessedEntityError = CommonUnprocessedEntityError; diff --git a/yarn.lock b/yarn.lock index 46fb5cf160..aeaa50bee5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5289,7 +5289,9 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-unprocessed-entities-common@workspace:plugins/catalog-unprocessed-entities-common" dependencies: + "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" + "@backstage/errors": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" languageName: unknown linkType: soft @@ -5298,13 +5300,13 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-unprocessed-entities@workspace:plugins/catalog-unprocessed-entities" dependencies: - "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/core-components": "workspace:^" "@backstage/core-plugin-api": "workspace:^" "@backstage/dev-utils": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/frontend-plugin-api": "workspace:^" + "@backstage/plugin-catalog-unprocessed-entities-common": "workspace:^" "@material-ui/core": "npm:^4.9.13" "@material-ui/icons": "npm:^4.9.1" "@material-ui/lab": "npm:^4.0.0-alpha.60"