Repository navigation
fix(client): keep a param value of "index" in $url() and $path() - #5297
Merged
yusukebe merged 1 commit intoAug 27, 2026
Merged
Conversation
removeIndexString() strips a trailing /index so that the synthetic .index
accessor resolves to the route it aliases. In the $url()/$path() branch it ran
after the params had been substituted, so anything that merely looked like the
alias once substitution was done got stripped as well:
client.docs[':page'].$path({ param: { page: 'index' } }) // "/docs"
client.index[':v?'].$path({ param: { v: undefined } }) // "/"
The second is a route with a literal /index segment; "/" does not match it and
returns 404, so that URL never pointed at the route it came from.
The alias belongs to the route template and neither of those does, so the strip
now runs before substitution. ClientRequestImpl.fetch already does it in that
order, which is why $get() has always returned the right path for these routes
while $url() and $path() did not.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5297 +/- ##
==========================================
- Coverage 79.88% 79.87% -0.01%
==========================================
Files 156 156
Lines 10925 10924 -1
Branches 2301 2301
==========================================
- Hits 8727 8726 -1
Misses 2198 2198 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
3 of 4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
removeIndexString()strips a trailing/indexso the synthetic.indexaccessor resolves to the route it aliases. In the
$url()/$path()branch itruns after the path params have been substituted, so anything that merely
looks like the alias once substitution is done gets stripped as well.
Moving the call ahead of substitution fixes it: the alias is part of the route
template, and a param value is not.
Before / after
/docs/:pageparam: { page: 'index' }/docs/docs/index/:pageparam: { page: 'index' }//index/index/:v?param: { v: undefined }//indexThe third row is a route with a literal
/indexsegment rather than a paramvalue. Dispatching against that route alone,
/returns 404 and/indexreturns 200, so the generated URL did not point at the route it came from.
Why this ordering
ClientRequestImpl.fetchhas doneremoveIndexString→replaceUrlParamsincehcwas introduced in #862, which is why$get()already returns the right pathfor all three rows above and only
$url()/$path()disagreed.This is a follow-up to #4267, which added the
removeIndexStringcall to thisbranch (fixing #4265) and placed it at the end of the sequence, immediately
before
return new URL(result). Moving it to the front brings the branch in linewith
fetch.removeIndexString's(?=\?|$)lookahead, added in #4352, is left as-is: it isstill exercised directly by
src/client/utils.test.ts, even though nohccallsite now passes it a query string.
Relationship to #5291
#5291 adds the same normalization to the
$ws()branch. The two are independenthunks in the same function and complementary. I merged them locally in a scratch
branch to check: no conflict, and
src/client/client.test.tspasses 128 withboth applied. With both in, all four accessors (
$get(),$url(),$path(),$ws()) strip the alias from the route template before substituting params.Happy to rebase on top of #5291 if it lands first.
Tests
5 tests added, 9 executions — four of them sit in the
$path/$urldescribe.each, and one in the query-option block. 7 fail onmain. The onethat passes either way —
Should still drop the index alias of a route with a param— is a regression guard that the genuine alias is still removed.Verification
npx vitest --run src/client/client.test.ts— 127 passed (120 withclient.tsreverted to
main, 7 failed)npx tsc -p tsconfig.spec.json— exit 0npx eslint src— exit 0npx vitest --run: green with--coverage.enabled=false. With coverageon I see at least one pre-existing 5 s timeout,
src/middleware/compress/index.test.ts"should compress streaming responseswritten in multiple chunks", which reproduces identically on a clean
maincheckout and passes 45/45 in isolation.
The author should do the following, if applicable
bun run format:fix && bun run lint:fixto format the code (verified withprettier --checkandeslintdirectly; the fixer itself rewrites every line ending on a CRLF checkout)