Skip to content

Commit

Permalink
Respect other arguments while creating underlying pagination selectio…
Browse files Browse the repository at this point in the history
…ns and use serial queries if skip limit exceeds (#76)
  • Loading branch information
ardatan authored May 11, 2022
1 parent 3b6344e commit 9d71ded
Show file tree
Hide file tree
Showing 9 changed files with 371 additions and 85 deletions.
5 changes: 5 additions & 0 deletions .changeset/eleven-pianos-glow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphprotocol/client-auto-pagination': patch
---

Respect other arguments while creating underlying pagination selections
5 changes: 5 additions & 0 deletions .changeset/smooth-rice-turn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphprotocol/client-auto-pagination': patch
---

Use lastID if skip exceeds the limit
67 changes: 67 additions & 0 deletions .github/workflows/canary.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Canary Release

on:
pull_request:
paths:
- '.changeset/**/*.md'

jobs:
publish-canary:
name: Publish Canary
runs-on: ubuntu-latest
if: github.event.pull_request.head.repo.full_name == github.repository
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Use Node
uses: actions/setup-node@v3
with:
node-version: 18
cache: 'yarn'

- name: Install Dependencies using Yarn
run: yarn

- name: Setup NPM credentials
run: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Release Canary
id: canary
uses: 'kamilkisiela/release-canary@master'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
with:
npm-token: ${{ secrets.NPM_TOKEN }}
npm-script: 'yarn release:canary'
changesets: true

- name: Publish a message
if: steps.canary.outputs.released == 'true'
uses: 'kamilkisiela/pr-comment@master'
with:
commentKey: canary
message: |
The latest changes of this PR are available as canary in npm (based on the declared `changesets`):
```
${{ steps.canary.outputs.changesetsPublishedPackages}}
```
bot-token: ${{ secrets.GITHUB_TOKEN }}
bot: 'github-actions[bot]'
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Publish a empty message
if: steps.canary.outputs.released == 'false'
uses: 'kamilkisiela/pr-comment@master'
with:
commentKey: canary
message: |
The latest changes of this PR are not available as canary, since there are no linked `changesets` for this PR.
bot-token: ${{ secrets.GITHUB_TOKEN }}
bot: 'github-actions[bot]'
github-token: ${{ secrets.GITHUB_TOKEN }}
7 changes: 5 additions & 2 deletions examples/transforms/.graphclientrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ sources:
endpoint: https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v2
transforms:
# Enable Automatic Block Tracking
- autoPagination:
validateSchema: true
- blockTracking:
validateSchema: true
- autoPagination:
validateSchema: true

serve:
browser: false
85 changes: 62 additions & 23 deletions packages/auto-pagination/__tests__/auto-pagination.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { execute, ExecutionResult, parse } from 'graphql'
import AutoPaginationTransform from '../src'

describe('Auto Pagination', () => {
const users = new Array(20).fill({}).map((_, i) => ({ id: (i + 1).toString(), name: `User ${i + 1}` }))
const LIMIT = 3
const users = new Array(20000).fill({}).map((_, i) => ({ id: (i + 1).toString(), name: `User ${i + 1}` }))
const usersOdd = users.filter((_, i) => i % 2 === 1)
const schema = makeExecutableSchema({
typeDefs: /* GraphQL */ `
type Query {
_meta: Meta
users(first: Int = ${LIMIT}, skip: Int = 0): [User!]!
users(first: Int = ${1000}, skip: Int = 0, odd: Boolean, where: WhereInput): [User!]!
}
type User {
id: ID!
Expand All @@ -22,14 +22,27 @@ describe('Auto Pagination', () => {
type Block {
number: Int
}
input WhereInput {
id_gte: ID
}
`,
resolvers: {
Query: {
users: (_, { first = LIMIT, skip = 0 }) => {
if (first > LIMIT) {
throw new Error(`You cannot request more than ${LIMIT} users; you requested ${first}`)
users: (_, { first = 1000, skip = 0, odd, where }) => {
if (first > 1000) {
throw new Error(`You cannot request more than 1000 users; you requested ${first}`)
}
if (skip > 5000) {
throw new Error(`You cannot skip more than 5000 users; you requested ${skip}`)
}
let usersSlice = users
if (odd) {
usersSlice = usersOdd
}
if (where?.id_gte) {
usersSlice = users.slice(where.id_gte)
}
return users.slice(skip, skip + first)
return usersSlice.slice(skip, skip + first)
},
_meta: () => ({
block: {
Expand All @@ -41,18 +54,12 @@ describe('Auto Pagination', () => {
})
const wrappedSchema = wrapSchema({
schema,
transforms: [
new AutoPaginationTransform({
config: {
limitOfRecords: LIMIT,
},
}),
],
transforms: [new AutoPaginationTransform()],
})
it('should give correct numbers of results if first arg are higher than given limit', async () => {
const query = /* GraphQL */ `
query {
users(first: 10) {
users(first: 2000) {
id
name
}
Expand All @@ -62,13 +69,13 @@ describe('Auto Pagination', () => {
schema: wrappedSchema,
document: parse(query),
})
expect(result.data?.users).toHaveLength(10)
expect(result.data?.users).toEqual(users.slice(0, 10))
expect(result.data?.users).toHaveLength(2000)
expect(result.data?.users).toEqual(users.slice(0, 2000))
})
it('should respect skip argument', async () => {
const query = /* GraphQL */ `
query {
users(first: 10, skip: 1) {
users(first: 2000, skip: 1) {
id
name
}
Expand All @@ -78,8 +85,8 @@ describe('Auto Pagination', () => {
schema: wrappedSchema,
document: parse(query),
})
expect(result.data?.users).toHaveLength(10)
expect(result.data?.users).toEqual(users.slice(1, 11))
expect(result.data?.users).toHaveLength(2000)
expect(result.data?.users).toEqual(users.slice(1, 2001))
})
it('should work with the values under the limit', async () => {
const query = /* GraphQL */ `
Expand All @@ -105,7 +112,7 @@ describe('Auto Pagination', () => {
number
}
}
users(first: 10) {
users(first: 2000) {
id
name
}
Expand All @@ -116,7 +123,39 @@ describe('Auto Pagination', () => {
document: parse(query),
})
expect(result.data?._meta?.block?.number).toBeDefined()
expect(result.data?.users).toHaveLength(10)
expect(result.data?.users).toEqual(users.slice(0, 10))
expect(result.data?.users).toHaveLength(2000)
expect(result.data?.users).toEqual(users.slice(0, 2000))
})
it('should respect other arguments', async () => {
const query = /* GraphQL */ `
query {
users(first: 2000, odd: true) {
id
name
}
}
`
const result: ExecutionResult<any> = await execute({
schema: wrappedSchema,
document: parse(query),
})
expect(result.data?.users).toHaveLength(2000)
expect(result.data?.users).toEqual(usersOdd.slice(0, 2000))
})
it('should make queries serially if skip limit reaches the limit', async () => {
const query = /* GraphQL */ `
query {
users(first: 15000) {
id
name
}
}
`
const result: ExecutionResult<any> = await execute({
schema: wrappedSchema,
document: parse(query),
})
expect(result.data?.users).toHaveLength(15000)
expect(result.data?.users).toEqual(users.slice(0, 15000))
})
})
6 changes: 6 additions & 0 deletions packages/auto-pagination/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,15 @@
"access": "public"
},
"dependencies": {
"@graphql-tools/delegate": "8.7.7",
"@graphql-tools/wrap": "8.4.16",
"@graphql-tools/utils": "8.6.10",
"lodash": "4.17.21",
"tslib": "2.4.0"
},
"devDependencies": {
"@types/lodash": "4.14.182"
},
"peerDependencies": {
"graphql": "^15.2.0 || ^16.0.0",
"@graphql-mesh/types": "^0.72.0"
Expand Down
Loading

0 comments on commit 9d71ded

Please sign in to comment.