From e79aaf9712fc9c991e67d94649c8903ed9488579 Mon Sep 17 00:00:00 2001 From: blam Date: Thu, 13 Jan 2022 10:33:36 +0100 Subject: [PATCH] chore: bringing all this up to date with the new dependencies. Still some stuff to work with. Signed-off-by: blam --- plugins/catalog-graphql/codegen.yml | 1 - plugins/catalog-graphql/package.json | 9 +- .../src/graphql/module.test.ts | 70 +- plugins/catalog-graphql/src/graphql/module.ts | 25 +- plugins/catalog-graphql/src/graphql/types.ts | 692 +++++++++--------- plugins/catalog-graphql/src/schema.js | 58 +- plugins/catalog-graphql/src/service/client.ts | 6 +- 7 files changed, 430 insertions(+), 431 deletions(-) diff --git a/plugins/catalog-graphql/codegen.yml b/plugins/catalog-graphql/codegen.yml index e100277942..d71c9a7017 100644 --- a/plugins/catalog-graphql/codegen.yml +++ b/plugins/catalog-graphql/codegen.yml @@ -9,7 +9,6 @@ generates: afterOneFileWrite: - eslint --fix config: - contextType: '@graphql-modules/core#ModuleContext' allowParentTypeOverride: true useIndexSignature: true defaultMapper: Partial<{T}> diff --git a/plugins/catalog-graphql/package.json b/plugins/catalog-graphql/package.json index b95e65034c..bb7cc4c45b 100644 --- a/plugins/catalog-graphql/package.json +++ b/plugins/catalog-graphql/package.json @@ -34,9 +34,9 @@ "@backstage/catalog-model": "^0.9.7", "@backstage/config": "^0.1.11", "@backstage/types": "^0.1.1", - "@graphql-modules/core": "^0.7.17", - "apollo-server": "^2.16.1", - "graphql": "^15.3.0", + "graphql-modules": "^1.0.0", + "apollo-server": "^3.0.0", + "graphql": "^16.0.0", "graphql-tag": "^2.11.0", "graphql-type-json": "^0.3.2", "node-fetch": "^2.6.1", @@ -47,7 +47,8 @@ "@backstage/test-utils": "^0.2.0", "@graphql-codegen/cli": "^2.3.1", "@graphql-codegen/typescript": "^2.4.2", - "@graphql-codegen/typescript-resolvers": "^2.4.2", + "@graphql-codegen/typescript-resolvers": "^2.4.3", + "@graphql-codegen/graphql-modules-preset": "^2.3.2", "eslint-plugin-graphql": "^4.0.0", "msw": "^0.35.0" }, diff --git a/plugins/catalog-graphql/src/graphql/module.test.ts b/plugins/catalog-graphql/src/graphql/module.test.ts index 3e835b3111..f896c64822 100644 --- a/plugins/catalog-graphql/src/graphql/module.test.ts +++ b/plugins/catalog-graphql/src/graphql/module.test.ts @@ -23,6 +23,7 @@ import { ReaderEntity } from '../service/client'; import { createLogger } from 'winston'; import { setupRequestMockHandlers } from '@backstage/test-utils'; import { gql } from 'apollo-server'; +import { Module, createApplication } from 'graphql-modules'; describe('Catalog Module', () => { const worker = setupServer(); @@ -33,6 +34,14 @@ describe('Catalog Module', () => { }, }); + const createSchema = (module: Module) => { + const application = createApplication({ + modules: [module], + }); + + return application; + }; + setupRequestMockHandlers(worker); describe('Default Entity', () => { @@ -66,10 +75,12 @@ describe('Catalog Module', () => { }); it('should call the catalog client when requesting entities', async () => { - const { schema } = await createModule({ - config: mockConfig, - logger: createLogger(), - }); + const { schema } = createSchema( + await createModule({ + config: mockConfig, + logger: createLogger(), + }), + ); const result = await execute({ schema, @@ -87,8 +98,7 @@ describe('Catalog Module', () => { } `, }); - - const [catalogItem] = result.data?.catalog.list; + const [catalogItem] = (result as any).data?.catalog?.list; expect(catalogItem.kind).toBe('Component'); expect(catalogItem.apiVersion).toBe('something'); expect(catalogItem.metadata.name).toBe('Ben'); @@ -121,10 +131,12 @@ describe('Catalog Module', () => { ), ); - const { schema } = await createModule({ - config: mockConfig, - logger: createLogger(), - }); + const { schema } = createSchema( + await createModule({ + config: mockConfig, + logger: createLogger(), + }), + ); const result = await execute({ schema, @@ -141,7 +153,7 @@ describe('Catalog Module', () => { `, }); - const [catalogItem] = result.data?.catalog.list; + const [catalogItem] = (result as any).data?.catalog.list; expect(catalogItem.metadata.annotations).toEqual({}); }); @@ -172,10 +184,12 @@ describe('Catalog Module', () => { ), ); - const { schema } = await createModule({ - config: mockConfig, - logger: createLogger(), - }); + const { schema } = createSchema( + await createModule({ + config: mockConfig, + logger: createLogger(), + }), + ); const result = await execute({ schema, @@ -192,7 +206,7 @@ describe('Catalog Module', () => { `, }); - const [catalogItem] = result.data?.catalog.list; + const [catalogItem] = (result as any).data?.catalog.list; expect(catalogItem.metadata.labels).toEqual({}); }); it('Returns the correct record from the annotation dictionary', async () => { @@ -222,10 +236,12 @@ describe('Catalog Module', () => { ), ); - const { schema } = await createModule({ - config: mockConfig, - logger: createLogger(), - }); + const { schema } = createSchema( + await createModule({ + config: mockConfig, + logger: createLogger(), + }), + ); const result = await execute({ schema, @@ -242,7 +258,7 @@ describe('Catalog Module', () => { `, }); - const [catalogItem] = result.data?.catalog.list; + const [catalogItem] = (result as any).data?.catalog.list; expect(catalogItem.metadata.test).toEqual('bloben'); }); it('Returns the correct record from the labels dictionary', async () => { @@ -272,10 +288,12 @@ describe('Catalog Module', () => { ), ); - const { schema } = await createModule({ - config: mockConfig, - logger: createLogger(), - }); + const { schema } = createSchema( + await createModule({ + config: mockConfig, + logger: createLogger(), + }), + ); const result = await execute({ schema, @@ -292,7 +310,7 @@ describe('Catalog Module', () => { `, }); - const [catalogItem] = result.data?.catalog.list; + const [catalogItem] = (result as any).data?.catalog.list; expect(catalogItem.metadata.test).toEqual('bloben'); }); }); diff --git a/plugins/catalog-graphql/src/graphql/module.ts b/plugins/catalog-graphql/src/graphql/module.ts index e7948fb1ed..e33ee429b4 100644 --- a/plugins/catalog-graphql/src/graphql/module.ts +++ b/plugins/catalog-graphql/src/graphql/module.ts @@ -15,8 +15,11 @@ */ import { Logger } from 'winston'; -import { makeExecutableSchema } from 'apollo-server'; -import { GraphQLModule } from '@graphql-modules/core'; +import { + createModule as createGraphQLModule, + Module, + gql, +} from 'graphql-modules'; import { Resolvers, CatalogQuery } from './types'; import { Config } from '@backstage/config'; import { CatalogClient } from '../service/client'; @@ -29,9 +32,7 @@ export interface ModuleOptions { config: Config; } -export async function createModule( - options: ModuleOptions, -): Promise { +export async function createModule(options: ModuleOptions): Promise { const catalogClient = new CatalogClient( options.config.getString('backend.baseUrl'), ); @@ -62,6 +63,7 @@ export async function createModule( const { entity: { kind }, } = rootValue as { entity: Entity }; + switch (kind) { case 'Component': return 'ComponentMetadata'; @@ -94,16 +96,9 @@ export async function createModule( }, }; - const schema = makeExecutableSchema({ - typeDefs, + return createGraphQLModule({ + id: 'plugin-catalog-graphql', + typeDefs: gql(typeDefs), resolvers, - inheritResolversFromInterfaces: true, }); - - const module = new GraphQLModule({ - extraSchemas: [schema], - logger: options.logger as any, - }); - - return module; } diff --git a/plugins/catalog-graphql/src/graphql/types.ts b/plugins/catalog-graphql/src/graphql/types.ts index 5c53a6d1e3..4dc5a3522b 100644 --- a/plugins/catalog-graphql/src/graphql/types.ts +++ b/plugins/catalog-graphql/src/graphql/types.ts @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Backstage Authors + * Copyright 2022 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,18 @@ import { GraphQLScalarType, GraphQLScalarTypeConfig, } from 'graphql'; -import { ModuleContext } from '@graphql-modules/core'; export type Maybe = T | null; +export type InputMaybe = Maybe; export type Exact = { [K in keyof T]: T[K]; }; +export type MakeOptional = Omit & { + [SubKey in K]?: Maybe; +}; +export type MakeMaybe = Omit & { + [SubKey in K]: Maybe; +}; export type Omit = Pick>; export type RequireFields = { [X in Exclude]?: T[X]; @@ -39,120 +45,6 @@ export type Scalars = { JSONObject: any; }; -export type EntityMetadata = { - name: Scalars['String']; - annotations: Scalars['JSONObject']; - annotation?: Maybe; - labels: Scalars['JSONObject']; - label?: Maybe; - uid: Scalars['String']; - etag: Scalars['String']; - generation: Scalars['Int']; -}; - -export type EntityMetadataAnnotationArgs = { - name: Scalars['String']; -}; - -export type EntityMetadataLabelArgs = { - name: Scalars['String']; -}; - -export type DefaultEntityMetadata = EntityMetadata & { - __typename?: 'DefaultEntityMetadata'; - name: Scalars['String']; - annotations: Scalars['JSONObject']; - annotation?: Maybe; - labels: Scalars['JSONObject']; - label?: Maybe; - uid: Scalars['String']; - etag: Scalars['String']; - generation: Scalars['Int']; -}; - -export type DefaultEntityMetadataAnnotationArgs = { - name: Scalars['String']; -}; - -export type DefaultEntityMetadataLabelArgs = { - name: Scalars['String']; -}; - -export type ComponentMetadata = EntityMetadata & { - __typename?: 'ComponentMetadata'; - name: Scalars['String']; - annotations: Scalars['JSONObject']; - annotation?: Maybe; - labels: Scalars['JSONObject']; - label?: Maybe; - uid: Scalars['String']; - etag: Scalars['String']; - generation: Scalars['Int']; - relationships?: Maybe; -}; - -export type ComponentMetadataAnnotationArgs = { - name: Scalars['String']; -}; - -export type ComponentMetadataLabelArgs = { - name: Scalars['String']; -}; - -export type TemplateMetadata = EntityMetadata & { - __typename?: 'TemplateMetadata'; - name: Scalars['String']; - annotations: Scalars['JSONObject']; - annotation?: Maybe; - labels: Scalars['JSONObject']; - label?: Maybe; - uid: Scalars['String']; - etag: Scalars['String']; - generation: Scalars['Int']; - updatedBy?: Maybe; -}; - -export type TemplateMetadataAnnotationArgs = { - name: Scalars['String']; -}; - -export type TemplateMetadataLabelArgs = { - name: Scalars['String']; -}; - -export type TemplateEntitySpec = { - __typename?: 'TemplateEntitySpec'; - type: Scalars['String']; - path?: Maybe; - schema: Scalars['JSONObject']; - templater: Scalars['String']; -}; - -export type ComponentEntitySpec = { - __typename?: 'ComponentEntitySpec'; - title: Scalars['String']; - lifecycle: Scalars['String']; - owner: Scalars['String']; -}; - -export type LocationEntitySpec = { - __typename?: 'LocationEntitySpec'; - type: Scalars['String']; - target?: Maybe; - targets: Array; -}; - -export type DefaultEntitySpec = { - __typename?: 'DefaultEntitySpec'; - raw?: Maybe; -}; - -export type EntitySpec = - | DefaultEntitySpec - | TemplateEntitySpec - | LocationEntitySpec - | ComponentEntitySpec; - export type CatalogEntity = { __typename?: 'CatalogEntity'; apiVersion: Scalars['String']; @@ -166,31 +58,128 @@ export type CatalogQuery = { list: Array; }; +export type ComponentEntitySpec = { + __typename?: 'ComponentEntitySpec'; + lifecycle: Scalars['String']; + owner: Scalars['String']; + type: Scalars['String']; +}; + +export type ComponentMetadata = EntityMetadata & { + __typename?: 'ComponentMetadata'; + annotation?: Maybe; + annotations: Scalars['JSONObject']; + etag: Scalars['String']; + generation: Scalars['Int']; + label?: Maybe; + labels: Scalars['JSONObject']; + name: Scalars['String']; + relationships?: Maybe; + uid: Scalars['String']; +}; + +export type ComponentMetadataAnnotationArgs = { + name: Scalars['String']; +}; + +export type ComponentMetadataLabelArgs = { + name: Scalars['String']; +}; + +export type DefaultEntityMetadata = EntityMetadata & { + __typename?: 'DefaultEntityMetadata'; + annotation?: Maybe; + annotations: Scalars['JSONObject']; + etag: Scalars['String']; + generation: Scalars['Int']; + label?: Maybe; + labels: Scalars['JSONObject']; + name: Scalars['String']; + uid: Scalars['String']; +}; + +export type DefaultEntityMetadataAnnotationArgs = { + name: Scalars['String']; +}; + +export type DefaultEntityMetadataLabelArgs = { + name: Scalars['String']; +}; + +export type DefaultEntitySpec = { + __typename?: 'DefaultEntitySpec'; + raw?: Maybe; +}; + +export type EntityMetadata = { + annotation?: Maybe; + annotations: Scalars['JSONObject']; + etag: Scalars['String']; + generation: Scalars['Int']; + label?: Maybe; + labels: Scalars['JSONObject']; + name: Scalars['String']; + uid: Scalars['String']; +}; + +export type EntityMetadataAnnotationArgs = { + name: Scalars['String']; +}; + +export type EntityMetadataLabelArgs = { + name: Scalars['String']; +}; + +export type EntitySpec = + | ComponentEntitySpec + | DefaultEntitySpec + | TemplateEntitySpec; + export type Query = { __typename?: 'Query'; catalog: CatalogQuery; }; +export type TemplateEntitySpec = { + __typename?: 'TemplateEntitySpec'; + path?: Maybe; + schema: Scalars['JSONObject']; + templater: Scalars['String']; + type: Scalars['String']; +}; + +export type TemplateMetadata = EntityMetadata & { + __typename?: 'TemplateMetadata'; + annotation?: Maybe; + annotations: Scalars['JSONObject']; + etag: Scalars['String']; + generation: Scalars['Int']; + label?: Maybe; + labels: Scalars['JSONObject']; + name: Scalars['String']; + uid: Scalars['String']; + updatedBy?: Maybe; +}; + +export type TemplateMetadataAnnotationArgs = { + name: Scalars['String']; +}; + +export type TemplateMetadataLabelArgs = { + name: Scalars['String']; +}; + export type WithIndex = TObject & Record; export type ResolversObject = WithIndex; export type ResolverTypeWrapper = Promise | T; -export type LegacyStitchingResolver = { - fragment: string; +export type ResolverWithResolve = { resolve: ResolverFn; }; - -export type NewStitchingResolver = { - selectionSet: string; - resolve: ResolverFn; -}; -export type StitchingResolver = - | LegacyStitchingResolver - | NewStitchingResolver; export type Resolver = | ResolverFn - | StitchingResolver; + | ResolverWithResolve; export type ResolverFn = ( parent: TParent, @@ -204,7 +193,7 @@ export type SubscriptionSubscribeFn = ( args: TArgs, context: TContext, info: GraphQLResolveInfo, -) => AsyncIterator | Promise>; +) => AsyncIterable | Promise>; export type SubscriptionResolveFn = ( parent: TParent, @@ -267,8 +256,9 @@ export type TypeResolveFn = ( info: GraphQLResolveInfo, ) => Maybe | Promise>; -export type IsTypeOfResolverFn = ( +export type IsTypeOfResolverFn = ( obj: T, + context: TContext, info: GraphQLResolveInfo, ) => boolean | Promise; @@ -289,66 +279,202 @@ export type DirectiveResolverFn< /** Mapping between all available schema types and the resolvers types */ export type ResolversTypes = ResolversObject<{ - JSON: ResolverTypeWrapper>; - JSONObject: ResolverTypeWrapper>; - EntityMetadata: - | ResolversTypes['DefaultEntityMetadata'] - | ResolversTypes['ComponentMetadata'] - | ResolversTypes['TemplateMetadata']; - String: ResolverTypeWrapper>; - Int: ResolverTypeWrapper>; - DefaultEntityMetadata: ResolverTypeWrapper>; - ComponentMetadata: ResolverTypeWrapper>; - TemplateMetadata: ResolverTypeWrapper>; - TemplateEntitySpec: ResolverTypeWrapper>; - ComponentEntitySpec: ResolverTypeWrapper>; - LocationEntitySpec: ResolverTypeWrapper>; - DefaultEntitySpec: ResolverTypeWrapper>; - EntitySpec: Partial< - | ResolversTypes['DefaultEntitySpec'] - | ResolversTypes['TemplateEntitySpec'] - | ResolversTypes['LocationEntitySpec'] - | ResolversTypes['ComponentEntitySpec'] - >; + Boolean: ResolverTypeWrapper>; CatalogEntity: ResolverTypeWrapper< Partial< Omit & { spec: ResolversTypes['EntitySpec'] } > >; CatalogQuery: ResolverTypeWrapper>; + ComponentEntitySpec: ResolverTypeWrapper>; + ComponentMetadata: ResolverTypeWrapper>; + DefaultEntityMetadata: ResolverTypeWrapper>; + DefaultEntitySpec: ResolverTypeWrapper>; + EntityMetadata: + | ResolversTypes['ComponentMetadata'] + | ResolversTypes['DefaultEntityMetadata'] + | ResolversTypes['TemplateMetadata']; + EntitySpec: Partial< + | ResolversTypes['ComponentEntitySpec'] + | ResolversTypes['DefaultEntitySpec'] + | ResolversTypes['TemplateEntitySpec'] + >; + Int: ResolverTypeWrapper>; + JSON: ResolverTypeWrapper>; + JSONObject: ResolverTypeWrapper>; Query: ResolverTypeWrapper<{}>; - Boolean: ResolverTypeWrapper>; + String: ResolverTypeWrapper>; + TemplateEntitySpec: ResolverTypeWrapper>; + TemplateMetadata: ResolverTypeWrapper>; }>; /** Mapping between all available schema types and the resolvers parents */ export type ResolversParentTypes = ResolversObject<{ - JSON: Partial; - JSONObject: Partial; - EntityMetadata: - | ResolversParentTypes['DefaultEntityMetadata'] - | ResolversParentTypes['ComponentMetadata'] - | ResolversParentTypes['TemplateMetadata']; - String: Partial; - Int: Partial; - DefaultEntityMetadata: Partial; - ComponentMetadata: Partial; - TemplateMetadata: Partial; - TemplateEntitySpec: Partial; - ComponentEntitySpec: Partial; - LocationEntitySpec: Partial; - DefaultEntitySpec: Partial; - EntitySpec: Partial< - | ResolversParentTypes['DefaultEntitySpec'] - | ResolversParentTypes['TemplateEntitySpec'] - | ResolversParentTypes['LocationEntitySpec'] - | ResolversParentTypes['ComponentEntitySpec'] - >; + Boolean: Partial; CatalogEntity: Partial< Omit & { spec: ResolversParentTypes['EntitySpec'] } >; CatalogQuery: Partial; + ComponentEntitySpec: Partial; + ComponentMetadata: Partial; + DefaultEntityMetadata: Partial; + DefaultEntitySpec: Partial; + EntityMetadata: + | ResolversParentTypes['ComponentMetadata'] + | ResolversParentTypes['DefaultEntityMetadata'] + | ResolversParentTypes['TemplateMetadata']; + EntitySpec: Partial< + | ResolversParentTypes['ComponentEntitySpec'] + | ResolversParentTypes['DefaultEntitySpec'] + | ResolversParentTypes['TemplateEntitySpec'] + >; + Int: Partial; + JSON: Partial; + JSONObject: Partial; Query: {}; - Boolean: Partial; + String: Partial; + TemplateEntitySpec: Partial; + TemplateMetadata: Partial; +}>; + +export type CatalogEntityResolvers< + ContextType = any, + ParentType = ResolversParentTypes['CatalogEntity'], +> = ResolversObject<{ + apiVersion?: Resolver; + kind?: Resolver; + metadata?: Resolver< + Maybe, + ParentType, + ContextType + >; + spec?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}>; + +export type CatalogQueryResolvers< + ContextType = any, + ParentType = ResolversParentTypes['CatalogQuery'], +> = ResolversObject<{ + list?: Resolver< + Array, + ParentType, + ContextType + >; + __isTypeOf?: IsTypeOfResolverFn; +}>; + +export type ComponentEntitySpecResolvers< + ContextType = any, + ParentType = ResolversParentTypes['ComponentEntitySpec'], +> = ResolversObject<{ + lifecycle?: Resolver; + owner?: Resolver; + type?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}>; + +export type ComponentMetadataResolvers< + ContextType = any, + ParentType = ResolversParentTypes['ComponentMetadata'], +> = ResolversObject<{ + annotation?: Resolver< + Maybe, + ParentType, + ContextType, + RequireFields + >; + annotations?: Resolver; + etag?: Resolver; + generation?: Resolver; + label?: Resolver< + Maybe, + ParentType, + ContextType, + RequireFields + >; + labels?: Resolver; + name?: Resolver; + relationships?: Resolver< + Maybe, + ParentType, + ContextType + >; + uid?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}>; + +export type DefaultEntityMetadataResolvers< + ContextType = any, + ParentType = ResolversParentTypes['DefaultEntityMetadata'], +> = ResolversObject<{ + annotation?: Resolver< + Maybe, + ParentType, + ContextType, + RequireFields + >; + annotations?: Resolver; + etag?: Resolver; + generation?: Resolver; + label?: Resolver< + Maybe, + ParentType, + ContextType, + RequireFields + >; + labels?: Resolver; + name?: Resolver; + uid?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}>; + +export type DefaultEntitySpecResolvers< + ContextType = any, + ParentType = ResolversParentTypes['DefaultEntitySpec'], +> = ResolversObject<{ + raw?: Resolver, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}>; + +export type EntityMetadataResolvers< + ContextType = any, + ParentType = ResolversParentTypes['EntityMetadata'], +> = ResolversObject<{ + __resolveType: TypeResolveFn< + 'ComponentMetadata' | 'DefaultEntityMetadata' | 'TemplateMetadata', + ParentType, + ContextType + >; + annotation?: Resolver< + Maybe, + ParentType, + ContextType, + RequireFields + >; + annotations?: Resolver; + etag?: Resolver; + generation?: Resolver; + label?: Resolver< + Maybe, + ParentType, + ContextType, + RequireFields + >; + labels?: Resolver; + name?: Resolver; + uid?: Resolver; +}>; + +export type EntitySpecResolvers< + ContextType = any, + ParentType = ResolversParentTypes['EntitySpec'], +> = ResolversObject<{ + __resolveType: TypeResolveFn< + 'ComponentEntitySpec' | 'DefaultEntitySpec' | 'TemplateEntitySpec', + ParentType, + ContextType + >; }>; export interface JsonScalarConfig @@ -361,226 +487,66 @@ export interface JsonObjectScalarConfig name: 'JSONObject'; } -export type EntityMetadataResolvers< - ContextType = ModuleContext, - ParentType = ResolversParentTypes['EntityMetadata'], +export type QueryResolvers< + ContextType = any, + ParentType = ResolversParentTypes['Query'], > = ResolversObject<{ - __resolveType: TypeResolveFn< - 'DefaultEntityMetadata' | 'ComponentMetadata' | 'TemplateMetadata', - ParentType, - ContextType - >; - name?: Resolver; - annotations?: Resolver; - annotation?: Resolver< - Maybe, - ParentType, - ContextType, - RequireFields - >; - labels?: Resolver; - label?: Resolver< - Maybe, - ParentType, - ContextType, - RequireFields - >; - uid?: Resolver; - etag?: Resolver; - generation?: Resolver; + catalog?: Resolver; }>; -export type DefaultEntityMetadataResolvers< - ContextType = ModuleContext, - ParentType = ResolversParentTypes['DefaultEntityMetadata'], +export type TemplateEntitySpecResolvers< + ContextType = any, + ParentType = ResolversParentTypes['TemplateEntitySpec'], > = ResolversObject<{ - name?: Resolver; - annotations?: Resolver; - annotation?: Resolver< - Maybe, - ParentType, - ContextType, - RequireFields - >; - labels?: Resolver; - label?: Resolver< - Maybe, - ParentType, - ContextType, - RequireFields - >; - uid?: Resolver; - etag?: Resolver; - generation?: Resolver; - __isTypeOf?: IsTypeOfResolverFn; -}>; - -export type ComponentMetadataResolvers< - ContextType = ModuleContext, - ParentType = ResolversParentTypes['ComponentMetadata'], -> = ResolversObject<{ - name?: Resolver; - annotations?: Resolver; - annotation?: Resolver< - Maybe, - ParentType, - ContextType, - RequireFields - >; - labels?: Resolver; - label?: Resolver< - Maybe, - ParentType, - ContextType, - RequireFields - >; - uid?: Resolver; - etag?: Resolver; - generation?: Resolver; - relationships?: Resolver< - Maybe, - ParentType, - ContextType - >; - __isTypeOf?: IsTypeOfResolverFn; + path?: Resolver, ParentType, ContextType>; + schema?: Resolver; + templater?: Resolver; + type?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; }>; export type TemplateMetadataResolvers< - ContextType = ModuleContext, + ContextType = any, ParentType = ResolversParentTypes['TemplateMetadata'], > = ResolversObject<{ - name?: Resolver; - annotations?: Resolver; annotation?: Resolver< Maybe, ParentType, ContextType, RequireFields >; - labels?: Resolver; + annotations?: Resolver; + etag?: Resolver; + generation?: Resolver; label?: Resolver< Maybe, ParentType, ContextType, RequireFields >; + labels?: Resolver; + name?: Resolver; uid?: Resolver; - etag?: Resolver; - generation?: Resolver; updatedBy?: Resolver< Maybe, ParentType, ContextType >; - __isTypeOf?: IsTypeOfResolverFn; + __isTypeOf?: IsTypeOfResolverFn; }>; -export type TemplateEntitySpecResolvers< - ContextType = ModuleContext, - ParentType = ResolversParentTypes['TemplateEntitySpec'], -> = ResolversObject<{ - type?: Resolver; - path?: Resolver, ParentType, ContextType>; - schema?: Resolver; - templater?: Resolver; - __isTypeOf?: IsTypeOfResolverFn; -}>; - -export type ComponentEntitySpecResolvers< - ContextType = ModuleContext, - ParentType = ResolversParentTypes['ComponentEntitySpec'], -> = ResolversObject<{ - title?: Resolver; - lifecycle?: Resolver; - owner?: Resolver; - __isTypeOf?: IsTypeOfResolverFn; -}>; - -export type LocationEntitySpecResolvers< - ContextType = ModuleContext, - ParentType = ResolversParentTypes['LocationEntitySpec'], -> = ResolversObject<{ - type?: Resolver; - target?: Resolver, ParentType, ContextType>; - targets?: Resolver, ParentType, ContextType>; - __isTypeOf?: IsTypeOfResolverFn; -}>; - -export type DefaultEntitySpecResolvers< - ContextType = ModuleContext, - ParentType = ResolversParentTypes['DefaultEntitySpec'], -> = ResolversObject<{ - raw?: Resolver, ParentType, ContextType>; - __isTypeOf?: IsTypeOfResolverFn; -}>; - -export type EntitySpecResolvers< - ContextType = ModuleContext, - ParentType = ResolversParentTypes['EntitySpec'], -> = ResolversObject<{ - __resolveType: TypeResolveFn< - | 'DefaultEntitySpec' - | 'TemplateEntitySpec' - | 'LocationEntitySpec' - | 'ComponentEntitySpec', - ParentType, - ContextType - >; -}>; - -export type CatalogEntityResolvers< - ContextType = ModuleContext, - ParentType = ResolversParentTypes['CatalogEntity'], -> = ResolversObject<{ - apiVersion?: Resolver; - kind?: Resolver; - metadata?: Resolver< - Maybe, - ParentType, - ContextType - >; - spec?: Resolver; - __isTypeOf?: IsTypeOfResolverFn; -}>; - -export type CatalogQueryResolvers< - ContextType = ModuleContext, - ParentType = ResolversParentTypes['CatalogQuery'], -> = ResolversObject<{ - list?: Resolver< - Array, - ParentType, - ContextType - >; - __isTypeOf?: IsTypeOfResolverFn; -}>; - -export type QueryResolvers< - ContextType = ModuleContext, - ParentType = ResolversParentTypes['Query'], -> = ResolversObject<{ - catalog?: Resolver; -}>; - -export type Resolvers = ResolversObject<{ - JSON?: GraphQLScalarType; - JSONObject?: GraphQLScalarType; - EntityMetadata?: EntityMetadataResolvers; - DefaultEntityMetadata?: DefaultEntityMetadataResolvers; - ComponentMetadata?: ComponentMetadataResolvers; - TemplateMetadata?: TemplateMetadataResolvers; - TemplateEntitySpec?: TemplateEntitySpecResolvers; - ComponentEntitySpec?: ComponentEntitySpecResolvers; - LocationEntitySpec?: LocationEntitySpecResolvers; - DefaultEntitySpec?: DefaultEntitySpecResolvers; - EntitySpec?: EntitySpecResolvers; +export type Resolvers = ResolversObject<{ CatalogEntity?: CatalogEntityResolvers; CatalogQuery?: CatalogQueryResolvers; + ComponentEntitySpec?: ComponentEntitySpecResolvers; + ComponentMetadata?: ComponentMetadataResolvers; + DefaultEntityMetadata?: DefaultEntityMetadataResolvers; + DefaultEntitySpec?: DefaultEntitySpecResolvers; + EntityMetadata?: EntityMetadataResolvers; + EntitySpec?: EntitySpecResolvers; + JSON?: GraphQLScalarType; + JSONObject?: GraphQLScalarType; Query?: QueryResolvers; + TemplateEntitySpec?: TemplateEntitySpecResolvers; + TemplateMetadata?: TemplateMetadataResolvers; }>; - -/** - * @deprecated - * Use "Resolvers" root object instead. If you wish to get "IResolvers", add "typesPrefix: I" to your config. - */ -export type IResolvers = Resolvers; diff --git a/plugins/catalog-graphql/src/schema.js b/plugins/catalog-graphql/src/schema.js index 6894ad5a03..6690f34da6 100644 --- a/plugins/catalog-graphql/src/schema.js +++ b/plugins/catalog-graphql/src/schema.js @@ -14,41 +14,58 @@ * limitations under the License. */ -const metadataFields = /* GraphQL */ ` - name: String! - annotations: JSONObject! - annotation(name: String!): JSON - labels: JSONObject! - label(name: String!): JSON - uid: String! - etag: String! - generation: Int! -`; - const schema = /* GraphQL */ ` scalar JSON scalar JSONObject - + interface EntityMetadata { - ${metadataFields} + name: String! + annotations: JSONObject! + annotation(name: String!): JSON + labels: JSONObject! + label(name: String!): JSON + uid: String! + etag: String! + generation: Int! } type DefaultEntityMetadata implements EntityMetadata { - ${metadataFields} + name: String! + annotations: JSONObject! + annotation(name: String!): JSON + labels: JSONObject! + label(name: String!): JSON + uid: String! + etag: String! + generation: Int! } type ComponentMetadata implements EntityMetadata { - ${metadataFields} + name: String! + annotations: JSONObject! + annotation(name: String!): JSON + labels: JSONObject! + label(name: String!): JSON + uid: String! + etag: String! + generation: Int! # mock field to prove extensions working relationships: String } type TemplateMetadata implements EntityMetadata { - ${metadataFields} + name: String! + annotations: JSONObject! + annotation(name: String!): JSON + labels: JSONObject! + label(name: String!): JSON + uid: String! + etag: String! + generation: Int! # mock field to prove extensions working updatedBy: String } - + # TODO: move this definition into plugin-scaffolder-graphql type TemplateEntitySpec { type: String! @@ -67,8 +84,11 @@ const schema = /* GraphQL */ ` raw: JSONObject } - union EntitySpec = DefaultEntitySpec | TemplateEntitySpec | ComponentEntitySpec - + union EntitySpec = + DefaultEntitySpec + | TemplateEntitySpec + | ComponentEntitySpec + type CatalogEntity { apiVersion: String! kind: String! diff --git a/plugins/catalog-graphql/src/service/client.ts b/plugins/catalog-graphql/src/service/client.ts index 8d517fcbd6..eaf2e63bc1 100644 --- a/plugins/catalog-graphql/src/service/client.ts +++ b/plugins/catalog-graphql/src/service/client.ts @@ -16,7 +16,6 @@ import { Entity, EntityMeta } from '@backstage/catalog-model'; import fetch from 'node-fetch'; -import { JsonObject } from '@backstage/types'; export interface ReaderEntityMeta extends EntityMeta { uid: string; @@ -28,14 +27,15 @@ export interface ReaderEntityMeta extends EntityMeta { } export interface ReaderEntity extends Entity { - metadata: JsonObject & ReaderEntityMeta; + metadata: ReaderEntityMeta; } export class CatalogClient { constructor(private baseUrl: string) {} async list(): Promise { - const res = await fetch(`${this.baseUrl}/catalog/entities`); + const res = await fetch(`${this.baseUrl}/api/catalog/entities`); + if (!res.ok) { // todo(blam): need some better way to handle errors here // experiment with throwing the input errors etc and having graphql versions of that