Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/composeWithMongoose.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
ObjectTypeComposer,
} from 'graphql-compose';
import { Document, Model } from 'mongoose';
import { ConnectionSortMapOpts } from './resolvers/connection';
import { ConnectionOpts } from './resolvers/connection';
import {
FilterHelperArgsOpts,
LimitHelperArgsOpts,
Expand Down Expand Up @@ -107,7 +107,7 @@ export type TypeConverterResolversOpts = {
| {
filter?: FilterHelperArgsOpts | false;
};
connection?: ConnectionSortMapOpts | false;
connection?: ConnectionOpts | false;
pagination?: PaginationResolverOpts | false;
};

Expand Down
4 changes: 2 additions & 2 deletions src/composeWithMongoose.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type {
} from './resolvers/helpers';
import MongoID from './types/mongoid';
import type { PaginationResolverOpts } from './resolvers/pagination';
import type { ConnectionSortMapOpts } from './resolvers/connection';
import type { ConnectionOpts } from './resolvers/connection';

export type ComposeWithMongooseOpts<TContext> = {|
schemaComposer?: SchemaComposer<TContext>,
Expand Down Expand Up @@ -111,7 +111,7 @@ export type TypeConverterResolversOpts = {
| {
filter?: FilterHelperArgsOpts | false,
},
connection?: ConnectionSortMapOpts | false,
connection?: ConnectionOpts<any> | false,
pagination?: PaginationResolverOpts | false,
};

Expand Down
48 changes: 39 additions & 9 deletions src/resolvers/__tests__/connection-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,26 +140,38 @@ describe('connection() resolver', () => {
await user2.save();
});

it('should return Resolver object', () => {
it('should return Resolver object with default name', () => {
const resolver = connection(UserModel, UserTC);
if (!resolver) throw new Error('Connection resolver is undefined');
expect(resolver).toBeInstanceOf(Resolver);
expect(resolver.getNestedName()).toEqual('connection');
});

it('should return Resolver object with custom name', () => {
const resolver = connection(UserModel, UserTC, {
// $FlowFixMe
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not found a solution to fix this and the error thrown by flow also does not make sense to me. Any idea or fix appreciated,

connectionResolverName: 'customConnection',
});
if (!resolver) throw new Error('Connection resolver is undefined');
expect(resolver).toBeInstanceOf(Resolver);
expect(resolver.getNestedName()).toEqual('customConnection');
});

it('Resolver object should have `filter` arg', () => {
const resolver = connection(UserModel, UserTC);
if (!resolver) throw new Error('Connection resolveris undefined');
if (!resolver) throw new Error('Connection resolver is undefined');
expect(resolver.hasArg('filter')).toBe(true);
});

it('Resolver object should have `sort` arg', () => {
const resolver = connection(UserModel, UserTC);
if (!resolver) throw new Error('Connection resolveris undefined');
if (!resolver) throw new Error('Connection resolver is undefined');
expect(resolver.hasArg('sort')).toBe(true);
});

it('Resolver object should have `connection args', () => {
const resolver = connection(UserModel, UserTC);
if (!resolver) throw new Error('Connection resolveris undefined');
if (!resolver) throw new Error('Connection resolver is undefined');
expect(resolver.hasArg('first')).toBe(true);
expect(resolver.hasArg('last')).toBe(true);
expect(resolver.hasArg('before')).toBe(true);
Expand All @@ -169,14 +181,14 @@ describe('connection() resolver', () => {
describe('Resolver.resolve():Promise', () => {
it('should be fulfilled Promise', async () => {
const resolver = connection(UserModel, UserTC);
if (!resolver) throw new Error('Connection resolveris undefined');
if (!resolver) throw new Error('Connection resolver is undefined');
const result = resolver.resolve({ args: { first: 20 } });
await expect(result).resolves.toBeDefined();
});

it('should return array of documents in `edges`', async () => {
const resolver = connection(UserModel, UserTC);
if (!resolver) throw new Error('Connection resolveris undefined');
if (!resolver) throw new Error('Connection resolver is undefined');
const result = await resolver.resolve({ args: { first: 20 } });

expect(result.edges).toBeInstanceOf(Array);
Expand All @@ -188,7 +200,7 @@ describe('connection() resolver', () => {

it('should limit records', async () => {
const resolver = connection(UserModel, UserTC);
if (!resolver) throw new Error('Connection resolveris undefined');
if (!resolver) throw new Error('Connection resolver is undefined');
const result = await resolver.resolve({ args: { first: 1 } });

expect(result.edges).toBeInstanceOf(Array);
Expand All @@ -197,7 +209,7 @@ describe('connection() resolver', () => {

it('should sort records', async () => {
const resolver = connection(UserModel, UserTC);
if (!resolver) throw new Error('Connection resolveris undefined');
if (!resolver) throw new Error('Connection resolver is undefined');

const result1 = await resolver.resolve({
args: { sort: { _id: 1 }, first: 1 },
Expand All @@ -212,7 +224,7 @@ describe('connection() resolver', () => {

it('should return mongoose documents', async () => {
const resolver = connection(UserModel, UserTC);
if (!resolver) throw new Error('Connection resolveris undefined');
if (!resolver) throw new Error('Connection resolver is undefined');

const result = await resolver.resolve({ args: { first: 20 } });
expect(result.edges[0].node).toBeInstanceOf(UserModel);
Expand Down Expand Up @@ -275,6 +287,24 @@ describe('connection() resolver', () => {

expect(result).toHaveProperty('edges.0.node', { overrides: true });
});

it('should return mongoose documents for custom resolvers from opts', async () => {
schemaComposer.clear();
UserTC = convertModelToGraphQL(UserModel, 'User', schemaComposer);
UserTC.setResolver('customFindMany', findMany(UserModel, UserTC));
UserTC.setResolver('customCount', count(UserModel, UserTC));
const resolver = connection(UserModel, UserTC, {
// $FlowFixMe
findResolverName: 'customFindMany',
// $FlowFixMe
countResolverName: 'customCount',
});
if (!resolver) throw new Error('Connection resolver is undefined');

const result = await resolver.resolve({ args: { first: 20 } });
expect(result.edges[0].node).toBeInstanceOf(UserModel);
expect(result.edges[1].node).toBeInstanceOf(UserModel);
});
});
});
});
11 changes: 8 additions & 3 deletions src/resolvers/connection.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Resolver, ObjectTypeComposer } from 'graphql-compose';
import { Resolver, ObjectTypeComposer, ObjectTypeComposerFieldConfigMap } from 'graphql-compose';
// import { ConnectionSortMapOpts } from 'graphql-compose-connection';
import { Model } from 'mongoose';
import { MongoId } from '../types/mongoid';
Expand All @@ -7,12 +7,17 @@ import { FilterHelperArgs, SortHelperArgs } from './helpers';

// @ts-todo The ConnectionSortMapOpts is not available yet since graphql-compose-connection doesn't have types for now,
// fallback to a simple object.
export type ConnectionSortMapOpts = { [opt: string]: any };
export type ConnectionOpts<TContext = any> = { [opt: string]: any } & {
connectionResolverName?: string,
findResolverName?: string;
countResolverName?: string;
edgeFields?: ObjectTypeComposerFieldConfigMap<any, TContext>;
};

export default function connection(
model: Model<any>,
tc: ObjectTypeComposer<any>,
opts?: ConnectionSortMapOpts,
opts?: ConnectionOpts<any>,
): Resolver<any, any> | undefined;

export function prepareCursorQuery(
Expand Down
31 changes: 24 additions & 7 deletions src/resolvers/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,28 @@

import type { MongooseDocument } from 'mongoose';
import type { ConnectionSortMapOpts as _ConnectionSortMapOpts } from 'graphql-compose-connection';
import type { Resolver, ObjectTypeComposer } from 'graphql-compose';
import type {
Resolver,
ObjectTypeComposer,
ObjectTypeComposerFieldConfigMap,
} from 'graphql-compose';
import {
getUniqueIndexes,
extendByReversedIndexes,
type IndexT,
} from '../utils/getIndexesFromModel';

export type ConnectionSortMapOpts = _ConnectionSortMapOpts;
export type ConnectionOpts<TContext = any> = _ConnectionSortMapOpts & {
edgeFields?: ObjectTypeComposerFieldConfigMap<any, TContext>,
connectionResolverName?: string,
findResolverName?: string,
countResolverName?: string,
};

export default function connection<TSource: MongooseDocument, TContext>(
model: Class<TSource>, // === MongooseModel
tc: ObjectTypeComposer<TSource, TContext>,
opts?: ConnectionSortMapOpts
opts?: ConnectionOpts<TContext>
): ?Resolver<TSource, TContext> {
try {
require.resolve('graphql-compose-connection');
Expand Down Expand Up @@ -56,14 +65,22 @@ export default function connection<TSource: MongooseDocument, TContext>(
},
};
});

const {
connectionResolverName = 'connection',
findResolverName = 'findMany',
countResolverName = 'count',
edgeFields,
...sortOptions
} = opts || {};
return prepareConnectionResolver(tc, {
findResolverName: 'findMany',
countResolverName: 'count',
connectionResolverName,
findResolverName,
countResolverName,
sort: {
...sortConfigs,
...opts,
...sortOptions,
},
edgeFields,
});
}

Expand Down