@zerooneit/expressive-tea 1.2.3 → 1.3.0-beta.2

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 (56) hide show
  1. package/.circleci/config.yml +9 -0
  2. package/README.md +70 -88
  3. package/classes/Boot.d.ts +7 -1
  4. package/classes/Boot.js +36 -133
  5. package/classes/LoadBalancer.d.ts +8 -0
  6. package/classes/LoadBalancer.js +31 -0
  7. package/classes/MetaData.js +1 -1
  8. package/classes/ProxyRoute.d.ts +14 -0
  9. package/classes/ProxyRoute.js +40 -0
  10. package/classes/Settings.d.ts +4 -2
  11. package/classes/Settings.js +29 -10
  12. package/decorators/annotations.d.ts +1 -0
  13. package/decorators/module.js +1 -1
  14. package/decorators/router.d.ts +3 -2
  15. package/decorators/router.js +8 -23
  16. package/decorators/server.d.ts +16 -14
  17. package/decorators/server.js +46 -33
  18. package/engines/http/index.d.ts +17 -0
  19. package/engines/http/index.js +60 -0
  20. package/engines/teacup/index.d.ts +19 -0
  21. package/engines/teacup/index.js +107 -0
  22. package/engines/teapot/index.d.ts +23 -0
  23. package/engines/teapot/index.js +157 -0
  24. package/engines/websocket/index.d.ts +9 -0
  25. package/engines/websocket/index.js +37 -0
  26. package/helpers/boot-helper.d.ts +7 -0
  27. package/helpers/boot-helper.js +78 -0
  28. package/helpers/object-helper.d.ts +1 -0
  29. package/helpers/object-helper.js +9 -1
  30. package/helpers/server.d.ts +6 -4
  31. package/helpers/server.js +54 -15
  32. package/helpers/teapot-helper.d.ts +17 -0
  33. package/helpers/teapot-helper.js +47 -0
  34. package/helpers/websocket-helper.d.ts +5 -0
  35. package/helpers/websocket-helper.js +20 -0
  36. package/inversify.config.d.ts +9 -0
  37. package/inversify.config.js +8 -0
  38. package/libs/classNames.d.ts +1 -0
  39. package/libs/classNames.js +4 -0
  40. package/libs/constants.d.ts +4 -2
  41. package/libs/constants.js +8 -6
  42. package/libs/interfaces.d.ts +27 -15
  43. package/package.json +30 -8
  44. package/services/WebsocketService.d.ts +8 -7
  45. package/services/WebsocketService.js +12 -7
  46. package/.editorconfig +0 -31
  47. package/.travis.yml +0 -26
  48. package/CHANGELOG.md +0 -256
  49. package/CODE_OF_CONDUCT.md +0 -76
  50. package/CONTRIBUTING.md +0 -92
  51. package/SECURITY.md +0 -20
  52. package/codecov.yml +0 -10
  53. package/jsdocs-json.json +0 -35
  54. package/tools/jsdocs/helpers/table-builder.js +0 -57
  55. package/tools/jsdocs/plugins/custom-tags.js +0 -33
  56. package/tools/jsdocs/plugins/scape-at.js +0 -24
@@ -23,9 +23,18 @@ jobs:
23
23
  - checkout
24
24
  # Next, the node orb's install-packages step will install the dependencies from a package.json.
25
25
  # The orb install-packages step will also automatically cache them for faster future runs.
26
+ - restore_cache:
27
+ keys:
28
+ - expressive-tea-{{ checksum "package.json" }}
29
+ - expressive-tea-
30
+
26
31
  - node/install-packages:
27
32
  # If you are using yarn, change the line below from "npm" to "yarn"
28
33
  pkg-manager: yarn
34
+ - save_cache:
35
+ paths:
36
+ - node_modules
37
+ key: expressive-tea-{{ checksum "package.json" }}
29
38
  - run:
30
39
  name: Expressive Tea Tests
31
40
  command: npm test
package/README.md CHANGED
@@ -1,77 +1,76 @@
1
1
  <p align="center">
2
2
  <!-- Npm Version -->
3
3
  <a href="https://www.npmjs.com/package/@zerooneit/expressive-tea">
