diff --git a/CHANGELOG.md b/CHANGELOG.md index b608ab9..4c2a7d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ and this project adheres to ## [Unreleased] +## [v1.3.1] - 2024-02-08 + +### Fixed + +- fix: support variables nested in query when making private queries + ## [v1.3.0] - 2024-02-02 ### Added diff --git a/package.json b/package.json index b1f1f4d..4a0ed9a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@wayfair/gqmock", - "version": "1.3.0", + "version": "1.3.1", "description": "GQMock - GraphQL Mocking Service", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/ApolloServerManager.ts b/src/ApolloServerManager.ts index ebcf69e..e094f8c 100644 --- a/src/ApolloServerManager.ts +++ b/src/ApolloServerManager.ts @@ -197,11 +197,13 @@ export default class ApolloServerManager { async getNewMock({ query, + variables, typeName, operationName, rollingKey, }: { query: string; + variables: Record; typeName: string; operationName: string; rollingKey: string; @@ -213,9 +215,10 @@ export default class ApolloServerManager { rollingKey, apolloServerManager: this, }); + const queryResult = await this.executeOperation({ query: newQuery, - variables: {}, + variables, operationName: this.getFieldName('privateQuery'), }); diff --git a/src/seed/SeedManager.ts b/src/seed/SeedManager.ts index e8c8f1a..3f29c42 100644 --- a/src/seed/SeedManager.ts +++ b/src/seed/SeedManager.ts @@ -238,6 +238,7 @@ export default class SeedManager { { apolloServerManager, query, + variables, operationName, } ); diff --git a/src/utilities/__tests__/buildPrivateTypeQuery.ts b/src/utilities/__tests__/buildPrivateTypeQuery.ts index 80ec87b..ee9243f 100644 --- a/src/utilities/__tests__/buildPrivateTypeQuery.ts +++ b/src/utilities/__tests__/buildPrivateTypeQuery.ts @@ -174,8 +174,8 @@ describe('buildPrivateTypeQuery', function () { it('should build a query for the correct nested inline fragment', () => { const rollingKey = 'data.item.subItem1'; - const query = `query itemQuery { - item { + const query = `query itemQuery($first: Int!, $second: String!) { + item(first: $first) { __typename id ... on ItemOne { @@ -183,8 +183,11 @@ describe('buildPrivateTypeQuery', function () { subItem1 { __typename id + fieldWithVariable(first: $first) ... on SubItemOne { field1 + anotherWithSameVariable(first: $first) + anotherWithDifferentVariable(second: $second) } ... on SubItemTwo { field2 @@ -209,11 +212,14 @@ describe('buildPrivateTypeQuery', function () { } }`; - const expectedQuery = `query gqmock_privateQuery { + const expectedQuery = `query gqmock_privateQuery($first: Int!, $second: String!) { gqmock_SubItemOne { __typename id + fieldWithVariable(first: $first) field1 + anotherWithSameVariable(first: $first) + anotherWithDifferentVariable(second: $second) } __typename }`; diff --git a/src/utilities/buildPrivateTypeQuery.ts b/src/utilities/buildPrivateTypeQuery.ts index 78cc3d9..02de33d 100644 --- a/src/utilities/buildPrivateTypeQuery.ts +++ b/src/utilities/buildPrivateTypeQuery.ts @@ -6,8 +6,10 @@ import { InlineFragmentNode, Kind, OperationDefinitionNode, + VariableDefinitionNode, parse, print, + visit, } from 'graphql'; import ApolloServerManager from '../ApolloServerManager'; @@ -57,6 +59,7 @@ export default function ({ apolloServerManager.schema as GraphQLSchema, typeName ); + const queryAst = parse(query); let node: ASTNode = queryAst.definitions.find((definition) => { return ( @@ -207,10 +210,38 @@ export default function ({ }, ], }, + variableDefinitions: [] as VariableDefinitionNode[], }, ], }; + const allVariableDefinitions: VariableDefinitionNode[] = []; + visit(queryAst, { + VariableDefinition(node) { + allVariableDefinitions.push(node); + }, + }); + + const variableDefinitions: VariableDefinitionNode[] = []; + // @ts-ignore meh + visit(newQueryAst, { + Variable(node) { + const matchingVariable = allVariableDefinitions.find( + (definition) => definition.variable.name.value === node.name.value + ); + if (matchingVariable) { + const addedToDefinitions = variableDefinitions.find( + (definition) => definition.variable.name.value === node.name.value + ); + if (!addedToDefinitions) { + variableDefinitions.push(matchingVariable); + } + } + }, + }); + + newQueryAst.definitions[0].variableDefinitions = variableDefinitions; + return apolloServerManager.addTypenameFieldsToQuery( print(newQueryAst as ASTNode) ); diff --git a/src/utilities/deepMerge.ts b/src/utilities/deepMerge.ts index 7330325..96c2310 100644 --- a/src/utilities/deepMerge.ts +++ b/src/utilities/deepMerge.ts @@ -48,6 +48,7 @@ function buildShorthandOverridesMap(object, metaPropertyPrefix) { * @param {string} graphqlContext.operationName - GraphQL operation name * @param {ApolloServerManager} graphqlContext.apolloServerManager - ApolloServerManager instance * @param {object} options - Merge options + * @param graphqlContext.variables * @returns {object} A merged object and a list of warnings */ async function deepMerge( @@ -55,6 +56,7 @@ async function deepMerge( seed: Record, graphqlContext: { query: string; + variables: Record; operationName: string; apolloServerManager: ApolloServerManager; }, @@ -63,7 +65,7 @@ async function deepMerge( data: Record; warnings: string[]; }> { - const {query, operationName, apolloServerManager} = graphqlContext; + const {query, operationName, apolloServerManager, variables} = graphqlContext; const warnings = new Set(); /** * Returns the result of merging target into source @@ -87,6 +89,7 @@ async function deepMerge( ) { source = await apolloServerManager.getNewMock({ query, + variables, typeName: target.__typename, operationName, rollingKey, @@ -107,6 +110,7 @@ async function deepMerge( // this should happen regardless of overrides const newSourceItemData = await apolloServerManager.getNewMock({ query, + variables, typeName: sourceItem.__typename, operationName, rollingKey: newRollingKey, @@ -145,6 +149,7 @@ async function deepMerge( // this should happen regardless of overrides const newSourceItemData = await apolloServerManager.getNewMock({ query, + variables, typeName: sourceItem.__typename, operationName, rollingKey: newRollingKey,