From c87139ffa948bba9a2253c1fd689791627ddeb99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 25 Apr 2025 17:07:12 +0200 Subject: [PATCH 1/6] do not use backend-common in the integration test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../src/tests/integration.test.ts | 65 ++++++++++++------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/plugins/catalog-backend/src/tests/integration.test.ts b/plugins/catalog-backend/src/tests/integration.test.ts index aa6d241d23..76d6af1f0d 100644 --- a/plugins/catalog-backend/src/tests/integration.test.ts +++ b/plugins/catalog-backend/src/tests/integration.test.ts @@ -52,9 +52,8 @@ import { DefaultEntitiesCatalog } from '../service/DefaultEntitiesCatalog'; import { DefaultRefreshService } from '../service/DefaultRefreshService'; import { RefreshOptions, RefreshService } from '../service/types'; import { DefaultStitcher } from '../stitching/DefaultStitcher'; -import { mockServices } from '@backstage/backend-test-utils'; +import { mockServices, TestDatabases } from '@backstage/backend-test-utils'; import { LoggerService } from '@backstage/backend-plugin-api'; -import { DatabaseManager } from '@backstage/backend-common'; import { entitiesResponseToObjects } from '../service/response'; import { deleteOrphanedEntities } from '../database/operations/util/deleteOrphanedEntities'; @@ -205,10 +204,10 @@ class TestHarness { readonly #proxyProgressTracker: ProxyProgressTracker; readonly #db: Knex; - static async create(options?: { + static async create(options: { disableRelationsCompatibility?: boolean; logger?: LoggerService; - db?: Knex; + db: Knex; permissions?: PermissionEvaluator; additionalProviders?: EntityProvider[]; processEntity?( @@ -231,24 +230,19 @@ class TestHarness { }, }); const logger = options?.logger ?? mockServices.logger.mock(); - const db = - options?.db ?? - (await DatabaseManager.fromConfig(config, { logger }) - .forPlugin('catalog') - .getClient()); - await applyDatabaseMigrations(db); + await applyDatabaseMigrations(options.db); const catalogDatabase = new DefaultCatalogDatabase({ - database: db, + database: options.db, logger, }); const providerDatabase = new DefaultProviderDatabase({ - database: db, + database: options.db, logger, }); const processingDatabase = new DefaultProcessingDatabase({ - database: db, + database: options.db, logger, refreshInterval: () => 0.05, }); @@ -281,9 +275,12 @@ class TestHarness { policy: EntityPolicies.allOf([]), legacySingleProcessorValidation: false, }); - const stitcher = DefaultStitcher.fromConfig(config, { knex: db, logger }); + const stitcher = DefaultStitcher.fromConfig(config, { + knex: options.db, + logger, + }); const catalog = new DefaultEntitiesCatalog({ - database: db, + database: options.db, logger, stitcher, disableRelationsCompatibility: options?.disableRelationsCompatibility, @@ -296,7 +293,7 @@ class TestHarness { config: new ConfigReader({}), logger, processingDatabase, - knex: db, + knex: options.db, orchestrator, stitcher, createHash: () => createHash('sha1'), @@ -333,7 +330,7 @@ class TestHarness { refresh, provider, proxyProgressTracker, - db, + options.db, ); } @@ -444,10 +441,13 @@ class TestHarness { } describe('Catalog Backend Integration', () => { + const databases = TestDatabases.create({ ids: ['SQLITE_3'] }); + it('should add entities and update errors', async () => { let triggerError = false; const harness = await TestHarness.create({ + db: await databases.init('SQLITE_3'), async processEntity(entity: Entity) { if (triggerError) { throw new Error('NOPE'); @@ -525,6 +525,7 @@ describe('Catalog Backend Integration', () => { const generatedApis = ['api-1', 'api-2']; const harness = await TestHarness.create({ + db: await databases.init('SQLITE_3'), async processEntity( entity: Entity, location: LocationSpec, @@ -609,7 +610,9 @@ describe('Catalog Backend Integration', () => { }); it('should not replace matching provided entities', async () => { - const harness = await TestHarness.create(); + const harness = await TestHarness.create({ + db: await databases.init('SQLITE_3'), + }); const entityA = { apiVersion: 'backstage.io/v1alpha1', @@ -669,6 +672,7 @@ describe('Catalog Backend Integration', () => { } const harness = await TestHarness.create({ + db: await databases.init('SQLITE_3'), async processEntity( entity: Entity, location: LocationSpec, @@ -788,7 +792,9 @@ describe('Catalog Backend Integration', () => { }); it('should reject insecure URLs', async () => { - const harness = await TestHarness.create(); + const harness = await TestHarness.create({ + db: await databases.init('SQLITE_3'), + }); await harness.setInputEntities([ { @@ -827,7 +833,9 @@ describe('Catalog Backend Integration', () => { }); it('should reject insecure location URLs', async () => { - const harness = await TestHarness.create(); + const harness = await TestHarness.create({ + db: await databases.init('SQLITE_3'), + }); await harness.setInputEntities([ { @@ -854,6 +862,7 @@ describe('Catalog Backend Integration', () => { it('should return valid responses in raw JSON mode', async () => { const harness = await TestHarness.create({ + db: await databases.init('SQLITE_3'), disableRelationsCompatibility: true, }); @@ -910,6 +919,7 @@ describe('Catalog Backend Integration', () => { const secondProvider = new TestProvider('second'); const harness = await TestHarness.create({ + db: await databases.init('SQLITE_3'), additionalProviders: [firstProvider, secondProvider], }); @@ -1066,7 +1076,10 @@ describe('Catalog Backend Integration', () => { _emit: CatalogProcessorEmit, ) => entity, ); - const harness = await TestHarness.create({ processEntity }); + const harness = await TestHarness.create({ + db: await databases.init('SQLITE_3'), + processEntity, + }); processEntity.mockImplementation(async (entity, location, emit) => { if (entity.metadata.name === entityA.metadata.name) { @@ -1189,7 +1202,10 @@ describe('Catalog Backend Integration', () => { _emit: CatalogProcessorEmit, ) => entity, ); - const harness = await TestHarness.create({ processEntity }); + const harness = await TestHarness.create({ + db: await databases.init('SQLITE_3'), + processEntity, + }); processEntity.mockImplementation(async (entity, location, emit) => { if (entity.metadata.name === entityA.metadata.name) { @@ -1246,7 +1262,10 @@ describe('Catalog Backend Integration', () => { _emit: CatalogProcessorEmit, ) => entity, ); - const harness = await TestHarness.create({ processEntity }); + const harness = await TestHarness.create({ + db: await databases.init('SQLITE_3'), + processEntity, + }); processEntity.mockImplementation(async (entity, location, emit) => { if (entity.metadata.name === entityA.metadata.name) { From 6c9b88e70cf5d5636c621e5c6af11d8d5b92a2f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 25 Apr 2025 15:01:18 +0200 Subject: [PATCH 2/6] remove the alpha export of the plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/chatty-showers-cheat.md | 5 +++++ plugins/catalog-backend/dev/index.ts | 2 +- plugins/catalog-backend/report-alpha.api.md | 5 ----- plugins/catalog-backend/src/alpha.ts | 6 ------ 4 files changed, 6 insertions(+), 12 deletions(-) create mode 100644 .changeset/chatty-showers-cheat.md diff --git a/.changeset/chatty-showers-cheat.md b/.changeset/chatty-showers-cheat.md new file mode 100644 index 0000000000..24c2720fb6 --- /dev/null +++ b/.changeset/chatty-showers-cheat.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': minor +--- + +**BREAKING ALPHA**: You can no longer import the catalog plugin from the `/alpha` export; please use the regular root default export instead. diff --git a/plugins/catalog-backend/dev/index.ts b/plugins/catalog-backend/dev/index.ts index 43c75d24df..dc287d46cc 100644 --- a/plugins/catalog-backend/dev/index.ts +++ b/plugins/catalog-backend/dev/index.ts @@ -17,5 +17,5 @@ import { createBackend } from '@backstage/backend-defaults'; const backend = createBackend(); -backend.add(import('../src/alpha')); +backend.add(import('../src')); backend.start(); diff --git a/plugins/catalog-backend/report-alpha.api.md b/plugins/catalog-backend/report-alpha.api.md index d32ef323c9..ca521a568d 100644 --- a/plugins/catalog-backend/report-alpha.api.md +++ b/plugins/catalog-backend/report-alpha.api.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; import { ConditionalPolicyDecision } from '@backstage/plugin-permission-common'; import { Conditions } from '@backstage/plugin-permission-node'; import { EntitiesSearchFilter } from '@backstage/plugin-catalog-node'; @@ -87,10 +86,6 @@ export const createCatalogPermissionRule: < rule: PermissionRule, ) => PermissionRule; -// @alpha (undocumented) -const _feature: BackendFeature; -export default _feature; - // @alpha export const permissionRules: { hasAnnotation: PermissionRule< diff --git a/plugins/catalog-backend/src/alpha.ts b/plugins/catalog-backend/src/alpha.ts index 4d40b8733e..82585fcf1d 100644 --- a/plugins/catalog-backend/src/alpha.ts +++ b/plugins/catalog-backend/src/alpha.ts @@ -14,10 +14,4 @@ * limitations under the License. */ -import { catalogPlugin } from './service/CatalogPlugin'; - -/** @alpha */ -const _feature = catalogPlugin; -export default _feature; - export * from './permissions'; From 90ab044afe8d890741007f964b24288a77c04aab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 25 Apr 2025 16:11:13 +0200 Subject: [PATCH 3/6] remove all regular deprecated exports except the builder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/sad-showers-begin.md | 57 ++ plugins/catalog-backend/package.json | 2 - plugins/catalog-backend/report.api.md | 338 ++---------- plugins/catalog-backend/src/deprecated.ts | 502 ------------------ plugins/catalog-backend/src/index.ts | 2 - .../LocationEntityProcessor.test.ts | 87 --- .../src/processors/LocationEntityProcessor.ts | 110 ---- .../catalog-backend/src/processors/index.ts | 2 - .../src/search/DefaultCatalogCollator.test.ts | 159 ------ .../src/search/DefaultCatalogCollator.ts | 137 ----- plugins/catalog-backend/src/search/index.ts | 20 - yarn.lock | 2 - 12 files changed, 104 insertions(+), 1314 deletions(-) create mode 100644 .changeset/sad-showers-begin.md delete mode 100644 plugins/catalog-backend/src/deprecated.ts delete mode 100644 plugins/catalog-backend/src/processors/LocationEntityProcessor.test.ts delete mode 100644 plugins/catalog-backend/src/processors/LocationEntityProcessor.ts delete mode 100644 plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts delete mode 100644 plugins/catalog-backend/src/search/DefaultCatalogCollator.ts delete mode 100644 plugins/catalog-backend/src/search/index.ts diff --git a/.changeset/sad-showers-begin.md b/.changeset/sad-showers-begin.md new file mode 100644 index 0000000000..eccbd9981c --- /dev/null +++ b/.changeset/sad-showers-begin.md @@ -0,0 +1,57 @@ +--- +'@backstage/plugin-catalog-backend': major +--- + +**BREAKING**: Removed all deprecated exports. + +The following removed exports are available from `@backstage/plugin-catalog-node`: + +- `locationSpecToMetadataName` +- `locationSpecToLocationEntity` +- `processingResult` +- `EntitiesSearchFilter` +- `EntityFilter` +- `DeferredEntity` +- `EntityRelationSpec` +- `CatalogProcessor` +- `CatalogProcessorParser` +- `CatalogProcessorCache` +- `CatalogProcessorEmit` +- `CatalogProcessorLocationResult` +- `CatalogProcessorEntityResult` +- `CatalogProcessorRelationResult` +- `CatalogProcessorErrorResult` +- `CatalogProcessorRefreshKeysResult` +- `CatalogProcessorResult` +- `EntityProvider` +- `EntityProviderConnection` +- `EntityProviderMutation` +- `AnalyzeOptions` +- `LocationAnalyzer` +- `ScmLocationAnalyzer` +- `PlaceholderResolver` +- `PlaceholderResolverParams` +- `PlaceholderResolverRead` +- `PlaceholderResolverResolveUrl` + +The following removed exports are available from `@backstage/plugin-catalog-common`: + +- `LocationSpec` +- `AnalyzeLocationRequest` +- `AnalyzeLocationResponse` +- `AnalyzeLocationExistingEntity` +- `AnalyzeLocationGenerateEntity` +- `AnalyzeLocationEntityField` + +The following removed exports are instead implemented in the new backend system by `@backstage/plugin-search-backend-module-catalog`: + +- `defaultCatalogCollatorEntityTransformer` +- `CatalogCollatorEntityTransformer` +- `DefaultCatalogCollator` + +The following exports are removed without a direct replacement: + +- `DefaultCatalogCollatorFactory` +- `DefaultCatalogCollatorFactoryOptions` +- `LocationEntityProcessor` +- `LocationEntityProcessorOptions` diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 930851b350..fb6032342b 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -74,8 +74,6 @@ "@backstage/plugin-events-node": "workspace:^", "@backstage/plugin-permission-common": "workspace:^", "@backstage/plugin-permission-node": "workspace:^", - "@backstage/plugin-search-backend-module-catalog": "workspace:^", - "@backstage/plugin-search-common": "workspace:^", "@backstage/types": "workspace:^", "@opentelemetry/api": "^1.9.0", "@types/express": "^4.17.6", diff --git a/plugins/catalog-backend/report.api.md b/plugins/catalog-backend/report.api.md index 3a47cc4354..e92e688aa4 100644 --- a/plugins/catalog-backend/report.api.md +++ b/plugins/catalog-backend/report.api.md @@ -3,49 +3,26 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { AnalyzeLocationEntityField as AnalyzeLocationEntityField_2 } from '@backstage/plugin-catalog-common'; -import { AnalyzeLocationExistingEntity as AnalyzeLocationExistingEntity_2 } from '@backstage/plugin-catalog-common'; -import { AnalyzeLocationGenerateEntity as AnalyzeLocationGenerateEntity_2 } from '@backstage/plugin-catalog-common'; -import { AnalyzeLocationRequest as AnalyzeLocationRequest_2 } from '@backstage/plugin-catalog-common'; -import { AnalyzeLocationResponse as AnalyzeLocationResponse_2 } from '@backstage/plugin-catalog-common'; -import { AnalyzeOptions as AnalyzeOptions_2 } from '@backstage/plugin-catalog-node'; import { AuditorService } from '@backstage/backend-plugin-api'; import { AuthService } from '@backstage/backend-plugin-api'; import { BackendFeature } from '@backstage/backend-plugin-api'; -import { CatalogApi } from '@backstage/catalog-client'; -import { CatalogCollatorEntityTransformer as CatalogCollatorEntityTransformer_2 } from '@backstage/plugin-search-backend-module-catalog'; -import { CatalogEntityDocument } from '@backstage/plugin-catalog-common'; -import { CatalogProcessor as CatalogProcessor_2 } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorCache as CatalogProcessorCache_2 } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorEmit as CatalogProcessorEmit_2 } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorEntityResult as CatalogProcessorEntityResult_2 } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorErrorResult as CatalogProcessorErrorResult_2 } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorLocationResult as CatalogProcessorLocationResult_2 } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorParser as CatalogProcessorParser_2 } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorRefreshKeysResult as CatalogProcessorRefreshKeysResult_2 } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorRelationResult as CatalogProcessorRelationResult_2 } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorResult as CatalogProcessorResult_2 } from '@backstage/plugin-catalog-node'; +import { CatalogProcessor } from '@backstage/plugin-catalog-node'; +import { CatalogProcessorCache } from '@backstage/plugin-catalog-node'; +import { CatalogProcessorEmit } from '@backstage/plugin-catalog-node'; +import { CatalogProcessorParser } from '@backstage/plugin-catalog-node'; +import { CatalogProcessorResult } from '@backstage/plugin-catalog-node'; import { Config } from '@backstage/config'; import { DatabaseService } from '@backstage/backend-plugin-api'; -import { DeferredEntity as DeferredEntity_2 } from '@backstage/plugin-catalog-node'; import { DiscoveryService } from '@backstage/backend-plugin-api'; -import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; -import { EntitiesSearchFilter as EntitiesSearchFilter_2 } from '@backstage/plugin-catalog-node'; +import { EntitiesSearchFilter } from '@backstage/plugin-catalog-node'; import { Entity } from '@backstage/catalog-model'; -import { EntityFilter as EntityFilter_2 } from '@backstage/plugin-catalog-node'; import { EntityPolicy } from '@backstage/catalog-model'; -import { EntityProvider as EntityProvider_2 } from '@backstage/plugin-catalog-node'; -import { EntityProviderConnection as EntityProviderConnection_2 } from '@backstage/plugin-catalog-node'; -import { EntityProviderMutation as EntityProviderMutation_2 } from '@backstage/plugin-catalog-node'; -import { EntityRelationSpec as EntityRelationSpec_2 } from '@backstage/plugin-catalog-node'; +import { EntityProvider } from '@backstage/plugin-catalog-node'; import { EventBroker } from '@backstage/plugin-events-node'; import { EventsService } from '@backstage/plugin-events-node'; -import { GetEntitiesRequest } from '@backstage/catalog-client'; import { HttpAuthService } from '@backstage/backend-plugin-api'; -import { LocationAnalyzer as LocationAnalyzer_2 } from '@backstage/plugin-catalog-node'; -import { LocationSpec as LocationSpec_2 } from '@backstage/plugin-catalog-common'; -import { locationSpecToLocationEntity as locationSpecToLocationEntity_2 } from '@backstage/plugin-catalog-node'; -import { locationSpecToMetadataName as locationSpecToMetadataName_2 } from '@backstage/plugin-catalog-node'; +import { LocationAnalyzer } from '@backstage/plugin-catalog-node'; +import { LocationSpec } from '@backstage/plugin-catalog-common'; import { LoggerService } from '@backstage/backend-plugin-api'; import { Permission } from '@backstage/plugin-permission-common'; import { PermissionAuthorizer } from '@backstage/plugin-permission-common'; @@ -53,54 +30,31 @@ import { PermissionRule } from '@backstage/plugin-permission-node'; import { PermissionRuleParams } from '@backstage/plugin-permission-common'; import { PermissionsRegistryService } from '@backstage/backend-plugin-api'; import { PermissionsService } from '@backstage/backend-plugin-api'; -import { PlaceholderResolver as PlaceholderResolver_2 } from '@backstage/plugin-catalog-node'; -import { PlaceholderResolverParams as PlaceholderResolverParams_2 } from '@backstage/plugin-catalog-node'; -import { PlaceholderResolverRead as PlaceholderResolverRead_2 } from '@backstage/plugin-catalog-node'; -import { PlaceholderResolverResolveUrl as PlaceholderResolverResolveUrl_2 } from '@backstage/plugin-catalog-node'; -import { Readable } from 'stream'; +import { PlaceholderResolver } from '@backstage/plugin-catalog-node'; import { RootConfigService } from '@backstage/backend-plugin-api'; import { Router } from 'express'; import { SchedulerService } from '@backstage/backend-plugin-api'; import { ScmIntegrationRegistry } from '@backstage/integration'; -import { ScmLocationAnalyzer as ScmLocationAnalyzer_2 } from '@backstage/plugin-catalog-node'; -import { TokenManager } from '@backstage/backend-common'; +import { ScmLocationAnalyzer } from '@backstage/plugin-catalog-node'; import { UrlReaderService } from '@backstage/backend-plugin-api'; import { Validators } from '@backstage/catalog-model'; -// @public @deprecated -export type AnalyzeLocationEntityField = AnalyzeLocationEntityField_2; - -// @public @deprecated -export type AnalyzeLocationExistingEntity = AnalyzeLocationExistingEntity_2; - -// @public @deprecated -export type AnalyzeLocationGenerateEntity = AnalyzeLocationGenerateEntity_2; - -// @public @deprecated (undocumented) -export type AnalyzeLocationRequest = AnalyzeLocationRequest_2; - -// @public @deprecated (undocumented) -export type AnalyzeLocationResponse = AnalyzeLocationResponse_2; - -// @public @deprecated (undocumented) -export type AnalyzeOptions = AnalyzeOptions_2; - // @public (undocumented) -export class AnnotateLocationEntityProcessor implements CatalogProcessor_2 { +export class AnnotateLocationEntityProcessor implements CatalogProcessor { constructor(options: { integrations: ScmIntegrationRegistry }); // (undocumented) getProcessorName(): string; // (undocumented) preProcessEntity( entity: Entity, - location: LocationSpec_2, - _: CatalogProcessorEmit_2, - originLocation: LocationSpec_2, + location: LocationSpec, + _: CatalogProcessorEmit, + originLocation: LocationSpec, ): Promise; } // @public (undocumented) -export class AnnotateScmSlugEntityProcessor implements CatalogProcessor_2 { +export class AnnotateScmSlugEntityProcessor implements CatalogProcessor { constructor(opts: { scmIntegrationRegistry: ScmIntegrationRegistry; kinds?: string[]; @@ -115,18 +69,18 @@ export class AnnotateScmSlugEntityProcessor implements CatalogProcessor_2 { // (undocumented) getProcessorName(): string; // (undocumented) - preProcessEntity(entity: Entity, location: LocationSpec_2): Promise; + preProcessEntity(entity: Entity, location: LocationSpec): Promise; } // @public (undocumented) -export class BuiltinKindsEntityProcessor implements CatalogProcessor_2 { +export class BuiltinKindsEntityProcessor implements CatalogProcessor { // (undocumented) getProcessorName(): string; // (undocumented) postProcessEntity( entity: Entity, - _location: LocationSpec_2, - emit: CatalogProcessorEmit_2, + _location: LocationSpec, + emit: CatalogProcessorEmit, ): Promise; // (undocumented) validateEntityKind(entity: Entity): Promise; @@ -144,10 +98,10 @@ export class CatalogBuilder { ...policies: Array> ): CatalogBuilder; addEntityProvider( - ...providers: Array> + ...providers: Array> ): CatalogBuilder; addLocationAnalyzers( - ...analyzers: Array> + ...analyzers: Array> ): CatalogBuilder; addPermissionRules( ...permissionRules: Array< @@ -156,24 +110,24 @@ export class CatalogBuilder { ): this; addPermissions(...permissions: Array>): this; addProcessor( - ...processors: Array> + ...processors: Array> ): CatalogBuilder; build(): Promise<{ processingEngine: CatalogProcessingEngine; router: Router; }>; static create(env: CatalogEnvironment): CatalogBuilder; - getDefaultProcessors(): CatalogProcessor_2[]; + getDefaultProcessors(): CatalogProcessor[]; replaceEntityPolicies(policies: EntityPolicy[]): CatalogBuilder; - replaceProcessors(processors: CatalogProcessor_2[]): CatalogBuilder; + replaceProcessors(processors: CatalogProcessor[]): CatalogBuilder; setAllowedLocationTypes(allowedLocationTypes: string[]): CatalogBuilder; - setEntityDataParser(parser: CatalogProcessorParser_2): CatalogBuilder; + setEntityDataParser(parser: CatalogProcessorParser): CatalogBuilder; setEventBroker(broker: EventBroker | EventsService): CatalogBuilder; setFieldFormatValidators(validators: Partial): CatalogBuilder; - setLocationAnalyzer(locationAnalyzer: LocationAnalyzer_2): CatalogBuilder; + setLocationAnalyzer(locationAnalyzer: LocationAnalyzer): CatalogBuilder; setPlaceholderResolver( key: string, - resolver: PlaceholderResolver_2, + resolver: PlaceholderResolver, ): CatalogBuilder; setProcessingInterval( processingInterval: ProcessingIntervalFunction, @@ -189,10 +143,6 @@ export class CatalogBuilder { useLegacySingleProcessorValidation(): this; } -// @public @deprecated (undocumented) -export type CatalogCollatorEntityTransformer = - CatalogCollatorEntityTransformer_2; - // @public @deprecated (undocumented) export type CatalogEnvironment = { logger: LoggerService; @@ -211,7 +161,7 @@ export type CatalogEnvironment = { // @public export type CatalogPermissionRuleInput< TParams extends PermissionRuleParams = PermissionRuleParams, -> = PermissionRule; +> = PermissionRule; // @public const catalogPlugin: BackendFeature; @@ -225,39 +175,8 @@ export interface CatalogProcessingEngine { stop(): Promise; } -// @public @deprecated (undocumented) -export type CatalogProcessor = CatalogProcessor_2; - -// @public @deprecated (undocumented) -export type CatalogProcessorCache = CatalogProcessorCache_2; - -// @public @deprecated (undocumented) -export type CatalogProcessorEmit = CatalogProcessorEmit_2; - -// @public @deprecated (undocumented) -export type CatalogProcessorEntityResult = CatalogProcessorEntityResult_2; - -// @public @deprecated (undocumented) -export type CatalogProcessorErrorResult = CatalogProcessorErrorResult_2; - -// @public @deprecated (undocumented) -export type CatalogProcessorLocationResult = CatalogProcessorLocationResult_2; - -// @public @deprecated (undocumented) -export type CatalogProcessorParser = CatalogProcessorParser_2; - -// @public @deprecated (undocumented) -export type CatalogProcessorRefreshKeysResult = - CatalogProcessorRefreshKeysResult_2; - -// @public @deprecated (undocumented) -export type CatalogProcessorRelationResult = CatalogProcessorRelationResult_2; - -// @public @deprecated (undocumented) -export type CatalogProcessorResult = CatalogProcessorResult_2; - // @public (undocumented) -export class CodeOwnersProcessor implements CatalogProcessor_2 { +export class CodeOwnersProcessor implements CatalogProcessor { constructor(options: { integrations: ScmIntegrationRegistry; logger: LoggerService; @@ -274,7 +193,7 @@ export class CodeOwnersProcessor implements CatalogProcessor_2 { // (undocumented) getProcessorName(): string; // (undocumented) - preProcessEntity(entity: Entity, location: LocationSpec_2): Promise; + preProcessEntity(entity: Entity, location: LocationSpec): Promise; } // @public @@ -283,218 +202,55 @@ export function createRandomProcessingInterval(options: { maxSeconds: number; }): ProcessingIntervalFunction; -// @public @deprecated (undocumented) -export class DefaultCatalogCollator { - constructor(options: { - discovery: DiscoveryService; - tokenManager: TokenManager; - locationTemplate?: string; - filter?: GetEntitiesRequest['filter']; - catalogClient?: CatalogApi; - }); - // (undocumented) - protected applyArgsToFormat( - format: string, - args: Record, - ): string; - // (undocumented) - protected readonly catalogClient: CatalogApi; - // (undocumented) - protected discovery: DiscoveryService; - // (undocumented) - execute(): Promise; - // (undocumented) - protected filter?: GetEntitiesRequest['filter']; - // (undocumented) - static fromConfig( - _config: Config, - options: { - discovery: DiscoveryService; - tokenManager: TokenManager; - filter?: GetEntitiesRequest['filter']; - }, - ): DefaultCatalogCollator; - // (undocumented) - protected locationTemplate: string; - // (undocumented) - protected tokenManager: TokenManager; - // (undocumented) - readonly type: string; - // (undocumented) - readonly visibilityPermission: Permission; -} - -// @public @deprecated (undocumented) -export const defaultCatalogCollatorEntityTransformer: CatalogCollatorEntityTransformer_2; - -// @public @deprecated (undocumented) -export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory { - // (undocumented) - static fromConfig( - configRoot: Config, - options: DefaultCatalogCollatorFactoryOptions, - ): DefaultCatalogCollatorFactory; - // (undocumented) - getCollator(): Promise; - // (undocumented) - readonly type = 'software-catalog'; - // (undocumented) - readonly visibilityPermission: Permission; -} - -// @public @deprecated (undocumented) -export type DefaultCatalogCollatorFactoryOptions = { - auth?: AuthService; - discovery: DiscoveryService; - tokenManager?: TokenManager; - locationTemplate?: string; - filter?: GetEntitiesRequest['filter']; - batchSize?: number; - catalogClient?: CatalogApi; - entityTransformer?: CatalogCollatorEntityTransformer; -}; - -// @public @deprecated (undocumented) -export type DeferredEntity = DeferredEntity_2; - -// @public @deprecated (undocumented) -export type EntitiesSearchFilter = EntitiesSearchFilter_2; - -// @public @deprecated (undocumented) -export type EntityFilter = EntityFilter_2; - -// @public @deprecated (undocumented) -export type EntityProvider = EntityProvider_2; - -// @public @deprecated (undocumented) -export type EntityProviderConnection = EntityProviderConnection_2; - -// @public @deprecated (undocumented) -export type EntityProviderMutation = EntityProviderMutation_2; - -// @public @deprecated (undocumented) -export type EntityRelationSpec = EntityRelationSpec_2; - // @public (undocumented) -export class FileReaderProcessor implements CatalogProcessor_2 { +export class FileReaderProcessor implements CatalogProcessor { // (undocumented) getProcessorName(): string; // (undocumented) readLocation( - location: LocationSpec_2, + location: LocationSpec, optional: boolean, - emit: CatalogProcessorEmit_2, - parser: CatalogProcessorParser_2, + emit: CatalogProcessorEmit, + parser: CatalogProcessorParser, ): Promise; } -// @public @deprecated (undocumented) -export type LocationAnalyzer = LocationAnalyzer_2; - -// @public @deprecated -export class LocationEntityProcessor implements CatalogProcessor_2 { - constructor(options: LocationEntityProcessorOptions); - // (undocumented) - getProcessorName(): string; - // (undocumented) - postProcessEntity( - entity: Entity, - location: LocationSpec_2, - emit: CatalogProcessorEmit_2, - ): Promise; -} - -// @public @deprecated (undocumented) -export type LocationEntityProcessorOptions = { - integrations: ScmIntegrationRegistry; -}; - -// @public @deprecated -export type LocationSpec = LocationSpec_2; - -// @public @deprecated (undocumented) -export const locationSpecToLocationEntity: typeof locationSpecToLocationEntity_2; - -// @public @deprecated (undocumented) -export const locationSpecToMetadataName: typeof locationSpecToMetadataName_2; - // @public (undocumented) export function parseEntityYaml( data: Buffer, - location: LocationSpec_2, -): Iterable; + location: LocationSpec, +): Iterable; // @public -export class PlaceholderProcessor implements CatalogProcessor_2 { +export class PlaceholderProcessor implements CatalogProcessor { constructor(options: PlaceholderProcessorOptions); // (undocumented) getProcessorName(): string; // (undocumented) preProcessEntity( entity: Entity, - location: LocationSpec_2, - emit: CatalogProcessorEmit_2, + location: LocationSpec, + emit: CatalogProcessorEmit, ): Promise; } // @public (undocumented) export type PlaceholderProcessorOptions = { - resolvers: Record; + resolvers: Record; reader: UrlReaderService; integrations: ScmIntegrationRegistry; }; -// @public @deprecated (undocumented) -export type PlaceholderResolver = PlaceholderResolver_2; - -// @public @deprecated (undocumented) -export type PlaceholderResolverParams = PlaceholderResolverParams_2; - -// @public @deprecated (undocumented) -export type PlaceholderResolverRead = PlaceholderResolverRead_2; - -// @public @deprecated (undocumented) -export type PlaceholderResolverResolveUrl = PlaceholderResolverResolveUrl_2; - // @public export type ProcessingIntervalFunction = () => number; -// @public @deprecated (undocumented) -export const processingResult: Readonly<{ - readonly notFoundError: ( - atLocation: LocationSpec_2, - message: string, - ) => CatalogProcessorResult_2; - readonly inputError: ( - atLocation: LocationSpec_2, - message: string, - ) => CatalogProcessorResult_2; - readonly generalError: ( - atLocation: LocationSpec_2, - message: string, - ) => CatalogProcessorResult_2; - readonly location: (newLocation: LocationSpec_2) => CatalogProcessorResult_2; - readonly entity: ( - atLocation: LocationSpec_2, - newEntity: Entity, - options?: { - locationKey?: string | null; - }, - ) => CatalogProcessorResult_2; - readonly relation: (spec: EntityRelationSpec_2) => CatalogProcessorResult_2; - readonly refresh: (key: string) => CatalogProcessorResult_2; -}>; - -// @public @deprecated (undocumented) -export type ScmLocationAnalyzer = ScmLocationAnalyzer_2; - // @public export function transformLegacyPolicyToProcessor( policy: EntityPolicy, -): CatalogProcessor_2; +): CatalogProcessor; // @public (undocumented) -export class UrlReaderProcessor implements CatalogProcessor_2 { +export class UrlReaderProcessor implements CatalogProcessor { constructor(options: { reader: UrlReaderService; logger: LoggerService; @@ -504,11 +260,11 @@ export class UrlReaderProcessor implements CatalogProcessor_2 { getProcessorName(): string; // (undocumented) readLocation( - location: LocationSpec_2, + location: LocationSpec, optional: boolean, - emit: CatalogProcessorEmit_2, - parser: CatalogProcessorParser_2, - cache: CatalogProcessorCache_2, + emit: CatalogProcessorEmit, + parser: CatalogProcessorParser, + cache: CatalogProcessorCache, ): Promise; } ``` diff --git a/plugins/catalog-backend/src/deprecated.ts b/plugins/catalog-backend/src/deprecated.ts deleted file mode 100644 index 023e93e664..0000000000 --- a/plugins/catalog-backend/src/deprecated.ts +++ /dev/null @@ -1,502 +0,0 @@ -/* - * 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 { - TokenManager, - createLegacyAuthAdapters, -} from '@backstage/backend-common'; -import { AuthService, DiscoveryService } from '@backstage/backend-plugin-api'; -import { - CatalogApi, - CatalogClient, - EntityFilterQuery, - GetEntitiesRequest, -} from '@backstage/catalog-client'; -import { - Entity, - isGroupEntity, - isUserEntity, - stringifyEntityRef, -} from '@backstage/catalog-model'; -import { Config } from '@backstage/config'; -import { - CatalogEntityDocument, - type AnalyzeLocationEntityField as _AnalyzeLocationEntityField, - type AnalyzeLocationExistingEntity as _AnalyzeLocationExistingEntity, - type AnalyzeLocationGenerateEntity as _AnalyzeLocationGenerateEntity, - type AnalyzeLocationRequest as _AnalyzeLocationRequest, - type AnalyzeLocationResponse as _AnalyzeLocationResponse, - type LocationSpec as _LocationSpec, -} from '@backstage/plugin-catalog-common'; -import { catalogEntityReadPermission } from '@backstage/plugin-catalog-common/alpha'; -import { - locationSpecToMetadataName as _locationSpecToMetadataName, - locationSpecToLocationEntity as _locationSpecToLocationEntity, - processingResult as _processingResult, - type EntitiesSearchFilter as _EntitiesSearchFilter, - type EntityFilter as _EntityFilter, - type DeferredEntity as _DeferredEntity, - type EntityRelationSpec as _EntityRelationSpec, - type CatalogProcessor as _CatalogProcessor, - type CatalogProcessorParser as _CatalogProcessorParser, - type CatalogProcessorCache as _CatalogProcessorCache, - type CatalogProcessorEmit as _CatalogProcessorEmit, - type CatalogProcessorLocationResult as _CatalogProcessorLocationResult, - type CatalogProcessorEntityResult as _CatalogProcessorEntityResult, - type CatalogProcessorRelationResult as _CatalogProcessorRelationResult, - type CatalogProcessorErrorResult as _CatalogProcessorErrorResult, - type CatalogProcessorRefreshKeysResult as _CatalogProcessorRefreshKeysResult, - type CatalogProcessorResult as _CatalogProcessorResult, - type EntityProvider as _EntityProvider, - type EntityProviderConnection as _EntityProviderConnection, - type EntityProviderMutation as _EntityProviderMutation, - type AnalyzeOptions as _AnalyzeOptions, - type PlaceholderResolver as _PlaceholderResolver, - type PlaceholderResolverParams as _PlaceholderResolverParams, - type PlaceholderResolverRead as _PlaceholderResolverRead, - type PlaceholderResolverResolveUrl as _PlaceholderResolverResolveUrl, - type LocationAnalyzer as _LocationAnalyzer, - type ScmLocationAnalyzer as _ScmLocationAnalyzer, -} from '@backstage/plugin-catalog-node'; -import { Permission } from '@backstage/plugin-permission-common'; -import { - defaultCatalogCollatorEntityTransformer as _defaultCatalogCollatorEntityTransformer, - type CatalogCollatorEntityTransformer as _CatalogCollatorEntityTransformer, -} from '@backstage/plugin-search-backend-module-catalog'; -import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; -import { Readable } from 'stream'; - -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export const locationSpecToMetadataName = _locationSpecToMetadataName; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export const locationSpecToLocationEntity = _locationSpecToLocationEntity; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export const processingResult = _processingResult; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type EntitiesSearchFilter = _EntitiesSearchFilter; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type EntityFilter = _EntityFilter; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type DeferredEntity = _DeferredEntity; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type EntityRelationSpec = _EntityRelationSpec; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessor = _CatalogProcessor; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessorParser = _CatalogProcessorParser; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessorCache = _CatalogProcessorCache; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessorEmit = _CatalogProcessorEmit; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessorLocationResult = _CatalogProcessorLocationResult; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessorEntityResult = _CatalogProcessorEntityResult; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessorRelationResult = _CatalogProcessorRelationResult; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessorErrorResult = _CatalogProcessorErrorResult; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessorRefreshKeysResult = - _CatalogProcessorRefreshKeysResult; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessorResult = _CatalogProcessorResult; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type EntityProvider = _EntityProvider; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type EntityProviderConnection = _EntityProviderConnection; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type EntityProviderMutation = _EntityProviderMutation; - -/** - * Holds the entity location information. - * - * @remarks - * - * `presence` flag: when using repo importer plugin, location is being created before the component yaml file is merged to the main branch. - * This flag is then set to indicate that the file can be not present. - * default value: 'required'. - * - * @public - * @deprecated use the same type from `@backstage/plugin-catalog-common` instead - */ -export type LocationSpec = _LocationSpec; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type AnalyzeOptions = _AnalyzeOptions; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type LocationAnalyzer = _LocationAnalyzer; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type ScmLocationAnalyzer = _ScmLocationAnalyzer; - -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type PlaceholderResolver = _PlaceholderResolver; - -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type PlaceholderResolverParams = _PlaceholderResolverParams; - -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type PlaceholderResolverRead = _PlaceholderResolverRead; - -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type PlaceholderResolverResolveUrl = _PlaceholderResolverResolveUrl; - -/** - * @public - * @deprecated use the same type from `@backstage/plugin-catalog-common` instead - */ -export type AnalyzeLocationRequest = _AnalyzeLocationRequest; -/** - * @public - * @deprecated use the same type from `@backstage/plugin-catalog-common` instead - */ -export type AnalyzeLocationResponse = _AnalyzeLocationResponse; - -/** - * If the folder pointed to already contained catalog info yaml files, they are - * read and emitted like this so that the frontend can inform the user that it - * located them and can make sure to register them as well if they weren't - * already - * @public - * @deprecated use the same type from `@backstage/plugin-catalog-common` instead - */ -export type AnalyzeLocationExistingEntity = _AnalyzeLocationExistingEntity; -/** - * This is some form of representation of what the analyzer could deduce. - * We should probably have a chat about how this can best be conveyed to - * the frontend. It'll probably contain a (possibly incomplete) entity, plus - * enough info for the frontend to know what form data to show to the user - * for overriding/completing the info. - * @public - * @deprecated use the same type from `@backstage/plugin-catalog-common` instead - */ -export type AnalyzeLocationGenerateEntity = _AnalyzeLocationGenerateEntity; - -/** - * - * This is where I get really vague. Something like this perhaps? Or it could be - * something like a json-schema that contains enough info for the frontend to - * be able to present a form and explanations - * @public - * @deprecated use the same type from `@backstage/plugin-catalog-common` instead - */ -export type AnalyzeLocationEntityField = _AnalyzeLocationEntityField; - -namespace search { - const configKey = 'search.collators.catalog'; - - const defaults = { - schedule: { - frequency: { minutes: 10 }, - timeout: { minutes: 15 }, - initialDelay: { seconds: 3 }, - }, - collatorOptions: { - locationTemplate: '/catalog/:namespace/:kind/:name', - filter: undefined, - batchSize: 500, - }, - }; - - export const readCollatorConfigOptions = ( - configRoot: Config, - ): { - locationTemplate: string; - filter: EntityFilterQuery | undefined; - batchSize: number; - } => { - const config = configRoot.getOptionalConfig(configKey); - if (!config) { - return defaults.collatorOptions; - } - - return { - locationTemplate: - config.getOptionalString('locationTemplate') ?? - defaults.collatorOptions.locationTemplate, - filter: - config.getOptional('filter') ?? - defaults.collatorOptions.filter, - batchSize: - config.getOptionalNumber('batchSize') ?? - defaults.collatorOptions.batchSize, - }; - }; - - export const getDocumentText = (entity: Entity): string => { - const documentTexts: string[] = []; - if (entity.metadata.description) { - documentTexts.push(entity.metadata.description); - } - - if (isUserEntity(entity) || isGroupEntity(entity)) { - if (entity.spec?.profile?.displayName) { - documentTexts.push(entity.spec.profile.displayName); - } - } - - if (isUserEntity(entity)) { - if (entity.spec?.profile?.email) { - documentTexts.push(entity.spec.profile.email); - } - } - - return documentTexts.join(' : '); - }; -} - -/** - * @public - * @deprecated import from `@backstage/plugin-search-backend-module-catalog` instead - */ -export const defaultCatalogCollatorEntityTransformer = - _defaultCatalogCollatorEntityTransformer; - -/** - * @public - * @deprecated This is no longer supported since the new backend system migration - */ -export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory { - public readonly type = 'software-catalog'; - public readonly visibilityPermission: Permission = - catalogEntityReadPermission; - - private locationTemplate: string; - private filter?: GetEntitiesRequest['filter']; - private batchSize: number; - private readonly catalogClient: CatalogApi; - private entityTransformer: CatalogCollatorEntityTransformer; - private auth: AuthService; - - static fromConfig( - configRoot: Config, - options: DefaultCatalogCollatorFactoryOptions, - ) { - const configOptions = search.readCollatorConfigOptions(configRoot); - const { auth: adaptedAuth } = createLegacyAuthAdapters({ - auth: options.auth, - discovery: options.discovery, - tokenManager: options.tokenManager, - }); - return new DefaultCatalogCollatorFactory({ - locationTemplate: - options.locationTemplate ?? configOptions.locationTemplate, - filter: options.filter ?? configOptions.filter, - batchSize: options.batchSize ?? configOptions.batchSize, - entityTransformer: options.entityTransformer, - auth: adaptedAuth, - discovery: options.discovery, - catalogClient: options.catalogClient, - }); - } - - private constructor(options: { - locationTemplate: string; - filter: GetEntitiesRequest['filter']; - batchSize: number; - entityTransformer?: CatalogCollatorEntityTransformer; - auth: AuthService; - discovery: DiscoveryService; - catalogClient?: CatalogApi; - }) { - const { - auth, - batchSize, - discovery, - locationTemplate, - filter, - catalogClient, - entityTransformer, - } = options; - - this.locationTemplate = locationTemplate; - this.filter = filter; - this.batchSize = batchSize; - this.catalogClient = - catalogClient || new CatalogClient({ discoveryApi: discovery }); - this.entityTransformer = - entityTransformer ?? defaultCatalogCollatorEntityTransformer; - this.auth = auth; - } - - async getCollator(): Promise { - return Readable.from(this.execute()); - } - - private async *execute(): AsyncGenerator { - let entitiesRetrieved = 0; - let cursor: string | undefined = undefined; - - do { - const { token } = await this.auth.getPluginRequestToken({ - onBehalfOf: await this.auth.getOwnServiceCredentials(), - targetPluginId: 'catalog', - }); - const response = await this.catalogClient.queryEntities( - { - filter: this.filter, - limit: this.batchSize, - ...(cursor ? { cursor } : {}), - }, - { token }, - ); - cursor = response.pageInfo.nextCursor; - entitiesRetrieved += response.items.length; - - for (const entity of response.items) { - yield { - ...this.entityTransformer(entity), - authorization: { - resourceRef: stringifyEntityRef(entity), - }, - location: this.applyArgsToFormat(this.locationTemplate, { - namespace: entity.metadata.namespace || 'default', - kind: entity.kind, - name: entity.metadata.name, - }), - }; - } - } while (cursor); - } - - private applyArgsToFormat( - format: string, - args: Record, - ): string { - let formatted = format; - - for (const [key, value] of Object.entries(args)) { - formatted = formatted.replace(`:${key}`, value); - } - - return formatted.toLowerCase(); - } -} - -/** - * @public - * @deprecated This is no longer supported since the new backend system migration - */ -export type DefaultCatalogCollatorFactoryOptions = { - auth?: AuthService; - discovery: DiscoveryService; - tokenManager?: TokenManager; - /** - * @deprecated Use the config key `search.collators.catalog.locationTemplate` instead. - */ - locationTemplate?: string; - /** - * @deprecated Use the config key `search.collators.catalog.filter` instead. - */ - filter?: GetEntitiesRequest['filter']; - /** - * @deprecated Use the config key `search.collators.catalog.batchSize` instead. - */ - batchSize?: number; - // TODO(freben): Change to required CatalogService instead when fully migrated to the new backend system. - catalogClient?: CatalogApi; - /** - * Allows you to customize how entities are shaped into documents. - */ - entityTransformer?: CatalogCollatorEntityTransformer; -}; - -/** - * @public - * @deprecated import from `@backstage/plugin-search-backend-module-catalog` instead - */ -export type CatalogCollatorEntityTransformer = - _CatalogCollatorEntityTransformer; diff --git a/plugins/catalog-backend/src/index.ts b/plugins/catalog-backend/src/index.ts index 3de6cea22e..40235a1724 100644 --- a/plugins/catalog-backend/src/index.ts +++ b/plugins/catalog-backend/src/index.ts @@ -23,8 +23,6 @@ export { catalogPlugin as default } from './service/CatalogPlugin'; export * from './processors'; export * from './processing'; -export * from './search'; export * from './service'; -export * from './deprecated'; export * from './constants'; export * from './util'; diff --git a/plugins/catalog-backend/src/processors/LocationEntityProcessor.test.ts b/plugins/catalog-backend/src/processors/LocationEntityProcessor.test.ts deleted file mode 100644 index 5e000f87d6..0000000000 --- a/plugins/catalog-backend/src/processors/LocationEntityProcessor.test.ts +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2020 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 { ConfigReader } from '@backstage/config'; -import { - ScmIntegrations, - ScmIntegrationRegistry, -} from '@backstage/integration'; -import path from 'path'; -import { toAbsoluteUrl } from './LocationEntityProcessor'; -import { LocationSpec } from '@backstage/plugin-catalog-common'; - -describe('LocationEntityProcessor', () => { - describe('toAbsoluteUrl', () => { - it('handles files', () => { - const integrations = {} as unknown as ScmIntegrationRegistry; - const base: LocationSpec = { - type: 'file', - target: `some${path.sep}path${path.sep}catalog-info.yaml`, - }; - expect(toAbsoluteUrl(integrations, base, `.${path.sep}c`)).toBe( - `some${path.sep}path${path.sep}c`, - ); - expect(toAbsoluteUrl(integrations, base, `${path.sep}c`)).toBe( - `${path.sep}c`, - ); - }); - - it('handles urls', () => { - const integrations = ScmIntegrations.fromConfig(new ConfigReader({})); - const base: LocationSpec = { - type: 'url', - target: 'http://a.com/b/catalog-info.yaml', - }; - jest.spyOn(integrations, 'resolveUrl'); - - expect(toAbsoluteUrl(integrations, base, './c/d')).toBe( - 'http://a.com/b/c/d', - ); - expect(toAbsoluteUrl(integrations, base, 'c/d')).toBe( - 'http://a.com/b/c/d', - ); - expect(toAbsoluteUrl(integrations, base, 'http://b.com/z')).toBe( - 'http://b.com/z', - ); - - expect(integrations.resolveUrl).toHaveBeenCalledTimes(3); - }); - - it('handles azure urls specifically', () => { - const integrations = ScmIntegrations.fromConfig( - new ConfigReader({ - integrations: { - azure: [{ host: 'dev.azure.com' }], - }, - }), - ); - - expect( - toAbsoluteUrl( - integrations, - { - type: 'url', - target: - 'https://dev.azure.com/organization/project/_git/repository?path=%2Fcatalog-info.yaml', - }, - './a.yaml', - ), - ).toBe( - 'https://dev.azure.com/organization/project/_git/repository?path=%2Fa.yaml', - ); - }); - }); -}); diff --git a/plugins/catalog-backend/src/processors/LocationEntityProcessor.ts b/plugins/catalog-backend/src/processors/LocationEntityProcessor.ts deleted file mode 100644 index 7bfd7f33cd..0000000000 --- a/plugins/catalog-backend/src/processors/LocationEntityProcessor.ts +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2020 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, LocationEntity } from '@backstage/catalog-model'; -import { ScmIntegrationRegistry } from '@backstage/integration'; -import path from 'path'; -import { LocationSpec } from '@backstage/plugin-catalog-common'; -import { - processingResult, - CatalogProcessor, - CatalogProcessorEmit, -} from '@backstage/plugin-catalog-node'; - -export function toAbsoluteUrl( - integrations: ScmIntegrationRegistry, - base: LocationSpec, - target: string, -): string { - try { - if (base.type === 'file') { - if (target.startsWith('.')) { - return path.join(path.dirname(base.target), target); - } - return target; - } - return integrations.resolveUrl({ url: target, base: base.target }); - } catch (e) { - return target; - } -} - -/** - * @public - * @deprecated This processor should no longer be used - */ -export type LocationEntityProcessorOptions = { - integrations: ScmIntegrationRegistry; -}; - -/** - * Legacy processor, should not be used. - * - * @remarks - * - * In the old catalog architecture, this processor translated Location entities - * into URLs that should be fetched. This is no longer needed since the engine - * handles this internally. - * - * @public - * @deprecated This processor should no longer be used - */ -export class LocationEntityProcessor implements CatalogProcessor { - constructor(private readonly options: LocationEntityProcessorOptions) {} - - getProcessorName(): string { - return 'LocationEntityProcessor'; - } - - async postProcessEntity( - entity: Entity, - location: LocationSpec, - emit: CatalogProcessorEmit, - ): Promise { - if (entity.kind === 'Location') { - const locationEntity = entity as LocationEntity; - - const type = locationEntity.spec.type || location.type; - if (type === 'file' && location.target.endsWith(path.sep)) { - emit( - processingResult.inputError( - location, - `LocationEntityProcessor cannot handle ${type} type location with target ${location.target} that ends with a path separator`, - ), - ); - } - - const targets = new Array(); - if (locationEntity.spec.target) { - targets.push(locationEntity.spec.target); - } - if (locationEntity.spec.targets) { - targets.push(...locationEntity.spec.targets); - } - - for (const maybeRelativeTarget of targets) { - const target = toAbsoluteUrl( - this.options.integrations, - location, - maybeRelativeTarget, - ); - emit(processingResult.location({ type, target })); - } - } - - return entity; - } -} diff --git a/plugins/catalog-backend/src/processors/index.ts b/plugins/catalog-backend/src/processors/index.ts index ee2204f20f..1a43444b1a 100644 --- a/plugins/catalog-backend/src/processors/index.ts +++ b/plugins/catalog-backend/src/processors/index.ts @@ -19,8 +19,6 @@ export { AnnotateScmSlugEntityProcessor } from './AnnotateScmSlugEntityProcessor export { BuiltinKindsEntityProcessor } from './BuiltinKindsEntityProcessor'; export { CodeOwnersProcessor } from './CodeOwnersProcessor'; export { FileReaderProcessor } from './FileReaderProcessor'; -export { LocationEntityProcessor } from './LocationEntityProcessor'; -export type { LocationEntityProcessorOptions } from './LocationEntityProcessor'; export { PlaceholderProcessor } from './PlaceholderProcessor'; export type { PlaceholderProcessorOptions } from './PlaceholderProcessor'; export { UrlReaderProcessor } from './UrlReaderProcessor'; diff --git a/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts b/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts deleted file mode 100644 index 9473d45bb6..0000000000 --- a/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2021 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 { TokenManager } from '@backstage/backend-common'; -import { - mockServices, - registerMswTestHooks, -} from '@backstage/backend-test-utils'; -import { Entity } from '@backstage/catalog-model'; -import { DefaultCatalogCollator } from './DefaultCatalogCollator'; -import { setupServer } from 'msw/node'; -import { rest } from 'msw'; -import { ConfigReader } from '@backstage/config'; - -const server = setupServer(); - -const expectedEntities: Entity[] = [ - { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'test-entity', - description: 'The expected description', - }, - spec: { - type: 'some-type', - lifecycle: 'experimental', - owner: 'someone', - }, - }, - { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - title: 'Test Entity', - name: 'test-entity-2', - description: 'The expected description 2', - }, - spec: { - type: 'some-type', - lifecycle: 'experimental', - owner: 'someone', - }, - }, -]; - -describe('DefaultCatalogCollator', () => { - const mockDiscovery = mockServices.discovery.mock({ - getBaseUrl: async () => 'http://localhost:7007', - }); - let mockTokenManager: jest.Mocked; - let collator: DefaultCatalogCollator; - - registerMswTestHooks(server); - beforeAll(() => { - mockTokenManager = { - getToken: jest.fn().mockResolvedValue({ token: '' }), - authenticate: jest.fn(), - }; - collator = new DefaultCatalogCollator({ - discovery: mockDiscovery, - tokenManager: mockTokenManager, - }); - }); - beforeEach(() => { - server.use( - rest.get('http://localhost:7007/entities', (req, res, ctx) => { - if (req.url.searchParams.has('filter')) { - const filter = req.url.searchParams.get('filter'); - if (filter === 'kind=Foo,kind=Bar') { - // When filtering on the 'Foo,Bar' kinds we simply return no items, to simulate a filter - return res(ctx.json([])); - } - throw new Error('Unexpected filter parameter'); - } - return res(ctx.json(expectedEntities)); - }), - ); - }); - afterAll(() => { - jest.useRealTimers(); - }); - - it('fetches from the configured catalog service', async () => { - const documents = await collator.execute(); - expect(mockDiscovery.getBaseUrl).toHaveBeenCalledWith('catalog'); - expect(documents).toHaveLength(expectedEntities.length); - }); - - it('maps a returned entity to an expected CatalogEntityDocument', async () => { - const documents = await collator.execute(); - expect(documents[0]).toMatchObject({ - title: expectedEntities[0].metadata.name, - location: '/catalog/default/component/test-entity', - text: expectedEntities[0].metadata.description, - namespace: 'default', - componentType: expectedEntities[0]!.spec!.type, - lifecycle: expectedEntities[0]!.spec!.lifecycle, - owner: expectedEntities[0]!.spec!.owner, - authorization: { - resourceRef: 'component:default/test-entity', - }, - }); - expect(documents[1]).toMatchObject({ - title: `${expectedEntities[1].metadata.title} (${expectedEntities[1].metadata.name})`, - location: '/catalog/default/component/test-entity-2', - text: expectedEntities[1].metadata.description, - namespace: 'default', - componentType: expectedEntities[1]!.spec!.type, - lifecycle: expectedEntities[1]!.spec!.lifecycle, - owner: expectedEntities[1]!.spec!.owner, - authorization: { - resourceRef: 'component:default/test-entity-2', - }, - }); - }); - - it('maps a returned entity with a custom locationTemplate', async () => { - // Provide an alternate location template. - collator = new DefaultCatalogCollator({ - discovery: mockDiscovery, - tokenManager: mockTokenManager, - locationTemplate: '/software/:name', - }); - - const documents = await collator.execute(); - expect(documents[0]).toMatchObject({ - location: '/software/test-entity', - }); - }); - - it('allows filtering of the retrieved catalog entities', async () => { - // Provide an alternate location template. - collator = DefaultCatalogCollator.fromConfig(new ConfigReader({}), { - discovery: mockDiscovery, - tokenManager: mockTokenManager, - filter: { - kind: ['Foo', 'Bar'], - }, - }); - - const documents = await collator.execute(); - // The simulated 'Foo,Bar' filter should return in an empty list - expect(documents).toHaveLength(0); - }); -}); diff --git a/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts b/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts deleted file mode 100644 index 11f6030ce6..0000000000 --- a/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2021 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 { TokenManager } from '@backstage/backend-common'; -import { - Entity, - isUserEntity, - stringifyEntityRef, -} from '@backstage/catalog-model'; -import { Config } from '@backstage/config'; -import { - CatalogApi, - CatalogClient, - GetEntitiesRequest, -} from '@backstage/catalog-client'; -import { catalogEntityReadPermission } from '@backstage/plugin-catalog-common/alpha'; -import { CatalogEntityDocument } from '@backstage/plugin-catalog-common'; -import { Permission } from '@backstage/plugin-permission-common'; -import { DiscoveryService } from '@backstage/backend-plugin-api'; - -/** - * @public - * @deprecated Upgrade to a more recent `@backstage/plugin-search-backend-node` and - * use `DefaultCatalogCollatorFactory` instead. - */ -export class DefaultCatalogCollator { - protected discovery: DiscoveryService; - protected locationTemplate: string; - protected filter?: GetEntitiesRequest['filter']; - protected readonly catalogClient: CatalogApi; - public readonly type: string = 'software-catalog'; - public readonly visibilityPermission: Permission = - catalogEntityReadPermission; - protected tokenManager: TokenManager; - - static fromConfig( - _config: Config, - options: { - discovery: DiscoveryService; - tokenManager: TokenManager; - filter?: GetEntitiesRequest['filter']; - }, - ) { - return new DefaultCatalogCollator({ - ...options, - }); - } - - constructor(options: { - discovery: DiscoveryService; - tokenManager: TokenManager; - locationTemplate?: string; - filter?: GetEntitiesRequest['filter']; - catalogClient?: CatalogApi; - }) { - const { discovery, locationTemplate, filter, catalogClient, tokenManager } = - options; - - this.discovery = discovery; - this.locationTemplate = - locationTemplate || '/catalog/:namespace/:kind/:name'; - this.filter = filter; - this.catalogClient = - catalogClient || new CatalogClient({ discoveryApi: discovery }); - this.tokenManager = tokenManager; - } - - protected applyArgsToFormat( - format: string, - args: Record, - ): string { - let formatted = format; - for (const [key, value] of Object.entries(args)) { - formatted = formatted.replace(`:${key}`, value); - } - return formatted.toLowerCase(); - } - - private getDocumentText(entity: Entity): string { - let documentText = entity.metadata.description || ''; - if (isUserEntity(entity)) { - if (entity.spec?.profile?.displayName && documentText) { - // combine displayName and description - const displayName = entity.spec?.profile?.displayName; - documentText = displayName.concat(' : ', documentText); - } else { - documentText = entity.spec?.profile?.displayName || documentText; - } - } - return documentText; - } - - async execute() { - const { token } = await this.tokenManager.getToken(); - const response = await this.catalogClient.getEntities( - { - filter: this.filter, - }, - { token }, - ); - return response.items.map((entity: Entity): CatalogEntityDocument => { - return { - title: entity.metadata.title - ? `${entity.metadata.title} (${entity.metadata.name})` - : entity.metadata.name, - location: this.applyArgsToFormat(this.locationTemplate, { - namespace: entity.metadata.namespace || 'default', - kind: entity.kind, - name: entity.metadata.name, - }), - text: this.getDocumentText(entity), - componentType: entity.spec?.type?.toString() || 'other', - type: entity.spec?.type?.toString() || 'other', - namespace: entity.metadata.namespace || 'default', - kind: entity.kind, - lifecycle: (entity.spec?.lifecycle as string) || '', - owner: (entity.spec?.owner as string) || '', - authorization: { - resourceRef: stringifyEntityRef(entity), - }, - }; - }); - } -} diff --git a/plugins/catalog-backend/src/search/index.ts b/plugins/catalog-backend/src/search/index.ts deleted file mode 100644 index 50966e4c5b..0000000000 --- a/plugins/catalog-backend/src/search/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2021 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. - */ - -/** - * todo(backstage/techdocs-core): stop exporting this in a future release. - */ -export { DefaultCatalogCollator } from './DefaultCatalogCollator'; diff --git a/yarn.lock b/yarn.lock index a6aa5e382c..9216e2687f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6032,8 +6032,6 @@ __metadata: "@backstage/plugin-events-node": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" "@backstage/plugin-permission-node": "workspace:^" - "@backstage/plugin-search-backend-module-catalog": "workspace:^" - "@backstage/plugin-search-common": "workspace:^" "@backstage/repo-tools": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/types": "workspace:^" From a459f17b2a766ff4818d906af3c52cdbff873832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 25 Apr 2025 16:43:49 +0200 Subject: [PATCH 4/6] move `parseEntityYaml` to the node package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/early-dryers-teach.md | 5 ++ .changeset/sad-showers-begin.md | 1 + plugins/catalog-backend/report.api.md | 7 -- plugins/catalog-backend/src/index.ts | 1 - plugins/catalog-backend/src/util/index.ts | 17 ----- plugins/catalog-backend/src/util/parse.ts | 42 +--------- plugins/catalog-node/package.json | 4 +- plugins/catalog-node/report.api.md | 6 ++ plugins/catalog-node/src/processing/index.ts | 1 + .../src/processing}/parse.test.ts | 0 plugins/catalog-node/src/processing/parse.ts | 76 +++++++++++++++++++ yarn.lock | 2 + 12 files changed, 95 insertions(+), 67 deletions(-) create mode 100644 .changeset/early-dryers-teach.md delete mode 100644 plugins/catalog-backend/src/util/index.ts rename plugins/{catalog-backend/src/util => catalog-node/src/processing}/parse.test.ts (100%) create mode 100644 plugins/catalog-node/src/processing/parse.ts diff --git a/.changeset/early-dryers-teach.md b/.changeset/early-dryers-teach.md new file mode 100644 index 0000000000..d747fbc730 --- /dev/null +++ b/.changeset/early-dryers-teach.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-node': minor +--- + +Added `parseEntityYaml` from `@backstage/plugin-catalog-backend`, to make it more easily usable by custom plugins and modules diff --git a/.changeset/sad-showers-begin.md b/.changeset/sad-showers-begin.md index eccbd9981c..6054072620 100644 --- a/.changeset/sad-showers-begin.md +++ b/.changeset/sad-showers-begin.md @@ -33,6 +33,7 @@ The following removed exports are available from `@backstage/plugin-catalog-node - `PlaceholderResolverParams` - `PlaceholderResolverRead` - `PlaceholderResolverResolveUrl` +- `parseEntityYaml` The following removed exports are available from `@backstage/plugin-catalog-common`: diff --git a/plugins/catalog-backend/report.api.md b/plugins/catalog-backend/report.api.md index e92e688aa4..cdabce4732 100644 --- a/plugins/catalog-backend/report.api.md +++ b/plugins/catalog-backend/report.api.md @@ -10,7 +10,6 @@ import { CatalogProcessor } from '@backstage/plugin-catalog-node'; import { CatalogProcessorCache } from '@backstage/plugin-catalog-node'; import { CatalogProcessorEmit } from '@backstage/plugin-catalog-node'; import { CatalogProcessorParser } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorResult } from '@backstage/plugin-catalog-node'; import { Config } from '@backstage/config'; import { DatabaseService } from '@backstage/backend-plugin-api'; import { DiscoveryService } from '@backstage/backend-plugin-api'; @@ -215,12 +214,6 @@ export class FileReaderProcessor implements CatalogProcessor { ): Promise; } -// @public (undocumented) -export function parseEntityYaml( - data: Buffer, - location: LocationSpec, -): Iterable; - // @public export class PlaceholderProcessor implements CatalogProcessor { constructor(options: PlaceholderProcessorOptions); diff --git a/plugins/catalog-backend/src/index.ts b/plugins/catalog-backend/src/index.ts index 40235a1724..ea658a9a13 100644 --- a/plugins/catalog-backend/src/index.ts +++ b/plugins/catalog-backend/src/index.ts @@ -25,4 +25,3 @@ export * from './processors'; export * from './processing'; export * from './service'; export * from './constants'; -export * from './util'; diff --git a/plugins/catalog-backend/src/util/index.ts b/plugins/catalog-backend/src/util/index.ts deleted file mode 100644 index b0e291ac60..0000000000 --- a/plugins/catalog-backend/src/util/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2024 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 { parseEntityYaml } from './parse'; diff --git a/plugins/catalog-backend/src/util/parse.ts b/plugins/catalog-backend/src/util/parse.ts index 778c176323..d87a98ef75 100644 --- a/plugins/catalog-backend/src/util/parse.ts +++ b/plugins/catalog-backend/src/util/parse.ts @@ -14,51 +14,11 @@ * limitations under the License. */ -import { Entity, stringifyLocationRef } from '@backstage/catalog-model'; -import lodash from 'lodash'; -import yaml from 'yaml'; -import { LocationSpec } from '@backstage/plugin-catalog-common'; import { CatalogProcessorParser, - CatalogProcessorResult, - processingResult, + parseEntityYaml, } from '@backstage/plugin-catalog-node'; -/** @public */ -export function* parseEntityYaml( - data: Buffer, - location: LocationSpec, -): Iterable { - let documents: yaml.Document.Parsed[]; - try { - documents = yaml.parseAllDocuments(data.toString('utf8')).filter(d => d); - } catch (e) { - const loc = stringifyLocationRef(location); - const message = `Failed to parse YAML at ${loc}, ${e}`; - yield processingResult.generalError(location, message); - return; - } - - for (const document of documents) { - if (document.errors?.length) { - const loc = stringifyLocationRef(location); - const message = `YAML error at ${loc}, ${document.errors[0]}`; - yield processingResult.generalError(location, message); - } else { - const json = document.toJSON(); - if (lodash.isPlainObject(json)) { - yield processingResult.entity(location, json as Entity); - } else if (json === null) { - // Ignore null values, these happen if there is an empty document in the - // YAML file, for example if --- is added to the end of the file. - } else { - const message = `Expected object at root, got ${typeof json}`; - yield processingResult.generalError(location, message); - } - } - } -} - export const defaultEntityDataParser: CatalogProcessorParser = async function* defaultEntityDataParser({ data, location }) { for (const e of parseEntityYaml(data, location)) { diff --git a/plugins/catalog-node/package.json b/plugins/catalog-node/package.json index 4c12f6b7fb..2aad8b676f 100644 --- a/plugins/catalog-node/package.json +++ b/plugins/catalog-node/package.json @@ -67,7 +67,9 @@ "@backstage/plugin-catalog-common": "workspace:^", "@backstage/plugin-permission-common": "workspace:^", "@backstage/plugin-permission-node": "workspace:^", - "@backstage/types": "workspace:^" + "@backstage/types": "workspace:^", + "lodash": "^4.17.21", + "yaml": "^2.0.0" }, "devDependencies": { "@backstage/backend-test-utils": "workspace:^", diff --git a/plugins/catalog-node/report.api.md b/plugins/catalog-node/report.api.md index f2fe86a38c..807bcaa8d5 100644 --- a/plugins/catalog-node/report.api.md +++ b/plugins/catalog-node/report.api.md @@ -297,6 +297,12 @@ export function locationSpecToLocationEntity(opts: { // @public export function locationSpecToMetadataName(location: LocationSpec_2): string; +// @public +export function parseEntityYaml( + data: string | Buffer, + location: LocationSpec_2, +): Iterable; + // @public (undocumented) export type PlaceholderResolver = ( params: PlaceholderResolverParams, diff --git a/plugins/catalog-node/src/processing/index.ts b/plugins/catalog-node/src/processing/index.ts index 4e83e6077d..1610e0cb89 100644 --- a/plugins/catalog-node/src/processing/index.ts +++ b/plugins/catalog-node/src/processing/index.ts @@ -24,3 +24,4 @@ export type { LocationAnalyzer, ScmLocationAnalyzer, } from './types'; +export { parseEntityYaml } from './parse'; diff --git a/plugins/catalog-backend/src/util/parse.test.ts b/plugins/catalog-node/src/processing/parse.test.ts similarity index 100% rename from plugins/catalog-backend/src/util/parse.test.ts rename to plugins/catalog-node/src/processing/parse.test.ts diff --git a/plugins/catalog-node/src/processing/parse.ts b/plugins/catalog-node/src/processing/parse.ts new file mode 100644 index 0000000000..2ef276d06d --- /dev/null +++ b/plugins/catalog-node/src/processing/parse.ts @@ -0,0 +1,76 @@ +/* + * Copyright 2020 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, stringifyLocationRef } from '@backstage/catalog-model'; +import lodash from 'lodash'; +import yaml from 'yaml'; +import { LocationSpec } from '@backstage/plugin-catalog-common'; +import { CatalogProcessorResult } from '../api/processor'; +import { processingResult } from '../api/processingResult'; + +/** + * A helper function that parses a YAML file, properly handling multiple + * documents in a single file. + * + * @public + * @remarks + * + * Each document is expected to be a valid Backstage entity. Each item in the + * iterable is in the form of an entity result if the document seemed like a + * valid object, or in the form of an error result if it seemed incorrect. This + * way, you can choose to retain a partial result if you want. + * + * Note that this function does NOT perform any validation of the entities. No + * assumptions whatsoever can be made on the emnitted entities except that they + * are valid JSON objects. + */ +export function* parseEntityYaml( + data: string | Buffer, + location: LocationSpec, +): Iterable { + let documents: yaml.Document.Parsed[]; + try { + documents = yaml + .parseAllDocuments( + typeof data === 'string' ? data : data.toString('utf8'), + ) + .filter(d => d); + } catch (e) { + const loc = stringifyLocationRef(location); + const message = `Failed to parse YAML at ${loc}, ${e}`; + yield processingResult.generalError(location, message); + return; + } + + for (const document of documents) { + if (document.errors?.length) { + const loc = stringifyLocationRef(location); + const message = `YAML error at ${loc}, ${document.errors[0]}`; + yield processingResult.generalError(location, message); + } else { + const json = document.toJSON(); + if (lodash.isPlainObject(json)) { + yield processingResult.entity(location, json as Entity); + } else if (json === null) { + // Ignore null values, these happen if there is an empty document in the + // YAML file, for example if --- is added to the end of the file. + } else { + const message = `Expected object at root, got ${typeof json}`; + yield processingResult.generalError(location, message); + } + } + } +} diff --git a/yarn.lock b/yarn.lock index 9216e2687f..c7f79ae2f0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6187,7 +6187,9 @@ __metadata: "@backstage/plugin-permission-common": "workspace:^" "@backstage/plugin-permission-node": "workspace:^" "@backstage/types": "workspace:^" + lodash: "npm:^4.17.21" msw: "npm:^1.0.0" + yaml: "npm:^2.0.0" languageName: unknown linkType: soft From cb93cd9b8ccdda2fbd793f0012f08fa0d15083b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 25 Apr 2025 20:32:18 +0200 Subject: [PATCH 5/6] removed old backend system support, removed backend-common MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/sad-showers-begin.md | 8 +- plugins/catalog-backend/package.json | 1 - plugins/catalog-backend/report.api.md | 109 ------------------ .../DefaultProcessingDatabase.test.ts | 2 +- .../src/database/DefaultProcessingDatabase.ts | 2 +- plugins/catalog-backend/src/index.ts | 2 - .../DefaultCatalogProcessingOrchestrator.ts | 1 - .../catalog-backend/src/processing/index.ts | 19 --- .../catalog-backend/src/processing/refresh.ts | 2 - .../src/service/CatalogBuilder.ts | 46 ++------ .../src/service/CatalogPlugin.ts | 6 +- .../src/service/createRouter.ts | 3 - plugins/catalog-backend/src/service/index.ts | 21 ---- plugins/catalog-backend/src/service/types.ts | 8 -- .../src/tests/integration.test.ts | 2 +- .../catalog-backend/src/util/conversion.ts | 1 - yarn.lock | 1 - 17 files changed, 22 insertions(+), 212 deletions(-) delete mode 100644 plugins/catalog-backend/src/processing/index.ts delete mode 100644 plugins/catalog-backend/src/service/index.ts diff --git a/.changeset/sad-showers-begin.md b/.changeset/sad-showers-begin.md index 6054072620..3f78400a13 100644 --- a/.changeset/sad-showers-begin.md +++ b/.changeset/sad-showers-begin.md @@ -2,7 +2,7 @@ '@backstage/plugin-catalog-backend': major --- -**BREAKING**: Removed all deprecated exports. +**BREAKING**: Removed all deprecated exports, and removed support for the old backend system. The following removed exports are available from `@backstage/plugin-catalog-node`: @@ -56,3 +56,9 @@ The following exports are removed without a direct replacement: - `DefaultCatalogCollatorFactoryOptions` - `LocationEntityProcessor` - `LocationEntityProcessorOptions` +- `CatalogBuilder` +- `CatalogEnvironment` +- `CatalogPermissionRuleInput` +- `CatalogProcessingEngine` +- `createRandomProcessingInterval` +- `ProcessingIntervalFunction` diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index fb6032342b..58df69f6a3 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -61,7 +61,6 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "^0.25.0", "@backstage/backend-openapi-utils": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-client": "workspace:^", diff --git a/plugins/catalog-backend/report.api.md b/plugins/catalog-backend/report.api.md index cdabce4732..9bb94b2dd5 100644 --- a/plugins/catalog-backend/report.api.md +++ b/plugins/catalog-backend/report.api.md @@ -3,40 +3,19 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { AuditorService } from '@backstage/backend-plugin-api'; -import { AuthService } from '@backstage/backend-plugin-api'; import { BackendFeature } from '@backstage/backend-plugin-api'; import { CatalogProcessor } from '@backstage/plugin-catalog-node'; import { CatalogProcessorCache } from '@backstage/plugin-catalog-node'; import { CatalogProcessorEmit } from '@backstage/plugin-catalog-node'; import { CatalogProcessorParser } from '@backstage/plugin-catalog-node'; import { Config } from '@backstage/config'; -import { DatabaseService } from '@backstage/backend-plugin-api'; -import { DiscoveryService } from '@backstage/backend-plugin-api'; -import { EntitiesSearchFilter } from '@backstage/plugin-catalog-node'; import { Entity } from '@backstage/catalog-model'; import { EntityPolicy } from '@backstage/catalog-model'; -import { EntityProvider } from '@backstage/plugin-catalog-node'; -import { EventBroker } from '@backstage/plugin-events-node'; -import { EventsService } from '@backstage/plugin-events-node'; -import { HttpAuthService } from '@backstage/backend-plugin-api'; -import { LocationAnalyzer } from '@backstage/plugin-catalog-node'; import { LocationSpec } from '@backstage/plugin-catalog-common'; import { LoggerService } from '@backstage/backend-plugin-api'; -import { Permission } from '@backstage/plugin-permission-common'; -import { PermissionAuthorizer } from '@backstage/plugin-permission-common'; -import { PermissionRule } from '@backstage/plugin-permission-node'; -import { PermissionRuleParams } from '@backstage/plugin-permission-common'; -import { PermissionsRegistryService } from '@backstage/backend-plugin-api'; -import { PermissionsService } from '@backstage/backend-plugin-api'; import { PlaceholderResolver } from '@backstage/plugin-catalog-node'; -import { RootConfigService } from '@backstage/backend-plugin-api'; -import { Router } from 'express'; -import { SchedulerService } from '@backstage/backend-plugin-api'; import { ScmIntegrationRegistry } from '@backstage/integration'; -import { ScmLocationAnalyzer } from '@backstage/plugin-catalog-node'; import { UrlReaderService } from '@backstage/backend-plugin-api'; -import { Validators } from '@backstage/catalog-model'; // @public (undocumented) export class AnnotateLocationEntityProcessor implements CatalogProcessor { @@ -91,89 +70,10 @@ export const CATALOG_CONFLICTS_TOPIC = 'experimental.catalog.conflict'; // @public (undocumented) export const CATALOG_ERRORS_TOPIC = 'experimental.catalog.errors'; -// @public @deprecated -export class CatalogBuilder { - addEntityPolicy( - ...policies: Array> - ): CatalogBuilder; - addEntityProvider( - ...providers: Array> - ): CatalogBuilder; - addLocationAnalyzers( - ...analyzers: Array> - ): CatalogBuilder; - addPermissionRules( - ...permissionRules: Array< - CatalogPermissionRuleInput | Array - > - ): this; - addPermissions(...permissions: Array>): this; - addProcessor( - ...processors: Array> - ): CatalogBuilder; - build(): Promise<{ - processingEngine: CatalogProcessingEngine; - router: Router; - }>; - static create(env: CatalogEnvironment): CatalogBuilder; - getDefaultProcessors(): CatalogProcessor[]; - replaceEntityPolicies(policies: EntityPolicy[]): CatalogBuilder; - replaceProcessors(processors: CatalogProcessor[]): CatalogBuilder; - setAllowedLocationTypes(allowedLocationTypes: string[]): CatalogBuilder; - setEntityDataParser(parser: CatalogProcessorParser): CatalogBuilder; - setEventBroker(broker: EventBroker | EventsService): CatalogBuilder; - setFieldFormatValidators(validators: Partial): CatalogBuilder; - setLocationAnalyzer(locationAnalyzer: LocationAnalyzer): CatalogBuilder; - setPlaceholderResolver( - key: string, - resolver: PlaceholderResolver, - ): CatalogBuilder; - setProcessingInterval( - processingInterval: ProcessingIntervalFunction, - ): CatalogBuilder; - setProcessingIntervalSeconds(seconds: number): CatalogBuilder; - // (undocumented) - subscribe(options: { - onProcessingError: (event: { - unprocessedEntity: Entity; - errors: Error[]; - }) => Promise | void; - }): void; - useLegacySingleProcessorValidation(): this; -} - -// @public @deprecated (undocumented) -export type CatalogEnvironment = { - logger: LoggerService; - database: DatabaseService; - config: RootConfigService; - reader: UrlReaderService; - permissions: PermissionsService | PermissionAuthorizer; - permissionsRegistry?: PermissionsRegistryService; - scheduler?: SchedulerService; - discovery?: DiscoveryService; - auth?: AuthService; - httpAuth?: HttpAuthService; - auditor?: AuditorService; -}; - -// @public -export type CatalogPermissionRuleInput< - TParams extends PermissionRuleParams = PermissionRuleParams, -> = PermissionRule; - // @public const catalogPlugin: BackendFeature; export default catalogPlugin; -// @public -export interface CatalogProcessingEngine { - // (undocumented) - start(): Promise; - // (undocumented) - stop(): Promise; -} - // @public (undocumented) export class CodeOwnersProcessor implements CatalogProcessor { constructor(options: { @@ -195,12 +95,6 @@ export class CodeOwnersProcessor implements CatalogProcessor { preProcessEntity(entity: Entity, location: LocationSpec): Promise; } -// @public -export function createRandomProcessingInterval(options: { - minSeconds: number; - maxSeconds: number; -}): ProcessingIntervalFunction; - // @public (undocumented) export class FileReaderProcessor implements CatalogProcessor { // (undocumented) @@ -234,9 +128,6 @@ export type PlaceholderProcessorOptions = { integrations: ScmIntegrationRegistry; }; -// @public -export type ProcessingIntervalFunction = () => number; - // @public export function transformLegacyPolicyToProcessor( policy: EntityPolicy, diff --git a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts index 750eebbadb..a09e938575 100644 --- a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts @@ -32,7 +32,7 @@ import { DbRefreshStateRow, DbRelationsRow, } from './tables'; -import { createRandomProcessingInterval } from '../processing'; +import { createRandomProcessingInterval } from '../processing/refresh'; import { timestampToDateTime } from './conversion'; import { generateStableHash } from './util'; import { LoggerService } from '@backstage/backend-plugin-api'; diff --git a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts index 0aa31dd36d..81c26c66ab 100644 --- a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts +++ b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts @@ -19,7 +19,7 @@ import { ConflictError } from '@backstage/errors'; import { DeferredEntity } from '@backstage/plugin-catalog-node'; import { Knex } from 'knex'; import lodash from 'lodash'; -import { ProcessingIntervalFunction } from '../processing'; +import { ProcessingIntervalFunction } from '../processing/refresh'; import { rethrowError, timestampToDateTime } from './conversion'; import { initDatabaseMetrics } from './metrics'; import { diff --git a/plugins/catalog-backend/src/index.ts b/plugins/catalog-backend/src/index.ts index ea658a9a13..72bfde4cdf 100644 --- a/plugins/catalog-backend/src/index.ts +++ b/plugins/catalog-backend/src/index.ts @@ -22,6 +22,4 @@ export { catalogPlugin as default } from './service/CatalogPlugin'; export * from './processors'; -export * from './processing'; -export * from './service'; export * from './constants'; diff --git a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.ts b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.ts index 5456371e15..b1fcba5d40 100644 --- a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.ts +++ b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.ts @@ -84,7 +84,6 @@ function addProcessorAttributes( ); } -/** @public */ export class DefaultCatalogProcessingOrchestrator implements CatalogProcessingOrchestrator { diff --git a/plugins/catalog-backend/src/processing/index.ts b/plugins/catalog-backend/src/processing/index.ts deleted file mode 100644 index 6e5893c976..0000000000 --- a/plugins/catalog-backend/src/processing/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2021 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 type { CatalogProcessingEngine } from './types'; -export { createRandomProcessingInterval } from './refresh'; -export type { ProcessingIntervalFunction } from './refresh'; diff --git a/plugins/catalog-backend/src/processing/refresh.ts b/plugins/catalog-backend/src/processing/refresh.ts index f9f596cdb9..9efc1dfcdc 100644 --- a/plugins/catalog-backend/src/processing/refresh.ts +++ b/plugins/catalog-backend/src/processing/refresh.ts @@ -16,14 +16,12 @@ /** * Function that returns the catalog processing interval in seconds. - * @public */ export type ProcessingIntervalFunction = () => number; /** * Creates a function that returns a random processing interval between minSeconds and maxSeconds. * @returns A {@link ProcessingIntervalFunction} that provides the next processing interval - * @public */ export function createRandomProcessingInterval(options: { minSeconds: number; diff --git a/plugins/catalog-backend/src/service/CatalogBuilder.ts b/plugins/catalog-backend/src/service/CatalogBuilder.ts index 99752ca5cf..899563c74d 100644 --- a/plugins/catalog-backend/src/service/CatalogBuilder.ts +++ b/plugins/catalog-backend/src/service/CatalogBuilder.ts @@ -14,10 +14,6 @@ * limitations under the License. */ -import { - createLegacyAuthAdapters, - HostDiscovery, -} from '@backstage/backend-common'; import { DefaultNamespaceEntityPolicy, Entity, @@ -38,7 +34,6 @@ import { AuditorService, AuthService, DatabaseService, - DiscoveryService, HttpAuthService, LoggerService, PermissionsRegistryService, @@ -55,7 +50,6 @@ import { import { CatalogProcessor, CatalogProcessorParser, - EntitiesSearchFilter, EntityProvider, LocationAnalyzer, PlaceholderResolver, @@ -65,13 +59,11 @@ import { EventBroker, EventsService } from '@backstage/plugin-events-node'; import { Permission, PermissionAuthorizer, - PermissionRuleParams, toPermissionEvaluator, } from '@backstage/plugin-permission-common'; import { createConditionTransformer, createPermissionIntegrationRouter, - PermissionRule, } from '@backstage/plugin-permission-node'; import { durationToMilliseconds } from '@backstage/types'; import { DefaultCatalogDatabase } from '../database/DefaultCatalogDatabase'; @@ -81,11 +73,11 @@ import { applyDatabaseMigrations } from '../database/migrations'; import { DefaultCatalogRulesEnforcer } from '../ingestion/CatalogRules'; import { RepoLocationAnalyzer } from '../ingestion/LocationAnalyzer'; import { permissionRules as catalogPermissionRules } from '../permissions/rules'; +import { CatalogProcessingEngine } from '../processing/types'; import { - CatalogProcessingEngine, createRandomProcessingInterval, ProcessingIntervalFunction, -} from '../processing'; +} from '../processing/refresh'; import { connectEntityProviders } from '../processing/connectEntityProviders'; import { evictEntitiesFromOrphanedProviders } from '../processing/evictEntitiesFromOrphanedProviders'; import { DefaultCatalogProcessingEngine } from '../processing/DefaultCatalogProcessingEngine'; @@ -116,21 +108,11 @@ import { DefaultEntitiesCatalog } from './DefaultEntitiesCatalog'; import { DefaultLocationService } from './DefaultLocationService'; import { DefaultRefreshService } from './DefaultRefreshService'; import { entitiesResponseToObjects } from './response'; -import { catalogEntityPermissionResourceRef } from '@backstage/plugin-catalog-node/alpha'; +import { + catalogEntityPermissionResourceRef, + CatalogPermissionRuleInput, +} from '@backstage/plugin-catalog-node/alpha'; -/** - * This is a duplicate of the alpha `CatalogPermissionRule` type, for use in the stable API. - * - * @public - */ -export type CatalogPermissionRuleInput< - TParams extends PermissionRuleParams = PermissionRuleParams, -> = PermissionRule; - -/** - * @deprecated Please migrate to the new backend system as this will be removed in the future. - * @public - */ export type CatalogEnvironment = { logger: LoggerService; database: DatabaseService; @@ -139,9 +121,8 @@ export type CatalogEnvironment = { permissions: PermissionsService | PermissionAuthorizer; permissionsRegistry?: PermissionsRegistryService; scheduler?: SchedulerService; - discovery?: DiscoveryService; - auth?: AuthService; - httpAuth?: HttpAuthService; + auth: AuthService; + httpAuth: HttpAuthService; auditor?: AuditorService; }; @@ -167,9 +148,6 @@ export type CatalogEnvironment = { * - Processors can be added or replaced. These implement the functionality of * reading, parsing, validating, and processing the entity data before it is * persisted in the catalog. - * - * @public - * @deprecated Please migrate to the new backend system as this will be removed in the future. */ export class CatalogBuilder { private readonly env: CatalogEnvironment; @@ -482,15 +460,11 @@ export class CatalogBuilder { permissions, scheduler, permissionsRegistry, - discovery = HostDiscovery.fromConfig(config), auditor, + auth, + httpAuth, } = this.env; - const { auth, httpAuth } = createLegacyAuthAdapters({ - ...this.env, - discovery, - }); - const disableRelationsCompatibility = config.getOptionalBoolean( 'catalog.disableRelationsCompatibility', ); diff --git a/plugins/catalog-backend/src/service/CatalogPlugin.ts b/plugins/catalog-backend/src/service/CatalogPlugin.ts index 13be6eea31..9925f11c7b 100644 --- a/plugins/catalog-backend/src/service/CatalogPlugin.ts +++ b/plugins/catalog-backend/src/service/CatalogPlugin.ts @@ -35,13 +35,14 @@ import { catalogModelExtensionPoint, CatalogPermissionExtensionPoint, catalogPermissionExtensionPoint, + CatalogPermissionRuleInput, CatalogProcessingExtensionPoint, catalogProcessingExtensionPoint, } from '@backstage/plugin-catalog-node/alpha'; import { eventsServiceRef } from '@backstage/plugin-events-node'; import { Permission } from '@backstage/plugin-permission-common'; import { merge } from 'lodash'; -import { CatalogBuilder, CatalogPermissionRuleInput } from './CatalogBuilder'; +import { CatalogBuilder } from './CatalogBuilder'; class CatalogLocationsExtensionPointImpl implements CatalogLocationsExtensionPoint @@ -232,7 +233,6 @@ export const catalogPlugin = createBackendPlugin({ httpRouter: coreServices.httpRouter, lifecycle: coreServices.rootLifecycle, scheduler: coreServices.scheduler, - discovery: coreServices.discovery, auth: coreServices.auth, httpAuth: coreServices.httpAuth, auditor: coreServices.auditor, @@ -248,7 +248,6 @@ export const catalogPlugin = createBackendPlugin({ httpRouter, lifecycle, scheduler, - discovery, auth, httpAuth, auditor, @@ -262,7 +261,6 @@ export const catalogPlugin = createBackendPlugin({ database, scheduler, logger, - discovery, auth, httpAuth, auditor, diff --git a/plugins/catalog-backend/src/service/createRouter.ts b/plugins/catalog-backend/src/service/createRouter.ts index 08e98d0548..f4ce26b66b 100644 --- a/plugins/catalog-backend/src/service/createRouter.ts +++ b/plugins/catalog-backend/src/service/createRouter.ts @@ -65,9 +65,6 @@ import { /** * Options used by {@link createRouter}. - * - * @public - * @deprecated Please migrate to the new backend system as this will be removed in the future. */ export interface RouterOptions { entitiesCatalog?: EntitiesCatalog; diff --git a/plugins/catalog-backend/src/service/index.ts b/plugins/catalog-backend/src/service/index.ts deleted file mode 100644 index 44645d39fe..0000000000 --- a/plugins/catalog-backend/src/service/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2021 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 type { - CatalogEnvironment, - CatalogPermissionRuleInput, -} from './CatalogBuilder'; -export { CatalogBuilder } from './CatalogBuilder'; diff --git a/plugins/catalog-backend/src/service/types.ts b/plugins/catalog-backend/src/service/types.ts index 30470e5af0..f9ec39c7d3 100644 --- a/plugins/catalog-backend/src/service/types.ts +++ b/plugins/catalog-backend/src/service/types.ts @@ -20,8 +20,6 @@ import { BackstageCredentials } from '@backstage/backend-plugin-api'; /** * Holds the information required to create a new location in the catalog location store. - * - * @public */ export interface LocationInput { type: string; @@ -30,7 +28,6 @@ export interface LocationInput { /** * The location service manages entity locations. - * @public */ export interface LocationService { createLocation( @@ -59,8 +56,6 @@ export interface LocationService { /** * Options for requesting a refresh of entities in the catalog. - * - * @public */ export type RefreshOptions = { /** The reference to a single entity that should be refreshed */ @@ -70,8 +65,6 @@ export type RefreshOptions = { /** * A service that manages refreshes of entities in the catalog. - * - * @public */ export interface RefreshService { /** @@ -82,7 +75,6 @@ export interface RefreshService { /** * Interacts with the database to manage locations. - * @public */ export interface LocationStore { createLocation(location: LocationInput): Promise; diff --git a/plugins/catalog-backend/src/tests/integration.test.ts b/plugins/catalog-backend/src/tests/integration.test.ts index 76d6af1f0d..400bbc7538 100644 --- a/plugins/catalog-backend/src/tests/integration.test.ts +++ b/plugins/catalog-backend/src/tests/integration.test.ts @@ -47,7 +47,7 @@ import { } from '../processing/DefaultCatalogProcessingEngine'; import { DefaultCatalogProcessingOrchestrator } from '../processing/DefaultCatalogProcessingOrchestrator'; import { connectEntityProviders } from '../processing/connectEntityProviders'; -import { CatalogProcessingEngine } from '../processing'; +import { CatalogProcessingEngine } from '../processing/types'; import { DefaultEntitiesCatalog } from '../service/DefaultEntitiesCatalog'; import { DefaultRefreshService } from '../service/DefaultRefreshService'; import { RefreshOptions, RefreshService } from '../service/types'; diff --git a/plugins/catalog-backend/src/util/conversion.ts b/plugins/catalog-backend/src/util/conversion.ts index 0b92b88d90..7d542e0ce1 100644 --- a/plugins/catalog-backend/src/util/conversion.ts +++ b/plugins/catalog-backend/src/util/conversion.ts @@ -32,7 +32,6 @@ export function locationSpecToMetadataName(location: LocationSpec) { return `generated-${hash}`; } -/** @public */ export function locationSpecToLocationEntity(opts: { location: LocationSpec; parentEntity?: Entity; diff --git a/yarn.lock b/yarn.lock index c7f79ae2f0..7a3aeefd84 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6016,7 +6016,6 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend@workspace:plugins/catalog-backend" dependencies: - "@backstage/backend-common": "npm:^0.25.0" "@backstage/backend-defaults": "workspace:^" "@backstage/backend-openapi-utils": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" From 633d950fe71ca74d68237d3ab6dd77e937cf2e09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 25 Apr 2025 22:04:34 +0200 Subject: [PATCH 6/6] remove CodeOwnersProcessor from the defaults MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/sad-showers-begin.md | 2 ++ plugins/catalog-backend/package.json | 2 +- plugins/catalog-backend/src/service/CatalogBuilder.ts | 2 -- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.changeset/sad-showers-begin.md b/.changeset/sad-showers-begin.md index 3f78400a13..7fce23a2ab 100644 --- a/.changeset/sad-showers-begin.md +++ b/.changeset/sad-showers-begin.md @@ -4,6 +4,8 @@ **BREAKING**: Removed all deprecated exports, and removed support for the old backend system. +It also removes the `CodeOwnersProcessor` from the default set of processors, because it is expensive to run and has vague semantics. You need to update your backend to add it to the `catalogProcessingExtensionPoint` if you wish to continue using it. + The following removed exports are available from `@backstage/plugin-catalog-node`: - `locationSpecToMetadataName` diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 58df69f6a3..f2c872e410 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -75,7 +75,6 @@ "@backstage/plugin-permission-node": "workspace:^", "@backstage/types": "workspace:^", "@opentelemetry/api": "^1.9.0", - "@types/express": "^4.17.6", "codeowners-utils": "^1.0.2", "core-js": "^3.6.5", "express": "^4.17.1", @@ -102,6 +101,7 @@ "@backstage/repo-tools": "workspace:^", "@backstage/test-utils": "workspace:^", "@types/core-js": "^2.5.4", + "@types/express": "^4.17.6", "@types/git-url-parse": "^9.0.0", "@types/glob": "^8.0.0", "@types/lodash": "^4.14.151", diff --git a/plugins/catalog-backend/src/service/CatalogBuilder.ts b/plugins/catalog-backend/src/service/CatalogBuilder.ts index 899563c74d..8aa2059209 100644 --- a/plugins/catalog-backend/src/service/CatalogBuilder.ts +++ b/plugins/catalog-backend/src/service/CatalogBuilder.ts @@ -85,7 +85,6 @@ import { DefaultCatalogProcessingOrchestrator } from '../processing/DefaultCatal import { AnnotateLocationEntityProcessor, BuiltinKindsEntityProcessor, - CodeOwnersProcessor, FileReaderProcessor, PlaceholderProcessor, UrlReaderProcessor, @@ -358,7 +357,6 @@ export class CatalogBuilder { return [ new FileReaderProcessor(), new UrlReaderProcessor({ reader, logger, config }), - CodeOwnersProcessor.fromConfig(config, { logger, reader }), new AnnotateLocationEntityProcessor({ integrations }), ]; }