From 96f0b23c145fcd8f405de9de4ee67e426afae24b Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Sun, 20 Mar 2016 19:20:21 +0100 Subject: [PATCH 01/20] 4.0 query fragment support --- README.md | 28 ++++++++++++++-------------- package.json | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 468cd0b..8e47b0c 100644 --- a/README.md +++ b/README.md @@ -16,21 +16,21 @@ var Parth = require('parth'); var parth = new Parth(); var props = {handle: function(){}}; -parth.set('(get|post) /:page(\\w+)/:view([^./]+)', props) +parth.set('get /:page/:view', props) .get('post /user/page/photo?query#hash') // => { + path: 'get /:page/:view', + stem: 'get /:page/:view:queryFragment(\\/?[?#][^/\\s]+)?', + depth: 2, + regex: /^get \/([^?#.\/\s]+)\/([^?#.\/\s]+)(\/?[?#][^\/\s]+)?/, + match: 'get /weekend/baby?query=string#hash', handle: [Function], - path: 'post /user/page/photo', - stem: ':0(get|post) /:page(\\w+)/:view([^./]+)', - regex: /^(get|post) \/(\w+)\/([^./]+)/, - depth: 3, - notFound: '/photo', + notFound: ' user.10.beers now', params: { - '0': 'post', - _: [ '0', 'page', 'view' ], - page: 'user', - view: 'page' + page: 'weekend', + view: 'baby', + queryFragment: '?query=string#hash' } } ``` @@ -93,15 +93,15 @@ _return_ > All matches are partial i.e. /^regex baby/. > Not being strict is useful for `notFound` paths. - +> > NOTE: the returned object is a deep copy of the original `options` > given in `parth.set` to avoid mutation ### parth properties - - `store`: all paths set for match are here - - `regex`: array of carefully ordered regexes - - `regex.master`: regex aggregating all learned + - `parth.store`: all paths set for match are here + - `parth.regex`: array of carefully ordered regexes + - `parth.regex.master`: regex aggregating all learned ## why diff --git a/package.json b/package.json index af13dee..be55629 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "parth", "main": "index.js", - "version": "3.3.0", + "version": "4.0.0", "engines": { "node": ">= 0.10.0" }, From 0e9b55ebf2446e7b2e7a9c1afd360a43ae2f5b23 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Sun, 20 Mar 2016 19:23:57 +0100 Subject: [PATCH 02/20] more useful example --- README.md | 8 ++++---- readme.md | 30 +++++++++++++++--------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 8e47b0c..5072ec1 100644 --- a/README.md +++ b/README.md @@ -16,14 +16,14 @@ var Parth = require('parth'); var parth = new Parth(); var props = {handle: function(){}}; -parth.set('get /:page/:view', props) - .get('post /user/page/photo?query#hash') +parth.set('(get|post) /:page/:view', props) + .get('get /weekend/baby?query=string#hash user.10.beers now') // => { path: 'get /:page/:view', - stem: 'get /:page/:view:queryFragment(\\/?[?#][^/\\s]+)?', + stem: ':0(get|post) /:page/:view:queryFragment(\\/?[?#][^/\\s]+)?', depth: 2, - regex: /^get \/([^?#.\/\s]+)\/([^?#.\/\s]+)(\/?[?#][^\/\s]+)?/, + regex: /^(get|post) \/([^?#.\/\s]+)\/([^?#.\/\s]+)(\/?[?#][^\/\s]+)?/, match: 'get /weekend/baby?query=string#hash', handle: [Function], notFound: ' user.10.beers now', diff --git a/readme.md b/readme.md index 468cd0b..5072ec1 100644 --- a/readme.md +++ b/readme.md @@ -16,21 +16,21 @@ var Parth = require('parth'); var parth = new Parth(); var props = {handle: function(){}}; -parth.set('(get|post) /:page(\\w+)/:view([^./]+)', props) - .get('post /user/page/photo?query#hash') +parth.set('(get|post) /:page/:view', props) + .get('get /weekend/baby?query=string#hash user.10.beers now') // => { + path: 'get /:page/:view', + stem: ':0(get|post) /:page/:view:queryFragment(\\/?[?#][^/\\s]+)?', + depth: 2, + regex: /^(get|post) \/([^?#.\/\s]+)\/([^?#.\/\s]+)(\/?[?#][^\/\s]+)?/, + match: 'get /weekend/baby?query=string#hash', handle: [Function], - path: 'post /user/page/photo', - stem: ':0(get|post) /:page(\\w+)/:view([^./]+)', - regex: /^(get|post) \/(\w+)\/([^./]+)/, - depth: 3, - notFound: '/photo', + notFound: ' user.10.beers now', params: { - '0': 'post', - _: [ '0', 'page', 'view' ], - page: 'user', - view: 'page' + page: 'weekend', + view: 'baby', + queryFragment: '?query=string#hash' } } ``` @@ -93,15 +93,15 @@ _return_ > All matches are partial i.e. /^regex baby/. > Not being strict is useful for `notFound` paths. - +> > NOTE: the returned object is a deep copy of the original `options` > given in `parth.set` to avoid mutation ### parth properties - - `store`: all paths set for match are here - - `regex`: array of carefully ordered regexes - - `regex.master`: regex aggregating all learned + - `parth.store`: all paths set for match are here + - `parth.regex`: array of carefully ordered regexes + - `parth.regex.master`: regex aggregating all learned ## why From 0eaaeeeefcf636d1f2efe03640dbd4484da7832a Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Sun, 20 Mar 2016 19:27:00 +0100 Subject: [PATCH 03/20] remove cached readme.md --- readme.md | 165 ------------------------------------------------------ 1 file changed, 165 deletions(-) delete mode 100644 readme.md diff --git a/readme.md b/readme.md deleted file mode 100644 index 5072ec1..0000000 --- a/readme.md +++ /dev/null @@ -1,165 +0,0 @@ -# parth [![NPM version][badge-version]][x-npm] [![downloads][badge-downloads]][x-npm] - -[documentation](#documentation) - -[examples](#examples) - -[install](#install) - -[todo](#todo) - -[why](#why) - -[![build][badge-build]][x-travis] - -## sample - -```js -var Parth = require('parth'); - -var parth = new Parth(); -var props = {handle: function(){}}; - -parth.set('(get|post) /:page/:view', props) - .get('get /weekend/baby?query=string#hash user.10.beers now') -// => -{ - path: 'get /:page/:view', - stem: ':0(get|post) /:page/:view:queryFragment(\\/?[?#][^/\\s]+)?', - depth: 2, - regex: /^(get|post) \/([^?#.\/\s]+)\/([^?#.\/\s]+)(\/?[?#][^\/\s]+)?/, - match: 'get /weekend/baby?query=string#hash', - handle: [Function], - notFound: ' user.10.beers now', - params: { - page: 'weekend', - view: 'baby', - queryFragment: '?query=string#hash' - } -} -``` - -## documentation - -The `module.exports` a `Parth` constructor - -````js -var Parth = require('parth'); -```` - -which takes no arguments -```js -var parth = new Parth(); -``` - -## parth.set - -```js -function set(string path[, object options]) -``` -This method purpose is to sanitize the `path` given -and classify the resulting regular expression with those -previously stored. - -_arguments_ - - `path`, type `string`, path to be set - - `options`, type `object`, to merge with this path properties - -_returns_ `this` - -> NOTE: `options` is deep cloned beforehand to avoid mutation - -`path` can contain any number of parameters(regexes) in the form -```js - :param-label(\\regexp(?:here)) -``` -Any string matching the regular expression below qualifies as a parameter - -````js -/:([-\w]+)(\([^\s]+?[)][?)]*)?/g; -```` - -[Go to http://regexr.com/](http://regexr.com/3cuqq) and test it out. - -## parth.get -```js -function get(string path) -``` - -Take a string and return a clone of the store object properties - -_arguments_ - - `path`, type `string` to match stored paths with - -_return_ - - null for non-supported types or not matching paths - - object with all the information stored in `parth.set` - -> All matches are partial i.e. /^regex baby/. -> Not being strict is useful for `notFound` paths. -> -> NOTE: the returned object is a deep copy of the original `options` -> given in `parth.set` to avoid mutation - -### parth properties - - - `parth.store`: all paths set for match are here - - `parth.regex`: array of carefully ordered regexes - - `parth.regex.master`: regex aggregating all learned - -## why - -I need it for the [gulp-runtime](https://github.com/stringparser/gulp-runtime) module. - -## install - -With [npm](http://npmjs.org) - - npm install --save parth - -### examples - -Run the [`example.js`](example.js) file. - -### test - - npm test - -``` -➜ parth (master) ✓ npm t -parth - paths - ✓ object - ✓ raw object paths - ✓ unix paths - ✓ raw unix paths - ✓ urls - ✓ raw urls - ✓ urls: querystring is stripped - ✓ urls: hash is stripped - ✓ urls: parameters are not mistaken as querystrings - ✓ space separated paths - ✓ raw, space separated paths - ✓ unix, object and url paths together - ✓ raw: unix, object and urls paths together - params - ✓ can be given as a string regex - ✓ will contain all parameter keys at _ - ✓ parameter values should be at params - notFound - ✓ should be false for perfect match - ✓ should have what is left of the path - - -18 passing (16ms) -``` - -### todo - - - [ ] set support for regexp input - -### license - -![LICENSE](http://img.shields.io/npm/l/parth.svg?style=flat-square) - -[x-npm]: https://npmjs.org/package/parth -[x-travis]: https://travis-ci.org/stringparser/parth/builds -[badge-build]: http://img.shields.io/travis/stringparser/parth/master.svg?style=flat-square -[badge-version]: http://img.shields.io/npm/v/parth.svg?style=flat-square -[badge-downloads]: http://img.shields.io/npm/dm/parth.svg?style=flat-square From 6fbaf5683daa52ffbdd5335d6bcc227586ff7621 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Sun, 20 Mar 2016 19:27:43 +0100 Subject: [PATCH 04/20] 4.0.1 - remove cached readme.md --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index be55629..fdd2033 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "parth", "main": "index.js", - "version": "4.0.0", + "version": "4.0.1", "engines": { "node": ">= 0.10.0" }, From aaf3d2b0d3fda8643a10fdb82d8c8038b8d2437e Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Wed, 11 May 2016 21:29:36 +0200 Subject: [PATCH 05/20] v4.1.0 - fix false positives return null --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fdd2033..a54e168 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "parth", "main": "index.js", - "version": "4.0.1", + "version": "4.1.0", "engines": { "node": ">= 0.10.0" }, From 145a85c0a27895f0a84df7db067592308e9d66e1 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Sun, 26 Jun 2016 11:24:43 +0200 Subject: [PATCH 06/20] lint: jshint -> eslint --- .eslintrc | 23 +++++++++++++++++++++++ .jshintrc | 21 --------------------- package.json | 4 ++-- 3 files changed, 25 insertions(+), 23 deletions(-) create mode 100644 .eslintrc delete mode 100644 .jshintrc diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..ebfe143 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,23 @@ +{ + "env": { + "node": true, + "mocha": true + }, + "rules": { + "strict": 2, + "quotes": [2, "single", "avoid-escape"], + "indent": ["error", 2, {"SwitchCase": 1}], + "eol-last": 2, + "no-shadow": 2, + "dot-notation": 2, + "dot-location": [2, "property"], + "comma-dangle": [2, "never"], + "no-unused-vars": 2, + "no-multi-spaces": 2, + "no-process-exit": 0, + "consistent-return": 2, + "no-use-before-define": 0, + "no-underscore-dangle": 0, + "no-unused-expressions": 2 + } +} diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 26fd393..0000000 --- a/.jshintrc +++ /dev/null @@ -1,21 +0,0 @@ -{ - "camelcase": true, - "curly": true, - "eqeqeq": true, - "freeze": true, - "indent": 2, - "newcap": false, - "quotmark": "single", - "maxdepth": 3, - "maxstatements": 50, - "maxlen": 100, - "eqnull": true, - "funcscope": true, - "strict": true, - "globalstrict": true, - "undef": true, - "unused": true, - "node": true, - "mocha" : true, - "laxbreak": true -} diff --git a/package.json b/package.json index a54e168..16f02b1 100644 --- a/package.json +++ b/package.json @@ -17,13 +17,13 @@ "url": "https://github.com/stringparser/parth/issues" }, "scripts": { - "lint": "jshint lib *.js", + "lint": "eslint lib *.js", "test": "npm run lint && mocha test" }, "devDependencies": { "mocha": "*", "should": "*", - "jshint": "*" + "eslint": "*" }, "keywords": [ "url", From 9e559369411d78e8a314d06a11013b79844e8120 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Sun, 26 Jun 2016 11:27:26 +0200 Subject: [PATCH 07/20] dev: be able to give param regexes as a parameter to the constructor --- index.js | 84 +++++++++++++++++--------------------------------------- 1 file changed, 25 insertions(+), 59 deletions(-) diff --git a/index.js b/index.js index a262ff7..4a4ff03 100644 --- a/index.js +++ b/index.js @@ -4,42 +4,31 @@ var util = require('./lib/util'); exports = module.exports = Parth; -function Parth(){ +function Parth(options){ if(!(this instanceof Parth)){ return new Parth(); } - this.regex = []; this.store = {}; - this.regex.master = new RegExp('(?:[])'); -} - - -/** -## parth.set -```js -function set(string path[, object options]) -``` -This method purpose is to sanitize the `path` given -and classify the resulting regular expression with those -previously stored. + this.regex = []; -arguments - - path, type `string` - - options, type `object`, to merge with this path properties + this.regex.param = /:([-\w]+)(\([^\s]+?[)][?)]*)?/g; + this.regex.master = new RegExp('(?:[])'); + this.regex.noParam = /(^|[/.=\s]+)(\(.+?\)+)/g; -returns `this` + if(options){ + this.regex.param = options.paramsRE || this.regex.param; + this.regex.noParam = options.noParamRE || this.regex.noParamRE; + } +} -> NOTE: `options` is deep cloned beforehand to avoid mutation -**/ var qsRE = /(\/?[?#][^!=:][^\s]+)/g; var depthRE = /((^|[/?#.\s]+)[(:\w])/g; -var paramRE = /:([-\w]+)(\([^\s]+?[)][?)]*)?/g; -var noParamRE = /(^|[/.=\s]+)(\(.+?\)+)/g; Parth.prototype.set = function(path, opt){ + var self = this; if(typeof path !== 'string'){ - return this; + return self; } var o = util.clone(opt || {}, true); @@ -52,7 +41,7 @@ Parth.prototype.set = function(path, opt){ this.store[o.path] = o; var index = -1; - o.stem = o.path.replace(noParamRE, function($0, $1, $2){ + o.stem = o.path.replace(this.regex.noParam, function($0, $1, $2){ return $1 + ':' + (++index) + $2; }); @@ -68,7 +57,7 @@ Parth.prototype.set = function(path, opt){ o.regex = new RegExp('^' + o.stem.replace(/\S+/g, function(s){ - return s.replace(paramRE, function($0, $1, $2){ + return s.replace(self.regex.param, function($0, $1, $2){ return ($2 || '([^?#./\\s]+)'); }); }).replace(/[^?( )+*$]+(?=\(|$)/g, function escapeRegExp($0){ @@ -76,20 +65,15 @@ Parth.prototype.set = function(path, opt){ }) ); - /** order regexes according to - * - depth (number of separation tokens - * - if that fails, use localCompare - **/ + // order regexes according to depth (# of separation tokes) or, + // if that fails, use localCompare this.regex.push(o); this.regex.sort(function(x, y){ return (y.depth - x.depth) || y.stem.localeCompare(x.stem); }); - /** sum up all learned - * - void all groups - * - make a giant regex - **/ + // sum up all learned (void all groups and make a giant regex) this.regex.master = new RegExp( '(' + this.regex.map(function voidRegExp(el){ return el.regex.source.replace(/\((?=[^?])/g, '(?:'); @@ -99,26 +83,6 @@ Parth.prototype.set = function(path, opt){ return this; }; - -/** -## parth.get -```js -function get(string path) -``` - -Take a string, and return a clone of the store object properties - -arguments - - path, type `string` to match stored paths with - -return - - null for non-supported types or not matching path - - object with all the stored information on `parth.set` - -> NOTE: the returned object is a deep copy of the original `options` -> given in `parth.set` to avoid mutation -**/ - Parth.prototype.get = function(path){ if(typeof path !== 'string'){ return null; @@ -135,17 +99,19 @@ Parth.prototype.get = function(path){ var found = this.regex.master.exec(path); if(!found){ return null; } - var o = {}; - o.match = found.shift(); - o.notFound = path.slice(o.match.length); + var o = { + match: found.shift(), + params: {} + }; found = this.regex[found.indexOf(o.match)]; - var params = found.regex.exec(path).slice(1); - if(params.length){ o.params = {}; } + o.notFound = path.slice(o.match.length); var index = -1; - found.stem.replace(paramRE, function($0, $1){ + var params = found.regex.exec(path).slice(1); + + found.stem.replace(this.regex.param, function($0, $1){ o.params[$1] = params[++index]; }); From ca0d2dcc61e25fdb6968c0df26d5738f478db648 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Sun, 26 Jun 2016 11:38:12 +0200 Subject: [PATCH 08/20] dev: actually just the default regex is necessary --- index.js | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/index.js b/index.js index 4a4ff03..6fd22f1 100644 --- a/index.js +++ b/index.js @@ -11,24 +11,22 @@ function Parth(options){ this.store = {}; this.regex = []; - - this.regex.param = /:([-\w]+)(\([^\s]+?[)][?)]*)?/g; this.regex.master = new RegExp('(?:[])'); - this.regex.noParam = /(^|[/.=\s]+)(\(.+?\)+)/g; + this.regex.default = /[^?#./\s]+/; if(options){ - this.regex.param = options.paramsRE || this.regex.param; - this.regex.noParam = options.noParamRE || this.regex.noParamRE; + this.regex.default = options.defaultRE || this.regex.default; } } var qsRE = /(\/?[?#][^!=:][^\s]+)/g; var depthRE = /((^|[/?#.\s]+)[(:\w])/g; +var paramRE = /:([-\w]+)(\([^\s]+?[)][?)]*)?/g; +var noParamRE = /(^|[/.=\s]+)(\(.+?\)+)/g Parth.prototype.set = function(path, opt){ - var self = this; if(typeof path !== 'string'){ - return self; + return this; } var o = util.clone(opt || {}, true); @@ -41,11 +39,12 @@ Parth.prototype.set = function(path, opt){ this.store[o.path] = o; var index = -1; - o.stem = o.path.replace(this.regex.noParam, function($0, $1, $2){ + o.stem = o.path.replace(noParamRE, function($0, $1, $2){ return $1 + ':' + (++index) + $2; }); var url = (o.stem.match(/[^\/\s]*\/\S*/) || [null]).pop(); + var defaultRE = '(' + this.regex.default.source + ')'; if(url){ var qsh = (url.match(qsRE) || [':queryFragment(\\/?[?#][^/\\s]+)?']).pop(); @@ -57,8 +56,8 @@ Parth.prototype.set = function(path, opt){ o.regex = new RegExp('^' + o.stem.replace(/\S+/g, function(s){ - return s.replace(self.regex.param, function($0, $1, $2){ - return ($2 || '([^?#./\\s]+)'); + return s.replace(paramRE, function($0, $1, $2){ + return ($2 || defaultRE); }); }).replace(/[^?( )+*$]+(?=\(|$)/g, function escapeRegExp($0){ return $0.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&'); @@ -111,7 +110,7 @@ Parth.prototype.get = function(path){ var index = -1; var params = found.regex.exec(path).slice(1); - found.stem.replace(this.regex.param, function($0, $1){ + found.stem.replace(paramRE, function($0, $1){ o.params[$1] = params[++index]; }); From 0053723cda875f1e3e8d54cb2e847cd6a7c10e9e Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Sun, 26 Jun 2016 14:08:30 +0200 Subject: [PATCH 09/20] docs: update license --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 32c5601..9b039d2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2014-2015 Javier Carrillo +Copyright (c) 2014-2016 Javier Carrillo Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 8b4862645efcdf8ddfbd03991057e6cf93139fed Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Sun, 26 Jun 2016 14:08:40 +0200 Subject: [PATCH 10/20] docs: update readme --- README.md | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5072ec1..9dc91ce 100644 --- a/README.md +++ b/README.md @@ -43,19 +43,46 @@ The `module.exports` a `Parth` constructor var Parth = require('parth'); ```` -which takes no arguments +which can take the options below + ```js -var parth = new Parth(); +var parth = new Parth(options); +``` + +_options_ type `object`, can be + - `options.defaultRE` default `regex` used if none is given after the params + +example: + +```js +var parth = new Parth({ defaultRE: /[^\s\/?#]+/ }); + +parth.set('/page/:view') // no regex given after ":view" + .get('/page/10/?query=here') +// => +{ + path: '/page/:view/', + stem: '/page/:view:qs(?:\\/?)([?#][^\\/\\s]*)?', + depth: 2, + regex: /^\/page\/([^\s\/?#]+)(?:\/?)([?#][^\/\s]*)?/, + match: '/page/10/?query=here', + params: { + view: '10', + qs: '?query=here' + }, + notFound: '' +} ``` +> NOTE: the query string is separated by default and assigned to `qs`. +> This will only happen if the path given to `parth.set` has no query string + ## parth.set ```js function set(string path[, object options]) ``` -This method purpose is to sanitize the `path` given -and classify the resulting regular expression with those -previously stored. +This method job is to sanitize `path` and order it with those previously stored. _arguments_ - `path`, type `string`, path to be set From 73cb1a1450e04262aad30dd9d5356ff130d82a50 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Sun, 26 Jun 2016 14:12:41 +0200 Subject: [PATCH 11/20] tests: update tests for next_release --- test/notFound.js | 2 +- test/params.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/test/notFound.js b/test/notFound.js index 959885b..067dfe5 100644 --- a/test/notFound.js +++ b/test/notFound.js @@ -19,6 +19,6 @@ module.exports = function(Parth){ path = 'get /hello/awesome/human'; result = parth.set(stems).get(path); result.should.not.be.eql(null); - result.notFound.should.be.eql('/human'); + result.notFound.should.be.eql('human'); }); }; diff --git a/test/params.js b/test/params.js index 1ab0321..54e4871 100644 --- a/test/params.js +++ b/test/params.js @@ -38,7 +38,7 @@ module.exports = function(Parth){ '0': 'post', you: '10', there: 'awesome', - queryFragment: '?query=string#here' + qs: '?query=string#here' } }); }); @@ -47,6 +47,7 @@ module.exports = function(Parth){ stem = 'post /:page\\/?:query(\\?[^/#\\s]+)?:fragment(#[^?\\s]+)?'; path = 'post /page?query=here#hash'; result = parth.set(stem).get(path); + result.should.have.properties({ params: { page: 'page', From 4be75adc798f3c99ede855a8cb99e0ad110bb428 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Sun, 26 Jun 2016 14:13:08 +0200 Subject: [PATCH 12/20] dev: added a function to get the query strings properly --- lib/util.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/util.js b/lib/util.js index 1aeb85a..9438bb9 100644 --- a/lib/util.js +++ b/lib/util.js @@ -6,3 +6,17 @@ exports = module.exports = {}; // exports.clone = require('lodash.clone'); exports.merge = require('lodash.merge'); + +// assorted +// +exports.getQueryString = function(url){ + if(!url){ return null; } + + var index = url.indexOf('?'); + + if(index > -1 && url.charAt(index + 1) !== ':'){ + return url.substring(index); + } else { + return null; + } +}; From 46d028025701f7bfb8ff16be316462c25a6856e1 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Sun, 26 Jun 2016 14:14:09 +0200 Subject: [PATCH 13/20] dev: be able to use a different default regex for parameters; improve query string matching, change long name for just qs --- index.js | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/index.js b/index.js index 6fd22f1..fd35695 100644 --- a/index.js +++ b/index.js @@ -6,20 +6,20 @@ exports = module.exports = Parth; function Parth(options){ if(!(this instanceof Parth)){ - return new Parth(); + return new Parth(options); } this.store = {}; this.regex = []; this.regex.master = new RegExp('(?:[])'); - this.regex.default = /[^?#./\s]+/; + this.regex.defaultRE = /[^?#./\s]+/; if(options){ - this.regex.default = options.defaultRE || this.regex.default; + this.regex.defaultRE = options.defaultRE || this.regex.defaultRE; } } -var qsRE = /(\/?[?#][^!=:][^\s]+)/g; +var qshRE = /[?#][^\/\s]*/g; var depthRE = /((^|[/?#.\s]+)[(:\w])/g; var paramRE = /:([-\w]+)(\([^\s]+?[)][?)]*)?/g; var noParamRE = /(^|[/.=\s]+)(\(.+?\)+)/g @@ -36,24 +36,25 @@ Parth.prototype.set = function(path, opt){ util.merge(this.store[o.path], o); return this; } - this.store[o.path] = o; + this.regex.push(this.store[o.path] = o); var index = -1; + var defaultRE = '(' + this.regex.defaultRE.source + ')'; + o.stem = o.path.replace(noParamRE, function($0, $1, $2){ return $1 + ':' + (++index) + $2; }); - var url = (o.stem.match(/[^\/\s]*\/\S*/) || [null]).pop(); - var defaultRE = '(' + this.regex.default.source + ')'; + var url = (o.stem.match(/[^\s]*\/\S*/) || [null]).pop(); + var qsh = util.getQueryString(url); - if(url){ - var qsh = (url.match(qsRE) || [':queryFragment(\\/?[?#][^/\\s]+)?']).pop(); - o.stem = o.stem.replace(url, url.replace(qsRE, '') + qsh); + if(url && !qsh){ + o.stem = o.stem.replace(url, url.replace(/\/$/, '$1') + + ':qs(?:\\/)?(' + qshRE.source + ')?' + ); } - o.depth = -1; - o.stem.replace(depthRE, function(){ ++o.depth; }); - + o.depth = o.stem.split(depthRE).length || -1; o.regex = new RegExp('^' + o.stem.replace(/\S+/g, function(s){ return s.replace(paramRE, function($0, $1, $2){ @@ -67,7 +68,6 @@ Parth.prototype.set = function(path, opt){ // order regexes according to depth (# of separation tokes) or, // if that fails, use localCompare - this.regex.push(o); this.regex.sort(function(x, y){ return (y.depth - x.depth) || y.stem.localeCompare(x.stem); }); @@ -99,10 +99,7 @@ Parth.prototype.get = function(path){ var found = this.regex.master.exec(path); if(!found){ return null; } - var o = { - match: found.shift(), - params: {} - }; + var o = {match: found.shift(), params: {}}; found = this.regex[found.indexOf(o.match)]; o.notFound = path.slice(o.match.length); From 7e0a24cb625df51fe1229b65036ab496472d4f54 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Sun, 26 Jun 2016 14:22:30 +0200 Subject: [PATCH 14/20] test: add test for constructor options --- test/index.js | 1 + test/options.js | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 test/options.js diff --git a/test/index.js b/test/index.js index 4bef9d9..2a4c3b1 100644 --- a/test/index.js +++ b/test/index.js @@ -8,6 +8,7 @@ require('should'); [ 'paths.js', 'params.js', + 'options.js', 'notFound.js' ].forEach(function(file){ if(file === 'index.js'){ return; } diff --git a/test/options.js b/test/options.js new file mode 100644 index 0000000..f8fab6e --- /dev/null +++ b/test/options.js @@ -0,0 +1,19 @@ +'use strict'; + +var path, stems, result; + +module.exports = function(Parth){ + + it('default regex can be changed using options', function(){ + var parth = new Parth({ + defaultRE: /\S+/ + }); + + stems = 'do :src :dest'; + path = 'do /src/**/*.js /dest/'; + + result = parth.set(stems).get(path); + result.notFound.should.be.eql(''); + result.regex.source.should.match(/[\\]+S\+/); + }); +}; From 5d63f914efd23c951487092d83166868790aa8c2 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Sun, 26 Jun 2016 14:24:43 +0200 Subject: [PATCH 15/20] v4.2.0 - improved qs regex, be able to change default regex - qs is handled a bit better now, more restrictive but better - the constructor function accepts an `defaultRE` parameter which will be the default regular expression used if the parameter did not have one defined with it --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 16f02b1..17855c4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "parth", "main": "index.js", - "version": "4.1.0", + "version": "4.2.0", "engines": { "node": ">= 0.10.0" }, From 32586c9f151aaa0d8b1f3191c09399f7cf6f6ee4 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Sun, 26 Jun 2016 16:36:21 +0200 Subject: [PATCH 16/20] fix: README.md inconsistency --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9dc91ce..2b1d488 100644 --- a/README.md +++ b/README.md @@ -21,16 +21,16 @@ parth.set('(get|post) /:page/:view', props) // => { path: 'get /:page/:view', - stem: ':0(get|post) /:page/:view:queryFragment(\\/?[?#][^/\\s]+)?', + stem: ':0(get|post) /:page/:view:qs(?:\\/?)?([?#][^\\/\s]*)?', depth: 2, - regex: /^(get|post) \/([^?#.\/\s]+)\/([^?#.\/\s]+)(\/?[?#][^\/\s]+)?/, + regex: /^(get|post) \/([^?#.\/\s]+)\/([^?#.\/\s]+)(?:\/?)?([?#][^\/\s]*)?/, match: 'get /weekend/baby?query=string#hash', handle: [Function], notFound: ' user.10.beers now', params: { page: 'weekend', view: 'baby', - queryFragment: '?query=string#hash' + qs: '?query=string#hash' } } ``` From dba40debf0343e19807e1ab08d7104a00f4e1302 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Sun, 26 Jun 2016 16:36:43 +0200 Subject: [PATCH 17/20] fix README.md inconsistency --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 17855c4..ae77b5c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "parth", "main": "index.js", - "version": "4.2.0", + "version": "4.2.1", "engines": { "node": ">= 0.10.0" }, From 6910dd3f22c0e6bd5a3875d5f2d6932064f6af47 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Sun, 12 Feb 2017 12:23:32 +0100 Subject: [PATCH 18/20] docs: fix license --- LICENSE | 19 ------------------- README.md | 10 +++++++++- package.json | 2 +- 3 files changed, 10 insertions(+), 21 deletions(-) delete mode 100644 LICENSE diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 9b039d2..0000000 --- a/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2014-2016 Javier Carrillo - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/README.md b/README.md index 2b1d488..56a3d33 100644 --- a/README.md +++ b/README.md @@ -183,7 +183,15 @@ parth ### license -![LICENSE](http://img.shields.io/npm/l/parth.svg?style=flat-square) +The MIT License (MIT) + +Copyright (c) 2014-present Javier Carrillo + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. [x-npm]: https://npmjs.org/package/parth [x-travis]: https://travis-ci.org/stringparser/parth/builds diff --git a/package.json b/package.json index ae77b5c..4d1bd0b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "parth", "main": "index.js", - "version": "4.2.1", + "version": "4.2.3", "engines": { "node": ">= 0.10.0" }, From 5c2364bc0176168f33ab68441b89ce637e462477 Mon Sep 17 00:00:00 2001 From: Javier Carrillo Date: Sun, 12 Feb 2017 14:33:36 +0100 Subject: [PATCH 19/20] fix: node build version should support const (eslint) --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3f00c73..821f418 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: node_js node_js: - - "0.10" - "4" - "stable" notifications: From 21266e89be86aa4855d70f1d190fc5e257c0ed7e Mon Sep 17 00:00:00 2001 From: Javier Carrillo Milla Date: Sat, 3 Mar 2018 11:06:28 +0100 Subject: [PATCH 20/20] Set theme jekyll-theme-cayman --- _config.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 _config.yml diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..c419263 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-cayman \ No newline at end of file