1 | "use strict";
|
2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3 | return new (P || (P = Promise))(function (resolve, reject) {
|
4 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
5 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
6 | function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
7 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
8 | });
|
9 | };
|
10 | Object.defineProperty(exports, "__esModule", { value: true });
|
11 | const mongodb_1 = require("mongodb");
|
12 | const common_1 = require("../common");
|
13 | const _1 = require(".");
|
14 |
|
15 |
|
16 |
|
17 | class DatabaseConnector {
|
18 | |
19 |
|
20 |
|
21 |
|
22 |
|
23 | constructor(reconnectTimeoutMillis) {
|
24 | this.reconnectTimeoutMillis =
|
25 | reconnectTimeoutMillis != null
|
26 | ? reconnectTimeoutMillis
|
27 | : DatabaseConnector.DEFAULT_RECONNECT_TIMEOUT_MILLIS;
|
28 | }
|
29 | |
30 |
|
31 |
|
32 |
|
33 |
|
34 | connect(config) {
|
35 | return __awaiter(this, void 0, void 0, function* () {
|
36 | let uri, databaseName;
|
37 | if (typeof config === 'string') {
|
38 | uri = config;
|
39 | databaseName = this.getDbName(uri);
|
40 | }
|
41 | else if (_1.isSeederDatabaseConfigObject(config)) {
|
42 | uri = this.getDbConnectionUri(config);
|
43 | databaseName = config.name;
|
44 | }
|
45 | else {
|
46 | throw new Error('You have to pass connection URI or database config object');
|
47 | }
|
48 | return this.connectWithUri(uri, databaseName);
|
49 | });
|
50 | }
|
51 | |
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 | connectWithUri(dbConnectionUri, dbName) {
|
58 | return __awaiter(this, void 0, void 0, function* () {
|
59 | common_1.log(`Connecting to ${this.maskUriCredentials(dbConnectionUri)}...`);
|
60 | const startMillis = new Date().getTime();
|
61 | let client;
|
62 | do {
|
63 | try {
|
64 | client = yield mongodb_1.MongoClient.connect(dbConnectionUri, {
|
65 | ignoreUndefined: true,
|
66 | useNewUrlParser: true,
|
67 | });
|
68 | }
|
69 | catch (err) {
|
70 | if (_1.checkTimeout(startMillis, this.reconnectTimeoutMillis)) {
|
71 | throw new Error(`Timeout ${this.reconnectTimeoutMillis}s expired while connecting to database due to: ${err.name}: ${err.message}`);
|
72 | }
|
73 | common_1.log(`${err.message}\nRetrying...`);
|
74 | yield _1.sleep(DatabaseConnector.SLEEP_INTERVAL_MILLIS);
|
75 | }
|
76 | } while (!client);
|
77 | common_1.log('Connection with database established.');
|
78 | this.client = client;
|
79 | const db = client.db(dbName);
|
80 | return new _1.Database(db);
|
81 | });
|
82 | }
|
83 | |
84 |
|
85 |
|
86 | close() {
|
87 | return __awaiter(this, void 0, void 0, function* () {
|
88 | common_1.log('Closing connection...');
|
89 | if (!this.client || !this.client.isConnected()) {
|
90 | return;
|
91 | }
|
92 | yield this.client.close(true);
|
93 | });
|
94 | }
|
95 | |
96 |
|
97 |
|
98 |
|
99 |
|
100 | getDbConnectionUri({ protocol, host, port, name, username, password, options, }) {
|
101 | const credentials = username
|
102 | ? `${username}${password ? `:${password}` : ''}@`
|
103 | : '';
|
104 | const optsUriPart = options ? this.getOptionsUriPart(options) : '';
|
105 | const portUriPart = protocol !== 'mongodb+srv' ? `:${port}` : '';
|
106 | return `${protocol}://${credentials}${host}${portUriPart}/${name}${optsUriPart}`;
|
107 | }
|
108 | |
109 |
|
110 |
|
111 |
|
112 |
|
113 | getOptionsUriPart(options) {
|
114 | return Object.keys(options).reduce((previousUri, currentKey) => {
|
115 | let uriPartFirstChar;
|
116 | if (previousUri == '') {
|
117 | uriPartFirstChar = '?';
|
118 | }
|
119 | else {
|
120 | uriPartFirstChar = '&';
|
121 | }
|
122 | return `${previousUri}${uriPartFirstChar}${currentKey}=${options[currentKey]}`;
|
123 | }, '');
|
124 | }
|
125 | |
126 |
|
127 |
|
128 |
|
129 |
|
130 | maskUriCredentials(uri) {
|
131 | if (!uri.includes('@')) {
|
132 | return uri;
|
133 | }
|
134 | const creds = uri.substring(uri.indexOf('://') + 3, uri.indexOf('@'));
|
135 | return uri.replace(creds, DatabaseConnector.MASKED_URI_CREDENTIALS);
|
136 | }
|
137 | |
138 |
|
139 |
|
140 |
|
141 |
|
142 | getDbName(dbConnectionUri) {
|
143 | const url = dbConnectionUri.replace('mongodb://', '');
|
144 | const parts = url.split('/');
|
145 | if (parts.length === 1) {
|
146 |
|
147 | return DatabaseConnector.DEFAULT_DB_NAME;
|
148 | }
|
149 | const lastPart = parts[parts.length - 1];
|
150 | const givenDbName = lastPart.split('?')[0];
|
151 | return givenDbName ? givenDbName : DatabaseConnector.DEFAULT_DB_NAME;
|
152 | }
|
153 | }
|
154 |
|
155 |
|
156 |
|
157 | DatabaseConnector.DEFAULT_DB_NAME = 'admin';
|
158 |
|
159 |
|
160 |
|
161 | DatabaseConnector.DEFAULT_RECONNECT_TIMEOUT_MILLIS = 10000;
|
162 |
|
163 |
|
164 |
|
165 | DatabaseConnector.SLEEP_INTERVAL_MILLIS = 500;
|
166 |
|
167 |
|
168 |
|
169 | DatabaseConnector.MASKED_URI_CREDENTIALS = '[secure]';
|
170 | exports.DatabaseConnector = DatabaseConnector;
|
171 |
|
\ | No newline at end of file |