@mimik/mongooser 1.2.5 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc +20 -3
- package/.husky/pre-commit +4 -0
- package/.husky/pre-push +4 -0
- package/.nycrc +4 -0
- package/Gulpfile.js +9 -9
- package/README.md +30 -2
- package/index.js +82 -16
- package/package.json +28 -16
package/.eslintrc
CHANGED
|
@@ -1,17 +1,34 @@
|
|
|
1
|
-
// Use this file as a starting point for your project's .eslintrc.
|
|
2
|
-
// Copy this file, and add rule overrides as needed.
|
|
3
1
|
{
|
|
2
|
+
"plugins": [
|
|
3
|
+
"@mimik/document-env",
|
|
4
|
+
"@mimik/dependencies"
|
|
5
|
+
],
|
|
4
6
|
"env": {
|
|
5
7
|
"node": true
|
|
6
8
|
},
|
|
9
|
+
"parserOptions": {
|
|
10
|
+
"ecmaVersion": 2020
|
|
11
|
+
},
|
|
7
12
|
"extends": "airbnb",
|
|
8
13
|
"rules": {
|
|
14
|
+
"import/no-extraneous-dependencies": ["error", {"devDependencies": true}],
|
|
9
15
|
"brace-style": [1, "stroustrup", {"allowSingleLine": true}],
|
|
10
16
|
"no-confusing-arrow": [0], // arrow isnt confusing
|
|
11
17
|
"max-len": [1, 180, { "ignoreComments": true }],
|
|
12
18
|
"linebreak-style": 0,
|
|
13
19
|
"quotes": [1, "single"],
|
|
14
|
-
"semi": [1, "always"]
|
|
20
|
+
"semi": [1, "always"],
|
|
21
|
+
"no-process-env": ["error"],
|
|
22
|
+
"@mimik/document-env/validate-document-env": 2,
|
|
23
|
+
"@mimik/dependencies/case-sensitive": 2,
|
|
24
|
+
"@mimik/dependencies/no-cycles": 2,
|
|
25
|
+
"@mimik/dependencies/no-unresolved": 2,
|
|
26
|
+
"@mimik/dependencies/require-json-ext": 2
|
|
27
|
+
},
|
|
28
|
+
"settings":{
|
|
29
|
+
"react": {
|
|
30
|
+
"version": "latest"
|
|
31
|
+
}
|
|
15
32
|
},
|
|
16
33
|
"globals": {
|
|
17
34
|
"module": true,
|
package/.husky/pre-push
ADDED
package/.nycrc
ADDED
package/Gulpfile.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
//* eslint-disable import/no-extraneous-dependencies */
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const log = require('fancy-log');
|
|
4
4
|
const gulp = require('gulp');
|
|
@@ -9,25 +9,25 @@ const jsdoc2md = require('jsdoc-to-markdown');
|
|
|
9
9
|
const files = [
|
|
10
10
|
'index.js',
|
|
11
11
|
'Gulpfile.js',
|
|
12
|
-
'test
|
|
12
|
+
'test/**.js',
|
|
13
13
|
'lib/**.js',
|
|
14
14
|
];
|
|
15
15
|
|
|
16
|
-
const
|
|
16
|
+
const createDocs = (done) => {
|
|
17
17
|
jsdoc2md.render({ files: 'index.js' })
|
|
18
|
-
.then(output => fs.writeFileSync('README.md', output))
|
|
19
|
-
.catch(err => log.error('docs creation failed:', err.message))
|
|
20
|
-
|
|
18
|
+
.then((output) => fs.writeFileSync('README.md', output))
|
|
19
|
+
.catch((err) => log.error('docs creation failed:', err.message))
|
|
20
|
+
.finally(() => done());
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
const lint = () => gulp.src(files)
|
|
24
24
|
.pipe(eslint({}))
|
|
25
|
-
.pipe(eslint.format())
|
|
26
|
-
.pipe(eslint.failOnError());
|
|
25
|
+
.pipe(eslint.format());
|
|
27
26
|
|
|
28
27
|
const add = () => gulp.src('README.md')
|
|
29
28
|
.pipe(git.add({ quiet: true }));
|
|
30
29
|
|
|
30
|
+
const docs = gulp.series(createDocs, add);
|
|
31
|
+
|
|
31
32
|
gulp.task('docs', docs);
|
|
32
33
|
gulp.task('lint', lint);
|
|
33
|
-
gulp.task('add', add);
|
package/README.md
CHANGED
|
@@ -10,7 +10,8 @@ const mongodb = require('@mimik/mongooser');
|
|
|
10
10
|
* _async_
|
|
11
11
|
* [~validate()](#module_mongooser..validate) ⇒ <code>Promise</code>
|
|
12
12
|
* _sync_
|
|
13
|
-
* [~
|
|
13
|
+
* [~getKMSProviders()](#module_mongooser..getKMSProviders) ⇒ <code>object</code>
|
|
14
|
+
* [~initializeSync(autoEncryption)](#module_mongooser..initializeSync) ⇒ <code>object</code>
|
|
14
15
|
* [~replicat()](#module_mongooser..replicat) ⇒ <code>boolean</code>
|
|
15
16
|
|
|
16
17
|
<a name="module_mongooser..validate"></a>
|
|
@@ -29,17 +30,44 @@ Will exit 1 if the connection request times out and the connection state is not
|
|
|
29
30
|
|
|
30
31
|
**Requires**: <code>module:@mimik/sumologic-winston-logger</code>
|
|
31
32
|
**Fulfil**: Return `null`.
|
|
33
|
+
<a name="module_mongooser..getKMSProviders"></a>
|
|
34
|
+
|
|
35
|
+
### mongooser~getKMSProviders() ⇒ <code>object</code>
|
|
36
|
+
AutoEncryption KMSProvider.
|
|
37
|
+
|
|
38
|
+
**Kind**: inner method of [<code>mongooser</code>](#module_mongooser)
|
|
39
|
+
**Returns**: <code>object</code> - The KMSProviders object.
|
|
40
|
+
|
|
41
|
+
Will return the kmsProvider settings for the service.
|
|
42
|
+
**Category**: sync
|
|
32
43
|
<a name="module_mongooser..initializeSync"></a>
|
|
33
44
|
|
|
34
|
-
### mongooser~initializeSync() ⇒ <code>object</code>
|
|
45
|
+
### mongooser~initializeSync(autoEncryption) ⇒ <code>object</code>
|
|
35
46
|
Database initialization.
|
|
36
47
|
|
|
37
48
|
**Kind**: inner method of [<code>mongooser</code>](#module_mongooser)
|
|
38
49
|
**Returns**: <code>object</code> - The database object.
|
|
39
50
|
|
|
51
|
+
The autoEncryption has the following strucuture:
|
|
52
|
+
``` javascript
|
|
53
|
+
{
|
|
54
|
+
"keyVaultClient" : <object>,
|
|
55
|
+
"keyVaultNamespace": <string>, // namespace for the keyvault collection
|
|
56
|
+
"kmsProviders": <object>, // KeyManager service settings
|
|
57
|
+
"schemaMap": <object>, // json object for defining encryption schema
|
|
58
|
+
"bypassAutoEncryption": <boolean>
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
Check MongoDB documentation for more details. https://docs.mongodb.com/manual/reference/method/Mongo/#clientsidefieldlevelencryptionoptions
|
|
62
|
+
|
|
40
63
|
Will exit 1 if the connection request generates an error or the connection state is `disconnected` or `disconnecting`.
|
|
41
64
|
**Category**: sync
|
|
42
65
|
**Requires**: <code>module:sumologic-winston-logger</code>
|
|
66
|
+
|
|
67
|
+
| Param | Type | Description |
|
|
68
|
+
| --- | --- | --- |
|
|
69
|
+
| autoEncryption | <code>object</code> | Encryption settings for mongo connection. |
|
|
70
|
+
|
|
43
71
|
<a name="module_mongooser..replicat"></a>
|
|
44
72
|
|
|
45
73
|
### mongooser~replicat() ⇒ <code>boolean</code>
|
package/index.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
const mongoose = require('mongoose');
|
|
2
2
|
const Promise = require('bluebird');
|
|
3
|
+
const _ = require('lodash');
|
|
4
|
+
|
|
5
|
+
const { getCorrelationId } = require('@mimik/request-helper');
|
|
3
6
|
const logger = require('@mimik/sumologic-winston-logger');
|
|
7
|
+
const { isProd, MASK } = require('@mimik/lib-filters');
|
|
8
|
+
|
|
4
9
|
/**
|
|
5
10
|
* @module mongooser
|
|
6
11
|
* @example
|
|
@@ -9,8 +14,8 @@ const logger = require('@mimik/sumologic-winston-logger');
|
|
|
9
14
|
|
|
10
15
|
mongoose.Promise = Promise;
|
|
11
16
|
|
|
12
|
-
const correlationId = 'database-start';
|
|
13
17
|
const type = 'mongo';
|
|
18
|
+
const correlationId = getCorrelationId(`${type}-database-start`);
|
|
14
19
|
|
|
15
20
|
const VALIDATION_CHECK = 100; // in ms
|
|
16
21
|
const DISCONNECTED = 0;
|
|
@@ -18,41 +23,99 @@ const CONNECTED = 1;
|
|
|
18
23
|
const CONNECTING = 2;
|
|
19
24
|
const DISCONNECTING = 3;
|
|
20
25
|
|
|
26
|
+
let fatal = false;
|
|
27
|
+
|
|
21
28
|
module.exports = (config) => {
|
|
29
|
+
const { mongoSettings, encryption } = config;
|
|
30
|
+
const { options } = mongoSettings;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* AutoEncryption KMSProvider.
|
|
34
|
+
*
|
|
35
|
+
* @function getKMSProviders
|
|
36
|
+
* @category sync
|
|
37
|
+
* @return {object} The KMSProviders object.
|
|
38
|
+
*
|
|
39
|
+
* Will return the kmsProvider settings for the service.
|
|
40
|
+
*/
|
|
41
|
+
const getKMSProviders = () => {
|
|
42
|
+
const kmsProviders = {};
|
|
43
|
+
const provider = encryption.kmsProvider.toLowerCase();
|
|
44
|
+
|
|
45
|
+
if (provider === 'local') {
|
|
46
|
+
kmsProviders.local = { key: Buffer.from(encryption.localMasterKey, 'base64') };
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
kmsProviders.aws = encryption.aws;
|
|
50
|
+
}
|
|
51
|
+
return kmsProviders;
|
|
52
|
+
};
|
|
53
|
+
|
|
22
54
|
/**
|
|
23
55
|
* Database initialization.
|
|
24
56
|
*
|
|
25
57
|
* @requires sumologic-winston-logger
|
|
26
58
|
*
|
|
27
|
-
* @
|
|
59
|
+
* @param {object} autoEncryption - Encryption settings for mongo connection.
|
|
28
60
|
* @category sync
|
|
29
61
|
* @return {object} The database object.
|
|
30
62
|
*
|
|
63
|
+
* The autoEncryption has the following strucuture:
|
|
64
|
+
* ``` javascript
|
|
65
|
+
* {
|
|
66
|
+
* "keyVaultClient" : <object>,
|
|
67
|
+
* "keyVaultNamespace": <string>, // namespace for the keyvault collection
|
|
68
|
+
* "kmsProviders": <object>, // KeyManager service settings
|
|
69
|
+
* "schemaMap": <object>, // json object for defining encryption schema
|
|
70
|
+
* "bypassAutoEncryption": <boolean>
|
|
71
|
+
* }
|
|
72
|
+
*```
|
|
73
|
+
* Check MongoDB documentation for more details. https://docs.mongodb.com/manual/reference/method/Mongo/#clientsidefieldlevelencryptionoptions
|
|
74
|
+
*
|
|
31
75
|
* Will exit 1 if the connection request generates an error or the connection state is `disconnected` or `disconnecting`.
|
|
32
76
|
*/
|
|
33
77
|
const initializeSync = () => {
|
|
34
|
-
let interval
|
|
78
|
+
let interval;
|
|
35
79
|
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
80
|
+
if (encryption.set === 'on') {
|
|
81
|
+
options.autoEncryption = {
|
|
82
|
+
keyVaultNamespace: `${encryption.database}.${encryption.keyVaultTable}`,
|
|
83
|
+
kmsProviders: getKMSProviders(),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (mongoose.connection.readyState === DISCONNECTED && !fatal) {
|
|
88
|
+
if (isProd(config.nodeEnvironment) && mongoSettings.password) {
|
|
89
|
+
const mongoSettingsClone = { ...mongoSettings };
|
|
90
|
+
|
|
91
|
+
mongoSettingsClone.url = _.replace(mongoSettingsClone.url, mongoSettings.password, MASK);
|
|
92
|
+
logger.info('creating a database connection', { type, settings: mongoSettingsClone }, correlationId);
|
|
93
|
+
}
|
|
94
|
+
else logger.info('creating a database connection', { type, settings: mongoSettings }, correlationId);
|
|
95
|
+
mongoose.connect(mongoSettings.url, options)
|
|
96
|
+
.then(() => mongoose)
|
|
97
|
+
.catch((error) => {
|
|
98
|
+
fatal = true;
|
|
99
|
+
logger.error('Fatal error: Could not connect to database', { type, error }, correlationId);
|
|
100
|
+
if (interval) clearInterval(interval);
|
|
101
|
+
logger.flushAndExit(1);
|
|
102
|
+
});
|
|
42
103
|
}
|
|
43
104
|
|
|
44
105
|
mongoose.connection.on('disconnected', () => {
|
|
45
106
|
interval = setInterval(() => {
|
|
46
107
|
const state = mongoose.connection.readyState;
|
|
47
108
|
|
|
48
|
-
if (state === DISCONNECTED || state === DISCONNECTING) {
|
|
109
|
+
if ((state === DISCONNECTED || state === DISCONNECTING) && !fatal) {
|
|
110
|
+
fatal = true;
|
|
49
111
|
logger.error('Fatal error: Could not connect to database', { type, error: state }, correlationId);
|
|
112
|
+
clearInterval(interval);
|
|
50
113
|
logger.flushAndExit(1);
|
|
51
114
|
}
|
|
52
|
-
}, (
|
|
115
|
+
}, (options.heartbeatFrequencyMS + (mongoSettings.reconnectOffset * 1000)));
|
|
53
116
|
});
|
|
54
117
|
mongoose.connection.on('connected', () => {
|
|
55
|
-
clearInterval(interval);
|
|
118
|
+
if (interval) clearInterval(interval);
|
|
56
119
|
});
|
|
57
120
|
return mongoose;
|
|
58
121
|
};
|
|
@@ -75,13 +138,15 @@ module.exports = (config) => {
|
|
|
75
138
|
const interval = setInterval(() => {
|
|
76
139
|
const state = mongoose.connection.readyState;
|
|
77
140
|
|
|
78
|
-
if (state !== CONNECTED) {
|
|
141
|
+
if (state !== CONNECTED && !fatal) {
|
|
142
|
+
fatal = true;
|
|
79
143
|
logger.error('Fatal error: Timeout in connecting to database', {
|
|
80
|
-
type, error: state, timeout:
|
|
144
|
+
type, error: state, timeout: mongoSettings.connectTimeout,
|
|
81
145
|
}, correlationId);
|
|
146
|
+
clearInterval(interval);
|
|
82
147
|
logger.flushAndExit(1);
|
|
83
148
|
}
|
|
84
|
-
},
|
|
149
|
+
}, mongoSettings.connectTimeout * 1000); // convert in seconds
|
|
85
150
|
|
|
86
151
|
return Promise.delay(VALIDATION_CHECK).then(() => {
|
|
87
152
|
const state = mongoose.connection.readyState;
|
|
@@ -109,11 +174,12 @@ module.exports = (config) => {
|
|
|
109
174
|
* @category sync
|
|
110
175
|
* @return {boolean} `True` if replica is set, `False` if not.
|
|
111
176
|
*/
|
|
112
|
-
const replicat = () =>
|
|
177
|
+
const replicat = () => mongoSettings.replicat;
|
|
113
178
|
|
|
114
179
|
return {
|
|
115
180
|
initializeSync,
|
|
116
181
|
validate,
|
|
117
182
|
replicat,
|
|
183
|
+
getKMSProviders,
|
|
118
184
|
};
|
|
119
185
|
};
|
package/package.json
CHANGED
|
@@ -1,45 +1,57 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mimik/mongooser",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Helper for setting up mongodb using mongoose for mimik microservices",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=12.0.0"
|
|
8
|
+
},
|
|
6
9
|
"scripts": {
|
|
7
10
|
"lint": "gulp lint",
|
|
8
11
|
"docs": "gulp docs",
|
|
9
|
-
"test": "exit 0"
|
|
12
|
+
"test": "exit 0",
|
|
13
|
+
"prepublishOnly": "gulp docs; gulp lint; npm run test",
|
|
14
|
+
"commit-ready": "gulp docs; gulp lint; npm run test",
|
|
15
|
+
"prepare": "husky install"
|
|
10
16
|
},
|
|
11
17
|
"husky": {
|
|
12
18
|
"hooks": {
|
|
13
|
-
"pre-commit": "npm run
|
|
14
|
-
"pre-push": "npm run
|
|
19
|
+
"pre-commit": "npm run commit-ready",
|
|
20
|
+
"pre-push": "npm run test"
|
|
15
21
|
}
|
|
16
22
|
},
|
|
17
23
|
"keywords": [
|
|
18
24
|
"mimik",
|
|
19
25
|
"microservice"
|
|
20
26
|
],
|
|
21
|
-
"author": "mimik",
|
|
27
|
+
"author": "mimik technology inc <support@mimik.com> (https://developer.mimik.com/)",
|
|
22
28
|
"license": "Apache-2.0",
|
|
23
29
|
"repository": {
|
|
24
30
|
"type": "git",
|
|
25
31
|
"url": "https://bitbucket.org/mimiktech/mongooser"
|
|
26
32
|
},
|
|
27
33
|
"dependencies": {
|
|
28
|
-
"@mimik/
|
|
29
|
-
"
|
|
30
|
-
"
|
|
34
|
+
"@mimik/lib-filters": "^1.4.3",
|
|
35
|
+
"@mimik/request-helper": "^1.7.3",
|
|
36
|
+
"@mimik/sumologic-winston-logger": "^1.6.6",
|
|
37
|
+
"bluebird": "3.7.2",
|
|
38
|
+
"lodash": "4.17.21",
|
|
39
|
+
"mongoose": "6.1.5"
|
|
31
40
|
},
|
|
32
41
|
"devDependencies": {
|
|
33
|
-
"eslint": "
|
|
34
|
-
"eslint-
|
|
35
|
-
"eslint
|
|
36
|
-
"eslint-
|
|
37
|
-
"eslint-plugin-
|
|
42
|
+
"@mimik/eslint-plugin-dependencies": "^2.4.1",
|
|
43
|
+
"@mimik/eslint-plugin-document-env": "^1.0.1",
|
|
44
|
+
"eslint": "7.2.0",
|
|
45
|
+
"eslint-config-airbnb": "18.2.1",
|
|
46
|
+
"eslint-plugin-import": "2.25.3",
|
|
47
|
+
"eslint-plugin-jsx-a11y": "6.5.1",
|
|
48
|
+
"eslint-plugin-react": "7.27.1",
|
|
49
|
+
"eslint-plugin-react-hooks": "4.3.0",
|
|
38
50
|
"fancy-log": "1.3.3",
|
|
39
51
|
"gulp": "4.0.2",
|
|
40
52
|
"gulp-eslint": "6.0.0",
|
|
41
|
-
"gulp-git": "2.
|
|
42
|
-
"husky": "
|
|
43
|
-
"jsdoc-to-markdown": "
|
|
53
|
+
"gulp-git": "2.10.1",
|
|
54
|
+
"husky": "7.0.4",
|
|
55
|
+
"jsdoc-to-markdown": "7.1.0"
|
|
44
56
|
}
|
|
45
57
|
}
|