roster-server 1.9.6 → 2.0.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 (36) hide show
  1. package/README.md +8 -0
  2. package/index.js +1 -1
  3. package/package.json +4 -3
  4. package/skills/roster-server/SKILL.md +257 -0
  5. package/vendor/greenlock-express/.prettierrc +7 -0
  6. package/vendor/greenlock-express/LICENSE +375 -0
  7. package/vendor/greenlock-express/README.md +536 -0
  8. package/vendor/greenlock-express/WALKTHROUGH.md +256 -0
  9. package/vendor/greenlock-express/config.js +20 -0
  10. package/vendor/greenlock-express/demo.js +35 -0
  11. package/vendor/greenlock-express/examples/cluster/package.json +12 -0
  12. package/vendor/greenlock-express/examples/express/my-express-app.js +17 -0
  13. package/vendor/greenlock-express/examples/express/package.json +12 -0
  14. package/vendor/greenlock-express/examples/http/package.json +12 -0
  15. package/vendor/greenlock-express/examples/http-proxy/package.json +12 -0
  16. package/vendor/greenlock-express/examples/http2/package.json +12 -0
  17. package/vendor/greenlock-express/examples/https/package.json +12 -0
  18. package/vendor/greenlock-express/examples/quickstart/README.md +22 -0
  19. package/vendor/greenlock-express/examples/quickstart/package.json +12 -0
  20. package/vendor/greenlock-express/examples/socket.io/package.json +12 -0
  21. package/vendor/greenlock-express/examples/websockets/package.json +12 -0
  22. package/vendor/greenlock-express/greenlock-express.js +48 -0
  23. package/vendor/greenlock-express/greenlock-shim.js +72 -0
  24. package/vendor/greenlock-express/http-middleware.js +154 -0
  25. package/vendor/greenlock-express/https-middleware.js +139 -0
  26. package/vendor/greenlock-express/install.sh +14 -0
  27. package/vendor/greenlock-express/lib/compat.js +37 -0
  28. package/vendor/greenlock-express/main.js +32 -0
  29. package/vendor/greenlock-express/master.js +164 -0
  30. package/vendor/greenlock-express/package-lock.json +149 -0
  31. package/vendor/greenlock-express/package.json +51 -0
  32. package/vendor/greenlock-express/scripts/postinstall +77 -0
  33. package/vendor/greenlock-express/servers.js +171 -0
  34. package/vendor/greenlock-express/single.js +36 -0
  35. package/vendor/greenlock-express/sni.js +215 -0
  36. package/vendor/greenlock-express/worker.js +73 -0
