diff --git a/.gitignore b/.gitignore index 446bcb2..bd49483 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ coverage/ node_modules/ npm-debug.log -temp/ \ No newline at end of file +temp/ +package-lock.json \ No newline at end of file diff --git a/README.md b/README.md index 38b7bf8..9b6532b 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ path.build({ id: '123' }) // => '/users/123' 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`) +- `'optionalQueryParams'`: whether or not it should match query params (default to `false`) - `'queryParams'`: [options for query parameters](https://github.com/troch/search-params#options) diff --git a/dist/cjs/path-parser.js b/dist/cjs/path-parser.js index e6d8908..a692217 100644 --- a/dist/cjs/path-parser.js +++ b/dist/cjs/path-parser.js @@ -19,12 +19,15 @@ See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ -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 __assign = function() { + __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; + }; + return __assign.apply(this, arguments); }; var defaultOrConstrained = function (match) { @@ -167,7 +170,7 @@ var Path = /** @class */ (function () { }; Path.prototype.test = function (path, opts) { var _this = this; - var options = __assign({ strictTrailingSlash: false, queryParams: {} }, opts); + var options = __assign({ strictTrailingSlash: false, optionalQueryParams: false, queryParams: {} }, opts); // trailingSlash: falsy => non optional, truthy => optional var source = optTrailingSlash(this.source, options.strictTrailingSlash); // Check if exact match @@ -178,10 +181,14 @@ var Path = /** @class */ (function () { } // Extract query params var queryParams = searchParams.parse(path, options.queryParams); - var unexpectedQueryParams = Object.keys(queryParams).filter(function (p) { return !_this.isQueryParam(p); }); + var unexpectedQueryParams = options.optionalQueryParams + ? [] + : 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]); }); + Object.keys(queryParams).forEach(function (p) { + match[p] = queryParams[p]; + }); return match; } return null; diff --git a/dist/es/path-parser.js b/dist/es/path-parser.js index 0d1c0ec..6912557 100644 --- a/dist/es/path-parser.js +++ b/dist/es/path-parser.js @@ -15,12 +15,15 @@ See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ -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 __assign = function() { + __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; + }; + return __assign.apply(this, arguments); }; var defaultOrConstrained = function (match) { @@ -163,7 +166,7 @@ var Path = /** @class */ (function () { }; Path.prototype.test = function (path, opts) { var _this = this; - var options = __assign({ strictTrailingSlash: false, queryParams: {} }, opts); + var options = __assign({ strictTrailingSlash: false, optionalQueryParams: false, queryParams: {} }, opts); // trailingSlash: falsy => non optional, truthy => optional var source = optTrailingSlash(this.source, options.strictTrailingSlash); // Check if exact match @@ -174,10 +177,14 @@ var Path = /** @class */ (function () { } // Extract query params var queryParams = parse(path, options.queryParams); - var unexpectedQueryParams = Object.keys(queryParams).filter(function (p) { return !_this.isQueryParam(p); }); + var unexpectedQueryParams = options.optionalQueryParams + ? [] + : 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]); }); + Object.keys(queryParams).forEach(function (p) { + match[p] = queryParams[p]; + }); return match; } return null; diff --git a/modules/Path.ts b/modules/Path.ts index a48763f..646a131 100644 --- a/modules/Path.ts +++ b/modules/Path.ts @@ -53,6 +53,7 @@ export interface IPartialTestOptions { export interface ITestOptions { caseSensitive?: boolean strictTrailingSlash?: boolean + optionalQueryParams?: boolean queryParams?: IOptions } @@ -116,7 +117,12 @@ export class Path { } public test(path: string, opts?: ITestOptions): TestMatch { - const options = { strictTrailingSlash: false, queryParams: {}, ...opts } + const options = { + strictTrailingSlash: false, + optionalQueryParams: false, + queryParams: {}, + ...opts + } // trailingSlash: falsy => non optional, truthy => optional const source = optTrailingSlash( this.source, @@ -134,14 +140,14 @@ export class Path { } // Extract query params const queryParams = parseQueryParams(path, options.queryParams) - const unexpectedQueryParams = Object.keys(queryParams).filter( - p => !this.isQueryParam(p) - ) - + const unexpectedQueryParams = options.optionalQueryParams + ? [] + : Object.keys(queryParams).filter(p => !this.isQueryParam(p)) if (unexpectedQueryParams.length === 0) { // Extend url match - Object.keys(queryParams).forEach(p => (match[p] = queryParams[p])) - + Object.keys(queryParams).forEach(p => { + match[p] = queryParams[p] + }) return match } diff --git a/package.json b/package.json index 4877b53..47a3639 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "sideEffects": false, "typings": "./typings/Path.d.ts", "scripts": { - "test": "mocha -r ts-node/register 'test/main.js'", + "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", diff --git a/test/main.js b/test/main.js index 4aeaaeb..017e8b4 100644 --- a/test/main.js +++ b/test/main.js @@ -65,7 +65,6 @@ describe('Path', function() { .test('/users?offset=1&limit=15') .should.eql({ offset: '1', limit: '15' }) path.test('/users?limit=15').should.eql({ limit: '15' }) - path.test('/users?limit=15').should.eql({ limit: '15' }) path .partialTest('/users?offset=true&limits=1', { queryParams: { booleanFormat: 'string' } @@ -137,7 +136,7 @@ describe('Path', function() { path .partialTest('/users/profile/123-456') .should.eql({ id: '123', id2: '456' }) - // Un,successful match + // Unsuccessful match should.not.exist(path.test('/users/details/123-456')) should.not.exist(path.test('/users/profile/123-456?id3=789&id4=000')) @@ -296,4 +295,23 @@ describe('Path', function() { param: '1+2=3@*' }) }) + + it('should match path and query params when query params are optional', function() { + const path = new Path('/users/profile/:id?name&surname') + // Successful match + path + .test('/users/profile/123', { optionalQueryParams: true }) + .should.eql({ id: '123' }) + path + .test('/users/profile/123?name=John&test=match', { + optionalQueryParams: true + }) + .should.eql({ id: '123', name: 'John', test: 'match' }) + + // Unsuccessful match + should.not.exist(path.test('/users/profile/123')) + should.not.exist( + path.test('/users/profile/123', { optionalQueryParams: false }) + ) + }) }) diff --git a/typings/Path.d.ts b/typings/Path.d.ts index c44a0d6..f079b79 100644 --- a/typings/Path.d.ts +++ b/typings/Path.d.ts @@ -8,6 +8,7 @@ export interface IPartialTestOptions { export interface ITestOptions { caseSensitive?: boolean; strictTrailingSlash?: boolean; + optionalQueryParams?: boolean; queryParams?: IOptions; } export interface IBuildOptions {