diff --git a/src/config/db.js b/src/config/db.js index 50738a43..3c09a593 100644 --- a/src/config/db.js +++ b/src/config/db.js @@ -1,8 +1,11 @@ +/* eslint-disable import/no-dynamic-require */ + 'use strict'; const fs = require('fs'); const path = require('path'); +const _ = require('lodash'); const hasOwn = require('has-own'); const die = require('../util/die'); @@ -21,22 +24,40 @@ if (homeDir) { if (fs.statSync(databasePath).isDirectory()) { let databaseConfig = {}; if (fs.existsSync(databaseConfigPath)) { - // eslint-disable-next-line import/no-dynamic-require databaseConfig = require(databaseConfigPath); const designDocNames = {}; databaseConfig.designDocNames = []; - if ( - databaseConfig.customDesign && - databaseConfig.customDesign.views - ) { - const views = databaseConfig.customDesign.views; - for (const key in views) { - if (hasOwn(key, views)) { - if (!views[key].designDoc) { - views[key].designDoc = constants.CUSTOM_DESIGN_DOC_NAME; - } - designDocNames[key] = views[key].designDoc; + databaseConfig.customDesign = databaseConfig.customDesign || {}; + databaseConfig.customDesign.views = + databaseConfig.customDesign.views || {}; + const views = databaseConfig.customDesign.views; + + // Get views from views folder + let viewFiles; + try { + viewFiles = fs.readdirSync(path.join(databasePath, 'views')); + } catch (e) { + viewFiles = []; + } + + for (let view of viewFiles) { + const v = require(path.join(databasePath, 'views', view)); + const currentKeys = Object.keys(views); + const newKeys = Object.keys(v); + const intersectionKeys = _.intersection(currentKeys, newKeys); + if (intersectionKeys.length !== 0) { + throw new Error( + `a view is defined more than once: ${intersectionKeys}` + ); + } + Object.assign(views, v); + } + for (const key in views) { + if (hasOwn(key, views)) { + if (!views[key].designDoc) { + views[key].designDoc = constants.CUSTOM_DESIGN_DOC_NAME; } + designDocNames[key] = views[key].designDoc; } } databaseConfig.designDocNames = designDocNames; @@ -53,7 +74,7 @@ if (homeDir) { } } catch (e) { console.error(e.stack || e); // eslint-disable-line no-console - die(`could not read database configurations from ${homeDir}`); + die(`could not read database configurations from ${homeDir}, ${e.message}`); } } @@ -66,7 +87,6 @@ function readImportConfig(databasePath, databaseConfig) { if (fs.statSync(importPath).isDirectory()) { let importConfig = {}; if (fs.existsSync(importConfigPath)) { - // eslint-disable-next-line import/no-dynamic-require importConfig = require(importConfigPath); } if (typeof importConfig === 'function') { diff --git a/test/homedir/test3/config.js b/test/homedir/test3/config.js index c6509cc1..fb2124a1 100644 --- a/test/homedir/test3/config.js +++ b/test/homedir/test3/config.js @@ -1,35 +1,27 @@ 'use strict'; module.exports = { - customDesign: { - version: 8, - views: { - lib: { - test: ['lib.js'] - }, - test: { - map: function (doc) { - const libTest = require('views/lib/test'); - if (doc.$type === 'entry') { - emit(doc._id, libTest.fortyTwo()); - } - } - }, - testCustom: { - map: function (doc) { - if (doc.$type === 'entry') { - emit(doc._id); - } - }, - designDoc: 'custom' - } - }, - updates: {}, - filters: { - abc: function (doc) { - return doc.$type === 'log'; - } + customDesign: { + version: 8, + views: { + lib: { + test: ['lib.js'] + }, + test: { + map: function (doc) { + const libTest = require('views/lib/test'); + if (doc.$type === 'entry') { + emit(doc._id, libTest.fortyTwo()); + } } + } }, - entryUnicity: 'global' + updates: {}, + filters: { + abc: function (doc) { + return doc.$type === 'log'; + } + } + }, + entryUnicity: 'global' }; diff --git a/test/homedir/test3/views/testCustom.js b/test/homedir/test3/views/testCustom.js new file mode 100644 index 00000000..c9217efc --- /dev/null +++ b/test/homedir/test3/views/testCustom.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = { + testCustom: { + map: function (doc) { + if (doc.$type === 'entry') { + emit(doc._id); + } + }, + designDoc: 'custom' + } +};