nodester 0.0.1
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/LICENSE +21 -0
- package/Readme.md +125 -0
- package/docs/App.md +13 -0
- package/docs/Queries.md +61 -0
- package/docs/Readme.md +2 -0
- package/docs/Routing.md +34 -0
- package/examples/goal/index.js +23 -0
- package/examples/rest/index.js +25 -0
- package/examples/rest/node_modules/.package-lock.json +40 -0
- package/examples/rest/package-lock.json +72 -0
- package/examples/rest/package.json +14 -0
- package/lib/application/MiddlewareStack.js +125 -0
- package/lib/application/http/request.js +462 -0
- package/lib/application/http/response.js +1107 -0
- package/lib/application/http/utils.js +254 -0
- package/lib/application/index.js +292 -0
- package/lib/constants/ConstantsEnum.js +13 -0
- package/lib/constants/ResponseFormats.js +7 -0
- package/lib/controllers/Controller.js +474 -0
- package/lib/controllers/JWTController.js +240 -0
- package/lib/controllers/ServiceController.js +109 -0
- package/lib/controllers/WebController.js +75 -0
- package/lib/facades/Facade.js +388 -0
- package/lib/facades/FacadeParams.js +11 -0
- package/lib/facades/ServiceFacade.js +17 -0
- package/lib/facades/jwt.facade.js +273 -0
- package/lib/factories/errors/CustomError.js +22 -0
- package/lib/factories/errors/index.js +9 -0
- package/lib/factories/responses/api.js +90 -0
- package/lib/factories/responses/html.js +55 -0
- package/lib/logger/console.js +24 -0
- package/lib/models/DisabledRefreshToken.js +68 -0
- package/lib/models/Extractor.js +320 -0
- package/lib/models/define.js +62 -0
- package/lib/models/mixins.js +369 -0
- package/lib/policies/Role.js +77 -0
- package/lib/policies/RoleExtracting.js +97 -0
- package/lib/preprocessors/BodyPreprocessor.js +61 -0
- package/lib/preprocessors/IncludesPreprocessor.js +55 -0
- package/lib/preprocessors/QueryPreprocessor.js +64 -0
- package/lib/routers/Default/index.js +143 -0
- package/lib/routers/Default/layer.js +50 -0
- package/lib/routers/Main/index.js +10 -0
- package/lib/routers/Roles/index.js +81 -0
- package/lib/services/includes.service.js +79 -0
- package/lib/services/jwt.service.js +147 -0
- package/lib/tools/sql.tool.js +82 -0
- package/lib/utils/dates.util.js +23 -0
- package/lib/utils/forms.util.js +22 -0
- package/lib/utils/json.util.js +49 -0
- package/lib/utils/mappers/Routes/index.js +100 -0
- package/lib/utils/mappers/Routes/utils.js +20 -0
- package/lib/utils/modelAssociations.util.js +44 -0
- package/lib/utils/objects.util.js +69 -0
- package/lib/utils/params.util.js +19 -0
- package/lib/utils/path.util.js +26 -0
- package/lib/utils/queries.util.js +240 -0
- package/lib/utils/sanitizations.util.js +111 -0
- package/lib/utils/sql.util.js +78 -0
- package/lib/utils/strings.util.js +43 -0
- package/lib/utils/types.util.js +26 -0
- package/package.json +63 -0
- package/tests/index.test.js +35 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* /nodester
|
|
3
|
+
* MIT Licensed
|
|
4
|
+
*/
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const contentType = require('content-type');
|
|
8
|
+
const mime = require('send').mime;
|
|
9
|
+
const etag = require('etag');
|
|
10
|
+
const proxyaddr = require('proxy-addr');
|
|
11
|
+
const qs = require('qs');
|
|
12
|
+
const querystring = require('querystring');
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
exports = module.exports = {
|
|
16
|
+
acceptParams: _acceptParams,
|
|
17
|
+
normalizeType: _normalizeType,
|
|
18
|
+
normalizeTypes: _normalizeTypes,
|
|
19
|
+
compileETag: _compileETag,
|
|
20
|
+
setCharset: _setCharset
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Parse accept params `str` returning an
|
|
26
|
+
* object with `.value`, `.quality` and `.params`.
|
|
27
|
+
* also includes `.originalIndex` for stable sorting
|
|
28
|
+
*
|
|
29
|
+
* @param {String} str
|
|
30
|
+
* @param {Number} index
|
|
31
|
+
* @return {Object}
|
|
32
|
+
*
|
|
33
|
+
* @api private
|
|
34
|
+
*/
|
|
35
|
+
function _acceptParams(str, index) {
|
|
36
|
+
const parts = str.split(/ *; */);
|
|
37
|
+
let result = { value: parts[0], quality: 1, params: {}, originalIndex: index };
|
|
38
|
+
|
|
39
|
+
for (let i = 1; i < parts.length; i++) {
|
|
40
|
+
const pms = parts[i].split(/ *= */);
|
|
41
|
+
if ('q' === pms[0]) {
|
|
42
|
+
result.quality = parseFloat(pms[1]);
|
|
43
|
+
} else {
|
|
44
|
+
result.params[pms[0]] = pms[1];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Create an ETag generator function, generating ETags with
|
|
54
|
+
* the given options.
|
|
55
|
+
*
|
|
56
|
+
* @param {object} options
|
|
57
|
+
* @return {function}
|
|
58
|
+
*
|
|
59
|
+
* @private
|
|
60
|
+
*/
|
|
61
|
+
function _createETagGenerator (options) {
|
|
62
|
+
return function generateETag (body, encoding) {
|
|
63
|
+
const buf = !Buffer.isBuffer(body)
|
|
64
|
+
? Buffer.from(body, encoding)
|
|
65
|
+
: body
|
|
66
|
+
|
|
67
|
+
return etag(buf, options)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Normalize the given `type`, for example "html" becomes "text/html".
|
|
74
|
+
*
|
|
75
|
+
* @param {String} type
|
|
76
|
+
* @return {Object}
|
|
77
|
+
*
|
|
78
|
+
* @api private
|
|
79
|
+
*/
|
|
80
|
+
function _normalizeType(type){
|
|
81
|
+
return ~type.indexOf('/')
|
|
82
|
+
? acceptParams(type)
|
|
83
|
+
: { value: mime.lookup(type), params: {} };
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Normalize `types`, for example "html" becomes "text/html".
|
|
89
|
+
*
|
|
90
|
+
* @param {Array} types
|
|
91
|
+
* @return {Array}
|
|
92
|
+
*
|
|
93
|
+
* @api private
|
|
94
|
+
*/
|
|
95
|
+
function _normalizeTypes(types){
|
|
96
|
+
const ret = [];
|
|
97
|
+
|
|
98
|
+
for (let i = 0; i < types.length; ++i) {
|
|
99
|
+
ret.push(
|
|
100
|
+
_normalizeType(types[i])
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return ret;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Compile "etag" value to function.
|
|
110
|
+
*
|
|
111
|
+
* @param {Boolean|String|Function} val
|
|
112
|
+
* @return {Function}
|
|
113
|
+
*
|
|
114
|
+
* @alias compileETag
|
|
115
|
+
* @api public
|
|
116
|
+
*/
|
|
117
|
+
function _compileETag(val) {
|
|
118
|
+
let fn;
|
|
119
|
+
|
|
120
|
+
if (typeof val === 'function') {
|
|
121
|
+
return val;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
switch (val) {
|
|
125
|
+
case true:
|
|
126
|
+
case 'weak':
|
|
127
|
+
fn = _createETagGenerator({ weak: true });
|
|
128
|
+
break;
|
|
129
|
+
case false:
|
|
130
|
+
break;
|
|
131
|
+
case 'strong':
|
|
132
|
+
fn = _createETagGenerator({ weak: false });
|
|
133
|
+
break;
|
|
134
|
+
default:
|
|
135
|
+
throw new TypeError('unknown value for etag function: ' + val);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return fn;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Compile "query parser" value to function.
|
|
143
|
+
*
|
|
144
|
+
* @param {String|Function} val
|
|
145
|
+
* @return {Function}
|
|
146
|
+
*
|
|
147
|
+
* @api private
|
|
148
|
+
*/
|
|
149
|
+
|
|
150
|
+
exports.compileQueryParser = function compileQueryParser(val) {
|
|
151
|
+
let fn;
|
|
152
|
+
|
|
153
|
+
if (typeof val === 'function') {
|
|
154
|
+
return val;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
switch (val) {
|
|
158
|
+
case true:
|
|
159
|
+
case 'simple':
|
|
160
|
+
fn = querystring.parse;
|
|
161
|
+
break;
|
|
162
|
+
case false:
|
|
163
|
+
fn = newObject;
|
|
164
|
+
break;
|
|
165
|
+
case 'extended':
|
|
166
|
+
fn = parseExtendedQueryString;
|
|
167
|
+
break;
|
|
168
|
+
default:
|
|
169
|
+
throw new TypeError('unknown value for query parser function: ' + val);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return fn;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Compile "proxy trust" value to function.
|
|
177
|
+
*
|
|
178
|
+
* @param {Boolean|String|Number|Array|Function} val
|
|
179
|
+
* @return {Function}
|
|
180
|
+
*
|
|
181
|
+
* @api private
|
|
182
|
+
*/
|
|
183
|
+
exports.compileTrust = function(val) {
|
|
184
|
+
if (typeof val === 'function') return val;
|
|
185
|
+
|
|
186
|
+
if (val === true) {
|
|
187
|
+
// Support plain true/false
|
|
188
|
+
return function(){ return true };
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (typeof val === 'number') {
|
|
192
|
+
// Support trusting hop count
|
|
193
|
+
return function(a, i){ return i < val };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (typeof val === 'string') {
|
|
197
|
+
// Support comma-separated values
|
|
198
|
+
val = val.split(',')
|
|
199
|
+
.map(function (v) { return v.trim() })
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return proxyaddr.compile(val || []);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Set the charset in a given Content-Type string.
|
|
208
|
+
*
|
|
209
|
+
* @param {String} type
|
|
210
|
+
* @param {String} charset
|
|
211
|
+
* @return {String}
|
|
212
|
+
*
|
|
213
|
+
* @api private
|
|
214
|
+
*/
|
|
215
|
+
function _setCharset(type, charset) {
|
|
216
|
+
if (!type || !charset) {
|
|
217
|
+
return type;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// parse type
|
|
221
|
+
const parsed = contentType.parse(type);
|
|
222
|
+
|
|
223
|
+
// set charset
|
|
224
|
+
parsed.parameters.charset = charset;
|
|
225
|
+
|
|
226
|
+
// format type
|
|
227
|
+
return contentType.format(parsed);
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Parse an extended query string with qs.
|
|
233
|
+
*
|
|
234
|
+
* @return {Object}
|
|
235
|
+
* @private
|
|
236
|
+
*/
|
|
237
|
+
function parseExtendedQueryString(str) {
|
|
238
|
+
return qs.parse(str, {
|
|
239
|
+
allowPrototypes: true
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Return new empty object.
|
|
246
|
+
*
|
|
247
|
+
* @return {Object}
|
|
248
|
+
*
|
|
249
|
+
* @api private
|
|
250
|
+
*/
|
|
251
|
+
function newObject() {
|
|
252
|
+
return {};
|
|
253
|
+
}
|
|
254
|
+
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* /nodester
|
|
3
|
+
* MIT Licensed
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
const Emitter = require('events');
|
|
9
|
+
const MiddlewareStack = require('./MiddlewareStack');
|
|
10
|
+
// Server:
|
|
11
|
+
const http = require('http');
|
|
12
|
+
const request = require('./http/request');
|
|
13
|
+
const response = require('./http/response');
|
|
14
|
+
// Utils:
|
|
15
|
+
const { typeOf } = require('../utils/types.util');
|
|
16
|
+
const { merge } = require('../utils/objects.util');
|
|
17
|
+
const consl = require('../logger/console');
|
|
18
|
+
const debug = require('debug')('nodester:application');
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
module.exports = class Application extends Emitter {
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Initialize a new `Application`.
|
|
25
|
+
*
|
|
26
|
+
* @api public
|
|
27
|
+
*/
|
|
28
|
+
constructor(opts={}) {
|
|
29
|
+
super();
|
|
30
|
+
|
|
31
|
+
// Fallback port.
|
|
32
|
+
this.port = opts?.port ?? 8080;
|
|
33
|
+
|
|
34
|
+
// Reference to middlewares stack.
|
|
35
|
+
this._middlewares = new MiddlewareStack();
|
|
36
|
+
|
|
37
|
+
// Reference to the database connection.
|
|
38
|
+
this.database = null;
|
|
39
|
+
|
|
40
|
+
// Reference to the http(s) server,
|
|
41
|
+
this.server = null;
|
|
42
|
+
|
|
43
|
+
this._hooks = {
|
|
44
|
+
beforeStart: ()=>{}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Indicatorors.
|
|
48
|
+
this.isListening = false;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/*
|
|
52
|
+
* Expose the prototype that will get set on requests.
|
|
53
|
+
*
|
|
54
|
+
* @api public
|
|
55
|
+
*/
|
|
56
|
+
get request() {
|
|
57
|
+
return Object.create(request, {
|
|
58
|
+
app: { configurable: true, enumerable: true, writable: true, value: app }
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
/*
|
|
64
|
+
* Expose the prototype that will get set on responses.
|
|
65
|
+
*
|
|
66
|
+
* @api public
|
|
67
|
+
*/
|
|
68
|
+
get response() {
|
|
69
|
+
return Object.create(response, {
|
|
70
|
+
app: { configurable: true, enumerable: true, writable: true, value: app }
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
/*
|
|
76
|
+
* Sets (or overrides):
|
|
77
|
+
* - (database) main database of the application and tries to make connection
|
|
78
|
+
* - (router) default Router
|
|
79
|
+
*
|
|
80
|
+
* @api public
|
|
81
|
+
*/
|
|
82
|
+
get set() {
|
|
83
|
+
return {
|
|
84
|
+
database: this.setDatabase.bind(this),
|
|
85
|
+
router: this.setRouter.bind(this)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Sets (or overrides) main database of the application and tries to make connection.
|
|
92
|
+
* @param {Sequilize} sequilizeConnection
|
|
93
|
+
* @param {Boolean} crashOnError
|
|
94
|
+
* @return {sequilizeConnection.authenticate}
|
|
95
|
+
*
|
|
96
|
+
* @public
|
|
97
|
+
*/
|
|
98
|
+
setDatabase(sequilizeConnection, crashOnError=true) {
|
|
99
|
+
try {
|
|
100
|
+
if (!sequilizeConnection) {
|
|
101
|
+
const err = new Error('Connection to database (Sequilize) can not be null or undefined.');
|
|
102
|
+
throw err;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const result = sequilizeConnection.authenticate();
|
|
106
|
+
this.database = sequilizeConnection;
|
|
107
|
+
|
|
108
|
+
return result;
|
|
109
|
+
}
|
|
110
|
+
catch(error) {
|
|
111
|
+
if (crashOnError === true) {
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
consl.error(error);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Overrides default Router.
|
|
123
|
+
*
|
|
124
|
+
* @public
|
|
125
|
+
*/
|
|
126
|
+
setRouter(newRouter) {
|
|
127
|
+
this.router = newRouter.init(this);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
/*
|
|
132
|
+
* Adds:
|
|
133
|
+
* - (middleware) new middleware to the stack;
|
|
134
|
+
*
|
|
135
|
+
* @api public
|
|
136
|
+
*/
|
|
137
|
+
get add() {
|
|
138
|
+
return {
|
|
139
|
+
middleware: this.addMiddleware.bind(this)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
/*
|
|
145
|
+
* Adds new middleware to the stack.
|
|
146
|
+
*
|
|
147
|
+
* @api public
|
|
148
|
+
*/
|
|
149
|
+
addMiddleware(fn) {
|
|
150
|
+
if (this._middlewares.isLocked === true) {
|
|
151
|
+
const err = new Error(`Can't add more middlewares after application has been started.`);
|
|
152
|
+
throw err;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
this._middlewares.add(fn);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
/*
|
|
160
|
+
* Proxy to .add().
|
|
161
|
+
*
|
|
162
|
+
* @param {Function} fn
|
|
163
|
+
*
|
|
164
|
+
* @api public
|
|
165
|
+
*/
|
|
166
|
+
use(fn) {
|
|
167
|
+
return this.add(fn);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Adds to hooks stack (beforeStart).
|
|
173
|
+
*
|
|
174
|
+
* @api public
|
|
175
|
+
*/
|
|
176
|
+
beforeStart(fn) {
|
|
177
|
+
if (typeOf(fn) !== 'function') {
|
|
178
|
+
const err = new TypeError('"fn" argument must be a function');
|
|
179
|
+
throw err;
|
|
180
|
+
}
|
|
181
|
+
this._hooks.beforeStart = fn;
|
|
182
|
+
|
|
183
|
+
return this._hooks.beforeStart;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Return a request handler callback
|
|
189
|
+
* for node's native http server.
|
|
190
|
+
*
|
|
191
|
+
* @return {Function}
|
|
192
|
+
*
|
|
193
|
+
* @api public
|
|
194
|
+
*/
|
|
195
|
+
start() {
|
|
196
|
+
try {
|
|
197
|
+
this._hooks.beforeStart.call(this);
|
|
198
|
+
}
|
|
199
|
+
catch(error) {
|
|
200
|
+
console.error('Application did not start due to error.');
|
|
201
|
+
consl.error(error);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Lock middlewares stack.
|
|
206
|
+
this._middlewares.lock();
|
|
207
|
+
|
|
208
|
+
return this.handle.bind(this);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Shorthand for:
|
|
214
|
+
*
|
|
215
|
+
* http.createServer(app.start()).listen(...)
|
|
216
|
+
*
|
|
217
|
+
* @param {Int} port
|
|
218
|
+
* @param {Mixed} ...
|
|
219
|
+
* @return {import('http').Server}
|
|
220
|
+
*
|
|
221
|
+
* @api public
|
|
222
|
+
*/
|
|
223
|
+
listen(port, ...args) {
|
|
224
|
+
// Remember port:
|
|
225
|
+
const _port = port ?? this.port;
|
|
226
|
+
this.port = _port;
|
|
227
|
+
|
|
228
|
+
debug(`listen on port ${ this.port }`);
|
|
229
|
+
|
|
230
|
+
if (!this.server) {
|
|
231
|
+
this.server = http.createServer(this.start());
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
this.isListening = true;
|
|
235
|
+
return this.server.listen(_port, ...args);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Handles server request.
|
|
241
|
+
*
|
|
242
|
+
* @api public
|
|
243
|
+
*/
|
|
244
|
+
handle(req, res) {
|
|
245
|
+
// Req & res with mixins:
|
|
246
|
+
merge(req, this.request);
|
|
247
|
+
merge(res, this.response);
|
|
248
|
+
|
|
249
|
+
// Exchange references:
|
|
250
|
+
req.res = res;
|
|
251
|
+
res.req = req;
|
|
252
|
+
|
|
253
|
+
return this._middlewares.process(req, res)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Extends Application & makes sure, that "key" param is not present already.
|
|
259
|
+
* @param {String} key
|
|
260
|
+
* @param {Any} fnOrProperty
|
|
261
|
+
* @return {Any} fnOrProperty in Application
|
|
262
|
+
*
|
|
263
|
+
* @api public
|
|
264
|
+
*/
|
|
265
|
+
extend(key='', fnOrProperty) {
|
|
266
|
+
const keys = Object.keys(this);
|
|
267
|
+
if (keys.indexOf(key) > -1) {
|
|
268
|
+
const err = new TypeError(`Key ${ key } is already present in Application instance`);
|
|
269
|
+
throw err;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
this[key] = fnOrProperty;
|
|
273
|
+
|
|
274
|
+
return this[key];
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Stops server
|
|
280
|
+
*
|
|
281
|
+
* @api public
|
|
282
|
+
*/
|
|
283
|
+
stop() {
|
|
284
|
+
if (this.isListening !== true) {
|
|
285
|
+
console.warn('Nothing to stop. Server is not listening.');
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
this.server.close();
|
|
290
|
+
this.isListening = false;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
module.exports = function ConstantsEnum(constantsList = {}) {
|
|
3
|
+
// Set list.
|
|
4
|
+
this.list = constantsList;
|
|
5
|
+
|
|
6
|
+
// Set getters.
|
|
7
|
+
Object.keys(constantsList).forEach(key => {
|
|
8
|
+
this[key] = constantsList[key];
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
// Set constants in static array.
|
|
12
|
+
this.asArray = Object.values(constantsList);
|
|
13
|
+
}
|