Skip to content

Commit

Permalink
Support InputObjectTypeDefinition & InputObjectTypeExtension for getF…
Browse files Browse the repository at this point in the history
…ieldsWithDirectives (#1934)

* test: add desired behavior

* feat: add includeInputTypes functionality

* refactor: remove incorrect type info
  • Loading branch information
danstarns committed Aug 30, 2020
1 parent 570285b commit a3ba3e3
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 7 deletions.
33 changes: 26 additions & 7 deletions packages/utils/src/get-fields-with-directives.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
import { DocumentNode, ObjectTypeDefinitionNode, ObjectTypeExtensionNode, ValueNode, Kind } from 'graphql';
import {
DocumentNode,
ObjectTypeDefinitionNode,
ObjectTypeExtensionNode,
InputObjectTypeDefinitionNode,
InputObjectTypeExtensionNode,
ValueNode,
Kind,
} from 'graphql';

export type DirectiveArgs = { [name: string]: any };
export type DirectiveUsage = { name: string; args: DirectiveArgs };
export type TypeAndFieldToDirectives = {
[typeAndField: string]: DirectiveUsage[];
};

function isObjectTypeDefinitionOrExtension(obj: any): obj is ObjectTypeDefinitionNode | ObjectTypeDefinitionNode {
return obj && (obj.kind === 'ObjectTypeDefinition' || obj.kind === 'ObjectTypeExtension');
interface Options {
includeInputTypes?: boolean;
}

type SelectedNodes =
| ObjectTypeDefinitionNode
| ObjectTypeExtensionNode
| InputObjectTypeDefinitionNode
| InputObjectTypeExtensionNode;

function parseDirectiveValue(value: ValueNode): any {
switch (value.kind) {
case Kind.INT:
Expand All @@ -32,11 +46,16 @@ function parseDirectiveValue(value: ValueNode): any {
}
}

export function getFieldsWithDirectives(documentNode: DocumentNode): TypeAndFieldToDirectives {
export function getFieldsWithDirectives(documentNode: DocumentNode, options: Options = {}): TypeAndFieldToDirectives {
const result: TypeAndFieldToDirectives = {};
const allTypes = documentNode.definitions.filter<ObjectTypeDefinitionNode | ObjectTypeExtensionNode>(
isObjectTypeDefinitionOrExtension
);

let selected = ['ObjectTypeDefinition', 'ObjectTypeExtension'];

if (options.includeInputTypes) {
selected = [...selected, 'InputObjectTypeDefinition', 'InputObjectTypeExtension'];
}

const allTypes = documentNode.definitions.filter(obj => selected.includes(obj.kind)) as SelectedNodes[];

for (const type of allTypes) {
const typeName = type.name.value;
Expand Down
32 changes: 32 additions & 0 deletions packages/utils/tests/get-fields-with-directives.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,36 @@ describe('getFieldsWithDirectives', () => {
const result = getFieldsWithDirectives(node);
expect(Object.keys(result).length).toBe(2);
});

it('Should detect multiple input types', () => {
const node = parse(`
input A {
f1: String @a
}
input B {
f2: String @a
}
`);

const result = getFieldsWithDirectives(node, {includeInputTypes: true});
expect(result['A.f1']).toEqual([{ name: 'a', args: {} }]);
expect(result['B.f2']).toEqual([{ name: 'a', args: {} }]);
});

it('Should detect multiple extend input types', () => {
const node = parse(`
extend input A {
f1: String @a
}
extend input B {
f2: String @a
}
`);

const result = getFieldsWithDirectives(node, {includeInputTypes: true});
expect(result['A.f1']).toEqual([{ name: 'a', args: {} }]);
expect(result['B.f2']).toEqual([{ name: 'a', args: {} }]);
});
});

0 comments on commit a3ba3e3

Please sign in to comment.