Skip to content

Commit 7e1b23d

Browse files
committed
fix: match multi-variable URI template paths
1 parent f2a3320 commit 7e1b23d

3 files changed

Lines changed: 20 additions & 0 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@modelcontextprotocol/core': patch
3+
---
4+
5+
Fix `UriTemplate.match()` for comma-separated simple expressions such as `/users/{userId,format}`.

packages/core/src/shared/uriTemplate.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,15 @@ export class UriTemplate {
227227

228228
switch (part.operator) {
229229
case '': {
230+
if (!part.exploded && part.names.length > 1) {
231+
for (let i = 0; i < part.names.length; i++) {
232+
patterns.push({
233+
pattern: (i === 0 ? '' : ',') + '([^/,]+)',
234+
name: part.names[i]!
235+
});
236+
}
237+
return patterns;
238+
}
230239
pattern = part.exploded ? '([^/,]+(?:,[^/,]+)*)' : '([^/,]+)';
231240
break;
232241
}

packages/core/test/shared/uriTemplate.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ describe('UriTemplate', () => {
9898
expect(match).toEqual({ username: 'fred', postId: '123' });
9999
});
100100

101+
it('should match comma-separated variables in one expression', () => {
102+
const template = new UriTemplate('/users/{userId,format}');
103+
const match = template.match('/users/42,json');
104+
expect(match).toEqual({ userId: '42', format: 'json' });
105+
});
106+
101107
it('should return null for non-matching URIs', () => {
102108
const template = new UriTemplate('/users/{username}');
103109
const match = template.match('/posts/123');

0 commit comments

Comments
 (0)