Skip to content

Commit

Permalink
Merge pull request #45 from fabrix-app/v1.6
Browse files Browse the repository at this point in the history
[feat] fix local and global namespaces #43
  • Loading branch information
scott-wyatt authored Jun 5, 2019
2 parents f72bcc4 + 445ce0f commit 4b7ce11
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 35 deletions.
5 changes: 5 additions & 0 deletions lib/SequelizeResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export class SequelizeResolver extends FabrixResolver {
private _schema
private _sequelize
private _sequelizeModel
private _plugins

constructor (model: FabrixModel, datastore?: Sequelize) {
super(model)
Expand Down Expand Up @@ -37,6 +38,10 @@ export class SequelizeResolver extends FabrixResolver {
return this._sequelize
}

get plugins() {
return this._sequelize ? this._sequelize.plugins : new Set()
}

/**
* Get options provided to the model when connected
*/
Expand Down
2 changes: 1 addition & 1 deletion lib/SequelizeSpool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export class SequelizeSpool extends DatastoreSpool {
*/
configure() {
// This set tracks the plugins that are being added to a single sequelize instance
this._datastore['plugins'] = this._datastore['plugins'] || new Set()
this._datastore['plugins'] = this._datastore['plugins'] || new Map([['plugins', new Set()]])

this._plugins = Transformer.getPlugins(this.app)
// Holds a collection of the connections made through Sequelize
Expand Down
69 changes: 38 additions & 31 deletions lib/transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,29 +202,30 @@ export const Transformer = {

definePlugins(app: FabrixApp, store_config = {}, plugins = {}) {
const global_plugins = Object.keys(plugins)
const store_plugins = Object.keys(store_config).filter(n => {
if (global_plugins.indexOf(n) === -1) {
return n
}
})
const store_plugins = Object.keys(store_config)
const plugs = new Map()

global_plugins.forEach(n => {
plugs.set(n, plugins[n])
})

store_plugins.forEach(n => {
plugs.set(n, plugins[n])
plugs.set(n, store_config[n])
})

return plugs
},

/**
* Create Sequelize object based on config options
* @param {Object} app.config.store
* @param {FabrixApp} app
* @param {Sequelize} sequelize
* @param {String} name
* @param {Object} config from config.stores<n>
* @param {Object} plugins global plugins from config.sequelize
* @return {Sequelize} Sequelize instance
*/
createConnectionsFromConfig (app: FabrixApp, sequelize, config: {[key: string]: any}, plugins: {[key: string]: any} = {}) {
createConnectionsFromConfig (app: FabrixApp, sequelize, name, config: {[key: string]: any}, plugins: {[key: string]: any} = {}) {
const logger = function(val) {
// https://github.com/sequelize/sequelize/issues/3781#issuecomment-421282703
// If for whatever reason the Sequelize logger exports a Sequelize object, then, this must be done
Expand All @@ -236,11 +237,22 @@ export const Transformer = {

const plugs: Map<string, any> = Transformer.definePlugins(app, config.plugins, plugins)

// Resolve or Define Connection plugin namespace
if (!sequelize.plugins.has(name)) {
sequelize.plugins.set(name, new Set())
}

// Make a copy so plugins don't collide on multiple stores
let Seq = sequelize

// Quick check to see if sequelize is already started
if (Seq instanceof sequelize) {
throw new Error('Sequelize is already initialized and cannot be loaded again, check your plugins')
}

// For each of the defined plugs
plugs.forEach((plug, key, map) => {
if (!sequelize.plugins.has(key)) {
if (!sequelize.plugins.get('plugins').has(key) && !sequelize.plugins.get(name).has(key)) {
try {
if (typeof plug === 'function') {
Seq = plug(Seq)
Expand All @@ -251,52 +263,47 @@ export const Transformer = {
else {
app.log.debug(`Transformer: ${key} ${plug} was not a function or Fabrix sequelize object`)
}
sequelize.plugins.add(key)
sequelize.plugins.get('plugins').add(key)
sequelize.plugins.get(name).add(key)
}
catch (err) {
app.log.error(err)
console.log('BRK err', err)
app.log.error(`${key} plugin threw an error:`, err)
}
}
else {
app.log.debug(`Attempted to add ${ key } as a sequelize instance plugin more than once`)
}
})

// // Add plugins
// plugs.forEach((plug: any) => {
// try {
// if (typeof plug === 'function') {
// Seq = plug(Seq)
// }
// else if (typeof plug === 'object' && plug.func && plug.config) {
// Seq = plug.func(Seq, plug.config)
// }
// else {
// app.log.debug(`Transformer: ${plug} was not a function or Fabrix sequelize object`)
// }
// }
// catch (err) {
// app.log.error(err)
// }
// })
// Log out that the plugins were added
app.log.silly(`${ Array.from(sequelize.plugins.get(name))} installed on connection`)

// Based on the config, initialize the sequelize instance
if (config.uri) {
// Sequelize modify options object
return new Seq(config.uri, Object.assign({}, { logging: logger }, config))
Seq = new Seq(config.uri, Object.assign({}, { logging: logger }, config))
}
else {
return new Seq(
Seq = new Seq(
config.database,
config.username || process.env.POSTGRES_USER,
config.password || process.env.POSTGRES_PASSWORD,
// Sequelize modify options object
Object.assign({}, { logging: logger }, config)
)
}

// A handy way to see what plugins are loaded on the connection instance added to the resolver
Seq.plugins = sequelize.plugins.get(name)

return Seq
},

/**
* Pick only Sequelize SQL stores from app config
*/
// TODO, this is too greedy, it should likely just grab stores that define the orm.sequelize
pickStores (stores): {[key: string]: any} {
return pickBy(stores, (_store, name) => {
return ((_store.dialect && isString(_store.dialect) && _store.orm === 'sequelize')
Expand Down Expand Up @@ -326,7 +333,7 @@ export const Transformer = {
const stores = Transformer.pickStores(app.config.get('stores'))
const _sequelize = {}
Object.keys(stores).forEach(key => {
_sequelize[key] = Transformer.createConnectionsFromConfig(app, sequelize, stores[key], plugins)
_sequelize[key] = Transformer.createConnectionsFromConfig(app, sequelize, key, stores[key], plugins)
_sequelize[key].fabrixApp = app
_sequelize[key].migrate = stores[key].migrate
_sequelize[key].models = {}
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fabrix/spool-sequelize",
"version": "1.6.15",
"version": "1.6.16",
"description": "Spool - Datastore Spool for Sequelize.js http://sequelizejs.com",
"scripts": {
"build": "tsc -p ./lib/tsconfig.release.json",
Expand Down
8 changes: 8 additions & 0 deletions test/fixtures/testPlugin2.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,13 @@ module.exports = function(Sequelize, config) {
if (!Sequelize) {
Sequelize = require('sequelize')
}

if (Sequelize.prototype.helloEarth) {
throw new Error('PLUGIN WAS DOUBLED LOADED')
}
Sequelize.prototype.helloEarth = function() {
return 'hello earth'
}

return Sequelize
}
25 changes: 24 additions & 1 deletion test/integrations/spool.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,36 @@ describe('Spool', () => {
})
})

it('should be able to access the datastore service', (done) => {
it('should be able to access the datastore service on model 1', (done) => {
assert(global.app.models.testModel.resolver.datastore)
assert(global.app.models.testModel.resolver.sequelize)
assert(global.app.models.testModel.datastore)
assert(global.app.models.testModel.sequelize)
assert.equal(global.app.models.testModel.sequelize, global.app.models.testModel.resolver.sequelize)
assert.equal(global.app.models.testModel.instance, global.app.models.testModel.resolver.sequelizeModel)
assert(global.app.models.testModel.resolver.plugins)
done()
})

it('should be able to access the datastore service on model 2', (done) => {
assert(global.app.models.testModel2.resolver.datastore)
assert(global.app.models.testModel2.resolver.sequelize)
assert(global.app.models.testModel2.datastore)
assert(global.app.models.testModel2.sequelize)
assert.equal(global.app.models.testModel2.sequelize, global.app.models.testModel2.resolver.sequelize)
assert.equal(global.app.models.testModel2.instance, global.app.models.testModel2.resolver.sequelizeModel)
assert(global.app.models.testModel2.resolver.plugins)
done()
})

it('should be able to access the datastore service on model 3', (done) => {
assert(global.app.models.testModel3.resolver.datastore)
assert(global.app.models.testModel3.resolver.sequelize)
assert(global.app.models.testModel3.datastore)
assert(global.app.models.testModel3.sequelize)
assert.equal(global.app.models.testModel3.sequelize, global.app.models.testModel3.resolver.sequelize)
assert.equal(global.app.models.testModel3.instance, global.app.models.testModel3.resolver.sequelizeModel)
assert(global.app.models.testModel3.resolver.plugins)
done()
})

Expand Down
Empty file.
2 changes: 2 additions & 0 deletions test/unit/lib/transformer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ describe('lib.Transformer', () => {
const plugins = lib.Transformer.getPlugins(app)
const connections = lib.Transformer.getConnections(app, Sequelize, plugins)
const models = lib.Transformer.getModels(app, Sequelize, connections)

assert.ok(plugins)
assert.equal(Sequelize.prototype.helloWorld(), 'hello world')
assert.equal(Sequelize.prototype.helloEarth(), 'hello earth')
})
})

Expand Down

0 comments on commit 4b7ce11

Please sign in to comment.