Socket
Socket
Sign inDemoInstall

path-parser

Package Overview
Dependencies
Maintainers
1
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

path-parser - npm Package Compare versions

Comparing version 3.0.1 to 4.0.0

typings/Path.d.ts

18

CHANGELOG.md

@@ -0,1 +1,19 @@

<a name="4.0.0"></a>
# [4.0.0](https://github.com/troch/path-parser/compare/v3.0.1...v4.0.0) (2018-03-25)
### Features
* make matching case insensitive, add support for 'caseSentive' option ([063aca6](https://github.com/troch/path-parser/commit/063aca6))
### BREAKING CHANGES
* query parameters can no longer be defined with brackets, instead options are available when matching and building to describe how arrays, booleans and null values are formatted (see 'queryParams' options in README).
* Boolean and null values in query parameters are stringified differently, see the list of options available. To keep behaviour unchanged, set `nullFormat` to `'hidden'` and `booleanFormat` to `'empty-true'`.
* 'trailingSlash' option has been renamed to 'strictTrailingSlash'
* 'test' and 'partialTest' are now case insensitive by default, use 'caseSensitive' option to make it case sensitive
<a name="3.0.1"></a>

@@ -2,0 +20,0 @@ ## [3.0.1](https://github.com/troch/path-parser/compare/v3.0.0...v3.0.1) (2017-11-16)

549

dist/cjs/path-parser.js

@@ -5,78 +5,77 @@ 'use strict';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
var defaultOrConstrained = function defaultOrConstrained(match) {
return '(' + (match ? match.replace(/(^<|>$)/g, '') : '[a-zA-Z0-9-_.~%\':]+') + ')';
var __assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
var rules = [{
// An URL can contain a parameter :paramName
// - and _ are allowed but not in last position
name: 'url-parameter',
pattern: /^:([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})(<(.+?)>)?/,
regex: function regex(match) {
return new RegExp(defaultOrConstrained(match[2]));
var defaultOrConstrained = function (match) {
return '(' + (match ? match.replace(/(^<|>$)/g, '') : "[a-zA-Z0-9-_.~%':]+") + ')';
};
var rules = [
{
name: 'url-parameter',
pattern: /^:([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})(<(.+?)>)?/,
regex: function (match) {
return new RegExp(defaultOrConstrained(match[2]));
}
},
{
name: 'url-parameter-splat',
pattern: /^\*([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})/,
regex: /([^?]*)/
},
{
name: 'url-parameter-matrix',
pattern: /^;([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})(<(.+?)>)?/,
regex: function (match) {
return new RegExp(';' + match[1] + '=' + defaultOrConstrained(match[2]));
}
},
{
name: 'query-parameter',
pattern: /^(?:\?|&)(?::)?([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})/
},
{
name: 'delimiter',
pattern: /^(\/|\?)/,
regex: function (match) { return new RegExp('\\' + match[0]); }
},
{
name: 'sub-delimiter',
pattern: /^(!|&|-|_|\.|;)/,
regex: function (match) { return new RegExp(match[0]); }
},
{
name: 'fragment',
pattern: /^([0-9a-zA-Z]+)/,
regex: function (match) { return new RegExp(match[0]); }
}
}, {
// Url parameter (splat)
name: 'url-parameter-splat',
pattern: /^\*([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})/,
regex: /([^\?]*)/
}, {
name: 'url-parameter-matrix',
pattern: /^\;([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})(<(.+?)>)?/,
regex: function regex(match) {
return new RegExp(';' + match[1] + '=' + defaultOrConstrained(match[2]));
}
}, {
// Query parameter: ?param1&param2
// ?:param1&:param2
name: 'query-parameter-bracket',
pattern: /^(?:\?|&)(?:\:)?([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})(?:\[\])/
// regex: match => new RegExp('(?=(\?|.*&)' + match[0] + '(?=(\=|&|$)))')
}, {
// Query parameter: ?param1&param2
// ?:param1&:param2
name: 'query-parameter',
pattern: /^(?:\?|&)(?:\:)?([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})/
// regex: match => new RegExp('(?=(\?|.*&)' + match[0] + '(?=(\=|&|$)))')
}, {
// Delimiter /
name: 'delimiter',
pattern: /^(\/|\?)/,
regex: function regex(match) {
return new RegExp('\\' + match[0]);
}
}, {
// Sub delimiters
name: 'sub-delimiter',
pattern: /^(\!|\&|\-|_|\.|;)/,
regex: function regex(match) {
return new RegExp(match[0]);
}
}, {
// Unmatched fragment (until delimiter is found)
name: 'fragment',
pattern: /^([0-9a-zA-Z]+)/,
regex: function regex(match) {
return new RegExp(match[0]);
}
}];
];
var exists = function exists(val) {
return val !== undefined && val !== null;
};
var tokenise = function tokenise(str) {
var tokens = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var tokenise = function (str, tokens) {
if (tokens === void 0) { tokens = []; }
// Look for a matching rule
var matched = rules.some(function (rule) {
var match = str.match(rule.pattern);
if (!match) return false;
if (!match) {
return false;
}
tokens.push({

@@ -89,278 +88,212 @@ type: rule.name,

});
if (match[0].length < str.length) tokens = tokenise(str.substr(match[0].length), tokens);
if (match[0].length < str.length) {
tokens = tokenise(str.substr(match[0].length), tokens);
}
return true;
});
// If no rules matched, throw an error (possible malformed path)
if (!matched) {
throw new Error('Could not parse path \'' + str + '\'');
throw new Error("Could not parse path '" + str + "'");
}
// Return tokens
return tokens;
};
var optTrailingSlash = function optTrailingSlash(source, trailingSlash) {
if (!trailingSlash) return source;
var identity = function (_) { return _; };
var exists = function (val) { return val !== undefined && val !== null; };
var optTrailingSlash = function (source, strictTrailingSlash) {
if (!strictTrailingSlash) {
return source;
}
return source.replace(/\\\/$/, '') + '(?:\\/)?';
};
var upToDelimiter = function upToDelimiter(source, delimiter) {
if (!delimiter) return source;
return (/(\/)$/.test(source) ? source : source + '(\\/|\\?|\\.|;|$)'
);
var upToDelimiter = function (source, delimiter) {
if (!delimiter) {
return source;
}
return /(\/)$/.test(source) ? source : source + '(\\/|\\?|\\.|;|$)';
};
var appendQueryParam = function appendQueryParam(params, param) {
var val = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
if (/\[\]$/.test(param)) {
param = searchParams.withoutBrackets(param);
val = [val];
var appendQueryParam = function (params, param, val) {
if (val === void 0) { val = ''; }
var existingVal = params[param];
if (existingVal === undefined) {
params[param] = val;
}
var existingVal = params[param];
if (existingVal === undefined) params[param] = val;else params[param] = Array.isArray(existingVal) ? existingVal.concat(val) : [existingVal, val];
else {
params[param] = Array.isArray(existingVal)
? existingVal.concat(val)
: [existingVal, val];
}
return params;
};
var parseQueryParams = function parseQueryParams(path) {
var searchPart = searchParams.getSearch(path);
if (!searchPart) return {};
return searchParams.toObject(searchParams.parse(searchPart));
};
function _serialise(key, val) {
if (Array.isArray(val)) {
return val.map(function (v) {
return _serialise(key, v);
}).join('&');
}
if (val === true) {
return key;
}
return key + '=' + val;
}
var Path = function () {
_createClass(Path, null, [{
key: 'createPath',
value: function createPath(path) {
return new Path(path);
var Path = /** @class */ (function () {
function Path(path) {
if (!path) {
throw new Error('Missing path in Path constructor');
}
}, {
key: 'serialise',
value: function serialise(key, val) {
return _serialise(key, val);
}
}]);
function Path(path) {
_classCallCheck(this, Path);
if (!path) throw new Error('Missing path in Path constructor');
this.path = path;
this.tokens = tokenise(path);
this.hasUrlParams = this.tokens.filter(function (t) {
return (/^url-parameter/.test(t.type)
);
}).length > 0;
this.hasSpatParam = this.tokens.filter(function (t) {
return (/splat$/.test(t.type)
);
}).length > 0;
this.hasMatrixParams = this.tokens.filter(function (t) {
return (/matrix$/.test(t.type)
);
}).length > 0;
this.hasQueryParams = this.tokens.filter(function (t) {
return (/^query-parameter/.test(t.type)
);
}).length > 0;
this.hasUrlParams =
this.tokens.filter(function (t) { return /^url-parameter/.test(t.type); }).length > 0;
this.hasSpatParam =
this.tokens.filter(function (t) { return /splat$/.test(t.type); }).length > 0;
this.hasMatrixParams =
this.tokens.filter(function (t) { return /matrix$/.test(t.type); }).length > 0;
this.hasQueryParams =
this.tokens.filter(function (t) { return /^query-parameter/.test(t.type); }).length > 0;
// Extract named parameters from tokens
this.spatParams = this._getParams('url-parameter-splat');
this.urlParams = this._getParams(/^url-parameter/);
this.spatParams = this.getParams('url-parameter-splat');
this.urlParams = this.getParams(/^url-parameter/);
// Query params
this.queryParams = this._getParams('query-parameter');
this.queryParamsBr = this._getParams('query-parameter-bracket');
this.queryParams = this.getParams('query-parameter');
// All params
this.params = this.urlParams.concat(this.queryParams).concat(this.queryParamsBr);
this.params = this.urlParams.concat(this.queryParams);
// Check if hasQueryParams
// Regular expressions for url part only (full and partial match)
this.source = this.tokens.filter(function (t) {
return t.regex !== undefined;
}).map(function (r) {
return r.regex.source;
}).join('');
this.source = this.tokens
.filter(function (t) { return t.regex !== undefined; })
.map(function (r) { return r.regex.source; })
.join('');
}
_createClass(Path, [{
key: '_getParams',
value: function _getParams(type) {
var predicate = type instanceof RegExp ? function (t) {
return type.test(t.type);
} : function (t) {
return t.type === type;
};
return this.tokens.filter(predicate).map(function (t) {
return t.val[0];
});
Path.createPath = function (path) {
return new Path(path);
};
Path.prototype.isQueryParam = function (name) {
return this.queryParams.indexOf(name) !== -1;
};
Path.prototype.test = function (path, opts) {
var _this = this;
var options = __assign({ strictTrailingSlash: false, queryParams: {} }, opts);
// trailingSlash: falsy => non optional, truthy => optional
var source = optTrailingSlash(this.source, options.strictTrailingSlash);
// Check if exact match
var match = this.urlTest(path, source + (this.hasQueryParams ? '(\\?.*$|$)' : '$'), opts);
// If no match, or no query params, no need to go further
if (!match || !this.hasQueryParams) {
return match;
}
}, {
key: '_isQueryParam',
value: function _isQueryParam(name) {
return this.queryParams.indexOf(name) !== -1 || this.queryParamsBr.indexOf(name) !== -1;
// Extract query params
var queryParams = searchParams.parse(path, options.queryParams);
var unexpectedQueryParams = Object.keys(queryParams).filter(function (p) { return !_this.isQueryParam(p); });
if (unexpectedQueryParams.length === 0) {
// Extend url match
Object.keys(queryParams).forEach(function (p) { return (match[p] = queryParams[p]); });
return match;
}
}, {
key: '_urlTest',
value: function _urlTest(path, regex) {
var _this = this;
var match = path.match(regex);
if (!match) return null;else if (!this.urlParams.length) return {};
// Reduce named params to key-value pairs
return match.slice(1, this.urlParams.length + 1).reduce(function (params, m, i) {
params[_this.urlParams[i]] = decodeURIComponent(m);
return params;
}, {});
return null;
};
Path.prototype.partialTest = function (path, opts) {
var _this = this;
var options = __assign({ delimited: true, queryParams: {} }, opts);
// Check if partial match (start of given path matches regex)
// trailingSlash: falsy => non optional, truthy => optional
var source = upToDelimiter(this.source, options.delimited);
var match = this.urlTest(path, source, options);
if (!match) {
return match;
}
}, {
key: 'test',
value: function test(path, opts) {
var _this2 = this;
var options = _extends({ trailingSlash: false }, opts);
// trailingSlash: falsy => non optional, truthy => optional
var source = optTrailingSlash(this.source, options.trailingSlash);
// Check if exact match
var matched = this._urlTest(path, new RegExp('^' + source + (this.hasQueryParams ? '(\\?.*$|$)' : '$')));
// If no match, or no query params, no need to go further
if (!matched || !this.hasQueryParams) return matched;
// Extract query params
var queryParams = parseQueryParams(path);
var unexpectedQueryParams = Object.keys(queryParams).filter(function (p) {
return _this2.queryParams.concat(_this2.queryParamsBr).indexOf(p) === -1;
});
if (unexpectedQueryParams.length === 0) {
// Extend url match
Object.keys(queryParams).forEach(function (p) {
return matched[p] = queryParams[p];
});
return matched;
}
return null;
}
}, {
key: 'partialTest',
value: function partialTest(path, opts) {
var _this3 = this;
var options = _extends({ delimited: true }, opts);
// Check if partial match (start of given path matches regex)
// trailingSlash: falsy => non optional, truthy => optional
var source = upToDelimiter(this.source, options.delimited);
var match = this._urlTest(path, new RegExp('^' + source));
if (!match) return match;
if (!this.hasQueryParams) return match;
var queryParams = parseQueryParams(path);
Object.keys(queryParams).filter(function (p) {
return _this3.queryParams.concat(_this3.queryParamsBr).indexOf(p) >= 0;
}).forEach(function (p) {
return appendQueryParam(match, p, queryParams[p]);
});
if (!this.hasQueryParams) {
return match;
}
}, {
key: 'build',
value: function build() {
var _this4 = this;
var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var options = _extends({ ignoreConstraints: false, ignoreSearch: false }, opts);
var encodedParams = Object.keys(params).reduce(function (acc, key) {
if (!exists(params[key])) {
return acc;
}
var val = params[key];
var encode = _this4._isQueryParam(key) ? encodeURIComponent : encodeURI;
if (typeof val === 'boolean') {
acc[key] = val;
} else if (Array.isArray(val)) {
acc[key] = val.map(encode);
} else {
acc[key] = encode(val);
}
var queryParams = searchParams.parse(path, options.queryParams);
Object.keys(queryParams)
.filter(function (p) { return _this.isQueryParam(p); })
.forEach(function (p) { return appendQueryParam(match, p, queryParams[p]); });
return match;
};
Path.prototype.build = function (params, opts) {
var _this = this;
if (params === void 0) { params = {}; }
var options = __assign({ ignoreConstraints: false, ignoreSearch: false, queryParams: {} }, opts);
var encodedUrlParams = Object.keys(params)
.filter(function (p) { return !_this.isQueryParam(p); })
.reduce(function (acc, key) {
if (!exists(params[key])) {
return acc;
}, {});
// Check all params are provided (not search parameters which are optional)
if (this.urlParams.some(function (p) {
return !exists(encodedParams[p]);
})) {
var missingParameters = this.urlParams.filter(function (p) {
return !exists(encodedParams[p]);
});
throw new Error('Cannot build path: \'' + this.path + '\' requires missing parameters { ' + missingParameters.join(', ') + ' }');
}
// Check constraints
if (!options.ignoreConstraints) {
var constraintsPassed = this.tokens.filter(function (t) {
return (/^url-parameter/.test(t.type) && !/-splat$/.test(t.type)
);
}).every(function (t) {
return new RegExp('^' + defaultOrConstrained(t.otherVal[0]) + '$').test(encodedParams[t.val]);
});
if (!constraintsPassed) throw new Error('Some parameters of \'' + this.path + '\' are of invalid format');
var val = params[key];
var encode = _this.isQueryParam(key) ? identity : encodeURI;
if (typeof val === 'boolean') {
acc[key] = val;
}
var base = this.tokens.filter(function (t) {
return (/^query-parameter/.test(t.type) === false
);
}).map(function (t) {
if (t.type === 'url-parameter-matrix') return ';' + t.val + '=' + encodedParams[t.val[0]];
return (/^url-parameter/.test(t.type) ? encodedParams[t.val[0]] : t.match
);
}).join('');
if (options.ignoreSearch) return base;
var queryParams = this.queryParams.concat(this.queryParamsBr.map(function (p) {
return p + '[]';
}));
var searchPart = queryParams.filter(function (p) {
return Object.keys(encodedParams).indexOf(searchParams.withoutBrackets(p)) !== -1;
}).map(function (p) {
return _serialise(p, encodedParams[searchParams.withoutBrackets(p)]);
}).join('&');
return base + (searchPart ? '?' + searchPart : '');
else if (Array.isArray(val)) {
acc[key] = val.map(encode);
}
else {
acc[key] = encode(val);
}
return acc;
}, {});
// Check all params are provided (not search parameters which are optional)
if (this.urlParams.some(function (p) { return !exists(params[p]); })) {
var missingParameters = this.urlParams.filter(function (p) { return !exists(params[p]); });
throw new Error("Cannot build path: '" +
this.path +
"' requires missing parameters { " +
missingParameters.join(', ') +
' }');
}
}]);
// Check constraints
if (!options.ignoreConstraints) {
var constraintsPassed = this.tokens
.filter(function (t) {
return /^url-parameter/.test(t.type) && !/-splat$/.test(t.type);
})
.every(function (t) {
return new RegExp('^' + defaultOrConstrained(t.otherVal[0]) + '$').test(encodedUrlParams[t.val]);
});
if (!constraintsPassed) {
throw new Error("Some parameters of '" + this.path + "' are of invalid format");
}
}
var base = this.tokens
.filter(function (t) { return /^query-parameter/.test(t.type) === false; })
.map(function (t) {
if (t.type === 'url-parameter-matrix') {
return ";" + t.val + "=" + encodedUrlParams[t.val[0]];
}
return /^url-parameter/.test(t.type)
? encodedUrlParams[t.val[0]]
: t.match;
})
.join('');
if (options.ignoreSearch) {
return base;
}
var searchParams$$1 = this.queryParams
.filter(function (p) { return Object.keys(params).indexOf(p) !== -1; })
.reduce(function (sparams, paramName) {
sparams[paramName] = params[paramName];
return sparams;
}, {});
var searchPart = searchParams.build(searchParams$$1, options.queryParams);
return searchPart ? base + '?' + searchPart : base;
};
Path.prototype.getParams = function (type) {
var predicate = type instanceof RegExp
? function (t) { return type.test(t.type); }
: function (t) { return t.type === type; };
return this.tokens.filter(predicate).map(function (t) { return t.val[0]; });
};
Path.prototype.urlTest = function (path, source, _a) {
var _this = this;
var _b = (_a === void 0 ? {} : _a).caseSensitive, caseSensitive = _b === void 0 ? false : _b;
var regex = new RegExp('^' + source, caseSensitive ? '' : 'i');
var match = path.match(regex);
if (!match) {
return null;
}
else if (!this.urlParams.length) {
return {};
}
// Reduce named params to key-value pairs
return match
.slice(1, this.urlParams.length + 1)
.reduce(function (params, m, i) {
params[_this.urlParams[i]] = decodeURIComponent(m);
return params;
}, {});
};
return Path;
}();
}());
module.exports = Path;

@@ -1,79 +0,78 @@

import { getSearch, parse, toObject, withoutBrackets } from 'search-params';
import { build, parse } from 'search-params';
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
var defaultOrConstrained = function defaultOrConstrained(match) {
return '(' + (match ? match.replace(/(^<|>$)/g, '') : '[a-zA-Z0-9-_.~%\':]+') + ')';
var __assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
var rules = [{
// An URL can contain a parameter :paramName
// - and _ are allowed but not in last position
name: 'url-parameter',
pattern: /^:([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})(<(.+?)>)?/,
regex: function regex(match) {
return new RegExp(defaultOrConstrained(match[2]));
var defaultOrConstrained = function (match) {
return '(' + (match ? match.replace(/(^<|>$)/g, '') : "[a-zA-Z0-9-_.~%':]+") + ')';
};
var rules = [
{
name: 'url-parameter',
pattern: /^:([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})(<(.+?)>)?/,
regex: function (match) {
return new RegExp(defaultOrConstrained(match[2]));
}
},
{
name: 'url-parameter-splat',
pattern: /^\*([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})/,
regex: /([^?]*)/
},
{
name: 'url-parameter-matrix',
pattern: /^;([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})(<(.+?)>)?/,
regex: function (match) {
return new RegExp(';' + match[1] + '=' + defaultOrConstrained(match[2]));
}
},
{
name: 'query-parameter',
pattern: /^(?:\?|&)(?::)?([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})/
},
{
name: 'delimiter',
pattern: /^(\/|\?)/,
regex: function (match) { return new RegExp('\\' + match[0]); }
},
{
name: 'sub-delimiter',
pattern: /^(!|&|-|_|\.|;)/,
regex: function (match) { return new RegExp(match[0]); }
},
{
name: 'fragment',
pattern: /^([0-9a-zA-Z]+)/,
regex: function (match) { return new RegExp(match[0]); }
}
}, {
// Url parameter (splat)
name: 'url-parameter-splat',
pattern: /^\*([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})/,
regex: /([^\?]*)/
}, {
name: 'url-parameter-matrix',
pattern: /^\;([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})(<(.+?)>)?/,
regex: function regex(match) {
return new RegExp(';' + match[1] + '=' + defaultOrConstrained(match[2]));
}
}, {
// Query parameter: ?param1&param2
// ?:param1&:param2
name: 'query-parameter-bracket',
pattern: /^(?:\?|&)(?:\:)?([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})(?:\[\])/
// regex: match => new RegExp('(?=(\?|.*&)' + match[0] + '(?=(\=|&|$)))')
}, {
// Query parameter: ?param1&param2
// ?:param1&:param2
name: 'query-parameter',
pattern: /^(?:\?|&)(?:\:)?([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})/
// regex: match => new RegExp('(?=(\?|.*&)' + match[0] + '(?=(\=|&|$)))')
}, {
// Delimiter /
name: 'delimiter',
pattern: /^(\/|\?)/,
regex: function regex(match) {
return new RegExp('\\' + match[0]);
}
}, {
// Sub delimiters
name: 'sub-delimiter',
pattern: /^(\!|\&|\-|_|\.|;)/,
regex: function regex(match) {
return new RegExp(match[0]);
}
}, {
// Unmatched fragment (until delimiter is found)
name: 'fragment',
pattern: /^([0-9a-zA-Z]+)/,
regex: function regex(match) {
return new RegExp(match[0]);
}
}];
];
var exists = function exists(val) {
return val !== undefined && val !== null;
};
var tokenise = function tokenise(str) {
var tokens = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var tokenise = function (str, tokens) {
if (tokens === void 0) { tokens = []; }
// Look for a matching rule
var matched = rules.some(function (rule) {
var match = str.match(rule.pattern);
if (!match) return false;
if (!match) {
return false;
}
tokens.push({

@@ -86,278 +85,212 @@ type: rule.name,

});
if (match[0].length < str.length) tokens = tokenise(str.substr(match[0].length), tokens);
if (match[0].length < str.length) {
tokens = tokenise(str.substr(match[0].length), tokens);
}
return true;
});
// If no rules matched, throw an error (possible malformed path)
if (!matched) {
throw new Error('Could not parse path \'' + str + '\'');
throw new Error("Could not parse path '" + str + "'");
}
// Return tokens
return tokens;
};
var optTrailingSlash = function optTrailingSlash(source, trailingSlash) {
if (!trailingSlash) return source;
var identity = function (_) { return _; };
var exists = function (val) { return val !== undefined && val !== null; };
var optTrailingSlash = function (source, strictTrailingSlash) {
if (!strictTrailingSlash) {
return source;
}
return source.replace(/\\\/$/, '') + '(?:\\/)?';
};
var upToDelimiter = function upToDelimiter(source, delimiter) {
if (!delimiter) return source;
return (/(\/)$/.test(source) ? source : source + '(\\/|\\?|\\.|;|$)'
);
var upToDelimiter = function (source, delimiter) {
if (!delimiter) {
return source;
}
return /(\/)$/.test(source) ? source : source + '(\\/|\\?|\\.|;|$)';
};
var appendQueryParam = function appendQueryParam(params, param) {
var val = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
if (/\[\]$/.test(param)) {
param = withoutBrackets(param);
val = [val];
var appendQueryParam = function (params, param, val) {
if (val === void 0) { val = ''; }
var existingVal = params[param];
if (existingVal === undefined) {
params[param] = val;
}
var existingVal = params[param];
if (existingVal === undefined) params[param] = val;else params[param] = Array.isArray(existingVal) ? existingVal.concat(val) : [existingVal, val];
else {
params[param] = Array.isArray(existingVal)
? existingVal.concat(val)
: [existingVal, val];
}
return params;
};
var parseQueryParams = function parseQueryParams(path) {
var searchPart = getSearch(path);
if (!searchPart) return {};
return toObject(parse(searchPart));
};
function _serialise(key, val) {
if (Array.isArray(val)) {
return val.map(function (v) {
return _serialise(key, v);
}).join('&');
}
if (val === true) {
return key;
}
return key + '=' + val;
}
var Path = function () {
_createClass(Path, null, [{
key: 'createPath',
value: function createPath(path) {
return new Path(path);
var Path = /** @class */ (function () {
function Path(path) {
if (!path) {
throw new Error('Missing path in Path constructor');
}
}, {
key: 'serialise',
value: function serialise(key, val) {
return _serialise(key, val);
}
}]);
function Path(path) {
_classCallCheck(this, Path);
if (!path) throw new Error('Missing path in Path constructor');
this.path = path;
this.tokens = tokenise(path);
this.hasUrlParams = this.tokens.filter(function (t) {
return (/^url-parameter/.test(t.type)
);
}).length > 0;
this.hasSpatParam = this.tokens.filter(function (t) {
return (/splat$/.test(t.type)
);
}).length > 0;
this.hasMatrixParams = this.tokens.filter(function (t) {
return (/matrix$/.test(t.type)
);
}).length > 0;
this.hasQueryParams = this.tokens.filter(function (t) {
return (/^query-parameter/.test(t.type)
);
}).length > 0;
this.hasUrlParams =
this.tokens.filter(function (t) { return /^url-parameter/.test(t.type); }).length > 0;
this.hasSpatParam =
this.tokens.filter(function (t) { return /splat$/.test(t.type); }).length > 0;
this.hasMatrixParams =
this.tokens.filter(function (t) { return /matrix$/.test(t.type); }).length > 0;
this.hasQueryParams =
this.tokens.filter(function (t) { return /^query-parameter/.test(t.type); }).length > 0;
// Extract named parameters from tokens
this.spatParams = this._getParams('url-parameter-splat');
this.urlParams = this._getParams(/^url-parameter/);
this.spatParams = this.getParams('url-parameter-splat');
this.urlParams = this.getParams(/^url-parameter/);
// Query params
this.queryParams = this._getParams('query-parameter');
this.queryParamsBr = this._getParams('query-parameter-bracket');
this.queryParams = this.getParams('query-parameter');
// All params
this.params = this.urlParams.concat(this.queryParams).concat(this.queryParamsBr);
this.params = this.urlParams.concat(this.queryParams);
// Check if hasQueryParams
// Regular expressions for url part only (full and partial match)
this.source = this.tokens.filter(function (t) {
return t.regex !== undefined;
}).map(function (r) {
return r.regex.source;
}).join('');
this.source = this.tokens
.filter(function (t) { return t.regex !== undefined; })
.map(function (r) { return r.regex.source; })
.join('');
}
_createClass(Path, [{
key: '_getParams',
value: function _getParams(type) {
var predicate = type instanceof RegExp ? function (t) {
return type.test(t.type);
} : function (t) {
return t.type === type;
};
return this.tokens.filter(predicate).map(function (t) {
return t.val[0];
});
Path.createPath = function (path) {
return new Path(path);
};
Path.prototype.isQueryParam = function (name) {
return this.queryParams.indexOf(name) !== -1;
};
Path.prototype.test = function (path, opts) {
var _this = this;
var options = __assign({ strictTrailingSlash: false, queryParams: {} }, opts);
// trailingSlash: falsy => non optional, truthy => optional
var source = optTrailingSlash(this.source, options.strictTrailingSlash);
// Check if exact match
var match = this.urlTest(path, source + (this.hasQueryParams ? '(\\?.*$|$)' : '$'), opts);
// If no match, or no query params, no need to go further
if (!match || !this.hasQueryParams) {
return match;
}
}, {
key: '_isQueryParam',
value: function _isQueryParam(name) {
return this.queryParams.indexOf(name) !== -1 || this.queryParamsBr.indexOf(name) !== -1;
// Extract query params
var queryParams = parse(path, options.queryParams);
var unexpectedQueryParams = Object.keys(queryParams).filter(function (p) { return !_this.isQueryParam(p); });
if (unexpectedQueryParams.length === 0) {
// Extend url match
Object.keys(queryParams).forEach(function (p) { return (match[p] = queryParams[p]); });
return match;
}
}, {
key: '_urlTest',
value: function _urlTest(path, regex) {
var _this = this;
var match = path.match(regex);
if (!match) return null;else if (!this.urlParams.length) return {};
// Reduce named params to key-value pairs
return match.slice(1, this.urlParams.length + 1).reduce(function (params, m, i) {
params[_this.urlParams[i]] = decodeURIComponent(m);
return params;
}, {});
return null;
};
Path.prototype.partialTest = function (path, opts) {
var _this = this;
var options = __assign({ delimited: true, queryParams: {} }, opts);
// Check if partial match (start of given path matches regex)
// trailingSlash: falsy => non optional, truthy => optional
var source = upToDelimiter(this.source, options.delimited);
var match = this.urlTest(path, source, options);
if (!match) {
return match;
}
}, {
key: 'test',
value: function test(path, opts) {
var _this2 = this;
var options = _extends({ trailingSlash: false }, opts);
// trailingSlash: falsy => non optional, truthy => optional
var source = optTrailingSlash(this.source, options.trailingSlash);
// Check if exact match
var matched = this._urlTest(path, new RegExp('^' + source + (this.hasQueryParams ? '(\\?.*$|$)' : '$')));
// If no match, or no query params, no need to go further
if (!matched || !this.hasQueryParams) return matched;
// Extract query params
var queryParams = parseQueryParams(path);
var unexpectedQueryParams = Object.keys(queryParams).filter(function (p) {
return _this2.queryParams.concat(_this2.queryParamsBr).indexOf(p) === -1;
});
if (unexpectedQueryParams.length === 0) {
// Extend url match
Object.keys(queryParams).forEach(function (p) {
return matched[p] = queryParams[p];
});
return matched;
}
return null;
}
}, {
key: 'partialTest',
value: function partialTest(path, opts) {
var _this3 = this;
var options = _extends({ delimited: true }, opts);
// Check if partial match (start of given path matches regex)
// trailingSlash: falsy => non optional, truthy => optional
var source = upToDelimiter(this.source, options.delimited);
var match = this._urlTest(path, new RegExp('^' + source));
if (!match) return match;
if (!this.hasQueryParams) return match;
var queryParams = parseQueryParams(path);
Object.keys(queryParams).filter(function (p) {
return _this3.queryParams.concat(_this3.queryParamsBr).indexOf(p) >= 0;
}).forEach(function (p) {
return appendQueryParam(match, p, queryParams[p]);
});
if (!this.hasQueryParams) {
return match;
}
}, {
key: 'build',
value: function build() {
var _this4 = this;
var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var options = _extends({ ignoreConstraints: false, ignoreSearch: false }, opts);
var encodedParams = Object.keys(params).reduce(function (acc, key) {
if (!exists(params[key])) {
return acc;
}
var val = params[key];
var encode = _this4._isQueryParam(key) ? encodeURIComponent : encodeURI;
if (typeof val === 'boolean') {
acc[key] = val;
} else if (Array.isArray(val)) {
acc[key] = val.map(encode);
} else {
acc[key] = encode(val);
}
var queryParams = parse(path, options.queryParams);
Object.keys(queryParams)
.filter(function (p) { return _this.isQueryParam(p); })
.forEach(function (p) { return appendQueryParam(match, p, queryParams[p]); });
return match;
};
Path.prototype.build = function (params, opts) {
var _this = this;
if (params === void 0) { params = {}; }
var options = __assign({ ignoreConstraints: false, ignoreSearch: false, queryParams: {} }, opts);
var encodedUrlParams = Object.keys(params)
.filter(function (p) { return !_this.isQueryParam(p); })
.reduce(function (acc, key) {
if (!exists(params[key])) {
return acc;
}, {});
// Check all params are provided (not search parameters which are optional)
if (this.urlParams.some(function (p) {
return !exists(encodedParams[p]);
})) {
var missingParameters = this.urlParams.filter(function (p) {
return !exists(encodedParams[p]);
});
throw new Error('Cannot build path: \'' + this.path + '\' requires missing parameters { ' + missingParameters.join(', ') + ' }');
}
// Check constraints
if (!options.ignoreConstraints) {
var constraintsPassed = this.tokens.filter(function (t) {
return (/^url-parameter/.test(t.type) && !/-splat$/.test(t.type)
);
}).every(function (t) {
return new RegExp('^' + defaultOrConstrained(t.otherVal[0]) + '$').test(encodedParams[t.val]);
});
if (!constraintsPassed) throw new Error('Some parameters of \'' + this.path + '\' are of invalid format');
var val = params[key];
var encode = _this.isQueryParam(key) ? identity : encodeURI;
if (typeof val === 'boolean') {
acc[key] = val;
}
var base = this.tokens.filter(function (t) {
return (/^query-parameter/.test(t.type) === false
);
}).map(function (t) {
if (t.type === 'url-parameter-matrix') return ';' + t.val + '=' + encodedParams[t.val[0]];
return (/^url-parameter/.test(t.type) ? encodedParams[t.val[0]] : t.match
);
}).join('');
if (options.ignoreSearch) return base;
var queryParams = this.queryParams.concat(this.queryParamsBr.map(function (p) {
return p + '[]';
}));
var searchPart = queryParams.filter(function (p) {
return Object.keys(encodedParams).indexOf(withoutBrackets(p)) !== -1;
}).map(function (p) {
return _serialise(p, encodedParams[withoutBrackets(p)]);
}).join('&');
return base + (searchPart ? '?' + searchPart : '');
else if (Array.isArray(val)) {
acc[key] = val.map(encode);
}
else {
acc[key] = encode(val);
}
return acc;
}, {});
// Check all params are provided (not search parameters which are optional)
if (this.urlParams.some(function (p) { return !exists(params[p]); })) {
var missingParameters = this.urlParams.filter(function (p) { return !exists(params[p]); });
throw new Error("Cannot build path: '" +
this.path +
"' requires missing parameters { " +
missingParameters.join(', ') +
' }');
}
}]);
// Check constraints
if (!options.ignoreConstraints) {
var constraintsPassed = this.tokens
.filter(function (t) {
return /^url-parameter/.test(t.type) && !/-splat$/.test(t.type);
})
.every(function (t) {
return new RegExp('^' + defaultOrConstrained(t.otherVal[0]) + '$').test(encodedUrlParams[t.val]);
});
if (!constraintsPassed) {
throw new Error("Some parameters of '" + this.path + "' are of invalid format");
}
}
var base = this.tokens
.filter(function (t) { return /^query-parameter/.test(t.type) === false; })
.map(function (t) {
if (t.type === 'url-parameter-matrix') {
return ";" + t.val + "=" + encodedUrlParams[t.val[0]];
}
return /^url-parameter/.test(t.type)
? encodedUrlParams[t.val[0]]
: t.match;
})
.join('');
if (options.ignoreSearch) {
return base;
}
var searchParams = this.queryParams
.filter(function (p) { return Object.keys(params).indexOf(p) !== -1; })
.reduce(function (sparams, paramName) {
sparams[paramName] = params[paramName];
return sparams;
}, {});
var searchPart = build(searchParams, options.queryParams);
return searchPart ? base + '?' + searchPart : base;
};
Path.prototype.getParams = function (type) {
var predicate = type instanceof RegExp
? function (t) { return type.test(t.type); }
: function (t) { return t.type === type; };
return this.tokens.filter(predicate).map(function (t) { return t.val[0]; });
};
Path.prototype.urlTest = function (path, source, _a) {
var _this = this;
var _b = (_a === void 0 ? {} : _a).caseSensitive, caseSensitive = _b === void 0 ? false : _b;
var regex = new RegExp('^' + source, caseSensitive ? '' : 'i');
var match = path.match(regex);
if (!match) {
return null;
}
else if (!this.urlParams.length) {
return {};
}
// Reduce named params to key-value pairs
return match
.slice(1, this.urlParams.length + 1)
.reduce(function (params, m, i) {
params[_this.urlParams[i]] = decodeURIComponent(m);
return params;
}, {});
};
return Path;
}();
}());
export default Path;
{
"name": "path-parser",
"version": "3.0.1",
"description": "A small utility to parse, match and generate paths",
"main": "dist/cjs/path-parser.js",
"jsnext:main": "dist/es/path-parser.js",
"module": "dist/es/path-parser.js",
"scripts": {
"test": "mocha --compilers js:babel-core/register",
"test-cover": "babel-node node_modules/.bin/isparta cover node_modules/.bin/_mocha",
"lint": "eslint modules/*.js",
"build": "npm run clean && rollup -c rollup.config.js",
"clean": "rimraf dist",
"clog": "conventional-changelog -p angular -i CHANGELOG.md -s"
},
"repository": {
"type": "git",
"url": "https://github.com/troch/path-parser.git"
},
"keywords": [
"path",
"parser",
"url",
"route",
"match",
"partial match",
"regex"
],
"author": "Thomas Roch",
"license": "ISC",
"bugs": {
"url": "https://github.com/troch/path-parser/issues"
},
"homepage": "https://github.com/troch/path-parser",
"devDependencies": {
"babel-core": "~6.26.0",
"babel-eslint": "~8.0.2",
"babel-plugin-add-module-exports": "~0.2.1",
"babel-plugin-transform-class-properties": "~6.24.1",
"babel-plugin-transform-export-extensions": "~6.22.0",
"babel-plugin-transform-object-rest-spread": "~6.26.0",
"babel-preset-env": "~1.6.1",
"conventional-changelog": "~1.1.7",
"coveralls": "~3.0.0",
"eslint": "~4.11.0",
"isparta": "~4.0.0",
"mkdirp": "~0.5.1",
"mocha": "~4.0.1",
"rimraf": "~2.6.2",
"rollup": "~0.51.5",
"rollup-plugin-babel": "~3.0.2",
"should": "~13.1.3"
},
"dependencies": {
"search-params": "~1.3.0"
}
"name": "path-parser",
"version": "4.0.0",
"description": "A small utility to parse, match and generate paths",
"main": "dist/cjs/path-parser.js",
"jsnext:main": "dist/es/path-parser.js",
"module": "dist/es/path-parser.js",
"side-effects": false,
"typings": "./typings/index.d.ts",
"scripts": {
"test": "mocha -r ts-node/register 'test/main.js'",
"lint": "tslint modules/*.ts",
"build": "npm run clean && rollup -c rollup.config.js",
"clean": "rimraf dist && rimraf temp",
"clog": "conventional-changelog -p angular -i CHANGELOG.md -s",
"precommit": "lint-staged"
},
"lint-staged": {
"modules/*.ts": [
"prettier --write",
"tslint",
"git add"
],
"test/*.js": [
"prettier --write",
"git add"
]
},
"repository": {
"type": "git",
"url": "https://github.com/troch/path-parser.git"
},
"keywords": [
"path",
"parser",
"url",
"route",
"match",
"partial match",
"regex"
],
"author": "Thomas Roch",
"license": "ISC",
"bugs": {
"url": "https://github.com/troch/path-parser/issues"
},
"homepage": "https://github.com/troch/path-parser",
"devDependencies": {
"conventional-changelog": "~1.1.18",
"husky": "~0.14.3",
"lint-staged": "~7.0.0",
"mkdirp": "~0.5.1",
"mocha": "~5.0.4",
"prettier": "~1.11.1",
"rimraf": "~2.6.2",
"rollup": "~0.57.1",
"rollup-plugin-typescript2": "~0.12.0",
"should": "~13.2.1",
"ts-node": "~5.0.1",
"tslint": "~5.9.1",
"tslint-config-prettier": "~1.10.0",
"typescript": "~2.7.2"
},
"dependencies": {
"search-params": "2.1.1"
}
}
[![npm version](https://badge.fury.io/js/path-parser.svg)](http://badge.fury.io/js/path-parser)
[![Build Status](https://travis-ci.org/troch/path-parser.svg)](https://travis-ci.org/troch/path-parser)
[![Coverage Status](https://coveralls.io/repos/troch/path-parser/badge.svg?branch=master)](https://coveralls.io/r/troch/path-parser?branch=master)
# path-parser
A small utility to parse and build paths. It can be used to partially or fully
A small library to parse and build paths. It can be used to partially or fully
test paths against a defined pattern.

@@ -13,16 +12,26 @@

## Usage
```javascript
import Path from 'path-parser';
// Defining a new path
const p = new Path('/users/profile/:id');
import Path from 'path-parser'
const path = new Path('/users/:id')
// Matching
p.test('/users/profile/00123') // => {id: "00123"}
// Partial testing: does this path
// starts with that pattern?
p.partialTest('/users/profile/00123/orders') // => {id: "00123"}
p.partialTest('/profile/00123/orders') // => null
path.test('/users/00123')
// {
// id: "00123"
// }
// Partial testing: does the provided path
// starts with the defined pattern?
path.partialTest('/users/00123/orders')
// {
// id: "00123"
// }
path.partialTest('/profile/00123/orders')
// null
// Building
p.build({id: '00123'}) // => "users/profile/00123"
path.build({ id: '00123' })
// => "/users/00123"
```

@@ -33,5 +42,3 @@

```javascript
import Path from 'path-parser';
const p = Path.createPath('/users/profile/:id');
const path = Path.createPath('/users/:id')
```

@@ -41,10 +48,8 @@

- `:param`: for URL parameters
- `;param`: for matrix parameters
- `*splat`: for parameters spanning over multiple segments. Handle with care
- `?param1&param2` or `?:param1&:param2`: for query parameters. Colons `:` are optional.
- `?param1=a&param1=b` will result in `{param1: ['a', 'b']}`
- `?param1[]=a` and `?param1[]=a&param1[]=b` will result respectively in `{param1: ['a']}` and `{param1: ['a', 'b']}`
* `:param`: for URL parameters
* `;param`: for matrix parameters
* `*splat`: for parameters spanning over multiple segments. Handle with care
* `?param1&param2` or `?:param1&:param2`: for query parameters. Colons `:` are optional.
## Parameter constraints
#### Parameter constraints

@@ -54,4 +59,4 @@ For URL parameters and matrix parameters, you can add a constraint in the form of a regular expression.

- `:param<\\d+>` will match numbers only for parameter `param`
- `;id<[a-fA-F0-9]{8}` will match 8 characters hexadecimal strings for parameter `id`
* `:param<\\d+>` will match numbers only for parameter `param`
* `;id<[a-fA-F0-9]{8}` will match 8 characters hexadecimal strings for parameter `id`

@@ -62,36 +67,40 @@ Constraints are also applied when building paths, unless specified otherwise (set option flag `ignoreConstraints` to true).

// Path.build(params, opts)
var Path = new Path('/users/profile/:id<\d+>');
var Path = new Path('/users/:id<d+>')
path.build({id: 'not-a-number'}); // => Will throw an error
path.build({id: 'not-a-number'}, {ignoreConstraints: true}); // => '/users/profile/not-a-number'
path.build({ id: 'not-a-number' }) // => Will throw an error
path.build({ id: '123' }) // => '/users/123'
```
## Optional trailing slashes
## API
`.test(path, options)` accepts an option object:
- `trailingSlash`: if truthy, it will make trailing slashes optional (default to `true`).
```javascript
var path = new Path('/my-path');
### path.test(path: string, opts?: object): object | null;
path.test('/my-path/') // => null
path.test('/my-path/', { trailingSlash: true }) // => {}
```
Test if the provided path matches the defined path template. Options available are:
- `'caseSensitive'`: whether matching should be case sensitive or not (default to `false`)
- `'strictTrailingSlash'`: whether or not it should strictly match trailing slashes (default to `false`)
- `'queryParams'`: [options for query parameters](https://github.com/troch/search-params#options)
## Partial test with delimiters
`.partialTest(path, options)` accepts an option object:
- `delimited`: if truthy, a partial test will only be successful if a delimiter is found at the end of a match (default to `true`, delimiters are `/`, `?`, `.` and `;`).
### path.partialTest(path: string, opts?: object): object | null;
```javascript
var path = new Path('/my-path');
Test if the provided path is partially matched (starts with) the defined path template. Options available are:
- `'caseSensitive'`: whether matching should be case sensitive or not (default to `false`)
- `'delimited'`: whether or not a partial match should only be successful if it reaches a delimiter (`/`, `?`, `.` and `;`). Default to `true`.
- `'queryParams'`: [options for query parameters](https://github.com/troch/search-params#options)
path.partialTest('/my-path/extended') // => {}
path.partialTest('/my-path-extended') // => null
path.partialTest('/my-path-extended', { delimited: false }) // => {}
```
### path.build(params?: object, opts?: object): string;
Builds the defined path template with the provided parameters
- `'ignoreConstraints'`: whether or not to ignore parameter constraints (default to `false`)
- `'ignoreSearch'`: whether or not to build query parameters (default to `false`)
- `'caseSensitive'`: whether matching should be case sensitive or not (default to `false`)
- `'queryParams'`: [options for query parameters](https://github.com/troch/search-params#options)
## Related modules
- [route-parser](https://github.com/rcs/route-parser)
- [url-pattern](https://github.com/snd/url-pattern)
* [route-parser](https://github.com/rcs/route-parser)
* [url-pattern](https://github.com/snd/url-pattern)

Sorry, the diff of this file is not supported yet

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