spotify-uri
Advanced tools
Comparing version 0.0.1 to 0.1.0
68
index.js
@@ -6,4 +6,7 @@ | ||
var url = require('url'); | ||
var qs = require('querystring'); | ||
var parse = require('./parse'); | ||
var formatURI = require('./formatURI'); | ||
var formatOpenURL = require('./formatOpenURL'); | ||
var formatPlayURL = require('./formatPlayURL'); | ||
var formatEmbedURL = require('./formatEmbedURL'); | ||
@@ -14,57 +17,8 @@ /** | ||
module.exports = parse; | ||
parse.parse = parse; | ||
exports = module.exports = parse; | ||
/** | ||
* Parses a "Spotify URI". | ||
* | ||
* @param {String} uri | ||
* @return {Object} parsed Spotify uri object | ||
* @api public | ||
*/ | ||
function parse (uri) { | ||
var parts; | ||
var parsed = url.parse(uri); | ||
var rtn = { uri: uri }; | ||
if ('spotify:' == parsed.protocol) { | ||
parts = uri.split(':'); | ||
parseParts(parts, rtn); | ||
} else if ('embed.spotify.com' == parsed.hostname) { | ||
return parse(qs.parse(parsed.query).uri); | ||
} else { // http: or https: | ||
parts = parsed.pathname.split('/'); | ||
parseParts(parts, rtn); | ||
} | ||
return rtn; | ||
} | ||
function parseParts (parts, obj) { | ||
var len = parts.length; | ||
if (len >= 3 && 'local' == parts[1]) { | ||
// local | ||
obj.type = 'local'; | ||
obj.artist = unencode(parts[2]); | ||
obj.album = unencode(parts[3]); | ||
obj.track = unencode(parts[4]); | ||
obj.seconds = +parts[5]; | ||
} else if (len >= 5) { | ||
// playlist | ||
obj.user = unencode(parts[2]); | ||
obj.type = parts[3]; | ||
obj.id = parts[4]; | ||
} else if (len >= 4 && 'starred' == parts[3]) { | ||
// starred | ||
obj.type = 'playlist'; | ||
obj.starred = true; | ||
obj.user = unencode(parts[2]); | ||
} else if (len >= 3) { | ||
// track, artist, album | ||
obj.type = parts[1]; | ||
obj.id = parts[2]; | ||
} | ||
} | ||
function unencode (str) { | ||
return unescape(str).replace(/\+/g, ' '); | ||
} | ||
exports.parse = parse; | ||
exports.formatURI = formatURI; | ||
exports.formatOpenURL = formatOpenURL; | ||
exports.formatPlayURL = formatPlayURL; | ||
exports.formatEmbedURL = formatEmbedURL; |
{ | ||
"name": "spotify-uri", | ||
"version": "0.0.1", | ||
"description": "Parse the various Spotify URI formats into Objects", | ||
"version": "0.1.0", | ||
"description": "Parse the various Spotify URI formats into Objects and back", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "mocha --reporter spec" | ||
"test": "mocha --reporter spec test/test.js" | ||
}, | ||
@@ -9,0 +9,0 @@ "repository": { |
102
README.md
spotify-uri | ||
=========== | ||
### Parse the various Spotify URI formats into Objects | ||
### Parse the various Spotify URI formats into Objects and back | ||
Spotify URIs get passed around in a variety of flavors. This module parses them | ||
into a JavaScript object so you can work with the further. | ||
into a JavaScript object so you can work with the further. You can also convert | ||
them back into Spotify URIs or HTTP URLs. | ||
@@ -11,2 +12,4 @@ Installation | ||
Install for node.js using `npm`: | ||
``` bash | ||
@@ -16,3 +19,9 @@ $ npm install spotify-uri | ||
Install for component(1) using `component`: | ||
``` bash | ||
$ component install TooTallNate/spotify-uri | ||
``` | ||
Example | ||
@@ -23,6 +32,8 @@ ------- | ||
``` javascript | ||
var parse = require('spotify-uri'); | ||
var parsed; | ||
var spotifyUri = require('spotify-uri'); | ||
var parsed, uri; | ||
parsed = parse('spotify:track:3GU4cxkfdc3lIp9pFEMMmw'); | ||
// parse Spotify URIs or HTTP URLs into JavaScipt metadata Objects: | ||
parsed = spotifyUri.parse('spotify:track:3GU4cxkfdc3lIp9pFEMMmw'); | ||
console.log(parsed); | ||
@@ -33,3 +44,3 @@ // { uri: 'spotify:track:3GU4cxkfdc3lIp9pFEMMmw', | ||
parsed = parse('http://open.spotify.com/track/1pKYYY0dkg23sQQXi0Q5zN'); | ||
parsed = spotifyUri.parse('http://open.spotify.com/track/1pKYYY0dkg23sQQXi0Q5zN'); | ||
console.log(parsed); | ||
@@ -39,4 +50,81 @@ // { uri: 'http://open.spotify.com/track/1pKYYY0dkg23sQQXi0Q5zN', | ||
// id: '1pKYYY0dkg23sQQXi0Q5zN' } | ||
// you can also format the parsed objects back into a URI or HTTP URL: | ||
uri = spotifyUri.formatURI(parsed); | ||
console.log(uri); | ||
// 'spotify:track:1pKYYY0dkg23sQQXi0Q5zN' | ||
uri = spotifyUri.formatOpenURL(parsed); | ||
console.log(uri); | ||
// 'http://open.spotify.com/track/1pKYYY0dkg23sQQXi0Q5zN' | ||
uri = spotifyUri.formatPlayURL(parsed); | ||
console.log(uri); | ||
// 'https://play.spotify.com/track/1pKYYY0dkg23sQQXi0Q5zN' | ||
uri = spotifyUri.formatEmbedURL(parsed); | ||
console.log(uri); | ||
// 'https://embed.spotify.com/?uri=spotify:track:1pKYYY0dkg23sQQXi0Q5zN' | ||
``` | ||
See the `test` directory for some more examples of Spotify URIs. | ||
See the [test cases][tests] for some more examples of Spotify URIs. | ||
## API | ||
### .parse(String uri) → Object | ||
Parses a Spotify URI or a Spotify HTTP(s) URL into an Object. The specific | ||
properties set on the returned Object depend on the "type" of `uri` that gets | ||
passed in. The different "types" are listed below: | ||
### .formatURI(Object parsedUri) → String | ||
Formats a parsed URI Object back into a Spotify URI. For example: | ||
``` js | ||
var parsed = spotifyUri.parse('https://play.spotify.com/track/3GU4cxkfdc3lIp9pFEMMmw'); | ||
var uri = spotifyUri.formatURI(parsed); | ||
console.log(uri); | ||
// 'spotify:track:3GU4cxkfdc3lIp9pFEMMmw' | ||
``` | ||
### .formatOpenURL(Object parsedUri) → String | ||
Formats a parsed URI Object back into a Spotify HTTP "open" URL. For example: | ||
``` js | ||
var parsed = spotifyUri.parse('spotify:track:3c1zC1Ma3987kQcHQfcG0Q'); | ||
var uri = spotifyUri.formatOpenURL(parsed); | ||
console.log(uri); | ||
// 'https://play.spotify.com/track/4Jgp57InfWE4MxJLfheNVz' | ||
``` | ||
### .formatPlayURL(Object parsedUri) → String | ||
Formats a parsed URI Object back into a Spotify HTTPS "play" URL. For example: | ||
``` js | ||
var parsed = spotifyUri.parse('spotify:track:4Jgp57InfWE4MxJLfheNVz'); | ||
var uri = spotifyUri.formatPlayURL(parsed); | ||
console.log(uri); | ||
// 'https://play.spotify.com/track/4Jgp57InfWE4MxJLfheNVz' | ||
``` | ||
### .formatEmbedURL(Object parsedUri) → String | ||
Formats a parsed URI Object back into a Spotify HTTPS "embed" URL. For example: | ||
``` js | ||
var parsed = spotifyUri.parse('spotify:track:6JmI8SpUHoQ4yveHLjTrko'); | ||
var uri = spotifyUri.formatEmbedURL(parsed); | ||
console.log(uri); | ||
// 'https://embed.spotify.com/?uri=spotify:track:6JmI8SpUHoQ4yveHLjTrko' | ||
``` | ||
## License | ||
MIT | ||
[tests]: http://tootallnate.github.io/spotify-uri/ |
238
test/test.js
@@ -7,11 +7,24 @@ | ||
var assert = require('assert'); | ||
var parse = require('../'); | ||
var parse; | ||
describe('HTTP URLs', function () { | ||
describe('open.spotify.com', function () { | ||
try { | ||
// component | ||
parse = require('spotify-uri'); | ||
} catch (e) { | ||
// node.js | ||
parse = require('../'); | ||
} | ||
var formatURI = parse.formatURI; | ||
var formatOpenURL = parse.formatOpenURL; | ||
var formatPlayURL = parse.formatPlayURL; | ||
var formatEmbedURL = parse.formatEmbedURL; | ||
describe('parse()', function () { | ||
describe('"open.spotify.com" URLs', function () { | ||
it('should parse "track" URLs', function () { | ||
var url = 'http://open.spotify.com/track/10M2REwwztVxgr0szw7UwD'; | ||
var obj = parse(url); | ||
assert.equal('track', obj.type); | ||
assert.equal('10M2REwwztVxgr0szw7UwD', obj.id); | ||
assert('track' == obj.type); | ||
assert('10M2REwwztVxgr0szw7UwD' == obj.id); | ||
}); | ||
@@ -21,5 +34,5 @@ it('should parse "playlist" URLs', function () { | ||
var obj = parse(url); | ||
assert.equal('playlist', obj.type); | ||
assert.equal('tootallnate', obj.user); | ||
assert.equal('0Lt5S4hGarhtZmtz7BNTeX', obj.id); | ||
assert('playlist' == obj.type); | ||
assert('tootallnate' == obj.user); | ||
assert('0Lt5S4hGarhtZmtz7BNTeX' == obj.id); | ||
}); | ||
@@ -29,69 +42,198 @@ it('should parse "local" URLs', function () { | ||
var obj = parse(url); | ||
assert.equal('local', obj.type); | ||
assert.equal('Yasunori Mitsuda', obj.artist); | ||
assert.equal('Chrono Trigger OST', obj.album); | ||
assert.equal('A Shot of Crisis', obj.track); | ||
assert.equal(161, obj.seconds); | ||
assert('local' == obj.type); | ||
assert('Yasunori Mitsuda' == obj.artist); | ||
assert('Chrono Trigger OST' == obj.album); | ||
assert('A Shot of Crisis' == obj.track); | ||
assert(161 == obj.seconds); | ||
}); | ||
it('should parse "search" URLs', function () { | ||
var url = 'http://open.spotify.com/search/artist%3ah%c3%a4xor'; | ||
var obj = parse(url); | ||
assert('search' == obj.type); | ||
assert('artist:häxor' == obj.query); | ||
}); | ||
}); | ||
describe('play.spotify.com', function () { | ||
describe('"play.spotify.com" URLs', function () { | ||
it('should parse "track" URLs', function () { | ||
var url = 'https://play.spotify.com/track/5W3cjX2J3tjhG8zb6u0qHn'; | ||
var obj = parse(url); | ||
assert.equal('track', obj.type); | ||
assert.equal('5W3cjX2J3tjhG8zb6u0qHn', obj.id); | ||
assert('track' == obj.type); | ||
assert('5W3cjX2J3tjhG8zb6u0qHn' == obj.id); | ||
}); | ||
}); | ||
describe('embed.spotify.com', function () { | ||
describe('"embed.spotify.com" URLs', function () { | ||
it('should parse "track" URLs', function () { | ||
var url = 'https://embed.spotify.com/?uri=spotify:track:5oscsdDQ0NpjsTgpG4bI8S'; | ||
var obj = parse(url); | ||
assert.equal('track', obj.type); | ||
assert.equal('5oscsdDQ0NpjsTgpG4bI8S', obj.id); | ||
assert('track' == obj.type); | ||
assert('5oscsdDQ0NpjsTgpG4bI8S' == obj.id); | ||
}); | ||
}); | ||
describe('Spotify URIs', function () { | ||
it('should parse "ablum" URIs', function () { | ||
var uri = 'spotify:album:4m2880jivSbbyEGAKfITCa'; | ||
var obj = parse(uri); | ||
assert('album' == obj.type); | ||
assert('4m2880jivSbbyEGAKfITCa' == obj.id); | ||
}); | ||
it('should parse "artist" URIs', function () { | ||
var uri = 'spotify:artist:4tZwfgrHOc3mvqYlEYSvVi'; | ||
var obj = parse(uri); | ||
assert('artist' == obj.type); | ||
assert('4tZwfgrHOc3mvqYlEYSvVi' == obj.id); | ||
}); | ||
it('should parse "track" URIs', function () { | ||
var uri = 'spotify:track:5CMjjywI0eZMixPeqNd75R'; | ||
var obj = parse(uri); | ||
assert('track' == obj.type); | ||
assert('5CMjjywI0eZMixPeqNd75R' == obj.id); | ||
}); | ||
it('should parse "playlist" URIs', function () { | ||
var uri = 'spotify:user:daftpunkofficial:playlist:6jP6EcvAwqNksccDkIe6hX'; | ||
var obj = parse(uri); | ||
assert('playlist' == obj.type); | ||
assert('daftpunkofficial' == obj.user); | ||
assert('6jP6EcvAwqNksccDkIe6hX' == obj.id); | ||
}); | ||
it('should parse "local" track URIs', function () { | ||
var uri = 'spotify:local:Yasunori+Mitsuda:Chrono+Trigger+OST:A+Shot+of+Crisis:161'; | ||
var obj = parse(uri); | ||
assert('local' == obj.type); | ||
assert('Yasunori Mitsuda' == obj.artist); | ||
assert('Chrono Trigger OST' == obj.album); | ||
assert('A Shot of Crisis' == obj.track); | ||
assert(161 === obj.seconds); | ||
}); | ||
it('should parse "lcoal" track URIs 2', function () { | ||
var uri = 'spotify:local:::a:6'; | ||
var obj = parse(uri); | ||
assert('local' == obj.type); | ||
assert('' === obj.artist); | ||
assert('' === obj.album); | ||
assert('a' === obj.track); | ||
assert(6 === obj.seconds); | ||
}); | ||
it('should parse "starred" playlist URIs', function () { | ||
var uri = 'spotify:user:tootallnate:starred'; | ||
var obj = parse(uri); | ||
assert('playlist' == obj.type); | ||
assert('tootallnate' == obj.user); | ||
assert(true == obj.starred); | ||
}); | ||
it('should parse "search" URIs', function () { | ||
var uri = 'spotify:search:artist:h%C3%A4xor'; | ||
var obj = parse(uri); | ||
assert('search' == obj.type); | ||
assert('artist:häxor' == obj.query); | ||
}); | ||
it('should parse combined "search"', function () { | ||
var uri = 'spotify:search:genre:hip-hop+year:1980-1989'; | ||
var obj = parse(uri); | ||
assert('search' == obj.type); | ||
assert('genre:hip-hop year:1980-1989' == obj.query); | ||
}); | ||
}); | ||
}); | ||
describe('Spotify URIs', function () { | ||
it('should parse "ablum" URIs', function () { | ||
var uri = 'spotify:album:4m2880jivSbbyEGAKfITCa'; | ||
describe('formatURI()', function () { | ||
it('should format "artist" open URLs', function () { | ||
var url = 'http://open.spotify.com/artist/1gR0gsQYfi6joyO1dlp76N'; | ||
var obj = parse(url); | ||
var expected = 'spotify:artist:1gR0gsQYfi6joyO1dlp76N'; | ||
var actual = formatURI(obj); | ||
assert(actual == expected); | ||
}); | ||
it('should format "search" query URIs', function () { | ||
var url = 'spotify:search:artist%3aDaft+Punk'; | ||
var obj = parse(url); | ||
var expected = 'spotify:search:artist%3ADaft+Punk'; | ||
var actual = formatURI(obj); | ||
assert(actual == expected); | ||
}); | ||
}); | ||
describe('formatOpenURL()', function () { | ||
it('should format "artist" URIs', function () { | ||
var uri = 'spotify:artist:1gR0gsQYfi6joyO1dlp76N'; | ||
var obj = parse(uri); | ||
assert.equal('album', obj.type); | ||
assert.equal('4m2880jivSbbyEGAKfITCa', obj.id); | ||
var expected = 'http://open.spotify.com/artist/1gR0gsQYfi6joyO1dlp76N'; | ||
var actual = formatOpenURL(obj); | ||
assert(actual == expected); | ||
}); | ||
it('should parse "artist" URIs', function () { | ||
var uri = 'spotify:artist:4tZwfgrHOc3mvqYlEYSvVi'; | ||
it('should format "album" URIs', function () { | ||
var uri = 'spotify:album:7CjakTZxwIF8oixONe6Bpb'; | ||
var obj = parse(uri); | ||
assert.equal('artist', obj.type); | ||
assert.equal('4tZwfgrHOc3mvqYlEYSvVi', obj.id); | ||
var expected = 'http://open.spotify.com/album/7CjakTZxwIF8oixONe6Bpb'; | ||
var actual = formatOpenURL(obj); | ||
assert(actual == expected); | ||
}); | ||
it('should parse "track" URIs', function () { | ||
var uri = 'spotify:track:5CMjjywI0eZMixPeqNd75R'; | ||
it('should format "track" URIs', function () { | ||
var uri = 'spotify:track:4XfokvilxHAOQXfnWD9p0Q'; | ||
var obj = parse(uri); | ||
assert.equal('track', obj.type); | ||
assert.equal('5CMjjywI0eZMixPeqNd75R', obj.id); | ||
var expected = 'http://open.spotify.com/track/4XfokvilxHAOQXfnWD9p0Q'; | ||
var actual = formatOpenURL(obj); | ||
assert(actual == expected); | ||
}); | ||
it('should parse "playlist" URIs', function () { | ||
it('should format "playlist" URIs', function () { | ||
var uri = 'spotify:user:daftpunkofficial:playlist:6jP6EcvAwqNksccDkIe6hX'; | ||
var obj = parse(uri); | ||
assert.equal('playlist', obj.type); | ||
assert.equal('daftpunkofficial', obj.user); | ||
assert.equal('6jP6EcvAwqNksccDkIe6hX', obj.id); | ||
var expected = 'http://open.spotify.com/user/daftpunkofficial/playlist/6jP6EcvAwqNksccDkIe6hX'; | ||
var actual = formatOpenURL(obj); | ||
assert(actual == expected); | ||
}); | ||
it('should parse "local" track URIs', function () { | ||
var uri = 'spotify:local:Yasunori+Mitsuda:Chrono+Trigger+OST:A+Shot+of+Crisis:161'; | ||
it('should format "starred" playlist URIs', function () { | ||
var uri = 'spotify:user:tootallnate:starred'; | ||
var obj = parse(uri); | ||
assert.equal('local', obj.type); | ||
assert.equal('Yasunori Mitsuda', obj.artist); | ||
assert.equal('Chrono Trigger OST', obj.album); | ||
assert.equal('A Shot of Crisis', obj.track); | ||
assert.equal(161, obj.seconds); | ||
var expected = 'http://open.spotify.com/user/tootallnate/starred'; | ||
var actual = formatOpenURL(obj); | ||
assert(actual == expected); | ||
}); | ||
it('should parse "starred" playlist URIs', function () { | ||
var uri = 'spotify:user:tootallnate:starred'; | ||
it('should format "local" URIs', function () { | ||
var uri = 'spotify:local:Yasunori+Mitsuda:Chrono+Trigger+OST+Disc+2:Ayla%27s+Theme:84'; | ||
var obj = parse(uri); | ||
assert.equal('playlist', obj.type); | ||
assert.equal('tootallnate', obj.user); | ||
assert.equal(true, obj.starred); | ||
var expected = 'http://open.spotify.com/local/Yasunori+Mitsuda/Chrono+Trigger+OST+Disc+2/Ayla%27s+Theme/84'; | ||
var actual = formatOpenURL(obj); | ||
assert(actual == expected); | ||
}); | ||
it('should format "local" URIs 2', function () { | ||
var uri = 'spotify:local:::a:6'; | ||
var obj = parse(uri); | ||
var expected = 'http://open.spotify.com/local///a/6'; | ||
var actual = formatOpenURL(obj); | ||
assert(actual == expected); | ||
}); | ||
it('should format "search" URIs', function () { | ||
var uri = 'spotify:search:artist%3aDaft+Punk'; | ||
var obj = parse(uri); | ||
var expected = 'http://open.spotify.com/search/artist%3ADaft+Punk'; | ||
var actual = formatOpenURL(obj); | ||
assert(actual == expected); | ||
}); | ||
}); | ||
describe('formatPlayURL()', function () { | ||
it('should format "track" URIs', function () { | ||
var uri = 'spotify:track:4XfokvilxHAOQXfnWD9p0Q'; | ||
var obj = parse(uri); | ||
var expected = 'https://play.spotify.com/track/4XfokvilxHAOQXfnWD9p0Q'; | ||
var actual = formatPlayURL(obj); | ||
assert(actual == expected); | ||
}); | ||
}); | ||
describe('formatEmbedURL()', function () { | ||
it('should format "track" URIs', function () { | ||
var uri = 'spotify:track:4XfokvilxHAOQXfnWD9p0Q'; | ||
var obj = parse(uri); | ||
var expected = 'https://embed.spotify.com/?uri=spotify:track:4XfokvilxHAOQXfnWD9p0Q'; | ||
var actual = formatEmbedURL(obj); | ||
assert(actual == expected); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
114832
15
4427
126
7
1