New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

path-to-regex

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

path-to-regex - npm Package Compare versions

Comparing version 1.0.1 to 1.1.1

148

index.js
module.exports = Regex;
const escapeRe = /([$.+*?=!:[\]{}(|)/\\])/g;
/**

@@ -19,3 +23,2 @@ * Класс Regex [description].

splitters: options.splitters||"/",
escapeChars: options.escapeChars||"/",
fromStart: options.fromStart||true,

@@ -57,12 +60,76 @@ toEnd: options.toEnd||true

this.path = path;
this.regstr = path
.replace(/([\.])/g, a=>{return "\\"+a})
.replace(/:([a-z]\w*)(\((.*?)\))?/gi,(str,id,a,pat)=>{
const pattern = (pat?pat:"[^"+this.escapeChars(this.options.splitters)+"]+?");
this.keys.push({key:id,pattern:pattern});
return "(?<"+id+">"+pattern+")";
});
this.regstr = "";
let offset = 0;
let count = 0;
path.replace(/:([a-z]\w*)(\((.*?)\))?([\?\*\+])?/gi,(str,key,a,pat,quant,index,string)=>{
// console.log("-----------------------------");
// console.log("str:", str);
// console.log("key:",key);
// console.log("a:",a);
// console.log("pat:",pat);
// console.log("quant:",quant);
// console.log("index:",index);
// console.log("string:",string);
const pattern = (pat?pat:"[^"+this.escape(this.options.splitters)+"]+");
const isMultiple = (quant==="*" || quant==="+")?true:false;
const isRequired = (quant!=="*" && quant!=="?")?true:false;
const quantifier = quant?quant:"";
const startChar = path.charAt(index-1);
const isStarted = this.splitter(startChar);
const isStoped = (index+str.length>=path.length)?true:this.splitter(path.charAt(index+str.length));
const isToken = isStarted && isStoped;
if( index > offset ){
const text = path.substring(offset,index);
const regstr = this.escape(text);
this.regstr+=regstr;
}
count++;
if( !isRequired && isStarted || isMultiple ){
this.regstr+="?";
}
const regstr =
isMultiple?
isToken?
"((?:\\"+startChar+""+pattern+")"+quantifier+")":
"((?:"+pattern+"\\"+startChar+"?)"+quantifier+")":
isToken?
"("+pattern+")"+quantifier:
"("+pattern+")"+quantifier;
this.regstr+=regstr;
const data = {
key: key,
multiple: isMultiple,
required: isRequired,
index: count,
pattern: pattern
};
if( isMultiple )
data.regexp = new RegExp(pattern, this.options.case?"g":"gi" );
this.keys.push(data);
offset = index+str.length;
return str;
});
if( offset < path.length-1 ){
const text = path.substring(offset);
const regstr = this.escape(text);
this.regstr+=regstr;
}
this.regexp = new RegExp(
(this.options.fromStart?"^":"")+
this.regstr+
"["+this.escape(this.options.splitters)+"]?"+
(this.options.toEnd?"$":"")

@@ -77,12 +144,21 @@ ,

/**
* Метод преобразует строку с шаблоном пути, включающим в себя строковое представление регулярных выражений
* и указадели на идентификаторы ключей в стиле Express.js в регулярное выражение
* @param {string} path Строка содержащая шаблон пути. Может содержать в себе регулярные выражения и объявление ключей типа :id. Поведение имитирует аналогичный функционал библиотеки Express.js v.5.x
* Метод экранирует все спец символы указанные в глобальной для модуля, переменной escapeRe
* @param {string} text Любая строка
* @return {string} Строка text, в которой все символы указанные в переменной escapeRe заэкранированы
*/
Regex.prototype.escapeChars = function (string) {
const re = new RegExp( "(["+this.options.escapeChars+this.options.splitters+"])", "g" );
return string.replace( re ,char=>{ return "\\"+char; });
Regex.prototype.escape = function(text) {
return text.replace(escapeRe,s=>{return "\\"+s});
}
/**
* Метод проверяет является ли char одним из разделителей указанных в this.options.splitters
* @param {string} char Cтрока содержащая в себе проверяемый символ (длинна строки должна быть равна 1)
* @return {boolean} Если проверяемый символ является одним из символов указанных в this.options.splitters то true иначе false
*/
Regex.prototype.splitter = function(char) {
return !!(this.options.splitters.indexOf(char)+1);
}
Regex.prototype.match = function(path) {

@@ -95,4 +171,46 @@ // console.log("Regex.match 01");

// console.log("Regex.match 03", result);
return result.groups||{};
const data = {};
this.keys.forEach(item=>{
let isMultiple = false;
// console.log("--------------");
// console.log(result[item.index]);
if( data[item.key] )
isMultiple = true;
if( data[item.key] && !Array.isArray(data[item.key]) ){
isMultiple = true;
data[item.key] = [data[item.key]];
}
if( item.multiple && !data[item.key] ){
isMultiple = true;
data[item.key] = [];
}
// console.log("key match 01", item.key, item.multiple, isMultiple);
if( !isMultiple && !item.multiple){
data[item.key] = result[item.index];
return;
}
// console.log("key match 02");
if( isMultiple && !item.multiple && result[item.index] ){
data[item.key].push(result[item.index]);
return;
}
// console.log("key match 03", result);
if(result[item.index])
result[item.index].replace(item.regexp, str=>{
data[item.key].push(str);
});
});
return data;
};

2

package.json
{
"name": "path-to-regex",
"version": "1.0.1",
"version": "1.1.1",
"description": "Turn a path string such as /user/:id or /user/:id(\\d+) into a regular expression",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -33,14 +33,182 @@ # path-to-regex

## Samples
#### Demonstration of processing a simple key identifier `:keyname`
```javascript
var pathToRegex = require('path-to-regex');
let parser = new pathToRegex('/foo/:bar');
// parser.regexp: /^\/foo\/([^\/]+)[\/]?$/
var matcher = new pathToRegex('/foo/:bar');
// matcher.regexp = /^\/foo\/(?<bar>[^\/]+?)$/
// matcher.keys = [{key:'bar',pattern:'[^\\/]+?'}]
let result = regex.match('/foo/asd'); // result: { bar: 'asd' }
var result = matcher.match('/foo/12345');
// result = { bar: '12345' }
let result = regex.match('/foo/123'); // result: { bar: '123' }
let result = regex.match('/foo/123/bar'); // result: undefined
```
#### Demonstration of processing a key identifier with a specific content `:keyname(\\d+)`
```javascript
let parser = new pathToRegex('/foo/:bar(\\d+)');
// parser.regexp: /^\/foo\/(\d+)[\/]?$/
let result = regex.match('/foo/123'); // result: { bar: '123' }
let result = regex.match('/foo/asd'); // result: undefined
let result = regex.match('/foo/123asd'); // result: undefined
let result = regex.match('/foo/123/bar'); // result: undefined
```
#### Demonstration of processing a multiple key identifiers `:keyname1 ... :keyname2`
```javascript
let parser = new pathToRegex('/user/:foo/:bar');
// parser.regexp: /^\/user\/([^\/]+)\/([^\/]+)[\/]?$/
let result = regex.match('/user/123/asd'); // result: { foo: '123', bar: 'asd' }
let result = regex.match('/user/asd/123'); // result: { foo: 'asd', bar: '123' }
```
#### Demonstration of processing a key identifiers with a repeated names `:keyname(\\d+) ... :keyname(\d+)`
```javascript
let parser = new pathToRegex('/foo/:bar/:bar');
// parser.regexp: /^\/foo\/([^\/]+)\/([^\/]+)[\/]?$/
let result = regex.match('/foo/123/asd'); // result: { bar: [ '123', 'asd' ] }
let result = regex.match('/foo/asd/123'); // result: { bar: [ 'asd', '123' ] }
```
#### Demonstration of processing a key identifier with a quantifier `?`
```javascript
let parser = new pathToRegex('/foo/:bar?');
// parser.regexp: /^\/foo\/?([^\/]+)?[\/]?$/
let result = regex.match('/foo/123'); // result: { bar: '123' }
let result = regex.match('/foo/'); // result: { bar: undefined }
let result = regex.match('/foo'); // result: { bar: undefined }
```
#### Demonstration of processing a key identifier with a quantifiers `*` and `+`
```javascript
let parser = new pathToRegex('/foo/:bar*');
// parser.regexp: /^\/foo\/?((?:\/[^\/]+)*)[\/]?$/
let result = regex.match('/foo'); // result: { bar: [] }
let result = regex.match('/foo/'); // result: { bar: [] }
let result = regex.match('/foo/123'); // result: { bar: [ '123' ] }
let result = regex.match('/foo/123/456'); // result: { bar: [ '123', '456' ] }
let result = regex.match('/foo/123/456/'); // result: { bar: [ '123', '456' ] }
let parser = new pathToRegex('/foo/ids: :bar*/:count?');
// parser.regexp: /^\/foo\/ids\: ?((?:[^\/]+\ ?)*)\/?([^\/]+)?[\/]?$/
let result = regex.match('/foo/ids: 123 456 789'); // result: { bar: [ '123 456 789' ], count: undefined }
let result = regex.match('/foo/ids: 123 456 789/3'); // result: { bar: [ '123 456 789' ], count: '3' }
let parser = new pathToRegex('/foo/:bar+');
// parser.regexp: /^\/foo\/?((?:\/[^\/]+)+)[\/]?$/
let result = regex.match('/foo'); // result: undefined
let result = regex.match('/foo/'); // result: undefined
let result = regex.match('/foo/123'); // result: { bar: [ '123' ] }
let result = regex.match('/foo/123/456'); // result: { bar: [ '123', '456' ] }
let result = regex.match('/foo/123/456/'); // result: { bar: [ '123', '456' ] }
let parser = new pathToRegex('/foo/ids-,:bar+/:count?');
// parser.regexp: /^\/foo\/ids-,?((?:[^\/]+\,?)+)\/?([^\/]+)?[\/]?$/
let result = regex.match('/foo/ids-123,456,789'); // result: { bar: [ '123,456,789' ], count: undefined }
let result = regex.match('/foo/ids-123,456,789/3'); // result: { bar: [ '123,456,789' ], count: '3' }
```
#### Demonstration of processing a key identifier with all features
```javascript
let parser = new pathToRegex('/user/:id/bar/:key(\\d+):post?fak/:key(\d+)*:foo+/test/pictures-,:multi(\w+?\.png)*/:key?');
// parser.regexp: /^\/user\/([^\/]+)\/bar\/(\d+)([^\/]+)?fak\/?((?:\d+\/?)*)?((?:[^\/]+\*?)+)\/test\/pictures-,?((?:\w+?\.png\,?)*)\/?([^\/]+)?[\/]?$/
let result = regex.match('/user/123/bar/111qwertyfak/222foo/test/pictures-p01.png,p02.png,p03.png');
/* result:
{ id: '123',
key: [ '111', '222' ],
post: 'qwerty',
foo: [ 'foo' ],
multi: [ 'p01.png', 'p02.png', 'p03.png' ] }
*/
let result = regex.match('/user/123/bar/111qwertyfak/222foo/test/pictures-p01.png,p02.png,p03.png/333');
/* result:
{ id: '123',
key: [ '111', '222', '333' ],
post: 'qwerty',
foo: [ 'foo' ],
multi: [ 'p01.png', 'p02.png', 'p03.png' ] }
*/
let parser = new pathToRegex('/user/:id/bar/:key(\\d+):post?fak/:key(\d+)*:foo+/test/pictures- :multi(\w+?\.png)*/:key*');
// parser.regexp: /^\/user\/([^\/]+)\/bar\/(\d+)([^\/]+)?fak\/?((?:\d+\/?)*)?((?:[^\/]+\*?)+)\/test\/pictures- ?((?:\w+?\.png\ ?)*)\/?((?:\/[^\/]+)*)[\/]?$/
let result = regex.match('/user/123/bar/111fak/222foo/test/pictures-p01.png p02.png p03.png');
/* result:
{ id: '123',
key: [ '111', '222' ],
post: undefined,
foo: [ 'foo' ],
multi: [ 'p01.png', 'p02.png', 'p03.png' ] }
*/
let result = regex.match('/user/123/bar/111fak/222foo/test/pictures-p01.png p02.png p03.png/333');
/* result:
{ id: '123',
key: [ '111', '222', '333' ],
post: undefined,
foo: [ 'foo' ],
multi: [ 'p01.png', 'p02.png', 'p03.png' ] }
*/
let result = regex.match('/user/123/bar/111fak/222foo/test/pictures-p01.png p02.png p03.png/333/444/');
/* result:
{ id: '123',
key: [ '111', '222', '333', '444' ],
post: undefined,
foo: [ 'foo' ],
multi: [ 'p01.png', 'p02.png', 'p03.png' ] }
*/
```
... documentation in processed

@@ -50,2 +218,4 @@

[![NPM](https://nodei.co/npm/path-to-regex.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/path-to-regex/)
[npm-image]: https://img.shields.io/npm/v/path-to-regex.svg?style=flat

@@ -52,0 +222,0 @@ [npm-url]: https://npmjs.org/package/path-to-regex

@@ -0,1 +1,3 @@

const PathToRegex = require("../index.js");
const chai = require('chai');

@@ -7,5 +9,5 @@ const assert = chai.assert;

const PathToRegex = require("../index.js");
describe("Тестируем модуль преобразования пути в RegExp", function() {

@@ -75,8 +77,6 @@

const params = re3.match("/foo/123/bar/456");
console.log("REGEX:", "\t\t"+re3.regexp, "\t\t", re3.regexp, "\t\t", re3.regstr, "\t\t", re3.path, "\t\t", re3.keys);
console.log("REGEX:", "\t\t", params);
assert.equal( !!params, true);
});
it("соотносим RegExp /^\\/foo\/(?<fooid>[^\\/]+?)\\/bar\\/(?<barid>[^\\/]+?)$/ (путь \"/foo/:fooid/bar/:barid\" ) со строками \"/foo/111/bar/222\" \"/foo/id1/bar/id22\" и проверяем наличие ключей fooid и barid и соответствие их значений", function() {
it("соотносим RegExp /^\\/foo\\/(?<fooid>[^\\/]+?)\\/bar\\/(?<barid>[^\\/]+?)$/ (путь \"/foo/:fooid/bar/:barid\" ) со строками \"/foo/111/bar/222\" \"/foo/id1/bar/id22\" и проверяем наличие ключей fooid и barid и соответствие их значений", function() {
const params1 = re3.match("/foo/111/bar/222");

@@ -88,4 +88,25 @@ const params2 = re3.match("/foo/id1/bar/id22");

assert.equal( params2.barid, "id22");
});
const re4 = new PathToRegex("/user/:id(\\d+)");
console.log("REGEX:", "\t\t"+re4.regexp, "\t\t", re4.regexp, "\t\t", re4.regstr, "\t\t", re4.path);
// console.log("REGEX:", "\t\t"+re3.regexp, "\t\t", re3.regexp, "\t\t", re3.regstr, "\t\t", re3.path, "\t\t", re3.keys);
// console.log("REGEX:", "\t\t", params);
it("создаем RegExp из \"/user/:id(\\\\d+)\"", function() {
assert.equal( re4 instanceof PathToRegex, true);
assert.equal( ""+re4.regexp, ""+/^\/user\/(?<id>\d+)$/ );
});
it("соотносим RegExp /^\\/user\\/(?<id>\\d+)$/ (путь \"/user/:id(\\\\d+)\" ) со строками \"/\" \"/user\" \"/user/123\" \"/user/123/foo\" \"/user/aaa\" ", function() {
assert.equal( !!re4.match("/"), false);
assert.equal( !!re4.match("/user"), false);
const params = re4.match("/user/123");
assert.equal( !!params, true);
assert.equal( params.id, "123");
assert.equal( !!re4.match("/user/123/foo"), false);
assert.equal( !!re4.match("/user/aaa"), false);
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc