Skip to content

Commit 2c601f2

Browse files
committed
add support for edgeFields
1 parent 0fc0ca4 commit 2c601f2

File tree

3 files changed

+78
-10
lines changed

3 files changed

+78
-10
lines changed

docs/relay.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,29 @@ const userTaskConnection = sequelizeConnection({
9797
// for custom args other than connectionArgs return a sequelize where parameter
9898

9999
return {[key]: value};
100+
},
101+
connectionFields: {
102+
total: {
103+
type: GraphQLInt,
104+
resolve: ({source}) => {
105+
/*
106+
* We return a object containing the source, edges and more as the connection result
107+
* You there for need to extract source from the usual source argument
108+
*/
109+
return source.countTasks();
110+
}
111+
}
112+
},
113+
edgeFields: {
114+
wasCreatedByUser: {
115+
type: GraphQLBoolean,
116+
resolve: (edge) => {
117+
/*
118+
* We attach the connection source to edges
119+
*/
120+
return edge.node.createdBy === edge.source.id;
121+
}
122+
}
100123
}
101124
});
102125

src/relay.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,15 @@ export function nodeType(connectionType) {
8888
return connectionType._fields.edges.type.ofType._fields.node.type;
8989
}
9090

91-
export function sequelizeConnection({name, nodeType, target, orderBy: orderByEnum, before, connectionFields, where}) {
91+
export function sequelizeConnection({name, nodeType, target, orderBy: orderByEnum, before, connectionFields, edgeFields, where}) {
9292
const {
9393
edgeType,
9494
connectionType
9595
} = connectionDefinitions({
9696
name,
9797
nodeType,
98-
connectionFields
98+
connectionFields,
99+
edgeFields
99100
});
100101

101102
const model = target.target ? target.target : target;
@@ -154,14 +155,15 @@ export function sequelizeConnection({name, nodeType, target, orderBy: orderByEnu
154155
return result;
155156
};
156157

157-
let resolveEdge = function (item, args = {}) {
158+
let resolveEdge = function (item, args = {}, source) {
158159
if (!args.orderBy) {
159160
args.orderBy = [defaultOrderBy];
160161
}
161162

162163
return {
163164
cursor: toCursor(item, args.orderBy),
164-
node: item
165+
node: item,
166+
source: source
165167
};
166168
};
167169

@@ -242,7 +244,7 @@ export function sequelizeConnection({name, nodeType, target, orderBy: orderByEnu
242244
},
243245
after: function (values, args, root, {source}) {
244246
let edges = values.map((value) => {
245-
return resolveEdge(value, args);
247+
return resolveEdge(value, args, source);
246248
});
247249

248250
let firstEdge = edges[0];

test/integration/relay/connection.test.js

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ if (helper.sequelize.dialect.name === 'postgres') {
6666
this.Project.Tasks = this.Project.hasMany(this.Task, {as: 'tasks', foreignKey: 'projectId'});
6767
this.Task.Project = this.Task.belongsTo(this.Project, {as: 'project', foreignKey: 'projectId'});
6868

69+
this.Project.Owner = this.Project.belongsTo(this.User, {as: 'owner', foreignKey: 'ownerId'});
70+
6971
this.taskType = new GraphQLObjectType({
7072
name: this.Task.name,
7173
fields: {
@@ -76,7 +78,7 @@ if (helper.sequelize.dialect.name === 'postgres') {
7678

7779
this.projectTaskConnectionFieldSpy = sinon.spy();
7880
this.projectTaskConnection = sequelizeConnection({
79-
name: this.Project.name + this.Task.name,
81+
name: 'projectTask',
8082
nodeType: this.taskType,
8183
target: this.Project.Tasks,
8284
orderBy: new GraphQLEnumType({
@@ -110,13 +112,13 @@ if (helper.sequelize.dialect.name === 'postgres') {
110112
type: this.projectTaskConnection.connectionType,
111113
args: this.projectTaskConnection.connectionArgs,
112114
resolve: this.projectTaskConnection.resolve
113-
},
115+
}
114116
}
115117
});
116118

117119
this.userTaskConnectionFieldSpy = sinon.spy();
118120
this.userTaskConnection = sequelizeConnection({
119-
name: this.User.name + this.Task.name,
121+
name: 'userTask',
120122
nodeType: this.taskType,
121123
target: this.User.Tasks,
122124
orderBy: new GraphQLEnumType({
@@ -148,15 +150,23 @@ if (helper.sequelize.dialect.name === 'postgres') {
148150
});
149151

150152
this.userProjectConnection = sequelizeConnection({
151-
name: this.Project.name,
153+
name: 'userProject',
152154
nodeType: this.projectType,
153155
target: this.User.Projects,
154156
orderBy: new GraphQLEnumType({
155157
name: this.User.name + this.Project.name + 'ConnectionOrder',
156158
values: {
157159
ID: {value: [this.Project.primaryKeyAttribute, 'ASC']}
158160
}
159-
})
161+
}),
162+
edgeFields: {
163+
isOwner: {
164+
type: GraphQLBoolean,
165+
resolve: function(edge) {
166+
return edge.node.ownerId === edge.source.id;
167+
}
168+
}
169+
}
160170
});
161171

162172
this.userType = new GraphQLObjectType({
@@ -260,6 +270,9 @@ if (helper.sequelize.dialect.name === 'postgres') {
260270
});
261271

262272
await Promise.join(
273+
this.projectA.update({
274+
ownerId: this.userA.get('id')
275+
}),
263276
this.ProjectMember.create({
264277
projectId: this.projectA.get('id'),
265278
userId: this.userA.get('id')
@@ -612,6 +625,36 @@ if (helper.sequelize.dialect.name === 'postgres') {
612625
expect(this.projectTaskConnectionFieldSpy.firstCall.args[0].source.get('tasks')).to.be.undefined;
613626
});
614627

628+
it('should support edgeFields', async function () {
629+
let sqlSpy = sinon.spy();
630+
631+
let result = await graphql(this.schema, `
632+
{
633+
user(id: ${this.userA.id}) {
634+
projects {
635+
edges {
636+
...projectOwner
637+
node {
638+
id
639+
}
640+
}
641+
}
642+
}
643+
}
644+
645+
fragment projectOwner on userProjectEdge {
646+
isOwner
647+
}
648+
`, {
649+
logging: sqlSpy
650+
});
651+
652+
if (result.errors) throw new Error(result.errors[0].stack);
653+
654+
let isOwner = result.data.user.projects.edges.map(edge => edge.isOwner);
655+
expect(isOwner.sort()).to.deep.equal([true, false].sort());
656+
});
657+
615658
it('should support connection fields with args/where', async function () {
616659
let sqlSpy = sinon.spy();
617660

0 commit comments

Comments
 (0)