4
- <img alt="npm (scoped)" src="https://img.shields.io/npm/v/@zerooneit/expressive-tea?style=for-the-badge">
5
- </a>
6
-
7
- <!-- Test Coverage -->
8
- <a href="https://codecov.io/gh/Expressive-Tea/expresive-tea">
9
- <img alt="Codecov" src="https://img.shields.io/codecov/c/github/Expressive-Tea/expresive-tea?style=for-the-badge">
10
- </a>
11
-
12
- <!-- Build -->
13
- <a href="https://travis-ci.org/Zero-OneiT/expresive-tea">
14
- <img alt="Circle CI" src="https://img.shields.io/circleci/build/github/Expressive-Tea/expresive-tea/master?style=for-the-badge">
15
- </a>
16
-
17
- <!-- License -->
18
- <a href="https://github.com/Zero-OneiT/expresive-tea/blob/develop/LICENSE">
19
- <img alt="NPM" src="https://img.shields.io/npm/l/@zerooneit/expressive-tea?style=for-the-badge">
4
+ <img alt="npm (scoped)" src="https://img.shields.io/npm/v/@zerooneit/expressive-tea?style=flat-square">
20
5
  </a>
21
6
 
22
7
  <!-- Downloads -->
23
8
  <a href="https://www.npmjs.com/package/@zerooneit/expressive-tea">
24
- <img alt="npm" src="https://img.shields.io/npm/dw/@zerooneit/expressive-tea?style=for-the-badge">
9
+ <img alt="npm" src="https://img.shields.io/npm/dw/@zerooneit/expressive-tea?style=flat-square">
25
10
  </a>
26
11
 
27
- <!-- Dependencies -->
12
+ <!-- Dependencies
28
13
  <a href="https://libraries.io/npm/@zerooneit%2Fexpressive-tea">
29
- <img alt="Libraries.io dependency status for latest release, scoped npm package" src="https://img.shields.io/librariesio/release/npm/@zerooneit/expressive-tea?style=for-the-badge">
14
+ <img alt="Libraries.io dependency status for latest release, scoped npm package" src="https://img.shields.io/librariesio/release/npm/@zerooneit/expressive-tea?style=flat-square">
15
+ </a>
16
+ -->
17
+
18
+ <!-- License
19
+ <a href="https://github.com/Expressive-Tea/expresive-tea/blob/develop/LICENSE">
20
+ <img alt="NPM" src="https://img.shields.io/npm/l/@zerooneit/expressive-tea?style=flat-square">
30
21
  </a>
22
+ -->
31
23
 
32
24
  <!-- Vulnerabilities -->
33
25
  <a href="https://snyk.io//test/github/Expressive-Tea/expresive-tea?targetFile=package.json">
34
- <img alt="Snyk Vulnerabilities for npm package" src="https://img.shields.io/snyk/vulnerabilities/github/Expressive-Tea/expresive-tea?style=for-the-badge">
26
+ <img alt="Snyk Vulnerabilities for npm package" src="https://img.shields.io/snyk/vulnerabilities/github/expressive-tea/expresive-tea?style=flat-square">
35
27
  </a>
36
28
 
37
29
  <!-- Last Commit
38
- <a href="https://github.com/Zero-OneiT/expresive-tea">
39
- <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Zero-OneiT/expresive-tea?style=for-the-badge">
40
- </a> -->
41
-
30
+ <a href="https://github.com/Expressive-Tea/expresive-tea">
31
+ <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Expressive-Tea/expresive-tea?style=flat-square">
32
+ </a>
33
+ -->
42
34
  <!-- Stars -->
43
- <a href="https://github.com/Zero-OneiT/expresive-tea/stargazers">
44
- <img alt="GitHub stars" src="https://img.shields.io/github/stars/Zero-OneiT/expresive-tea?style=for-the-badge">
35
+ <a href="https://github.com/Expressive-Tea/expresive-tea/stargazers">
36
+ <img alt="GitHub stars" src="https://img.shields.io/github/stars/Expressive-Tea/expresive-tea?style=flat-square">
45
37
  </a>
46
38
 
47
- <!-- Source Rank
39
+ <!-- Source Rank
48
40
  <a href="https://libraries.io/npm/@zerooneit%2Fexpressive-tea/sourcerank">
49
- <img alt="Libraries.io SourceRank, scoped npm package" src="https://img.shields.io/librariesio/sourcerank/npm/@zerooneit/expressive-tea?style=for-the-badge">
50
- </a> -->
51
-
41
+ <img alt="Libraries.io SourceRank, scoped npm package" src="https://img.shields.io/librariesio/sourcerank/npm/@zerooneit/expressive-tea?style=flat-square">
42
+ </a>
43
+ -->
52
44
  <!-- Rating
53
45
  <a href="https://pkgreview.dev/npm/@zerooneit%2Fexpressive-tea">
54
- <img alt="pkgreview.dev Package Ratings" src="https://img.shields.io/pkgreview/rating/npm/@zerooneit/expressive-tea?style=for-the-badge">
55
- </a> -->
56
-
46
+ <img alt="pkgreview.dev Package Ratings" src="https://img.shields.io/pkgreview/rating/npm/@zerooneit/expressive-tea?style=flat-square">
47
+ </a>
48
+ -->
57
49
  <!-- Issues
