Skip to content

Commit

Permalink
fix(getDirectives): respect extensionASTNodes in GraphQLSchema object
Browse files Browse the repository at this point in the history
  • Loading branch information
ardatan committed Aug 12, 2024
1 parent e6f44e0 commit 07b87ed
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 25 deletions.
5 changes: 5 additions & 0 deletions .changeset/stupid-geckos-lay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphql-tools/utils': patch
---

Respect `extensionASTNodes` in directable GraphQLSchema object
59 changes: 35 additions & 24 deletions packages/utils/src/getDirectiveExtensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { getArgumentValues } from './getArgumentValues.js';
export type DirectableASTNode = ASTNode & { directives?: readonly DirectiveNode[] };
export type DirectableObject = {
astNode?: DirectableASTNode | null;
extensionASTNodes?: readonly DirectableASTNode[] | null;
extensions?: { directives?: Record<string, any> } | null;
};

Expand All @@ -24,36 +25,46 @@ export function getDirectiveExtensions<
TDirectiveAnnotationsMap[directiveName]
>;
} = {};
if (directableObj.astNode?.directives?.length) {
for (const directive of directableObj.astNode.directives) {
const directiveName: keyof TDirectiveAnnotationsMap = directive.name.value;
let existingDirectiveExtensions = directiveExtensions[directiveName];
if (!existingDirectiveExtensions) {
existingDirectiveExtensions = [];
directiveExtensions[directiveName] = existingDirectiveExtensions;
}
const directiveInSchema = schema?.getDirective(directiveName);
let value: any = {};
if (directiveInSchema) {
value = getArgumentValues(directiveInSchema, directive);
}
if (directive.arguments) {
for (const argNode of directive.arguments) {
const argName = argNode.name.value;
if (value[argName] == null) {
const argInDirective = directiveInSchema?.args.find(arg => arg.name === argName);
if (argInDirective) {
value[argName] = valueFromAST(argNode.value, argInDirective.type);
const astNodes: DirectableASTNode[] = [];
if (directableObj.astNode) {
astNodes.push(directableObj.astNode);
}
if (directableObj.extensionASTNodes) {
astNodes.push(...directableObj.extensionASTNodes);
}
for (const astNode of astNodes) {
if (astNode.directives?.length) {
for (const directive of astNode.directives) {
const directiveName: keyof TDirectiveAnnotationsMap = directive.name.value;
let existingDirectiveExtensions = directiveExtensions[directiveName];
if (!existingDirectiveExtensions) {
existingDirectiveExtensions = [];
directiveExtensions[directiveName] = existingDirectiveExtensions;
}
const directiveInSchema = schema?.getDirective(directiveName);
let value: any = {};
if (directiveInSchema) {
value = getArgumentValues(directiveInSchema, directive);
}
if (directive.arguments) {
for (const argNode of directive.arguments) {
const argName = argNode.name.value;
if (value[argName] == null) {
const argInDirective = directiveInSchema?.args.find(arg => arg.name === argName);
if (argInDirective) {
value[argName] = valueFromAST(argNode.value, argInDirective.type);
}
}
if (value[argName] == null) {
value[argName] = valueFromASTUntyped(argNode.value);
}
}
if (value[argName] == null) {
value[argName] = valueFromASTUntyped(argNode.value);
}
}
existingDirectiveExtensions.push(value);
}
existingDirectiveExtensions.push(value);
}
}

if (directableObj.extensions) {
let directivesInExtensions = directableObj.extensions;
for (const pathSegment of pathToDirectivesInExtensions) {
Expand Down
36 changes: 35 additions & 1 deletion packages/utils/tests/get-directives.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GraphQLSchema } from 'graphql';
import { GraphQLObjectType, GraphQLSchema, GraphQLString, Kind } from 'graphql';
import { makeExecutableSchema } from '@graphql-tools/schema';
import { assertGraphQLObjectType } from '../../testing/assertion.js';
import { getDirectives } from '../src/index.js';
Expand Down Expand Up @@ -133,4 +133,38 @@ describe('getDirectives', () => {
},
]);
});
it('gets the directives from extensionASTNodes', () => {
const schema = new GraphQLSchema({
query: new GraphQLObjectType({
name: 'Query',
fields: {
first: {
type: GraphQLString,
},
},
}),
extensionASTNodes: [
{
kind: Kind.SCHEMA_EXTENSION,
directives: [
{
kind: 'Directive',

Check failure on line 151 in packages/utils/tests/get-directives.spec.ts

View workflow job for this annotation

GitHub Actions / deployment

Type '"Directive"' is not assignable to type 'Kind.DIRECTIVE'.

Check failure on line 151 in packages/utils/tests/get-directives.spec.ts

View workflow job for this annotation

GitHub Actions / Type Check on GraphQL v16

Type '"Directive"' is not assignable to type 'Kind.DIRECTIVE'.

Check failure on line 151 in packages/utils/tests/get-directives.spec.ts

View workflow job for this annotation

GitHub Actions / Browser Test

Type '"Directive"' is not assignable to type 'Kind.DIRECTIVE'.

Check failure on line 151 in packages/utils/tests/get-directives.spec.ts

View workflow job for this annotation

GitHub Actions / Type Check on GraphQL v17.0.0-alpha.1

Type '"Directive"' is not assignable to type 'Kind.DIRECTIVE'.

Check failure on line 151 in packages/utils/tests/get-directives.spec.ts

View workflow job for this annotation

GitHub Actions / ESM Test

Type '"Directive"' is not assignable to type 'Kind.DIRECTIVE'.
name: {
kind: 'Name',

Check failure on line 153 in packages/utils/tests/get-directives.spec.ts

View workflow job for this annotation

GitHub Actions / deployment

Type '"Name"' is not assignable to type 'Kind.NAME'.

Check failure on line 153 in packages/utils/tests/get-directives.spec.ts

View workflow job for this annotation

GitHub Actions / Type Check on GraphQL v16

Type '"Name"' is not assignable to type 'Kind.NAME'.

Check failure on line 153 in packages/utils/tests/get-directives.spec.ts

View workflow job for this annotation

GitHub Actions / Browser Test

Type '"Name"' is not assignable to type 'Kind.NAME'.

Check failure on line 153 in packages/utils/tests/get-directives.spec.ts

View workflow job for this annotation

GitHub Actions / Type Check on GraphQL v17.0.0-alpha.1

Type '"Name"' is not assignable to type 'Kind.NAME'.

Check failure on line 153 in packages/utils/tests/get-directives.spec.ts

View workflow job for this annotation

GitHub Actions / ESM Test

Type '"Name"' is not assignable to type 'Kind.NAME'.
value: 'mydir',
},
arguments: [],
},
],
},
],
});
const directives = getDirectives(schema, schema);
expect(directives).toEqual([
{
name: 'mydir',
args: {},
},
]);
});
});

0 comments on commit 07b87ed

Please sign in to comment.