From 90579b9089ca4111ba81316d2985e8eb283fdc44 Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 10 Aug 2020 18:50:08 +0200 Subject: [PATCH] feat(gql/catalog): Reduce the amount of duplication a little for unions --- plugins/catalog-graphql/codegen.yml | 2 +- plugins/catalog-graphql/schema.gql | 38 +++++++++- plugins/catalog-graphql/src/graphql/module.ts | 54 +++++++++++++- plugins/catalog-graphql/src/graphql/types.ts | 72 +++++++++++++++++-- 4 files changed, 156 insertions(+), 10 deletions(-) diff --git a/plugins/catalog-graphql/codegen.yml b/plugins/catalog-graphql/codegen.yml index ebdb34a938..a4f3abcbe4 100644 --- a/plugins/catalog-graphql/codegen.yml +++ b/plugins/catalog-graphql/codegen.yml @@ -1,5 +1,5 @@ overwrite: true -schema: ./src/schema.gql +schema: ./schema.gql require: - ts-node/register/transpile-only generates: diff --git a/plugins/catalog-graphql/schema.gql b/plugins/catalog-graphql/schema.gql index bb8e5bcc87..813b2840a6 100644 --- a/plugins/catalog-graphql/schema.gql +++ b/plugins/catalog-graphql/schema.gql @@ -1,9 +1,43 @@ scalar JSON scalar JSONObject -type EntityMetadata { +interface EntityMetadata { + name: String! + annotations: JSONObject! + annotation(name: String!): JSON + labels: JSONObject! + label(name: String!): JSON + uid: String! + etag: String! + generation: Int! +} + +type ComponentMetadata implements EntityMetadata { + name: String! + annotations: JSONObject! + annotation(name: String!): JSON + labels: JSONObject! + label(name: String!): JSON + uid: String! + etag: String! + generation: Int! + relationships: String! +} + +type TemplateMetadata implements EntityMetadata { + name: String! + annotations: JSONObject! + annotation(name: String!): JSON + labels: JSONObject! + label(name: String!): JSON + uid: String! + etag: String! + generation: Int! + updatedBy: String! +} + +type DefaultEntityMetadata implements EntityMetadata { name: String! - namespace: String! annotations: JSONObject! annotation(name: String!): JSON labels: JSONObject! diff --git a/plugins/catalog-graphql/src/graphql/module.ts b/plugins/catalog-graphql/src/graphql/module.ts index 3068b3b129..f66ff5073e 100644 --- a/plugins/catalog-graphql/src/graphql/module.ts +++ b/plugins/catalog-graphql/src/graphql/module.ts @@ -17,8 +17,14 @@ import { Logger } from 'winston'; import fs from 'fs'; import path from 'path'; +import { makeExecutableSchema } from 'apollo-server'; import { GraphQLModule } from '@graphql-modules/core'; -import { Resolvers, CatalogQuery } from './types'; +import { + Resolvers, + CatalogQuery, + CatalogEntityTypes, + EntityMetadataResolvers, +} from './types'; import { Config } from '@backstage/config'; import { CatalogClient } from '../service/client'; import GraphQLJSON, { GraphQLJSONObject } from 'graphql-type-json'; @@ -33,6 +39,19 @@ const schemaPath = path.resolve( '../schema.gql', ); +const getSpecTypenameForEntity = (e: { kind?: string }) => { + switch (e.kind) { + case 'Component': + return 'ComponentEntity'; + case 'Location': + return 'LocationEntity'; + case 'Template': + return 'TemplateEntity'; + default: + return null; + } +}; + export async function createModule( options: ModuleOptions, ): Promise { @@ -53,15 +72,46 @@ export async function createModule( return await catalogClient.list(); }, }, + ComponentMetadata: { + relationships: () => 'boop', + }, + TemplateMetadata: { + updatedBy: () => 'blam', + }, + CatalogEntity: { + metadata: e => ({ ...e.metadata!, catalogEntity: e }), + }, EntityMetadata: { + __resolveType: (obj: any) => { + const kind = obj.catalogEntity!.kind; + switch (kind) { + case 'Component': + return 'ComponentMetadata'; + case 'Template': + return 'TemplateMetadata'; + default: + return 'DefaultEntityMetadata'; + } + }, annotation: (e, { name }) => e.annotations?.[name] ?? null, + labels: e => e ?? {}, + annotations: e => e ?? {}, label: (e, { name }) => e.labels?.[name] ?? null, }, }; - const module = new GraphQLModule({ + const schema = makeExecutableSchema({ typeDefs, resolvers, + inheritResolversFromInterfaces: true, + resolverValidationOptions: { + allowResolversNotInSchema: true, + }, + }); + + const module = new GraphQLModule({ + resolverValidationOptions: {}, + extraSchemas: [schema], logger: options.logger as any, }); diff --git a/plugins/catalog-graphql/src/graphql/types.ts b/plugins/catalog-graphql/src/graphql/types.ts index 7294f749ad..e2b10ec6a2 100644 --- a/plugins/catalog-graphql/src/graphql/types.ts +++ b/plugins/catalog-graphql/src/graphql/types.ts @@ -33,9 +33,7 @@ export type Scalars = { export type EntityMetadata = { - __typename?: 'EntityMetadata'; name: Scalars['String']; - namespace: Scalars['String']; annotations: Scalars['JSONObject']; annotation?: Maybe; labels: Scalars['JSONObject']; @@ -55,6 +53,39 @@ export type EntityMetadataLabelArgs = { name: Scalars['String']; }; +export type ComponentMetadata = EntityMetadata & { + __typename?: 'ComponentMetadata'; + relationships: Scalars['String']; +}; + +export type TemplateMetadata = EntityMetadata & { + __typename?: 'TemplateMetadata'; + updatedBy: 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']; + updatedBy: Scalars['String']; +}; + + +export type DefaultEntityMetadataAnnotationArgs = { + name: Scalars['String']; +}; + + +export type DefaultEntityMetadataLabelArgs = { + name: Scalars['String']; +}; + export type CatalogEntity = { __typename?: 'CatalogEntity'; apiVersion: Scalars['String']; @@ -153,9 +184,12 @@ export type DirectiveResolverFn>; JSONObject: ResolverTypeWrapper>; - EntityMetadata: ResolverTypeWrapper>; + EntityMetadata: ResolversTypes['ComponentMetadata'] | ResolversTypes['TemplateMetadata'] | ResolversTypes['DefaultEntityMetadata']; String: ResolverTypeWrapper>; Int: ResolverTypeWrapper>; + ComponentMetadata: ResolverTypeWrapper>; + TemplateMetadata: ResolverTypeWrapper>; + DefaultEntityMetadata: ResolverTypeWrapper>; CatalogEntity: ResolverTypeWrapper>; CatalogQuery: ResolverTypeWrapper>; Query: ResolverTypeWrapper<{}>; @@ -166,9 +200,12 @@ export type ResolversTypes = ResolversObject<{ export type ResolversParentTypes = ResolversObject<{ JSON: Partial; JSONObject: Partial; - EntityMetadata: Partial; + EntityMetadata: ResolversParentTypes['ComponentMetadata'] | ResolversParentTypes['TemplateMetadata'] | ResolversParentTypes['DefaultEntityMetadata']; String: Partial; Int: Partial; + ComponentMetadata: Partial; + TemplateMetadata: Partial; + DefaultEntityMetadata: Partial; CatalogEntity: Partial; CatalogQuery: Partial; Query: {}; @@ -184,8 +221,8 @@ export interface JsonObjectScalarConfig extends GraphQLScalarTypeConfig = ResolversObject<{ + __resolveType: TypeResolveFn<'ComponentMetadata' | 'TemplateMetadata' | 'DefaultEntityMetadata', ParentType, ContextType>; name?: Resolver; - namespace?: Resolver; annotations?: Resolver; annotation?: Resolver, ParentType, ContextType, RequireFields>; labels?: Resolver; @@ -193,6 +230,28 @@ export type EntityMetadataResolvers; etag?: Resolver; generation?: Resolver; +}>; + +export type ComponentMetadataResolvers = ResolversObject<{ + relationships?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}>; + +export type TemplateMetadataResolvers = ResolversObject<{ + updatedBy?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}>; + +export type DefaultEntityMetadataResolvers = ResolversObject<{ + name?: Resolver; + annotations?: Resolver; + annotation?: Resolver, ParentType, ContextType, RequireFields>; + labels?: Resolver; + label?: Resolver, ParentType, ContextType, RequireFields>; + uid?: Resolver; + etag?: Resolver; + generation?: Resolver; + updatedBy?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }>; @@ -216,6 +275,9 @@ export type Resolvers = ResolversObject<{ JSON?: GraphQLScalarType; JSONObject?: GraphQLScalarType; EntityMetadata?: EntityMetadataResolvers; + ComponentMetadata?: ComponentMetadataResolvers; + TemplateMetadata?: TemplateMetadataResolvers; + DefaultEntityMetadata?: DefaultEntityMetadataResolvers; CatalogEntity?: CatalogEntityResolvers; CatalogQuery?: CatalogQueryResolvers; Query?: QueryResolvers;