58
- <a href="https://github.com/Zero-OneiT/expresive-tea/issues">
59
- <img alt="GitHub issues" src="https://img.shields.io/github/issues-raw/Zero-Oneit/expresive-tea?style=for-the-badge">
60
- </a> -->
61
-
62
- <!-- Gitter -->
63
- <a href="https://gitter.im/Zero-OneiT/expresive-tea">
64
- <img alt="Gitter" src="https://img.shields.io/gitter/room/zero-oneit/expresive-tea?style=for-the-badge">
50
+ <a href="https://github.com/Expressive-Tea/expresive-tea/issues">
51
+ <img alt="GitHub issues" src="https://img.shields.io/github/issues-raw/Zero-Oneit/expresive-tea?style=flat-square">
52
+ </a>
53
+ -->
54
+ <!-- Gitter
55
+ <a href="https://gitter.im/Expressive-Tea/expresive-tea">
56
+ <img alt="Gitter" src="https://img.shields.io/gitter/room/zero-oneit/expresive-tea?style=flat-square">
57
+ </a>
58
+ -->
59
+ <!-- Test Coverage -->
60
+ <a href="https://codecov.io/gh/Expressive-Tea/expresive-tea">
61
+ <img alt="Codecov" src="https://img.shields.io/codecov/c/github/expressive-tea/expresive-tea?label=Test%20coverage&style=flat-square">
65
62
  </a>
66
63
 
67
-
64
+ <!-- Build -->
65
+ <a href="https://travis-ci.org/Expressive-Tea/expresive-tea">
66
+ <img alt="Travis (.org) branch" src="https://ci.zero-oneit.systems/buildStatus/icon?job=Expressive+Tea&style=flat-square">
67
+ </a>
68
68
  </p>
69
69
 
70
-
71
70
  <!-- PROJECT LOGO -->
72
71
  <br />
73
72
  <p align="center">
74
- <a href="https://github.com/Zero-OneiT/expresive-tea">
73
+ <a href="https://github.com/Expressive-Tea/expresive-tea">
75
74
  <img src="images/logo.png" alt="Logo" width="160" />
76
75
  </a>
77
76
 
@@ -85,9 +84,9 @@
85
84
  <br />
86
85
  <a href="https://codesandbox.io/s/expressive-tea-2kmg7?fontsize=14&hidenavigation=1&theme=dark">View Demo</a>
87
86
  ·
88
- <a href="https://github.com/Zero-OneiT/expresive-tea/issues">Report Bug</a>
87
+ <a href="https://github.com/Expressive-Tea/expresive-tea/issues">Report Bug</a>
89
88
  ·
90
- <a href="https://github.com/Zero-OneiT/expresive-tea/issues">Request Feature</a>
89
+ <a href="https://github.com/Expressive-Tea/expresive-tea/issues">Request Feature</a>
91
90
  </p>
92
91
  </p>
93
92
 
