Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for named wildcards #44

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,15 @@ wildcard matches are collected in the `_` property:
if there is only one wildcard then `_` contains the matching string.
otherwise `_` contains an array of matching strings.

`*:` in a pattern is a named wildcard. the match will be
captured to the corresponding property instead of `_`:

```javascript
> var pattern = new UrlPattern('/search/*:term');
> pattern.match('/search/fruit');
{term: 'fruit'}
```

[look at the tests for additional examples of `.match`](test/match-fixtures.coffee)

## make pattern from regex
Expand Down
8 changes: 7 additions & 1 deletion lib/url-pattern.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 13 additions & 3 deletions src/url-pattern.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,15 @@

U.name = P.regex new RegExp "^[#{options.segmentNameCharset}]+"

U.namedWildcard = P.tag(
'namedWildcard',
P.pick(2,
P.string(options.wildcardChar)
P.string(options.segmentNameStartChar)
P.lazy(-> U.name)
)
)

U.named = P.tag(
'named',
P.pick(1,
Expand Down Expand Up @@ -235,6 +244,7 @@

U.token = P.lazy ->
P.firstChoice(
U.namedWildcard
U.wildcard
U.optional
U.named
Expand Down Expand Up @@ -266,7 +276,7 @@
baseAstNodeToRegexString(node, segmentValueCharset)

switch astNode.tag
when 'wildcard' then '(.*?)'
when 'wildcard', 'namedWildcard' then '(.*?)'
when 'named' then "([#{segmentValueCharset}]+)"
when 'static' then escapeForRegex(astNode.value)
when 'optional'
Expand All @@ -281,7 +291,7 @@

switch astNode.tag
when 'wildcard' then ['_']
when 'named' then [astNode.value]
when 'namedWildcard', 'named' then [astNode.value]
when 'static' then []
when 'optional' then astNodeToNames(astNode.value)

Expand Down Expand Up @@ -330,7 +340,7 @@

switch astNode.tag
when 'wildcard' then getParam params, '_', nextIndexes, true
when 'named' then getParam params, astNode.value, nextIndexes, true
when 'named', 'namedWildcard' then getParam params, astNode.value, nextIndexes, true
when 'static' then astNode.value
when 'optional'
if astNodeContainsSegmentsForProvidedParams astNode.value, params, nextIndexes
Expand Down
12 changes: 12 additions & 0 deletions test/ast.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ test 'astNodeToRegexString and astNodeToNames', (t) ->
t.deepEqual astNodeToNames(parsed.value), ['_']
t.end()

t.test 'just named wildcard', (t) ->
parsed = parse '*:variable'
t.equal astNodeToRegexString(parsed.value), '^(.*?)$'
t.deepEqual astNodeToNames(parsed.value), ['variable']
t.end()

t.test 'just optional static', (t) ->
parsed = parse '(foo)'
t.equal astNodeToRegexString(parsed.value), '^(?:foo)?$'
Expand All @@ -58,6 +64,12 @@ test 'astNodeToRegexString and astNodeToNames', (t) ->
t.deepEqual astNodeToNames(parsed.value), ['_']
t.end()

t.test 'just optional named wildcard', (t) ->
parsed = parse '(*:foo)'
t.equal astNodeToRegexString(parsed.value), '^(?:(.*?))?$'
t.deepEqual astNodeToNames(parsed.value), ['foo']
t.end()

test 'getParam', (t) ->
t.test 'no side effects', (t) ->
next = {}
Expand Down
9 changes: 9 additions & 0 deletions test/match-fixtures.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ test 'match', (t) ->
_: '/school/10',
userId: '10'

pattern = new UrlPattern '*:root/user/:userId'
t.deepEqual pattern.match('/school/10/user/10'),
root: '/school/10',
userId: '10'

pattern = new UrlPattern '*-user-:userId'
t.deepEqual pattern.match('-school-10-user-10'),
_: '-school-10'
Expand All @@ -53,6 +58,10 @@ test 'match', (t) ->
t.deepEqual pattern.match('/admin/school/10/user/10'),
_: '/school/10/user/10'

pattern = new UrlPattern '/admin*:tail'
t.deepEqual pattern.match('/admin/school/10/user/10'),
tail: '/school/10/user/10'

pattern = new UrlPattern '#admin*'
t.deepEqual pattern.match('#admin#school#10#user#10'),
_: '#school#10#user#10'
Expand Down
30 changes: 30 additions & 0 deletions test/parser.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,36 @@ test 'named', (t) ->
t.equal U.named('abc'), undefined
t.end()


test 'namedWildcard', (t) ->
t.deepEqual U.namedWildcard('*:a'),
value:
tag: 'namedWildcard'
value: 'a'
rest: ''
t.deepEqual U.namedWildcard('*:ab96c'),
value:
tag: 'namedWildcard'
value: 'ab96c'
rest: ''
t.deepEqual U.namedWildcard('*:ab96c.'),
value:
tag: 'namedWildcard'
value: 'ab96c'
rest: '.'
t.deepEqual U.namedWildcard('*:96c-:ab'),
value:
tag: 'namedWildcard'
value: '96c'
rest: '-:ab'
t.equal U.namedWildcard(':'), undefined
t.equal U.namedWildcard('*:'), undefined
t.equal U.namedWildcard('*'), undefined
t.equal U.namedWildcard(''), undefined
t.equal U.namedWildcard('a'), undefined
t.equal U.namedWildcard('abc'), undefined
t.end()

test 'static', (t) ->
t.deepEqual U.static('a'),
value:
Expand Down
9 changes: 9 additions & 0 deletions test/stringify-fixtures.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ test 'stringify', (t) ->
_: '/school/10',
userId: '10'

pattern = new UrlPattern '*:root/user/:userId'
t.equal '/school/10/user/10', pattern.stringify
root: '/school/10',
userId: '10'

pattern = new UrlPattern '*-user-:userId'
t.equal '-school-10-user-10', pattern.stringify
_: '-school-10'
Expand All @@ -35,6 +40,10 @@ test 'stringify', (t) ->
t.equal '/admin/school/10/user/10', pattern.stringify
_: '/school/10/user/10'

pattern = new UrlPattern '/admin*:tail'
t.equal '/admin/school/10/user/10', pattern.stringify
tail: '/school/10/user/10'

pattern = new UrlPattern '/admin/*/user/*/tail'
t.equal '/admin/school/10/user/10/12/tail', pattern.stringify
_: ['school/10', '10/12']
Expand Down
Loading