periodicjs
Version:
Periodic is a rapid enterprise application framework for data driven web and mobile applications.
283 lines (275 loc) • 11 kB
JavaScript
;
const Promisie = require('promisie');
const fs = require('fs-extra');
const requestMethods = ['CONNECT', 'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PUT', 'POST', ];
const path = require('path');
const flatten = require('flat');
function getModelFilesMap(dir, modelfile) {
return path.join(dir, modelfile, '___FULLPATH___');
}
function loadExtensionFiles(options) {
const { extension = {}, container = {}, } = options;
return new Promise((resolve, reject) => {
try {
const standardModelsDir = (container.name) ?
(container.type === 'local') ?
`${this.config.app_root}/content/container/${container.name}/config/databases/standard/models` :
`${this.config.app_root}/node_modules/${container.name}/config/databases/standard/models` :
`${this.config.app_root}/node_modules/${extension.name}/config/databases/standard/models`;
const modelFilesMap = getModelFilesMap.bind(standardModelsDir);
fs.readdir(standardModelsDir)
.then(modelFiles => {
const modelFilesFullPath = modelFiles.map(file => getModelFilesMap(standardModelsDir, file));
this.resources.standard_models.push(...modelFilesFullPath);
resolve(true);
}).catch(e => {
resolve('does not have standard models');
});
} catch (e) {
reject(e);
}
});
}
function loadExtensionSettings(options) {
const { extension = {}, container = {}, } = options;
let defaultSettings = {};
try {
defaultSettings = (container.name) ?
(container.type === 'local') ?
require(`${this.config.app_root}/content/container/${container.name}/config/settings.js`) :
require(`${container.name}/config/settings.js`) :
require(`${extension.name}/config/settings.js`); // load default settings
} catch (e) {
if (this.config.debug) {
if (container.name) {
this.logger.warn(`${container.name} is missing default settings`, e);
} else {
this.logger.warn(`${extension.name} is missing default settings`, e);
}
}
}
const envConfigFilePath = (container.name) ?
`content/config/container/${container.name}/${this.config.process.runtime}.json` :
`content/config/extensions/${extension.name}/${this.config.process.runtime}.json`; // load environment settings
const overrideSettings = (container.name) ?
this.settings.container[`${container.name}`] // load override settings
:
this.settings.extensions[`${extension.name}`]; // load override settings
// assign to periodic.config.settings
return new Promise((resolve, reject) => {
try {
this.configuration.load({
docid: 'filepath',
query: envConfigFilePath,
}).then(dbenvconfig => {
const envconfigJSON = (dbenvconfig && dbenvconfig.toJSON) ?
dbenvconfig.toJSON() :
dbenvconfig || {};
const envconfig = envconfigJSON.config;
const updatedSettings = flatten.unflatten(
Object.assign({},
flatten(defaultSettings || {}),
flatten(envconfig || {}),
flatten(overrideSettings || {})
)
);
if (updatedSettings.databases) {
if (container.name) {
Object.keys(updatedSettings.databases).forEach(db => {
this.resources.databases.container[db] = updatedSettings.databases[db];
this.resources.databases.container[db].container = container.name;
this.resources.databases.container[db].container_type = container.type;
});
} else {
Object.keys(updatedSettings.databases).forEach(db => {
this.resources.databases.extensions[db] = updatedSettings.databases[db];
this.resources.databases.extensions[db].extension = extension.name;
});
}
}
if (container.name) {
this.settings.container[container.name] = updatedSettings.settings;
} else {
this.settings.extensions[extension.name] = updatedSettings.settings;
}
resolve(true);
}).catch(reject);
} catch (e) {
reject(e);
}
});
}
function getExtensionFromMap(ext) {
return { extension: ext, };
}
function assignExtensionResources(options) {
const { extension = {}, container = {}, } = options;
return new Promise((resolve, reject) => {
try {
const extensionModule = (container.name) ?
(container.type === 'local') ?
require(`${this.config.app_root}/content/container/${container.name}`) :
require(`${container.name}`) :
require(`${extension.name}`);
// try {
// if (container.name) {
// this.routers.set(`container_${container.name}`, {
// type: 'container',
// router: (container.type === 'local') ?
// require(`${this.config.app_root}/content/container/${container.name}/routers/index`) : require(`${container.name}/routers/index`),
// });
// } else {
// this.routers.set(`extension_${extension.name}`, {
// type: 'extension',
// router: require(`${extension.name}/routers/index`),
// });
// }
// } catch (e) {
// if (this.config.debug) {
// this.logger.warn(`${extension.name || container.name} is missing a default router`, e);
// }
// }
try {
if (container.name) {
this.controllers.container.set(`${container.name}`,
(container.type === 'local') ?
require(`${this.config.app_root}/content/container/${container.name}/controllers/index`) :
require(`${container.name}/controllers/index`));
} else {
this.controllers.extension.set(`${extension.name}`, require(`${extension.name}/controllers/index`));
}
} catch (e) {
if (this.config.debug) {
this.logger.warn(`${extension.name || container.name} is missing a default controller`, e);
}
}
try {
if (container.name) {
this.locals.container.set(`${container.name}`,
(container.type === 'local') ?
require(`${this.config.app_root}/content/container/${container.name}/utilities/index`) :
require(`${container.name}/utilities/index`));
} else {
this.locals.extensions.set(`${extension.name}`, require(`${extension.name}/utilities/index`));
}
} catch (e) {
if (this.config.debug) {
this.logger.warn(`${extension.name || container.name} is missing a default utilities`, e);
}
}
try {
if (container.name) {
this.resources.commands.container.set(`${container.name}`,
(container.type === 'local') ?
require(`${this.config.app_root}/content/container/${container.name}/commands/index`) :
require(`${container.name}/commands/index`));
} else {
this.resources.commands.extensions.set(`${extension.name}`, require(`${extension.name}/commands/index`));
}
} catch (e) {
if (this.config.debug) {
this.logger.warn(`${extension.name || container.name} is missing a default utilities`, e);
}
}
try {
const transforms = (container.name) ?
(container.type === 'local') ?
require(`${this.config.app_root}/content/container/${container.name}/transforms/index`) :
require(`${container.name}/transforms/index`) :
require(`${extension.name}/transforms/index`);
requestMethods.forEach(reqMethod => {
if (transforms.pre) {
this.transforms.pre[reqMethod] = Object.assign({}, this.transforms.pre[reqMethod], transforms.pre[reqMethod]);
}
if (transforms.post) {
this.transforms.post[reqMethod] = Object.assign({}, this.transforms.post[reqMethod], transforms.post[reqMethod]);
}
});
} catch (e) {
// console.log('HAS NO TRANSFORMS')
// if (this.config.debug) {
// this.logger.warn(`${extension.name} is missing a default transforms`, e);
// }
}
if (typeof extensionModule !== 'function') {
if (container.name) {
throw new Error(`Container: ${container.name} must be a function that returns a promise`);
} else {
throw new Error(`Extension: ${extension.name} must be a function that returns a promise`);
}
}
resolve(extensionModule());
} catch (e) {
reject(e);
}
});
}
function setupExtensions() {
return new Promise((resolve, reject) => {
try {
if (this.config.process.skip_external_resources) return resolve(true);
const extensions = Array.from(this.extensions.values());
const extensionSettings = loadExtensionSettings.bind(this);
const extensionResources = assignExtensionResources.bind(this);
const extensionModelFiles = loadExtensionFiles.bind(this);
const extensionList = extensions.map(getExtensionFromMap);
//load all the files for extensions
//load the configurations
if (extensionList.length) {
Promisie.each(extensionList, 5, extensionSettings)
.then(result => {
return Promisie.each(extensionList, 5, extensionResources);
})
.then(result => {
return Promisie.each(extensionList, 5, extensionModelFiles);
})
.then(result => {
resolve(result);
})
.catch(reject);
//set settings on this.settings.extensions
//load the routers
//load the controllers
//load transforms
// resolve(true);
} else {
resolve('no-arrays');
}
} catch (e) {
reject(e);
}
});
}
function setupContainer() {
return new Promise((resolve, reject) => {
try {
if (this.config.process.skip_external_resources) return resolve(true);
if (this.settings.container && this.settings.container.name) {
loadExtensionSettings.call(this, { container: this.settings.container, })
.then(result => {
return assignExtensionResources.call(this, { container: this.settings.container, });
})
.then(result => {
return loadExtensionFiles.call(this, { container: this.settings.container, });
})
.then(result => {
resolve(result);
})
.catch(reject);
} else {
resolve('no-container');
}
} catch (e) {
reject(e);
}
});
}
module.exports = {
getModelFilesMap,
loadExtensionFiles,
loadExtensionSettings,
getExtensionFromMap,
assignExtensionResources,
setupExtensions,
setupContainer,
};