Skip to content

Commit

Permalink
feat(app): Support paginations
Browse files Browse the repository at this point in the history
Facebook style pagination with connections on objects and relations
  • Loading branch information
Tallyb committed Nov 14, 2016
1 parent 5fea65d commit 5ca2257
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 46 deletions.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Place your settings in this file to overwrite default and user settings.
{
"search.exclude": {
"**/out": true
}
}
6 changes: 5 additions & 1 deletion common/models/author.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,12 @@
"type": "referencesMany",
"model": "Author",
"foreignKey": "friendIds"
},
"others": {
"type": "hasMany",
"model": "Author"
}
},
"acls": [],
"methods": {}
}
}
29 changes: 19 additions & 10 deletions lib/execution.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ var utils = require('./utils');

function buildSelector(model, args) {
let selector = {
where: {}
where: args.where || {}
};
const begin = utils.getId(args.after);
const end = utils.getId(args.before);
Expand All @@ -24,20 +24,21 @@ function buildSelector(model, args) {
}

function findOne(model, obj, args, context) {
let id = obj ? obj.id : args.id;
let id = obj ? obj[model.getIdName()] : args.id;
return model.findById(id);
}

function getCount(model, obj, args, context) {
return model.count();
return model.count(args.where);
}

function getFirst(model, obj, args) {
return model.findOne({
order: model.getIdName() + (args.before ? ' DESC' : ' ASC')
order: model.getIdName() + (args.before ? ' DESC' : ' ASC'),
where: args.where
})
.then(res => {
return res.__data;
return res ? res.__data : {};
});
}

Expand Down Expand Up @@ -65,13 +66,21 @@ function findAll(model, obj, args, context) {
}

function findRelated(rel, obj, args, context) {
let selector = {};
if (!rel.multiple || _.isArray(obj[rel.keyFrom])) {
if (_.isArray(obj[rel.keyFrom])) {
return [];
}
if (rel.multiple) {
// single relationship or set of items with ids included
return rel.modelTo.findByIds(obj[rel.keyFrom]);
args.where = {
[rel.keyTo]: obj[rel.keyFrom]
};
return findAll(rel.modelTo, obj, args, context);
//rel.modelTo.findByIds(obj[rel.keyFrom]);
} else {
selector.where[rel.keyTo] = obj[rel.keyFrom];
return rel.modelTo.find(selector);

return findOne(rel.modelTo, obj, args, context);
//selector.where[rel.keyTo] = obj[rel.keyFrom];
//return rel.modelTo.find(selector);
}
}

Expand Down
30 changes: 10 additions & 20 deletions lib/relations.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,25 @@ function isSimple(rel) {
return rel.embed || !rel.multiple;
}

function isShared(rel) {
return rel.modelTo.shared;
function sharedRelations(model) {
return _.pickBy(model.relations, rel => rel.modelTo.shared);
}

function typeDefs(model) {
return _.reduce(model.relations, (obj, rel, key) => {
if (isShared(rel)) {
obj = obj + ' \n ' + (isSimple(rel) ?
`${rel.name}: ${rel.modelTo.modelName}` :
`${rel.name} ${utils.PAGINATION}: [${connections.connectionTypeName(rel.modelTo)}]`);
}
return _.reduce(sharedRelations(model), (obj, rel, key) => {
obj = obj + ' \n ' + (isSimple(rel) ?
`${rel.name}: ${rel.modelTo.modelName}` :
`${rel.name} ${utils.PAGINATION}: ${connections.connectionTypeName(rel.modelTo)}`);
return obj;
}, '');
}

function resolvers(model) {
let resolver = {};
_.forEach(model.relations, rel => {
if (isShared(rel)) {
if (isSimple(rel)) {
resolver[rel.name] = (obj, args, context) => {
return execution.findEmbedded(rel, obj, args, context);
};
} else {
resolver[rel.name] = (obj, args, context) => {
return execution.findRelated(rel, obj, args, context);
};
}
}
_.forEach(sharedRelations(model), rel => {
resolver[rel.name] = (obj, args, context) => {
return execution.findRelated(rel, obj, args, context);
};
});

return {
Expand Down
21 changes: 10 additions & 11 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

var _ = require('lodash');

const PREFIX = 'connection.';

const SCALARS = {
number: 'Float',
string: 'String',
Expand All @@ -13,7 +11,12 @@ const SCALARS = {
object: 'JSON'
};

const PAGINATION = '(after: String, first: Int, before: String, last: Int)';
const PAGINATION = '(where: JSON, after: String, first: Int, before: String, last: Int)';

function toType(type) {
let scalar = SCALARS[type.toLowerCase().trim()];
return scalar ? scalar : type;
}

function base64(i) {
return (new Buffer(i, 'ascii')).toString('base64');
Expand All @@ -23,6 +26,8 @@ function unbase64(i) {
return (new Buffer(i, 'base64')).toString('ascii');
}

const PREFIX = 'connection.';

/**
* Creates the cursor string from an offset.
* @param {String} id the id to convert
Expand All @@ -45,15 +50,9 @@ function getId(cursor) {
if (cursor === undefined || cursor === null) {
return null;
}

return cursorToId(cursor);
}

function toType(type) {
let scalar = SCALARS[type.toLowerCase().trim()];
return scalar ? scalar : type;
}

/**
* Filter models to return shared models only
* @param {Array<Model>} models all Loopback Models
Expand Down Expand Up @@ -82,7 +81,7 @@ module.exports = {
sharedModels,
sharedRelations,
PAGINATION,
getId,
idToCursor,
cursorToId,
getId
cursorToId
};
9 changes: 5 additions & 4 deletions test/pagination.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ describe('Pagination', () => {
.then(res => {
expect(res).to.have.status(200);
res = res.body.data;
console.log('RES', res);
expect(res.allNotes.edges.length).to.be.above(0);
});
});
Expand Down Expand Up @@ -79,7 +78,6 @@ describe('Pagination', () => {
.then(res => {
expect(res).to.have.status(200);
res = res.body.data;
console.log('RES', res);
expect(res.allNotes.edges.length).to.be.above(0);
expect(res.allNotes.edges[0].node.id).to.be.above(4);
expect(res.allNotes.pageInfo.hasPreviousPage).to.be.true;
Expand Down Expand Up @@ -119,8 +117,11 @@ describe('Pagination', () => {
.then(res => {
expect(res).to.have.status(200);
res = res.body.data;
console.log('RES', res);
expect(res.allAuthors.edges[0].node.Notes.length).to.be.above(1);
console.log('RES', res.allAuthors.edges[0]);

expect(res.allAuthors.edges[0].node.notes.Notes.length).to.be.above(0);
expect(res.allAuthors.edges[0].node.notes.totalCount).to.be.above(0);
expect(res.allAuthors.edges[0].cursor).not.to.be.empty;
});
});

Expand Down

0 comments on commit 5ca2257

Please sign in to comment.