@rangojs/router 0.0.0-experimental.76 → 0.0.0-experimental.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vite/index.js
CHANGED
|
@@ -1864,7 +1864,7 @@ import { resolve } from "node:path";
|
|
|
1864
1864
|
// package.json
|
|
1865
1865
|
var package_default = {
|
|
1866
1866
|
name: "@rangojs/router",
|
|
1867
|
-
version: "0.0.0-experimental.
|
|
1867
|
+
version: "0.0.0-experimental.77",
|
|
1868
1868
|
description: "Django-inspired RSC router with composable URL patterns",
|
|
1869
1869
|
keywords: [
|
|
1870
1870
|
"react",
|
|
@@ -3580,11 +3580,19 @@ function substituteRouteParams(pattern, params, encode = encodeURIComponent) {
|
|
|
3580
3580
|
let hadOmittedOptional = false;
|
|
3581
3581
|
for (const [key, value] of Object.entries(params)) {
|
|
3582
3582
|
const escaped = escapeRegExp2(key);
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3583
|
+
if (value === "") {
|
|
3584
|
+
result = result.replace(
|
|
3585
|
+
new RegExp(`:${escaped}(\\([^)]*\\))?(?!\\?)`),
|
|
3586
|
+
""
|
|
3587
|
+
);
|
|
3588
|
+
result = result.replace(`*${key}`, "");
|
|
3589
|
+
} else {
|
|
3590
|
+
result = result.replace(
|
|
3591
|
+
new RegExp(`:${escaped}(\\([^)]*\\))?\\??`),
|
|
3592
|
+
encode(value)
|
|
3593
|
+
);
|
|
3594
|
+
result = result.replace(`*${key}`, encode(value));
|
|
3595
|
+
}
|
|
3588
3596
|
}
|
|
3589
3597
|
result = result.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)(\([^)]*\))?\?/g, () => {
|
|
3590
3598
|
hadOmittedOptional = true;
|
package/package.json
CHANGED
package/src/reverse.ts
CHANGED
|
@@ -311,7 +311,10 @@ export function createReverse<TRoutes extends Record<string, string>>(
|
|
|
311
311
|
/:([a-zA-Z_][a-zA-Z0-9_]*)(\([^)]*\))?(\?)/g,
|
|
312
312
|
(_, key, _constraint, optional) => {
|
|
313
313
|
const value = params[key];
|
|
314
|
-
|
|
314
|
+
// Empty string is treated as omitted — the trie matcher fills
|
|
315
|
+
// unmatched optional params with "" (not undefined), so reverse
|
|
316
|
+
// must collapse those segments instead of leaving empty slots.
|
|
317
|
+
if (value === undefined || value === "") {
|
|
315
318
|
hadOmittedOptional = true;
|
|
316
319
|
return "";
|
|
317
320
|
}
|
|
@@ -174,7 +174,10 @@ export function createReverseFunction(
|
|
|
174
174
|
/:([a-zA-Z_][a-zA-Z0-9_]*)(\([^)]*\))?(\?)/g,
|
|
175
175
|
(_, key) => {
|
|
176
176
|
const value = effectiveParams[key];
|
|
177
|
-
|
|
177
|
+
// Empty string is treated as omitted — the trie matcher fills
|
|
178
|
+
// unmatched optional params with "" (not undefined), so reverse
|
|
179
|
+
// must collapse those segments instead of leaving empty slots.
|
|
180
|
+
if (value === undefined || value === "") {
|
|
178
181
|
hadOmittedOptional = true;
|
|
179
182
|
return "";
|
|
180
183
|
}
|
|
@@ -41,14 +41,28 @@ export function substituteRouteParams(
|
|
|
41
41
|
let result = pattern;
|
|
42
42
|
let hadOmittedOptional = false;
|
|
43
43
|
|
|
44
|
-
// First pass: substitute provided params
|
|
44
|
+
// First pass: substitute provided params.
|
|
45
|
+
// Empty string on an optional placeholder is treated as omitted (the trie
|
|
46
|
+
// matcher fills unmatched optionals with "" — letting the second pass
|
|
47
|
+
// strip them keeps slash cleanup consistent). Empty string on required
|
|
48
|
+
// `:key` or wildcard `*key` still substitutes, matching prior behaviour.
|
|
45
49
|
for (const [key, value] of Object.entries(params)) {
|
|
46
50
|
const escaped = escapeRegExp(key);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
if (value === "") {
|
|
52
|
+
// Only replace required placeholders (negative lookahead for `?`);
|
|
53
|
+
// leave `:key?` for the second pass.
|
|
54
|
+
result = result.replace(
|
|
55
|
+
new RegExp(`:${escaped}(\\([^)]*\\))?(?!\\?)`),
|
|
56
|
+
"",
|
|
57
|
+
);
|
|
58
|
+
result = result.replace(`*${key}`, "");
|
|
59
|
+
} else {
|
|
60
|
+
result = result.replace(
|
|
61
|
+
new RegExp(`:${escaped}(\\([^)]*\\))?\\??`),
|
|
62
|
+
encode(value),
|
|
63
|
+
);
|
|
64
|
+
result = result.replace(`*${key}`, encode(value));
|
|
65
|
+
}
|
|
52
66
|
}
|
|
53
67
|
|
|
54
68
|
// Second pass: strip remaining optional param placeholders not in params
|