@@ -110,28 +109,31 @@
110
109
  * [Principal Sponsors](#principal-sponsors)
111
110
  * [Stay on touch](#stay-on-touch)
112
111
  * [License](#license)
113
- * [Disclaimers](#disclaimers)
112
+ * [Disclamers](#disclaimers)
114
113
 
115
114
 
116
115
  ## About the project
117
- Expressive Tea is a framework to help build server-side applications in [NodeJS](https://nodejs.org/) and use modern Javascript powered by
118
- [Typescript](https://www.typescriptlang.org/). As Expressive Tea is using [express](https://expressjs.com/) is compatible with all the middlewares and modules and provides
119
- easy migration from express applications.
116
+ Expressive Tea is framework to help build server-side applications in [NodeJS](https://nodejs.org/) and use modern Javascript powered by
117
+ [Typescript](https://www.typescriptlang.org/). As Expressive Tea is using [express](https://expressjs.com/) is compatible with all the middlewares and modules and provide
118
+ an easy migration from express applications.
120
119
 
121
- Expressive Tea is a flexible framework. It also gives developers the freedom to build their architectures by providing descriptive decorators, a plugin engine, shareable modules, and modern Javascript.
120
+ Expressive Tea is a flexible framework but also giving freedom to the developer to build their own architectures
121
+ by providing descriptive decorators, a plugin engine, shareable modules and moder Javascript.
122
122
 
123
123
  ### Motivation
124
- Server-side applications contain excellent tools, helpers, and libraries to improve productivity, but at the same time, it haves a considerable downside, **architecture**. Expressive Tea's primary motivation is a relief the stress of the architecture by providing shareable/pluggable projects; you can write a plugin to set up express middlewares, databases settings, or WebSockets, to name some; and you can share them through your following projects or the community.
125
- The main goal is making uncomplicated creation of server-side applications, module-driven, pluggable, accessible, and effortless architecture.
124
+ Server-side applications it contains awesome tools, helpers, and libraries to improve productivity but at same time it
125
+ haves a large downside, **architecture**. Expressive Tea main motivation is relief the stress of the architecture by
126
+ providing a shareable/pluggable projects, you can write a plugin to setting up express middlewares, databases settings,
127
+ or websockets to name some; and you can share them through your next projects or the community.
126
128
 
127
129
  Main goal is making uncomplicaded creation of server-side applications, modulables, plugables, free and efortless
128
130
  architecture.
129
131
 
130
132
  ### Features
131
- * Easy Setting up and start-up of a webserver.
133
+ * Easy Setting up and start up of webserver.
132
134
  * Extends and configuration with plugins and well-defined boot stages.
133
- * Modules are not complex dependencies and can be shareable between projects.
134
- * Declare Server Middlewares configuration as hard or soft dependent at the server level.
135
+ * Modules are not hard dependencies and can be shareable between projects.
136
+ * Declare Server Middlewares configuration as hard or soft dependency at server level.
135
137
  * Dependency Injection is available for controllers as providers declared in modules using InversifyJs.
136
138
  * Declarative Router on Controllers.
137
139
  * Declarative Verbs and Middlewares under module and verb level.
@@ -143,6 +145,7 @@ architecture.
143
145
  * [Typescript](https://www.typescriptlang.org/) - Main Language
144
146
  * [Inversify](https://github.com/inversify/InversifyJS/) - Used for dependency Injection
145
147
  * [Reflect Metadata](https://github.com/rbuckton/reflect-metadata) - Used to get code metadata.
148
+ * [YARN](https://yarnpkg.com/) - Used to build and dependencies.
146
149
 
147
150
  ## Getting Started
148
151
 
@@ -151,30 +154,10 @@ architecture.
151
154
  **Important!** Expressive Tea requires Node >= 6, Express >= 4, TypeScript >= 2.0 and the `experimentalDecorators`,
152
155
  `lib` compilation options in your `tsconfig.json` with the next configuration.
153
156
 
154
- Expressive Tea is woking as **Bring Your Own Architecture**, which means is not include any plugin or particular configuration for Express.
155
-
156
- ### Installation using Tea CLI
157
-
158
- #### Installing tea
159
- ```bash
160
- npm i -g @expressive-tea/tea
161
- ```
162
-
163
- #### Create a Project
164
- ```bash
165
- tea brew <name_of_project>
166
- ```
167
-
168
- #### Run Project
169
-
170
- In the project directory.
171
-
172
- ```bash
173
- tea serve
174
- ```
175
-
176
- ### Installation by pure typescript
157
+ Expressive Tea is not having any configuration of any Express Plugin or any database connection beside is built it
158
+ on Express it is woking as **Bring Your Own Architecture**.
177
159
 
160
+ ### Installation
178
161
  ```bash
179
162
  npm i --save @zerooneit/expressive-tea
180
163
  ```
@@ -198,7 +181,7 @@ npm i --save @zerooneit/expressive-tea
198
181
  }
199
182
  ```
200
183
  ### Examples
201
- You can look into our simple example [here](https://github.com/Zero-OneiT/expressive-tea-sandbox), or edit or see how is working on our live preview.
184
+ You can looking into our simple example [here](https://github.com/Expressive-Tea/expressive-tea-sandbox), or edit or see how is working on our live preview using th button below.
202
185
 
203
186
  <p align="center">
204
187
  <br/>
@@ -209,26 +192,25 @@ You can look into our simple example [here](https://github.com/Zero-OneiT/expres
209
192
 
210
193
  ## Contributing
211
194
 
212
- Please read [CONTRIBUTING.md](https://gist.github.com/PurpleBooth/b24679402957c63ec426) for details on our code of conduct and the process for submitting pull requests to us.
195
+ Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.
213
196
 
214
197
  ## Versioning
215
198
 
216
- We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/your/project/tags).
199
+ We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/Expressive-Tea/expresive-tea/tags).
217
200
 
218
201
  ## Contributors
219
202
 
220
203
  * **Diego Resendez** - *Lead Developer / Author* - [zerooneit](https://github.com/zerooneit)
221
204
 
222
- See also the list of [contributors](https://github.com/Zero-OneiT/expresive-tea/contributors) who participated in this project.
205
+ See also the list of [contributors](https://github.com/Expressive-Tea/expresive-tea/contributors) who participated in this project.
223
206
 
224
207
  ## Support
225
- If you are experiencing any issues, we will be happy to help. You can report a problem using the [issues page](https://github.com/Zero-OneiT/expresive-tea/issues) or the [chat](https://gitter.im/Zero-OneiT/expresive-tea). You can also ask questions at [Stack overflow](http://stackoverflow.com/tags/expressive-tea) using the `expressive-tea` tag.
226
-
227
- If you want to share your thoughts with the development team or join us, you will do so using the [official mailing list](https://groups.google.com/forum/#!forum/expressive-tea/). You can check out the
228
- [wiki](https://github.com/Zero-OneiT/expresive-tea/blob/develop/README.md) to learn more about Expressive Tea internals or check our [documentation](https://zero-oneit.github.io/expresive-tea/).
208
+ If you are experience any kind of issues we will be happy to help. You can report an issue using the [issues page](https://github.com/Expressive-Tea/expresive-tea/issues) or the [chat](https://gitter.im/Expressive-Tea/expresive-tea). You can also ask questions at [Stack overflow](http://stackoverflow.com/tags/expressive-tea) using the `expressive-tea` tag.
229
209
 
230
- Expressive Tea is an open-source project; our goal is to create a fantastic framework that helps build marvelous server-side applications. If you like to join as a Sponsor or backer to continue growing, don't hesitate to get in touch with us at [projects@zero-oneit.com](mailto:projects@zero-oneit.com).
210
+ If you want to share your thoughts with the development team or join us you will be able to do so using the [official the mailing list](https://groups.google.com/forum/#!forum/expressive-tea/). You can check out the
211
+ [wiki](https://github.com/Expressive-Tea/expresive-tea/blob/develop/README.md) to learn more about Expressive Tea internals or check our [documentation](https://docs.expressive-tea.io).
231
212
 
213
+ Expressive Tea is an open source project, our goal is create an awesome framework that helps to build marvelous server side applications. If you like to join as Sponsor or backer to continue grow, please you can contact us on [projects@zero-oneit.com](mailto:projects@zero-oneit.com)
232
214
  #### Principal Sponsors
233
215
 
234
216
  <table style="text-align:center;"><tr><td>
@@ -243,7 +225,7 @@ Expressive Tea is an open-source project; our goal is to create a fantastic fram
243
225
  * Email - [support@expressive-tea.io](support@expressive-tea.io)
244
226
 
245
227
  ## License
246
- This project is licensed under the Apache-2.0 License - see the [LICENSE](LICENSE) file for details.
228
+ This project is licensed under the Apache-2.0 License - see the [LICENSE](LICENSE) file for details
247
229
 
248
230
  <p align="center">
249
231
  <a href="https://app.fossa.io/projects/git%2Bgithub.com%2FZero-OneiT%2Fexpresive-tea?ref=badge_large">
package/classes/Boot.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import 'reflect-metadata';
2
+ import '../inversify.config';
1
3
  import { Express } from 'express';
2
4
  import Settings from '../classes/Settings';
3
5
  import { ExpressiveTeaApplication } from '../libs/interfaces';
@@ -36,6 +38,11 @@ declare abstract class Boot {
36
38
  */
37
39
  private readonly server;
38
40
  constructor();
41
+ /**
42
+ * Get Express Application
43
+ * @returns Express
44
+ */
45
+ getApplication(): Express;
39
46
  /**
40
47
  * Bootstrap and verify that all the required plugins are correctly configured and proceed to attach all the
41
48
  * registered modules. <b>Remember</b> this is the unique method that must be decorated for the Register Module
@@ -45,5 +52,4 @@ declare abstract class Boot {
45
52
  */
46
53
  start(): Promise<ExpressiveTeaApplication>;
47
54
  }
48
- export declare function resolveProxy(ProxyContainer: any, server: Express): Promise<void>;
49
55
  export default Boot;
package/classes/Boot.js CHANGED
@@ -1,19 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resolveProxy = void 0;
3
+ require("reflect-metadata");
4
+ require("../inversify.config");
4
5
  const $P = require("bluebird");
5
6
  // tslint:disable-next-line:no-duplicate-imports
6
7
  const express = require("express");
7
8
  const fs = require("fs");
8
9
  const http = require("http");
9
10
  const https = require("https");
10
- const MetaData_1 = require("../classes/MetaData");
11
11
  const Settings_1 = require("../classes/Settings");
12
- const BootLoaderExceptions_1 = require("../exceptions/BootLoaderExceptions");
13
- const object_helper_1 = require("../helpers/object-helper");
14
12
  const constants_1 = require("../libs/constants");
15
- const WebSocket = require("ws");
16
- const WebsocketService_1 = require("../services/WebsocketService");
13
+ const index_1 = require("../engines/http/index");
14
+ const index_2 = require("../engines/websocket/index");
15
+ const index_3 = require("../engines/teapot/index");
16
+ const teacup_1 = require("../engines/teacup");
17
+ // tslint:disable-next-line:no-duplicate-imports
18
+ const inversify_config_1 = require("../inversify.config");
17
19
  /**
18
20
  * Expressive Tea Application interface is the response from an started application, contains the express application
19
21
  * and a node http server instance.
@@ -32,15 +34,6 @@ const WebsocketService_1 = require("../services/WebsocketService");
32
34
  */
33
35
  class Boot {
34
36
  constructor() {
35
- /**
36
- * Maintain a reference to Singleton instance of Settings, if settings still does not initialized it will created
37
- * automatically when extended class create a new instance.
38
- *
39
- * @type {Settings}
40
- * @public
41
- * @summary Server Settings instance reference
42
- */
43
- this.settings = new Settings_1.default();
44
37
  /**
45
38
  * Automatically create an Express application instance which will be user to configure over all the boot stages.
46
39
  * @type {Express}
@@ -49,7 +42,14 @@ class Boot {
49
42
  * @summary Express Application instance internal property.
50
43
  */
51
44
  this.server = express();
52
- this.settings.set('application', this.server);
45
+ this.settings = Settings_1.default.getInstance(this);
46
+ }
47
+ /**
48
+ * Get Express Application
49
+ * @returns Express
50
+ */
51
+ getApplication() {
52
+ return this.server;
53
53
  }
54
54
  /**
55
55
  * Bootstrap and verify that all the required plugins are correctly configured and proceed to attach all the
@@ -61,53 +61,33 @@ class Boot {
61
61
  async start() {
62
62
  return new $P(async (resolver, rejector) => {
63
63
  try {
64
+ const localContainer = inversify_config_1.default.createChild();
64
65
  const privateKey = this.settings.get('privateKey');
65
66
  const certificate = this.settings.get('certificate');
66
- const startWebsocket = this.settings.get('startWebsocket');
67
- const detachWebsocket = this.settings.get('detachWebsocket');
68
- const serverConfigQueue = [];
69
- // tslint:disable-next-line:one-variable-per-declaration
70
- let ws, wss;
71
67
  const server = http.createServer(this.server);
72
68
  const secureServer = privateKey && certificate && https.createServer({
73
69
  cert: fs.readFileSync(certificate).toString('utf-8'),
74
70
  key: fs.readFileSync(privateKey).toString('utf-8')
75
71
  }, this.server);
76
- if (startWebsocket) {
77
- ws = new WebSocket.Server(detachWebsocket ? { noServer: true } : { server });
78
- if (secureServer) {
79
- wss = new WebSocket.Server(detachWebsocket ? { noServer: true } : { server: secureServer });
80
- }
81
- WebsocketService_1.default.init(ws, wss);
82
- WebsocketService_1.default.getInstance().setHttpServer(server);
83
- WebsocketService_1.default.getInstance().setHttpServer(secureServer);
84
- }
85
- await resolveProxyContainers(this);
86
- await resolveDirectives(this, this.server);
87
- await resolveStatic(this, this.server);
88
- for (const stage of constants_1.BOOT_ORDER) {
89
- await resolveStage(stage, this, this.server);
90
- }
91
- await resolveStage(constants_1.BOOT_STAGES.APPLICATION, this, this.server);
92
- serverConfigQueue.push(new $P(resolve => server.listen(this.settings.get('port'), () => {
93
- console.log(`Running HTTP Server on [${this.settings.get('port')}]`);
94
- resolve();
95
- })));
96
- if (secureServer) {
97
- serverConfigQueue.push(new $P(resolve => secureServer.listen(this.settings.get('securePort'), () => {
98
- console.log(`Running Secure HTTP Server on [${this.settings.get('securePort')}]`);
99
- resolve();
100
- })));
101
- }
102
- await $P.all([
103
- resolveStage(constants_1.BOOT_STAGES.AFTER_APPLICATION_MIDDLEWARES, this, this.server),
104
- resolveStage(constants_1.BOOT_STAGES.ON_HTTP_CREATION, this, this.server, server, secureServer)
105
- ]);
106
- $P.all(serverConfigQueue)
107
- .then(() => {
108
- return resolveStage(constants_1.BOOT_STAGES.START, this, this.server, server, secureServer);
109
- })
110
- .then(() => resolver({ application: this.server, server, secureServer }));
72
+ // Injectables
73
+ localContainer.bind('server').toConstantValue(server);
74
+ localContainer.bind('secureServer').toConstantValue(secureServer || undefined);
75
+ localContainer.bind('context').toConstantValue(this);
76
+ localContainer.bind('settings').toConstantValue(this.settings);
77
+ const httpEngine = localContainer.resolve(index_1.default);
78
+ const websocketEngine = localContainer.resolve(index_2.default);
79
+ const teapotEngine = localContainer.resolve(index_3.default);
80
+ const teacupEngine = localContainer.resolve(teacup_1.default);
81
+ await websocketEngine.init();
82
+ await httpEngine.init();
83
+ await httpEngine.resolveProxyContainers();
84
+ await httpEngine.resolveStages(constants_1.BOOT_ORDER);
85
+ await httpEngine.resolveStages([constants_1.BOOT_STAGES.AFTER_APPLICATION_MIDDLEWARES, constants_1.BOOT_STAGES.ON_HTTP_CREATION], server, secureServer);
86
+ const listenerServers = await httpEngine.start();
87
+ await httpEngine.resolveStages([constants_1.BOOT_STAGES.START], ...listenerServers);
88
+ await teapotEngine.start();
89
+ await teacupEngine.start();
90
+ resolver({ application: this.server, server, secureServer });
111
91
  }
112
92
  catch (e) {
113
93
  return rejector(e);
@@ -115,81 +95,4 @@ class Boot {
115
95
  });
116
96
  }
117
97
  }
118
- async function resolveStage(stage, ctx, server, ...extraArgs) {
119
- try {
120
- await bootloaderResolve(stage, server, ctx, ...extraArgs);
121
- if (stage === constants_1.BOOT_STAGES.APPLICATION) {
122
- await resolveModules(ctx, server);
123
- }
124
- }
125
- catch (e) {
126
- checkIfStageFails(e);
127
- }
128
- }
129
- async function resolveDirectives(instance, server) {
130
- const registeredDirectives = MetaData_1.default.get(constants_1.REGISTERED_DIRECTIVES_KEY, (0, object_helper_1.getClass)(instance)) || [];
131
- registeredDirectives.forEach((options) => {
132
- server.set.call(server, options.name, ...options.settings);
133
- });
134
- }
135
- async function resolveStatic(instance, server) {
136
- const registeredStatic = MetaData_1.default.get(constants_1.REGISTERED_STATIC_KEY, (0, object_helper_1.getClass)(instance)) || [];
137
- registeredStatic.forEach((staticOptions) => {
138
- if (staticOptions.virtual) {
139
- server.use(staticOptions.virtual, express.static(staticOptions.root, staticOptions.options));
140
- }
141
- else {
142
- server.use(express.static(staticOptions.root, staticOptions.options));
143
- }
144
- });
145
- }
146
- async function resolveModules(instance, server) {
147
- const registeredModules = MetaData_1.default.get(constants_1.REGISTERED_MODULE_KEY, instance, 'start') || [];
148
- registeredModules.forEach(Module => {
149
- const moduleInstance = new Module();
150
- moduleInstance.__register(server);
151
- });
152
- }
153
- async function bootloaderResolve(STAGE, server, instance, ...args) {
154
- const bootLoader = MetaData_1.default.get(constants_1.BOOT_STAGES_KEY, (0, object_helper_1.getClass)(instance)) || constants_1.STAGES_INIT;
155
- for (const loader of bootLoader[STAGE] || []) {
156
- try {
157
- await selectLoaderType(loader, server, ...args);
158
- }
159
- catch (e) {
160
- shouldFailIfRequire(e, loader);
161
- }
162
- }
163
- }
164
- async function resolveProxyContainers(context) {
165
- const ProxyContainers = MetaData_1.default.get(constants_1.ROUTER_PROXIES_KEY, (0, object_helper_1.getClass)(context)) || [];
166
- for (const Container of ProxyContainers) {
167
- resolveProxy(Container, context.server);
168
- }
169
- }
170
- async function resolveProxy(ProxyContainer, server) {
171
- const proxyContainer = new ProxyContainer();
172
- proxyContainer.__register(server);
173
- }
174
- exports.resolveProxy = resolveProxy;
175
- async function selectLoaderType(loader, server, ...args) {
176
- return loader.method(server, ...args);
177
- }
178
- function checkIfStageFails(e) {
179
- if (e instanceof BootLoaderExceptions_1.BootLoaderSoftExceptions) {
180
- console.info(e.message);
181
- }
182
- else {
183
- console.error(e.message);
184
- // Re Throwing Error to Get it a top level.
185
- throw e;
186
- }
187
- }
188
- function shouldFailIfRequire(e, loader) {
189
- const failMessage = `Failed [${loader.name}]: ${e.message}`;
190
- if (!loader || loader.required) {
191
- throw new BootLoaderExceptions_1.BootLoaderRequiredExceptions(failMessage);
192
- }
193
- throw new BootLoaderExceptions_1.BootLoaderSoftExceptions(`${failMessage} and will be not enabled`);
194
- }
195
98
  exports.default = Boot;
@@ -0,0 +1,8 @@
1
+ export default class LoadBalancer {
2
+ private readonly bins;
3
+ /**
4
+ * @offset should be used for unit testing and nothing else.
5
+ */
6
+ constructor(count: number, offset?: number);
7
+ pick(): number;
8
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class LoadBalancer {
4
+ /**
5
+ * @offset should be used for unit testing and nothing else.
6
+ */
7
+ constructor(count, offset = 0) {
8
+ this.bins = new Array(count);
9
+ // Initializes the elements of the array to zero.
10
+ for (let i = 0; i < this.bins.length; i++) {
11
+ this.bins[i] = offset;
12
+ }
13
+ }
14
+ pick() {
15
+ const a = Math.trunc(Math.random() * this.bins.length);
16
+ const b = Math.trunc(Math.random() * this.bins.length);
17
+ const result = this.bins[a] < this.bins[b] ? a : b;
18
+ // Accounts for overflow if enough requests go through this balancer.
19
+ if (this.bins[result] === Number.MAX_SAFE_INTEGER) {
20
+ // Resets all bins as it assumes they have all received an equal
21
+ // number of requests. Starts again from a blank state.
22
+ for (let i = 0; i < this.bins.length; i++) {
23
+ this.bins[i] = 0;
24
+ }
25
+ }
26
+ // Increments the number of requests assigned to this bin.
27
+ this.bins[result]++;
28
+ return result;
29
+ }
30
+ }
31
+ exports.default = LoadBalancer;
@@ -32,8 +32,8 @@ class Metadata {
32
32
  return Reflect.hasMetadata(key, (0, object_helper_1.getClass)(target), propertyKey);
33
33
  }
34
34
  catch (er) {
35
+ return false;
35
36
  }
36
- return false;
37
37
  }
38
38
  static hasOwn(key, target, propertyKey) {
39
39
  return Reflect.hasOwnMetadata(key, (0, object_helper_1.getClass)(target), propertyKey);
@@ -0,0 +1,14 @@
1
+ import { RequestHandler } from 'express';
2
+ export default class ProxyRoute {
3
+ readonly registeredOn: string;
4
+ private balancer;
5
+ private servers;
6
+ private clients;
7
+ private lastServerSelected;
8
+ constructor(registeredOn: string);
9
+ hasClients(): boolean;
10
+ isClientOnRoute(teacupId: string): boolean;
11
+ registerServer(address: string, teacupId: string): void;
12
+ unregisterServer(teacupId: string): void;
13
+ registerRoute(): RequestHandler;
14
+ }
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const proxy = require("express-http-proxy");
4
+ const LoadBalancer_1 = require("./LoadBalancer");
5
+ const lodash_1 = require("lodash");
6
+ class ProxyRoute {
7
+ constructor(registeredOn) {
8
+ this.servers = [];
9
+ this.clients = [];
10
+ this.lastServerSelected = 0;
11
+ this.registeredOn = registeredOn;
12
+ }
13
+ hasClients() {
14
+ return (0, lodash_1.size)(this.clients) > 0;
15
+ }
16
+ isClientOnRoute(teacupId) {
17
+ return (0, lodash_1.includes)(this.clients, teacupId);
18
+ }
19
+ registerServer(address, teacupId) {
20
+ this.servers.push({ teacupId, address });
21
+ this.clients.push(teacupId);
22
+ this.balancer = new LoadBalancer_1.default(this.servers.length, this.lastServerSelected);
23
+ }
24
+ unregisterServer(teacupId) {
25
+ const index = (0, lodash_1.indexOf)(this.clients, teacupId);
26
+ this.servers.splice(index, 1);
27
+ this.clients.splice(index, 1);
28
+ this.balancer = new LoadBalancer_1.default(this.servers.length);
29
+ }
30
+ registerRoute() {
31
+ return proxy(() => {
32
+ this.lastServerSelected = this.balancer.pick();
33
+ const server = this.servers[this.lastServerSelected];
34
+ return server.address;
35
+ }, {
36
+ memoizeHost: false
37
+ });
38
+ }
39
+ }
40
+ exports.default = ProxyRoute;