knextancy
Advanced tools
Comparing version 2.3.1 to 2.4.0
@@ -15,52 +15,50 @@ 'use strict'; | ||
exports.default = function (baseKnex, options) { | ||
var opts = options || {}; | ||
var header = opts.header || 'x-client-id'; | ||
exports.default = function (setupTenant) { | ||
return function (baseKnex, options) { | ||
var opts = options || {}; | ||
var header = opts.header || 'x-client-id'; | ||
return function () { | ||
var _ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(req, res, next) { | ||
var tenantId; | ||
return _regenerator2.default.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
tenantId = req.header(header); | ||
return function () { | ||
var _ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(req, res, next) { | ||
var tenantId; | ||
return _regenerator2.default.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
tenantId = req.header(header); | ||
if (!(typeof tenantId === 'undefined')) { | ||
_context.next = 3; | ||
break; | ||
} | ||
if (!(typeof tenantId === 'undefined')) { | ||
_context.next = 3; | ||
break; | ||
} | ||
return _context.abrupt('return', next('Missing ' + header + ' header')); | ||
return _context.abrupt('return', next('Missing ' + header + ' header')); | ||
case 3: | ||
_context.next = 5; | ||
return (0, _tenant2.default)(baseKnex, tenantId); | ||
case 3: | ||
_context.next = 5; | ||
return setupTenant(baseKnex, tenantId); | ||
case 5: | ||
req.knex = _context.sent; | ||
case 5: | ||
req.knex = _context.sent; | ||
next(); | ||
next(); | ||
case 7: | ||
case 'end': | ||
return _context.stop(); | ||
case 7: | ||
case 'end': | ||
return _context.stop(); | ||
} | ||
} | ||
} | ||
}, _callee, this); | ||
})); | ||
}, _callee, this); | ||
})); | ||
function middleware(_x, _x2, _x3) { | ||
return _ref.apply(this, arguments); | ||
} | ||
function middleware(_x, _x2, _x3) { | ||
return _ref.apply(this, arguments); | ||
} | ||
return middleware; | ||
}(); | ||
return middleware; | ||
}(); | ||
}; | ||
}; | ||
var _tenant = require('./tenant'); | ||
var _tenant2 = _interopRequireDefault(_tenant); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } |
'use strict'; | ||
var _fetchTenants = require('./fetch-tenants'); | ||
var _fetchTenants2 = _interopRequireDefault(_fetchTenants); | ||
var _tenant = require('./tenant'); | ||
@@ -11,2 +15,6 @@ | ||
var _setupAllTenants = require('./setup-all-tenants'); | ||
var _setupAllTenants2 = _interopRequireDefault(_setupAllTenants); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -16,4 +24,6 @@ | ||
module.exports = { | ||
fetchTenants: _fetchTenants2.default, | ||
tenant: _tenant2.default, | ||
middleware: _connectMiddleware2.default | ||
middleware: (0, _connectMiddleware2.default)(_tenant2.default), | ||
setupAllTenants: (0, _setupAllTenants2.default)(_tenant2.default, _fetchTenants2.default) | ||
}; |
@@ -51,3 +51,4 @@ 'use strict'; | ||
// custom migration with the table name prefix | ||
multitenantConfig.migrations.tableName = tenantId + '_' + (multitenantConfig.migrations.tableName || 'knex_migrations'); | ||
var tableName = multitenantConfig.migrations.tableName || 'knex_migrations'; | ||
multitenantConfig.migrations.tableName = tenantId + '_' + tableName; | ||
@@ -54,0 +55,0 @@ return multitenantConfig; |
{ | ||
"name": "knextancy", | ||
"version": "2.3.1", | ||
"version": "2.4.0", | ||
"description": "Small library that provides a way of implementing multi-tenancy using table prefixes.", | ||
@@ -10,4 +10,6 @@ "main": "lib/index.js", | ||
"lint": "eslint src/ spec/", | ||
"test": "npm run lint && NODE_ENV=test mocha --compilers js:babel-core/register --timeout 30000 --reporter spec --recursive --watch-extensions .spec.js ./spec", | ||
"waitdb": "waitforit -full-connection $DB_PORT -timeout 60", | ||
"test": "npm run test:mysql && npm run test:postgres", | ||
"test:mysql": "npm run lint && DB_CLIENT=mysql NODE_ENV=test mocha --compilers js:babel-core/register --timeout 30000 --reporter spec --recursive --watch-extensions .spec.js ./spec", | ||
"test:postgres": "npm run lint && DB_CLIENT=postgres NODE_ENV=test mocha --compilers js:babel-core/register --timeout 30000 --reporter spec --recursive --watch-extensions .spec.js ./spec", | ||
"waitdb": "waitforit -full-connection $POSTGRES_PORT -timeout 60 && waitforit -full-connection $MYSQL_PORT -timeout 60", | ||
"waitdb-test": "npm run waitdb && npm test" | ||
@@ -55,6 +57,9 @@ }, | ||
"knex": "^0.11.0", | ||
"knex-spec-helper": "^0.1.2", | ||
"mocha": "^2.4.5", | ||
"mysql": "^2.5.2", | ||
"pg": "^6.1.0", | ||
"sinon": "^1.17.6", | ||
"supertest": "^0.14.0" | ||
} | ||
} |
@@ -82,2 +82,26 @@ # Knextancy - knex with multitenancy | ||
## Setup All Tenants | ||
Allow execute all migrations/seed for all existing tenants at once. | ||
Bellow is a usage example: | ||
```js | ||
knextancy.setupAllTenants(knex).then(function () { | ||
// done | ||
}); | ||
``` | ||
## Fetch Tenants | ||
Based in the migration tables in the current database is possible to fetch the existing tenants. | ||
Bellow is a usage example: | ||
```js | ||
knextancy.fetchTenants(knex).then(function (tenants) { | ||
// ['01', '02'] | ||
}); | ||
``` | ||
## Tests | ||
@@ -84,0 +108,0 @@ |
import url from 'url'; | ||
const client = process.env.DB_CLIENT; | ||
function getEnv(type) { | ||
const name = client.toUpperCase(); | ||
return process.env[`${name}_${type}`] || process.env[`${name}_ENV_${name}_${type}`]; | ||
} | ||
const address = url.parse(process.env.DB_PORT || getEnv('PORT')); | ||
export default { | ||
test: { | ||
client: 'mysql', | ||
client: client === 'postgres' ? 'pg' : client, | ||
connection: { | ||
multipleStatements: true, | ||
host: url.parse(process.env.DB_PORT).hostname, | ||
port: url.parse(process.env.DB_PORT).port, | ||
user: process.env.DB_USER || process.env.DB_ENV_MYSQL_USER, | ||
password: process.env.DB_PASSWORD || process.env.DB_ENV_MYSQL_PASSWORD, | ||
database: process.env.DB_DATABASE || process.env.DB_ENV_MYSQL_DATABASE, | ||
host: address.hostname, | ||
port: address.port, | ||
user: process.env.DB_USER || getEnv('USER'), | ||
password: process.env.DB_PASSWORD || getEnv('PASSWORD'), | ||
database: process.env.DB_DATABASE || getEnv('DB') || getEnv('DATABASE'), | ||
}, | ||
@@ -15,0 +24,0 @@ migrations: { |
// setup ES6 Proxy shim | ||
require('harmony-reflect'); | ||
import knexSpecHelper from 'knex-spec-helper'; | ||
import { readFileSync } from 'fs'; | ||
import { join } from 'path'; | ||
import knexConfig from './fixtures/knexfile'; | ||
const truncateTablesSQL = readFileSync(join(__dirname, './spec-helper.sql'), { encoding: 'utf8' }); | ||
export const knex = require('knex')(knexConfig.test); | ||
beforeEach(function() { | ||
return truncateAllTables(); | ||
beforeEach(async function () { | ||
this.knex = await knexSpecHelper.setup({ | ||
knexConfig: knexConfig.test, | ||
knextancyEnabled: false, | ||
truncateEnabled: true, | ||
}); | ||
}); | ||
function truncateAllTables () { | ||
return knex.raw(truncateTablesSQL).then(function (sql) { | ||
const _sqlQuery = sql[0].map(function (sqlQuery) { | ||
return sqlQuery.trucate_table_cmd; | ||
}).join(''); | ||
return knex.raw(_sqlQuery); | ||
}); | ||
} | ||
export default { | ||
knex: knex, | ||
}; |
@@ -40,25 +40,28 @@ import { knex } from './spec-helper'; | ||
it('should return the result without the tenant ids in the table names', function () { | ||
return knextancy.tenant(knex, '01').then(function (tenantKnex) { | ||
return tenantKnex | ||
.select() | ||
.from('$_users') | ||
.leftJoin('$_roles', '$_users.role_id', '$_roles.id') | ||
.options({ nestTables: true }) | ||
.then(function (result) { | ||
expect(result).to.eql([{ | ||
'$_roles': { | ||
'id': 1, | ||
'name': 'Admin', | ||
}, | ||
'$_users': { | ||
'id': 1, | ||
'name': 'Paulo', | ||
'role_id': 1, | ||
}, | ||
}]); | ||
}); | ||
// Seems only mysql has support for "nestTables" | ||
if (process.env.DB_CLIENT === 'mysql') { | ||
it('should return the result without the tenant ids in the table names', function () { | ||
return knextancy.tenant(knex, '01').then(function (tenantKnex) { | ||
return tenantKnex | ||
.select() | ||
.from('$_users') | ||
.leftJoin('$_roles', '$_users.role_id', '$_roles.id') | ||
.options({ nestTables: true }) | ||
.then(function (result) { | ||
expect(result).to.eql([{ | ||
'$_roles': { | ||
'id': 1, | ||
'name': 'Admin', | ||
}, | ||
'$_users': { | ||
'id': 1, | ||
'name': 'Paulo', | ||
'role_id': 1, | ||
}, | ||
}]); | ||
}); | ||
}); | ||
}); | ||
}); | ||
} | ||
}); | ||
}); |
@@ -5,2 +5,6 @@ import { knex } from './spec-helper'; | ||
function wrap(text) { | ||
const identifier = process.env.DB_CLIENT === 'mysql' ? '`' : '"'; | ||
return `${identifier}${text}${identifier}`; | ||
} | ||
@@ -17,4 +21,4 @@ describe('tenant raw queries', function() { | ||
return knextancy.tenant(knex, '10').then(function (tenantKnex) { | ||
return tenantKnex.raw('select * from `$_users`').then(function (result) { | ||
const users = result[0]; | ||
return tenantKnex.raw(`select * from ${wrap('$_users')}`).then(function (result) { | ||
const users = result.rows || result[0]; | ||
expect(users.length).to.eql(1); | ||
@@ -27,4 +31,4 @@ }); | ||
return knextancy.tenant(knex, '20').then(function (tenantKnex) { | ||
return tenantKnex.raw('select * from `$_users`').then(function (result) { | ||
const users = result[0]; | ||
return tenantKnex.raw(`select * from ${wrap('$_users')}`).then(function (result) { | ||
const users = result.rows || result[0]; | ||
expect(users.length).to.eql(0); | ||
@@ -31,0 +35,0 @@ }); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
36838
30
755
119
18