@wsst/egg-mongoose
Version:
egg mongoose plugin
205 lines (163 loc) • 5.88 kB
JavaScript
;
const assert = require('assert');
const path = require('path');
const mongoose = require('mongoose');
const awaitFirst = require('await-first');
const { MongoMemoryServer } = require('mongodb-memory-server');
const filterURLPassword = require('./filterURLPassword');
let count = 0;
module.exports = app => {
const { client, clients, url, options, defaultDB, customPromise, loadModel, plugins, mock } = app.config.mongoose;
// compatibility
if (!client && !clients && url) {
app.config.mongoose.client = {
url,
options,
};
}
mongoose.Promise = customPromise ? customPromise : Promise;
if (Array.isArray(plugins)) {
plugins.forEach(plugin => {
mongoose.plugin.apply(mongoose, Array.isArray(plugin) ? plugin : [ plugin ]);
});
}
// TODO addSingleton support config[this.configName]?
if (mock) {
app.config.mongoose.client = {
url,
options,
loadModel,
};
app.addSingleton('mongoose', createOneMockClient);
return;
}
app.addSingleton('mongoose', createOneClient);
app.mongooseDB = app.mongoose;
// set default connection(ref models has fixed in mongoose 4.13.7)
if (app.mongooseDB instanceof mongoose.Connection) {
mongoose.connection = app.mongooseDB;
} else if (defaultDB && app.mongooseDB.get(defaultDB) instanceof mongoose.Connection) {
mongoose.connection = app.mongooseDB.get(defaultDB);
}
app.mongoose = mongoose;
/* deprecated, next primary version remove */
app.__mongoose = mongoose;
app.mongoose.loadModel = () => loadModelToApp(app);
if (loadModel) {
app.beforeStart(() => {
loadModelToApp(app);
});
}
};
function createOneClient(config, app) {
const { url, options } = config;
const filteredURL = filterURLPassword(url);
assert(url, '[egg-mongoose] url is required on config');
// Notice we MUST add an option arg called `useNewUrlParser` and set to `true`
// in default, otherwises there'll be a warning since v4.X of mongodb.
// Ref: https://github.com/eggjs/egg/issues/3081
if (!options.hasOwnProperty('useNewUrlParser')) {
options.useNewUrlParser = true;
}
app.coreLogger.info('[egg-mongoose] connecting %s', filteredURL);
const db = mongoose.createConnection(url, options);
/* istanbul ignore next */
db.on('error', err => {
err.message = `[egg-mongoose]${err.message}`;
app.coreLogger.error(err);
});
/* istanbul ignore next */
db.on('disconnected', () => {
app.coreLogger.error(`[egg-mongoose] ${filteredURL} disconnected`);
});
db.on('connected', () => {
app.coreLogger.info(`[egg-mongoose] ${filteredURL} connected successfully`);
});
/* istanbul ignore next */
db.on('reconnected', () => {
app.coreLogger.info(`[egg-mongoose] ${filteredURL} reconnected successfully`);
});
app.beforeStart(function* () {
app.coreLogger.info('[egg-mongoose] starting...');
yield awaitFirst(db, [ 'connected', 'error' ]);
const index = count++;
/*
*remove heartbeat to avoid no authentication
const serverStatus = yield db.db.command({
serverStatus: 1,
});
assert(serverStatus.ok === 1, '[egg-mongoose] server status is not ok, please check mongodb service!');
*/
app.coreLogger.info(`[egg-mongoose] instance[${index}] start successfully`);
});
return db;
}
function loadModelToApp(app) {
const dir = path.join(app.config.baseDir, 'app/model');
app.loader.loadToApp(dir, 'model', {
inject: app,
caseStyle: 'upper',
filter(model) {
return typeof model === 'function' && model.prototype instanceof app.mongoose.Model;
},
});
}
async function createOneMockClient(config, app) {
let { url, options, loadModel } = config;
const filteredURL = filterURLPassword(url);
const mongoServer = new MongoMemoryServer();
url = await mongoServer.getUri();
assert(url, '[egg-mongoose] url is required on config');
// Notice we MUST add an option arg called `useNewUrlParser` and set to `true`
// in default, otherwises there'll be a warning since v4.X of mongodb.
// Ref: https://github.com/eggjs/egg/issues/3081
if (!options.hasOwnProperty('useNewUrlParser')) {
options.useNewUrlParser = true;
}
app.coreLogger.info('[egg-mongoose] connecting %s', filteredURL);
const db = mongoose.createConnection(url, options);
/* istanbul ignore next */
db.on('error', err => {
err.message = `[egg-mongoose]${err.message}`;
app.coreLogger.error(err);
});
/* istanbul ignore next */
db.on('disconnected', () => {
app.coreLogger.error(`[egg-mongoose] ${filteredURL} disconnected`);
});
db.on('connected', () => {
app.coreLogger.info(`[egg-mongoose] ${filteredURL} connected successfully`);
});
/* istanbul ignore next */
db.on('reconnected', () => {
app.coreLogger.info(`[egg-mongoose] ${filteredURL} reconnected successfully`);
});
app.beforeStart(function* () {
app.coreLogger.info('[egg-mongoose] starting...');
yield awaitFirst(db, [ 'connected', 'error' ]);
const index = count++;
/*
*remove heartbeat to avoid no authentication
const serverStatus = yield db.db.command({
serverStatus: 1,
});
assert(serverStatus.ok === 1, '[egg-mongoose] server status is not ok, please check mongodb service!');
*/
app.coreLogger.info(`[egg-mongoose] instance[${index}] start successfully`);
});
app.mongooseDB = db;
// set default connection(ref models has fixed in mongoose 4.13.7)
if (app.mongooseDB instanceof mongoose.Connection) {
mongoose.connection = app.mongooseDB;
}
app.mongoose = mongoose;
/* deprecated, next primary version remove */
app.__mongoose = mongoose;
app.mongoose.loadModel = () => loadModelToApp(app);
if (loadModel) {
app.beforeStart(() => {
loadModelToApp(app);
});
}
return mongoose;
}