tlsd 2.5.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +26 -3
  2. package/domains/README.txt +0 -0
  3. package/package.json +1 -1
  4. package/proxy/config.json +5 -0
  5. package/proxy/package-lock.json +118 -0
  6. package/proxy/package.json +15 -0
  7. package/proxy/proxy.js +20 -0
  8. package/proxy/siriusmercantile.com/index.js +14 -0
  9. package/proxy/siriusmercantile.com/package-lock.json +137 -0
  10. package/proxy/siriusmercantile.com/package.json +7 -0
  11. package/proxy/zzz/was-nm/debug/CHANGELOG.md +395 -0
  12. package/proxy/zzz/was-nm/debug/LICENSE +19 -0
  13. package/proxy/zzz/was-nm/debug/README.md +437 -0
  14. package/proxy/zzz/was-nm/debug/dist/debug.js +886 -0
  15. package/proxy/zzz/was-nm/debug/node.js +1 -0
  16. package/proxy/zzz/was-nm/debug/package.json +90 -0
  17. package/proxy/zzz/was-nm/debug/src/browser.js +180 -0
  18. package/proxy/zzz/was-nm/debug/src/common.js +249 -0
  19. package/proxy/zzz/was-nm/debug/src/index.js +12 -0
  20. package/proxy/zzz/was-nm/debug/src/node.js +174 -0
  21. package/proxy/zzz/was-nm/eventemitter3/LICENSE +21 -0
  22. package/proxy/zzz/was-nm/eventemitter3/README.md +92 -0
  23. package/proxy/zzz/was-nm/eventemitter3/index.d.ts +67 -0
  24. package/proxy/zzz/was-nm/eventemitter3/index.js +336 -0
  25. package/proxy/zzz/was-nm/eventemitter3/package.json +84 -0
  26. package/proxy/zzz/was-nm/eventemitter3/umd/eventemitter3.js +340 -0
  27. package/proxy/zzz/was-nm/eventemitter3/umd/eventemitter3.min.js +1 -0
  28. package/proxy/zzz/was-nm/eventemitter3/umd/eventemitter3.min.js.map +1 -0
  29. package/proxy/zzz/was-nm/follow-redirects/LICENSE +18 -0
  30. package/proxy/zzz/was-nm/follow-redirects/README.md +145 -0
  31. package/proxy/zzz/was-nm/follow-redirects/http.js +1 -0
  32. package/proxy/zzz/was-nm/follow-redirects/https.js +1 -0
  33. package/proxy/zzz/was-nm/follow-redirects/index.js +452 -0
  34. package/proxy/zzz/was-nm/follow-redirects/package.json +87 -0
  35. package/proxy/zzz/was-nm/http-proxy/.auto-changelog +6 -0
  36. package/proxy/zzz/was-nm/http-proxy/.gitattributes +1 -0
  37. package/proxy/zzz/was-nm/http-proxy/CHANGELOG.md +1864 -0
  38. package/proxy/zzz/was-nm/http-proxy/CODE_OF_CONDUCT.md +74 -0
  39. package/proxy/zzz/was-nm/http-proxy/LICENSE +23 -0
  40. package/proxy/zzz/was-nm/http-proxy/README.md +568 -0
  41. package/proxy/zzz/was-nm/http-proxy/codecov.yml +10 -0
  42. package/proxy/zzz/was-nm/http-proxy/index.js +13 -0
  43. package/proxy/zzz/was-nm/http-proxy/lib/http-proxy/common.js +248 -0
  44. package/proxy/zzz/was-nm/http-proxy/lib/http-proxy/index.js +185 -0
  45. package/proxy/zzz/was-nm/http-proxy/lib/http-proxy/passes/web-incoming.js +192 -0
  46. package/proxy/zzz/was-nm/http-proxy/lib/http-proxy/passes/web-outgoing.js +147 -0
  47. package/proxy/zzz/was-nm/http-proxy/lib/http-proxy/passes/ws-incoming.js +162 -0
  48. package/proxy/zzz/was-nm/http-proxy/lib/http-proxy.js +66 -0
  49. package/proxy/zzz/was-nm/http-proxy/package.json +77 -0
  50. package/proxy/zzz/was-nm/http-proxy/renovate.json +19 -0
  51. package/proxy/zzz/was-nm/ms/index.js +162 -0
  52. package/proxy/zzz/was-nm/ms/license.md +21 -0
  53. package/proxy/zzz/was-nm/ms/package.json +69 -0
  54. package/proxy/zzz/was-nm/ms/readme.md +60 -0
  55. package/proxy/zzz/was-nm/requires-port/.travis.yml +19 -0
  56. package/proxy/zzz/was-nm/requires-port/LICENSE +22 -0
  57. package/proxy/zzz/was-nm/requires-port/README.md +47 -0
  58. package/proxy/zzz/was-nm/requires-port/index.js +38 -0
  59. package/proxy/zzz/was-nm/requires-port/package.json +74 -0
  60. package/proxy/zzz/was-nm/requires-port/test.js +98 -0
  61. package/proxy/zzz/was-nm/sleepless/README.md +4 -0
  62. package/proxy/zzz/was-nm/sleepless/autosite/README.txt +0 -0
  63. package/proxy/zzz/was-nm/sleepless/autosite/site/foobar.txt +1 -0
  64. package/proxy/zzz/was-nm/sleepless/autosite/site/pull.php +4 -0
  65. package/proxy/zzz/was-nm/sleepless/index.js +2 -0
  66. package/proxy/zzz/was-nm/sleepless/package.json +44 -0
  67. package/proxy/zzz/was-nm/sleepless/sleepless.js +613 -0
  68. package/proxy/zzz/was-nm/sleepless/test.html +9 -0
  69. package/proxy/zzz/was-nm/sleepless/test.js +146 -0
  70. package/tlsd +11 -2
  71. package/tlsd.js +2 -0
