http_router 0.8.11 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,668 @@
1
+ (function() {
2
+ var Sherpa;
3
+ var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
4
+ for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
5
+ function ctor() { this.constructor = child; }
6
+ ctor.prototype = parent.prototype;
7
+ child.prototype = new ctor;
8
+ child.__super__ = parent.prototype;
9
+ return child;
10
+ };
11
+ root.Sherpa = Sherpa = (function() {
12
+ var Glob, Lookup, Node, Path, PathRequest, RegexMatcher, RegexPath, Request, RequestMatcher, Response, Route, SpanningRegexMatcher, Variable;
13
+ function Sherpa(callback) {
14
+ this.callback = callback;
15
+ this.root = new Node();
16
+ this.routes = {};
17
+ }
18
+ Sherpa.prototype.match = function(httpRequest, httpResponse) {
19
+ var request;
20
+ request = (httpRequest.url != null) ? new Request(httpRequest) : new PathRequest(httpRequest);
21
+ this.root.match(request);
22
+ if (request.destinations.length > 0) {
23
+ return new Response(request, httpResponse).invoke();
24
+ } else if (this.callback != null) {
25
+ return this.callback(request.underlyingRequest);
26
+ }
27
+ };
28
+ Sherpa.prototype.findSubparts = function(part) {
29
+ var match, subparts;
30
+ subparts = [];
31
+ while (match = part.match(/\\.|[:*][a-z0-9_]+|[^:*\\]+/)) {
32
+ part = part.slice(match.index, part.length);
33
+ subparts.push(part.slice(0, match[0].length));
34
+ part = part.slice(match[0].length, part.length);
35
+ }
36
+ return subparts;
37
+ };
38
+ Sherpa.prototype.generatePaths = function(path) {
39
+ var add, c, charIndex, chars, endIndex, pathIndex, paths, startIndex, _ref, _ref2;
40
+ _ref = [[''], path.split(''), 0, 1], paths = _ref[0], chars = _ref[1], startIndex = _ref[2], endIndex = _ref[3];
41
+ for (charIndex = 0, _ref2 = chars.length; 0 <= _ref2 ? charIndex < _ref2 : charIndex > _ref2; 0 <= _ref2 ? charIndex++ : charIndex--) {
42
+ c = chars[charIndex];
43
+ switch (c) {
44
+ case '\\':
45
+ charIndex++;
46
+ add = chars[charIndex] === ')' || chars[charIndex] === '(' ? chars[charIndex] : "\\" + chars[charIndex];
47
+ for (pathIndex = startIndex; startIndex <= endIndex ? pathIndex < endIndex : pathIndex > endIndex; startIndex <= endIndex ? pathIndex++ : pathIndex--) {
48
+ paths[pathIndex] += add;
49
+ }
50
+ break;
51
+ case '(':
52
+ for (pathIndex = startIndex; startIndex <= endIndex ? pathIndex < endIndex : pathIndex > endIndex; startIndex <= endIndex ? pathIndex++ : pathIndex--) {
53
+ paths.push(paths[pathIndex]);
54
+ }
55
+ startIndex = endIndex;
56
+ endIndex = paths.length;
57
+ break;
58
+ case ')':
59
+ startIndex -= endIndex - startIndex;
60
+ break;
61
+ default:
62
+ for (pathIndex = startIndex; startIndex <= endIndex ? pathIndex < endIndex : pathIndex > endIndex; startIndex <= endIndex ? pathIndex++ : pathIndex--) {
63
+ paths[pathIndex] += c;
64
+ }
65
+ }
66
+ }
67
+ paths.reverse();
68
+ return paths;
69
+ };
70
+ Sherpa.prototype.url = function(name, params) {
71
+ var _ref;
72
+ return (_ref = this.routes[name]) != null ? _ref.url(params) : void 0;
73
+ };
74
+ Sherpa.prototype.addComplexPart = function(subparts, compiledPath, matchesWith, variableNames) {
75
+ var captures, capturingIndicies, escapeRegexp, name, part, regexSubparts, regexp, spans, splittingIndicies, _ref;
76
+ escapeRegexp = function(str) {
77
+ return str.replace(/([\.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
78
+ };
79
+ _ref = [[], [], 0, false], capturingIndicies = _ref[0], splittingIndicies = _ref[1], captures = _ref[2], spans = _ref[3];
80
+ regexSubparts = (function() {
81
+ var _i, _len, _results;
82
+ _results = [];
83
+ for (_i = 0, _len = subparts.length; _i < _len; _i++) {
84
+ part = subparts[_i];
85
+ _results.push((function() {
86
+ var _ref2;
87
+ switch (part[0]) {
88
+ case '\\':
89
+ compiledPath.push("'" + part[1] + "'");
90
+ return escapeRegexp(part[1]);
91
+ case ':':
92
+ case '*':
93
+ if (part[0] === '*') {
94
+ spans = true;
95
+ }
96
+ captures += 1;
97
+ name = part.slice(1, part.length);
98
+ variableNames.push(name);
99
+ if (part[0] === '*') {
100
+ splittingIndicies.push(captures);
101
+ compiledPath.push("params['" + name + "'].join('/')");
102
+ } else {
103
+ capturingIndicies.push(captures);
104
+ compiledPath.push("params['" + name + "']");
105
+ }
106
+ if (spans) {
107
+ if (matchesWith[name] != null) {
108
+ return "((?:" + matchesWith[name].source + "\\/?)+)";
109
+ } else {
110
+ return '(.*?)';
111
+ }
112
+ } else {
113
+ return "(" + (((_ref2 = matchesWith[name]) != null ? _ref2.source : void 0) || '[^/]*?') + ")";
114
+ }
115
+ break;
116
+ default:
117
+ compiledPath.push("'" + part + "'");
118
+ return escapeRegexp(part);
119
+ }
120
+ })());
121
+ }
122
+ return _results;
123
+ })();
124
+ regexp = new RegExp("" + (regexSubparts.join('')) + "$");
125
+ if (spans) {
126
+ return new SpanningRegexMatcher(regexp, capturingIndicies, splittingIndicies);
127
+ } else {
128
+ return new RegexMatcher(regexp, capturingIndicies, splittingIndicies);
129
+ }
130
+ };
131
+ Sherpa.prototype.addSimplePart = function(subparts, compiledPath, matchesWith, variableNames) {
132
+ var part, variableName;
133
+ part = subparts[0];
134
+ switch (part[0]) {
135
+ case ':':
136
+ variableName = part.slice(1, part.length);
137
+ compiledPath.push("params['" + variableName + "']");
138
+ variableNames.push(variableName);
139
+ if (matchesWith[variableName] != null) {
140
+ return new SpanningRegexMatcher(matchesWith[variableName], [0], []);
141
+ } else {
142
+ return new Variable();
143
+ }
144
+ break;
145
+ case '*':
146
+ compiledPath.push("params['" + variableName + "'].join('/')");
147
+ variableName = part.slice(1, part.length);
148
+ variableNames.push(variableName);
149
+ return new Glob(matchesWith[variableName]);
150
+ default:
151
+ compiledPath.push("'" + part + "'");
152
+ return new Lookup(part);
153
+ }
154
+ };
155
+ Sherpa.prototype.add = function(rawPath, opts) {
156
+ var compiledPath, defaults, matchesWith, nextNodeFn, node, part, partiallyMatch, parts, path, pathSet, route, routeName, subparts, variableNames;
157
+ matchesWith = (opts != null ? opts.matchesWith : void 0) || {};
158
+ defaults = (opts != null ? opts["default"] : void 0) || {};
159
+ routeName = opts != null ? opts.name : void 0;
160
+ partiallyMatch = false;
161
+ route = rawPath.exec != null ? new Route([this.root.add(new RegexPath(this.root, rawPath))]) : (rawPath.substring(rawPath.length - 1) === '*' ? (rawPath = rawPath.substring(0, rawPath.length - 1), partiallyMatch = true) : void 0, pathSet = (function() {
162
+ var _i, _j, _len, _len2, _ref, _results;
163
+ _ref = this.generatePaths(rawPath);
164
+ _results = [];
165
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
166
+ path = _ref[_i];
167
+ node = this.root;
168
+ variableNames = [];
169
+ parts = path.split('/');
170
+ compiledPath = [];
171
+ for (_j = 0, _len2 = parts.length; _j < _len2; _j++) {
172
+ part = parts[_j];
173
+ if (part !== '') {
174
+ compiledPath.push("'/'");
175
+ subparts = this.findSubparts(part);
176
+ nextNodeFn = subparts.length === 1 ? this.addSimplePart : this.addComplexPart;
177
+ node = node.add(nextNodeFn(subparts, compiledPath, matchesWith, variableNames));
178
+ }
179
+ }
180
+ if ((opts != null ? opts.conditions : void 0) != null) {
181
+ node = node.add(new RequestMatcher(opts.conditions));
182
+ }
183
+ path = new Path(node, variableNames);
184
+ path.partial = partiallyMatch;
185
+ path.compiled = compiledPath.length === 0 ? "'/'" : compiledPath.join('+');
186
+ _results.push(path);
187
+ }
188
+ return _results;
189
+ }).call(this), new Route(pathSet, matchesWith));
190
+ route["default"] = defaults;
191
+ route.name = routeName;
192
+ if (routeName != null) {
193
+ this.routes[routeName] = route;
194
+ }
195
+ return route;
196
+ };
197
+ Response = (function() {
198
+ function Response(request, httpResponse, position) {
199
+ this.request = request;
200
+ this.httpResponse = httpResponse;
201
+ this.position = position;
202
+ this.position || (this.position = 0);
203
+ }
204
+ Response.prototype.next = function() {
205
+ if (this.position === this.destinations.length - 1) {
206
+ return false;
207
+ } else {
208
+ return new Response(this.request, this.httpResponse, this.position + 1).invoke();
209
+ }
210
+ };
211
+ Response.prototype.invoke = function() {
212
+ var req;
213
+ req = typeof this.request.underlyingRequest === 'string' ? {} : this.request.underlyingRequest;
214
+ req.params = this.request.destinations[this.position].params;
215
+ req.route = this.request.destinations[this.position].route;
216
+ req.pathInfo = this.request.destinations[this.position].pathInfo;
217
+ return this.request.destinations[this.position].route.destination(req, this.httpResponse);
218
+ };
219
+ return Response;
220
+ })();
221
+ Node = (function() {
222
+ function Node() {
223
+ this.type || (this.type = 'node');
224
+ this.matchers = [];
225
+ }
226
+ Node.prototype.add = function(n) {
227
+ var _ref;
228
+ if (!((_ref = this.matchers[this.matchers.length - 1]) != null ? _ref.usable(n) : void 0)) {
229
+ this.matchers.push(n);
230
+ }
231
+ return this.matchers[this.matchers.length - 1].use(n);
232
+ };
233
+ Node.prototype.usable = function(n) {
234
+ return n.type === this.type;
235
+ };
236
+ Node.prototype.match = function(request) {
237
+ var m, _i, _len, _ref, _results;
238
+ _ref = this.matchers;
239
+ _results = [];
240
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
241
+ m = _ref[_i];
242
+ _results.push(m.match(request));
243
+ }
244
+ return _results;
245
+ };
246
+ Node.prototype.superMatch = Node.prototype.match;
247
+ Node.prototype.use = function(n) {
248
+ return this;
249
+ };
250
+ return Node;
251
+ })();
252
+ Lookup = (function() {
253
+ __extends(Lookup, Node);
254
+ function Lookup(part) {
255
+ this.part = part;
256
+ this.type = 'lookup';
257
+ this.map = {};
258
+ Lookup.__super__.constructor.apply(this, arguments);
259
+ }
260
+ Lookup.prototype.match = function(request) {
261
+ var part;
262
+ if (this.map[request.path[0]] != null) {
263
+ request = request.clone();
264
+ part = request.path.shift();
265
+ return this.map[part].match(request);
266
+ }
267
+ };
268
+ Lookup.prototype.use = function(n) {
269
+ var _base, _name;
270
+ (_base = this.map)[_name = n.part] || (_base[_name] = new Node());
271
+ return this.map[n.part];
272
+ };
273
+ return Lookup;
274
+ })();
275
+ Variable = (function() {
276
+ __extends(Variable, Node);
277
+ function Variable() {
278
+ this.type || (this.type = 'variable');
279
+ Variable.__super__.constructor.apply(this, arguments);
280
+ }
281
+ Variable.prototype.match = function(request) {
282
+ if (request.path.length > 0) {
283
+ request = request.clone();
284
+ request.variables.push(request.path.shift());
285
+ return Variable.__super__.match.call(this, request);
286
+ }
287
+ };
288
+ return Variable;
289
+ })();
290
+ Glob = (function() {
291
+ __extends(Glob, Variable);
292
+ function Glob(regexp) {
293
+ this.regexp = regexp;
294
+ this.type = 'glob';
295
+ Glob.__super__.constructor.apply(this, arguments);
296
+ }
297
+ Glob.prototype.match = function(request) {
298
+ var cloned_path, i, match, original_request, _ref, _results;
299
+ if (request.path.length > 0) {
300
+ original_request = request;
301
+ cloned_path = request.path.slice(0, request.path);
302
+ _results = [];
303
+ for (i = 1, _ref = original_request.path.length; 1 <= _ref ? i <= _ref : i >= _ref; 1 <= _ref ? i++ : i--) {
304
+ request = original_request.clone();
305
+ if (this.regexp != null) {
306
+ match = request.path[i - 1].match(this.regexp);
307
+ }
308
+ if ((this.regexp != null) && (!(match != null) || match[0].length !== request.path[i - 1].length)) {
309
+ return;
310
+ }
311
+ request.variables.push(request.path.slice(0, i));
312
+ request.path = request.path.slice(i, request.path.length);
313
+ _results.push(this.superMatch(request));
314
+ }
315
+ return _results;
316
+ }
317
+ };
318
+ return Glob;
319
+ })();
320
+ RegexMatcher = (function() {
321
+ __extends(RegexMatcher, Node);
322
+ function RegexMatcher(regexp, capturingIndicies, splittingIndicies) {
323
+ var i, _i, _j, _len, _len2, _ref, _ref2;
324
+ this.regexp = regexp;
325
+ this.capturingIndicies = capturingIndicies;
326
+ this.splittingIndicies = splittingIndicies;
327
+ this.type || (this.type = 'regex');
328
+ this.varIndicies = [];
329
+ _ref = this.splittingIndicies;
330
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
331
+ i = _ref[_i];
332
+ this.varIndicies[i] = [i, 'split'];
333
+ }
334
+ _ref2 = this.capturingIndicies;
335
+ for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
336
+ i = _ref2[_j];
337
+ this.varIndicies[i] = [i, 'capture'];
338
+ }
339
+ this.varIndicies.sort(function(a, b) {
340
+ return a[0] - b[0];
341
+ });
342
+ RegexMatcher.__super__.constructor.apply(this, arguments);
343
+ }
344
+ RegexMatcher.prototype.match = function(request) {
345
+ var match;
346
+ if ((request.path[0] != null) && (match = request.path[0].match(this.regexp))) {
347
+ if (match[0].length !== request.path[0].length) {
348
+ return;
349
+ }
350
+ request = request.clone();
351
+ this.addVariables(request, match);
352
+ request.path.shift();
353
+ return RegexMatcher.__super__.match.call(this, request);
354
+ }
355
+ };
356
+ RegexMatcher.prototype.addVariables = function(request, match) {
357
+ var idx, type, v, _i, _len, _ref, _results;
358
+ _ref = this.varIndicies;
359
+ _results = [];
360
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
361
+ v = _ref[_i];
362
+ if (v != null) {
363
+ idx = v[0];
364
+ type = v[1];
365
+ _results.push((function() {
366
+ switch (type) {
367
+ case 'split':
368
+ return request.variables.push(match[idx].split('/'));
369
+ case 'capture':
370
+ return request.variables.push(match[idx]);
371
+ }
372
+ })());
373
+ }
374
+ }
375
+ return _results;
376
+ };
377
+ RegexMatcher.prototype.usable = function(n) {
378
+ return n.type === this.type && n.regexp === this.regexp && n.capturingIndicies === this.capturingIndicies && n.splittingIndicies === this.splittingIndicies;
379
+ };
380
+ return RegexMatcher;
381
+ })();
382
+ SpanningRegexMatcher = (function() {
383
+ __extends(SpanningRegexMatcher, RegexMatcher);
384
+ function SpanningRegexMatcher(regexp, capturingIndicies, splittingIndicies) {
385
+ this.regexp = regexp;
386
+ this.capturingIndicies = capturingIndicies;
387
+ this.splittingIndicies = splittingIndicies;
388
+ this.type = 'spanning';
389
+ SpanningRegexMatcher.__super__.constructor.apply(this, arguments);
390
+ }
391
+ SpanningRegexMatcher.prototype.match = function(request) {
392
+ var match, wholePath;
393
+ if (request.path.length > 0) {
394
+ wholePath = request.wholePath();
395
+ if (match = wholePath.match(this.regexp)) {
396
+ if (match.index !== 0) {
397
+ return;
398
+ }
399
+ request = request.clone();
400
+ this.addVariables(request, match);
401
+ request.path = request.splitPath(wholePath.slice(match.index + match[0].length, wholePath.length));
402
+ return this.superMatch(request);
403
+ }
404
+ }
405
+ };
406
+ return SpanningRegexMatcher;
407
+ })();
408
+ RequestMatcher = (function() {
409
+ __extends(RequestMatcher, Node);
410
+ function RequestMatcher(conditions) {
411
+ this.conditions = conditions;
412
+ this.type = 'request';
413
+ RequestMatcher.__super__.constructor.apply(this, arguments);
414
+ }
415
+ RequestMatcher.prototype.match = function(request) {
416
+ var conditionCount, matcher, matching, satisfiedConditionCount, type, v, val, _ref;
417
+ conditionCount = 0;
418
+ satisfiedConditionCount = 0;
419
+ _ref = this.conditions;
420
+ for (type in _ref) {
421
+ matcher = _ref[type];
422
+ val = request.underlyingRequest[type];
423
+ conditionCount++;
424
+ v = matcher instanceof Array ? (matching = function() {
425
+ var cond, _i, _len;
426
+ for (_i = 0, _len = matcher.length; _i < _len; _i++) {
427
+ cond = matcher[_i];
428
+ if (cond.exec != null) {
429
+ if (matcher.exec(val)) {
430
+ return true;
431
+ }
432
+ } else {
433
+ if (cond === val) {
434
+ return true;
435
+ }
436
+ }
437
+ }
438
+ return false;
439
+ }, matching()) : matcher.exec != null ? matcher.exec(val) : matcher === val;
440
+ if (v) {
441
+ satisfiedConditionCount++;
442
+ }
443
+ }
444
+ if (conditionCount === satisfiedConditionCount) {
445
+ return RequestMatcher.__super__.match.call(this, request);
446
+ }
447
+ };
448
+ RequestMatcher.prototype.usable = function(n) {
449
+ return n.type === this.type && n.conditions === this.conditions;
450
+ };
451
+ return RequestMatcher;
452
+ })();
453
+ Path = (function() {
454
+ __extends(Path, Node);
455
+ function Path(parent, variableNames) {
456
+ this.parent = parent;
457
+ this.variableNames = variableNames;
458
+ this.type = 'path';
459
+ this.partial = false;
460
+ }
461
+ Path.prototype.addDestination = function(request) {
462
+ return request.destinations.push({
463
+ route: this.route,
464
+ request: request,
465
+ params: this.constructParams(request)
466
+ });
467
+ };
468
+ Path.prototype.match = function(request) {
469
+ if (this.partial || request.path.length === 0) {
470
+ this.addDestination(request);
471
+ if (this.partial) {
472
+ return request.destinations[request.destinations.length - 1].pathInfo = "/" + (request.wholePath());
473
+ }
474
+ }
475
+ };
476
+ Path.prototype.constructParams = function(request) {
477
+ var i, params, _ref;
478
+ params = {};
479
+ for (i = 0, _ref = this.variableNames.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
480
+ params[this.variableNames[i]] = request.variables[i];
481
+ }
482
+ return params;
483
+ };
484
+ Path.prototype.url = function(rawParams) {
485
+ var key, match, name, params, path, _i, _j, _k, _len, _len2, _len3, _ref, _ref2, _ref3;
486
+ if (rawParams == null) {
487
+ rawParams = {};
488
+ }
489
+ params = {};
490
+ _ref = this.variableNames;
491
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
492
+ key = _ref[_i];
493
+ params[key] = this.route["default"] != null ? rawParams[key] || this.route["default"][key] : rawParams[key];
494
+ if (!(params[key] != null)) {
495
+ return;
496
+ }
497
+ }
498
+ _ref2 = this.variableNames;
499
+ for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
500
+ name = _ref2[_j];
501
+ if (this.route.matchesWith[name] != null) {
502
+ match = params[name].match(this.route.matchesWith[name]);
503
+ if (!((match != null) && match[0].length === params[name].length)) {
504
+ return;
505
+ }
506
+ }
507
+ }
508
+ path = this.compiled === '' ? '' : eval(this.compiled);
509
+ if (path != null) {
510
+ _ref3 = this.variableNames;
511
+ for (_k = 0, _len3 = _ref3.length; _k < _len3; _k++) {
512
+ name = _ref3[_k];
513
+ delete rawParams[name];
514
+ }
515
+ return path;
516
+ }
517
+ };
518
+ return Path;
519
+ })();
520
+ RegexPath = (function() {
521
+ __extends(RegexPath, Path);
522
+ function RegexPath(parent, regexp) {
523
+ this.parent = parent;
524
+ this.regexp = regexp;
525
+ this.type = 'regexp_route';
526
+ RegexPath.__super__.constructor.apply(this, arguments);
527
+ }
528
+ RegexPath.prototype.match = function(request) {
529
+ request.regexpRouteMatch = this.regexp.exec(request.decodedPath());
530
+ if ((request.regexpRouteMatch != null) && request.regexpRouteMatch[0].length === request.decodedPath().length) {
531
+ request = request.clone();
532
+ request.path = [];
533
+ return RegexPath.__super__.match.call(this, request);
534
+ }
535
+ };
536
+ RegexPath.prototype.constructParams = function(request) {
537
+ return request.regexpRouteMatch;
538
+ };
539
+ RegexPath.prototype.url = function(rawParams) {
540
+ throw "This route cannot be generated";
541
+ };
542
+ return RegexPath;
543
+ })();
544
+ Route = (function() {
545
+ function Route(pathSet, matchesWith) {
546
+ var path, _i, _len, _ref;
547
+ this.pathSet = pathSet;
548
+ this.matchesWith = matchesWith;
549
+ _ref = this.pathSet;
550
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
551
+ path = _ref[_i];
552
+ path.route = this;
553
+ }
554
+ }
555
+ Route.prototype.to = function(destination) {
556
+ var path, _i, _len, _ref, _results;
557
+ this.destination = destination;
558
+ _ref = this.pathSet;
559
+ _results = [];
560
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
561
+ path = _ref[_i];
562
+ _results.push(path.parent.add(path));
563
+ }
564
+ return _results;
565
+ };
566
+ Route.prototype.generateQuery = function(params, base, query) {
567
+ var idx, k, v, _ref;
568
+ query = "";
569
+ base || (base = "");
570
+ if (params != null) {
571
+ if (params instanceof Array) {
572
+ for (idx = 0, _ref = params.length; 0 <= _ref ? idx < _ref : idx > _ref; 0 <= _ref ? idx++ : idx--) {
573
+ query += this.generateQuery(params[idx], "" + base + "[]");
574
+ }
575
+ } else if (params instanceof Object) {
576
+ for (k in params) {
577
+ v = params[k];
578
+ query += this.generateQuery(v, base === '' ? k : "" + base + "[" + k + "]");
579
+ }
580
+ } else {
581
+ query += encodeURIComponent(base).replace(/%20/g, '+');
582
+ query += '=';
583
+ query += encodeURIComponent(params).replace(/%20/g, '+');
584
+ query += '&';
585
+ }
586
+ }
587
+ return query;
588
+ };
589
+ Route.prototype.url = function(params) {
590
+ var joiner, path, pathObj, query, _i, _len, _ref;
591
+ path = void 0;
592
+ _ref = this.pathSet;
593
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
594
+ pathObj = _ref[_i];
595
+ path = pathObj.url(params);
596
+ if (path != null) {
597
+ break;
598
+ }
599
+ }
600
+ if (path != null) {
601
+ query = this.generateQuery(params);
602
+ joiner = query !== '' ? '?' : '';
603
+ return "" + (encodeURI(path)) + joiner + (query.substr(0, query.length - 1));
604
+ } else {
605
+ return;
606
+ }
607
+ };
608
+ return Route;
609
+ })();
610
+ Request = (function() {
611
+ function Request(underlyingRequest, callback) {
612
+ this.underlyingRequest = underlyingRequest;
613
+ this.callback = callback;
614
+ this.variables = [];
615
+ this.destinations = [];
616
+ if (this.underlyingRequest != null) {
617
+ this.path = this.splitPath();
618
+ }
619
+ }
620
+ Request.prototype.toString = function() {
621
+ return "<Request path: /" + (this.path.join('/')) + " " + this.path.length + ">";
622
+ };
623
+ Request.prototype.wholePath = function() {
624
+ return this.path.join('/');
625
+ };
626
+ Request.prototype.decodedPath = function(path) {
627
+ if (path == null) {
628
+ path = require('url').parse(this.underlyingRequest.url).pathname;
629
+ }
630
+ return decodeURI(path);
631
+ };
632
+ Request.prototype.splitPath = function(path) {
633
+ var decodedPath, splitPath;
634
+ decodedPath = this.decodedPath(path);
635
+ splitPath = decodedPath === '/' ? [] : decodedPath.split('/');
636
+ if (splitPath[0] === '') {
637
+ splitPath.shift();
638
+ }
639
+ return splitPath;
640
+ };
641
+ Request.prototype.clone = function() {
642
+ var c;
643
+ c = new Request();
644
+ c.path = this.path.slice(0, this.path.length);
645
+ c.variables = this.variables.slice(0, this.variables.length);
646
+ c.underlyingRequest = this.underlyingRequest;
647
+ c.callback = this.callback;
648
+ c.destinations = this.destinations;
649
+ return c;
650
+ };
651
+ return Request;
652
+ })();
653
+ PathRequest = (function() {
654
+ __extends(PathRequest, Request);
655
+ function PathRequest() {
656
+ PathRequest.__super__.constructor.apply(this, arguments);
657
+ }
658
+ PathRequest.prototype.decodedPath = function(path) {
659
+ if (path == null) {
660
+ path = this.underlyingRequest;
661
+ }
662
+ return decodeURI(path);
663
+ };
664
+ return PathRequest;
665
+ })();
666
+ return Sherpa;
667
+ })();
668
+ }).call(this);
data/js/package.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "http_router",
3
+ "description": "URL routing and generation in js",
4
+ "author": "Joshua Hull <joshbuddy@gmail.com>",
5
+ "version": "0.9.2",
6
+ "directories": {
7
+ "lib" : "./lib/http_router"
8
+ },
9
+ "main": "lib/http_router"
10
+ }