├── .gitignore ├── README.md ├── example ├── simple.js └── static │ └── users │ └── 1 │ └── description.txt ├── index.js ├── package.json └── test ├── old-match.js └── paramify.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![development sponsored by voltra.co](https://img.shields.io/badge/Development%20sponsored%20by-Voltra.co-yellow.svg)](https://voltra.co/) 2 | 3 | # SYNOPSIS 4 | Parses urls so you can "route" 5 | 6 | # MOTIVATION 7 | For when you want url parameters but not a big bloated router 8 | 9 | # USAGE 10 | ```js 11 | var fs = require('fs') 12 | var http = require('http') 13 | var paramify = require('paramify') 14 | 15 | http.createServer(function (req, res) { 16 | 17 | var match = paramify(req.url) 18 | res.writeHead(200, {'Content-Type': 'text/plain'}) 19 | 20 | if (match('intro/:greeting')) { 21 | 22 | intro(match.params, res) 23 | } 24 | else if (match('showtimes/:start/:end')) { 25 | 26 | showtimes(match.params, res) 27 | } 28 | else if (match('files/*')) { 29 | 30 | serveFile(match.params, res) 31 | } 32 | 33 | }).listen(1337, '127.0.0.1') 34 | 35 | function intro(params, res) { 36 | 37 | res.end('Greeting was "' + params.greeting + '"\n') 38 | } 39 | 40 | function showtimes(params, res) { 41 | 42 | var message = [ 43 | 'Show starts at', params.start, 44 | 'and ends at', params.end 45 | ].join(' ') + '\n' 46 | 47 | res.end(message) 48 | } 49 | 50 | function serveFile(params, res) { 51 | // match.params contains numeric keys for any 52 | // path components matched with * 53 | fs.createReadStream(__dirname + '/static/' + params[0]).pipe(res) 54 | } 55 | 56 | 57 | console.log('Server running at http://127.0.0.1:1337/') 58 | ``` 59 | 60 | Given the following url 61 | ``` 62 | http://localhost:1337/showtimes/10:00AM/8:30PM 63 | ``` 64 | 65 | The server would respond with 66 | ``` 67 | Show starts at 10:00AM and ends at 8:30PM 68 | ``` 69 | 70 | Given the following url 71 | ``` 72 | http://localhost:1337/intro/Hello%20world! 73 | ``` 74 | 75 | The server would respond with 76 | ``` 77 | Greeting was "Hello world!" 78 | ``` 79 | 80 | Given the following url 81 | ``` 82 | http://localhost:1337/files/users/1/description.txt 83 | ``` 84 | 85 | The server would respond with the contents of `static/users/1/description.txt`. 86 | -------------------------------------------------------------------------------- /example/simple.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs') 2 | var http = require('http') 3 | var paramify = require('../') 4 | 5 | http.createServer(function (req, res) { 6 | 7 | var match = paramify(req.url) 8 | res.writeHead(200, {'Content-Type': 'text/plain'}) 9 | 10 | if (match('intro/:greeting')) { 11 | 12 | intro(match.params, res) 13 | } 14 | else if (match('showtimes/:start/:end')) { 15 | 16 | showtimes(match.params, res) 17 | } 18 | else if (match('files/*')) { 19 | 20 | serveFile(match.params, res) 21 | } 22 | 23 | }).listen(1337, '127.0.0.1') 24 | 25 | function intro(params, res) { 26 | 27 | res.end('Greeting was "' + params.greeting + '"\n') 28 | } 29 | 30 | function showtimes(params, res) { 31 | 32 | var message = [ 33 | 'Show starts at', params.start, 34 | 'and ends at', params.end 35 | ].join(' ') + '\n' 36 | 37 | res.end(message) 38 | } 39 | 40 | function serveFile(params, res) { 41 | // match.params contains numeric keys for any 42 | // path components matched with * 43 | fs.createReadStream(__dirname + '/static/' + params[0]).pipe(res) 44 | } 45 | 46 | console.log('Server running at http://127.0.0.1:1337/') 47 | -------------------------------------------------------------------------------- /example/static/users/1/description.txt: -------------------------------------------------------------------------------- 1 | A DESCRIPTION. 2 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 2 | var pathToRegexp = require('path-to-regexp') 3 | var cache = {} 4 | 5 | function regify(vurl) { 6 | var re = vurl instanceof RegExp 7 | var key = re ? '$$' + vurl.source : vurl 8 | 9 | if (cache[key]) { 10 | return cache[key] 11 | } 12 | 13 | if (!re && vurl.charAt(0) != '/') { 14 | vurl = '/' + vurl 15 | } 16 | 17 | var reg = cache[key] = {} 18 | reg.keys = [] 19 | reg.exp = pathToRegexp(vurl, reg.keys) 20 | 21 | return reg 22 | } 23 | 24 | function paramify(url) { 25 | try { url = decodeURI(url) } catch($) {} 26 | try { url = decodeURIComponent(url) } catch($) {} 27 | 28 | function match (vurl) { 29 | 30 | var reg = regify(vurl) 31 | var matches = url.match(reg.exp) 32 | 33 | if (!matches) { 34 | return false 35 | } 36 | 37 | var params = [] 38 | 39 | for (var i = 1; i < matches.length; i++) { 40 | var key = reg.keys[i - 1] 41 | if (key) { 42 | params[key.name] = matches[i] 43 | } else { 44 | params.push(matches[i]) 45 | } 46 | } 47 | 48 | match.params = params 49 | 50 | return true 51 | } 52 | 53 | match.match = match 54 | return match 55 | } 56 | 57 | module.exports = paramify 58 | 59 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "paramify", 3 | "version": "0.1.2", 4 | "description": "Parameterized routes without a big bloated router, e.g. 'showtimes/:start/:end' and 'files/*'", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "tape test/*.js" 8 | }, 9 | "repository": { 10 | "url": "git://github.com/hij1nx/paramify.git" 11 | }, 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "tape": "~1.0.4" 16 | }, 17 | "dependencies": { 18 | "path-to-regexp": "0.0.2" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/old-match.js: -------------------------------------------------------------------------------- 1 | 2 | var paramify = require('..') 3 | var test = require('tape') 4 | 5 | test('old match', function (t) { 6 | t.plan(1) 7 | 8 | var match = paramify('/intro/:greeting') 9 | match('intro/ohai') 10 | t.equals(match, match.match) 11 | }) 12 | -------------------------------------------------------------------------------- /test/paramify.js: -------------------------------------------------------------------------------- 1 | var paramify = require('..') 2 | var test = require('tape') 3 | 4 | test('single named param', function (t) { 5 | t.plan(2) 6 | 7 | var match = paramify('/intro/ohai') 8 | t.assert(match('intro/:greeting')) 9 | t.equal(match.params.greeting, 'ohai') 10 | }) 11 | 12 | 13 | test('multiple named params', function (t) { 14 | t.plan(3) 15 | 16 | var match = paramify('/showtimes/1337/7331') 17 | t.assert(match('showtimes/:start/:end')) 18 | t.equal(match.params.start, '1337') 19 | t.equal(match.params.end, '7331') 20 | }) 21 | 22 | test('globbing matches', function (t) { 23 | t.plan(3) 24 | 25 | var match = paramify('/files/mydir/path/to/file.txt') 26 | t.assert(match('/files/:root/*')) 27 | t.equal(match.params.root, 'mydir') 28 | t.equal(match.params[0], 'path/to/file.txt') 29 | }) 30 | 31 | test('regex matches', function (t) { 32 | t.plan(3) 33 | 34 | var match = paramify('/files/mydir/path/to/file.txt') 35 | t.assert(match(/^\/files(\/.*)?/)) 36 | 37 | match = paramify('/files') 38 | t.assert(match(/^\/files(\/.*)?/)) 39 | 40 | match = paramify('/file') 41 | t.assert(!match(/^\/files(\/.*)?/)) 42 | }) 43 | 44 | test('regex fail to match', function (t) { 45 | t.plan(2) 46 | 47 | var match = paramify('/profile') 48 | t.assert(!match(/^\/xprofile/)) 49 | 50 | match = paramify('/@username') 51 | t.assert(!match(/^\/(xprofile|@#(.*?))/)) 52 | }) 53 | 54 | test('encoded paths', function(t) { 55 | t.plan(3) 56 | 57 | var match = paramify('/@example%2ftest') 58 | t.assert(match('/@:first/:second')) 59 | t.equal(match.params.first, 'example') 60 | t.equal(match.params.second, 'test') 61 | }) 62 | --------------------------------------------------------------------------------