Created
October 18, 2017 01:27
-
-
Save jlsan92/0e4cc9e66949b5f9a8778a04f91e158c to your computer and use it in GitHub Desktop.
Mongoose Sails Hook
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const _ = require('lodash'); | |
const mongoose = require('mongoose'); | |
const Promise = require('bluebird'); | |
const Schema = mongoose.Schema; | |
const ORM_NAME = 'mongoose'; | |
module.exports = function mongooseOrm(sails) { | |
return { | |
defaults: { | |
__configKey__: { | |
connection: { | |
url: 'mongodb://localhost/test', | |
options: {}, | |
}, | |
schemas: { | |
renameFields: { _id: 'id' }, | |
hiddenFields: ['password'], | |
options: { | |
versionKey: false, | |
timestamps: true, | |
}, | |
}, | |
plugins: [], | |
}, | |
}, | |
_transform(rename, hidden) { | |
return { | |
toJSON(doc, ret) { | |
_.forEach(hidden, (field) => { | |
delete ret[field]; | |
}); | |
ret = JSON.stringify(ret); | |
_.forEach(rename, (newName, oldName) => { | |
oldName = new RegExp(`"${oldName}":`, 'g'); | |
ret = _.replace(ret, oldName, `"${newName}":`); | |
}); | |
return JSON.parse(ret); | |
}, | |
toObject(doc, ret) { | |
_.forEach(rename, (newName, oldName) => { | |
ret[newName] = doc[oldName]; | |
}); | |
}, | |
}; | |
}, | |
configure() { | |
sails.Schema = Schema; | |
}, | |
initialize(next) { | |
const config = sails.config[this.configKey]; | |
mongoose.Promise = Promise; | |
const connection = | |
mongoose.connect(config.connection.url, config.connection.options).connection; | |
const self = this; | |
// Error instantiating mongoose | |
connection.once('error', (err) => { | |
sails.log.error(err); | |
return next(err); | |
}); | |
// Connected successfully | |
connection.once('open', () => { | |
try { | |
config.plugins.forEach((plugin) => { | |
const type = typeof plugin; | |
if (type === 'object' && plugin != null) { | |
mongoose.plugin(type.plugin, type.options || {}); | |
} else if (type === 'function') { | |
mongoose.plugin(plugin); | |
} | |
}); | |
} catch (e) { | |
return next(e); | |
} | |
// Load model definitions using module loader | |
return sails.modules.loadModels((err, models) => { | |
if (err) { | |
sails.log.error(err); | |
return next(err); | |
} | |
try { | |
// Expand only mongoose models | |
if (!sails.models) { | |
sails.models = {}; | |
} | |
// Instantiate Mongoose schemas for each model definition | |
Object.assign(sails.models, _.reduce(models, (result, value, key) => { | |
if (value.orm !== ORM_NAME) { | |
return result; | |
} | |
value.schema = value.schema || {}; | |
value.plugins = value.plugins || []; | |
value.options = Object.assign(value.options || {}, config.schemas.options); | |
// Add default transform to each schema if not defined | |
if (!value.options.toJSON || !value.options.toJSON.transform) { | |
const renameFields = | |
Object.assign(value.renameFields || {}, config.schemas.renameFields); | |
const hiddenFields = _.union(value.hiddenFields || [], config.schemas.hiddenFields); | |
const transform = self._transform(renameFields, hiddenFields); | |
value.options.toJSON = value.options.toJSON || {}; | |
value.options.toJSON.transform = transform.toJSON; | |
if (!value.options.toObject || !value.options.toObject.transform) { | |
value.options.toObject = value.options.toObject || {}; | |
value.options.toObject.transform = transform.toObject; | |
} | |
} | |
// Create Mongoose's schema | |
const schemaObj = new Schema(value.schema, value.options); | |
schemaObj.statics = value; | |
schemaObj.methods = value.methods || {}; | |
if (value.indexes) { | |
value.indexes.forEach(index => schemaObj.index(index.fields, index.options || {})); | |
} | |
// Configure existing plugins in current schema | |
value.plugins.forEach((plugin) => { | |
const type = typeof plugin; | |
if (type === 'object' && plugin != null) { | |
schemaObj.plugin(plugin.plugin, plugin.options || {}); | |
} else if (type === 'function') { | |
schemaObj.plugin(plugin); | |
} | |
}); | |
const collectionName = value.collectionName ? | |
value.collectionName : | |
value.globalId; | |
result[key] = mongoose.model(collectionName, schemaObj); | |
result[key].globalId = value.globalId; | |
result[key].identity = value.identity; | |
return result; | |
}, {})); | |
// Expose the models globally | |
if (_.isObject(sails.config.globals) && sails.config.globals.models) { | |
_.each(sails.models, (Model, key) => { | |
if (models[key].orm === ORM_NAME) { | |
global[Model.globalId] = Model; | |
} | |
}); | |
} | |
return next(); | |
} catch (e) { | |
return next(e); | |
} | |
}); | |
}); | |
}, | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment