ah-sequelize-plugin
Advanced tools
Comparing version 1.0.5 to 1.1.0
@@ -21,43 +21,57 @@ const path = require('path') | ||
this.umzug = new Umzug({ | ||
storage: 'sequelize', | ||
storageOptions: { | ||
sequelize: this.sequelize | ||
}, | ||
migrations: { | ||
params: [ | ||
this.sequelize.getQueryInterface(), | ||
this.sequelize.constructor, | ||
() => { | ||
throw new Error('Migration tried to use old style "done" callback. Please upgrade to "umzug" and return a promise instead.') | ||
}], | ||
path: path.join(api.projectRoot, 'migrations'), | ||
pattern: /\.js$/ | ||
} | ||
}) | ||
this.umzug = [] | ||
this.importMigrationsFromDirectory(config.migrationsDir || ['migrations']) | ||
} | ||
async connect () { | ||
const importModelsFromDirectory = (dir) => { | ||
fs.readdirSync(dir).forEach((file) => { | ||
const filename = path.join(dir, file) | ||
if (fs.statSync(filename).isDirectory()) { | ||
return importModelsFromDirectory(filename) | ||
} | ||
if (path.extname(file) !== '.js') return | ||
var nameParts = file.split('/') | ||
var name = nameParts[(nameParts.length - 1)].split('.')[0] | ||
var modelFunc = currySchemaFunc(require(filename)) | ||
this.sequelize.import(name, modelFunc) | ||
api.watchFileAndAct(filename, async () => { | ||
api.log(`*** Rebooting due to model change (${filename}) ***`, 'info') | ||
delete require.cache[require.resolve(filename)] | ||
delete this.sequelize.importCache[filename] | ||
await api.commands.restart() | ||
importMigrationsFromDirectory (dir) { | ||
(Array.isArray(dir) ? dir : [dir]) | ||
.map(dir => path.normalize(path.join(api.projectRoot, dir))) | ||
.forEach(dir => { | ||
this.umzug.push(new Umzug({ | ||
storage: 'sequelize', | ||
storageOptions: { | ||
sequelize: this.sequelize | ||
}, | ||
migrations: { | ||
params: [ | ||
this.sequelize.getQueryInterface(), | ||
this.sequelize.constructor, | ||
() => { | ||
throw new Error('Migration tried to use old style "done" callback. Please upgrade to "umzug" and return a promise instead.') | ||
}], | ||
path: dir, | ||
pattern: /\.js$/ | ||
} | ||
})) | ||
}) | ||
} | ||
importModelsFromDirectory (dir) { | ||
(Array.isArray(dir) ? dir : [dir]) | ||
.map(dir => path.normalize(path.join(api.projectRoot, dir))) | ||
.forEach(dir => { | ||
fs.readdirSync(dir).forEach(file => { | ||
const filename = path.join(dir, file) | ||
if (fs.statSync(filename).isDirectory()) { | ||
return this.importModelsFromDirectory(filename) | ||
} | ||
if (path.extname(file) !== '.js') return | ||
let nameParts = file.split('/') | ||
let name = nameParts[(nameParts.length - 1)].split('.')[0] | ||
let modelFunc = currySchemaFunc(require(filename)) | ||
this.sequelize.import(name, modelFunc) | ||
// watch model files for changes | ||
api.watchFileAndAct(filename, async () => { | ||
api.log(`*** Rebooting due to model change (${filename}) ***`, 'info') | ||
delete require.cache[require.resolve(filename)] | ||
delete this.sequelize.importCache[filename] | ||
await api.commands.restart() | ||
}) | ||
}) | ||
}) | ||
} | ||
} | ||
let dir = path.normalize(path.join(api.projectRoot, 'models')) | ||
importModelsFromDirectory(dir) | ||
async connect () { | ||
this.importModelsFromDirectory(config.modelsDir || 'models') | ||
api.models = this.sequelize.models | ||
@@ -81,3 +95,5 @@ await this.test() | ||
await checkMetaOldSchema() | ||
await this.umzug.execute(options) | ||
for (const umzug of this.umzug) { | ||
await umzug.execute(options) | ||
} | ||
} | ||
@@ -88,3 +104,5 @@ | ||
await checkMetaOldSchema() | ||
await this.umzug.up() | ||
for (const umzug of this.umzug) { | ||
await umzug.up() | ||
} | ||
} | ||
@@ -95,3 +113,5 @@ } | ||
await checkMetaOldSchema() | ||
await this.umzug.down() | ||
for (const umzug of this.umzug) { | ||
await umzug.down() | ||
} | ||
} | ||
@@ -98,0 +118,0 @@ |
@@ -6,3 +6,3 @@ { | ||
"description": "Use Sequelize in ActionHero", | ||
"version": "1.0.5", | ||
"version": "1.1.0", | ||
"homepage": "http://actionherojs.com", | ||
@@ -28,12 +28,13 @@ "repository": { | ||
"mkdirp": "^0.5.1", | ||
"umzug": "^2.0.1" | ||
"umzug": "^2.2.0" | ||
}, | ||
"devDependencies": { | ||
"actionhero": "^19.0.1", | ||
"chai": "^4.1.2", | ||
"actionhero": "^19.0.4", | ||
"chai": "^4.2.0", | ||
"cross-env": "^5.2.0", | ||
"dirty-chai": "^2.0.1", | ||
"mocha": "^5.2.0", | ||
"mysql2": "^1.5.3", | ||
"sequelize": "^4.37.8", | ||
"standard": "^11.0.1" | ||
"mysql2": "^1.6.4", | ||
"sequelize": "^4.41.2", | ||
"standard": "^12.0.1" | ||
}, | ||
@@ -45,3 +46,3 @@ "peerDependencies": { | ||
"scripts": { | ||
"test": "NODE_ENV=test mocha", | ||
"test": "cross-env NODE_ENV=test mocha", | ||
"pretest": "standard", | ||
@@ -48,0 +49,0 @@ "postinstall": "node scripts/postinstall.js" |
@@ -37,3 +37,3 @@ ![plugin](https://i.imgur.com/nd1btLt.png) | ||
### Add optional depenedencies | ||
### Add optional dependencies | ||
- For automatic fixures: `npm install sequelize-fixtures --save` | ||
@@ -46,2 +46,24 @@ - For Sequelize CLI: `npm install --save-dev sequelize-cli` | ||
To override the default location for models and/or migrations, use the `modelsDir` and `migrationsDir` configuration parameter with an array of paths relative to the project root. | ||
```javascript | ||
exports.default = { | ||
sequelize: (api) => { | ||
return { | ||
'autoMigrate': true, | ||
'loadFixtures': false, | ||
'database': 'DEVELOPMENT_DB', | ||
'dialect': 'mysql', | ||
'port': 3306, | ||
'host': '127.0.0.1', | ||
'username': 'root', | ||
'password': '', | ||
'modelsDir': ['models', 'plugins/acl-plugin/models'], // Default: ['models'] | ||
'migrationsDir': ['migrations', 'plugins/acl-plugin/migrations'] // Default: ['migrations'] | ||
} | ||
} | ||
} | ||
``` | ||
## [Models](http://docs.sequelizejs.com/en/latest/api/models) | ||
@@ -185,2 +207,2 @@ | ||
By default, `ah-sequelize-plugin` will **not** automatically load your fixtures when Actionhero starts up. You can enable this behaviour by adding `loadFixtures: true` to your sequelize config. | ||
By default, `ah-sequelize-plugin` will **not** automatically load your fixtures when Actionhero starts up. You can enable this behavior by adding `loadFixtures: true` to your sequelize config. |
module.exports = function (sequelize, DataTypes, api) { | ||
const model = sequelize.define('User', { | ||
id: { | ||
type: DataTypes.INTEGER.UNSIGNED, | ||
type: DataTypes.INTEGER, | ||
autoIncrement: true, | ||
@@ -22,5 +22,7 @@ primaryKey: true | ||
model.countEvans = function () { | ||
return model.count({where: { | ||
name: { [sequelize.Op.like]: '%evan%' } | ||
}}) | ||
return model.count({ | ||
where: { | ||
name: { [sequelize.Op.like]: '%evan%' } | ||
} | ||
}) | ||
} | ||
@@ -27,0 +29,0 @@ |
@@ -13,2 +13,4 @@ const fs = require('fs') | ||
const migrationsPath = path.join(process.env.PROJECT_ROOT, 'migrations') | ||
const pluginsPath = path.join(process.env.PROJECT_ROOT, 'plugins') | ||
const testPluginPath = path.join(pluginsPath, 'test-plugin') | ||
@@ -19,3 +21,3 @@ const actionhero = new ActionHero.Process() | ||
const configChanges = { | ||
plugins: {'ah-sequelize-plugin': { path: PACKAGE_PATH }} | ||
plugins: { 'ah-sequelize-plugin': { path: PACKAGE_PATH } } | ||
} | ||
@@ -34,6 +36,8 @@ | ||
describe('ah-sequelize-plugin', () => { | ||
describe('ah-sequelize-plugin', function () { | ||
this.timeout(100000) | ||
before(async () => { | ||
// copy configuration files | ||
await CopyFile(path.join(PACKAGE_PATH, 'config', 'sequelize.js'), path.join(process.env.PROJECT_ROOT, 'config', 'sequelize.js')) | ||
await CopyFile(path.join(PACKAGE_PATH, 'test', 'config', 'sequelize.js'), path.join(process.env.PROJECT_ROOT, 'config', 'sequelize.js')) | ||
await CopyFile(path.join(PACKAGE_PATH, 'config', '.sequelizerc'), path.join(process.env.PROJECT_ROOT, 'sequelizerc')) | ||
@@ -48,7 +52,17 @@ | ||
await CopyFile(path.join(PACKAGE_PATH, 'test', 'migrations', '01-createUsers.js'), path.join(process.env.PROJECT_ROOT, 'migrations', '01-createUsers.js')) | ||
// copy plugin model files | ||
if (!fs.existsSync(pluginsPath)) { fs.mkdirSync(pluginsPath) } | ||
if (!fs.existsSync(testPluginPath)) { fs.mkdirSync(testPluginPath) } | ||
if (!fs.existsSync(path.join(testPluginPath, 'models'))) { fs.mkdirSync(path.join(testPluginPath, 'models')) } | ||
await CopyFile(path.join(PACKAGE_PATH, 'test', 'plugins', 'test-plugin', 'models', 'post.js'), path.join(process.env.PROJECT_ROOT, 'plugins', 'test-plugin', 'models', 'post.js')) | ||
// copy plugin migration files | ||
if (!fs.existsSync(path.join(testPluginPath, 'migrations'))) { fs.mkdirSync(path.join(testPluginPath, 'migrations')) } | ||
await CopyFile(path.join(PACKAGE_PATH, 'test', 'plugins', 'test-plugin', 'migrations', '02-createPosts.js'), path.join(process.env.PROJECT_ROOT, 'plugins', 'test-plugin', 'migrations', '02-createPosts.js')) | ||
}) | ||
before(async () => { api = await actionhero.start({configChanges}) }) | ||
before(async () => { await api.models.User.truncate({force: true}) }) | ||
after(async () => { await api.models.User.truncate({force: true}) }) | ||
before(async () => { api = await actionhero.start({ configChanges }) }) | ||
before(async () => { await api.models.User.truncate({ force: true }) }) | ||
after(async () => { await api.models.User.truncate({ force: true }) }) | ||
after(async () => { await actionhero.stop() }) | ||
@@ -70,3 +84,4 @@ | ||
person.name = 'test person' | ||
await person.save() | ||
let { error } = await person.save() | ||
expect(error).to.not.exist() | ||
}) | ||
@@ -80,3 +95,3 @@ | ||
it('can read saved models', async () => { | ||
const person = await api.models.User.find({where: {email: 'hello@example.com'}}) | ||
const person = await api.models.User.findOne({ where: { email: 'hello@example.com' } }) | ||
expect(person.name).to.equal('test person') | ||
@@ -86,3 +101,3 @@ }) | ||
it('can update saved models', async () => { | ||
const person = await api.models.User.find({where: {email: 'hello@example.com'}}) | ||
const person = await api.models.User.findOne({ where: { email: 'hello@example.com' } }) | ||
person.name = 'a new name' | ||
@@ -95,3 +110,3 @@ await person.save() | ||
it('auto-adds timestamp columns to models', async () => { | ||
const person = await api.models.User.find({where: {email: 'hello@example.com'}}) | ||
const person = await api.models.User.findOne({ where: { email: 'hello@example.com' } }) | ||
expect(person.createdAt).to.be.below(new Date()) | ||
@@ -103,3 +118,3 @@ expect(person.updatedAt).to.be.below(new Date()) | ||
it('can use instance methods on models', async () => { | ||
const person = await api.models.User.find({where: {email: 'hello@example.com'}}) | ||
const person = await api.models.User.findOne({ where: { email: 'hello@example.com' } }) | ||
const apiData = person.apiData() | ||
@@ -138,3 +153,3 @@ expect(apiData.email).not.to.exist() | ||
it('can delete a model', async () => { | ||
const person = await api.models.User.find({where: {email: 'hello@example.com'}}) | ||
const person = await api.models.User.findOne({ where: { email: 'hello@example.com' } }) | ||
await person.destroy() | ||
@@ -146,7 +161,33 @@ let count = await api.models.User.count() | ||
it('can *really* delete a model', async () => { | ||
const person = await api.models.User.find({paranoid: false, where: {email: 'hello@example.com'}}) | ||
await person.destroy({force: true}) | ||
const person = await api.models.User.findOne({ paranoid: false, where: { email: 'hello@example.com' } }) | ||
await person.destroy({ force: true }) | ||
let count = await api.models.User.count() | ||
expect(count).to.equal(0) | ||
}) | ||
it('should have loaded plugin models', async () => { | ||
expect(api.models.Post).to.exist() | ||
let count = await api.models.Post.count() | ||
expect(count).to.equal(0) | ||
}) | ||
it('can create a plugin model instance (indicating the databse was migrated for plugin as well)', async () => { | ||
const post = new api.models.Post() | ||
post.title = 'You\'ll never guess what happened next!' | ||
let { error } = await post.save() | ||
expect(error).to.not.exist() | ||
}) | ||
it('can count newly saved plugin models', async () => { | ||
let count = await api.models.Post.count() | ||
expect(count).to.equal(1) | ||
}) | ||
it('can delete a plugin model', async () => { | ||
const post = await api.models.Post.findOne({ where: { title: 'You\'ll never guess what happened next!' } }) | ||
let { error } = await post.destroy() | ||
expect(error).to.not.exist() | ||
let count = await api.models.Post.count() | ||
expect(count).to.equal(0) | ||
}) | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
29923
16
536
206
8
15
Updatedumzug@^2.2.0