Merge pull request #10196 from backstage/jhaals/reduce-catalog-backend-api

catalog-backend: Reduce public API surface
This commit is contained in:
Fredrik Adelöw
2022-03-15 12:12:38 +01:00
committed by GitHub
13 changed files with 53 additions and 296 deletions
+44
View File
@@ -0,0 +1,44 @@
---
'@backstage/plugin-catalog-backend': minor
---
**BREAKING**: A number of types and classes have been removed, without a prior deprecation period. These were all very internal, essentially unused by the vast majority of users, and their being exposed was leading to excessive breaking of public interfaces for little-to-zero benefit. So for the 1.0 release of the catalog, the following interface changes have been made (but should have no effect on most users):
- The return type of `CatalogBuilder.build()` now only has the fields `processingEngine` and `router` which is what most users actually consume; the other three fields (`entitiesCatalog`, `locationAnalyzer`, `locationService`) that see very little use have been removed. If you were relying on the presence of either of these in any way, please [open an issue](https://github.com/backstage/backstage/issues/new/choose) that describes your use case, and we'll see how we could fill the gap.
- The function `createRouter` is removed; use `CatalogBuilder` as follows instead:
```ts
const builder = await CatalogBuilder.create(env);
// add things as needed, e.g builder.addProcessor(new ScaffolderEntitiesProcessor());
const { processingEngine, router } = await builder.build();
await processingEngine.start();
return router;
```
- The following types were removed:
- `CatalogProcessingOrchestrator`
- `CatalogRule`
- `CatalogRulesEnforcer`
- `EntityAncestryResponse`
- `EntityFacetsRequest`
- `EntityFacetsResponse`
- `EntityPagination`
- `EntityProcessingRequest`
- `EntityProcessingResult`
- `EntitiesCatalog`
- `EntitiesRequest`
- `EntitiesResponse`
- `LocationService`
- `LocationInput`
- `LocationStore`
- `PageInfo`
- `RefreshOptions`
- `RefreshService`
- `RouterOptions`
- The following classes were removed:
- `DefaultCatalogProcessingOrchestrator`
- `DefaultCatalogRulesEnforcer`
-235
View File
@@ -14,11 +14,8 @@ import { Config } from '@backstage/config';
import { DocumentCollatorFactory } from '@backstage/plugin-search-common';
import { Entity } from '@backstage/catalog-model';
import { EntityPolicy } from '@backstage/catalog-model';
import express from 'express';
import { GetEntitiesRequest } from '@backstage/catalog-client';
import { JsonObject } from '@backstage/types';
import { JsonValue } from '@backstage/types';
import { Location as Location_2 } from '@backstage/catalog-client';
import { Logger } from 'winston';
import { Permission } from '@backstage/plugin-permission-common';
import { PermissionAuthorizer } from '@backstage/plugin-permission-common';
@@ -121,10 +118,7 @@ export class CatalogBuilder {
): void;
addProcessor(...processors: CatalogProcessor[]): CatalogBuilder;
build(): Promise<{
entitiesCatalog: EntitiesCatalog;
locationAnalyzer: LocationAnalyzer;
processingEngine: CatalogProcessingEngine;
locationService: LocationService;
router: Router;
}>;
static create(env: CatalogEnvironment): CatalogBuilder;
@@ -187,12 +181,6 @@ export interface CatalogProcessingEngine {
stop(): Promise<void>;
}
// @public
export interface CatalogProcessingOrchestrator {
// (undocumented)
process(request: EntityProcessingRequest): Promise<EntityProcessingResult>;
}
// @public (undocumented)
export type CatalogProcessor = {
getProcessorName(): string;
@@ -267,22 +255,6 @@ export type CatalogProcessorResult =
| CatalogProcessorRelationResult
| CatalogProcessorErrorResult;
// @public
export type CatalogRule = {
allow: Array<{
kind: string;
}>;
locations?: Array<{
target?: string;
type: string;
}>;
};
// @public
export type CatalogRulesEnforcer = {
isAllowed(entity: Entity, location: LocationSpec): boolean;
};
// @public (undocumented)
export class CodeOwnersProcessor implements CatalogProcessor {
constructor(options: {
@@ -320,9 +292,6 @@ export function createRandomProcessingInterval(options: {
maxSeconds: number;
}): ProcessingIntervalFunction;
// @public
export function createRouter(options: RouterOptions): Promise<express.Router>;
// @public @deprecated (undocumented)
export class DefaultCatalogCollator {
constructor(options: {
@@ -389,101 +358,18 @@ export type DefaultCatalogCollatorFactoryOptions = {
catalogClient?: CatalogApi;
};
// @public (undocumented)
export class DefaultCatalogProcessingOrchestrator
implements CatalogProcessingOrchestrator
{
constructor(options: {
processors: CatalogProcessor[];
integrations: ScmIntegrationRegistry;
logger: Logger;
parser: CatalogProcessorParser;
policy: EntityPolicy;
rulesEnforcer: CatalogRulesEnforcer;
});
// (undocumented)
process(request: EntityProcessingRequest): Promise<EntityProcessingResult>;
}
// @public
export class DefaultCatalogRulesEnforcer implements CatalogRulesEnforcer {
constructor(rules: CatalogRule[]);
static readonly defaultRules: CatalogRule[];
static fromConfig(config: Config): DefaultCatalogRulesEnforcer;
isAllowed(entity: Entity, location: LocationSpec): boolean;
}
// @public
export type DeferredEntity = {
entity: Entity;
locationKey?: string;
};
// @public (undocumented)
export type EntitiesCatalog = {
entities(request?: EntitiesRequest): Promise<EntitiesResponse>;
removeEntityByUid(
uid: string,
options?: {
authorizationToken?: string;
},
): Promise<void>;
entityAncestry(
entityRef: string,
options?: {
authorizationToken?: string;
},
): Promise<EntityAncestryResponse>;
facets(request: EntityFacetsRequest): Promise<EntityFacetsResponse>;
};
// @public (undocumented)
export type EntitiesRequest = {
filter?: EntityFilter;
fields?: (entity: Entity) => Entity;
pagination?: EntityPagination;
authorizationToken?: string;
};
// @public (undocumented)
export type EntitiesResponse = {
entities: Entity[];
pageInfo: PageInfo;
};
// @public
export type EntitiesSearchFilter = {
key: string;
values?: string[];
};
// @public (undocumented)
export type EntityAncestryResponse = {
rootEntityRef: string;
items: Array<{
entity: Entity;
parentEntityRefs: string[];
}>;
};
// @public
export interface EntityFacetsRequest {
authorizationToken?: string;
facets: string[];
filter?: EntityFilter;
}
// @public
export interface EntityFacetsResponse {
facets: Record<
string,
Array<{
value: string;
count: number;
}>
>;
}
// @public
export type EntityFilter =
| {
@@ -497,34 +383,6 @@ export type EntityFilter =
}
| EntitiesSearchFilter;
// @public
export type EntityPagination = {
limit?: number;
offset?: number;
after?: string;
};
// @public
export type EntityProcessingRequest = {
entity: Entity;
state?: JsonObject;
};
// @public
export type EntityProcessingResult =
| {
ok: true;
state: JsonObject;
completedEntity: Entity;
deferredEntities: DeferredEntity[];
relations: EntityRelationSpec[];
errors: Error[];
}
| {
ok: false;
errors: Error[];
};
// @public
export interface EntityProvider {
connect(connection: EntityProviderConnection): Promise<void>;
@@ -593,48 +451,6 @@ export type LocationEntityProcessorOptions = {
integrations: ScmIntegrationRegistry;
};
// @public
export interface LocationInput {
// (undocumented)
target: string;
// (undocumented)
type: string;
}
// @public
export interface LocationService {
// (undocumented)
createLocation(
location: LocationInput,
dryRun: boolean,
options?: {
authorizationToken?: string;
},
): Promise<{
location: Location_2;
entities: Entity[];
exists?: boolean;
}>;
// (undocumented)
deleteLocation(
id: string,
options?: {
authorizationToken?: string;
},
): Promise<void>;
// (undocumented)
getLocation(
id: string,
options?: {
authorizationToken?: string;
},
): Promise<Location_2>;
// (undocumented)
listLocations(options?: {
authorizationToken?: string;
}): Promise<Location_2[]>;
}
// @public
export type LocationSpec = {
type: string;
@@ -642,28 +458,6 @@ export type LocationSpec = {
presence?: 'optional' | 'required';
};
// @public
export interface LocationStore {
// (undocumented)
createLocation(location: LocationInput): Promise<Location_2>;
// (undocumented)
deleteLocation(id: string): Promise<void>;
// (undocumented)
getLocation(id: string): Promise<Location_2>;
// (undocumented)
listLocations(): Promise<Location_2[]>;
}
// @public (undocumented)
export type PageInfo =
| {
hasNextPage: false;
}
| {
hasNextPage: true;
endCursor: string;
};
// @public (undocumented)
export function parseEntityYaml(
data: Buffer,
@@ -760,35 +554,6 @@ export const processingResult: Readonly<{
readonly relation: (spec: EntityRelationSpec) => CatalogProcessorResult;
}>;
// @public
export type RefreshOptions = {
entityRef: string;
authorizationToken?: string;
};
// @public
export interface RefreshService {
refresh(options: RefreshOptions): Promise<void>;
}
// @public
export interface RouterOptions {
// (undocumented)
config: Config;
// (undocumented)
entitiesCatalog?: EntitiesCatalog;
// (undocumented)
locationAnalyzer?: LocationAnalyzer;
// (undocumented)
locationService: LocationService;
// (undocumented)
logger: Logger;
// (undocumented)
permissionIntegrationRouter?: express.Router;
// (undocumented)
refreshService?: RefreshService;
}
// @public (undocumented)
export class UrlReaderProcessor implements CatalogProcessor {
constructor(options: { reader: UrlReader; logger: Logger });
+1 -12
View File
@@ -14,15 +14,4 @@
* limitations under the License.
*/
export type {
EntitiesCatalog,
EntitiesRequest,
EntitiesResponse,
EntitiesSearchFilter,
EntityAncestryResponse,
EntityFacetsRequest,
EntityFacetsResponse,
EntityFilter,
EntityPagination,
PageInfo,
} from './types';
export type { EntitiesSearchFilter, EntityFilter } from './types';
+2 -12
View File
@@ -31,7 +31,6 @@ export type EntityFilter =
/**
* A pagination rule for entities.
* @public
*/
export type EntityPagination = {
limit?: number;
@@ -60,7 +59,6 @@ export type EntitiesSearchFilter = {
values?: string[];
};
/** @public */
export type PageInfo =
| {
hasNextPage: false;
@@ -70,7 +68,6 @@ export type PageInfo =
endCursor: string;
};
/** @public */
export type EntitiesRequest = {
filter?: EntityFilter;
fields?: (entity: Entity) => Entity;
@@ -78,13 +75,11 @@ export type EntitiesRequest = {
authorizationToken?: string;
};
/** @public */
export type EntitiesResponse = {
entities: Entity[];
pageInfo: PageInfo;
};
/** @public */
export type EntityAncestryResponse = {
rootEntityRef: string;
items: Array<{
@@ -95,8 +90,6 @@ export type EntityAncestryResponse = {
/**
* The request shape for {@link EntitiesCatalog.facets}.
*
* @public
*/
export interface EntityFacetsRequest {
/**
@@ -121,8 +114,6 @@ export interface EntityFacetsRequest {
/**
* The response shape for {@link EntitiesCatalog.facets}.
*
* @public
*/
export interface EntityFacetsResponse {
/**
@@ -131,8 +122,7 @@ export interface EntityFacetsResponse {
facets: Record<string, Array<{ value: string; count: number }>>;
}
/** @public */
export type EntitiesCatalog = {
export interface EntitiesCatalog {
/**
* Fetch entities.
*
@@ -167,4 +157,4 @@ export type EntitiesCatalog = {
* @param request - Request options
*/
facets(request: EntityFacetsRequest): Promise<EntityFacetsResponse>;
};
}
@@ -23,8 +23,6 @@ import { LocationSpec } from '../api';
* Rules to apply to catalog entities.
*
* An undefined list of matchers means match all, an empty list of matchers means match none.
*
* @public
*/
export type CatalogRule = {
allow: Array<{
@@ -39,8 +37,6 @@ export type CatalogRule = {
/**
* Decides whether an entity from a given location is allowed to enter the
* catalog, according to some rule set.
*
* @public
*/
export type CatalogRulesEnforcer = {
isAllowed(entity: Entity, location: LocationSpec): boolean;
@@ -49,8 +45,6 @@ export type CatalogRulesEnforcer = {
/**
* Implements the default catalog rule set, consuming the config keys
* `catalog.rules` and `catalog.locations.[].rules`.
*
* @public
*/
export class DefaultCatalogRulesEnforcer implements CatalogRulesEnforcer {
/**
@@ -14,8 +14,6 @@
* limitations under the License.
*/
export { DefaultCatalogRulesEnforcer } from './CatalogRules';
export type { CatalogRule, CatalogRulesEnforcer } from './CatalogRules';
export type {
AnalyzeLocationEntityField,
AnalyzeLocationExistingEntity,
@@ -22,7 +22,7 @@ import { DbLocationsRow } from '../../database/tables';
import { getEntityLocationRef } from '../../processing/util';
import { EntityProvider, EntityProviderConnection } from '../../api';
import { locationSpecToLocationEntity } from '../../util/conversion';
import { LocationInput, LocationStore } from '../../service';
import { LocationInput, LocationStore } from '../../service/types';
export class DefaultLocationStore implements LocationStore, EntityProvider {
private _connection: EntityProviderConnection | undefined;
@@ -14,14 +14,7 @@
* limitations under the License.
*/
export type {
CatalogProcessingOrchestrator,
CatalogProcessingEngine,
EntityProcessingRequest,
EntityProcessingResult,
DeferredEntity,
} from './types';
export { DefaultCatalogProcessingOrchestrator } from './DefaultCatalogProcessingOrchestrator';
export type { CatalogProcessingEngine, DeferredEntity } from './types';
export { createRandomProcessingInterval } from './refresh';
export type { ProcessingIntervalFunction } from './refresh';
@@ -32,7 +32,7 @@ import { ScmIntegrations } from '@backstage/integration';
import { createHash } from 'crypto';
import { Router } from 'express';
import lodash, { keyBy } from 'lodash';
import { EntitiesCatalog, EntitiesSearchFilter } from '../catalog';
import { EntitiesSearchFilter } from '../catalog';
import {
CatalogProcessor,
@@ -76,7 +76,6 @@ import { AuthorizedRefreshService } from './AuthorizedRefreshService';
import { DefaultCatalogRulesEnforcer } from '../ingestion/CatalogRules';
import { Config } from '@backstage/config';
import { Logger } from 'winston';
import { LocationService } from './types';
import { connectEntityProviders } from '../processing/connectEntityProviders';
import { permissionRules as catalogPermissionRules } from '../permissions/rules';
import { PermissionAuthorizer } from '@backstage/plugin-permission-common';
@@ -355,10 +354,7 @@ export class CatalogBuilder {
* Wires up and returns all of the component parts of the catalog
*/
async build(): Promise<{
entitiesCatalog: EntitiesCatalog;
locationAnalyzer: LocationAnalyzer;
processingEngine: CatalogProcessingEngine;
locationService: LocationService;
router: Router;
}> {
const { config, database, logger, permissions } = this.env;
@@ -460,10 +456,7 @@ export class CatalogBuilder {
await connectEntityProviders(processingDatabase, entityProviders);
return {
entitiesCatalog,
locationAnalyzer,
processingEngine,
locationService,
router,
};
}
@@ -21,7 +21,7 @@ import type { Location } from '@backstage/catalog-client';
import type { Entity } from '@backstage/catalog-model';
import express from 'express';
import request from 'supertest';
import { EntitiesCatalog } from '../catalog';
import { EntitiesCatalog } from '../catalog/types';
import { LocationInput, LocationService, RefreshService } from './types';
import { basicEntityFilter } from './request';
import { createRouter } from './createRouter';
@@ -22,7 +22,7 @@ import express from 'express';
import Router from 'express-promise-router';
import { Logger } from 'winston';
import yn from 'yn';
import { EntitiesCatalog } from '../catalog';
import { EntitiesCatalog } from '../catalog/types';
import { LocationAnalyzer } from '../ingestion/types';
import {
basicEntityFilter,
@@ -14,14 +14,5 @@
* limitations under the License.
*/
export type {
LocationService,
RefreshService,
RefreshOptions,
LocationStore,
LocationInput,
} from './types';
export { createRouter } from './createRouter';
export type { RouterOptions } from './createRouter';
export type { CatalogEnvironment } from './CatalogBuilder';
export { CatalogBuilder } from './CatalogBuilder';
@@ -15,7 +15,7 @@
*/
import { InputError } from '@backstage/errors';
import { EntityPagination } from '../../catalog';
import { EntityPagination } from '../../catalog/types';
import { parseIntegerParam, parseStringParam } from './common';
/**