82 lines
1.5 KiB
JavaScript
82 lines
1.5 KiB
JavaScript
|
const common = require('./common')
|
||
|
|
||
|
function hasRel(x) {
|
||
|
return x && x.rel;
|
||
|
}
|
||
|
|
||
|
function intoRels (acc, x) {
|
||
|
function splitRel (rel) {
|
||
|
acc[rel] = xtend(x, { rel: rel });
|
||
|
}
|
||
|
|
||
|
x.rel.split(/\s+/).forEach(splitRel);
|
||
|
|
||
|
return acc;
|
||
|
}
|
||
|
|
||
|
function createObjects (acc, p) {
|
||
|
// rel="next" => 1: rel 2: next
|
||
|
var m = p.match(/\s*(.+)\s*=\s*"?([^"]+)"?/)
|
||
|
if (m) acc[m[1]] = m[2];
|
||
|
return acc;
|
||
|
}
|
||
|
|
||
|
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||
|
|
||
|
function extend() {
|
||
|
var target = {}
|
||
|
|
||
|
for (var i = 0; i < arguments.length; i++) {
|
||
|
var source = arguments[i]
|
||
|
|
||
|
for (var key in source) {
|
||
|
if (hasOwnProperty.call(source, key)) {
|
||
|
target[key] = source[key]
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return target
|
||
|
}
|
||
|
|
||
|
function parseLink(link) {
|
||
|
try {
|
||
|
var m = link.match(/<?([^>]*)>(.*)/)
|
||
|
, linkUrl = m[1]
|
||
|
, parts = m[2].split(';')
|
||
|
, qry = new URL(linkUrl).searchParams;
|
||
|
|
||
|
parts.shift();
|
||
|
|
||
|
var info = parts
|
||
|
.reduce(createObjects, {});
|
||
|
|
||
|
info = extend(qry, info);
|
||
|
info.url = linkUrl;
|
||
|
return info;
|
||
|
} catch (e) {
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function parse(linkHeader) {
|
||
|
return linkHeader.split(/,\s*</)
|
||
|
.map(parseLink)
|
||
|
.filter(hasRel)
|
||
|
.reduce(intoRels, {});
|
||
|
}
|
||
|
|
||
|
exports.fetchPage = function(url) {
|
||
|
return common.sendRequest({
|
||
|
method: 'GET',
|
||
|
url: url,
|
||
|
}, true)
|
||
|
.then(function(result) {
|
||
|
return {
|
||
|
data: result.data,
|
||
|
links: parse(result.headers.link || ''),
|
||
|
total: Number(result.headers.pagination_total || '0'),
|
||
|
}
|
||
|
})
|
||
|
}
|