From 814469c2761a54e52805237392fba56f965aa3e4 Mon Sep 17 00:00:00 2001 From: mthaip Date: Fri, 9 Oct 2026 14:22:29 +0200 Subject: [PATCH 1/2] fix(withTrailingSlash): trailing slash detection with query slash --- src/utils.ts | 2 +- test/trailing-slash.test.ts | 24 +++++++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index ea98aba4..314ba5a7 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -12,7 +12,7 @@ const PROTOCOL_STRICT_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{1,2})/; const PROTOCOL_REGEX = /^[\s\w\0+.-]{2,}:([/\\]{2})?/; const PROTOCOL_RELATIVE_REGEX = /^([/\\]\s*){2,}[^/\\]/; const PROTOCOL_SCRIPT_RE = /^[\s\0]*(blob|data|javascript|vbscript):$/i; -const TRAILING_SLASH_RE = /\/$|\/\?|\/#/; +const TRAILING_SLASH_RE = /^[^?#]*\/(?:[?#]|$)/; const JOIN_LEADING_SLASH_RE = /^\.?\//; /** diff --git a/test/trailing-slash.test.ts b/test/trailing-slash.test.ts index af141d0a..1cabedeb 100644 --- a/test/trailing-slash.test.ts +++ b/test/trailing-slash.test.ts @@ -1,5 +1,9 @@ import { describe, expect, test } from "vitest"; -import { withTrailingSlash, withoutTrailingSlash } from "../src"; +import { + hasTrailingSlash, + withTrailingSlash, + withoutTrailingSlash, +} from "../src"; describe("withTrailingSlash, queryParams: false", () => { const tests = { @@ -31,6 +35,9 @@ describe("withTrailingSlash, queryParams: true", () => { "foo?123": "foo/?123", "foo/?123": "foo/?123", "foo?123#abc": "foo/?123#abc", + "foo?query=/": "foo/?query=/", + "foo?query=/#abc": "foo/?query=/#abc", + "foo/?query=/": "foo/?query=/", "/#abc": "/#abc", "#abc": "#abc", "#": "#", @@ -47,6 +54,21 @@ describe("withTrailingSlash, queryParams: true", () => { }); }); +describe("hasTrailingSlash, queryParams: true", () => { + const tests = { + "foo?query=/": false, + "foo?query=/#abc": false, + "foo/?query=/": true, + "foo/#abc": true, + }; + + for (const input in tests) { + test(input, () => { + expect(hasTrailingSlash(input, true)).toBe(tests[input]); + }); + } +}); + describe("withoutTrailingSlash, queryParams: false", () => { const tests = { "": "/", From dca325197708d758fd5993488391650c876d08f6 Mon Sep 17 00:00:00 2001 From: mthaip Date: Fri, 9 Oct 2026 20:28:58 +0200 Subject: [PATCH 2/2] test(trailing-slash): Add more test cases to withTrailingSlash & hasTrailingSlash --- test/trailing-slash.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/trailing-slash.test.ts b/test/trailing-slash.test.ts index 1cabedeb..62c7313a 100644 --- a/test/trailing-slash.test.ts +++ b/test/trailing-slash.test.ts @@ -37,6 +37,7 @@ describe("withTrailingSlash, queryParams: true", () => { "foo?123#abc": "foo/?123#abc", "foo?query=/": "foo/?query=/", "foo?query=/#abc": "foo/?query=/#abc", + "/foo#/bar/": "/foo/#/bar/", "foo/?query=/": "foo/?query=/", "/#abc": "/#abc", "#abc": "#abc", @@ -58,6 +59,7 @@ describe("hasTrailingSlash, queryParams: true", () => { const tests = { "foo?query=/": false, "foo?query=/#abc": false, + "/foo#/bar/": false, "foo/?query=/": true, "foo/#abc": true, };