Types and validation framework for Backstage's software catalog model with support for all entity kinds, relationships, and validation policies
npx @tessl/cli install tessl/npm-backstage--catalog-model@1.7.0The Backstage Catalog Model provides the foundational type system and validation framework for Backstage's software catalog. It enables applications to work with catalog entities (Components, APIs, Systems, etc.) through a comprehensive set of TypeScript types, validation schemas, and utilities that ensure consistency across the entire Backstage ecosystem.
npm install @backstage/catalog-modelimport { Entity, EntityMeta, parseEntityRef, stringifyEntityRef } from "@backstage/catalog-model";For working with entity specifications:
import type { JsonObject } from "@backstage/types";For specific entity kinds:
import {
ComponentEntity,
ApiEntity,
SystemEntity,
UserEntity,
GroupEntity,
DomainEntity,
ResourceEntity,
LocationEntity
} from "@backstage/catalog-model";For validation:
import { entitySchemaValidator, makeValidator } from "@backstage/catalog-model";For alpha features:
import { AlphaEntity, EntityStatus } from "@backstage/catalog-model/alpha";import {
Entity,
ComponentEntity,
parseEntityRef,
stringifyEntityRef,
isComponentEntity,
entitySchemaValidator
} from "@backstage/catalog-model";
// Parse entity references
const entityRef = parseEntityRef("component:default/my-service");
console.log(entityRef); // { kind: "component", namespace: "default", name: "my-service" }
// Convert back to string
const refString = stringifyEntityRef(entityRef);
console.log(refString); // "component:default/my-service"
// Type checking
function processEntity(entity: Entity) {
if (isComponentEntity(entity)) {
// entity is now typed as ComponentEntity
console.log(entity.spec.type); // TypeScript knows about spec.type
}
}
// Validation
const validator = entitySchemaValidator();
try {
const validEntity = validator(someEntityData);
console.log("Entity is valid:", validEntity);
} catch (error) {
console.error("Validation failed:", error);
}The Backstage Catalog Model is built around several key components:
Entity interface and metadata structures that all catalog entities inherit fromBase entity types and metadata structures that form the foundation of the Backstage catalog model.
/** Type alias for JSON object values */
type JsonObject = Record<string, any>;
interface Entity {
apiVersion: string;
kind: string;
metadata: EntityMeta;
spec?: JsonObject;
relations?: EntityRelation[];
}
interface EntityMeta extends JsonObject {
uid?: string;
etag?: string;
name: string;
namespace?: string;
title?: string;
description?: string;
labels?: Record<string, string>;
annotations?: Record<string, string>;
tags?: string[];
links?: EntityLink[];
}Pre-defined entity types for common software catalog components with full TypeScript interfaces and validation schemas.
interface ComponentEntity extends Entity {
apiVersion: 'backstage.io/v1alpha1';
kind: 'Component';
spec: {
type: string;
lifecycle: string;
owner: string;
subcomponentOf?: string;
providesApis?: string[];
consumesApis?: string[];
dependsOn?: string[];
dependencyOf?: string[];
system?: string;
};
}
interface ApiEntity extends Entity {
apiVersion: 'backstage.io/v1alpha1';
kind: 'API';
spec: {
type: string;
lifecycle: string;
owner: string;
definition: string;
system?: string;
};
}Utilities for parsing, formatting, and working with entity references that uniquely identify catalog entities.
type CompoundEntityRef = {
kind: string;
namespace: string;
name: string;
};
function parseEntityRef(
ref: string | CompoundEntityRef,
context?: { defaultKind?: string; defaultNamespace?: string }
): CompoundEntityRef;
function stringifyEntityRef(ref: Entity | CompoundEntityRef): string;
function getCompoundEntityRef(entity: Entity): CompoundEntityRef;Comprehensive validation system with schema-based validation, field format checking, and pluggable validator functions.
function entitySchemaValidator<T extends Entity>(
schema?: unknown
): (data: unknown) => T;
function makeValidator(overrides?: Partial<Validators>): Validators;
interface Validators {
apiVersion(value: unknown): boolean;
kind(value: unknown): boolean;
entityName(value: unknown): boolean;
namespace(value: unknown): boolean;
labelKey(value: unknown): boolean;
labelValue(value: unknown): boolean;
annotationKey(value: unknown): boolean;
annotationValue(value: unknown): boolean;
tag(value: unknown): boolean;
}Rule-based entity processing system for validation and mutation during entity ingestion and processing.
interface EntityPolicy {
enforce(entity: Entity): Promise<Entity | undefined>;
}
class DefaultNamespaceEntityPolicy implements EntityPolicy {
constructor(namespace?: string);
enforce(entity: Entity): Promise<Entity>;
}
const EntityPolicies: {
allOf(policies: EntityPolicy[]): EntityPolicy;
oneOf(policies: EntityPolicy[]): EntityPolicy;
};Utilities for tracking entity sources and managing location-based metadata and references.
function parseLocationRef(ref: string): { type: string; target: string };
function stringifyLocationRef(ref: { type: string; target: string }): string;
function getEntitySourceLocation(entity: Entity): { type: string; target: string };
const ANNOTATION_LOCATION = 'backstage.io/managed-by-location';
const ANNOTATION_ORIGIN_LOCATION = 'backstage.io/managed-by-origin-location';
const ANNOTATION_SOURCE_LOCATION = 'backstage.io/source-location';Typed relationships between catalog entities for dependency tracking, ownership, and organizational structure.
interface EntityRelation {
type: string;
targetRef: string;
}
// Relation type constants
const RELATION_OWNED_BY = 'ownedBy';
const RELATION_OWNER_OF = 'ownerOf';
const RELATION_DEPENDS_ON = 'dependsOn';
const RELATION_DEPENDENCY_OF = 'dependencyOf';
const RELATION_CONSUMES_API = 'consumesApi';
const RELATION_API_CONSUMED_BY = 'apiConsumedBy';
const RELATION_PROVIDES_API = 'providesApi';
const RELATION_API_PROVIDED_BY = 'apiProvidedBy';