fix(core): match multi-variable URI templates like {a,b} (#2166) - #2170
fix(core): match multi-variable URI templates like {a,b} (#2166)#2170NishchayMahor wants to merge 1 commit into
{a,b} (#2166)#2170Conversation
🦋 Changeset detectedLatest commit: 0c20a9b The changes in this PR will be included in the next version bump. This PR includes changesets to release 6 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@modelcontextprotocol/client
@modelcontextprotocol/codemod
@modelcontextprotocol/core
@modelcontextprotocol/server
@modelcontextprotocol/server-legacy
@modelcontextprotocol/express
@modelcontextprotocol/fastify
@modelcontextprotocol/hono
@modelcontextprotocol/node
commit: |
|
Heads up on the red |
17e6435 to
e7f131e
Compare
…extprotocol#2166) `UriTemplate.expand` already joins multi-name expansions with commas, but `match` only emitted one regex capture per part and assigned the whole captured run to the first name. Anything past the first variable silently never matched and resources registered against templates like `data://users/{userId,format}` were unreachable. Emit one capture per name with literal commas between them in `partToRegExp`, mirroring what `expandPart` produces, so round tripping through expand and match recovers the original variables. Path / label / fragment operators get their existing literal prefix on the first capture; the bare and reserved cases just sit at the current position.
e7f131e to
0c20a9b
Compare
|
Rebased onto The bug is still live on
Worth noting the reserved and fragment forms fail differently: Single-name parts and the
One thing worth flagging rather than leaving for you to find: #2216 and #2218 fix the same issue. #2218 is still against the old |
Closes #2166.
What's wrong
UriTemplate.expandalready supports multi-variable expansions like{userId,format}and produces values joined by commas.UriTemplate.matchonly emitted a single regex capture per part and assigned the entire captured run topart.name, so everything past the first variable was silently dropped. Any resource registered with a template such asdata://users/{userId,format}never routed becausematch()returnednull.Minimal repro:
The fix
packages/core/src/shared/uriTemplate.ts:partToRegExp, whenpart.names.length > 1and the operator is not?/&, emit one capture per name with a literal comma between captures, mirroring the comma joinexpandPartalready does./,\\.,#), so path / label / fragment operators keep matching like they did for the single-variable case.?and&(form-style query strings) were already handled by the earlier branch and are untouched.Tests
packages/core/test/shared/uriTemplate.test.ts:{userId,format}template against42,jsondata://users/{userId,format}{/userId,format})pnpm --filter @modelcontextprotocol/core lintandtypecheckclean. Lefthook pre-push (typecheck, build, lint) all green.