Skip to content

Instantly share code, notes, and snippets.

@waptik
Created June 21, 2019 02:51
Show Gist options
  • Save waptik/466e6403f4c880c5928b9bc3ba976750 to your computer and use it in GitHub Desktop.
Save waptik/466e6403f4c880c5928b9bc3ba976750 to your computer and use it in GitHub Desktop.
Mongoose import models the Sequelize way
'use strict';
const fs = require('fs');
const path = require('path');
const Mongoose = require('mongoose');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
if (config.database.url) {
Mongoose.connect(config.database.url, config.database.options);
} else if (config.database.config.dbName) {
Mongoose.connect(`${config.database.protocol}://${config.database.username}:${config.database.password}@${config.database.host}:${config.database.port}`, config.database.options);
} else {
Mongoose.connect(`${config.database.protocol}://${config.database.username}:${config.database.password}@${config.database.host}:${config.database.port}/${config.database.name}`, config.database.options);
}
const db = () => {
const m = {};
fs
.readdirSync(__dirname)
.filter(file => {
return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
})
.forEach(file => {
const model = importModels(path.join(__dirname, file));
// console.log('Model: ', model.modelName);
m[model.modelName] = model;
});
return m;
}
const models = db();
export const mongoose = Mongoose;
export default models;
/**
* Everything here is not to be touched
*/
function stack () {
const orig = Error.prepareStackTrace;
Error.prepareStackTrace = (_, stack) => stack;
const err = new Error();
Error.captureStackTrace(err, stack);
const errStack = err.stack;
Error.prepareStackTrace = orig;
return errStack;
}
/**
* Imports a model defined in another file. Imported models are cached, so multiple
* calls to import with the same path will not load the file multiple times.
*
* @credit https://github.com/sequelize/sequelize/blob/master/lib/sequelize.js#L466
*
* @param {string} importPath The path to the file that holds the model you want to import. If the part is relative, it will be resolved relatively to the calling file
*
* @returns {Model} Imported model, returned from cache if was already imported
*/
function importModels (importPath) {
// save imported models
const importCache = {};
// is it a relative path?
if (path.normalize(importPath) !== path.resolve(importPath)) {
// make path relative to the caller
const callerFilename = stack()[1].getFileName();
const callerPath = path.dirname(callerFilename);
importPath = path.resolve(callerPath, importPath);
}
if (!importCache[importPath]) {
let defineCall = arguments.length > 1 ? arguments[1] : require(importPath);
if (typeof defineCall === 'object') {
// ES6 module compatibility
defineCall = defineCall.default;
}
importCache[importPath] = defineCall(Mongoose);
}
return importCache[importPath];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment