Types and validation framework for Backstage's software catalog model with support for all entity kinds, relationships, and validation policies
93
Evaluation — 93%
↑ 1.05xAgent success when using this tile
The 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';Install with Tessl CLI
npx tessl i tessl/npm-backstage--catalog-modeldocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10