Skip to content

Commit 5fa9964

Browse files
committed
feat: add option to specify paginationResolverName
Closes #6
1 parent fc429ac commit 5fa9964

File tree

6 files changed

+84
-9
lines changed

6 files changed

+84
-9
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ import composeWithPagination from 'graphql-compose-pagination';
2929
import userTypeComposer from './user.js';
3030

3131
composeWithPagination(userTypeComposer, {
32+
paginationResolverName: 'pagination', // Default
3233
findResolverName: 'findMany',
3334
countResolverName: 'count',
35+
perPage: 20, // Default
3436
});
3537
```
3638

src/__tests__/composeWithPagination-test.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,50 @@ describe('composeWithRelay', () => {
4848
expect(myTC.getResolver('pagination')).toBeTruthy();
4949
expect(myTC.getResolver('pagination').resolve()).toBe('mockData');
5050
});
51+
52+
it('should add resolver with user-specified name', () => {
53+
let myTC = TypeComposer.create('type CustomComplex { a: String, b: Int }');
54+
myTC.addResolver({
55+
name: 'count',
56+
resolve: () => 1,
57+
});
58+
myTC.addResolver({
59+
name: 'findMany',
60+
resolve: () => ['mockData'],
61+
});
62+
myTC = composeWithPagination(myTC, {
63+
paginationResolverName: 'customPagination',
64+
countResolverName: 'count',
65+
findResolverName: 'findMany',
66+
});
67+
68+
expect(myTC.getResolver('customPagination')).toBeTruthy();
69+
expect(myTC.hasResolver('pagination')).toBeFalsy();
70+
});
71+
72+
it('should add two connection resolvers', () => {
73+
let myTC = TypeComposer.create('type CustomComplex { a: String, b: Int }');
74+
myTC.addResolver({
75+
name: 'count',
76+
resolve: () => 1,
77+
});
78+
myTC.addResolver({
79+
name: 'findMany',
80+
resolve: () => ['mockData'],
81+
});
82+
myTC = composeWithPagination(myTC, {
83+
countResolverName: 'count',
84+
findResolverName: 'findMany',
85+
});
86+
myTC = composeWithPagination(myTC, {
87+
paginationResolverName: 'customPagination',
88+
countResolverName: 'count',
89+
findResolverName: 'findMany',
90+
});
91+
92+
expect(myTC.hasResolver('pagination')).toBeTruthy();
93+
expect(myTC.getResolver('customPagination')).toBeTruthy();
94+
});
5195
});
5296

5397
describe('check `pagination` resolver props', () => {

src/composeWithPagination.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
/* @flow */
22

33
import { TypeComposer } from 'graphql-compose';
4-
import { preparePaginationResolver, type ComposeWithPaginationOpts } from './paginationResolver';
4+
import {
5+
preparePaginationResolver,
6+
type ComposeWithPaginationOpts,
7+
DEFAULT_RESOLVER_NAME,
8+
} from './paginationResolver';
59

610
export function composeWithPagination(
711
typeComposer: TypeComposer,
@@ -15,12 +19,14 @@ export function composeWithPagination(
1519
throw new Error('You should provide non-empty options to composeWithPagination');
1620
}
1721

18-
if (typeComposer.hasResolver('pagination')) {
22+
const resolverName = opts.paginationResolverName || DEFAULT_RESOLVER_NAME;
23+
24+
if (typeComposer.hasResolver(resolverName)) {
1925
return typeComposer;
2026
}
2127

2228
const resolver = preparePaginationResolver(typeComposer, opts);
2329

24-
typeComposer.setResolver('pagination', resolver);
30+
typeComposer.setResolver(resolverName, resolver);
2531
return typeComposer;
2632
}

src/paginationResolver.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ import type {
1010
import type { GraphQLResolveInfo } from 'graphql-compose/lib/graphql';
1111
import { preparePaginationTC } from './types/preparePaginationType';
1212

13-
const DEFAULT_PER_PAGE = 20;
13+
export const DEFAULT_RESOLVER_NAME = 'pagination';
14+
export const DEFAULT_PER_PAGE = 20;
1415

1516
export type ComposeWithPaginationOpts = {
17+
paginationResolverName?: string,
1618
findResolverName: string,
1719
countResolverName: string,
1820
perPage?: number,
@@ -56,6 +58,8 @@ export function preparePaginationResolver(
5658
throw new Error('First arg for prepareConnectionResolver() should be instance of TypeComposer');
5759
}
5860

61+
const resolverName = opts.paginationResolverName || DEFAULT_RESOLVER_NAME;
62+
5963
if (!opts.countResolverName) {
6064
throw new Error(
6165
`TypeComposer(${tc.getTypeName()}) provided to composeWithConnection ` +
@@ -103,8 +107,8 @@ export function preparePaginationResolver(
103107
}
104108

105109
return new tc.constructor.schemaComposer.Resolver({
106-
type: preparePaginationTC(tc),
107-
name: 'pagination',
110+
type: preparePaginationTC(tc, resolverName),
111+
name: resolverName,
108112
kind: 'query',
109113
args: {
110114
page: {

src/types/__tests__/preparePaginationType-test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,28 @@ describe('preparePaginationTC()', () => {
1010
expect(preparePaginationTC(UserTC)).toBeInstanceOf(TypeComposer);
1111
});
1212

13+
it('should return the same Type object when called again', () => {
14+
const firstPaginationType = preparePaginationTC(UserTC);
15+
const secondPaginationType = preparePaginationTC(UserTC);
16+
expect(firstPaginationType).toBe(secondPaginationType);
17+
});
18+
19+
it('should return a separate GraphQLObjectType with a different name', () => {
20+
const paginationType = preparePaginationTC(UserTC);
21+
const otherPaginationType = preparePaginationTC(UserTC, 'otherPagination');
22+
expect(paginationType).not.toBe(otherPaginationType);
23+
});
24+
1325
it('should have name ending with `Pagination`', () => {
1426
expect(preparePaginationTC(UserTC).getTypeName()).toBe('UserPagination');
1527
});
1628

29+
it('should have name ending with `OtherPagination` when passed lowercase otherPagination', () => {
30+
expect(preparePaginationTC(UserTC, 'otherConnection').getTypeName()).toBe(
31+
'UserOtherConnection'
32+
);
33+
});
34+
1735
it('should have field `count` with provided Type', () => {
1836
const tc = preparePaginationTC(UserTC);
1937
expect(tc.getFieldType('count')).toBe(GraphQLInt);

src/types/preparePaginationType.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* @flow */
22
/* eslint-disable arrow-body-style */
33

4-
import type { TypeComposer, SchemaComposer } from 'graphql-compose';
4+
import { upperFirst, type TypeComposer, type SchemaComposer } from 'graphql-compose';
55

66
export function preparePaginationInfoTC(schemaComposer: SchemaComposer<any>): TypeComposer {
77
return schemaComposer.getOrCreateTC('PaginationInfo', tc => {
@@ -35,9 +35,10 @@ export function preparePaginationInfoTC(schemaComposer: SchemaComposer<any>): Ty
3535
});
3636
}
3737

38-
export function preparePaginationTC(tc: TypeComposer): TypeComposer {
38+
export function preparePaginationTC(tc: TypeComposer, resolverName: ?string): TypeComposer {
3939
const schemaComposer = tc.constructor.schemaComposer;
40-
const name = `${tc.getTypeName()}Pagination`;
40+
41+
const name = `${tc.getTypeName()}${upperFirst(resolverName || 'pagination')}`;
4142
const type = tc.getType();
4243

4344
if (schemaComposer.has(name)) {

0 commit comments

Comments
 (0)