Skip to content

Commit

Permalink
feat: match ember-data jsonapi pagination implementation (#151)
Browse files Browse the repository at this point in the history
  • Loading branch information
zacharygolba authored Jun 18, 2016
1 parent ea4786b commit a569225
Show file tree
Hide file tree
Showing 12 changed files with 199 additions and 85 deletions.
7 changes: 5 additions & 2 deletions decl/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ type params = {
relationships?: Object;
};

page: {
size: number;
number: number;
};

fields: Object;
filter: Object;
id?: number | string | Buffer;
include: Array<string> | Object;
limit: number;
page: number;
sort: string | [string, string];
};

Expand Down
5 changes: 2 additions & 3 deletions src/packages/controller/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,6 @@ class Controller {
params: {
sort,
page,
limit,
filter,
fields,
include
Expand All @@ -374,8 +373,8 @@ class Controller {

return this.model.select(...fields)
.include(include)
.limit(limit)
.page(page)
.limit(page.size)
.page(page.number)
.where(filter)
.order(...sort);
}
Expand Down
28 changes: 8 additions & 20 deletions src/packages/route/middleware/sanitize-params.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export default function sanitizeParams(
}
}: {
modelName: string,

model: {
relationshipNames: Array<string>
}
Expand All @@ -32,25 +33,12 @@ export default function sanitizeParams(

let {
page,
limit,
sort,
filter,
include,
fields
} = params;

if (!page) {
page = 1;
} else if (typeof page === 'string') {
page = parseInt(page, 10);
}

if (!limit) {
limit = 25;
} else if (typeof limit === 'string') {
limit = parseInt(limit, 10);
}

if (!sort) {
sort = ['createdAt', 'ASC'];
} else {
Expand Down Expand Up @@ -118,14 +106,12 @@ export default function sanitizeParams(
}, {});

req.params = {
id: params.id,
filter: pick(filter, ...this.filter),

page,
limit,
sort,
include,
fields
fields,
id: params.id,
filter: pick(filter, ...this.filter)
};

if (/^(POST|PATCH)$/g.test(req.method)) {
Expand All @@ -136,13 +122,15 @@ export default function sanitizeParams(
}
} = params;

Object.assign(req.params, {
req.params = {
...req.params,

data: {
id: params.data.id,

type,
attributes: pick(attributes, ...this.params)
}
});
};
}
}
24 changes: 0 additions & 24 deletions src/packages/route/middleware/set-limit.js

This file was deleted.

46 changes: 46 additions & 0 deletions src/packages/route/middleware/set-page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// @flow
import type { IncomingMessage, ServerResponse } from 'http';

/**
* @private
*/
export default function setPage(
req: IncomingMessage,
res: ServerResponse
): void {
const { route } = req;

if (route && route.action === 'index') {
const { defaultPerPage } = this;

let {
params: {
page: {
size,
number
} = {
size: defaultPerPage,
number: 1
}
}
} = req;

size = parseInt(size, 10);
number = parseInt(number, 10);

if (!Number.isFinite(size)) {
size = defaultPerPage;
} else if (!Number.isFinite(number)) {
number = 1;
}

req.params = {
...req.params,

page: {
size,
number
}
};
}
}
6 changes: 2 additions & 4 deletions src/packages/route/utils/create-action.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Model, Query } from '../../database';
import sanitizeParams from '../middleware/sanitize-params';
import setInclude from '../middleware/set-include';
import setFields from '../middleware/set-fields';
import setLimit from '../middleware/set-limit';
import setPage from '../middleware/set-page';

import insert from '../../../utils/insert';
import createPageLinks from './create-page-links';
Expand All @@ -25,7 +25,7 @@ export default function createAction(
sanitizeParams,
setInclude,
setFields,
setLimit
setPage
];

