Node.js utilities and types for building Backstage catalog modules, providing core APIs for catalog processors, entity providers, and processing workflows
npx @tessl/cli install tessl/npm-backstage--plugin-catalog-node@1.4.0The @backstage/plugin-catalog-node package provides essential Node.js utilities and TypeScript types for building Backstage catalog modules and extensions. It serves as the foundational library for backend catalog functionality, offering core APIs for catalog processors, entity providers, processing workflows, and utility functions for catalog operations.
yarn add @backstage/plugin-catalog-nodeimport {
CatalogProcessor,
EntityProvider,
processingResult,
locationSpecToLocationEntity,
DeferredEntity
} from "@backstage/plugin-catalog-node";For alpha features:
import {
catalogServiceRef,
catalogProcessingExtensionPoint
} from "@backstage/plugin-catalog-node/alpha";import {
CatalogProcessor,
processingResult,
EntityProvider,
locationSpecToLocationEntity
} from "@backstage/plugin-catalog-node";
import { Entity } from "@backstage/catalog-model";
import { LocationSpec } from "@backstage/plugin-catalog-common";
// Example processor implementation
class MyProcessor implements CatalogProcessor {
getProcessorName(): string {
return "my-processor";
}
async preProcessEntity(
entity: Entity,
location: LocationSpec,
emit: CatalogProcessorEmit,
originLocation: LocationSpec,
cache: CatalogProcessorCache
): Promise<Entity> {
// Add custom metadata
return {
...entity,
metadata: {
...entity.metadata,
annotations: {
...entity.metadata.annotations,
"example.com/processed": "true"
}
}
};
}
}
// Example entity provider
class MyEntityProvider implements EntityProvider {
getProviderName(): string {
return "my-provider";
}
async connect(connection: EntityProviderConnection): Promise<void> {
// Provide entities to catalog
await connection.applyMutation({
type: "full",
entities: [{ entity: myEntity }]
});
}
}
// Create location entity
const locationEntity = locationSpecToLocationEntity({
location: { type: "url", target: "https://example.com/catalog.yaml" }
});Backstage Plugin Catalog Node is built around several key components:
Core catalog processor interface and utilities for building custom catalog processors that handle entity ingestion, transformation, and validation.
interface CatalogProcessor {
getProcessorName(): string;
readLocation?(
location: LocationSpec,
optional: boolean,
emit: CatalogProcessorEmit,
parser: CatalogProcessorParser,
cache: CatalogProcessorCache
): Promise<boolean>;
preProcessEntity?(
entity: Entity,
location: LocationSpec,
emit: CatalogProcessorEmit,
originLocation: LocationSpec,
cache: CatalogProcessorCache
): Promise<Entity>;
validateEntityKind?(entity: Entity): Promise<boolean>;
postProcessEntity?(
entity: Entity,
location: LocationSpec,
emit: CatalogProcessorEmit,
cache: CatalogProcessorCache
): Promise<Entity>;
}
type CatalogProcessorEmit = (generated: CatalogProcessorResult) => void;
interface CatalogProcessorCache {
get<ItemType extends JsonValue>(key: string): Promise<ItemType | undefined>;
set<ItemType extends JsonValue>(key: string, value: ItemType): Promise<void>;
}Entity provider interface and related types for connecting external data sources to supply entities to the Backstage catalog.
interface EntityProvider {
getProviderName(): string;
connect(connection: EntityProviderConnection): Promise<void>;
}
interface EntityProviderConnection {
applyMutation(mutation: EntityProviderMutation): Promise<void>;
refresh(options: EntityProviderRefreshOptions): Promise<void>;
}
type EntityProviderMutation =
| { type: 'full'; entities: DeferredEntity[] }
| { type: 'delta'; added: DeferredEntity[]; removed: (DeferredEntity | { entityRef: string; locationKey?: string })[] };Factory functions and types for creating standardized processing results with proper error handling and result typing.
const processingResult: {
notFoundError(atLocation: LocationSpec, message: string): CatalogProcessorResult;
inputError(atLocation: LocationSpec, message: string): CatalogProcessorResult;
generalError(atLocation: LocationSpec, message: string): CatalogProcessorResult;
location(newLocation: LocationSpec): CatalogProcessorResult;
entity(atLocation: LocationSpec, newEntity: Entity): CatalogProcessorResult;
relation(spec: EntityRelationSpec): CatalogProcessorResult;
refresh(key: string): CatalogProcessorResult;
};
type CatalogProcessorResult =
| CatalogProcessorLocationResult
| CatalogProcessorEntityResult
| CatalogProcessorRelationResult
| CatalogProcessorErrorResult
| CatalogProcessorRefreshKeysResult;Utility functions for converting location specifications into standardized formats and Location entities.
function locationSpecToMetadataName(location: LocationSpec): string;
function locationSpecToLocationEntity(opts: {
location: LocationSpec;
parentEntity?: Entity;
}): LocationEntityV1alpha1;Alpha extension points and service references for plugin-based architecture integration. These APIs are in alpha stage and may change in future versions.
const catalogServiceRef: ServiceRef<CatalogApi, 'plugin'>;
interface CatalogProcessingExtensionPoint {
addProcessor(...processors: Array<CatalogProcessor | Array<CatalogProcessor>>): void;
addEntityProvider(...providers: Array<EntityProvider | Array<EntityProvider>>): void;
addPlaceholderResolver(key: string, resolver: PlaceholderResolver): void;
}
const catalogProcessingExtensionPoint: ExtensionPoint<CatalogProcessingExtensionPoint>;Core types and interfaces for deferred entity processing and placeholder resolution in catalog workflows.
type DeferredEntity = {
entity: Entity;
locationKey?: string;
};
type PlaceholderResolver = (params: PlaceholderResolverParams) => Promise<JsonValue>;
type PlaceholderResolverParams = {
key: string;
value: JsonValue;
baseUrl: string;
read: PlaceholderResolverRead;
resolveUrl: PlaceholderResolverResolveUrl;
emit: CatalogProcessorEmit;
};
type PlaceholderResolverRead = (url: string) => Promise<Buffer>;
type PlaceholderResolverResolveUrl = (url: string, base: string) => string;type EntityRelationSpec = {
source: CompoundEntityRef;
type: string;
target: CompoundEntityRef;
};
type LocationSpec = {
type: string;
target: string;
presence?: 'required' | 'optional';
};
type CatalogProcessorParser = (options: {
data: Buffer;
location: LocationSpec;
}) => AsyncIterable<CatalogProcessorResult>;type ServiceRef<TService, TScope = 'root'> = {
id: string;
scope: TScope;
defaultFactory?: (service: ServiceRef<TService, TScope>) => Promise<ServiceFactory<TService>>;
};
type ExtensionPoint<T> = {
id: string;
T: T;
};
type ServiceFactory<TService> = {
service: ServiceRef<TService>;
initialization: 'always' | 'lazy';
factory: (...args: any[]) => TService | Promise<TService>;
};
type JsonValue = null | boolean | number | string | JsonArray | JsonObject;
type JsonArray = JsonValue[];
type JsonObject = { [key: string]: JsonValue };