From af309f2ec5e4d4dd00ded77377f1b11c4caa28d8 Mon Sep 17 00:00:00 2001 From: easing Date: Tue, 9 Apr 2024 05:06:32 +0700 Subject: [PATCH] Fix regular expression for optional params --- README.md | 2 +- index.js | 6 ++++-- package.json | 4 ++-- test/router.test.ts | 12 ++++++++++++ 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e18fe18..d0528ee 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ A tiny URL router for [Nano Stores](https://github.com/nanostores/nanostores) state manager. -* **Small.** 685 bytes (minified and brotlied). Zero dependencies. +* **Small.** 696 bytes (minified and brotlied). Zero dependencies. * Good **TypeScript** support. * Framework agnostic. Can be used with **React**, **Preact**, **Vue**, **Svelte**, **Angular**, **Solid.js**, and vanilla JS. diff --git a/index.js b/index.js index 5a6b809..cbf9084 100644 --- a/index.js +++ b/index.js @@ -9,14 +9,16 @@ export function createRouter(routes, opts = {}) { let names = value.match(/(?<=\/:)\w+/g) || [] let pattern = value .replace(/[\s!#$()+,.:<=?[\\\]^{|}]/g, '\\$&') - .replace(/\/\\:\w+\\\?/g, '/?([^/]*)') + .replace(/\/\\:\w+\\\?/g, '(?:/((?<=/)[^/]+))?') .replace(/\/\\:\w+/g, '/([^/]+)') return [ name, RegExp('^' + pattern + '$', 'i'), (...matches) => matches.reduce((params, match, index) => { - params[names[index]] = decodeURIComponent(match) + // match === undefined when nothing captured in regexp group + // and we swap it with empty string for backward compatibility + params[names[index]] = match ? decodeURIComponent(match) : '' return params }, {}), value diff --git a/package.json b/package.json index a6c9565..389f05a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@nanostores/router", "version": "0.14.1", - "description": "A tiny (685 bytes) router for Nano Stores state manager", + "description": "A tiny (696 bytes) router for Nano Stores state manager", "keywords": [ "nano", "router", @@ -103,7 +103,7 @@ "import": { "./index.js": "{ createRouter }" }, - "limit": "685 B" + "limit": "696 B" } ], "clean-publish": { diff --git a/test/router.test.ts b/test/router.test.ts index bb8e471..b01472b 100644 --- a/test/router.test.ts +++ b/test/router.test.ts @@ -185,6 +185,18 @@ test('parameters can be optional', () => { route: 'optional', search: {} }) + + changePath('/profile//') + deepStrictEqual(router.get(), undefined) + + changePath('/profile///') + deepStrictEqual(router.get(), undefined) + + changePath('/profile-missed-route') + deepStrictEqual(router.get(), undefined) + + changePath('/profile/10/contacts/20') + deepStrictEqual(router.get(), undefined) }) test('detects URL changes', () => {