binhend 2.3.7 → 2.3.9
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/index.js +3 -3
- package/jsconfig.json +1 -1
- package/package.json +1 -1
- package/packages/config/index.js +1 -0
- package/packages/config/src/process.env.js +32 -0
- package/packages/utils/src/HttpError.js +2 -2
- package/packages/utils/src/defaultErrorRepsonse.js +13 -3
- package/packages/validation/src/typeValidation.js +57 -6
package/index.js
CHANGED
|
@@ -11,7 +11,7 @@ const path = require('path');
|
|
|
11
11
|
|
|
12
12
|
//___ Run scripts ___//
|
|
13
13
|
const moduleAlias = require('./packages/module-alias'); // path alias '@' for requiring modules: require('@/any/path') - use jsconfig.json
|
|
14
|
-
moduleAlias.path('@binhend/*', [
|
|
14
|
+
moduleAlias.path('@binhend/*', [path.join(__dirname, './packages')]); // set path alias '@binhend' for all packages to call each others when 'npm install' in another project
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
//___ Load packages ___//
|
|
@@ -30,7 +30,7 @@ const csrf = require('./packages/middlewares/src/csrf');
|
|
|
30
30
|
const trycatch = require('./packages/middlewares/src/trycatch');
|
|
31
31
|
const { Auth } = require('./packages/middlewares/src/authorize');
|
|
32
32
|
|
|
33
|
-
const { config, ConfigLoader } = require('./packages/config
|
|
33
|
+
const { config, ConfigLoader, env } = require('./packages/config');
|
|
34
34
|
|
|
35
35
|
const CSD = require('./packages/csd/src/csd');
|
|
36
36
|
const CinCSD = require('./packages/csd/src/controller');
|
|
@@ -53,7 +53,7 @@ module.exports = {
|
|
|
53
53
|
|
|
54
54
|
cors, csrf, trycatch, Auth,
|
|
55
55
|
|
|
56
|
-
config, ConfigLoader,
|
|
56
|
+
env, config, ConfigLoader,
|
|
57
57
|
|
|
58
58
|
CSD, CinCSD, SinCSD, DinCSD, // only use CSD, others for exposing methods (via IDE auto-suggestion)
|
|
59
59
|
|
package/jsconfig.json
CHANGED
package/package.json
CHANGED
package/packages/config/index.js
CHANGED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { cli } = require('./configuration').ConfigLoader;
|
|
4
|
+
const { String } = require('@binhend/validation');
|
|
5
|
+
|
|
6
|
+
function env(env = String(), rootPath = String()) {
|
|
7
|
+
rootPath = String(rootPath, { default: require.main.path });
|
|
8
|
+
|
|
9
|
+
const envExtension = typeof env === 'string' ? `.${env}` : '';
|
|
10
|
+
const configModuleFileName = `./env${envExtension}`;
|
|
11
|
+
const configModuleFilePath = path.resolve(rootPath, configModuleFileName);
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
const localConfigs = require(configModuleFilePath);
|
|
15
|
+
|
|
16
|
+
for (var key in localConfigs) {
|
|
17
|
+
const value = localConfigs[key];
|
|
18
|
+
localConfigs[key] = typeof value === 'string' ? value : JSON.stringify(value);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
...localConfigs,
|
|
23
|
+
...process.env,
|
|
24
|
+
...cli()
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
throw new Error(`[BINHEND][CONFIG] Failed loading config from: ${configModuleFilePath}`, { cause: error });
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
module.exports = { env };
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
2
|
+
function StatusCode(code = 500) {
|
|
3
|
+
/**
|
|
4
|
+
* Range of HTTP codes are from 100 to 599.
|
|
5
|
+
* HTTP code 500 is `Internal Server Error`.
|
|
6
|
+
*/
|
|
7
|
+
return Number.isInteger(code) && code >= 100 && code <= 599 ? code : 500;
|
|
8
|
+
}
|
|
3
9
|
|
|
4
10
|
module.exports = function (error, response, next) {
|
|
5
|
-
if (
|
|
6
|
-
|
|
11
|
+
if (Object.prototype.hasOwnProperty.call(error, 'httpCode')) {
|
|
12
|
+
response.status(StatusCode(error.httpCode)).json({ error: error.message || 'Internal Server Error' });
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
next(error);
|
|
16
|
+
}
|
|
7
17
|
};
|
|
@@ -274,6 +274,44 @@ function Prop(key, object, validator, options) {
|
|
|
274
274
|
});
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
+
/**
|
|
278
|
+
* Return an object with all properties defined in the validator, using non-strict validation.
|
|
279
|
+
* Instead of throwing errors, invalid values are set to `null` by enforcing `{ default: null, required: false }` across all validations.
|
|
280
|
+
*
|
|
281
|
+
* @template V
|
|
282
|
+
* @param {((...args: any[]) => V)} [validator] - Validation function
|
|
283
|
+
* @returns {V} - An object with keys bypass requirement
|
|
284
|
+
* @throws {HttpError} - If validation fails
|
|
285
|
+
*/
|
|
286
|
+
function DefaultObject(validator) {
|
|
287
|
+
OptionControl.default = null;
|
|
288
|
+
OptionControl.required = false;
|
|
289
|
+
|
|
290
|
+
try {
|
|
291
|
+
var value = validator();
|
|
292
|
+
return value;
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
// TODO app log error for debug
|
|
296
|
+
throw new HttpError(HttpCodes.INTERNAL_SERVER_ERROR, `Type validation failed`);
|
|
297
|
+
}
|
|
298
|
+
finally {
|
|
299
|
+
delete OptionControl.default;
|
|
300
|
+
delete OptionControl.required;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Returns an empty object as the validator output without performing any validation.
|
|
306
|
+
*
|
|
307
|
+
* @template V
|
|
308
|
+
* @param {((...args: any[]) => V)} [validator] - Validation function
|
|
309
|
+
* @returns {V} - An empty object with no property
|
|
310
|
+
*/
|
|
311
|
+
function EmptyObject(validator) {
|
|
312
|
+
return /** @type {V} */ ({});
|
|
313
|
+
}
|
|
314
|
+
|
|
277
315
|
/**
|
|
278
316
|
* Validate an input being a function
|
|
279
317
|
*
|
|
@@ -407,10 +445,12 @@ function NotNullish(input, options = {}) {
|
|
|
407
445
|
/**
|
|
408
446
|
* Generic validator that accepts a validation function
|
|
409
447
|
*
|
|
410
|
-
* @
|
|
448
|
+
* @template T
|
|
449
|
+
*
|
|
450
|
+
* @param {T} input - Input value needs to be validated.
|
|
411
451
|
* @param {Function} validate - Validation function that returns boolean
|
|
412
452
|
* @param {Options} options - Additional options for validation.
|
|
413
|
-
* @returns {
|
|
453
|
+
* @returns {T} - The validated input
|
|
414
454
|
* @throws {HttpError} - If validation fails
|
|
415
455
|
*/
|
|
416
456
|
function Validator(input, validate, options = {}) {
|
|
@@ -418,14 +458,22 @@ function Validator(input, validate, options = {}) {
|
|
|
418
458
|
return input;
|
|
419
459
|
}
|
|
420
460
|
|
|
421
|
-
options = { ...options }; // prevent options being null
|
|
461
|
+
options = { ...options, ...OptionControl }; // prevent options being null
|
|
422
462
|
|
|
423
463
|
// use default value (options.default - must also be valid) if has, when input is invalid
|
|
424
|
-
if (options.hasOwnProperty('default')
|
|
425
|
-
|
|
464
|
+
if (options.hasOwnProperty('default')) {
|
|
465
|
+
var defaultValue = options.default;
|
|
466
|
+
|
|
467
|
+
if (validate(defaultValue)) {
|
|
468
|
+
return defaultValue;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
if (!options.required && types.isNullish(defaultValue)) {
|
|
472
|
+
return defaultValue;
|
|
473
|
+
}
|
|
426
474
|
}
|
|
427
475
|
|
|
428
|
-
//
|
|
476
|
+
// accept `null` or `undefined` by default, set `options.required=true` for not accepting nullish values
|
|
429
477
|
if (!options.required && types.isNullish(input)) {
|
|
430
478
|
return input;
|
|
431
479
|
}
|
|
@@ -443,6 +491,8 @@ function Validator(input, validate, options = {}) {
|
|
|
443
491
|
}
|
|
444
492
|
}
|
|
445
493
|
|
|
494
|
+
const OptionControl = {};
|
|
495
|
+
|
|
446
496
|
module.exports = {
|
|
447
497
|
String,
|
|
448
498
|
Number,
|
|
@@ -453,6 +503,7 @@ module.exports = {
|
|
|
453
503
|
PropIf, Prop,
|
|
454
504
|
AssignIf, Assign,
|
|
455
505
|
Value, Optional,
|
|
506
|
+
DefaultObject, EmptyObject,
|
|
456
507
|
Function,
|
|
457
508
|
AsyncFunction,
|
|
458
509
|
Date,
|