Skip to content

Commit 6ea0742

Browse files
committed
Update and modernize
Update dependencies, modernize code. Also include small fixes from few PRs.
1 parent 8076199 commit 6ea0742

File tree

7 files changed

+133
-87
lines changed

7 files changed

+133
-87
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
.npm/.package-garbage-*/

.npm/package/npm-shrinkwrap.json

Lines changed: 4 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Picker.route('/post/:_id', function(params, req, res, next) {
2929

3030
## Filtering and Sub Routes
3131

32-
This is an unique functionality of this router. See following example:
32+
This is a unique functionality of this router. See following example:
3333

3434
Let's say we need to handle only `POST` requests. This is how you can do it with `Picker`.
3535

@@ -53,9 +53,7 @@ You can create any amount of sub routes with this `filter` API. Same time, you c
5353
You can use existing `connect` and `express` middlewares without any issues.
5454

5555
~~~js
56-
// You can use the meteorhacks:npm package to load in the body-parser package
57-
// via NPM.
58-
var bodyParser = Meteor.npmRequire( 'body-parser');
56+
import bodyParser from 'body-parser';
5957

6058
// Add two middleware calls. The first attempting to parse the request body as
6159
// JSON data and the second as URL encoded data.

lib/implementation.js

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
1-
var pathToRegexp = Npm.require('path-to-regexp');
2-
var Fiber = Npm.require('fibers');
3-
var urlParse = Npm.require('url').parse;
1+
import { pathToRegexp } from 'path-to-regexp';
2+
// TODO replace fibers
3+
import Fiber from 'fibers';
44

5-
PickerImp = function(filterFunction) {
5+
function parseQuery(queryString) {
6+
if (!queryString) return {}
7+
let query = {};
8+
const pairs = queryString.replace(/^\?/, '').split('&');
9+
for (let i = 0; i < pairs.length; i++) {
10+
const pair = pairs[i].split('=');
11+
query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || '');
12+
}
13+
return query;
14+
}
15+
16+
export const PickerImp = function(filterFunction) {
617
this.filterFunction = filterFunction;
718
this.routes = [];
819
this.subRouters = [];
@@ -14,50 +25,51 @@ PickerImp.prototype.middleware = function(callback) {
1425
};
1526

1627
PickerImp.prototype.route = function(path, callback) {
17-
var regExp = pathToRegexp(path);
28+
const keys = [];
29+
const regExp = pathToRegexp(path, keys);
1830
regExp.callback = callback;
31+
regExp.keys = keys;
1932
this.routes.push(regExp);
2033
return this;
2134
};
2235

2336
PickerImp.prototype.filter = function(callback) {
24-
var subRouter = new PickerImp(callback);
37+
const subRouter = new PickerImp(callback);
2538
this.subRouters.push(subRouter);
2639
return subRouter;
2740
};
2841

2942
PickerImp.prototype._dispatch = function(req, res, bypass) {
30-
var self = this;
31-
var currentRoute = 0;
32-
var currentSubRouter = 0;
33-
var currentMiddleware = 0;
43+
let currentRoute = 0;
44+
let currentSubRouter = 0;
45+
let currentMiddleware = 0;
3446

3547
if(this.filterFunction) {
36-
var result = this.filterFunction(req, res);
48+
const result = this.filterFunction(req, res);
3749
if(!result) {
3850
return bypass();
3951
}
4052
}
4153

42-
processNextMiddleware();
43-
function processNextMiddleware () {
44-
var middleware = self.middlewares[currentMiddleware++];
54+
const processNextMiddleware = () => {
55+
const middleware = this.middlewares[currentMiddleware++];
4556
if(middleware) {
46-
self._processMiddleware(middleware, req, res, processNextMiddleware);
57+
this._processMiddleware(middleware, req, res, processNextMiddleware);
4758
} else {
4859
processNextRoute();
4960
}
5061
}
5162

52-
function processNextRoute () {
53-
var route = self.routes[currentRoute++];
63+
const processNextRoute = () => {
64+
const route = this.routes[currentRoute++];
5465
if(route) {
55-
var uri = req.url.replace(/\?.*/, '');
56-
var m = uri.match(route);
66+
const uri = req.url.replace(/\?.*/, '');
67+
const m = uri.match(route);
5768
if(m) {
58-
var params = self._buildParams(route.keys, m);
59-
params.query = urlParse(req.url, true).query;
60-
self._processRoute(route.callback, params, req, res, bypass);
69+
const params = this._buildParams(route.keys, m);
70+
params.query = parseQuery(req._parsedUrl?.query);
71+
// See https://github.com/meteorhacks/picker/pull/39 for processNextRoute reason in the following method.
72+
this._processRoute(route.callback, params, req, res, processNextRoute);
6173
} else {
6274
processNextRoute();
6375
}
@@ -66,22 +78,22 @@ PickerImp.prototype._dispatch = function(req, res, bypass) {
6678
}
6779
}
6880

69-
function processNextSubRouter () {
70-
var subRouter = self.subRouters[currentSubRouter++];
81+
const processNextSubRouter = () => {
82+
const subRouter = this.subRouters[currentSubRouter++];
7183
if(subRouter) {
7284
subRouter._dispatch(req, res, processNextSubRouter);
7385
} else {
7486
bypass();
7587
}
7688
}
89+
processNextMiddleware();
7790
};
7891

7992
PickerImp.prototype._buildParams = function(keys, m) {
80-
var params = {};
81-
for(var lc=1; lc<m.length; lc++) {
82-
var key = keys[lc-1].name;
83-
var value = m[lc];
84-
params[key] = value;
93+
const params = {};
94+
for(let lc = 1; lc < m.length; lc++) {
95+
const key = keys[lc-1]?.name;
96+
params[key] = decodeURIComponent(m[lc]);
8597
}
8698

8799
return params;

lib/instance.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
Picker = new PickerImp();
1+
import { WebApp } from 'meteor/webapp';
2+
import { PickerImp } from './implementation';
3+
4+
export const Picker = new PickerImp();
25
WebApp.rawConnectHandlers.use(function(req, res, next) {
36
Picker._dispatch(req, res, next);
47
});

package.js

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,28 @@
11
Package.describe({
2-
name: 'meteorhacks:picker',
2+
name: 'storyteller:picker',
33
summary: 'Server Side Router for Meteor',
4-
version: '1.0.4',
5-
git: 'https://github.com/meteorhacks/picker.git'
4+
version: '1.1.0',
5+
git: 'https://github.com/storytellercz/picker.git',
6+
documentation: 'README.md'
67
});
78

89
Npm.depends({
9-
'path-to-regexp': '1.2.1'
10+
'path-to-regexp': '6.1.0'
1011
});
1112

1213
Package.onUse(function(api) {
1314
configurePackage(api);
14-
api.export(['Picker']);
15+
api.mainModule('lib/instance.js', 'server');
1516
});
1617

1718
Package.onTest(function(api) {
1819
configurePackage(api);
19-
api.use(['tinytest', 'http', 'random'], ['server']);
20-
api.addFiles([
21-
'test/instance.js'
22-
], ['server']);
20+
api.use('storyteller:picker', 'server');
21+
api.use(['tinytest', 'http', 'random'], 'server');
22+
api.mainModule('test/instance.js', 'server');
2323
});
2424

2525
function configurePackage(api) {
26-
if(api.versionsFrom) {
27-
api.versionsFrom('[email protected]');
28-
}
29-
30-
api.use(['webapp', 'underscore'], ['server']);
31-
api.addFiles([
32-
'lib/implementation.js',
33-
'lib/instance.js',
34-
], ['server']);
26+
api.versionsFrom('1.3');
27+
api.use(['webapp', 'ecmascript', 'url'], 'server');
3528
}

test/instance.js

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,63 @@
1+
import { Picker } from 'meteor/storyteller:picker';
2+
// TODO replace HTTP with fetch
3+
import { HTTP } from 'meteor/http';
4+
import { Random } from 'meteor/random';
5+
import { Meteor } from 'meteor/meteor';
6+
7+
function getPath(path) {
8+
return Meteor.absoluteUrl(path);
9+
}
10+
111
Tinytest.add('normal route', function(test) {
2-
var path = "/" + Random.id();
3-
Picker.route(path, function(params, req, res) {
12+
const id = Random.id();
13+
Picker.route(`/${id}`, function(params, req, res) {
414
res.end("done");
515
});
616

7-
var res = HTTP.get(getPath(path));
17+
const res = HTTP.get(getPath(id));
818
test.equal(res.content, 'done');
919
});
1020

1121
Tinytest.add('with params', function(test) {
12-
var id = Random.id();
13-
var path = "/post/:id";
22+
const id = Random.id();
23+
const path = "/post/:id";
1424
Picker.route(path, function(params, req, res) {
1525
res.end(params.id);
1626
});
1727

18-
var res = HTTP.get(getPath("/post/" + id));
28+
const res = HTTP.get(getPath(`post/${id}`));
1929
test.equal(res.content, id);
2030
});
2131

2232
Tinytest.add('filter only POST', function(test) {
23-
var path = "/" + Random.id();
24-
var postRoutes = Picker.filter(function(req, res) {
25-
return req.method == "POST";
33+
const id = Random.id();
34+
const postRoutes = Picker.filter(function(req, res) {
35+
return req.method === "POST";
2636
});
2737

28-
postRoutes.route(path, function(params, req, res) {
38+
postRoutes.route(`/${id}`, function(params, req, res) {
2939
res.end("done");
3040
});
3141

32-
var res = HTTP.get(getPath(path));
33-
test.isFalse(res.content == "done");
42+
const res1 = HTTP.get(getPath(`/${id}`));
43+
test.isFalse(res1.content === "done");
3444

35-
var res = HTTP.post(getPath(path));
36-
test.isTrue(res.content == "done");
45+
const res2 = HTTP.post(getPath(`/${id}`));
46+
test.isTrue(res2.content === "done");
3747
});
3848

3949
Tinytest.add('query strings', function(test) {
40-
var path = "/" + Random.id();
41-
Picker.route(path, function(params, req, res) {
50+
const id = Random.id();
51+
Picker.route(`/${id}`, function(params, req, res) {
4252
res.end("" + params.query.aa);
4353
});
4454

45-
var res = HTTP.get(getPath(path + "?aa=10"));
55+
const res = HTTP.get(getPath(`/${id}?aa=10&bb=10`));
4656
test.equal(res.content, "10");
4757
});
4858

4959
Tinytest.add('middlewares', function(test) {
50-
var path = "/" + Random.id();
60+
const id = Random.id();
5161

5262
Picker.middleware(function(req, res, next) {
5363
setTimeout(function() {
@@ -56,19 +66,19 @@ Tinytest.add('middlewares', function(test) {
5666
}, 100);
5767
});
5868

59-
Picker.route(path, function(params, req, res) {
69+
Picker.route(`/${id}`, function(params, req, res) {
6070
res.end(req.middlewarePass);
6171
});
6272

63-
var res = HTTP.get(getPath(path + "?aa=10"));
73+
const res = HTTP.get(getPath(`/${id}?aa=10`));
6474
test.equal(res.content, "ok");
6575
});
6676

6777
Tinytest.add('middlewares - with filtered routes', function(test) {
68-
var path = "/" + Random.id() + "/coola";
78+
const path = `${Random.id()}/coola`;
6979

70-
var routes = Picker.filter(function(req, res) {
71-
var matched = /coola/.test(req.url);
80+
const routes = Picker.filter(function(req, res) {
81+
const matched = /coola/.test(req.url);
7282
return matched;
7383
});
7484

@@ -79,15 +89,45 @@ Tinytest.add('middlewares - with filtered routes', function(test) {
7989
}, 100);
8090
});
8191

82-
routes.route(path, function(params, req, res) {
92+
routes.route(`/${path}`, function(params, req, res) {
8393
res.end(req.middlewarePass);
8494
});
8595

86-
var res = HTTP.get(getPath(path));
96+
const res = HTTP.get(getPath(path));
8797
test.equal(res.content, "ok");
8898
});
8999

90-
var urlResolve = Npm.require('url').resolve;
91-
function getPath(path) {
92-
return urlResolve(process.env.ROOT_URL, path);
93-
}
100+
/*
101+
Tinytest.add('middlewares - with several filtered routes', function(test) {
102+
const path1 = `${Random.id()}/coola`;
103+
const path2 = `${Random.id()}/coola`;
104+
105+
const routes1 = Picker.filter();
106+
const routes2 = Picker.filter();
107+
108+
const increaseResultBy = (i) => (req, res, next) => {
109+
setTimeout(function() {
110+
req.result = req.result || 0;
111+
req.result += i;
112+
next();
113+
}, 100);
114+
};
115+
116+
routes1.middleware(increaseResultBy(1));
117+
routes2.middleware(increaseResultBy(2));
118+
119+
Picker.middleware(increaseResultBy(10));
120+
121+
routes1.route(`/${path1}`, function(params, req, res) {
122+
res.end(req.result+'');
123+
});
124+
routes2.route(`/${path2}`, function(params, req, res) {
125+
res.end(req.result+'');
126+
});
127+
128+
const res1 = HTTP.get(getPath(path1));
129+
test.equal(res1.content, "11");
130+
131+
const res2 = HTTP.get(getPath(path2));
132+
test.equal(res2.content, "12");
133+
});*/

0 commit comments

Comments
 (0)