From aee620d589f8832b375e45e4406867fec111f37e Mon Sep 17 00:00:00 2001 From: Sam Marks Date: Thu, 23 Jan 2020 19:31:30 -0500 Subject: [PATCH] feat: add modifyEdgeFn for edge customization --- .nvmrc | 1 + README.md | 18 +++++++++++++ src/builder/index.js | 9 +++++-- .../src/queries/cat/root/cats-connection.js | 4 +++ tests/test-app/src/type-defs/cat.js | 1 + .../knex-implementation.test.js | 26 +++++++++++++++++++ 6 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 .nvmrc diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..f599e28 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +10 diff --git a/README.md b/README.md index fd63ac2..3e1c4ce 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,24 @@ database column name is "created_at" and the column name on the model is "create ``` +#### Customizing Edges + +If you have additional metadata you would like to pass along with each edge, as is allowed by the Relay +specification, you may do so using the `modifyEdgeFn` option: + +```javascript +const result = await paginate( + baseQuery, + { first, last, before, after, orderBy, orderDirection }, + { + modifyEdgeFn: (edge) => ({ + ...edge, + custom: 'foo', + }) + } +); +``` + ### Creating your own connector Only Knex.js is implemented for now. If you want to connect to a different ORM, you must make your own connector. diff --git a/src/builder/index.js b/src/builder/index.js index 6069cc0..7d318e1 100644 --- a/src/builder/index.js +++ b/src/builder/index.js @@ -109,7 +109,9 @@ const apolloCursorPaginationBuilder = ({ }, opts = {}, ) => { - const { isAggregateFn, formatColumnFn, skipTotalCount = false } = opts; + const { + isAggregateFn, formatColumnFn, skipTotalCount = false, modifyEdgeFn, + } = opts; let { orderColumn, ascOrDesc, } = opts; @@ -146,11 +148,14 @@ const apolloCursorPaginationBuilder = ({ getNodesLength, }); - const edges = convertNodesToEdges(nodes, { + let edges = convertNodesToEdges(nodes, { before, after, first, last, }, { orderColumn, ascOrDesc, isAggregateFn, formatColumnFn, }); + if (modifyEdgeFn) { + edges = edges.map(edge => modifyEdgeFn(edge)); + } const startCursor = edges[0] && edges[0].cursor; const endCursor = edges[edges.length - 1] && edges[edges.length - 1].cursor; diff --git a/tests/test-app/src/queries/cat/root/cats-connection.js b/tests/test-app/src/queries/cat/root/cats-connection.js index 6d1c9b8..99122a9 100644 --- a/tests/test-app/src/queries/cat/root/cats-connection.js +++ b/tests/test-app/src/queries/cat/root/cats-connection.js @@ -22,6 +22,10 @@ export default async (_, args) => { { isAggregateFn: column => column === 'idsum', formatColumnFn: column => (column === 'idsum' ? Cat.knex().raw('sum(id)') : column), + modifyEdgeFn: edge => ({ + ...edge, + custom: 'foo', + }), }, ); return result; diff --git a/tests/test-app/src/type-defs/cat.js b/tests/test-app/src/type-defs/cat.js index 65b6fa8..3b8b9c9 100644 --- a/tests/test-app/src/type-defs/cat.js +++ b/tests/test-app/src/type-defs/cat.js @@ -14,6 +14,7 @@ const Cat = ` type CatEdge { cursor: String! node: Cat! + custom: String } enum OrderDirection { diff --git a/tests/test-app/tests/apollo-cursor-pagination/knex-implementation.test.js b/tests/test-app/tests/apollo-cursor-pagination/knex-implementation.test.js index f73ebae..bbb7cc1 100644 --- a/tests/test-app/tests/apollo-cursor-pagination/knex-implementation.test.js +++ b/tests/test-app/tests/apollo-cursor-pagination/knex-implementation.test.js @@ -678,4 +678,30 @@ describe('getCatsByOwner root query', () => { expect(response2.body.data.catsConnection.edges[1].node.lastName).not.toEqual(null); }); }); + + describe('modifyEdgeFn', () => { + it('modifies edges per the callback', async () => { + const query = ` + { + catsConnection(first: 2) { + edges { + cursor + node { + id + name + } + custom + } + } + } + `; + const response = await graphqlQuery(app, query); + expect(response.body.errors).not.toBeDefined(); + expect(response.body.data.catsConnection.edges).toHaveLength(2); + expect(response.body.data.catsConnection.edges.map(edge => edge.node.name)) + .toEqual([cat1.name, cat2.name]); + expect(response.body.data.catsConnection.edges.map(edge => edge.custom)) + .toEqual(['foo', 'foo']); + }); + }); });