diff --git a/.travis.yml b/.travis.yml index de28bad..c88f0f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: node_js node_js: -- '4' -- stable +- '8' +- '9' services: mongodb diff --git a/api/services/FootprintService.js b/api/services/FootprintService.js index 24e5a39..3e8d266 100644 --- a/api/services/FootprintService.js +++ b/api/services/FootprintService.js @@ -1,7 +1,4 @@ -'use strict' - const _ = require('lodash') -const Service = require('trails/service') /** * Trails Service that maps abstract ORM methods to their respective Waterine diff --git a/api/services/SchemaMigrationService.js b/api/services/SchemaMigrationService.js index cd7a40e..95be347 100644 --- a/api/services/SchemaMigrationService.js +++ b/api/services/SchemaMigrationService.js @@ -1,8 +1,3 @@ -'use strict' - -const _ = require('lodash') -const Service = require('trails/service') - /** * @module SchemaMigrationService * @description Schema Migrations @@ -16,9 +11,10 @@ module.exports = class SchemaMigrationService extends Service { */ drop (connection) { return Promise.all( - _.map(connection.collections, collection => { + Object.values(connection.collections).map(collection => { return new Promise((resolve, reject) => { - collection.drop((err) => { + collection.drop(err => { + if (err) return reject() resolve() }) }) @@ -31,4 +27,10 @@ module.exports = class SchemaMigrationService extends Service { alter (connection) { throw new Error('trailpack-mongoose does not currently support migrate=alter') } + + /** + * Do not perform any migrations. + */ + none () { + } } diff --git a/index.js b/index.js index fab523a..8119544 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,5 @@ -'use strict' - -const _ = require('lodash') const mongoose = require('mongoose') -const DatastoreTrailpack = require('trailpack-datastore') +const DatastoreTrailpack = require('trailpack/datastore') const lib = require('./lib') /** @@ -15,16 +12,13 @@ module.exports = class MongooseTrailpack extends DatastoreTrailpack { * Ensure that this trailpack supports the configured migration */ validate () { - if (!_.includes([ 'none', 'drop', 'create' ], this.app.config.database.models.migrate)) { - throw new Error('Migrate must be configured to either "create" or "drop"') - } } /** * Create default configuration */ configure () { - this.app.config.database.orm = 'mongoose' + this.app.config.set('stores.orm', 'mongoose') this.mongoose = mongoose } @@ -43,20 +37,21 @@ module.exports = class MongooseTrailpack extends DatastoreTrailpack { this.orm = this.orm || {} // Need to pick only mongoose stores - const stores = lib.Transformer.pickStores(this.app.config.database.stores) + const stores = lib.Transformer.pickStores(this.app.config.stores) // iterating only through mongo stores - this.connections = _.mapValues(stores, (_store, storeName) => { - const store = _.merge({ }, _store) - if (!_.isString(store.uri)) - throw new Error('Store have to contain "uri" option') + this.connections = new Map(Object.entries(stores).map(([ storeName, store ]) => { + store = Object.assign({ }, store) + + if (typeof store.uri !== 'string') + throw new Error('Store must contain "uri" option') - if (!_.isObject(store.options)) - store.options = {} + if (typeof store.options !== 'object') + store.options = { } const connection = mongoose.createConnection(store.uri, store.options) - const models = _.pickBy(this.models, { connection: storeName }) + const models = Object.values(this.models).filter(m => m.connection === storeName) - _.map(models, model => { + models.forEach(model => { const schema = new mongoose.Schema(model.schema, model.schemaOptions) // Bind statics & methods schema.statics = model.statics @@ -66,11 +61,11 @@ module.exports = class MongooseTrailpack extends DatastoreTrailpack { //create model this.orm[model.globalId] = connection.model(model.globalId, schema, model.tableName) - this.packs.mongoose.orm[model.identity] = this.orm[model.globalId] + this.orm[model.identity] = this.orm[model.globalId] }) - return connection - }) + return [ storeName, connection ] + })) this.app.orm = this.orm @@ -81,18 +76,17 @@ module.exports = class MongooseTrailpack extends DatastoreTrailpack { * Close all database connections */ unload () { - return Promise.all( - _.map(this.connections, connection => { - return new Promise((resolve, reject) => { - connection.close((err) => { - if (err) - return reject(err) - - resolve() - }) + const closeConnections = [ ] + this.connections.forEach(connection => { + closeConnections.push(new Promise((resolve, reject) => { + connection.close((err) => { + if (err) return reject(err) + resolve() }) - }) - ) + })) + }) + + return Promise.all(closeConnections) } constructor (app) { @@ -108,15 +102,16 @@ module.exports = class MongooseTrailpack extends DatastoreTrailpack { */ migrate () { const SchemaMigrationService = this.app.services.SchemaMigrationService - const database = this.app.config.database - if (database.models.migrate == 'none') return + if (this.app.config.get('stores.models.migrate') == 'none') return - return Promise.all( - _.map(this.connections, connection => { - if (database.models.migrate == 'drop') { - return SchemaMigrationService.drop(connection) - } - })) + const migrations = [ ] + this.connections.forEach((connection, storeName) => { + const migrateMethod = this.app.config.get(`stores.${storeName}.migrate`) + //console.log('migrating with migrate method', migrateMethod) + migrations.push(SchemaMigrationService[migrateMethod](connection)) + }) + + return Promise.all(migrations) } } diff --git a/lib/transformer.js b/lib/transformer.js index 71a7683..9a0494f 100644 --- a/lib/transformer.js +++ b/lib/transformer.js @@ -1,7 +1,3 @@ -'use strict' - -const _ = require('lodash') - module.exports = { /** @@ -10,9 +6,9 @@ module.exports = { * @return {Object} */ pickStores (stores) { - return _.pickBy(stores, (_store, name) => { - return (_.isString(_store.uri) && _.startsWith(_store.uri, 'mongodb://')) - }) + return Object.entries(stores) + .filter(([ , store ]) => /^mongodb:\/\//.test(store.uri)) + .reduce((stores, [ storeName, store ]) => Object.assign(stores, { [storeName]: store }), { }) }, /** @@ -21,27 +17,27 @@ module.exports = { * @return {Object} */ transformModels (app) { - const models = app.models - const dbConfig = app.config.database - return _.mapValues(models, (model, modelName) => { - const config = model.constructor.config(app, require('mongoose')) || { } - const schema = model.constructor.schema(app, require('mongoose')) || { } - const onSchema = config.onSchema || _.noop - - return { - identity: modelName.toLowerCase(), - globalId: modelName, - tableName: config.tableName || modelName.toLowerCase(), - connection: config.store || dbConfig.models.defaultStore, - migrate: config.migrate || dbConfig.models.migrate, - schema: schema, - schemaOptions: config.schema, - statics: config.statics || {}, - methods: config.methods || {}, - onSchema: onSchema - } + return Object.entries(app.models) + .map(([ modelName, model ]) => { + const modelConfig = model.constructor.config(app, require('mongoose')) || { } + const storeConfig = app.config.get(`stores.${modelConfig.store}`) + const schema = model.constructor.schema(app, require('mongoose')) || { } + const onSchema = modelConfig.onSchema || function () { } - }) + return { + identity: modelName.toLowerCase(), + globalId: modelName, + tableName: modelConfig.tableName || modelName.toLowerCase(), + connection: modelConfig.store, + migrate: modelConfig.migrate || storeConfig.migrate, + schema: schema, + schemaOptions: modelConfig.schema, + statics: modelConfig.statics || {}, + methods: modelConfig.methods || {}, + onSchema: onSchema + } + }) + .reduce((models, model) => Object.assign(models, { [model.globalId]: model }), { }) } } diff --git a/package.json b/package.json index 8d394a2..bdb1ee6 100644 --- a/package.json +++ b/package.json @@ -21,15 +21,13 @@ } ], "dependencies": { - "lodash": "^4.0.0", "mongoose": "^4.7.7", - "trailpack": "2.1.0", - "trailpack-datastore": "2.0.0" + "trailpack": "^3" }, "devDependencies": { "chai": "^3.5.0", "eslint": "3.13.1", - "eslint-config-trails": "2.0.6", + "eslint-config-trails": "^3", "mocha": "3.2.0", "smokesignals": "2.1.0", "trails": "2.0.0" diff --git a/test/app.js b/test/app.js index 86d23f3..9e28a5b 100644 --- a/test/app.js +++ b/test/app.js @@ -1,11 +1,8 @@ -'use strict' - -const _ = require('lodash') const smokesignals = require('smokesignals') const User = require('./model/User') const Role = require('./model/Role') -module.exports = _.defaultsDeep({ +module.exports = Object.assign(smokesignals.FailsafeConfig, { pkg: { name: 'mongoose-trailpack-test' }, @@ -24,29 +21,26 @@ module.exports = _.defaultsDeep({ require('../') // trailpack-mongoose ] }, - database: { - stores: { - teststore: { - uri: 'mongodb://localhost:27017/test', - options: { + stores: { + teststore: { + migrate: 'drop', + uri: 'mongodb://localhost:27017/test', + options: { - } - }, - storeoverride: { - uri: 'mongodb://localhost:27017/test2', - options: { + } + }, + storeoverride: { + migrate: 'drop', + uri: 'mongodb://localhost:27017/test2', + options: { - } - }, - notMongoStore: { - uri: 'postgres://localhost:5432/tests', - options: {} } }, - models: { - defaultStore: 'teststore', - migrate: 'drop' + notMongoStore: { + migrate: 'drop', + uri: 'postgres://localhost:5432/tests', + options: {} } } } -}, smokesignals.FailsafeConfig) +}) diff --git a/test/lib/transformer.test.js b/test/lib/transformer.test.js index b58a170..1000127 100644 --- a/test/lib/transformer.test.js +++ b/test/lib/transformer.test.js @@ -39,7 +39,7 @@ describe('lib.Transformer', () => { describe('#pickStores', () => { it('should pick only stores for mongo', () => { - const stores = lib.Transformer.pickStores(global.app.config.database.stores) + const stores = lib.Transformer.pickStores(global.app.config.stores) assert.equal(typeof stores, 'object') assert.deepEqual(Object.keys(stores), [ 'teststore', 'storeoverride' ]) }) diff --git a/test/model/Role.js b/test/model/Role.js index 4d299b6..a506376 100644 --- a/test/model/Role.js +++ b/test/model/Role.js @@ -1,4 +1,3 @@ -'use strict' const Model = require('trails/model') const Schema = require('mongoose').Schema diff --git a/test/model/User.js b/test/model/User.js index cc47875..e95b36f 100644 --- a/test/model/User.js +++ b/test/model/User.js @@ -1,4 +1,3 @@ -'use strict' const Model = require('trails/model') const Schema = require('mongoose').Schema @@ -40,6 +39,7 @@ module.exports = class User extends Model { static config(app, Mongoose) { return { + store: 'teststore', schema: { timestamps: true, versionKey: false diff --git a/test/services/FootprintService.test.js b/test/services/FootprintService.test.js index bb8bf29..9a8ef11 100644 --- a/test/services/FootprintService.test.js +++ b/test/services/FootprintService.test.js @@ -1,7 +1,4 @@ -'use strict' - const assert = require('assert') -const _ = require('lodash') describe('api.services.FootprintService', () => { @@ -117,7 +114,7 @@ describe('api.services.FootprintService', () => { return FootprintService.destroy('Role', role.id) }) .then(role => { - assert(_.isObject(role)) + assert.equal(typeof role, 'object') assert.equal(role.name, 'destroytestid') return FootprintService.find('Role', { name: 'destroytestid' }) }) @@ -174,7 +171,7 @@ describe('api.services.FootprintService', () => { .then((rec) => { assert(rec) assert.equal(rec.id, user.id) - assert(_.isArray(rec.roles)) + assert(Array.isArray(rec.roles)) assert.equal(rec.roles.length, 1) assert.equal(rec.roles[0], role.id) }) @@ -192,7 +189,7 @@ describe('api.services.FootprintService', () => { .then((rec) => { assert(rec) assert.equal(rec.id, user.id) - assert(_.isArray(rec.superRoles)) + assert(Array.isArray(rec.superRoles)) assert.equal(rec.superRoles.length, 1) assert.equal(rec.superRoles[0], role.id) }) @@ -232,7 +229,7 @@ describe('api.services.FootprintService', () => { .then((rec) => { assert(rec) assert.equal(rec.id, user.id) - assert(_.isArray(rec.roles)) + assert(Array.isArray(rec.roles)) // We have 1 record added in prev test // So need to look into last one assert.equal(rec.roles.length, 2) @@ -269,7 +266,7 @@ describe('api.services.FootprintService', () => { return FootprintService .findAssociation('User', user._id, 'role') // eslint-disable-line .then((list) => { - assert(_.isArray(list)) + assert(Array.isArray(list)) assert.equal(list.length, 1) assert.equal(list[0]._id.toString(), role._id.toString()) // eslint-disable-line }) diff --git a/test/trailpack.test.js b/test/trailpack.test.js index 6905af9..720a2aa 100644 --- a/test/trailpack.test.js +++ b/test/trailpack.test.js @@ -1,5 +1,3 @@ -'use strict' - const assert = require('assert') describe('Mongoose Trailpack', () => { @@ -19,8 +17,8 @@ describe('Mongoose Trailpack', () => { }) it('should load and transform connections', () => { assert(pack.connections) - assert(pack.connections.teststore) - assert(pack.connections.storeoverride) + assert(pack.connections.get('teststore')) + assert(pack.connections.get('storeoverride')) }) }) diff --git a/test/unit/services/SchemaMigrationService.test.js b/test/unit/services/SchemaMigrationService.test.js index 2132885..342edc6 100644 --- a/test/unit/services/SchemaMigrationService.test.js +++ b/test/unit/services/SchemaMigrationService.test.js @@ -1,6 +1,5 @@ /* global describe, it */ -const _ = require('lodash') const assert = require('assert') describe('SchemaMigrationService', () => { @@ -9,7 +8,7 @@ describe('SchemaMigrationService', () => { }) describe('#create', () => { it('should create collections', () => { - return Promise.all(_.map(global.app.models, model => { + return Promise.all(Object.values(global.app.models).map(model => { return Promise.resolve() })) })