Skip to content

Commit 8aae208

Browse files
committed
refactor: get rid of TC.getResolver() method
BREAKING CHANGE: change config options. Get rid of `TC.getResolver()` method. Now you need to pass Resolver instance explicitly.
1 parent 420d712 commit 8aae208

12 files changed

+386
-364
lines changed

README.md

+8-13
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,20 @@ Modules `graphql` and `graphql-compose` are in `peerDependencies`, so should be
2323
## Example
2424

2525
```js
26-
import composeWithPagination from 'graphql-compose-pagination';
27-
import userTypeComposer from './user.js';
26+
import { preparePaginationResolver } from 'graphql-compose-pagination';
27+
import { UserTC, findManyResolver, countResolver } from './user';
2828

29-
composeWithPagination(userTypeComposer, {
30-
paginationResolverName: 'pagination', // Default
31-
findResolverName: 'findMany',
32-
countResolverName: 'count',
29+
const paginationResolver = preparePaginationResolver(UserTC, {
30+
findManyResolver,
31+
countResolver,
32+
name: 'pagination', // Default
3333
perPage: 20, // Default
3434
});
3535
```
3636

37-
<img width="832" alt="screen shot 2017-08-07 at 23 31 46" src="https://user-images.githubusercontent.com/1946920/29038210-ad2390e4-7bc8-11e7-8143-ff0cca2b39cc.png">
38-
39-
## Requirements
37+
Implementation of `findManyResolver` and `countResolver` can be found in [this file](./src/__mocks__/User.ts).
4038

41-
Types should have following resolvers:
42-
43-
- `count` - for records count
44-
- `findMany` - for filtering records. Resolver `findMany` should have `limit` and `skip` args.
39+
<img width="832" alt="screen shot 2017-08-07 at 23 31 46" src="https://user-images.githubusercontent.com/1946920/29038210-ad2390e4-7bc8-11e7-8143-ff0cca2b39cc.png">
4540

4641
## Used in plugins
4742

package.json