@@ -0,0 +1,147 @@
1
+ var url = require('url'),
2
+ common = require('../common');
3
+
4
+
5
+ var redirectRegex = /^201|30(1|2|7|8)$/;
6
+
7
+ /*!
8
+ * Array of passes.
9
+ *
10
+ * A `pass` is just a function that is executed on `req, res, options`
11
+ * so that you can easily add new checks while still keeping the base
12
+ * flexible.
13
+ */
14
+
15
+ module.exports = { // <--
16
+
17
+ /**
18
+ * If is a HTTP 1.0 request, remove chunk headers
19
+ *
20
+ * @param {ClientRequest} Req Request object
21
+ * @param {IncomingMessage} Res Response object
22
+ * @param {proxyResponse} Res Response object from the proxy request
23
+ *
24
+ * @api private
25
+ */
26
+ removeChunked: function removeChunked(req, res, proxyRes) {
27
+ if (req.httpVersion === '1.0') {
28
+ delete proxyRes.headers['transfer-encoding'];
29
+ }
30
+ },
31
+
32
+ /**
33
+ * If is a HTTP 1.0 request, set the correct connection header
34
+ * or if connection header not present, then use `keep-alive`
35
+ *
36
+ * @param {ClientRequest} Req Request object
37
+ * @param {IncomingMessage} Res Response object
38
+ * @param {proxyResponse} Res Response object from the proxy request
39
+ *
40
+ * @api private
41
+ */
42
+ setConnection: function setConnection(req, res, proxyRes) {
43
+ if (req.httpVersion === '1.0') {
44
+ proxyRes.headers.connection = req.headers.connection || 'close';
45
+ } else if (req.httpVersion !== '2.0' && !proxyRes.headers.connection) {
46
+ proxyRes.headers.connection = req.headers.connection || 'keep-alive';
47
+ }
48
+ },
49
+
50
+ setRedirectHostRewrite: function setRedirectHostRewrite(req, res, proxyRes, options) {
51
+ if ((options.hostRewrite || options.autoRewrite || options.protocolRewrite)
52
+ && proxyRes.headers['location']
53
+ && redirectRegex.test(proxyRes.statusCode)) {
54
+ var target = url.parse(options.target);
55
+ var u = url.parse(proxyRes.headers['location']);
56
+
57
+ // make sure the redirected host matches the target host before rewriting
58
+ if (target.host != u.host) {
59
+ return;
60
+ }
61
+
62
+ if (options.hostRewrite) {
63
+ u.host = options.hostRewrite;
64
+ } else if (options.autoRewrite) {
65
+ u.host = req.headers['host'];
66
+ }
67
+ if (options.protocolRewrite) {
68
+ u.protocol = options.protocolRewrite;
69
+ }
70
+
71
+ proxyRes.headers['location'] = u.format();
72
+ }
73
+ },
74
+ /**
75
+ * Copy headers from proxyResponse to response
76
+ * set each header in response object.
77
+ *
78
+ * @param {ClientRequest} Req Request object
79
+ * @param {IncomingMessage} Res Response object
80
+ * @param {proxyResponse} Res Response object from the proxy request
81
+ * @param {Object} Options options.cookieDomainRewrite: Config to rewrite cookie domain
82
+ *
83
+ * @api private
84
+ */
85
+ writeHeaders: function writeHeaders(req, res, proxyRes, options) {
86
+ var rewriteCookieDomainConfig = options.cookieDomainRewrite,
87
+ rewriteCookiePathConfig = options.cookiePathRewrite,
88
+ preserveHeaderKeyCase = options.preserveHeaderKeyCase,
89
+ rawHeaderKeyMap,
90
+ setHeader = function(key, header) {
91
+ if (header == undefined) return;
92
+ if (rewriteCookieDomainConfig && key.toLowerCase() === 'set-cookie') {
93
+ header = common.rewriteCookieProperty(header, rewriteCookieDomainConfig, 'domain');
94
+ }
95
+ if (rewriteCookiePathConfig && key.toLowerCase() === 'set-cookie') {
96
+ header = common.rewriteCookieProperty(header, rewriteCookiePathConfig, 'path');
97
+ }
98
+ res.setHeader(String(key).trim(), header);
99
+ };
100
+
101
+ if (typeof rewriteCookieDomainConfig === 'string') { //also test for ''
102
+ rewriteCookieDomainConfig = { '*': rewriteCookieDomainConfig };
103
+ }
104
+
105
+ if (typeof rewriteCookiePathConfig === 'string') { //also test for ''
106
+ rewriteCookiePathConfig = { '*': rewriteCookiePathConfig };
107
+ }
108
+
109
+ // message.rawHeaders is added in: v0.11.6
110
+ // https://nodejs.org/api/http.html#http_message_rawheaders
111
+ if (preserveHeaderKeyCase && proxyRes.rawHeaders != undefined) {
112
+ rawHeaderKeyMap = {};
113
+ for (var i = 0; i < proxyRes.rawHeaders.length; i += 2) {
114
+ var key = proxyRes.rawHeaders[i];
115
+ rawHeaderKeyMap[key.toLowerCase()] = key;
116
+ }
117
+ }
118
+
119
+ Object.keys(proxyRes.headers).forEach(function(key) {
120
+ var header = proxyRes.headers[key];
121
+ if (preserveHeaderKeyCase && rawHeaderKeyMap) {
122
+ key = rawHeaderKeyMap[key] || key;
123
+ }
124
+ setHeader(key, header);
125
+ });
126
+ },
127
+
128
+ /**
129
+ * Set the statusCode from the proxyResponse
130
+ *
131
+ * @param {ClientRequest} Req Request object
132
+ * @param {IncomingMessage} Res Response object
133
+ * @param {proxyResponse} Res Response object from the proxy request
134
+ *
135
+ * @api private
136
+ */
137
+ writeStatusCode: function writeStatusCode(req, res, proxyRes) {
138
+ // From Node.js docs: response.writeHead(statusCode[, statusMessage][, headers])
139
+ if(proxyRes.statusMessage) {
140
+ res.statusCode = proxyRes.statusCode;
141
+ res.statusMessage = proxyRes.statusMessage;
142
+ } else {
143
+ res.statusCode = proxyRes.statusCode;
144
+ }
145
+ }
146
+
147
+ };
@@ -0,0 +1,162 @@
1
+ var http = require('http'),
2
+ https = require('https'),
3
+ common = require('../common');
4
+
5
+ /*!
6
+ * Array of passes.
7
+ *
8
+ * A `pass` is just a function that is executed on `req, socket, options`
9
+ * so that you can easily add new checks while still keeping the base
10
+ * flexible.
11
+ */
12
+
13
+ /*
14
+ * Websockets Passes
15
+ *
16
+ */
17
+
18
+
19
+ module.exports = {
20
+ /**
21
+ * WebSocket requests must have the `GET` method and
22
+ * the `upgrade:websocket` header
23
+ *
24
+ * @param {ClientRequest} Req Request object
25
+ * @param {Socket} Websocket
26
+ *
27
+ * @api private
28
+ */
29
+
30
+ checkMethodAndHeader : function checkMethodAndHeader(req, socket) {
31
+ if (req.method !== 'GET' || !req.headers.upgrade) {
32
+ socket.destroy();
33
+ return true;
34
+ }
35
+
36
+ if (req.headers.upgrade.toLowerCase() !== 'websocket') {
37
+ socket.destroy();
38
+ return true;
39
+ }
40
+ },
41
+
42
+ /**
43
+ * Sets `x-forwarded-*` headers if specified in config.
44
+ *
45
+ * @param {ClientRequest} Req Request object
46
+ * @param {Socket} Websocket
47
+ * @param {Object} Options Config object passed to the proxy
48
+ *
49
+ * @api private
50
+ */
51
+
52
+ XHeaders : function XHeaders(req, socket, options) {
53
+ if(!options.xfwd) return;
54
+
55
+ var values = {
56
+ for : req.connection.remoteAddress || req.socket.remoteAddress,
57
+ port : common.getPort(req),
58
+ proto: common.hasEncryptedConnection(req) ? 'wss' : 'ws'
59
+ };
60
+
61
+ ['for', 'port', 'proto'].forEach(function(header) {
62
+ req.headers['x-forwarded-' + header] =
63
+ (req.headers['x-forwarded-' + header] || '') +
64
+ (req.headers['x-forwarded-' + header] ? ',' : '') +
65
+ values[header];
66
+ });
67
+ },
68
+
69
+ /**
70
+ * Does the actual proxying. Make the request and upgrade it
71
+ * send the Switching Protocols request and pipe the sockets.
72
+ *
73
+ * @param {ClientRequest} Req Request object
74
+ * @param {Socket} Websocket
75
+ * @param {Object} Options Config object passed to the proxy
76
+ *
77
+ * @api private
78
+ */
79
+ stream : function stream(req, socket, options, head, server, clb) {
80
+
81
+ var createHttpHeader = function(line, headers) {
82
+ return Object.keys(headers).reduce(function (head, key) {
83
+ var value = headers[key];
84
+
85
+ if (!Array.isArray(value)) {
86
+ head.push(key + ': ' + value);
87
+ return head;
88
+ }
89
+
90
+ for (var i = 0; i < value.length; i++) {
91
+ head.push(key + ': ' + value[i]);
92
+ }
93
+ return head;
94
+ }, [line])
95
+ .join('\r\n') + '\r\n\r\n';
96
+ }
97
+
98
+ common.setupSocket(socket);
99
+
100
+ if (head && head.length) socket.unshift(head);
101
+
102
+
103
+ var proxyReq = (common.isSSL.test(options.target.protocol) ? https : http).request(
104
+ common.setupOutgoing(options.ssl || {}, options, req)
105
+ );
106
+
107
+ // Enable developers to modify the proxyReq before headers are sent
108
+ if (server) { server.emit('proxyReqWs', proxyReq, req, socket, options, head); }
109
+
110
+ // Error Handler
111
+ proxyReq.on('error', onOutgoingError);
112
+ proxyReq.on('response', function (res) {
113
+ // if upgrade event isn't going to happen, close the socket
114
+ if (!res.upgrade) {
115
+ socket.write(createHttpHeader('HTTP/' + res.httpVersion + ' ' + res.statusCode + ' ' + res.statusMessage, res.headers));
116
+ res.pipe(socket);
117
+ }
118
+ });
119
+
120
+ proxyReq.on('upgrade', function(proxyRes, proxySocket, proxyHead) {
121
+ proxySocket.on('error', onOutgoingError);
122
+
123
+ // Allow us to listen when the websocket has completed
124
+ proxySocket.on('end', function () {
125
+ server.emit('close', proxyRes, proxySocket, proxyHead);
126
+ });
127
+
128
+ // The pipe below will end proxySocket if socket closes cleanly, but not
129
+ // if it errors (eg, vanishes from the net and starts returning
130
+ // EHOSTUNREACH). We need to do that explicitly.
131
+ socket.on('error', function () {
132
+ proxySocket.end();
133
+ });
134
+
135
+ common.setupSocket(proxySocket);
136
+
137
+ if (proxyHead && proxyHead.length) proxySocket.unshift(proxyHead);
138
+
139
+ //
140
+ // Remark: Handle writing the headers to the socket when switching protocols
141
+ // Also handles when a header is an array
142
+ //
143
+ socket.write(createHttpHeader('HTTP/1.1 101 Switching Protocols', proxyRes.headers));
144
+
145
+ proxySocket.pipe(socket).pipe(proxySocket);
146
+
147
+ server.emit('open', proxySocket);
148
+ server.emit('proxySocket', proxySocket); //DEPRECATED.
149
+ });
150
+
151
+ return proxyReq.end(); // XXX: CHECK IF THIS IS THIS CORRECT
152
+
153
+ function onOutgoingError(err) {
154
+ if (clb) {
155
+ clb(err, req, socket);
156
+ } else {
157
+ server.emit('error', err, req, socket);
158
+ }
159
+ socket.end();
160
+ }
161
+ }
162
+ };
@@ -0,0 +1,66 @@
1
+ // Use explicit /index.js to help browserify negociation in require '/lib/http-proxy' (!)
2
+ var ProxyServer = require('./http-proxy/index.js').Server;
3
+
4
+
5
+ /**
6
+ * Creates the proxy server.
7
+ *
8
+ * Examples:
9
+ *
10
+ * httpProxy.createProxyServer({ .. }, 8000)
11
+ * // => '{ web: [Function], ws: [Function] ... }'
12
+ *
13
+ * @param {Object} Options Config object passed to the proxy
14
+ *
15
+ * @return {Object} Proxy Proxy object with handlers for `ws` and `web` requests
16
+ *
17
+ * @api public
18
+ */
19
+
20
+
21
+ function createProxyServer(options) {
22
+ /*
23
+ * `options` is needed and it must have the following layout:
24
+ *
25
+ * {
26
+ * target : <url string to be parsed with the url module>
27
+ * forward: <url string to be parsed with the url module>
28
+ * agent : <object to be passed to http(s).request>
29
+ * ssl : <object to be passed to https.createServer()>
30
+ * ws : <true/false, if you want to proxy websockets>
31
+ * xfwd : <true/false, adds x-forward headers>
32
+ * secure : <true/false, verify SSL certificate>
33
+ * toProxy: <true/false, explicitly specify if we are proxying to another proxy>
34
+ * prependPath: <true/false, Default: true - specify whether you want to prepend the target's path to the proxy path>
35
+ * ignorePath: <true/false, Default: false - specify whether you want to ignore the proxy path of the incoming request>
36
+ * localAddress : <Local interface string to bind for outgoing connections>
37
+ * changeOrigin: <true/false, Default: false - changes the origin of the host header to the target URL>
38
+ * preserveHeaderKeyCase: <true/false, Default: false - specify whether you want to keep letter case of response header key >
39
+ * auth : Basic authentication i.e. 'user:password' to compute an Authorization header.
40
+ * hostRewrite: rewrites the location hostname on (201/301/302/307/308) redirects, Default: null.
41
+ * autoRewrite: rewrites the location host/port on (201/301/302/307/308) redirects based on requested host/port. Default: false.
42
+ * protocolRewrite: rewrites the location protocol on (201/301/302/307/308) redirects to 'http' or 'https'. Default: null.
43
+ * }
44
+ *
45
+ * NOTE: `options.ws` and `options.ssl` are optional.
46
+ * `options.target and `options.forward` cannot be
47
+ * both missing
48
+ * }
49
+ */
50
+
51
+ return new ProxyServer(options);
52
+ }
53
+
54
+
55
+ ProxyServer.createProxyServer = createProxyServer;
56
+ ProxyServer.createServer = createProxyServer;
57
+ ProxyServer.createProxy = createProxyServer;
58
+
59
+
60
+
61
+
62
+ /**
63
+ * Export the proxy "Server" as the main export.
64
+ */
65
+ module.exports = ProxyServer;
66
+
@@ -0,0 +1,77 @@
1
+ {
2
+ "_from": "http-proxy",
3
+ "_id": "http-proxy@1.18.0",
4
+ "_inBundle": false,
5
+ "_integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==",
6
+ "_location": "/http-proxy",
7
+ "_phantomChildren": {},
8
+ "_requested": {
9
+ "type": "tag",
10
+ "registry": true,
11
+ "raw": "http-proxy",
12
+ "name": "http-proxy",
13
+ "escapedName": "http-proxy",
14
+ "rawSpec": "",
15
+ "saveSpec": null,
16
+ "fetchSpec": "latest"
17
+ },
18
+ "_requiredBy": [
19
+ "#USER",
20
+ "/"
21
+ ],
22
+ "_resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz",
23
+ "_shasum": "dbe55f63e75a347db7f3d99974f2692a314a6a3a",
24
+ "_spec": "http-proxy",
25
+ "_where": "/root/proxy",
26
+ "author": {
27
+ "name": "Charlie Robbins",
28
+ "email": "charlie.robbins@gmail.com"
29
+ },
30
+ "bugs": {
31
+ "url": "https://github.com/http-party/node-http-proxy/issues"
32
+ },
33
+ "bundleDependencies": false,
34
+ "dependencies": {
35
+ "eventemitter3": "^4.0.0",
36
+ "follow-redirects": "^1.0.0",
37
+ "requires-port": "^1.0.0"
38
+ },
39
+ "deprecated": false,
40
+ "description": "HTTP proxying for the masses",
41
+ "devDependencies": {
42
+ "async": "^3.0.0",
43
+ "auto-changelog": "^1.15.0",
44
+ "concat-stream": "^2.0.0",
45
+ "expect.js": "~0.3.1",
46
+ "mocha": "^3.5.3",
47
+ "nyc": "^14.0.0",
48
+ "semver": "^5.0.3",
49
+ "socket.io": "^2.1.0",
50
+ "socket.io-client": "^2.1.0",
51
+ "sse": "0.0.8",
52
+ "ws": "^3.0.0"
53
+ },
54
+ "engines": {
55
+ "node": ">=6.0.0"
56
+ },
57
+ "homepage": "https://github.com/http-party/node-http-proxy#readme",
58
+ "license": "MIT",
59
+ "main": "index.js",
60
+ "maintainers": [
61
+ {
62
+ "name": "jcrugzz",
63
+ "email": "jcrugzz@gmail.com"
64
+ }
65
+ ],
66
+ "name": "http-proxy",
67
+ "repository": {
68
+ "type": "git",
69
+ "url": "git+https://github.com/http-party/node-http-proxy.git"
70
+ },
71
+ "scripts": {
72
+ "mocha": "mocha test/*-test.js",
73
+ "test": "nyc --reporter=text --reporter=lcov npm run mocha",
74
+ "version": "auto-changelog -p && git add CHANGELOG.md"
75
+ },
76
+ "version": "1.18.0"
77
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "platform": "github",
3
+ "autodiscover": false,
4
+ "requireConfig": true,
5
+ "ignoreNpmrcFile": true,
6
+ "rangeStrategy": "replace",
7
+ "packageRules": [
8
+ {
9
+ "packagePatterns": [
10
+ "*"
11
+ ],
12
+ "minor": {
13
+ "groupName": "all non-major dependencies",
14
+ "groupSlug": "all-minor-patch"
15
+ }
16
+ }
17
+ ],
18
+ "commitMessagePrefix": "[dist]"
19
+ }
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Helpers.
3
+ */
4
+
5
+ var s = 1000;
6
+ var m = s * 60;
7
+ var h = m * 60;
8
+ var d = h * 24;
9
+ var w = d * 7;
10
+ var y = d * 365.25;
11
+
12
+ /**
13
+ * Parse or format the given `val`.
14
+ *
15
+ * Options:
16
+ *
17
+ * - `long` verbose formatting [false]
18
+ *
19
+ * @param {String|Number} val
20
+ * @param {Object} [options]
21
+ * @throws {Error} throw an error if val is not a non-empty string or a number
22
+ * @return {String|Number}
23
+ * @api public
24
+ */
25
+
26
+ module.exports = function(val, options) {
27
+ options = options || {};
28
+ var type = typeof val;
29
+ if (type === 'string' && val.length > 0) {
30
+ return parse(val);
31
+ } else if (type === 'number' && isFinite(val)) {
32
+ return options.long ? fmtLong(val) : fmtShort(val);
33
+ }
34
+ throw new Error(
35
+ 'val is not a non-empty string or a valid number. val=' +
36
+ JSON.stringify(val)
37
+ );
38
+ };
39
+
40
+ /**
41
+ * Parse the given `str` and return milliseconds.
42
+ *
43
+ * @param {String} str
44
+ * @return {Number}
45
+ * @api private
46
+ */
47
+
48
+ function parse(str) {
49
+ str = String(str);
50
+ if (str.length > 100) {
51
+ return;
52
+ }
53
+ var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
54
+ str
55
+ );
56
+ if (!match) {
57
+ return;
58
+ }
59
+ var n = parseFloat(match[1]);
60
+ var type = (match[2] || 'ms').toLowerCase();
61
+ switch (type) {
62
+ case 'years':
63
+ case 'year':
64
+ case 'yrs':
65
+ case 'yr':
66
+ case 'y':
67
+ return n * y;
68
+ case 'weeks':
69
+ case 'week':
70
+ case 'w':
71
+ return n * w;
72
+ case 'days':
73
+ case 'day':
74
+ case 'd':
75
+ return n * d;
76
+ case 'hours':
77
+ case 'hour':
78
+ case 'hrs':
79
+ case 'hr':
80
+ case 'h':
81
+ return n * h;
82
+ case 'minutes':
83
+ case 'minute':
84
+ case 'mins':
85
+ case 'min':
86
+ case 'm':
87
+ return n * m;
88
+ case 'seconds':
89
+ case 'second':
90
+ case 'secs':
91
+ case 'sec':
92
+ case 's':
93
+ return n * s;
94
+ case 'milliseconds':
95
+ case 'millisecond':
96
+ case 'msecs':
97
+ case 'msec':
98
+ case 'ms':
99
+ return n;
100
+ default:
101
+ return undefined;
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Short format for `ms`.
107
+ *
108
+ * @param {Number} ms
109
+ * @return {String}
110
+ * @api private
111
+ */
112
+
113
+ function fmtShort(ms) {
114
+ var msAbs = Math.abs(ms);
115
+ if (msAbs >= d) {
116
+ return Math.round(ms / d) + 'd';
117
+ }
118
+ if (msAbs >= h) {
119
+ return Math.round(ms / h) + 'h';
120
+ }
121
+ if (msAbs >= m) {
122
+ return Math.round(ms / m) + 'm';
123
+ }
124
+ if (msAbs >= s) {
125
+ return Math.round(ms / s) + 's';
126
+ }
127
+ return ms + 'ms';
128
+ }
129
+
130
+ /**
131
+ * Long format for `ms`.
132
+ *
133
+ * @param {Number} ms
134
+ * @return {String}
135
+ * @api private
136
+ */
137
+
138
+ function fmtLong(ms) {
139
+ var msAbs = Math.abs(ms);
140
+ if (msAbs >= d) {
141
+ return plural(ms, msAbs, d, 'day');
142
+ }
143
+ if (msAbs >= h) {
144
+ return plural(ms, msAbs, h, 'hour');
145
+ }
146
+ if (msAbs >= m) {
147
+ return plural(ms, msAbs, m, 'minute');
148
+ }
149
+ if (msAbs >= s) {
150
+ return plural(ms, msAbs, s, 'second');
151
+ }
152
+ return ms + ' ms';
153
+ }
154
+
155
+ /**
156
+ * Pluralization helper.
157
+ */
158
+
159
+ function plural(ms, msAbs, n, name) {
160
+ var isPlural = msAbs >= n * 1.5;
161
+ return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
162
+ }
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Zeit, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.