mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-07-04 12:01:52 +02:00
fix: Resolve : ambiguity in URL path placeholders (#465)
Co-authored-by: Simon Johansson <simon.johansson@infor.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Gregory Schier <gschier1990@gmail.com>
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
import { describe, expect, test } from "vite-plus/test";
|
||||
import { extractPathPlaceholders } from "./pathPlaceholders";
|
||||
|
||||
describe("extractPathPlaceholders", () => {
|
||||
test("extracts a single placeholder", () => {
|
||||
expect(extractPathPlaceholders("/users/:id")).toEqual([":id"]);
|
||||
});
|
||||
|
||||
test("extracts multiple placeholders", () => {
|
||||
expect(extractPathPlaceholders("/users/:id/posts/:postId")).toEqual([":id", ":postId"]);
|
||||
});
|
||||
|
||||
test("stops at a literal `:` in the same segment", () => {
|
||||
expect(extractPathPlaceholders("/tasks/:id:cancel")).toEqual([":id"]);
|
||||
});
|
||||
|
||||
test("does not match `:foo` mid-segment", () => {
|
||||
expect(extractPathPlaceholders("/users/abc:def")).toEqual([]);
|
||||
});
|
||||
|
||||
test("does not match `:` in a host port", () => {
|
||||
expect(extractPathPlaceholders("https://example.com:8080/users/:id")).toEqual([":id"]);
|
||||
});
|
||||
|
||||
test("returns empty for a URL with no placeholders", () => {
|
||||
expect(extractPathPlaceholders("https://example.com/foo/bar?q=1#hash")).toEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Extract `:name`-style path placeholders from a URL string.
|
||||
*
|
||||
* A placeholder is `:` followed by one-or-more characters that are not `/`, `?`,
|
||||
* `#`, or `:`. The `:` boundary means a placeholder ends where a literal colon
|
||||
* starts in the same segment, e.g. `/tasks/:id:increment-importance` yields one
|
||||
* placeholder `:id` and `:increment-importance` is literal text.
|
||||
*
|
||||
* Only `:` that sits at the start of a `/`-delimited segment counts — `/abc:def`
|
||||
* has no placeholders. Returned names include the leading colon.
|
||||
*/
|
||||
export function extractPathPlaceholders(url: string): string[] {
|
||||
return Array.from(url.matchAll(/\/(:[^/?#:]+)/g)).map((m) => m[1] ?? "");
|
||||
}
|
||||
Reference in New Issue
Block a user