Skip to content

Commit 00176d8

Browse files
committed
added support for connectionFields and adding where queries to connections
1 parent 79d7e95 commit 00176d8

File tree

4 files changed

+217
-105
lines changed

4 files changed

+217
-105
lines changed

src/generateIncludes.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export default function generateIncludes(simpleAST, type, root, options) {
3333
}
3434
}
3535

36-
if (isConnection(fieldType)) {
36+
if (isConnection(fieldType) && fieldAST.fields.edges) {
3737
fieldAST = nodeAST(fieldAST);
3838
fieldType = nodeType(fieldType);
3939
}

src/relay.js

Lines changed: 115 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818

1919
import _ from 'lodash';
2020
import resolver from './resolver';
21+
import simplifyAST from './simplifyAST';
2122

2223
class NodeTypeMapper {
2324

@@ -79,11 +80,11 @@ export function nodeType(connectionType) {
7980
return connectionType._fields.edges.type.ofType._fields.node.type;
8081
}
8182

82-
export function sequelizeConnection({name, nodeType, target, orderBy: orderByEnum, before}) {
83+
export function sequelizeConnection({name, nodeType, target, orderBy: orderByEnum, before, connectionFields, where}) {
8384
const {
8485
edgeType,
8586
connectionType
86-
} = connectionDefinitions({name, nodeType});
87+
} = connectionDefinitions({name, nodeType, connectionFields});
8788

8889
const model = target.target ? target.target : target;
8990
const SEPERATOR = '$';
@@ -128,111 +129,137 @@ export function sequelizeConnection({name, nodeType, target, orderBy: orderByEnu
128129
};
129130
};
130131

131-
return {
132-
connectionType,
133-
edgeType,
134-
nodeType,
135-
connectionArgs: $connectionArgs,
136-
resolve: resolver(target, {
137-
handleConnection: false,
138-
include: true,
139-
before: function (options, args) {
140-
if (args.first || args.last) {
141-
options.limit = parseInt(args.first || args.last, 10);
142-
}
132+
let argsToWhere = function (args) {
133+
let result = {};
143134

144-
if (!args.orderBy) {
145-
args.orderBy = [orderByEnum._values[0].value];
146-
} else if (typeof args.orderBy === 'string') {
147-
args.orderBy = [orderByEnum._nameLookup[args.orderBy].value];
148-
}
135+
_.each(args, (value, key) => {
136+
if (key in $connectionArgs) return;
137+
_.assign(result, where(key, value));
138+
});
149139

150-
let orderBy = args.orderBy;
151-
let orderAttribute = orderByAttribute(orderBy);
152-
let orderDirection = args.orderBy[0][1];
140+
return result;
141+
};
153142

154-
if (args.last) {
155-
orderDirection = orderDirection === 'ASC' ? 'DESC' : 'ASC';
156-
}
143+
let $resolver = resolver(target, {
144+
handleConnection: false,
145+
include: true,
146+
before: function (options, args) {
147+
if (args.first || args.last) {
148+
options.limit = parseInt(args.first || args.last, 10);
149+
}
157150

158-
options.order = [
159-
[orderAttribute, orderDirection]
160-
];
151+
if (!args.orderBy) {
152+
args.orderBy = [orderByEnum._values[0].value];
153+
} else if (typeof args.orderBy === 'string') {
154+
args.orderBy = [orderByEnum._nameLookup[args.orderBy].value];
155+
}
161156

162-
if (orderAttribute !== model.primaryKeyAttribute) {
163-
options.order.push([model.primaryKeyAttribute, 'ASC']);
164-
}
157+
let orderBy = args.orderBy;
158+
let orderAttribute = orderByAttribute(orderBy);
159+
let orderDirection = args.orderBy[0][1];
165160

166-
options.attributes.push(orderAttribute);
161+
if (args.last) {
162+
orderDirection = orderDirection === 'ASC' ? 'DESC' : 'ASC';
163+
}
167164

168-
if (model.sequelize.dialect.name === 'postgres' && options.limit) {
169-
options.attributes.push([
170-
model.sequelize.literal('COUNT(*) OVER()'),
171-
'full_count'
172-
]);
173-
}
165+
options.order = [
166+
[orderAttribute, orderDirection]
167+
];
174168

175-
if (args.after || args.before) {
176-
let cursor = fromCursor(args.after || args.before);
177-
let orderValue = cursor.orderValue;
169+
if (orderAttribute !== model.primaryKeyAttribute) {
170+
options.order.push([model.primaryKeyAttribute, 'ASC']);
171+
}
178172

179-
if (model.rawAttributes[orderAttribute].type instanceof model.sequelize.constructor.DATE) {
180-
orderValue = new Date(orderValue);
181-
}
173+
options.attributes.push(orderAttribute);
182174

183-
options.where = options.where || {};
175+
if (model.sequelize.dialect.name === 'postgres' && options.limit) {
176+
options.attributes.push([
177+
model.sequelize.literal('COUNT(*) OVER()'),
178+
'full_count'
179+
]);
180+
}
184181

185-
let where = {
186-
$or: [
187-
{
188-
[orderAttribute]: {
189-
[orderDirection === 'ASC' ? '$gt' : '$lt']: orderValue
190-
}
191-
},
192-
{
193-
[orderAttribute]: {
194-
$eq: orderValue
195-
},
196-
[model.primaryKeyAttribute]: {
197-
$gt: cursor.id
198-
}
199-
}
200-
]
201-
};
182+
options.where = argsToWhere(args);
202183

203-
// TODO, do a proper merge that won't kill another $or
204-
_.assign(options.where, where);
205-
}
184+
if (args.after || args.before) {
185+
let cursor = fromCursor(args.after || args.before);
186+
let orderValue = cursor.orderValue;
206187

207-
return before(options);
208-
},
209-
after: function (values, args) {
210-
if (!args.orderBy) {
211-
args.orderBy = [orderByEnum._values[0].value];
188+
if (model.rawAttributes[orderAttribute].type instanceof model.sequelize.constructor.DATE) {
189+
orderValue = new Date(orderValue);
212190
}
213191

214-
let edges = values.map((value) => {
215-
return {
216-
cursor: toCursor(value, args.orderBy),
217-
node: value
218-
};
219-
});
192+
let slicingWhere = {
193+
$or: [
194+
{
195+
[orderAttribute]: {
196+
[orderDirection === 'ASC' ? '$gt' : '$lt']: orderValue
197+
}
198+
},
199+
{
200+
[orderAttribute]: {
201+
$eq: orderValue
202+
},
203+
[model.primaryKeyAttribute]: {
204+
$gt: cursor.id
205+
}
206+
}
207+
]
208+
};
209+
210+
// TODO, do a proper merge that won't kill another $or
211+
_.assign(options.where, slicingWhere);
212+
}
220213

221-
let firstEdge = edges[0];
222-
let lastEdge = edges[edges.length - 1];
223-
let fullCount = values[0] && values[0].dataValues.full_count &&
224-
parseInt(values[0].dataValues.full_count, 10) || 0;
214+
return before(options);
215+
},
216+
after: function (values, args, root, {source}) {
217+
if (!args.orderBy) {
218+
args.orderBy = [orderByEnum._values[0].value];
219+
}
225220

221+
let edges = values.map((value) => {
226222
return {
227-
edges,
228-
pageInfo: {
229-
startCursor: firstEdge ? firstEdge.cursor : null,
230-
endCursor: lastEdge ? lastEdge.cursor : null,
231-
hasPreviousPage: args.last !== null && args.last !== undefined ? fullCount > parseInt(args.last, 10) : false,
232-
hasNextPage: args.first !== null && args.first !== undefined ? fullCount > parseInt(args.first, 10) : false,
233-
}
223+
cursor: toCursor(value, args.orderBy),
224+
node: value
234225
};
226+
});
227+
228+
let firstEdge = edges[0];
229+
let lastEdge = edges[edges.length - 1];
230+
let fullCount = values[0] && values[0].dataValues.full_count &&
231+
parseInt(values[0].dataValues.full_count, 10) || 0;
232+
233+
return {
234+
source,
235+
args,
236+
where: argsToWhere(args),
237+
edges,
238+
pageInfo: {
239+
startCursor: firstEdge ? firstEdge.cursor : null,
240+
endCursor: lastEdge ? lastEdge.cursor : null,
241+
hasPreviousPage: args.last !== null && args.last !== undefined ? fullCount > parseInt(args.last, 10) : false,
242+
hasNextPage: args.first !== null && args.first !== undefined ? fullCount > parseInt(args.first, 10) : false,
243+
}
244+
};
245+
}
246+
});
247+
248+
return {
249+
connectionType,
250+
edgeType,
251+
nodeType,
252+
connectionArgs: $connectionArgs,
253+
resolve: (source, args, info) => {
254+
if (simplifyAST(info.fieldASTs[0], info).fields.edges) {
255+
return $resolver(source, args, info);
235256
}
236-
})
257+
258+
return {
259+
source,
260+
args,
261+
where: argsToWhere(args)
262+
};
263+
}
237264
};
238265
}

src/resolver.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ module.exports = function (target, options) {
5050
}
5151
return options.after(source.get(association.as), args, root, {
5252
ast: simpleAST,
53-
type: type
53+
type: type,
54+
source: source
5455
});
5556
}
5657

@@ -77,7 +78,8 @@ module.exports = function (target, options) {
7778

7879
findOptions = options.before(findOptions, args, root, {
7980
ast: simpleAST,
80-
type: type
81+
type: type,
82+
source: source
8183
});
8284

8385
if (!findOptions.order) {
@@ -91,14 +93,16 @@ module.exports = function (target, options) {
9193
}
9294
return options.after(result, args, root, {
9395
ast: simpleAST,
94-
type: type
96+
type: type,
97+
source: source
9598
});
9699
});
97100
}
98101
return model[list ? 'findAll' : 'findOne'](findOptions).then(function (result) {
99102
return options.after(result, args, root, {
100103
ast: simpleAST,
101-
type: type
104+
type: type,
105+
source: source
102106
});
103107
});
104108
};

0 commit comments

Comments
 (0)