Skip to content

Commit

Permalink
fix(runtime): disable GraphQL JIT if there are nested input types (#6760
Browse files Browse the repository at this point in the history
)

* fix(runtime): disable GraphQL JIT if there are nested input types

* Fix TS build
  • Loading branch information
ardatan authored Mar 28, 2024
1 parent 425afee commit c008dda
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/spotty-chefs-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@graphql-mesh/runtime": patch
---

Disable GraphQL JIT if there are nested input types
34 changes: 26 additions & 8 deletions packages/legacy/runtime/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { ASTNode, BREAK, getNamedType, GraphQLSchema, visit } from 'graphql';
import {
ASTNode,
BREAK,
getNamedType,
GraphQLInputObjectType,
GraphQLInputType,
GraphQLSchema,
visit,
} from 'graphql';
import { getDocumentString } from '@envelop/core';
import { MapperKind, mapSchema, memoize1 } from '@graphql-tools/utils';

Expand Down Expand Up @@ -33,16 +41,26 @@ export const isGraphQLJitCompatible = memoize1(function isGraphQLJitCompatible(
let compatibleSchema = true;
mapSchema(schema, {
[MapperKind.INPUT_OBJECT_TYPE]: type => {
const fieldMap = type.getFields();
for (const fieldName in fieldMap) {
const fieldObj = fieldMap[fieldName];
const namedType = getNamedType(fieldObj.type);
if (namedType.name === type.name) {
const seenTypes = new Set<string>();
function visitInputType(type: GraphQLInputObjectType) {
if (seenTypes.has(type.toString())) {
compatibleSchema = false;
return undefined;
return false;
}
seenTypes.add(type.toString());
const fields = type.getFields();
for (const field of Object.values(fields)) {
const fieldType = getNamedType(field.type) as GraphQLInputType;
if (fieldType instanceof GraphQLInputObjectType) {
if (!visitInputType(fieldType)) {
return false;
}
}
}
return true;
}
return undefined;
visitInputType(type);
return type;
},
});
if (compatibleSchema) {
Expand Down
53 changes: 53 additions & 0 deletions packages/legacy/runtime/test/isGraphQLJitCompatible.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { makeExecutableSchema } from '@graphql-tools/schema';
import { isGraphQLJitCompatible } from '../src/utils';

describe('isGraphQLJitCompatible', () => {
it('should return false if the schema has recursive input types', () => {
const schema = makeExecutableSchema({
typeDefs: `
type Query {
hello(field: RecursiveInput): String
}
input RecursiveInput {
regularInput: String
recursiveInput: RecursiveInput
}
`,
resolvers: {},
});
expect(isGraphQLJitCompatible(schema)).toBeFalsy();
});
it('should return false if the schema has recursive input types nestedly', () => {
const schema = makeExecutableSchema({
typeDefs: `
type Query {
hello(field: RecursiveInput): String
}
input RecursiveInput {
regularInput: String
anotherInput: AnotherInput
}
input AnotherInput {
recursiveInput: RecursiveInput
}
`,
resolvers: {},
});
expect(isGraphQLJitCompatible(schema)).toBeFalsy();
});
it('should return true if the schema does not have recursive input types', () => {
const schema = makeExecutableSchema({
typeDefs: `
type Query {
hello(input: TestInput): String
hello2(input: TestInput): String
}
input TestInput {
field: String
}
`,
resolvers: {},
});
expect(isGraphQLJitCompatible(schema)).toBeTruthy();
});
});

0 comments on commit c008dda

Please sign in to comment.