Skip to content

Commit b267ffb

Browse files
authored
support resolver/relay target as thunk (#568)
* support resolver/relay target as thunk * fix lint * rename targetResolver to targetMaybeThunk
1 parent b5ece31 commit b267ffb

File tree

5 files changed

+47
-43
lines changed

5 files changed

+47
-43
lines changed

src/relay.js

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import {
77
} from 'graphql-relay';
88

99
import {
10-
GraphQLList,
11-
GraphQLEnumType
10+
GraphQLList
1211
} from 'graphql';
1312

1413
import {
@@ -105,7 +104,7 @@ export function nodeType(connectionType) {
105104
export function sequelizeConnection({
106105
name,
107106
nodeType,
108-
target,
107+
target: targetMaybeThunk,
109108
orderBy: orderByEnum,
110109
before,
111110
after,
@@ -123,29 +122,22 @@ export function sequelizeConnection({
123122
edgeFields
124123
});
125124

126-
const model = target.target ? target.target : target;
127125
const SEPERATOR = '$';
128126
const PREFIX = 'arrayconnection' + SEPERATOR;
129127

130-
if (orderByEnum === undefined) {
131-
orderByEnum = new GraphQLEnumType({
132-
name: name + 'ConnectionOrder',
133-
values: {
134-
ID: {value: [model.primaryKeyAttribute, 'ASC']}
135-
}
136-
});
137-
}
138-
139128
before = before || ((options) => options);
140129
after = after || ((result) => result);
141130

142131
let $connectionArgs = {
143-
...connectionArgs,
144-
orderBy: {
145-
type: new GraphQLList(orderByEnum)
146-
}
132+
...connectionArgs
147133
};
148134

135+
if (orderByEnum) {
136+
$connectionArgs.orderBy = {
137+
type: new GraphQLList(orderByEnum)
138+
};
139+
}
140+
149141
let orderByAttribute = function (orderAttr, {source, args, context, info}) {
150142
return typeof orderAttr === 'function' ? orderAttr(source, args, context, info) : orderAttr;
151143
};
@@ -166,7 +158,7 @@ export function sequelizeConnection({
166158
* @return {String} The Base64 encoded cursor string
167159
*/
168160
let toCursor = function (item, index) {
169-
let id = item.get(model.primaryKeyAttribute);
161+
let id = item.get(item.Model.primaryKeyAttribute);
170162
return base64(PREFIX + id + SEPERATOR + index);
171163
};
172164

@@ -189,6 +181,8 @@ export function sequelizeConnection({
189181
let argsToWhere = function (args) {
190182
let result = {};
191183

184+
if (where === undefined) return result;
185+
192186
_.each(args, (value, key) => {
193187
if (key in $connectionArgs) return;
194188
_.assign(result, where(key, value, result));
@@ -213,16 +207,21 @@ export function sequelizeConnection({
213207
};
214208
};
215209

216-
let $resolver = require('./resolver')(target, {
210+
let $resolver = require('./resolver')(targetMaybeThunk, {
217211
handleConnection: false,
218212
list: true,
219213
before: function (options, args, context, info) {
214+
const target = info.target;
215+
const model = target.target ? target.target : target;
216+
220217
if (args.first || args.last) {
221218
options.limit = parseInt(args.first || args.last, 10);
222219
}
223220
if (!args.orderBy) {
224-
args.orderBy = [orderByEnum._values[0].value];
225-
} else if (typeof args.orderBy === 'string') {
221+
args.orderBy = [
222+
[model.primaryKeyAttribute, 'ASC']
223+
];
224+
} else if (orderByEnum && typeof args.orderBy === 'string') {
226225
args.orderBy = [orderByEnum._nameLookup[args.orderBy].value];
227226
}
228227

@@ -275,6 +274,7 @@ export function sequelizeConnection({
275274
after: async function (values, args, context, info) {
276275
const {
277276
source,
277+
target
278278
} = info;
279279

280280
var cursor = null;

src/resolver.js

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,32 @@ function whereQueryVarsToValues(o, vals) {
1515
});
1616
}
1717

18-
function resolverFactory(target, options = {}) {
19-
var resolver
20-
, targetAttributes
21-
, isModel = !!target.getTableName
22-
, isAssociation = !!target.associationType
23-
, association = isAssociation && target
24-
, model = isAssociation && target.target || isModel && target
25-
, contextToOptions = _.assign({}, resolverFactory.contextToOptions, options.contextToOptions);
26-
27-
targetAttributes = Object.keys(model.rawAttributes);
18+
function resolverFactory(targetMaybeThunk, options = {}) {
19+
const contextToOptions = _.assign({}, resolverFactory.contextToOptions, options.contextToOptions);
2820

2921
invariant(options.include === undefined, 'Include support has been removed in favor of dataloader batching');
3022
if (options.before === undefined) options.before = (options) => options;
3123
if (options.after === undefined) options.after = (result) => result;
3224
if (options.handleConnection === undefined) options.handleConnection = true;
3325

34-
resolver = function (source, args, context, info) {
35-
var type = info.returnType
36-
, list = options.list || type instanceof GraphQLList
26+
return async function (source, args, context, info) {
27+
let target = typeof targetMaybeThunk === 'function' && targetMaybeThunk.findAndCountAll === undefined ?
28+
await Promise.resolve(targetMaybeThunk(source, args, context, info)) : targetMaybeThunk
29+
, isModel = !!target.getTableName
30+
, isAssociation = !!target.associationType
31+
, association = isAssociation && target
32+
, model = isAssociation && target.target || isModel && target
33+
, type = info.returnType
34+
, list = options.list || type instanceof GraphQLList;
35+
36+
let targetAttributes = Object.keys(model.rawAttributes)
3737
, findOptions = argsToFindOptions(args, targetAttributes);
3838

3939
info = {
4040
...info,
4141
type: type,
42-
source: source
42+
source: source,
43+
target: target
4344
};
4445

4546
context = context || {};
@@ -92,8 +93,6 @@ function resolverFactory(target, options = {}) {
9293
return options.after(result, args, context, info);
9394
});
9495
};
95-
96-
return resolver;
9796
}
9897

9998
resolverFactory.contextToOptions = {};

test/integration/relay/connection.test.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ describe('relay', function () {
111111
this.userTaskConnection = sequelizeConnection({
112112
name: 'userTask',
113113
nodeType: this.taskType,
114-
target: this.User.Tasks,
114+
target: () => this.User.Tasks,
115115
orderBy: new GraphQLEnumType({
116116
name: this.User.name + this.Task.name + 'ConnectionOrder',
117117
values: {
@@ -507,7 +507,7 @@ describe('relay', function () {
507507
});
508508

509509
it('should handle orderBy function case', async function () {
510-
await graphql(this.schema, `
510+
const result = await graphql(this.schema, `
511511
{
512512
user(id: ${this.userA.id}) {
513513
projects(first: 1) {
@@ -529,6 +529,8 @@ describe('relay', function () {
529529
}
530530
`, null, {});
531531

532+
if (result.errors) throw new Error(result.errors[0]);
533+
532534
expect(this.projectOrderSpy).to.have.been.calledOnce;
533535
expect(this.projectOrderSpy.alwaysCalledWithMatch({}, { first: 5 })).to.be.ok;
534536
});

test/integration/resolver.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ describe('resolver', function () {
166166
type: GraphQLInt
167167
}
168168
},
169-
resolve: resolver(User.Tasks, {
169+
resolve: resolver(() => User.Tasks, {
170170
before: function (options, args) {
171171
if (args.first) {
172172
options.order = options.order || [];

test/unit/relay/connection.test.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ describe('relay', function () {
8989
});
9090

9191
it('passes context, root and info to before', async function () {
92-
await graphql(this.schema, `
92+
const result = await graphql(this.schema, `
9393
query {
9494
viewer {
9595
tasks {
@@ -105,10 +105,13 @@ describe('relay', function () {
105105
viewer: this.viewer
106106
});
107107

108+
if (result.errors) throw new Error(result.errors[0]);
109+
110+
expect(this.beforeSpy).to.have.been.calledOnce;
108111
expect(this.beforeSpy).to.have.been.calledWithMatch(
109112
sinon.match.any,
110113
sinon.match({
111-
orderBy: sinon.match.any
114+
first: sinon.match.any
112115
}),
113116
sinon.match({
114117
viewer: {
@@ -125,7 +128,7 @@ describe('relay', function () {
125128
fullCount: sinon.match.number
126129
}),
127130
sinon.match({
128-
orderBy: sinon.match.any
131+
first: sinon.match.any
129132
}),
130133
sinon.match({
131134
viewer: {

0 commit comments

Comments
 (0)