exports.Key =
class Key
constructor: ( @name, @optional )->
@regex = /[\w\-\s]+/ # default url-friendly regex
exports.Key =
class Key
constructor: ( @name, @optional )->
@regex = /[\w\-\s]+/ # default url-friendly regex
special defaults for controllers & actions, which will always be function-name-safe
if @name == 'controller' || @name == 'action'
@regex = /[a-zA-Z_][\w\-]*/
regexString: ->
ret = String(@regex).replace(/^\//, '').replace /\/[gis]?$/, ''
"(#{ret})#{if @optional then '?' else ''}"
test: ( string )->
new RegExp("^#{@regexString()}$").test(string)
returns a string for building the url if it matches the key conditions
url: ( string )->
if @test(string) then string else false
where: ( conditions )->
condition = conditions[@name]
if condition instanceof RegExp
@regex = condition # e.g. /\d+/
if condition instanceof String
@regex = new RegExp condition.replace(/^\//, '').replace /\/[gis]?$/, '' # e.g. "\d+"
an array of allowed values, e.g. ['stop','play','pause']
if condition instanceof Array
@regex = new RegExp condition.map( (cond)->
cond.toString().replace(/^\//, '').replace /\/[gis]?$/, ''
).join '|'
this # chainable
returns a unique id that can be compared to other parts
toString: ->
"key-#{@name}"
exports.Glob =
class Glob extends Key
constructor: ( @name, @optional )->
@regex = /[\w\-\/\s]+?/ # default url-friendly regex
special defaults for controllers & actions, which will always be function-name-safe
if @name == 'controller' || @name == 'action'
@regex = /[a-zA-Z_][\w\-]*/