Comparing version 1.1.0 to 1.2.1
@@ -11,3 +11,3 @@ (function (name, definition, context) { | ||
// compile regular expressions ahead of time for efficiency | ||
var relsRegExp = /^;\s*rel=(?:"([^"]+)"|([^";,]+)(?:[;,]|$))/; | ||
var relsRegExp = /^;\s*([^"=]+)=(?:"([^"]+)"|([^";,]+)(?:[;,]|$))/; | ||
var keysRegExp = /([^\s]+)/g; | ||
@@ -18,7 +18,8 @@ var sourceRegExp = /^<([^>]*)>/; | ||
return { | ||
parse: function (linksHeader) { | ||
var links = {}; | ||
parse: function (linksHeader, options) { | ||
var match; | ||
var source; | ||
var rels; | ||
var extended = options && options.extended || false; | ||
var links = []; | ||
@@ -32,20 +33,31 @@ while (linksHeader) { | ||
var current = { | ||
link: source[1] | ||
}; | ||
// Move cursor | ||
linksHeader = linksHeader.slice(source[0].length); | ||
// Parse `; rel=relation` and `; rel="relation"` | ||
match = relsRegExp.exec(linksHeader); | ||
if (!match) break; | ||
// Parse `; attr=relation` and `; attr="relation"` | ||
// Move cursor | ||
linksHeader = linksHeader.slice(match[0].length); | ||
var nextDelimiter = linksHeader.match(delimiterRegExp); | ||
while(linksHeader && (!nextDelimiter || nextDelimiter.index > 0)) { | ||
match = relsRegExp.exec(linksHeader); | ||
if (!match) break; | ||
// Add either quoted rel or unquoted rel | ||
rels = (match[1] || match[2]).split(/\s+/) | ||
// Move cursor | ||
linksHeader = linksHeader.slice(match[0].length); | ||
nextDelimiter = linksHeader.match(delimiterRegExp); | ||
// Add the link to `links` under every rel | ||
rels.forEach(function (rel) { | ||
links[rel] = source[1]; | ||
}); | ||
if (match[1] === 'rel' || match[1] === 'rev') { | ||
// Add either quoted rel or unquoted rel | ||
rels = (match[2] || match[3]).split(/\s+/); | ||
current[match[1]] = rels; | ||
} else { | ||
current[match[1]] = match[2] || match[3]; | ||
} | ||
} | ||
links.push(current); | ||
// Move cursor | ||
@@ -55,2 +67,13 @@ linksHeader = linksHeader.replace(delimiterRegExp, ''); | ||
if (!extended) { | ||
return links.reduce(function(result, currentLink) { | ||
if (currentLink.rel) { | ||
currentLink.rel.forEach(function(rel) { | ||
result[rel] = currentLink.link; | ||
}); | ||
} | ||
return result; | ||
}, {}); | ||
} | ||
return links; | ||
@@ -57,0 +80,0 @@ }, |
{ | ||
"name": "li", | ||
"version": "1.1.0", | ||
"version": "1.2.1", | ||
"description": "Parse the Links header format and return a javascript object.", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -0,1 +1,3 @@ | ||
[![Build Status](https://travis-ci.org/jfromaniello/li.svg?branch=master)](https://travis-ci.org/jfromaniello/li) | ||
Parse and format [Link header according to RFC 5988](http://www.w3.org/Protocols/9707-link-header.html). | ||
@@ -2,0 +4,0 @@ |
@@ -13,17 +13,8 @@ var should = require('chai').should(); | ||
'</api/users?q=smith&fields=fname,lname>; rel="search"'; | ||
var quotfixture = '</api/users/1>; rel=home,'+ | ||
'</api/users/2>; rel=only one'; | ||
var linksObject = { | ||
first : '/api/users?page=0&per_page=2', | ||
next : '/api/users?page=1&per_page=2', | ||
last : '/api/users?page=3&per_page=2', | ||
self : '/api/users/123', | ||
filtered : '/api/users/123?filter=my;ids=1,2,3', | ||
'related alternate' : '/api/users/12345', | ||
'http://example.org/search-results' : '/api/users?name=Joe+Bloggs', | ||
'http://example.org/status-result collection': '/api/users?status=registered', | ||
'search' : '/api/users?q=smith&fields=fname,lname' | ||
}; | ||
describe('parse-links', function () { | ||
@@ -56,8 +47,61 @@ describe('parse the links!', function(){ | ||
describe('stringify link object', function(){ | ||
it('should return a string with the links', function() { | ||
var stringified = li.stringify(linksObject); | ||
stringified.should.equal(fixture); | ||
describe('with extra param (issue #6)', function() { | ||
it('should return the links', function() { | ||
var parsed = li.parse('</3>; rel="next", </2>; rel="prev", </home>; rel="up"; rev="home", </void>; rel="ignored"'); | ||
parsed.next.should.eql('/3'); | ||
parsed.prev.should.eql('/2'); | ||
parsed.up.should.eql('/home'); | ||
}); | ||
it('should return the complete parsed object when using extended true', function() { | ||
var parsed = li.parse('</3>; rel="next", </2>; rel="prev", </home>; rel="up"; rev="home", </void>; rel="ignored"', { extended: true }); | ||
parsed[0].link.should.equal('/3'); | ||
parsed[0].rel[0].should.equal('next'); | ||
parsed[1].link.should.equal('/2'); | ||
parsed[1].rel[0].should.equal('prev'); | ||
parsed[2].link.should.equal('/home'); | ||
parsed[2].rel[0].should.equal('up'); | ||
parsed[2].rev[0].should.equal('home'); | ||
}); | ||
}); | ||
describe('links without rel (issue #7)', function() { | ||
it('should return the links', function() { | ||
var parsed = li.parse('</3>; rel="next", </2>; rel="prev", </home>, </void>; rel="ignored"'); | ||
parsed.next.should.eql('/3'); | ||
parsed.prev.should.eql('/2'); | ||
parsed.ignored.should.eql('/void'); | ||
}); | ||
it('should return the links with extended param', function() { | ||
var parsed = li.parse('</3>; rel="next", </2>; rel="prev", </home>, </void>; rel="ignored"', { extended: true }); | ||
parsed[0].rel[0].should.eql('next'); | ||
parsed[0].link.should.eql('/3'); | ||
parsed[1].rel[0].should.eql('prev'); | ||
parsed[1].link.should.eql('/2'); | ||
parsed[2].link.should.eql('/home'); | ||
}); | ||
}); | ||
}); | ||
describe('stringify link object', function(){ | ||
it('should return a string with the links', function() { | ||
var linksObject = { | ||
first : '/api/users?page=0&per_page=2', | ||
next : '/api/users?page=1&per_page=2', | ||
last : '/api/users?page=3&per_page=2', | ||
self : '/api/users/123', | ||
filtered : '/api/users/123?filter=my;ids=1,2,3', | ||
'related alternate' : '/api/users/12345', | ||
'http://example.org/search-results' : '/api/users?name=Joe+Bloggs', | ||
'http://example.org/status-result collection': '/api/users?status=registered', | ||
'search' : '/api/users?q=smith&fields=fname,lname' | ||
}; | ||
var stringified = li.stringify(linksObject); | ||
stringified.should.equal(fixture); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
10397
166
55