+10-10
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,26 @@
2323
},
2424
"homepage": "https://github.com/graphql-compose/graphql-compose-pagination",
2525
"peerDependencies": {
26-
"graphql-compose": "^7.0.4"
26+
"graphql-compose": "^7.15.0"
2727
},
2828
"devDependencies": {
2929
"@types/graphql": "14.5.0",
30-
"@types/jest": "26.0.10",
31-
"@typescript-eslint/eslint-plugin": "3.9.1",
32-
"@typescript-eslint/parser": "3.9.1",
33-
"eslint": "7.7.0",
30+
"@types/jest": "26.0.13",
31+
"@typescript-eslint/eslint-plugin": "4.1.0",
32+
"@typescript-eslint/parser": "4.1.0",
33+
"eslint": "7.9.0",
3434
"eslint-config-airbnb-base": "14.2.0",
3535
"eslint-config-prettier": "6.11.0",
3636
"eslint-plugin-import": "2.22.0",
3737
"eslint-plugin-prettier": "3.1.4",
3838
"graphql": "15.3.0",
39-
"graphql-compose": "7.19.4",
40-
"jest": "26.4.0",
41-
"prettier": "2.0.5",
39+
"graphql-compose": "7.21.1",
40+
"jest": "26.4.2",
41+
"prettier": "2.1.1",
4242
"rimraf": "3.0.2",
4343
"semantic-release": "17.1.1",
44-
"ts-jest": "26.2.0",
45-
"typescript": "3.9.7"
44+
"ts-jest": "26.3.0",
45+
"typescript": "4.0.2"
4646
},
4747
"scripts": {
4848
"build": "rimraf lib && tsc -p ./tsconfig.build.json",

src/__mocks__/User.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ function prepareFilterFromArgs(resolveParams = {} as ResolverResolveParams<any,
9393
return filter;
9494
}
9595

96-
export const findManyResolver = schemaComposer.createResolver({
96+
export const findManyResolver = schemaComposer.createResolver<any, any>({
9797
name: 'findMany',
9898
kind: 'query',
9999
type: UserTC,
@@ -130,7 +130,6 @@ export const findManyResolver = schemaComposer.createResolver({
130130
return Promise.resolve(list);
131131
},
132132
});
133-
UserTC.setResolver('findMany', findManyResolver);
134133

135134
export const countResolver = schemaComposer.createResolver({
136135
name: 'count',
@@ -143,4 +142,3 @@ export const countResolver = schemaComposer.createResolver({
143142
return Promise.resolve(filteredUserList(userList, prepareFilterFromArgs(resolveParams)).length);
144143
},
145144
});
146-
UserTC.setResolver('count', countResolver);

src/__tests__/composeWithPagination-test.ts

+19-19
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { ObjectTypeComposer, schemaComposer } from 'graphql-compose';
22
import { GraphQLList, graphql } from 'graphql-compose/lib/graphql';
33
import { composeWithPagination } from '../composeWithPagination';
4-
import { UserTC } from '../__mocks__/User';
4+
import { UserTC, countResolver, findManyResolver } from '../__mocks__/User';
55

6-
describe('composeWithRelay', () => {
6+
describe('composeWithPagination', () => {
77
const userComposer = composeWithPagination(UserTC, {
8-
countResolverName: 'count',
9-
findResolverName: 'findMany',
8+
countResolver,
9+
findManyResolver,
1010
perPage: 5,
1111
});
1212

@@ -32,17 +32,17 @@ describe('composeWithRelay', () => {
3232
}).toThrowError('should provide non-empty options');
3333
});
3434

35-
it('should not change `pagination` resolver if exists', () => {
35+
it('should not change `pagination` resolver if it already exists', () => {
3636
let myTC = schemaComposer.createObjectTC('type Complex { a: String, b: Int }');
3737
myTC.addResolver({
3838
name: 'pagination',
3939
resolve: () => 'mockData',
4040
});
4141

42-
// try ovewrite `pagination` resolver
42+
// try overwrite `pagination` resolver
4343
myTC = composeWithPagination(myTC, {
44-
countResolverName: 'count',
45-
findResolverName: 'findMany',
44+
countResolver,
45+
findManyResolver,
4646
});
4747

4848
expect(myTC.getResolver('pagination')).toBeTruthy();
@@ -60,33 +60,33 @@ describe('composeWithRelay', () => {
6060
resolve: () => ['mockData'],
6161
});
6262
myTC = composeWithPagination(myTC, {
63-
paginationResolverName: 'customPagination',
64-
countResolverName: 'count',
65-
findResolverName: 'findMany',
63+
name: 'customPagination',
64+
countResolver,
65+
findManyResolver,
6666
});
6767

6868
expect(myTC.getResolver('customPagination')).toBeTruthy();
6969
expect(myTC.hasResolver('pagination')).toBeFalsy();
7070
});
7171

72-
it('should add two connection resolvers', () => {
72+
it('should return different resolvers', () => {
7373
let myTC = schemaComposer.createObjectTC('type CustomComplex { a: String, b: Int }');
74-
myTC.addResolver({
74+
const myCountResolver = schemaComposer.createResolver({
7575
name: 'count',
7676
resolve: () => 1,
7777
});
78-
myTC.addResolver({
78+
const myFindManyResolver = schemaComposer.createResolver({
7979
name: 'findMany',
8080
resolve: () => ['mockData'],
8181
});
8282
myTC = composeWithPagination(myTC, {
83-
countResolverName: 'count',
84-
findResolverName: 'findMany',
83+
countResolver: myCountResolver,
84+
findManyResolver: myFindManyResolver,
8585
});
8686
myTC = composeWithPagination(myTC, {
87-
paginationResolverName: 'customPagination',
88-
countResolverName: 'count',
89-
findResolverName: 'findMany',
87+
name: 'customPagination',
88+
countResolver: myCountResolver,
89+
findManyResolver: myFindManyResolver,
9090
});
9191

9292
expect(myTC.hasResolver('pagination')).toBeTruthy();

src/__tests__/mocks-userTypeComposer-test.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
import { UserTC } from '../__mocks__/User';
1+
import { countResolver, findManyResolver } from '../__mocks__/User';
22

33
describe('mocks/UserTC', () => {
4-
it('UserTC should have `count` resolver', async () => {
5-
const cnt = await UserTC.getResolver('count').resolve({});
4+
it('UserTC should have `countResolver`', async () => {
5+
const cnt = await countResolver.resolve({});
66
expect(cnt).toBe(15);
77
});
88

9-
it('UserTC should have `findMany` resolver', async () => {
10-
const res = await UserTC.getResolver('findMany').resolve({});
9+
it('UserTC should have `findManyResolver`', async () => {
10+
const res = await findManyResolver.resolve({});
1111
expect(res).toHaveLength(15);
1212
});
1313

14-
it('UserTC should have `findMany` resolver with working `filter` arg', async () => {
15-
const res = await UserTC.getResolver('findMany').resolve({
14+
it('UserTC should have `findManyResolver` with working `filter` arg', async () => {
15+
const res = await findManyResolver.resolve({
1616
args: {
1717
filter: {
1818
gender: 'm',
@@ -32,8 +32,8 @@ describe('mocks/UserTC', () => {
3232
expect(res).toEqual([{ id: 9, name: 'user09', age: 19, gender: 'm' }]);
3333
});
3434

35-
it('UserTC should have `findMany` resolver with working `sort` arg', async () => {
36-
const res = await UserTC.getResolver('findMany').resolve({
35+
it('UserTC should have `findManyResolver` with working `sort` arg', async () => {
36+
const res = await findManyResolver.resolve({
3737
args: {
3838
sort: {
3939
age: -1,

src/__tests__/paginationResolver-test.ts src/__tests__/pagination-test.ts

+27-33
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { Resolver, ResolverResolveParams } from 'graphql-compose';
22
import { GraphQLInt } from 'graphql-compose/lib/graphql';
3-
import { UserTC } from '../__mocks__/User';
4-
import { preparePaginationResolver } from '../paginationResolver';
3+
import { UserTC, countResolver, findManyResolver } from '../__mocks__/User';
4+
import { preparePaginationResolver } from '../pagination';
55

6-
describe('paginationResolver', () => {
7-
const spyFindManyResolve = jest.spyOn(UserTC.getResolver('findMany'), 'resolve');
8-
const spyCountResolve = jest.spyOn(UserTC.getResolver('count'), 'resolve');
6+
describe('preparePaginationResolver()', () => {
7+
const spyFindManyResolve = jest.spyOn(findManyResolver, 'resolve');
8+
const spyCountResolve = jest.spyOn(countResolver, 'resolve');
99
const paginationResolver = preparePaginationResolver(UserTC, {
10-
countResolverName: 'count',
11-
findResolverName: 'findMany',
10+
countResolver,
11+
findManyResolver,
1212
perPage: 5,
1313
});
1414

@@ -25,38 +25,36 @@ describe('paginationResolver', () => {
2525
}).toThrowError('should be instance of ObjectTypeComposer');
2626
});
2727

28-
it('should throw error if opts.countResolverName are empty', () => {
28+
it('should throw error if opts.countResolverName are empty or wrong', () => {
2929
expect(() => {
3030
const wrongArgs = [UserTC, {}];
3131
// @ts-expect-error
3232
preparePaginationResolver(...wrongArgs);
33-
}).toThrowError('should have option `opts.countResolverName`');
34-
});
33+
}).toThrowError("'opts.countResolver' must be a Resolver instance");
3534

36-
it('should throw error if resolver opts.countResolverName does not exists', () => {
3735
expect(() =>
3836
preparePaginationResolver(UserTC, {
39-
countResolverName: 'countDoesNotExists',
40-
findResolverName: 'findMany',
37+
// @ts-expect-error
38+
countResolver: 'countDoesNotExists',
39+
findManyResolver,
4140
})
42-
).toThrowError("does not have resolver with name 'countDoesNotExists'");
41+
).toThrowError("'opts.countResolver' must be a Resolver instance");
4342
});
4443

45-
it('should throw error if opts.findResolverName are empty', () => {
44+
it('should throw error if opts.findManyResolver are empty or wrong', () => {
4645
expect(() => {
4746
const wrongArgs = [UserTC, { countResolverName: 'count' }];
4847
// @ts-expect-error
4948
preparePaginationResolver(...wrongArgs);
50-
}).toThrowError('should have option `opts.findResolverName`');
51-
});
49+
}).toThrowError("'opts.countResolver' must be a Resolver instance");
5250

53-
it('should throw error if resolver opts.countResolverName does not exists', () => {
5451
expect(() =>
5552
preparePaginationResolver(UserTC, {
56-
countResolverName: 'count',
57-
findResolverName: 'findManyDoesNotExists',
53+
countResolver,
54+
// @ts-expect-error
55+
findManyResolver: 'findManyDoesNotExists',
5856
})
59-
).toThrowError("does not have resolver with name 'findManyDoesNotExists'");
57+
).toThrowError("'opts.findManyResolver' must be a Resolver instance");
6058
});
6159
});
6260

@@ -93,23 +91,19 @@ describe('paginationResolver', () => {
9391
beforeEach(() => {
9492
findManyResolverCalled = false;
9593
countResolverCalled = false;
96-
const mockedFindMany = UserTC.getResolver('findMany').wrapResolve(
97-
(next) => (resolveParams) => {
98-
findManyResolverCalled = true;
99-
spyResolveParams = resolveParams;
100-
return next(resolveParams);
101-
}
102-
);
103-
const mockedCount = UserTC.getResolver('findMany').wrapResolve((next) => (resolveParams) => {
94+
const mockedFindMany = findManyResolver.wrapResolve((next) => (resolveParams) => {
95+
findManyResolverCalled = true;
96+
spyResolveParams = resolveParams;
97+
return next(resolveParams);
98+
});
99+
const mockedCount = countResolver.wrapResolve((next) => (resolveParams) => {
104100
countResolverCalled = true;
105101
spyResolveParams = resolveParams;
106102
return next(resolveParams);
107103
});
108-
UserTC.setResolver('mockedFindMany', mockedFindMany);
109-
UserTC.setResolver('mockedCount', mockedCount);
110104
mockedPaginationResolver = preparePaginationResolver(UserTC, {
111-
countResolverName: 'mockedCount',
112-
findResolverName: 'mockedFindMany',
105+
countResolver: mockedCount,
106+
findManyResolver: mockedFindMany,
113107
});
114108
});
115109

src/__tests__/preparePaginationType-test.ts src/__tests__/types-test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ObjectTypeComposer } from 'graphql-compose';
22
import { GraphQLNonNull, getNamedType, GraphQLInt, GraphQLList } from 'graphql-compose/lib/graphql';
33
import { UserTC } from '../__mocks__/User';
4-
import { preparePaginationTC, preparePaginationInfoTC } from '../preparePaginationType';
4+
import { preparePaginationTC, preparePaginationInfoTC } from '../types';
55

66
describe('preparePaginationTC()', () => {
77
it('should return ObjectTypeComposer', () => {

src/composeWithPagination.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
preparePaginationResolver,
44
ComposeWithPaginationOpts,
55
DEFAULT_RESOLVER_NAME,
6-
} from './paginationResolver';
6+
} from './pagination';
77

88
export function composeWithPagination<TSource, TContext>(
99
typeComposer: ObjectTypeComposer<TSource, TContext>,
@@ -19,14 +19,12 @@ export function composeWithPagination<TSource, TContext>(
1919
throw new Error('You should provide non-empty options to composeWithPagination');
2020
}
2121

22-
const resolverName = opts.paginationResolverName || DEFAULT_RESOLVER_NAME;
23-
22+
const resolverName = opts.name || DEFAULT_RESOLVER_NAME;
2423
if (typeComposer.hasResolver(resolverName)) {
2524
return typeComposer;
2625
}
27-
2826
const resolver = preparePaginationResolver(typeComposer, opts);
29-
3027
typeComposer.setResolver(resolverName, resolver);
28+
3129
return typeComposer;
3230
}

src/index.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1+
import { preparePaginationResolver } from './pagination';
12
import { composeWithPagination } from './composeWithPagination';
2-
import { preparePaginationResolver } from './paginationResolver';
3-
4-
export default composeWithPagination;
53

64
export { composeWithPagination, preparePaginationResolver };
75

86
export type {
97
ComposeWithPaginationOpts,
10-
PaginationResolveParams,
8+
PaginationTArgs,
119
PaginationType,
1210
PaginationInfoType,
13-
} from './paginationResolver';
11+
} from './pagination';

0 commit comments

Comments
 (0)