@villedemontreal/mongo 6.7.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/LICENSE +22 -0
- package/README.md +226 -0
- package/dist/src/config/configs.d.ts +16 -0
- package/dist/src/config/configs.js +26 -0
- package/dist/src/config/configs.js.map +1 -0
- package/dist/src/config/constants.d.ts +85 -0
- package/dist/src/config/constants.js +104 -0
- package/dist/src/config/constants.js.map +1 -0
- package/dist/src/config/init.d.ts +9 -0
- package/dist/src/config/init.js +24 -0
- package/dist/src/config/init.js.map +1 -0
- package/dist/src/config/mongooseConfigs.d.ts +73 -0
- package/dist/src/config/mongooseConfigs.js +107 -0
- package/dist/src/config/mongooseConfigs.js.map +1 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.js +24 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/mongoClient.d.ts +19 -0
- package/dist/src/mongoClient.js +111 -0
- package/dist/src/mongoClient.js.map +1 -0
- package/dist/src/mongoUpdater.d.ts +103 -0
- package/dist/src/mongoUpdater.js +297 -0
- package/dist/src/mongoUpdater.js.map +1 -0
- package/dist/src/mongoUpdater.test.d.ts +1 -0
- package/dist/src/mongoUpdater.test.js +232 -0
- package/dist/src/mongoUpdater.test.js.map +1 -0
- package/dist/src/mongoUtils.d.ts +68 -0
- package/dist/src/mongoUtils.js +280 -0
- package/dist/src/mongoUtils.js.map +1 -0
- package/dist/src/mongoUtils.test.d.ts +1 -0
- package/dist/src/mongoUtils.test.js +24 -0
- package/dist/src/mongoUtils.test.js.map +1 -0
- package/dist/src/plugins/pagination/index.d.ts +11 -0
- package/dist/src/plugins/pagination/index.js +79 -0
- package/dist/src/plugins/pagination/index.js.map +1 -0
- package/dist/src/plugins/pagination/index.test.d.ts +1 -0
- package/dist/src/plugins/pagination/index.test.js +129 -0
- package/dist/src/plugins/pagination/index.test.js.map +1 -0
- package/dist/src/plugins/pagination/specs/IPaginateOptions.d.ts +51 -0
- package/dist/src/plugins/pagination/specs/IPaginateOptions.js +3 -0
- package/dist/src/plugins/pagination/specs/IPaginateOptions.js.map +1 -0
- package/dist/src/utils/logger.d.ts +11 -0
- package/dist/src/utils/logger.js +54 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/testingConfigurations.d.ts +8 -0
- package/dist/src/utils/testingConfigurations.js +17 -0
- package/dist/src/utils/testingConfigurations.js.map +1 -0
- package/dist/tests/testingMongoUpdates/1.0.0.d.ts +5 -0
- package/dist/tests/testingMongoUpdates/1.0.0.js +27 -0
- package/dist/tests/testingMongoUpdates/1.0.0.js.map +1 -0
- package/dist/tests/testingMongoUpdates/1.0.1.d.ts +5 -0
- package/dist/tests/testingMongoUpdates/1.0.1.js +22 -0
- package/dist/tests/testingMongoUpdates/1.0.1.js.map +1 -0
- package/package.json +63 -0
- package/src/config/configs.ts +27 -0
- package/src/config/constants.ts +122 -0
- package/src/config/init.ts +23 -0
- package/src/config/mongooseConfigs.ts +178 -0
- package/src/index.ts +13 -0
- package/src/mongoClient.ts +122 -0
- package/src/mongoUpdater.test.ts +286 -0
- package/src/mongoUpdater.ts +423 -0
- package/src/mongoUtils.test.ts +23 -0
- package/src/mongoUtils.ts +322 -0
- package/src/plugins/pagination/index.test.ts +140 -0
- package/src/plugins/pagination/index.ts +96 -0
- package/src/plugins/pagination/specs/IPaginateOptions.ts +51 -0
- package/src/utils/logger.ts +53 -0
- package/src/utils/testingConfigurations.ts +13 -0
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
import { Timer, utils } from '@villedemontreal/general-utils';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import { isFunction } from 'lodash';
|
|
4
|
+
import * as MongoDb from 'mongodb';
|
|
5
|
+
import * as semver from 'semver';
|
|
6
|
+
import { constants as mongodbConstants } from './config/constants';
|
|
7
|
+
import { createLogger } from './utils/logger';
|
|
8
|
+
|
|
9
|
+
const logger = createLogger('MongoUpdater');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Mongo updater
|
|
13
|
+
* Manages the updates of the mongo schemas
|
|
14
|
+
*/
|
|
15
|
+
export interface IMongoUpdater {
|
|
16
|
+
/**
|
|
17
|
+
* Validates that the application has been installed.
|
|
18
|
+
* This involves creating a special "appSchema" collection
|
|
19
|
+
* and document to track the application version and being able
|
|
20
|
+
* to update its schemas and documents...
|
|
21
|
+
*/
|
|
22
|
+
checkInstallation(): Promise<void>;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Checks if the application needs update or not. Installs the updates
|
|
26
|
+
* if so.
|
|
27
|
+
*/
|
|
28
|
+
checkUpdates(): Promise<void>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Locks the appSchema document.
|
|
32
|
+
*
|
|
33
|
+
* @returns true if the lock has been acquired succesfully
|
|
34
|
+
* or false if the document was already locked.
|
|
35
|
+
*/
|
|
36
|
+
lockAppSchemaDocument(): Promise<boolean>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Unlocks the appSchema document.
|
|
40
|
+
*
|
|
41
|
+
* @returns true if the lock has been removed succesfully
|
|
42
|
+
* or false if the document was not locked.
|
|
43
|
+
*/
|
|
44
|
+
unlockAppSchemaDocument(): Promise<boolean>;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Updates the app schema version stored in mongo database
|
|
48
|
+
*/
|
|
49
|
+
updateAppSchemaVersion(currentVersion: string, newVersion: string): Promise<void>;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Installs the appSchema collection.
|
|
53
|
+
*/
|
|
54
|
+
installAppSchemaCollection(): Promise<any>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Gets a list of available app schema update files.
|
|
58
|
+
*/
|
|
59
|
+
getAppSchemaUpdateFiles(currentVersion: string, newVersion: string): Promise<string[]>;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Updates the app schema
|
|
63
|
+
*/
|
|
64
|
+
applyAppSchemaUpdates(currentVersion: string, newVersion: string): Promise<any>;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Gets the appSchema collection
|
|
68
|
+
*/
|
|
69
|
+
getAppSchemaCollection(): Promise<MongoDb.Collection>;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Gets the current version from the appSchema document.
|
|
73
|
+
*/
|
|
74
|
+
getAppSchemaVersion(): Promise<string>;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface ISchemeInfo {
|
|
78
|
+
version: string;
|
|
79
|
+
lock: boolean;
|
|
80
|
+
lockTimestamp: number;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export class MongoUpdater implements IMongoUpdater {
|
|
84
|
+
constructor(
|
|
85
|
+
private mongoDb: MongoDb.Db,
|
|
86
|
+
/**
|
|
87
|
+
* The *relative* path to the directory where the
|
|
88
|
+
* update files are.
|
|
89
|
+
*/
|
|
90
|
+
private mongoSchemaUpdatesDirPath: string,
|
|
91
|
+
private lockMaxAgeSeconds: number,
|
|
92
|
+
private appSchemaCollectionName: string
|
|
93
|
+
) {}
|
|
94
|
+
|
|
95
|
+
public async installAppSchemaCollection(): Promise<any> {
|
|
96
|
+
try {
|
|
97
|
+
// Installing the "appSchema" collection.
|
|
98
|
+
// tslint:disable-next-line: prefer-template
|
|
99
|
+
logger.info(' > Installing the "' + this.appSchemaCollectionName + '" collection.');
|
|
100
|
+
const collection: MongoDb.Collection = await this.mongoDb.createCollection(this.appSchemaCollectionName);
|
|
101
|
+
|
|
102
|
+
// ==========================================
|
|
103
|
+
// Makes sure only one appSchema document exists.
|
|
104
|
+
// ==========================================
|
|
105
|
+
await collection.createIndexes([
|
|
106
|
+
{
|
|
107
|
+
key: {
|
|
108
|
+
name: 1
|
|
109
|
+
},
|
|
110
|
+
name: 'name_1',
|
|
111
|
+
unique: true
|
|
112
|
+
}
|
|
113
|
+
]);
|
|
114
|
+
|
|
115
|
+
// ==========================================
|
|
116
|
+
// Inserts the first version of the AppSchema document
|
|
117
|
+
// ==========================================
|
|
118
|
+
await collection.insertOne({
|
|
119
|
+
name: 'singleton', // do not change!
|
|
120
|
+
version: '0.0.0',
|
|
121
|
+
lock: false,
|
|
122
|
+
lockTimestamp: 0
|
|
123
|
+
} as ISchemeInfo);
|
|
124
|
+
} catch (err) {
|
|
125
|
+
// ==========================================
|
|
126
|
+
// Maybe the error occured because another app
|
|
127
|
+
// was also trying to create the collection?
|
|
128
|
+
// ==========================================
|
|
129
|
+
const maxWaitMilliseconds = 10 * 1000;
|
|
130
|
+
const start = new Timer();
|
|
131
|
+
while (start.getMillisecondsElapsed() < maxWaitMilliseconds) {
|
|
132
|
+
await utils.sleep(1000);
|
|
133
|
+
|
|
134
|
+
const appSchemaCollection: MongoDb.Collection = await this.getAppSchemaCollection();
|
|
135
|
+
if (!appSchemaCollection) {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const document = await appSchemaCollection.findOne({});
|
|
140
|
+
if (!document) {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// ==========================================
|
|
145
|
+
// We ignore the error!
|
|
146
|
+
// ==========================================
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// ==========================================
|
|
151
|
+
// Throws the error...
|
|
152
|
+
// ==========================================
|
|
153
|
+
throw err;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
public async updateAppSchemaVersion(currentVersion: string, newVersion: string): Promise<void> {
|
|
158
|
+
const appSchemaCollection: MongoDb.Collection = await this.getAppSchemaCollection();
|
|
159
|
+
|
|
160
|
+
await appSchemaCollection.updateOne({}, { $set: { version: newVersion } });
|
|
161
|
+
// tslint:disable-next-line: prefer-template
|
|
162
|
+
logger.info(' > MongoDB App Schema updagred from version ' + currentVersion + ' to version ' + newVersion);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
public async getAppSchemaUpdateFiles(
|
|
166
|
+
currentAppSchemaVersion: string,
|
|
167
|
+
targetAppSchemaVersion: string
|
|
168
|
+
): Promise<string[]> {
|
|
169
|
+
return new Promise<string[]>((resolve, reject) => {
|
|
170
|
+
fs.readdir(this.getAppSchemaFilesDirPath(), (err, files) => {
|
|
171
|
+
if (err) {
|
|
172
|
+
return reject(err);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
let filesClean = files;
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
filesClean = filesClean
|
|
179
|
+
.filter(name => {
|
|
180
|
+
return name.match(/\.js$/) !== null;
|
|
181
|
+
})
|
|
182
|
+
.map(name => {
|
|
183
|
+
return name.split('.js')[0];
|
|
184
|
+
})
|
|
185
|
+
.filter(updateFileVersion => {
|
|
186
|
+
if (
|
|
187
|
+
semver.gt(updateFileVersion, currentAppSchemaVersion) &&
|
|
188
|
+
semver.lte(updateFileVersion, targetAppSchemaVersion)
|
|
189
|
+
) {
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
return false;
|
|
193
|
+
});
|
|
194
|
+
} catch (err2) {
|
|
195
|
+
return reject(err2);
|
|
196
|
+
}
|
|
197
|
+
return resolve(filesClean.sort(semver.compare));
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
public async applyAppSchemaUpdates(currentVersion: string, newVersion: string): Promise<void> {
|
|
203
|
+
const updateFileNames: string[] = await this.getAppSchemaUpdateFiles(currentVersion, newVersion);
|
|
204
|
+
if (updateFileNames.length > 0) {
|
|
205
|
+
for (const updateFileName of updateFileNames) {
|
|
206
|
+
logger.info(' > Pending app schema update: ' + updateFileName);
|
|
207
|
+
|
|
208
|
+
// tslint:disable-next-line: prefer-template
|
|
209
|
+
const updateFilePath = this.getAppSchemaFilesDirPath() + '/' + updateFileName;
|
|
210
|
+
let updateFunction: (db: MongoDb.Db) => Promise<void>;
|
|
211
|
+
try {
|
|
212
|
+
updateFunction = require(updateFilePath).default;
|
|
213
|
+
} catch (e) {
|
|
214
|
+
return Promise.reject(e);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (!isFunction(updateFunction)) {
|
|
218
|
+
return Promise.reject(
|
|
219
|
+
'The default export for an app schema update file must be a function! Was not for file : ' + updateFilePath
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
await updateFunction(this.mongoDb);
|
|
224
|
+
}
|
|
225
|
+
logger.info('All app schema updates done');
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
public async getAppSchemaCollection(): Promise<MongoDb.Collection> {
|
|
230
|
+
return await this.mongoDb.collection(this.appSchemaCollectionName);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
public async getAppSchemaVersion(): Promise<string> {
|
|
234
|
+
const appSchemaCollection: MongoDb.Collection = await this.getAppSchemaCollection();
|
|
235
|
+
|
|
236
|
+
const documents: any[] = await appSchemaCollection.find().toArray();
|
|
237
|
+
if (documents.length > 0) {
|
|
238
|
+
return documents[0].version;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return '0.0.0';
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Tries to get the lock to modify Mongo's schemas.
|
|
246
|
+
*
|
|
247
|
+
* If a lock already exists, checks if it is too old.
|
|
248
|
+
* If too old, will create a new one... This is to prevents
|
|
249
|
+
* situations where a lock would have been taken by an app
|
|
250
|
+
* but that app *crashed* while the lock was on. We don't want
|
|
251
|
+
* suck lock to be active forever...
|
|
252
|
+
*
|
|
253
|
+
*/
|
|
254
|
+
public async lockAppSchemaDocument(): Promise<boolean> {
|
|
255
|
+
const appSchemaCollection: MongoDb.Collection = await this.getAppSchemaCollection();
|
|
256
|
+
|
|
257
|
+
let document = await appSchemaCollection.findOneAndUpdate(
|
|
258
|
+
{ lock: false },
|
|
259
|
+
{
|
|
260
|
+
$set: {
|
|
261
|
+
lock: true,
|
|
262
|
+
lockTimestamp: new Date().getTime()
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
if (document.value !== null) {
|
|
268
|
+
logger.info(` > Succesfully locked the ${this.appSchemaCollectionName} document`);
|
|
269
|
+
return true;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
document = await appSchemaCollection.findOne({ lock: true });
|
|
273
|
+
if (document === null) {
|
|
274
|
+
// try again!
|
|
275
|
+
return this.lockAppSchemaDocument();
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// ==========================================
|
|
279
|
+
// Checks the existing lock's timestamp
|
|
280
|
+
// ==========================================
|
|
281
|
+
const lockTimestamp = (document as any).lockTimestamp;
|
|
282
|
+
const nowTimestamp = new Date().getTime();
|
|
283
|
+
const lockAgeMilliSeconds = nowTimestamp - lockTimestamp;
|
|
284
|
+
|
|
285
|
+
// ==========================================
|
|
286
|
+
// Lock is too old! We overwrite it....
|
|
287
|
+
// ==========================================
|
|
288
|
+
if (lockAgeMilliSeconds > this.lockMaxAgeSeconds * 1000) {
|
|
289
|
+
document = await appSchemaCollection.findOneAndUpdate(
|
|
290
|
+
{ lockTimestamp },
|
|
291
|
+
{
|
|
292
|
+
$set: {
|
|
293
|
+
lock: true,
|
|
294
|
+
lockTimestamp: new Date().getTime()
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
// ==========================================
|
|
300
|
+
// *Just* taken by another app!
|
|
301
|
+
// ==========================================
|
|
302
|
+
if (document.value === null) {
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return true;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// ==========================================
|
|
310
|
+
// The existing lock is still valid...
|
|
311
|
+
// We can't get it.
|
|
312
|
+
// ==========================================
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
public async unlockAppSchemaDocument(): Promise<boolean> {
|
|
317
|
+
const appSchemaCollection: MongoDb.Collection = await this.getAppSchemaCollection();
|
|
318
|
+
|
|
319
|
+
const document = await appSchemaCollection.findOneAndUpdate(
|
|
320
|
+
{ lock: true },
|
|
321
|
+
{
|
|
322
|
+
$set: {
|
|
323
|
+
lock: false,
|
|
324
|
+
lockTimestamp: 0
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
);
|
|
328
|
+
|
|
329
|
+
if (document.value !== null) {
|
|
330
|
+
logger.info(` > Succesfully unlocked the ${this.appSchemaCollectionName} document`);
|
|
331
|
+
return true;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
logger.info(`> The ${this.appSchemaCollectionName} document was not locked`);
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
public async checkInstallation(): Promise<void> {
|
|
339
|
+
logger.info(
|
|
340
|
+
`Validating that the "${this.appSchemaCollectionName}" collection required by the application has been installed.`
|
|
341
|
+
);
|
|
342
|
+
const collections: any[] = await this.mongoDb.listCollections({ name: this.appSchemaCollectionName }).toArray();
|
|
343
|
+
|
|
344
|
+
if (collections.length === 0) {
|
|
345
|
+
logger.info(` > The "${this.appSchemaCollectionName}" collection was not found... Starting a new installation.`);
|
|
346
|
+
await this.installAppSchemaCollection();
|
|
347
|
+
} else {
|
|
348
|
+
logger.info(` > The "${this.appSchemaCollectionName}" collection was found. No installation required.`);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
public checkUpdates = async (): Promise<void> => {
|
|
353
|
+
logger.info('Checking for db app schema updates:');
|
|
354
|
+
|
|
355
|
+
let lockAcquired = false;
|
|
356
|
+
const targetVersion: string = this.findMongoAppSchemaTargetVersion();
|
|
357
|
+
try {
|
|
358
|
+
while (true) {
|
|
359
|
+
// ==========================================
|
|
360
|
+
// Checks if the appSchema version has to be
|
|
361
|
+
// updated.
|
|
362
|
+
// ==========================================
|
|
363
|
+
const currentAppSchemaVersion: string = await this.getAppSchemaVersion();
|
|
364
|
+
if (semver.gte(currentAppSchemaVersion, targetVersion)) {
|
|
365
|
+
// tslint:disable-next-line: prefer-template
|
|
366
|
+
logger.info(' > Current database app schema is up to date : ' + currentAppSchemaVersion + ').');
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (lockAcquired) {
|
|
371
|
+
logger.info(` > Applying some required updates...`);
|
|
372
|
+
await this.applyAppSchemaUpdates(currentAppSchemaVersion, targetVersion);
|
|
373
|
+
await this.updateAppSchemaVersion(currentAppSchemaVersion, targetVersion);
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// ==========================================
|
|
378
|
+
// Tries to get the lock. Will do this as long
|
|
379
|
+
// as the lock can't be acquired (ie : it is
|
|
380
|
+
// released or is too old) or as long as the appSchema
|
|
381
|
+
// version still is not up to date.
|
|
382
|
+
// ==========================================
|
|
383
|
+
lockAcquired = await this.lockAppSchemaDocument();
|
|
384
|
+
if (!lockAcquired) {
|
|
385
|
+
const wait = 1000;
|
|
386
|
+
logger.warning(
|
|
387
|
+
`The lock can't be acquired. The maximum age it can be before being considered ` +
|
|
388
|
+
`to be too old is ${this.lockMaxAgeSeconds} seconds. Waiting for ${wait} milliseconds...`
|
|
389
|
+
);
|
|
390
|
+
await utils.sleep(wait);
|
|
391
|
+
} else {
|
|
392
|
+
logger.info(` > Lock acquired.`);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
} finally {
|
|
396
|
+
if (lockAcquired) {
|
|
397
|
+
await this.unlockAppSchemaDocument();
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
protected getAppSchemaFilesDirPath(): string {
|
|
403
|
+
return mongodbConstants.appRoot + this.mongoSchemaUpdatesDirPath;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Finds the latest Mongo update file version.
|
|
408
|
+
*/
|
|
409
|
+
protected findMongoAppSchemaTargetVersion(): string {
|
|
410
|
+
let targetVersion = '0.0.0';
|
|
411
|
+
|
|
412
|
+
fs.readdirSync(this.getAppSchemaFilesDirPath()).forEach(fileName => {
|
|
413
|
+
if (fileName.endsWith('.js')) {
|
|
414
|
+
const version = fileName.split('.js')[0];
|
|
415
|
+
if (semver.gt(version, targetVersion)) {
|
|
416
|
+
targetVersion = version;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
return targetVersion;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { assert } from 'chai';
|
|
2
|
+
import { MongoMemoryReplSet, MongoMemoryServer } from 'mongodb-memory-server-core';
|
|
3
|
+
import { MongoUtils } from './mongoUtils';
|
|
4
|
+
|
|
5
|
+
describe('MongoUtils - #mockMongoose', () => {
|
|
6
|
+
/*
|
|
7
|
+
It is mandatory to create a new instance of MongoUtils to test the function mockMongoose as the singleton will keep its parameters instanced if used again. The parameter mongoMemServer, if instanciated by a first call,
|
|
8
|
+
won't be changed on a second one, as if the memory server is already mocked, nothing happens.
|
|
9
|
+
*/
|
|
10
|
+
it('should return a mongo memory server', async function() {
|
|
11
|
+
const mongoUtils = new MongoUtils();
|
|
12
|
+
const memServ = await mongoUtils.mockMongoose(this, null, false);
|
|
13
|
+
assert.isDefined(memServ);
|
|
14
|
+
assert.instanceOf(memServ, MongoMemoryServer);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('should return a mongo memory replica set', async function() {
|
|
18
|
+
const mongoUtils = new MongoUtils();
|
|
19
|
+
const memServ = await mongoUtils.mockMongoose(this, null, true);
|
|
20
|
+
assert.isDefined(memServ);
|
|
21
|
+
assert.instanceOf(memServ, MongoMemoryReplSet);
|
|
22
|
+
});
|
|
23
|
+
});
|