const handlers = new Array(builtIns.length + middleware.length + 1);
Expand All @@ -52,7 +52,6 @@ export default function createAction(

params: {
page,
limit,
include
}
} = req;
Expand All @@ -76,7 +75,6 @@ export default function createAction(

...createPageLinks({
page,
limit,
total,
query,
domain,
Expand Down
53 changes: 32 additions & 21 deletions src/packages/route/utils/create-page-links.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
// @flow
import querystring from 'querystring';

import omit from '../../../utils/omit';
import createQueryString from '../../../utils/create-query-string';

import type { IncomingMessage } from 'http';

export default function createPageLinks({
page,
limit,
total,
query,
domain,
pathname,
defaultPerPage
}: {
page: number,
limit: number,
page: IncomingMessage.params.page,
total: number,
query: Object,
domain: string,
Expand All @@ -25,50 +24,62 @@ export default function createPageLinks({
prev: ?string,
next: ?string
} {
const params = omit(query, 'limit', 'page');
const lastPageNum = total > 0 ? Math.ceil(total / limit) : 1;
const params = omit(query, 'page', 'page[size]', 'page[number]');
const lastPageNum = total > 0 ? Math.ceil(total / page.size) : 1;
let base = domain + pathname;
let prev = null;
let next = null;
let last = null;
let first = null;

if (limit !== defaultPerPage) {
params.limit = limit;
}
params.page = page.size !== defaultPerPage ? {
size: page.size
} : {};

if (Object.keys(params).length) {
if (Object.keys(params).length > 1) {
base += '?';
first = base + querystring.stringify(params);
first = base + createQueryString(params);
} else {
first = base;
base += '?';
}

if (lastPageNum > 1) {
last = base + querystring.stringify({
last = base + createQueryString({
...params,
page: lastPageNum

page: {
...params.page,
number: lastPageNum
}
});
} else {
last = first;
}

if (page > 1) {
if (page === 2) {
if (page.number > 1) {
if (page.number === 2) {
prev = first;
} else {
prev = base + querystring.stringify({
prev = base + createQueryString({
...params,
page: page - 1

page: {
...params.page,
number: page.number - 1
}
});
}
}

if (page < lastPageNum) {
next = base + querystring.stringify({
if (page.number < lastPageNum) {
next = base + createQueryString({
...params,
page: page + 1

page: {
...params.page,
number: page.number + 1
}
});
}

Expand Down
12 changes: 6 additions & 6 deletions src/packages/serializer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ class Serializer {
* ],
* "links": {
* "self": "http://localhost:4000/posts",
* "first": "http://localhost:4000/posts?page=1",
* "last": "http://localhost:4000/posts?page=1",
* "first": "http://localhost:4000/posts",
* "last": "http://localhost:4000/posts",
* "prev": null,
* "next": null
* }
Expand Down Expand Up @@ -198,8 +198,8 @@ class Serializer {
* ],
* "links": {
* "self": "http://localhost:4000/posts",
* "first": "http://localhost:4000/posts?page=1",
* "last": "http://localhost:4000/posts?page=1",
* "first": "http://localhost:4000/posts",
* "last": "http://localhost:4000/posts",
* "prev": null,
* "next": null
* }
Expand Down Expand Up @@ -261,8 +261,8 @@ class Serializer {
* ],
* "links": {
* "self": "http://localhost:4000/posts",
* "first": "http://localhost:4000/posts?page=1",
* "last": "http://localhost:4000/posts?page=1",
* "first": "http://localhost:4000/posts",
* "last": "http://localhost:4000/posts",
* "prev": null,
* "next": null
* }
Expand Down
6 changes: 5 additions & 1 deletion src/packages/server/utils/format-params.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export default async function formatParams(req) {

return {
...result,

[parentKey]: {
...parentValue,
[childKey]: value
Expand All @@ -85,7 +86,10 @@ export default async function formatParams(req) {
}, {});

if (/(PATCH|POST)/g.test(method)) {
Object.assign(params, await bodyParser(req));
params = {
...params,
...(await bodyParser(req))
};
}

return format(params, method);
Expand Down
Loading

0 comments on commit a569225

Please sign in to comment.