From f55a17458d93307352a05c9449dfbf9d5a04e4c2 Mon Sep 17 00:00:00 2001 From: Nicola Dellarocca Date: Thu, 8 Jun 2023 10:10:24 +0100 Subject: [PATCH 1/2] feat(introspection): add parents --- src/introspection/introspection.ts | 58 +++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/src/introspection/introspection.ts b/src/introspection/introspection.ts index d609e19..b42a550 100644 --- a/src/introspection/introspection.ts +++ b/src/introspection/introspection.ts @@ -137,8 +137,8 @@ function simplifySchema(schema: GraphQLSchema): SimplifiedIntrospection { return { types: mapValues(schema.getTypeMap(), (type) => convertType(schema, type)), queryType: schema.getQueryType().name, - mutationType: schema.getMutationType().name ?? null, - subscriptionType: schema.getSubscriptionType().name ?? null, + mutationType: schema.getMutationType()?.name ?? null, + subscriptionType: schema.getSubscriptionType()?.name ?? null, //FIXME: //directives: }; @@ -209,13 +209,63 @@ function assignTypesAndIDs(schema: SimplifiedIntrospection) { } function addParent(schema: SimplifiedIntrospection) { - return schema; + function extractFields(type) { + // no need to inspect circular types any further + if (type.type === "[Circular]") return [type]; + + // same with scalars and enums + if (_.includes(["SCALAR", "ENUM"], type.kind && type.kind)) return []; + if ( + type.type && + type.type.kind && + _.includes(["SCALAR", "ENUM"], type.type.kind) + ) + return []; + + return _.flatMap(_.values(type.fields), (currentType) => { + // if it's a composite object, use recursion to introspect the inner object + const innerTypes = currentType.type.fields + ? _.flatMap(currentType.type.fields, (subType) => + extractFields(subType) + ) + : [currentType]; + // dedupe types by their id + return _.uniqBy(_.concat(innerTypes, currentType), (x) => x.id); + }); + } + + const allFields = _.flatMap(_.values(schema.types), (type) => + extractFields(type) + ); + + /* + * Group fields by their corresponding type id + */ + const groupedFieldsByType = _.groupBy(allFields, function (field) { + return field.type.id; + }); + + /* + * Extract id and prepare the mapping + */ + const mappings = _.mapValues(groupedFieldsByType, function (t) { + return _.map(t, (field) => field.id); + }); + + /* + * Assign the mapping + */ + _.each(Object.keys(schema.types), (type) => { + if (mappings[type]) { + (schema.types[type] as any).parents = mappings[type]; + } + }); } export function getSchema(schema: GraphQLSchema) { const simpleSchema = simplifySchema(schema); assignTypesAndIDs(simpleSchema); - addParent(simpleSchema); + // addParent(simpleSchema); // Force cast to the correct type // FIXME: This is not the right way of doing it From c2297aea134cc7be52d3faad1023b5d9dda36b0f Mon Sep 17 00:00:00 2001 From: Stefano Cislaghi Date: Thu, 8 Jun 2023 10:13:45 +0100 Subject: [PATCH 2/2] chore(types): add parents in type definition --- src/types.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/types.ts b/src/types.ts index 3f1b3db..41a47c6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -37,6 +37,7 @@ export type SimplifiedType = SimplifiedTypeBase & { fields?: Record>; interfaces?: string[]; possibleTypes?: string[]; + parents?: string[]; }; export type SimplifiedTypeWithIDs = SimplifiedTypeBase & { @@ -54,6 +55,7 @@ export type SimplifiedTypeWithIDs = SimplifiedTypeBase & { id: string; type: SimplifiedTypeWithIDs; }[]; + parents?: string[]; }; export interface SimplifiedIntrospection {