])
})
+ it('param custom re followed by static', () => {
+ expect(tokenizePath('/:id(\\d+)hey')).toEqual([
+ [
+ {
+ type: TokenType.Param,
+ value: 'id',
+ regexp: '\\d+',
+ repeatable: false,
+ optional: false,
+ },
+ {
+ type: TokenType.Static,
+ value: 'hey',
+ },
+ ],
+ ])
+ })
+
+ it('param custom re followed by new segment', () => {
+ expect(tokenizePath('/:id(\\d+)/new')).toEqual([
+ [
+ {
+ type: TokenType.Param,
+ value: 'id',
+ regexp: '\\d+',
+ repeatable: false,
+ optional: false,
+ },
+ ],
+ [
+ {
+ type: TokenType.Static,
+ value: 'new',
+ },
+ ],
+ ])
+ })
+
+ it('param custom re?', () => {
+ expect(tokenizePath('/:id(\\d+)?')).toEqual([
+ [
+ {
+ type: TokenType.Param,
+ value: 'id',
+ regexp: '\\d+',
+ repeatable: false,
+ optional: true,
+ },
+ ],
+ ])
+ })
+
+ it('param custom re? followed by static', () => {
+ expect(tokenizePath('/:id(\\d+)?hey')).toEqual([
+ [
+ {
+ type: TokenType.Param,
+ value: 'id',
+ regexp: '\\d+',
+ repeatable: false,
+ optional: true,
+ },
+ {
+ type: TokenType.Static,
+ value: 'hey',
+ },
+ ],
+ ])
+ })
+
+ it('param custom re? followed by new segment', () => {
+ expect(tokenizePath('/:id(\\d+)?/new')).toEqual([
+ [
+ {
+ type: TokenType.Param,
+ value: 'id',
+ regexp: '\\d+',
+ repeatable: false,
+ optional: true,
+ },
+ ],
+ [
+ {
+ type: TokenType.Static,
+ value: 'new',
+ },
+ ],
+ ])
+ })
+
it('param single?', () => {
expect(tokenizePath('/:id?')).toEqual([
[
Static,
Param,
ParamRegExp, // custom re for a param
+ ParamRegExpEnd, // check if there is any ? + *
EscapeNext,
}
})
} else if (
state === TokenizerState.Param ||
- state === TokenizerState.ParamRegExp
+ state === TokenizerState.ParamRegExp ||
+ state === TokenizerState.ParamRegExpEnd
) {
if (segment.length > 1 && (char === '*' || char === '+'))
crash(
consumeBuffer()
state = TokenizerState.Static
// go back one character if we were not modifying
- if (char !== '*' && char !== '?' && char !== '+') {
- i--
- }
+ if (char !== '*' && char !== '?' && char !== '+') i--
}
break
case TokenizerState.ParamRegExp:
if (char === ')') {
- consumeBuffer()
- state = TokenizerState.Static
+ state = TokenizerState.ParamRegExpEnd
} else {
customRe += char
}
break
+ case TokenizerState.ParamRegExpEnd:
+ // same as finalizing a param
+ consumeBuffer()
+ state = TokenizerState.Static
+ // go back one character if we were not modifying
+ if (char !== '*' && char !== '?' && char !== '+') i--
+ break
+
default:
crash('Unkwnonw state')
break
optional: token.optional,
})
const re = token.regexp ? token.regexp : BASE_PARAM_PATTERN
+ if (re !== BASE_PARAM_PATTERN) {
+ try {
+ new RegExp(re)
+ } catch (err) {
+ throw new Error(
+ `Invalid custom RegExp for param "${token.value}": ` + err.message
+ )
+ }
+ }
pattern += token.repeatable ? `((?:${re})(?:/(?:${re}))*)` : `(${re})`
if (token.optional) pattern += '?'
}