feature(cloudcmd) add ability to override modules (#109)

This commit is contained in:
coderaiser 2017-03-23 17:53:41 +02:00
parent 3044ac0c88
commit 51481fb054
13 changed files with 201 additions and 128 deletions

12
HELP.md
View file

@ -408,10 +408,22 @@ const plugins = [
__dirname + '/plugin.js'
];
const filePicker = {
data: {
FilePicker: {
key: 'key'
}
}
};
// override option from json/modules.json
const modules = {filePicker};
app.use(cloudcmd({
socket, /* used by Config, Edit (optional) and Console (required) */
config, /* config data (optional) */
plugins, /* optional */
modules, /* optional */
}));
server.listen(port);

View file

@ -93,10 +93,22 @@ const plugins = [
__dirname + '/plugin.js'
];
const filePicker = {
data: {
FilePicker: {
key: 'key',
}
}
};
// override option from json/modules.json
const modules = {filePicker};
app.use(cloudcmd({
socket, /* used by Config, Edit (optional) and Console (required) */
config, /* config data (optional) */
plugins, /* optional */
modules, /* optional */
}));
server.listen(port);

View file

@ -2,6 +2,7 @@
const itype = require('itype/legacy');
const rendy = require('rendy');
const exec = require('execon');
const Images = require('./dom/images');
const join = require('join-io/www/join');
@ -134,7 +135,7 @@ function CloudCmdProto(Util, DOM) {
const prefix = CloudCmd.PREFIX;
const pathFull = prefix + CloudCmd.DIRCLIENT_MODULES + path;
Util.exec(doBefore);
exec(doBefore);
return DOM.load.js(pathFull, func ||
function(error) {
@ -172,7 +173,7 @@ function CloudCmdProto(Util, DOM) {
*/
this.init = (prefix, config) => {
const func = () => {
Util.exec.series([
exec.series([
initModules,
baseInit,
loadPlugins,
@ -208,7 +209,7 @@ function CloudCmdProto(Util, DOM) {
if (config.onePanelMode)
CloudCmd.MIN_ONE_PANEL_WIDTH = Infinity;
Util.exec.if(document.body.scrollIntoViewIfNeeded, func, funcBefore);
exec.if(document.body.scrollIntoViewIfNeeded, func, funcBefore);
};
function loadPlugins(callback) {
@ -263,7 +264,7 @@ function CloudCmdProto(Util, DOM) {
};
function initModules(callback) {
Util.exec.if(CloudCmd.Key, () => {
exec.if(CloudCmd.Key, () => {
Key = new CloudCmd.Key();
CloudCmd.Key = Key;
Key.bind();
@ -278,13 +279,11 @@ function CloudCmdProto(Util, DOM) {
});
Files.get('modules', (error, modules) => {
const STORAGE = 'storage';
const showLoad = Images.show.load;
const doBefore = {
'edit' : showLoad,
'menu' : showLoad,
'storage/_filepicker' : showLoad
'edit': showLoad,
'menu': showLoad,
};
const load = (name, path, dobefore) => {
@ -302,32 +301,17 @@ function CloudCmdProto(Util, DOM) {
if (!modules)
modules = [];
modules.forEach((module) => {
const isStr = itype.string(module);
if (!isStr)
return;
modules.local.forEach((module) => {
load(null, module, doBefore[module]);
});
const storageObj = Util.findObjByNameInArr(modules, STORAGE);
const mod = Util.getNamesFromObjArray(storageObj);
mod.forEach((name) => {
const path = STORAGE + '/_' + name.toLowerCase();
load(name, path, doBefore[path]);
});
callback();
});
}
function baseInit(callback) {
var dirPath = '',
files = DOM.getFiles();
const files = DOM.getFiles();
/* выделяем строку с первым файлом */
if (files)
DOM.setCurrentFile(files[0], {
@ -337,8 +321,8 @@ function CloudCmdProto(Util, DOM) {
history: !location.hash
});
dirPath = DOM.getCurrentDirPath(),
Listeners = CloudCmd.Listeners;
const dirPath = DOM.getCurrentDirPath();
Listeners = CloudCmd.Listeners;
Listeners.init();
Listeners.setOnPanel('left');
@ -346,9 +330,9 @@ function CloudCmdProto(Util, DOM) {
Listeners.initKeysPanel();
Storage.get(dirPath, function(error, data) {
Storage.get(dirPath, (error, data) => {
if (!data) {
data = getJSONfromFileTable();
data = getJSONfromFileTable();
Storage.set(dirPath, data);
}
});
@ -356,18 +340,16 @@ function CloudCmdProto(Util, DOM) {
callback();
}
this.execFromModule = function(moduleName, funcName) {
var args = [].slice.call(arguments, 2),
obj = CloudCmd[moduleName],
isObj = itype.object(obj);
this.execFromModule = (moduleName, funcName, ...args) => {
const obj = CloudCmd[moduleName];
const isObj = itype.object(obj);
Util.exec.if(isObj,
function() {
var obj = CloudCmd[moduleName],
func = obj[funcName];
func.apply(null, args);
}, obj);
exec.if(isObj, () => {
const obj = CloudCmd[moduleName];
const func = obj[funcName];
func(...args);
}, obj);
};
this.refresh = function(panelParam, options, callback) {
@ -437,7 +419,7 @@ function CloudCmdProto(Util, DOM) {
DOM.setCurrentByName(name);
}
Util.exec(callback);
exec(callback);
});
});
};
@ -511,7 +493,7 @@ function CloudCmdProto(Util, DOM) {
});
}
Util.exec(callback);
exec(callback);
});
}

View file

@ -19,9 +19,7 @@ module.exports = (name, options, callback = options) => {
Files.get('modules', (error, modules) => {
const online = config('online') && navigator.onLine;
const remoteObj = findObjByNameInArr(modules, 'remote');
const module = findObjByNameInArr(remoteObj, name);
const module = findObjByNameInArr(modules.remote, name);
const isArray = itype.array(module.local);
const version = module.version;

View file

@ -53,9 +53,7 @@ function loadFiles(callback) {
load.js('//api.filepicker.io/v1/filepicker.js', () => {
Files.get('modules', (error, modules) => {
const storage = Util.findObjByNameInArr(modules, 'storage');
const picker = Util.findObjByNameInArr(storage, 'FilePicker');
const key = picker && picker.key;
const {key} = modules.data.FilePicker;
filepicker.setKey(key);

View file

@ -120,24 +120,6 @@ function UtilProto(exec) {
return ret;
};
/**
* get values from Object Array name properties
* or
* @pObj
*/
this.getNamesFromObjArray = function(arr) {
var ret = [];
if (!Array.isArray(arr))
throw Error('arr should be array!');
ret = arr.map(function(item) {
return item.name;
});
return ret;
};
/**
* find object by name in arrray
*

View file

@ -1,57 +1,56 @@
[
"edit",
"edit-file",
"edit-names",
"menu",
"view",
"help",
"markdown",
"config",
"contact",
"upload",
"operation",
"konsole",
"terminal",
"cloud", [{
"name": "remote",
"data": [{
"name": "jquery",
"version": "3.1.1",
"local": "/modules/jquery/dist/jquery.min.js",
"remote": "//ajax.googleapis.com/ajax/libs/jquery/{{ version }}/jquery.min.js"
}, {
"name": "socket",
"version": "1.7.3",
"local": "/socket.io/socket.io.js",
"remote": "https://cdnjs.cloudflare.com/ajax/libs/socket.io/{{ version }}/socket.io.js"
}, {
"name": "fancybox",
"version": "2.1.6",
"local": [
"/modules/fancybox/source/jquery.fancybox.css",
"/modules/fancybox/source/jquery.fancybox.pack.js"
],
"remote": [
"//cdnjs.cloudflare.com/ajax/libs/fancybox/{{ version }}/css/jquery.fancybox.min.css",
"//cdnjs.cloudflare.com/ajax/libs/fancybox/{{ version }}/js/jquery.fancybox.min.js"
]
}, {
"name": "menu",
"version": "1.0.2",
"local": [
"/modules/menu/menu-io.min.css",
"/modules/menu/menu-io.min.js"
],
"remote": [
"//cdn.jsdelivr.net/menu-io/{{ version }}/menu-io.min.js",
"//cdn.jsdelivr.net/menu-io/{{ version }}/menu-io.min.css"
]
}]
{
"local": [
"edit",
"edit-file",
"edit-names",
"menu",
"view",
"help",
"markdown",
"config",
"contact",
"upload",
"operation",
"konsole",
"terminal",
"cloud"
],
"remote": [{
"name": "jquery",
"version": "3.1.1",
"local": "/modules/jquery/dist/jquery.min.js",
"remote": "//ajax.googleapis.com/ajax/libs/jquery/{{ version }}/jquery.min.js"
}, {
"name": "storage",
"data": [{
"name" : "FilePicker",
"key" : "AACq5fTfzRY2E_Rw_4kyaz"
}]
}]
]
"name": "socket",
"version": "1.7.3",
"local": "/socket.io/socket.io.js",
"remote": "https://cdnjs.cloudflare.com/ajax/libs/socket.io/{{ version }}/socket.io.js"
}, {
"name": "fancybox",
"version": "2.1.6",
"local": [
"/modules/fancybox/source/jquery.fancybox.css",
"/modules/fancybox/source/jquery.fancybox.pack.js"
],
"remote": [
"//cdnjs.cloudflare.com/ajax/libs/fancybox/{{ version }}/css/jquery.fancybox.min.css",
"//cdnjs.cloudflare.com/ajax/libs/fancybox/{{ version }}/js/jquery.fancybox.min.js"
]
}, {
"name": "menu",
"version": "1.0.2",
"local": [
"/modules/menu/menu-io.min.css",
"/modules/menu/menu-io.min.js"
],
"remote": [
"//cdn.jsdelivr.net/menu-io/{{ version }}/menu-io.min.js",
"//cdn.jsdelivr.net/menu-io/{{ version }}/menu-io.min.css"
]
}],
"data": {
"FilePicker": {
"key": "AACq5fTfzRY2E_Rw_4kyaz"
}
}
}

View file

@ -111,6 +111,7 @@
"copymitter": "^2.0.0",
"criton": "^1.0.0",
"currify": "^2.0.3",
"deepmerge": "^1.3.2",
"deepword": "^1.3.0",
"dword": "^4.1.0",
"edward": "^4.2.0",

View file

@ -6,6 +6,7 @@ const DIR_ROOT = DIR + '../';
const cloudfunc = require(DIR + 'cloudfunc');
const auth = require(DIR + 'auth');
const config = require(DIR + 'config');
const modulas = require(DIR + 'modulas');
const rest = require(DIR + 'rest');
const route = require(DIR + 'route');
const validate = require(DIR + 'validate');
@ -48,6 +49,8 @@ module.exports = (params) => {
const p = params || {};
const options = p.config || {};
const plugins = p.plugins;
const modules = p.modules;
const keys = Object.keys(options);
let prefix;
@ -88,7 +91,7 @@ module.exports = (params) => {
if (p.socket)
listen(prefix, p.socket);
return cloudcmd(prefix, plugins);
return cloudcmd(prefix, plugins, modules);
};
function defaultValue(value, previous) {
@ -183,7 +186,7 @@ function listen(prefix, socket) {
});
}
function cloudcmd(prefix, plugins) {
function cloudcmd(prefix, plugins, modules) {
const isOption = (name) => {
return config(name);
};
@ -266,6 +269,8 @@ function cloudcmd(prefix, plugins) {
auth(),
config.middle,
modules && modulas(modules),
restafary({
prefix: cloudfunc.apiURL + '/fs',
root

16
server/modulas.js Normal file
View file

@ -0,0 +1,16 @@
'use strict';
const deepmerge = require('deepmerge');
const originalModules = require('../json/modules');
module.exports = (modules = {}) => {
const result = deepmerge(originalModules, modules);
return (req, res, next) => {
if (req.url !== '/json/modules.json')
return next();
res.send(result);
};
};

View file

@ -38,7 +38,7 @@ module.exports = (options) => {
config: options,
socket: io(server, {
path: prefix() + '/socket.io'
})
}),
}));
if (port < 0 || port > 65535)

View file

@ -19,7 +19,7 @@ module.exports = (options, fn = options) => {
options = {};
}
const {config, plugins} = options;
const {config, plugins, modules} = options;
const app = express();
const server = http.createServer(app);
@ -35,7 +35,8 @@ module.exports = (options, fn = options) => {
app.use(cloudcmd({
socket,
plugins,
config: assign(defaultConfig(), config)
config: assign(defaultConfig(), config),
modules,
}));
server.listen(() => {

67
test/server/modulas.js Normal file
View file

@ -0,0 +1,67 @@
'use strict';
const path = require('path');
const test = require('tape');
const promisify = require('es6-promisify');
const pullout = require('pullout');
const request = require('request');
const modulesPath = path.join(__dirname, '..', '..', 'json', 'modules.json');
const localModules = require(modulesPath);
const warp = (fn, ...a) => (...b) => fn(...b, ...a);
const _pullout = promisify(pullout);
const get = promisify((url, fn) => {
fn(null, request(url));
});
const before = require('../before');
test('cloudcmd: modules', (t) => {
const modules = {
data: {
FilePicker: {
key: 'hello'
}
}
};
const expected = Object.assign({}, localModules);
expected.data.FilePicker.key = 'hello';
before({modules}, (port, after) => {
get(`http://localhost:${port}/json/modules.json`)
.then(warp(_pullout, 'string'))
.then(JSON.parse)
.then((result) => {
t.deepEqual(result, expected, 'should equal');
t.end();
after();
})
.catch(console.error);
});
});
test('cloudcmd: modules: wrong route', (t) => {
const modules = {
hello: 'world'
};
const expected = Object.assign({}, localModules, modules);
before({modules}, (port, after) => {
get(`http://localhost:${port}/package.json`)
.then(warp(_pullout, 'string'))
.then(JSON.parse)
.then((result) => {
t.notDeepEqual(result, expected, 'should not be equal');
t.end();
after();
})
.catch(console.error);
});
});