Skip to content

Commit

Permalink
common: prevent mergeSelectionsets from mutating its input
Browse files Browse the repository at this point in the history
  • Loading branch information
tilacog committed Sep 6, 2023
1 parent 72a742a commit 74cc907
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 3 deletions.
2 changes: 2 additions & 0 deletions packages/indexer-common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@graphprotocol/common-ts": "2.0.3",
"@graphprotocol/cost-model": "0.1.16",
"@thi.ng/heaps": "1.2.38",
"@types/lodash.clonedeep": "^4.5.7",
"@types/lodash.intersection": "^4.4.7",
"@types/lodash.xor": "^4.5.7",
"@urql/core": "2.4.4",
Expand All @@ -39,6 +40,7 @@
"graphql": "16.3.0",
"graphql-tag": "2.12.6",
"jayson": "3.6.6",
"lodash.clonedeep": "^4.5.0",
"lodash.groupby": "^4.6.0",
"lodash.intersection": "^4.4.0",
"lodash.isequal": "^4.5.0",
Expand Down
37 changes: 36 additions & 1 deletion packages/indexer-common/src/__tests__/subgraph.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DocumentNode } from 'graphql'
import { DocumentNode, print } from 'graphql'
import {
SubgraphFreshnessChecker,
LoggerInterface,
Expand All @@ -7,6 +7,8 @@ import {
} from '../subgraphs'
import { QueryResult } from '../network-subgraph'
import gql from 'graphql-tag'
import { mergeSelectionSets } from '../utils'
import { merge } from 'evt/lib/Evt.merge'

/* eslint-disable @typescript-eslint/no-explicit-any */
export const mockProvider: ProviderInterface & any = {
Expand Down Expand Up @@ -48,6 +50,39 @@ function mockQueryResult(blockNumber: number): QueryResult<any> & {
}
}
/* eslint-enable @typescript-eslint/no-explicit-any */
const blockNumberQuery = gql`
{
_meta {
block {
number
}
}
}
`

const expectedMergedQuery = gql`
query TestQuery {
foo {
id
}
_meta {
block {
number
}
}
}
`

describe('mergeSelectionSets function', () => {
it('can append the block number to an existing query', () => {
let result: DocumentNode
// Repetition required to test `mergeSelectionSets` doesn't mutate its inputq
for (let i = 0; i < 3; i++) {
result = mergeSelectionSets(testSubgraphQuery, blockNumberQuery)
}
expect(print(result!)).toEqual(print(expectedMergedQuery))
})
})

describe('SubgraphFreshnessChecker', () => {
beforeEach(jest.resetAllMocks)
Expand Down
7 changes: 5 additions & 2 deletions packages/indexer-common/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
import { Logger, Metrics, timer } from '@graphprotocol/common-ts'
import { indexerError, IndexerErrorCode } from './errors'
import { DocumentNode, SelectionSetNode, Kind } from 'graphql'
import cloneDeep from 'lodash.clonedeep'

export const parseBoolean = (
val: string | boolean | number | undefined | null,
Expand Down Expand Up @@ -68,13 +69,15 @@ export function mergeSelectionSets(
first: DocumentNode,
second: DocumentNode,
): DocumentNode {
const firstSelectionSet = extractSelectionSet(first)
// Work on a copy to avoid mutating inupt
const copy = cloneDeep(first)
const firstSelectionSet = extractSelectionSet(copy)
const secondSelectionSet = extractSelectionSet(second)
firstSelectionSet.selections = [
...firstSelectionSet.selections,
...secondSelectionSet.selections,
]
return first
return copy
}

function extractSelectionSet(document: DocumentNode): SelectionSetNode {
Expand Down

0 comments on commit 74cc907

Please sign in to comment.