Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 54 additions & 4 deletions src/introspection/introspection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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:
};
Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export type SimplifiedType = SimplifiedTypeBase & {
fields?: Record<string, SimplifiedField<string>>;
interfaces?: string[];
possibleTypes?: string[];
parents?: string[];
};

export type SimplifiedTypeWithIDs = SimplifiedTypeBase & {
Expand All @@ -54,6 +55,7 @@ export type SimplifiedTypeWithIDs = SimplifiedTypeBase & {
id: string;
type: SimplifiedTypeWithIDs;
}[];
parents?: string[];
};

export interface SimplifiedIntrospection {
Expand Down