diff --git a/packages/catalog-model/report-alpha.api.md b/packages/catalog-model/report-alpha.api.md index c00f6ac675..5b45d80adb 100644 --- a/packages/catalog-model/report-alpha.api.md +++ b/packages/catalog-model/report-alpha.api.md @@ -39,6 +39,24 @@ export interface AlphaEntity extends Entity_2 { status?: EntityStatus; } +// @public +interface ApiEntityV1alpha1 extends Entity { + // (undocumented) + apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1'; + // (undocumented) + kind: 'API'; + // (undocumented) + spec: { + type: string; + lifecycle: string; + owner: string; + definition: string; + system?: string; + }; +} +export { ApiEntityV1alpha1 as ApiEntity }; +export { ApiEntityV1alpha1 }; + // @alpha export type AsyncCatalogModelSourceGenerator = AsyncGenerator< { @@ -493,7 +511,7 @@ export const isAiResourceEntity: ( // @alpha export function isMcpServerApiEntity( - entity: Entity, + entity: ApiEntityV1alpha1 | McpServerApiEntity, ): entity is McpServerApiEntity; // @alpha @@ -507,11 +525,7 @@ export type KindValidator = { }; // @alpha -export interface McpServerApiEntity extends Entity { - // (undocumented) - apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1'; - // (undocumented) - kind: 'API'; +export interface McpServerApiEntity extends Omit { // (undocumented) spec: { type: 'mcp-server'; diff --git a/packages/catalog-model/src/kinds/McpServerApiEntity.test.ts b/packages/catalog-model/src/kinds/McpServerApiEntity.test.ts index 60498b1c3d..a203a462da 100644 --- a/packages/catalog-model/src/kinds/McpServerApiEntity.test.ts +++ b/packages/catalog-model/src/kinds/McpServerApiEntity.test.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import type { ApiEntityV1alpha1 } from './ApiEntityV1alpha1'; import { McpServerApiEntity, mcpServerApiEntityValidator, @@ -104,29 +105,17 @@ describe('isMcpServerApiEntity', () => { }); it('returns false for a non-mcp-server API entity', () => { - expect( - isMcpServerApiEntity({ - apiVersion: 'backstage.io/v1alpha1', - kind: 'API', - metadata: { name: 'a' }, - spec: { - type: 'openapi', - lifecycle: 'production', - owner: 'me', - definition: 'x', - }, - }), - ).toBe(false); - }); - - it('returns false for a non-API entity', () => { - expect( - isMcpServerApiEntity({ - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { name: 'c' }, - spec: { type: 'service', lifecycle: 'production', owner: 'me' }, - }), - ).toBe(false); + const entity: ApiEntityV1alpha1 = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'API', + metadata: { name: 'a' }, + spec: { + type: 'openapi', + lifecycle: 'production', + owner: 'me', + definition: 'x', + }, + }; + expect(isMcpServerApiEntity(entity)).toBe(false); }); }); diff --git a/packages/catalog-model/src/kinds/McpServerApiEntity.ts b/packages/catalog-model/src/kinds/McpServerApiEntity.ts index a81de0cc41..8ddfad472e 100644 --- a/packages/catalog-model/src/kinds/McpServerApiEntity.ts +++ b/packages/catalog-model/src/kinds/McpServerApiEntity.ts @@ -15,7 +15,7 @@ */ import { createCatalogModelLayer } from '../model/createCatalogModelLayer'; -import type { Entity } from '../entity/Entity'; +import type { ApiEntityV1alpha1 } from './ApiEntityV1alpha1'; import mcpServerSchema from '../schema/kinds/API.v1alpha1.mcp-server.schema.json'; import { ajvCompiledJsonSchemaValidator } from './util'; @@ -25,9 +25,7 @@ import { ajvCompiledJsonSchemaValidator } from './util'; * * @alpha */ -export interface McpServerApiEntity extends Entity { - apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1'; - kind: 'API'; +export interface McpServerApiEntity extends Omit { spec: { type: 'mcp-server'; lifecycle: string; @@ -61,12 +59,9 @@ export const mcpServerApiEntityValidator = * @alpha */ export function isMcpServerApiEntity( - entity: Entity, + entity: ApiEntityV1alpha1 | McpServerApiEntity, ): entity is McpServerApiEntity { - return ( - entity.kind === 'API' && - (entity as McpServerApiEntity).spec?.type === 'mcp-server' - ); + return entity.spec.type === 'mcp-server'; } /** diff --git a/packages/catalog-model/src/kinds/apiEntityModel.test.ts b/packages/catalog-model/src/kinds/apiEntityModel.test.ts index 09373490fd..fbea61ebb5 100644 --- a/packages/catalog-model/src/kinds/apiEntityModel.test.ts +++ b/packages/catalog-model/src/kinds/apiEntityModel.test.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import lodash from 'lodash'; import { compileCatalogModel } from '../model/compileCatalogModel'; import { defaultCatalogEntityModel } from '../model/defaultCatalogEntityModel'; import { mcpServerApiEntityModel } from './McpServerApiEntity'; @@ -40,10 +41,14 @@ describe('apiEntityModel mcp-server dispatch', () => { expect(openapi).toBeDefined(); expect(mcp!.description).not.toBe(openapi!.description); - const mcpSpecRequired = (mcp!.jsonSchema.properties as any).spec - .required as string[]; - const openapiSpecRequired = (openapi!.jsonSchema.properties as any).spec - .required as string[]; + const mcpSpecRequired = lodash.get( + mcp, + 'jsonSchema.properties.spec.required', + ); + const openapiSpecRequired = lodash.get( + openapi, + 'jsonSchema.properties.spec.required', + ); expect(mcpSpecRequired).toContain('remotes'); expect(mcpSpecRequired).not.toContain('definition'); @@ -58,8 +63,7 @@ describe('apiEntityModel mcp-server dispatch', () => { spec: { type: 'mcp-server' }, }); expect(mcp).toBeDefined(); - const required = (mcp!.jsonSchema.properties as any).spec - .required as string[]; + const required = lodash.get(mcp, 'jsonSchema.properties.spec.required'); expect(required).toContain('remotes'); }); });