Skip to content

Commit

Permalink
refactor: get rid of TC.getResolver() method
Browse files Browse the repository at this point in the history
BREAKING CHANGE: change config options. Get rid of `TC.getResolver()` method. Now you need to pass Resolver instance explicitly.
  • Loading branch information
nodkz committed Sep 14, 2020
1 parent 420d712 commit 8aae208
Show file tree
Hide file tree
Showing 12 changed files with 386 additions and 364 deletions.
21 changes: 8 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,20 @@ Modules `graphql` and `graphql-compose` are in `peerDependencies`, so should be
## Example

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

composeWithPagination(userTypeComposer, {
paginationResolverName: 'pagination', // Default
findResolverName: 'findMany',
countResolverName: 'count',
const paginationResolver = preparePaginationResolver(UserTC, {
findManyResolver,
countResolver,
name: 'pagination', // Default
perPage: 20, // Default
});
```

<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">

## Requirements
Implementation of `findManyResolver` and `countResolver` can be found in [this file](./src/__mocks__/User.ts).

Types should have following resolvers:

- `count` - for records count
- `findMany` - for filtering records. Resolver `findMany` should have `limit` and `skip` args.
<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">

## Used in plugins

Expand Down
20 changes: 10 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,26 @@
},
"homepage": "https://github.com/graphql-compose/graphql-compose-pagination",
"peerDependencies": {
"graphql-compose": "^7.0.4"
"graphql-compose": "^7.15.0"
},
"devDependencies": {
"@types/graphql": "14.5.0",
"@types/jest": "26.0.10",
"@typescript-eslint/eslint-plugin": "3.9.1",
"@typescript-eslint/parser": "3.9.1",
"eslint": "7.7.0",
"@types/jest": "26.0.13",
"@typescript-eslint/eslint-plugin": "4.1.0",
"@typescript-eslint/parser": "4.1.0",
"eslint": "7.9.0",
"eslint-config-airbnb-base": "14.2.0",
"eslint-config-prettier": "6.11.0",
"eslint-plugin-import": "2.22.0",
"eslint-plugin-prettier": "3.1.4",
"graphql": "15.3.0",
"graphql-compose": "7.19.4",
"jest": "26.4.0",
"prettier": "2.0.5",
"graphql-compose": "7.21.1",
"jest": "26.4.2",
"prettier": "2.1.1",
"rimraf": "3.0.2",
"semantic-release": "17.1.1",
"ts-jest": "26.2.0",
"typescript": "3.9.7"
"ts-jest": "26.3.0",
"typescript": "4.0.2"
},
"scripts": {
"build": "rimraf lib && tsc -p ./tsconfig.build.json",
Expand Down
4 changes: 1 addition & 3 deletions src/__mocks__/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ function prepareFilterFromArgs(resolveParams = {} as ResolverResolveParams<any,
return filter;
}

export const findManyResolver = schemaComposer.createResolver({
export const findManyResolver = schemaComposer.createResolver<any, any>({
name: 'findMany',
kind: 'query',
type: UserTC,
Expand Down Expand Up @@ -130,7 +130,6 @@ export const findManyResolver = schemaComposer.createResolver({
return Promise.resolve(list);
},
});
UserTC.setResolver('findMany', findManyResolver);

export const countResolver = schemaComposer.createResolver({
name: 'count',
Expand All @@ -143,4 +142,3 @@ export const countResolver = schemaComposer.createResolver({
return Promise.resolve(filteredUserList(userList, prepareFilterFromArgs(resolveParams)).length);
},
});
UserTC.setResolver('count', countResolver);
38 changes: 19 additions & 19 deletions src/__tests__/composeWithPagination-test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { ObjectTypeComposer, schemaComposer } from 'graphql-compose';
import { GraphQLList, graphql } from 'graphql-compose/lib/graphql';
import { composeWithPagination } from '../composeWithPagination';
import { UserTC } from '../__mocks__/User';
import { UserTC, countResolver, findManyResolver } from '../__mocks__/User';

describe('composeWithRelay', () => {
describe('composeWithPagination', () => {
const userComposer = composeWithPagination(UserTC, {
countResolverName: 'count',
findResolverName: 'findMany',
countResolver,
findManyResolver,
perPage: 5,
});

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

it('should not change `pagination` resolver if exists', () => {
it('should not change `pagination` resolver if it already exists', () => {
let myTC = schemaComposer.createObjectTC('type Complex { a: String, b: Int }');
myTC.addResolver({
name: 'pagination',
resolve: () => 'mockData',
});

// try ovewrite `pagination` resolver
// try overwrite `pagination` resolver
myTC = composeWithPagination(myTC, {
countResolverName: 'count',
findResolverName: 'findMany',
countResolver,
findManyResolver,
});

expect(myTC.getResolver('pagination')).toBeTruthy();
Expand All @@ -60,33 +60,33 @@ describe('composeWithRelay', () => {
resolve: () => ['mockData'],
});
myTC = composeWithPagination(myTC, {
paginationResolverName: 'customPagination',
countResolverName: 'count',
findResolverName: 'findMany',
name: 'customPagination',
countResolver,
findManyResolver,
});

expect(myTC.getResolver('customPagination')).toBeTruthy();
expect(myTC.hasResolver('pagination')).toBeFalsy();
});

it('should add two connection resolvers', () => {
it('should return different resolvers', () => {
let myTC = schemaComposer.createObjectTC('type CustomComplex { a: String, b: Int }');
myTC.addResolver({
const myCountResolver = schemaComposer.createResolver({
name: 'count',
resolve: () => 1,
});
myTC.addResolver({
const myFindManyResolver = schemaComposer.createResolver({
name: 'findMany',
resolve: () => ['mockData'],
});
myTC = composeWithPagination(myTC, {
countResolverName: 'count',
findResolverName: 'findMany',
countResolver: myCountResolver,
findManyResolver: myFindManyResolver,
});
myTC = composeWithPagination(myTC, {
paginationResolverName: 'customPagination',
countResolverName: 'count',
findResolverName: 'findMany',
name: 'customPagination',
countResolver: myCountResolver,
findManyResolver: myFindManyResolver,
});

expect(myTC.hasResolver('pagination')).toBeTruthy();
Expand Down
18 changes: 9 additions & 9 deletions src/__tests__/mocks-userTypeComposer-test.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { UserTC } from '../__mocks__/User';
import { countResolver, findManyResolver } from '../__mocks__/User';

describe('mocks/UserTC', () => {
it('UserTC should have `count` resolver', async () => {
const cnt = await UserTC.getResolver('count').resolve({});
it('UserTC should have `countResolver`', async () => {
const cnt = await countResolver.resolve({});
expect(cnt).toBe(15);
});

it('UserTC should have `findMany` resolver', async () => {
const res = await UserTC.getResolver('findMany').resolve({});
it('UserTC should have `findManyResolver`', async () => {
const res = await findManyResolver.resolve({});
expect(res).toHaveLength(15);
});

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

it('UserTC should have `findMany` resolver with working `sort` arg', async () => {
const res = await UserTC.getResolver('findMany').resolve({
it('UserTC should have `findManyResolver` with working `sort` arg', async () => {
const res = await findManyResolver.resolve({
args: {
sort: {
age: -1,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Resolver, ResolverResolveParams } from 'graphql-compose';
import { GraphQLInt } from 'graphql-compose/lib/graphql';
import { UserTC } from '../__mocks__/User';
import { preparePaginationResolver } from '../paginationResolver';
import { UserTC, countResolver, findManyResolver } from '../__mocks__/User';
import { preparePaginationResolver } from '../pagination';

describe('paginationResolver', () => {
const spyFindManyResolve = jest.spyOn(UserTC.getResolver('findMany'), 'resolve');
const spyCountResolve = jest.spyOn(UserTC.getResolver('count'), 'resolve');
describe('preparePaginationResolver()', () => {
const spyFindManyResolve = jest.spyOn(findManyResolver, 'resolve');
const spyCountResolve = jest.spyOn(countResolver, 'resolve');
const paginationResolver = preparePaginationResolver(UserTC, {
countResolverName: 'count',
findResolverName: 'findMany',
countResolver,
findManyResolver,
perPage: 5,
});

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

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

it('should throw error if resolver opts.countResolverName does not exists', () => {
expect(() =>
preparePaginationResolver(UserTC, {
countResolverName: 'countDoesNotExists',
findResolverName: 'findMany',
// @ts-expect-error
countResolver: 'countDoesNotExists',
findManyResolver,
})
).toThrowError("does not have resolver with name 'countDoesNotExists'");
).toThrowError("'opts.countResolver' must be a Resolver instance");
});

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

it('should throw error if resolver opts.countResolverName does not exists', () => {
expect(() =>
preparePaginationResolver(UserTC, {
countResolverName: 'count',
findResolverName: 'findManyDoesNotExists',
countResolver,
// @ts-expect-error
findManyResolver: 'findManyDoesNotExists',
})
).toThrowError("does not have resolver with name 'findManyDoesNotExists'");
).toThrowError("'opts.findManyResolver' must be a Resolver instance");
});
});

Expand Down Expand Up @@ -93,23 +91,19 @@ describe('paginationResolver', () => {
beforeEach(() => {
findManyResolverCalled = false;
countResolverCalled = false;
const mockedFindMany = UserTC.getResolver('findMany').wrapResolve(
(next) => (resolveParams) => {
findManyResolverCalled = true;
spyResolveParams = resolveParams;
return next(resolveParams);
}
);
const mockedCount = UserTC.getResolver('findMany').wrapResolve((next) => (resolveParams) => {
const mockedFindMany = findManyResolver.wrapResolve((next) => (resolveParams) => {
findManyResolverCalled = true;
spyResolveParams = resolveParams;
return next(resolveParams);
});
const mockedCount = countResolver.wrapResolve((next) => (resolveParams) => {
countResolverCalled = true;
spyResolveParams = resolveParams;
return next(resolveParams);
});
UserTC.setResolver('mockedFindMany', mockedFindMany);
UserTC.setResolver('mockedCount', mockedCount);
mockedPaginationResolver = preparePaginationResolver(UserTC, {
countResolverName: 'mockedCount',
findResolverName: 'mockedFindMany',
countResolver: mockedCount,
findManyResolver: mockedFindMany,
});
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ObjectTypeComposer } from 'graphql-compose';
import { GraphQLNonNull, getNamedType, GraphQLInt, GraphQLList } from 'graphql-compose/lib/graphql';
import { UserTC } from '../__mocks__/User';
import { preparePaginationTC, preparePaginationInfoTC } from '../preparePaginationType';
import { preparePaginationTC, preparePaginationInfoTC } from '../types';

describe('preparePaginationTC()', () => {
it('should return ObjectTypeComposer', () => {
Expand Down
8 changes: 3 additions & 5 deletions src/composeWithPagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
preparePaginationResolver,
ComposeWithPaginationOpts,
DEFAULT_RESOLVER_NAME,
} from './paginationResolver';
} from './pagination';

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

const resolverName = opts.paginationResolverName || DEFAULT_RESOLVER_NAME;

const resolverName = opts.name || DEFAULT_RESOLVER_NAME;
if (typeComposer.hasResolver(resolverName)) {
return typeComposer;
}

const resolver = preparePaginationResolver(typeComposer, opts);

typeComposer.setResolver(resolverName, resolver);

return typeComposer;
}
8 changes: 3 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { preparePaginationResolver } from './pagination';
import { composeWithPagination } from './composeWithPagination';
import { preparePaginationResolver } from './paginationResolver';

export default composeWithPagination;

export { composeWithPagination, preparePaginationResolver };

export type {
ComposeWithPaginationOpts,
PaginationResolveParams,
PaginationTArgs,
PaginationType,
PaginationInfoType,
} from './paginationResolver';
} from './pagination';
Loading

0 comments on commit 8aae208

Please sign in to comment.