Skip to content

Commit

Permalink
fix(wrap/TransformQuery): skip fragments
Browse files Browse the repository at this point in the history
  • Loading branch information
ardatan committed Mar 13, 2024
1 parent 100ee98 commit 807491e
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 30 deletions.
5 changes: 5 additions & 0 deletions .changeset/late-cows-dress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@graphql-tools/wrap": patch
---

Skip fragments in TransformQuery
81 changes: 51 additions & 30 deletions packages/wrap/src/transforms/TransformQuery.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
import { FragmentDefinitionNode, GraphQLError, Kind, SelectionSetNode, visit } from 'graphql';
import {
DocumentNode,
FragmentDefinitionNode,
GraphQLError,
Kind,
SelectionSetNode,
visit,
} from 'graphql';
import { DelegationContext, Transform } from '@graphql-tools/delegate';
import { ExecutionRequest, ExecutionResult, relocatedError } from '@graphql-tools/utils';
import {
ExecutionRequest,
ExecutionResult,
getOperationASTFromRequest,
relocatedError,
} from '@graphql-tools/utils';

export type QueryTransformer = <TContext>(
selectionSet: SelectionSetNode | undefined,
Expand Down Expand Up @@ -55,34 +67,43 @@ export default class TransformQuery<TContext = Record<string, any>>
): ExecutionRequest {
const pathLength = this.path.length;
let index = 0;
const document = visit(originalRequest.document, {
[Kind.FIELD]: {
enter: node => {
if (index === pathLength || node.name.value !== this.path[index]) {
return false;
}

index++;

if (index === pathLength) {
const selectionSet = this.queryTransformer(
node.selectionSet,
this.fragments,
delegationContext,
transformationContext,
);

return {
...node,
selectionSet,
};
}
},
leave: () => {
index--;
},
},
});
const operationAst = getOperationASTFromRequest(originalRequest);
const document: DocumentNode = {
kind: Kind.DOCUMENT,
definitions: originalRequest.document.definitions.map(def => {
if (def === operationAst) {
return visit(def, {
[Kind.FIELD]: {
enter: node => {
if (index === pathLength || node.name.value !== this.path[index]) {
return false;
}

index++;

if (index === pathLength) {
const selectionSet = this.queryTransformer(
node.selectionSet,
this.fragments,
delegationContext,
transformationContext,
);

return {
...node,
selectionSet,
};
}
},
leave: () => {
index--;
},
},
});
}
return def;
}),
};

return {
...originalRequest,
Expand Down
104 changes: 104 additions & 0 deletions packages/wrap/tests/transformTransformQuery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,108 @@ describe('TransformQuery', () => {
expect(queryTransformerCalled).toEqual(1);
expect(result).toEqual({ data: { zipByUser: '12345' } });
});
test('skips fragments', async () => {
const subschema = makeExecutableSchema({
typeDefs: /* GraphQL */ `
type Query {
fooContainer: FooContainer
}
type FooContainer {
foo: Foo
}
type Foo {
bar: String
fooContainer: FooContainer
}
`,
resolvers: {
Query: {
fooContainer() {
const fooContainer = {
foo: {
bar: 'baz',
get fooContainer() {
return fooContainer;
},
},
};
return fooContainer;
},
},
},
});
const schema = makeExecutableSchema({
typeDefs: /* GraphQL */ `
type Query {
foo: Foo
}
type Foo {
bar: String
fooContainer: FooContainer
}
type FooContainer {
foo: Foo
}
`,
resolvers: {
Query: {
foo(_parent, _args, context, info) {
return delegateToSchema({
schema: subschema,
operation: 'query' as OperationTypeNode,
fieldName: 'fooContainer',
context,
info,
transforms: [
new TransformQuery({
path: ['fooContainer'],
queryTransformer: subTree => ({
kind: Kind.SELECTION_SET,
selections: [
{
kind: Kind.FIELD,
name: { kind: Kind.NAME, value: 'foo' },
selectionSet: subTree,
},
],
}),
resultTransformer: result => result.foo,
}),
],
});
},
},
},
});
const result = await execute({
schema,
document: parse(/* GraphQL */ `
fragment FooFragment on Foo {
bar
fooContainer {
foo {
bar
}
}
}
query {
foo {
...FooFragment
}
}
`),
});
expect(result).toEqual({
data: {
foo: {
bar: 'baz',
fooContainer: {
foo: {
bar: 'baz',
},
},
},
},
});
});
});

0 comments on commit 807491e

Please sign in to comment.