@@ -0,0 +1,149 @@
1
+ {
2
+ "name": "@root/greenlock-express",
3
+ "version": "4.0.4",
4
+ "lockfileVersion": 1,
5
+ "requires": true,
6
+ "dependencies": {
7
+ "@greenlock/manager": {
8
+ "version": "3.1.0",
9
+ "resolved": "https://registry.npmjs.org/@greenlock/manager/-/manager-3.1.0.tgz",
10
+ "integrity": "sha512-PBy5CMK+j4oD7sj7hF5qE+xKEOSiiuL2hHd5X5ttEbtnTSDKjNeqbrR5k2ZddwVNdjOVeBIeuqlm81IFZ+Ftew==",
11
+ "requires": {
12
+ "greenlock-manager-fs": "^3.1.0"
13
+ }
14
+ },
15
+ "@root/acme": {
16
+ "version": "3.1.0",
17
+ "resolved": "https://registry.npmjs.org/@root/acme/-/acme-3.1.0.tgz",
18
+ "integrity": "sha512-GAyaW63cpSYd2KvVp5lHLbCWeEhJPKZK9nsJvZJOKsD9Uv88KEttn4FpDZEJ+2q3Jsey0DWpuQ2I4ft0JV9p2w==",
19
+ "requires": {
20
+ "@root/csr": "^0.8.1",
21
+ "@root/encoding": "^1.0.1",
22
+ "@root/keypairs": "^0.10.0",
23
+ "@root/pem": "^1.0.4",
24
+ "@root/request": "^1.6.1",
25
+ "@root/x509": "^0.7.2"
26
+ }
27
+ },
28
+ "@root/asn1": {
29
+ "version": "1.0.0",
30
+ "resolved": "https://registry.npmjs.org/@root/asn1/-/asn1-1.0.0.tgz",
31
+ "integrity": "sha512-0lfZNuOULKJDJmdIkP8V9RnbV3XaK6PAHD3swnFy4tZwtlMDzLKoM/dfNad7ut8Hu3r91wy9uK0WA/9zym5mig==",
32
+ "requires": {
33
+ "@root/encoding": "^1.0.1"
34
+ }
35
+ },
36
+ "@root/csr": {
37
+ "version": "0.8.1",
38
+ "resolved": "https://registry.npmjs.org/@root/csr/-/csr-0.8.1.tgz",
39
+ "integrity": "sha512-hKl0VuE549TK6SnS2Yn9nRvKbFZXn/oAg+dZJU/tlKl/f/0yRXeuUzf8akg3JjtJq+9E592zDqeXZ7yyrg8fSQ==",
40
+ "requires": {
41
+ "@root/asn1": "^1.0.0",
42
+ "@root/pem": "^1.0.4",
43
+ "@root/x509": "^0.7.2"
44
+ }
45
+ },
46
+ "@root/encoding": {
47
+ "version": "1.0.1",
48
+ "resolved": "https://registry.npmjs.org/@root/encoding/-/encoding-1.0.1.tgz",
49
+ "integrity": "sha512-OaEub02ufoU038gy6bsNHQOjIn8nUjGiLcaRmJ40IUykneJkIW5fxDqKxQx48cszuNflYldsJLPPXCrGfHs8yQ=="
50
+ },
51
+ "@root/greenlock": {
52
+ "version": "4.0.5",
53
+ "resolved": "https://registry.npmjs.org/@root/greenlock/-/greenlock-4.0.5.tgz",
54
+ "integrity": "sha512-KR9w3mYE9aH33FCibI8oSYBQV+f7lc3MVPdZ9nxY2tqRLmJp05cMOMz340mtG14VnWDuznLj4TbBj3sHIuoQPQ==",
55
+ "requires": {
56
+ "@greenlock/manager": "^3.1.0",
57
+ "@root/acme": "^3.1.0",
58
+ "@root/csr": "^0.8.1",
59
+ "@root/keypairs": "^0.10.0",
60
+ "@root/mkdirp": "^1.0.0",
61
+ "@root/request": "^1.6.1",
62
+ "acme-http-01-standalone": "^3.0.5",
63
+ "cert-info": "^1.5.1",
64
+ "greenlock-store-fs": "^3.2.2",
65
+ "safe-replace": "^1.1.0"
66
+ }
67
+ },
68
+ "@root/keypairs": {
69
+ "version": "0.10.0",
70
+ "resolved": "https://registry.npmjs.org/@root/keypairs/-/keypairs-0.10.0.tgz",
71
+ "integrity": "sha512-t8VocY46Mtb0NTsxzyLLf5tsgfw0BXLYVADAyiRdEdqHcvPFGJdjkXNtHVQuSV/FMaC65iTOHVP4E6X8iT3Ikg==",
72
+ "requires": {
73
+ "@root/encoding": "^1.0.1",
74
+ "@root/pem": "^1.0.4",
75
+ "@root/x509": "^0.7.2"
76
+ }
77
+ },
78
+ "@root/mkdirp": {
79
+ "version": "1.0.0",
80
+ "resolved": "https://registry.npmjs.org/@root/mkdirp/-/mkdirp-1.0.0.tgz",
81
+ "integrity": "sha512-hxGAYUx5029VggfG+U9naAhQkoMSXtOeXtbql97m3Hi6/sQSRL/4khKZPyOF6w11glyCOU38WCNLu9nUcSjOfA=="
82
+ },
83
+ "@root/pem": {
84
+ "version": "1.0.4",
85
+ "resolved": "https://registry.npmjs.org/@root/pem/-/pem-1.0.4.tgz",
86
+ "integrity": "sha512-rEUDiUsHtild8GfIjFE9wXtcVxeS+ehCJQBwbQQ3IVfORKHK93CFnRtkr69R75lZFjcmKYVc+AXDB+AeRFOULA=="
87
+ },
88
+ "@root/request": {
89
+ "version": "1.6.1",
90
+ "resolved": "https://registry.npmjs.org/@root/request/-/request-1.6.1.tgz",
91
+ "integrity": "sha512-8wrWyeBLRp7T8J36GkT3RODJ6zYmL0/maWlAUD5LOXT28D3TDquUepyYDKYANNA3Gc8R5ZCgf+AXvSTYpJEWwQ=="
92
+ },
93
+ "@root/x509": {
94
+ "version": "0.7.2",
95
+ "resolved": "https://registry.npmjs.org/@root/x509/-/x509-0.7.2.tgz",
96
+ "integrity": "sha512-ENq3LGYORK5NiMFHEVeNMt+fTXaC7DTS6sQXoqV+dFdfT0vmiL5cDLjaXQhaklJQq0NiwicZegzJRl1ZOTp3WQ==",
97
+ "requires": {
98
+ "@root/asn1": "^1.0.0",
99
+ "@root/encoding": "^1.0.1"
100
+ }
101
+ },
102
+ "acme-http-01-standalone": {
103
+ "version": "3.0.5",
104
+ "resolved": "https://registry.npmjs.org/acme-http-01-standalone/-/acme-http-01-standalone-3.0.5.tgz",
105
+ "integrity": "sha512-W4GfK+39GZ+u0mvxRVUcVFCG6gposfzEnSBF20T/NUwWAKG59wQT1dUbS1NixRIAsRuhpGc4Jx659cErFQH0Pg=="
106
+ },
107
+ "cert-info": {
108
+ "version": "1.5.1",
109
+ "resolved": "https://registry.npmjs.org/cert-info/-/cert-info-1.5.1.tgz",
110
+ "integrity": "sha512-eoQC/yAgW3gKTKxjzyClvi+UzuY97YCjcl+lSqbsGIy7HeGaWxCPOQFivhUYm27hgsBMhsJJFya3kGvK6PMIcQ=="
111
+ },
112
+ "escape-html": {
113
+ "version": "1.0.3",
114
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
115
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
116
+ },
117
+ "greenlock-manager-fs": {
118
+ "version": "3.1.1",
119
+ "resolved": "https://registry.npmjs.org/greenlock-manager-fs/-/greenlock-manager-fs-3.1.1.tgz",
120
+ "integrity": "sha512-np6qdnPIOZx40PAcSQcqK1eMPWjTKxsxcgRd/OVg0ai49WC1Ds74CTrwmB84pq2n53ikbnDBQFmKEQ4AC0DK8w==",
121
+ "requires": {
122
+ "@root/mkdirp": "^1.0.0",
123
+ "safe-replace": "^1.1.0"
124
+ }
125
+ },
126
+ "greenlock-store-fs": {
127
+ "version": "3.2.2",
128
+ "resolved": "https://registry.npmjs.org/greenlock-store-fs/-/greenlock-store-fs-3.2.2.tgz",
129
+ "integrity": "sha512-92ejLB4DyV4qv/2b6VLGF2nKfYQeIfg3o+e/1cIoYLjlIaUFdbBXkzLTRozFlHsQPZt2ALi5qYrpC9IwH7GK8A==",
130
+ "requires": {
131
+ "@root/mkdirp": "^1.0.0",
132
+ "safe-replace": "^1.1.0"
133
+ }
134
+ },
135
+ "redirect-https": {
136
+ "version": "1.3.1",
137
+ "resolved": "https://registry.npmjs.org/redirect-https/-/redirect-https-1.3.1.tgz",
138
+ "integrity": "sha512-Stex2nI+tMpZXKvy++32TiBXEy+GdpAfp3EUnl5BqCiJ5f5i6XvUSFrs7TR7IoRSlthM7ZtD89uYGTtJBXlFYg==",
139
+ "requires": {
140
+ "escape-html": "^1.0.3"
141
+ }
142
+ },
143
+ "safe-replace": {
144
+ "version": "1.1.0",
145
+ "resolved": "https://registry.npmjs.org/safe-replace/-/safe-replace-1.1.0.tgz",
146
+ "integrity": "sha512-9/V2E0CDsKs9DWOOwJH7jYpSl9S3N05uyevNjvsnDauBqRowBPOyot1fIvV5N2IuZAbYyvrTXrYFVG0RZInfFw=="
147
+ }
148
+ }
149
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@root/greenlock-express",
3
+ "version": "4.0.4",
4
+ "description": "Free SSL and managed or automatic HTTPS for node.js with Express, Koa, Connect, Hapi, and all other middleware systems.",
5
+ "main": "greenlock-express.js",
6
+ "homepage": "https://greenlock.domains",
7
+ "files": [
8
+ "*.js",
9
+ "lib",
10
+ "scripts"
11
+ ],
12
+ "scripts": {
13
+ "start": "node_todo server.js ./config.js",
14
+ "test": "node_todo test/greenlock.js"
15
+ },
16
+ "directories": {
17
+ "example": "examples"
18
+ },
19
+ "dependencies": {
20
+ "@root/greenlock": "^4.0.5",
21
+ "redirect-https": "^1.3.1"
22
+ },
23
+ "trulyOptionalDependencies": {
24
+ "http-proxy": "^1.17.0",
25
+ "express": "^4.16.3",
26
+ "express-basic-auth": "^1.2.0",
27
+ "finalhandler": "^1.1.1",
28
+ "serve-index": "^1.9.1",
29
+ "serve-static": "^1.13.2",
30
+ "ws": "^5.2.1"
31
+ },
32
+ "devDependencies": {},
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "https://git.rootprojects.org/root/greenlock-express.js.git"
36
+ },
37
+ "keywords": [
38
+ "Let's Encrypt",
39
+ "ACME",
40
+ "greenlock",
41
+ "Free SSL",
42
+ "Automated HTTPS",
43
+ "https",
44
+ "tls"
45
+ ],
46
+ "author": "AJ ONeal <coolaj86@gmail.com> (https://solderjs.com/)",
47
+ "license": "MPL-2.0",
48
+ "bugs": {
49
+ "url": "https://git.rootprojects.org/root/greenlock-express.js/issues"
50
+ }
51
+ }
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ // BG WH \u001b[47m
5
+ // BOLD \u001b[1m
6
+ // RED \u001b[31m
7
+ // GREEN \u001b[32m
8
+ // RESET \u001b[0m
9
+
10
+ var grabbers = [
11
+ [
12
+ "",
13
+ "================================================================================",
14
+ "",
15
+ " 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥",
16
+ "🔥 🔥",
17
+ "🔥 Do you rely on Greenlock? 🔥",
18
+ "🔥 🔥",
19
+ " 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥"
20
+ ],
21
+
22
+ [
23
+ "",
24
+ "================================================================================",
25
+ "",
26
+ " 🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒",
27
+ "🍒 🍒",
28
+ "🍒 Do you rely on Greenlock? 🍒",
29
+ "🍒 🍒",
30
+ " 🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒"
31
+ ],
32
+
33
+ [
34
+ "",
35
+ "================================================================================",
36
+ "",
37
+ " 👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇",
38
+ "👉 👈",
39
+ "👉 Do you rely on Greenlock? 👈",
40
+ "👉 👈",
41
+ " 👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆 "
42
+ ],
43
+
44
+ [
45
+ "",
46
+ "================================================================================",
47
+ "",
48
+ " 👀 👀 👀 👀 👀 👀 👀 👀 👀 👀 👀 ",
49
+ "👀 👀",
50
+ "👀 Do you rely on Greenlock? 👀",
51
+ "👀 👀",
52
+ " 👀 👀 👀 👀 👀 👀 👀 👀 👀 👀 👀 ",
53
+ ]
54
+ ];
55
+
56
+ setTimeout(function() {
57
+ grabbers[Math.floor(Math.random() * grabbers.length)].concat([
58
+ "",
59
+ "Hey! Let's Encrypt will \u001b[31mSTOP WORKING\u001b[0m with Greenlock v2 at the end of October,",
60
+ "and \u001b[31mWITHOUT YOUR HELP\u001b[0m we won't get the next release out in time.",
61
+ "",
62
+ "If Greenlock has saved you time and money, and taken stress out of your life,",
63
+ "or you just love it, please reach out to return the favor today:",
64
+ "",
65
+ "\u001b[31mSAVE GREENLOCK:\u001b[0m",
66
+ "https://indiegogo.com/at/greenlock",
67
+ "",
68
+ "================================================================================",
69
+ ""
70
+ ]).forEach(function(line) {
71
+ console.info(line);
72
+ });
73
+ }, 300);
74
+
75
+ setTimeout(function() {
76
+ // give time to read
77
+ }, 1500);
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+
3
+ var Servers = module.exports;
4
+
5
+ var http = require("http");
6
+ var HttpMiddleware = require("./http-middleware.js");
7
+ var HttpsMiddleware = require("./https-middleware.js");
8
+ var sni = require("./sni.js");
9
+ var cluster = require("cluster");
10
+
11
+ Servers.create = function(greenlock) {
12
+ var servers = {};
13
+ var _httpServer;
14
+ var _httpsServer;
15
+
16
+ function startError(e) {
17
+ explainError(e);
18
+ process.exit(1);
19
+ }
20
+
21
+ servers.httpServer = function(defaultApp) {
22
+ if (_httpServer) {
23
+ if (defaultApp) {
24
+ console.error("error: can only call httpServer(app) once");
25
+ process.exit(1);
26
+ }
27
+ return _httpServer;
28
+ }
29
+
30
+ if (!defaultApp) {
31
+ defaultApp = require("redirect-https")();
32
+ }
33
+ // HEADERS SENT DEBUG NOTE #1
34
+ // As seen above, it's only possible to create the server once.
35
+ // It always gets the http middleware, it always gets a single default app
36
+ // Therefore it seems impossible to be an http.on('connection', app) problem
37
+ _httpServer = http.createServer(HttpMiddleware.create(greenlock, defaultApp));
38
+ _httpServer.once("error", startError);
39
+
40
+ return _httpServer;
41
+ };
42
+
43
+ var _middlewareApp;
44
+
45
+ servers.http2Server = function(secureOpts, defaultApp) {
46
+ return servers._httpsServer(secureOpts, defaultApp, function(secureOpts, fn) {
47
+ secureOpts.allowHTTP1 = true;
48
+ return require("http2").createSecureServer(secureOpts, fn);
49
+ });
50
+ };
51
+ servers.httpsServer = function(secureOpts, defaultApp) {
52
+ return servers._httpsServer(secureOpts, defaultApp, function(secureOpts, fn) {
53
+ return require("https").createServer(secureOpts, fn);
54
+ });
55
+ };
56
+ servers._httpsServer = function(secureOpts, defaultApp, createSecureServer) {
57
+ if (defaultApp) {
58
+ // TODO guard against being set twice?
59
+ _middlewareApp = defaultApp;
60
+ }
61
+
62
+ if (_httpsServer) {
63
+ if (secureOpts && Object.keys(secureOpts).length) {
64
+ throw new Error("Call glx.httpsServer(tlsOptions) before calling glx.serveApp(app)");
65
+ }
66
+ return _httpsServer;
67
+ }
68
+
69
+ if (!secureOpts) {
70
+ secureOpts = {};
71
+ }
72
+
73
+ _httpsServer = createSecureServer(
74
+ wrapDefaultSniCallback(greenlock, secureOpts),
75
+ HttpsMiddleware.create(greenlock, function(req, res) {
76
+ if (!_middlewareApp) {
77
+ throw new Error("Set app with `glx.serveApp(app)` or `glx.httpsServer(tlsOptions, app)`");
78
+ }
79
+ _middlewareApp(req, res);
80
+ })
81
+ );
82
+ _httpsServer.once("error", startError);
83
+
84
+ return _httpsServer;
85
+ };
86
+
87
+ servers.id = function() {
88
+ return (cluster.isWorker && cluster.worker.id) || "0";
89
+ };
90
+ servers.serveApp = function(app) {
91
+ return new Promise(function(resolve, reject) {
92
+ if ("function" !== typeof app) {
93
+ reject(
94
+ new Error(
95
+ "glx.serveApp(app) expects a node/express app in the format `function (req, res) { ... }`"
96
+ )
97
+ );
98
+ return;
99
+ }
100
+
101
+ var id = cluster.isWorker && cluster.worker.id;
102
+ var idstr = (id && "#" + id + " ") || "";
103
+ var plainServer = servers.httpServer();
104
+ var plainAddr = "0.0.0.0";
105
+ var plainPort = 80;
106
+ plainServer.listen(plainPort, plainAddr, function() {
107
+ console.info(
108
+ idstr + "Listening on",
109
+ plainAddr + ":" + plainPort,
110
+ "for ACME challenges, and redirecting to HTTPS"
111
+ );
112
+
113
+ // TODO fetch greenlock.servername
114
+ _middlewareApp = app || _middlewareApp;
115
+ var secureServer = servers.httpsServer(null, app);
116
+ var secureAddr = "0.0.0.0";
117
+ var securePort = 443;
118
+ secureServer.listen(securePort, secureAddr, function() {
119
+ console.info(idstr + "Listening on", secureAddr + ":" + securePort, "for secure traffic");
120
+
121
+ plainServer.removeListener("error", startError);
122
+ secureServer.removeListener("error", startError);
123
+ resolve();
124
+ });
125
+ });
126
+ });
127
+ };
128
+
129
+ return servers;
130
+ };
131
+
132
+ function explainError(e) {
133
+ console.error();
134
+ console.error("Error: " + e.message);
135
+ if ("EACCES" === e.errno) {
136
+ console.error("You don't have prmission to access '" + e.address + ":" + e.port + "'.");
137
+ console.error('You probably need to use "sudo" or "sudo setcap \'cap_net_bind_service=+ep\' $(which node)"');
138
+ } else if ("EADDRINUSE" === e.errno) {
139
+ console.error("'" + e.address + ":" + e.port + "' is already being used by some other program.");
140
+ console.error("You probably need to stop that program or restart your computer.");
141
+ } else {
142
+ console.error(e.code + ": '" + e.address + ":" + e.port + "'");
143
+ }
144
+ console.error();
145
+ }
146
+
147
+ function wrapDefaultSniCallback(greenlock, secureOpts) {
148
+ // I'm not sure yet if the original SNICallback
149
+ // should be called before or after, so I'm just
150
+ // going to delay making that choice until I have the use case
151
+ /*
152
+ if (!secureOpts.SNICallback) {
153
+ secureOpts.SNICallback = function(servername, cb) {
154
+ cb(null, null);
155
+ };
156
+ }
157
+ */
158
+ if (secureOpts.SNICallback) {
159
+ console.warn();
160
+ console.warn("[warning] Ignoring the given tlsOptions.SNICallback function.");
161
+ console.warn();
162
+ console.warn(" We're very open to implementing support for this,");
163
+ console.warn(" we just don't understand the use case yet.");
164
+ console.warn(" Please open an issue to discuss. We'd love to help.");
165
+ console.warn();
166
+ }
167
+
168
+ // TODO greenlock.servername for workers
169
+ secureOpts.SNICallback = sni.create(greenlock, secureOpts);
170
+ return secureOpts;
171
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+
3
+ require("./main.js");
4
+
5
+ var Single = module.exports;
6
+ var Servers = require("./servers.js");
7
+
8
+ Single.create = function(opts) {
9
+ var greenlock = require("./greenlock-shim.js").create(opts);
10
+
11
+ var servers = Servers.create(greenlock);
12
+
13
+ var single = {
14
+ ready: function(fn) {
15
+ fn(servers);
16
+ return single;
17
+ },
18
+ master: function(/*fn*/) {
19
+ // ignore
20
+ //fn(master);
21
+ return single;
22
+ },
23
+ serve: function(fn) {
24
+ // keeping backwards compat
25
+ if (1 === fn.length) {
26
+ single.ready(fn);
27
+ return;
28
+ }
29
+ // serving the app, right away
30
+ single.ready(function(glx) {
31
+ glx.serveApp(fn);
32
+ });
33
+ }
34
+ };
35
+ return single;
36
+ };