Skip to content

Commit

Permalink
Add support for giving back total count via header
Browse files Browse the repository at this point in the history
  • Loading branch information
mkg20001 committed Feb 25, 2023
1 parent fc43360 commit 9679bfe
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 7 deletions.
11 changes: 10 additions & 1 deletion lib/action-util.js
Expand Up @@ -10,7 +10,7 @@ const internals = {};
*
* @type {Object}
*/
module.exports = (request, options) => {
module.exports = (request, options, h) => {

return {

Expand Down Expand Up @@ -194,6 +194,15 @@ module.exports = (request, options) => {
const userId = Hoek.reach(request.auth.credentials, options.userIdProperty);

return userId;
},

replyWithRange: (rangeStart, rangeEnd, total, results) => {
if (options.totalCountHeader === 'content-range') {
return h.response(results).header('content-range', `${options.model} ${rangeStart}-${rangeStart + results.length}/${total.total}`);
}

return h.response(results).header(options.totalCountHeader, String(total.total));

}
};
};
2 changes: 1 addition & 1 deletion lib/actions/add.js
Expand Up @@ -32,7 +32,7 @@ module.exports = function addToCollection(route, options) {
return Boom.notFound('No record found with the specified `id`.');
}

//if a key was specified for the relation, we're linking an exsiting.
//if a key was specified for the relation, we're linking an existing.
if (keys.child.value) {

const updatedTokenId = await foundModel.$relatedQuery(options.associationAttr)
Expand Down
22 changes: 17 additions & 5 deletions lib/actions/find.js
Expand Up @@ -21,16 +21,16 @@ const Actions = require('../action-util');

module.exports = function findRecords(route, options) {

return async (request) => {
return async (request, h) => {

const actionUtil = Actions(request, options);
const actionUtil = Actions(request, options, h);
// Look up the model
const Model = actionUtil.parseModel();
// Lookup for records that match the specified criteria. Are we just counting?
if (options._private.count) {

const modelCount = await Model.query().count().first();
return modelCount[Object.keys(modelCount)[0]];
const modelCount = await Model.query().count({ total: '*' }).first();
return modelCount.total;
}

const limit = actionUtil.parseLimit();
Expand All @@ -39,18 +39,30 @@ module.exports = function findRecords(route, options) {
const rangeEnd = rangeStart ? rangeStart + limit : limit;
const where = actionUtil.parseWhere(Model);

const foundModelsQuery = Model.query().range(rangeStart, rangeEnd).limit(limit);
const foundModelsQuery = Model.query();

if (where) {
foundModelsQuery.where(where);
}

let total;

if (options.includeTotalCount) {
total = await foundModelsQuery.clone().count({ total: '*' }).first();
}

if (sort) {
foundModelsQuery.orderByRaw(sort);
}

foundModelsQuery.range(rangeStart, rangeEnd).limit(limit);

const foundModels = await foundModelsQuery;

if (total) {
return actionUtil.replyWithRange(rangeStart, rangeEnd, total, foundModels.results);
}

return foundModels.results;

};
Expand Down
2 changes: 2 additions & 0 deletions lib/index.js
Expand Up @@ -72,6 +72,8 @@ internals.defaults = {
userModel: 'Users', // since it's not in the url
userIdProperty: 'id', // on auth credentials
prefix: '',
includeTotalCount: false,
totalCountHeader: 'content-range',
_private: {
actAsUserModifiedPath: false,
count: false
Expand Down
73 changes: 73 additions & 0 deletions test/index.js
Expand Up @@ -955,6 +955,79 @@ describe('Tandy', () => {
expect(result).to.be.an.array();
expect(result.length).to.equal(4);
});
it('Fetches all users and includes total count', async () => {

const server = await getServer(getOptions({
tandy: {
includeTotalCount: true
}
}));
server.registerModel([
TestModels.Users,
TestModels.Tokens
]);

await server.initialize();
const knex = server.knex();
// const data = await knex.seed.run({ directory: 'test/seeds' });
await knex.seed.run({ directory: 'test/seeds' });

server.route({
method: 'GET',
path: '/users',
handler: { tandy: {} }
});

const options = {
method: 'GET',
url: '/users'
};

const response = await server.inject(options);
const result = response.result;

expect(response.statusCode).to.equal(200);
expect(result).to.be.an.array();
expect(result.length).to.equal(4);
expect(response.headers['content-range']).to.equal('users 0-4/4');
});
it('Fetches all users and includes total count, custom header name', async () => {

const server = await getServer(getOptions({
tandy: {
includeTotalCount: true,
totalCountHeader: 'x-count'
}
}));
server.registerModel([
TestModels.Users,
TestModels.Tokens
]);

await server.initialize();
const knex = server.knex();
// const data = await knex.seed.run({ directory: 'test/seeds' });
await knex.seed.run({ directory: 'test/seeds' });

server.route({
method: 'GET',
path: '/users',
handler: { tandy: {} }
});

const options = {
method: 'GET',
url: '/users'
};

const response = await server.inject(options);
const result = response.result;

expect(response.statusCode).to.equal(200);
expect(result).to.be.an.array();
expect(result.length).to.equal(4);
expect(response.headers['x-count']).to.equal('4');
});
it('Fetches all users without actAsUser', async () => {

const config = getOptions({
Expand Down

0 comments on commit 9679bfe

Please sign in to comment.