@zerooneit/expressive-tea 1.2.0 → 1.2.3
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.
- package/.circleci/config.yml +49 -0
- package/README.md +122 -35
- package/SECURITY.md +20 -0
- package/classes/Boot.d.ts +2 -0
- package/classes/Boot.js +53 -20
- package/classes/MetaData.js +9 -9
- package/decorators/annotations.js +1 -0
- package/decorators/module.js +5 -4
- package/decorators/proxy.d.ts +13 -0
- package/decorators/proxy.js +70 -0
- package/decorators/router.js +23 -15
- package/decorators/server.d.ts +14 -4
- package/decorators/server.js +38 -10
- package/exceptions/BootLoaderExceptions.js +1 -0
- package/exceptions/RequestExceptions.js +1 -0
- package/helpers/decorators.js +1 -0
- package/helpers/object-helper.d.ts +1 -0
- package/helpers/object-helper.js +10 -3
- package/helpers/server.d.ts +1 -1
- package/helpers/server.js +7 -6
- package/images/announcement-01.png +0 -0
- package/images/logo-sticky-01.png +0 -0
- package/images/logo-wp-01.png +0 -0
- package/libs/constants.d.ts +31 -6
- package/libs/constants.js +34 -0
- package/libs/interfaces.d.ts +14 -2
- package/libs/types.d.ts +2 -0
- package/package.json +30 -35
- package/services/DependencyInjection.js +2 -1
- package/services/WebsocketService.d.ts +19 -0
- package/services/WebsocketService.js +40 -0
- package/.chglog/CHANGELOG.tpl.md +0 -24
- package/.chglog/config.yml +0 -40
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Use the latest 2.1 version of CircleCI pipeline process engine.
|
|
2
|
+
# See: https://circleci.com/docs/2.0/configuration-reference
|
|
3
|
+
version: 2.1
|
|
4
|
+
|
|
5
|
+
orbs:
|
|
6
|
+
# The Node.js orb contains a set of prepackaged CircleCI configuration you can utilize
|
|
7
|
+
# Orbs reduce the amount of configuration required for common tasks.
|
|
8
|
+
# See the orb documentation here: https://circleci.com/developer/orbs/orb/circleci/node
|
|
9
|
+
node: circleci/node@4.7
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
# Below is the definition of your job to build and test your app, you can rename and customize it as you want.
|
|
13
|
+
build-and-test:
|
|
14
|
+
# These next lines define a Docker executor: https://circleci.com/docs/2.0/executor-types/
|
|
15
|
+
# You can specify an image from Dockerhub or use one of our Convenience Images from CircleCI's Developer Hub.
|
|
16
|
+
# A list of available CircleCI Docker Convenience Images are available here: https://circleci.com/developer/images/image/cimg/node
|
|
17
|
+
docker:
|
|
18
|
+
- image: cimg/node:16.10
|
|
19
|
+
# Then run your tests!
|
|
20
|
+
# CircleCI will report the results back to your VCS provider.
|
|
21
|
+
steps:
|
|
22
|
+
# Checkout the code as the first step.
|
|
23
|
+
- checkout
|
|
24
|
+
# Next, the node orb's install-packages step will install the dependencies from a package.json.
|
|
25
|
+
# The orb install-packages step will also automatically cache them for faster future runs.
|
|
26
|
+
- node/install-packages:
|
|
27
|
+
# If you are using yarn, change the line below from "npm" to "yarn"
|
|
28
|
+
pkg-manager: yarn
|
|
29
|
+
- run:
|
|
30
|
+
name: Expressive Tea Tests
|
|
31
|
+
command: npm test
|
|
32
|
+
environment:
|
|
33
|
+
JEST_JUNIT_OUTPUT_DIR: "./coverage"
|
|
34
|
+
JUNIT_REPORT_NAME: "junit.xml"
|
|
35
|
+
- store_test_results:
|
|
36
|
+
path: ./coverage
|
|
37
|
+
- store_artifacts:
|
|
38
|
+
path: ./coverage
|
|
39
|
+
|
|
40
|
+
workflows:
|
|
41
|
+
# Below is the definition of your workflow.
|
|
42
|
+
# Inside the workflow, you provide the jobs you want to run, e.g this workflow runs the build-and-test job above.
|
|
43
|
+
# CircleCI will run this workflow on every commit.
|
|
44
|
+
# For more details on extending your workflow, see the configuration docs: https://circleci.com/docs/2.0/configuration-reference/#workflows
|
|
45
|
+
Testing:
|
|
46
|
+
jobs:
|
|
47
|
+
- build-and-test
|
|
48
|
+
# For running simple node tests, you could optionally use the node/test job from the orb to replicate and replace the job above in fewer lines.
|
|
49
|
+
# - node/test
|
package/README.md
CHANGED
|
@@ -1,18 +1,78 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<!-- Npm Version -->
|
|
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">
|
|
20
|
+
</a>
|
|
21
|
+
|
|
22
|
+
<!-- Downloads -->
|
|
23
|
+
<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">
|
|
25
|
+
</a>
|
|
26
|
+
|
|
27
|
+
<!-- Dependencies -->
|
|
28
|
+
<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">
|
|
30
|
+
</a>
|
|
31
|
+
|
|
32
|
+
<!-- Vulnerabilities -->
|
|
33
|
+
<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">
|
|
35
|
+
</a>
|
|
36
|
+
|
|
37
|
+
<!-- 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
|
+
|
|
42
|
+
<!-- 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">
|
|
45
|
+
</a>
|
|
46
|
+
|
|
47
|
+
<!-- Source Rank
|
|
48
|
+
<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
|
+
|
|
52
|
+
<!-- Rating
|
|
53
|
+
<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
|
+
|
|
57
|
+
<!-- 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">
|
|
65
|
+
</a>
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
</p>
|
|
69
|
+
|
|
10
70
|
|
|
11
71
|
<!-- PROJECT LOGO -->
|
|
12
72
|
<br />
|
|
13
73
|
<p align="center">
|
|
14
74
|
<a href="https://github.com/Zero-OneiT/expresive-tea">
|
|
15
|
-
<img src="images/logo.png" alt="Logo" width="
|
|
75
|
+
<img src="images/logo.png" alt="Logo" width="160" />
|
|
16
76
|
</a>
|
|
17
77
|
|
|
18
78
|
<h3 align="center">Expressive Tea</h3>
|
|
@@ -50,31 +110,28 @@
|
|
|
50
110
|
* [Principal Sponsors](#principal-sponsors)
|
|
51
111
|
* [Stay on touch](#stay-on-touch)
|
|
52
112
|
* [License](#license)
|
|
53
|
-
* [
|
|
113
|
+
* [Disclaimers](#disclaimers)
|
|
54
114
|
|
|
55
115
|
|
|
56
116
|
## About the project
|
|
57
|
-
Expressive Tea is framework to help build server-side applications in [NodeJS](https://nodejs.org/) and use modern Javascript powered by
|
|
58
|
-
[Typescript](https://www.typescriptlang.org/). As Expressive Tea is using [express](https://expressjs.com/) is compatible with all the middlewares and modules and
|
|
59
|
-
|
|
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.
|
|
60
120
|
|
|
61
|
-
Expressive Tea is a flexible framework
|
|
62
|
-
by providing descriptive decorators, a plugin engine, shareable modules and moder Javascript.
|
|
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.
|
|
63
122
|
|
|
64
123
|
### Motivation
|
|
65
|
-
Server-side applications
|
|
66
|
-
|
|
67
|
-
providing a shareable/pluggable projects, you can write a plugin to setting up express middlewares, databases settings,
|
|
68
|
-
or websockets to name some; and you can share them through your next projects or the community.
|
|
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.
|
|
69
126
|
|
|
70
127
|
Main goal is making uncomplicaded creation of server-side applications, modulables, plugables, free and efortless
|
|
71
128
|
architecture.
|
|
72
129
|
|
|
73
130
|
### Features
|
|
74
|
-
* Easy Setting up and start
|
|
131
|
+
* Easy Setting up and start-up of a webserver.
|
|
75
132
|
* Extends and configuration with plugins and well-defined boot stages.
|
|
76
|
-
* Modules are not
|
|
77
|
-
* Declare Server Middlewares configuration as hard or soft
|
|
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.
|
|
78
135
|
* Dependency Injection is available for controllers as providers declared in modules using InversifyJs.
|
|
79
136
|
* Declarative Router on Controllers.
|
|
80
137
|
* Declarative Verbs and Middlewares under module and verb level.
|
|
@@ -94,10 +151,30 @@ architecture.
|
|
|
94
151
|
**Important!** Expressive Tea requires Node >= 6, Express >= 4, TypeScript >= 2.0 and the `experimentalDecorators`,
|
|
95
152
|
`lib` compilation options in your `tsconfig.json` with the next configuration.
|
|
96
153
|
|
|
97
|
-
Expressive Tea is
|
|
98
|
-
|
|
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
|
|
99
177
|
|
|
100
|
-
### Installation
|
|
101
178
|
```bash
|
|
102
179
|
npm i --save @zerooneit/expressive-tea
|
|
103
180
|
```
|
|
@@ -121,13 +198,18 @@ npm i --save @zerooneit/expressive-tea
|
|
|
121
198
|
}
|
|
122
199
|
```
|
|
123
200
|
### Examples
|
|
124
|
-
You can
|
|
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.
|
|
125
202
|
|
|
126
|
-
|
|
203
|
+
<p align="center">
|
|
204
|
+
<br/>
|
|
205
|
+
<a href="https://codesandbox.io/s/expressive-tea-2kmg7?fontsize=14&hidenavigation=1&module=%2Fmain.ts&theme=dark">
|
|
206
|
+
<img src="https://codesandbox.io/static/img/play-codesandbox.svg">
|
|
207
|
+
</a>
|
|
208
|
+
</p>
|
|
127
209
|
|
|
128
210
|
## Contributing
|
|
129
211
|
|
|
130
|
-
Please read [CONTRIBUTING.md](https://gist.github.com/PurpleBooth/b24679402957c63ec426) for details on our code of conduct
|
|
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.
|
|
131
213
|
|
|
132
214
|
## Versioning
|
|
133
215
|
|
|
@@ -140,12 +222,13 @@ We use [SemVer](http://semver.org/) for versioning. For the versions available,
|
|
|
140
222
|
See also the list of [contributors](https://github.com/Zero-OneiT/expresive-tea/contributors) who participated in this project.
|
|
141
223
|
|
|
142
224
|
## Support
|
|
143
|
-
If you are
|
|
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.
|
|
144
226
|
|
|
145
|
-
If you want to share your thoughts with the development team or join us you will
|
|
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
|
|
146
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/).
|
|
147
229
|
|
|
148
|
-
Expressive Tea is an open
|
|
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).
|
|
231
|
+
|
|
149
232
|
#### Principal Sponsors
|
|
150
233
|
|
|
151
234
|
<table style="text-align:center;"><tr><td>
|
|
@@ -157,12 +240,16 @@ Expressive Tea is an open source project, our goal is create an awesome framewor
|
|
|
157
240
|
|
|
158
241
|
* Author - [Diego Resendez](https://twitter.com/diegoresendez)
|
|
159
242
|
* Twitter - [@expressive_tea](https://twitter.com/expressive_tea)
|
|
160
|
-
* Email - [
|
|
243
|
+
* Email - [support@expressive-tea.io](support@expressive-tea.io)
|
|
161
244
|
|
|
162
245
|
## License
|
|
163
|
-
This project is licensed under the Apache-2.0 License - see the [LICENSE](LICENSE) file for details
|
|
246
|
+
This project is licensed under the Apache-2.0 License - see the [LICENSE](LICENSE) file for details.
|
|
164
247
|
|
|
165
|
-
|
|
248
|
+
<p align="center">
|
|
249
|
+
<a href="https://app.fossa.io/projects/git%2Bgithub.com%2FZero-OneiT%2Fexpresive-tea?ref=badge_large">
|
|
250
|
+
<img src="https://app.fossa.io/api/projects/git%2Bgithub.com%2FZero-OneiT%2Fexpresive-tea.svg?type=large" />
|
|
251
|
+
</a>
|
|
252
|
+
</p>
|
|
166
253
|
|
|
167
254
|
## Disclaimers
|
|
168
255
|
The banner and the logo is a derivate work [Designed by Freepik](http://www.freepik.com)
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
All our code is constantly reviewed by Snyk to provide a better response for vulnerabilities and tacking actions by Dependabot mostly of cases or by a team member.
|
|
6
|
+
|
|
7
|
+
| Version | Supported |
|
|
8
|
+
| ------- | ------------------ |
|
|
9
|
+
| >= 1.0 |:white_check_mark:|
|
|
10
|
+
|
|
11
|
+
## Reporting a Vulnerability
|
|
12
|
+
|
|
13
|
+
However, if you know about a vulnerability in our code or we fail on security compliance please report it at:
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<br />
|
|
17
|
+
<a href="mailto:security@expressive-tea.io">Security</a>
|
|
18
|
+
·
|
|
19
|
+
<a href="mailto:compliance@expressive-tea.io">Compliance</a>
|
|
20
|
+
</p>
|
package/classes/Boot.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Express } from 'express';
|
|
1
2
|
import Settings from '../classes/Settings';
|
|
2
3
|
import { ExpressiveTeaApplication } from '../libs/interfaces';
|
|
3
4
|
/**
|
|
@@ -44,4 +45,5 @@ declare abstract class Boot {
|
|
|
44
45
|
*/
|
|
45
46
|
start(): Promise<ExpressiveTeaApplication>;
|
|
46
47
|
}
|
|
48
|
+
export declare function resolveProxy(ProxyContainer: any, server: Express): Promise<void>;
|
|
47
49
|
export default Boot;
|
package/classes/Boot.js
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveProxy = void 0;
|
|
3
4
|
const $P = require("bluebird");
|
|
5
|
+
// tslint:disable-next-line:no-duplicate-imports
|
|
6
|
+
const express = require("express");
|
|
4
7
|
const fs = require("fs");
|
|
5
8
|
const http = require("http");
|
|
6
9
|
const https = require("https");
|
|
7
|
-
// tslint:disable-next-line:no-duplicate-imports
|
|
8
|
-
const express = require("express");
|
|
9
10
|
const MetaData_1 = require("../classes/MetaData");
|
|
10
11
|
const Settings_1 = require("../classes/Settings");
|
|
11
12
|
const BootLoaderExceptions_1 = require("../exceptions/BootLoaderExceptions");
|
|
12
13
|
const object_helper_1 = require("../helpers/object-helper");
|
|
13
14
|
const constants_1 = require("../libs/constants");
|
|
15
|
+
const WebSocket = require("ws");
|
|
16
|
+
const WebsocketService_1 = require("../services/WebsocketService");
|
|
14
17
|
/**
|
|
15
18
|
* Expressive Tea Application interface is the response from an started application, contains the express application
|
|
16
19
|
* and a node http server instance.
|
|
@@ -60,31 +63,50 @@ class Boot {
|
|
|
60
63
|
try {
|
|
61
64
|
const privateKey = this.settings.get('privateKey');
|
|
62
65
|
const certificate = this.settings.get('certificate');
|
|
66
|
+
const startWebsocket = this.settings.get('startWebsocket');
|
|
67
|
+
const detachWebsocket = this.settings.get('detachWebsocket');
|
|
63
68
|
const serverConfigQueue = [];
|
|
69
|
+
// tslint:disable-next-line:one-variable-per-declaration
|
|
70
|
+
let ws, wss;
|
|
71
|
+
const server = http.createServer(this.server);
|
|
72
|
+
const secureServer = privateKey && certificate && https.createServer({
|
|
73
|
+
cert: fs.readFileSync(certificate).toString('utf-8'),
|
|
74
|
+
key: fs.readFileSync(privateKey).toString('utf-8')
|
|
75
|
+
}, 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);
|
|
64
86
|
await resolveDirectives(this, this.server);
|
|
65
87
|
await resolveStatic(this, this.server);
|
|
66
88
|
for (const stage of constants_1.BOOT_ORDER) {
|
|
67
89
|
await resolveStage(stage, this, this.server);
|
|
68
90
|
}
|
|
69
|
-
|
|
70
|
-
let secureServer;
|
|
91
|
+
await resolveStage(constants_1.BOOT_STAGES.APPLICATION, this, this.server);
|
|
71
92
|
serverConfigQueue.push(new $P(resolve => server.listen(this.settings.get('port'), () => {
|
|
72
93
|
console.log(`Running HTTP Server on [${this.settings.get('port')}]`);
|
|
73
94
|
resolve();
|
|
74
95
|
})));
|
|
75
|
-
if (
|
|
76
|
-
// fs.existsSync(privateKey)
|
|
77
|
-
// fs.existsSync(certificate)
|
|
78
|
-
secureServer = https.createServer({
|
|
79
|
-
cert: fs.readFileSync(certificate).toString('utf-8'),
|
|
80
|
-
key: fs.readFileSync(privateKey).toString('utf-8')
|
|
81
|
-
}, this.server);
|
|
96
|
+
if (secureServer) {
|
|
82
97
|
serverConfigQueue.push(new $P(resolve => secureServer.listen(this.settings.get('securePort'), () => {
|
|
83
98
|
console.log(`Running Secure HTTP Server on [${this.settings.get('securePort')}]`);
|
|
84
99
|
resolve();
|
|
85
100
|
})));
|
|
86
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
|
+
]);
|
|
87
106
|
$P.all(serverConfigQueue)
|
|
107
|
+
.then(() => {
|
|
108
|
+
return resolveStage(constants_1.BOOT_STAGES.START, this, this.server, server, secureServer);
|
|
109
|
+
})
|
|
88
110
|
.then(() => resolver({ application: this.server, server, secureServer }));
|
|
89
111
|
}
|
|
90
112
|
catch (e) {
|
|
@@ -93,9 +115,9 @@ class Boot {
|
|
|
93
115
|
});
|
|
94
116
|
}
|
|
95
117
|
}
|
|
96
|
-
async function resolveStage(stage, ctx, server) {
|
|
118
|
+
async function resolveStage(stage, ctx, server, ...extraArgs) {
|
|
97
119
|
try {
|
|
98
|
-
await bootloaderResolve(stage, server, ctx);
|
|
120
|
+
await bootloaderResolve(stage, server, ctx, ...extraArgs);
|
|
99
121
|
if (stage === constants_1.BOOT_STAGES.APPLICATION) {
|
|
100
122
|
await resolveModules(ctx, server);
|
|
101
123
|
}
|
|
@@ -105,13 +127,13 @@ async function resolveStage(stage, ctx, server) {
|
|
|
105
127
|
}
|
|
106
128
|
}
|
|
107
129
|
async function resolveDirectives(instance, server) {
|
|
108
|
-
const registeredDirectives = MetaData_1.default.get(constants_1.REGISTERED_DIRECTIVES_KEY, object_helper_1.getClass(instance)) || [];
|
|
130
|
+
const registeredDirectives = MetaData_1.default.get(constants_1.REGISTERED_DIRECTIVES_KEY, (0, object_helper_1.getClass)(instance)) || [];
|
|
109
131
|
registeredDirectives.forEach((options) => {
|
|
110
132
|
server.set.call(server, options.name, ...options.settings);
|
|
111
133
|
});
|
|
112
134
|
}
|
|
113
135
|
async function resolveStatic(instance, server) {
|
|
114
|
-
const registeredStatic = MetaData_1.default.get(constants_1.REGISTERED_STATIC_KEY, object_helper_1.getClass(instance)) || [];
|
|
136
|
+
const registeredStatic = MetaData_1.default.get(constants_1.REGISTERED_STATIC_KEY, (0, object_helper_1.getClass)(instance)) || [];
|
|
115
137
|
registeredStatic.forEach((staticOptions) => {
|
|
116
138
|
if (staticOptions.virtual) {
|
|
117
139
|
server.use(staticOptions.virtual, express.static(staticOptions.root, staticOptions.options));
|
|
@@ -128,19 +150,30 @@ async function resolveModules(instance, server) {
|
|
|
128
150
|
moduleInstance.__register(server);
|
|
129
151
|
});
|
|
130
152
|
}
|
|
131
|
-
async function bootloaderResolve(STAGE, server, instance) {
|
|
132
|
-
const bootLoader = MetaData_1.default.get(constants_1.BOOT_STAGES_KEY, instance) || constants_1.STAGES_INIT;
|
|
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;
|
|
133
155
|
for (const loader of bootLoader[STAGE] || []) {
|
|
134
156
|
try {
|
|
135
|
-
await selectLoaderType(loader, server);
|
|
157
|
+
await selectLoaderType(loader, server, ...args);
|
|
136
158
|
}
|
|
137
159
|
catch (e) {
|
|
138
160
|
shouldFailIfRequire(e, loader);
|
|
139
161
|
}
|
|
140
162
|
}
|
|
141
163
|
}
|
|
142
|
-
async function
|
|
143
|
-
|
|
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);
|
|
144
177
|
}
|
|
145
178
|
function checkIfStageFails(e) {
|
|
146
179
|
if (e instanceof BootLoaderExceptions_1.BootLoaderSoftExceptions) {
|
package/classes/MetaData.js
CHANGED
|
@@ -5,15 +5,15 @@ require("reflect-metadata");
|
|
|
5
5
|
const object_helper_1 = require("../helpers/object-helper");
|
|
6
6
|
function get(key, target, propertyKey, own = false) {
|
|
7
7
|
return own ?
|
|
8
|
-
Reflect.getOwnMetadata(key, object_helper_1.getClass(target), propertyKey) :
|
|
9
|
-
Reflect.getMetadata(key, object_helper_1.getClass(target), propertyKey);
|
|
8
|
+
Reflect.getOwnMetadata(key, (0, object_helper_1.getClass)(target), propertyKey) :
|
|
9
|
+
Reflect.getMetadata(key, (0, object_helper_1.getClass)(target), propertyKey);
|
|
10
10
|
}
|
|
11
11
|
class Metadata {
|
|
12
12
|
static get(key, target, propertyKey) {
|
|
13
|
-
return get(key, object_helper_1.getClass(target), propertyKey);
|
|
13
|
+
return get(key, (0, object_helper_1.getClass)(target), propertyKey);
|
|
14
14
|
}
|
|
15
15
|
static getOwn(key, target, propertyKey) {
|
|
16
|
-
return get(key, object_helper_1.getClass(target), propertyKey, true);
|
|
16
|
+
return get(key, (0, object_helper_1.getClass)(target), propertyKey, true);
|
|
17
17
|
}
|
|
18
18
|
static getType(target, propertyKey) {
|
|
19
19
|
return Reflect.getMetadata(DESIGN_TYPE, target, propertyKey);
|
|
@@ -29,29 +29,29 @@ class Metadata {
|
|
|
29
29
|
}
|
|
30
30
|
static has(key, target, propertyKey) {
|
|
31
31
|
try {
|
|
32
|
-
return Reflect.hasMetadata(key, object_helper_1.getClass(target), propertyKey);
|
|
32
|
+
return Reflect.hasMetadata(key, (0, object_helper_1.getClass)(target), propertyKey);
|
|
33
33
|
}
|
|
34
34
|
catch (er) {
|
|
35
35
|
}
|
|
36
36
|
return false;
|
|
37
37
|
}
|
|
38
38
|
static hasOwn(key, target, propertyKey) {
|
|
39
|
-
return Reflect.hasOwnMetadata(key, object_helper_1.getClass(target), propertyKey);
|
|
39
|
+
return Reflect.hasOwnMetadata(key, (0, object_helper_1.getClass)(target), propertyKey);
|
|
40
40
|
}
|
|
41
41
|
static setParamTypes(target, propertyKey, value) {
|
|
42
42
|
return this.set(DESIGN_PARAM_TYPES, value, target.prototype, propertyKey);
|
|
43
43
|
}
|
|
44
44
|
static delete(key, target, propertyKey) {
|
|
45
|
-
return Reflect.deleteMetadata(key, object_helper_1.getClass(target), propertyKey);
|
|
45
|
+
return Reflect.deleteMetadata(key, (0, object_helper_1.getClass)(target), propertyKey);
|
|
46
46
|
}
|
|
47
47
|
static set(key, value, target, propertyKey) {
|
|
48
48
|
const targets = PROPERTIES.has(key) ? PROPERTIES.get(key) || [] : [];
|
|
49
|
-
const classConstructor = object_helper_1.getClass(target);
|
|
49
|
+
const classConstructor = (0, object_helper_1.getClass)(target);
|
|
50
50
|
if (targets.indexOf(classConstructor) === -1) {
|
|
51
51
|
targets.push(classConstructor);
|
|
52
52
|
PROPERTIES.set(key, targets);
|
|
53
53
|
}
|
|
54
|
-
Reflect.defineMetadata(key, value, object_helper_1.getClass(target), propertyKey);
|
|
54
|
+
Reflect.defineMetadata(key, value, (0, object_helper_1.getClass)(target), propertyKey);
|
|
55
55
|
}
|
|
56
56
|
static getParamTypes(targetPrototype, propertyKey) {
|
|
57
57
|
return get(DESIGN_PARAM_TYPES, targetPrototype, propertyKey) || [];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.param = exports.body = exports.query = exports.next = exports.response = exports.request = void 0;
|
|
3
4
|
const MetaData_1 = require("../classes/MetaData");
|
|
4
5
|
const constants_1 = require("../libs/constants");
|
|
5
6
|
/**
|
package/decorators/module.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Module = void 0;
|
|
3
4
|
const express_1 = require("express");
|
|
4
5
|
const lodash_1 = require("lodash");
|
|
5
6
|
const DependencyInjection_1 = require("../services/DependencyInjection");
|
|
@@ -32,13 +33,13 @@ function Module(options) {
|
|
|
32
33
|
return class extends Module {
|
|
33
34
|
constructor(...args) {
|
|
34
35
|
super(...args);
|
|
35
|
-
this.router = express_1.Router();
|
|
36
|
+
this.router = (0, express_1.Router)();
|
|
36
37
|
this.settings = options;
|
|
37
|
-
lodash_1.each(this.settings.providers, P => DependencyInjection_1.default.setProvider(P));
|
|
38
|
-
this.controllers = lodash_1.map(this.settings.controllers, C => new C());
|
|
38
|
+
(0, lodash_1.each)(this.settings.providers, P => DependencyInjection_1.default.setProvider(P));
|
|
39
|
+
this.controllers = (0, lodash_1.map)(this.settings.controllers, C => new C());
|
|
39
40
|
}
|
|
40
41
|
__register(server) {
|
|
41
|
-
lodash_1.each(this.controllers, c => c.__mount(this.router));
|
|
42
|
+
(0, lodash_1.each)(this.controllers, c => c.__mount(this.router));
|
|
42
43
|
server.use(this.settings.mountpoint, this.router);
|
|
43
44
|
}
|
|
44
45
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ExpressiveTeaProxyOptions, ExpressiveTeaProxyProperty, MethodDecorator } from '../libs/types';
|
|
2
|
+
import { Express, RequestHandler } from 'express';
|
|
3
|
+
export declare function ProxyContainer(source: string, targetUrl: string): <T extends new (...args: any[]) => any>(ProxyContainerClass: T) => {
|
|
4
|
+
new (...args: any[]): {
|
|
5
|
+
[x: string]: any;
|
|
6
|
+
readonly source: string;
|
|
7
|
+
readonly target: string;
|
|
8
|
+
readonly proxyHandler: RequestHandler;
|
|
9
|
+
__register(server: Express): void;
|
|
10
|
+
};
|
|
11
|
+
} & T;
|
|
12
|
+
export declare function ProxyOption(option: ExpressiveTeaProxyOptions): MethodDecorator;
|
|
13
|
+
export declare function ProxyProperty(option: ExpressiveTeaProxyProperty, value: any): PropertyDecorator;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProxyProperty = exports.ProxyOption = exports.ProxyContainer = void 0;
|
|
4
|
+
const MetaData_1 = require("../classes/MetaData");
|
|
5
|
+
const httpProxy = require("express-http-proxy");
|
|
6
|
+
const object_helper_1 = require("../helpers/object-helper");
|
|
7
|
+
const lodash_1 = require("lodash");
|
|
8
|
+
const RequestExceptions_1 = require("../exceptions/RequestExceptions");
|
|
9
|
+
const constants_1 = require("../libs/constants");
|
|
10
|
+
const NON_ASYNC_METHODS = ['host'];
|
|
11
|
+
function ProxyContainer(source, targetUrl) {
|
|
12
|
+
return (ProxyContainerClass) => {
|
|
13
|
+
class ExpressiveTeaProxy extends ProxyContainerClass {
|
|
14
|
+
constructor(...args) {
|
|
15
|
+
super(...args);
|
|
16
|
+
this.source = source;
|
|
17
|
+
this.target = targetUrl;
|
|
18
|
+
const options = {};
|
|
19
|
+
const host = MetaData_1.default.get(constants_1.PROXY_SETTING_KEY, this, constants_1.PROXY_METHODS.HOST);
|
|
20
|
+
for (const value of Object.values(constants_1.PROXY_METHODS)) {
|
|
21
|
+
if (value !== constants_1.PROXY_METHODS.HOST) {
|
|
22
|
+
options[value] = MetaData_1.default.get(constants_1.PROXY_SETTING_KEY, this, value);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
for (const value of Object.values(constants_1.PROXY_PROPERTIES)) {
|
|
26
|
+
const key = MetaData_1.default.get(constants_1.PROXY_SETTING_KEY, this, value);
|
|
27
|
+
if (!(0, lodash_1.isUndefined)(key)) {
|
|
28
|
+
// @ts-ignore:next-line
|
|
29
|
+
options[value] = this[key];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
this.proxyHandler = httpProxy(host ? host.value.bind(this) : this.target);
|
|
33
|
+
}
|
|
34
|
+
__register(server) {
|
|
35
|
+
const proxyMetadata = MetaData_1.default.get(constants_1.PROXY_SETTING_KEY, (0, object_helper_1.getClass)(this));
|
|
36
|
+
console.info(`[PROXY - ${proxyMetadata.name}] ${this.source} -> ${this.target}`);
|
|
37
|
+
server.use(this.source, this.proxyHandler);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
;
|
|
41
|
+
const settings = {
|
|
42
|
+
source,
|
|
43
|
+
targetUrl,
|
|
44
|
+
name: ProxyContainerClass.name
|
|
45
|
+
};
|
|
46
|
+
MetaData_1.default.set(constants_1.PROXY_SETTING_KEY, settings, ProxyContainerClass);
|
|
47
|
+
return ExpressiveTeaProxy;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
exports.ProxyContainer = ProxyContainer;
|
|
51
|
+
function ProxyOption(option) {
|
|
52
|
+
return (target, propertyKey, descriptor) => {
|
|
53
|
+
if (NON_ASYNC_METHODS.includes(option) && (0, object_helper_1.isAsyncFunction)(descriptor.value)) {
|
|
54
|
+
throw new RequestExceptions_1.GenericRequestException(`${String(propertyKey)} must not be declared as Async Function.`);
|
|
55
|
+
}
|
|
56
|
+
MetaData_1.default.set(constants_1.PROXY_SETTING_KEY, descriptor, target, option);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
exports.ProxyOption = ProxyOption;
|
|
60
|
+
function ProxyProperty(option, value) {
|
|
61
|
+
return (target, propertyKey) => {
|
|
62
|
+
MetaData_1.default.set(constants_1.PROXY_SETTING_KEY, propertyKey, target, option);
|
|
63
|
+
let currentValue = target[propertyKey];
|
|
64
|
+
Object.defineProperty(target, propertyKey, {
|
|
65
|
+
get: () => value,
|
|
66
|
+
set: () => { currentValue = value; }
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
exports.ProxyProperty = ProxyProperty;
|