mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-23 02:35:49 +00:00
feature(config-manager) add (#208)
This commit is contained in:
parent
fe9723fa15
commit
f9c659612a
33 changed files with 446 additions and 477 deletions
3
HELP.md
3
HELP.md
|
|
@ -671,6 +671,8 @@ const app = require('express')();
|
|||
const port = 1337;
|
||||
const prefix = '/';
|
||||
|
||||
const {createConfigManager} = cloudcmd;
|
||||
|
||||
const server = http.createServer(app);
|
||||
const socket = io.listen(server, {
|
||||
path: `{prefix}socket.io`
|
||||
|
|
@ -702,6 +704,7 @@ app.use(prefix, cloudcmd({
|
|||
config, // config data (optional)
|
||||
plugins, // DEPRECATED, use User Menu instead
|
||||
modules, // optional
|
||||
configManager: createConfigManager(), //optional
|
||||
}));
|
||||
|
||||
server.listen(port);
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ function main() {
|
|||
if (password)
|
||||
config('password', getPassword(password));
|
||||
|
||||
validateRoot(options.root);
|
||||
validateRoot(options.root, config);
|
||||
|
||||
if (args['show-config'])
|
||||
showConfig();
|
||||
|
|
@ -213,14 +213,19 @@ function main() {
|
|||
const importConfig = promisify(distribute.import);
|
||||
const caller = (fn) => fn();
|
||||
|
||||
importConfig()
|
||||
importConfig(config)
|
||||
.then(args.save ? caller(config.save) : noop)
|
||||
.then(startWraped(options));
|
||||
}
|
||||
|
||||
function validateRoot(root) {
|
||||
function validateRoot(root, config) {
|
||||
const validate = require(DIR_SERVER + 'validate');
|
||||
validate.root(root, console.log);
|
||||
validate.root(root, config);
|
||||
|
||||
if (root === '/')
|
||||
return;
|
||||
|
||||
console.log(`root: ${root}`);
|
||||
}
|
||||
|
||||
function getPassword(password) {
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ test('util: getRegExp', (t) => {
|
|||
test('util: getRegExp: no', (t) => {
|
||||
const reg = getRegExp('');
|
||||
|
||||
t.deepEqual(reg, RegExp('^.*$'), 'should return regexp');
|
||||
t.deepEqual(reg, RegExp('^$'), 'should return regexp');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@
|
|||
"minimist": "^1.2.0",
|
||||
"nomine": "^3.0.0",
|
||||
"object.omit": "^3.0.0",
|
||||
"once": "^1.4.0",
|
||||
"onezip": "^3.0.0",
|
||||
"open": "^6.0.0",
|
||||
"package-json": "^6.0.0",
|
||||
|
|
|
|||
|
|
@ -4,18 +4,17 @@ const httpAuth = require('http-auth');
|
|||
const criton = require('criton');
|
||||
const currify = require('currify');
|
||||
const middle = currify(_middle);
|
||||
const check = currify(_check);
|
||||
|
||||
const config = require('./config');
|
||||
|
||||
module.exports = () => {
|
||||
module.exports = (config) => {
|
||||
const auth = httpAuth.basic({
|
||||
realm: 'Cloud Commander',
|
||||
}, check);
|
||||
}, check(config));
|
||||
|
||||
return middle(auth);
|
||||
return middle(config, auth);
|
||||
};
|
||||
|
||||
function _middle(authentication, req, res, next) {
|
||||
function _middle(config, authentication, req, res, next) {
|
||||
const is = config('auth');
|
||||
|
||||
if (!is)
|
||||
|
|
@ -25,7 +24,7 @@ function _middle(authentication, req, res, next) {
|
|||
authentication.check(req, res, success);
|
||||
}
|
||||
|
||||
function check(username, password, callback) {
|
||||
function _check(config, username, password, callback) {
|
||||
const BAD_CREDENTIALS = false;
|
||||
const name = config('username');
|
||||
const pass = config('password');
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ const fs = require('fs');
|
|||
|
||||
const cloudfunc = require(DIR_COMMON + 'cloudfunc');
|
||||
const authentication = require(DIR + 'auth');
|
||||
const config = require(DIR + 'config');
|
||||
const defaultConfig = require(DIR + 'config');
|
||||
const modulas = require(DIR + 'modulas');
|
||||
const userMenu = require(DIR + 'user-menu');
|
||||
const rest = require(DIR + 'rest');
|
||||
|
|
@ -38,15 +38,15 @@ const getDist = (isDev) => isDev ? 'dist-dev' : 'dist';
|
|||
const getIndexPath = (isDev) => path.join(DIR, '..', `${getDist(isDev)}/index.html`);
|
||||
const defaultHtml = fs.readFileSync(getIndexPath(isDev), 'utf8');
|
||||
|
||||
const auth = currify(_auth);
|
||||
const root = () => config('root');
|
||||
|
||||
const initAuth = currify(_initAuth);
|
||||
const notEmpty = (a) => a;
|
||||
const clean = (a) => a.filter(notEmpty);
|
||||
|
||||
module.exports = (params) => {
|
||||
const p = params || {};
|
||||
const options = p.config || {};
|
||||
const config = p.configManager || defaultConfig;
|
||||
|
||||
const {
|
||||
modules,
|
||||
plugins,
|
||||
|
|
@ -59,7 +59,10 @@ module.exports = (params) => {
|
|||
keys.forEach((name) => {
|
||||
let value = options[name];
|
||||
|
||||
if (/root|editor|packer|columns/.test(name))
|
||||
if (/root/.test(name))
|
||||
validate.root(value, config);
|
||||
|
||||
if (/editor|packer|columns/.test(name))
|
||||
validate[name](value);
|
||||
|
||||
if (/prefix/.test(name))
|
||||
|
|
@ -68,21 +71,31 @@ module.exports = (params) => {
|
|||
config(name, value);
|
||||
});
|
||||
|
||||
config('console', defaultValue('console', options));
|
||||
config('configDialog', defaultValue('configDialog', options));
|
||||
config('console', defaultValue(config, 'console', options));
|
||||
config('configDialog', defaultValue(config, 'configDialog', options));
|
||||
|
||||
const {prefix} = prefixer(options.prefix);
|
||||
const prefixSocket = prefixer(options.prefixSocket);
|
||||
|
||||
if (p.socket)
|
||||
listen(prefixSocket, p.socket);
|
||||
listen({
|
||||
prefixSocket,
|
||||
config,
|
||||
socket: p.socket,
|
||||
});
|
||||
|
||||
return cloudcmd(prefix, plugins, modules);
|
||||
return cloudcmd({
|
||||
plugins,
|
||||
modules,
|
||||
config,
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.createConfigManager = defaultConfig.create;
|
||||
module.exports.configPath = defaultConfig.path;
|
||||
|
||||
module.exports._getIndexPath = getIndexPath;
|
||||
|
||||
function defaultValue(name, options) {
|
||||
function defaultValue(config, name, options) {
|
||||
const value = options[name];
|
||||
const previous = config(name);
|
||||
|
||||
|
|
@ -100,8 +113,8 @@ function getPrefix(prefix) {
|
|||
return prefix || '';
|
||||
}
|
||||
|
||||
module.exports._auth = _auth;
|
||||
function _auth(accept, reject, username, password) {
|
||||
module.exports._initAuth = _initAuth;
|
||||
function _initAuth(config, accept, reject, username, password) {
|
||||
if (!config('auth'))
|
||||
return accept();
|
||||
|
||||
|
|
@ -114,10 +127,14 @@ function _auth(accept, reject, username, password) {
|
|||
reject();
|
||||
}
|
||||
|
||||
function listen(prefixSocket, socket) {
|
||||
function listen({prefixSocket, socket, config}) {
|
||||
const root = () => config('root');
|
||||
const auth = initAuth(config);
|
||||
|
||||
prefixSocket = getPrefix(prefixSocket);
|
||||
|
||||
config.listen(socket, auth);
|
||||
if (config.listen)
|
||||
config.listen(socket, auth);
|
||||
|
||||
edward.listen(socket, {
|
||||
root,
|
||||
|
|
@ -148,17 +165,17 @@ function listen(prefixSocket, socket) {
|
|||
prefix: prefixSocket + '/fileop',
|
||||
});
|
||||
|
||||
config('terminal') && terminal().listen(socket, {
|
||||
config('terminal') && terminal(config).listen(socket, {
|
||||
auth,
|
||||
prefix: prefixSocket + '/gritty',
|
||||
command: config('terminalCommand'),
|
||||
autoRestart: config('terminalAutoRestart'),
|
||||
});
|
||||
|
||||
distribute.export(socket);
|
||||
distribute.export(config, socket);
|
||||
}
|
||||
|
||||
function cloudcmd(prefix, plugins, modules) {
|
||||
function cloudcmd({plugins, modules, config}) {
|
||||
const online = apart(config, 'online');
|
||||
const cache = false;
|
||||
const diff = apart(config, 'diff');
|
||||
|
|
@ -169,13 +186,14 @@ function cloudcmd(prefix, plugins, modules) {
|
|||
|
||||
const dropbox = config('dropbox');
|
||||
const dropboxToken = config('dropboxToken');
|
||||
const root = () => config('root');
|
||||
|
||||
const funcs = clean([
|
||||
config('console') && konsole({
|
||||
online,
|
||||
}),
|
||||
|
||||
config('terminal') && terminal({}),
|
||||
config('terminal') && terminal(config, {}),
|
||||
|
||||
edward({
|
||||
online,
|
||||
|
|
@ -202,13 +220,12 @@ function cloudcmd(prefix, plugins, modules) {
|
|||
}),
|
||||
|
||||
fileop(),
|
||||
|
||||
nomine(),
|
||||
|
||||
setUrl,
|
||||
setSW,
|
||||
logout,
|
||||
authentication(),
|
||||
authentication(config),
|
||||
config.middle,
|
||||
|
||||
modules && modulas(modules),
|
||||
|
|
@ -228,8 +245,8 @@ function cloudcmd(prefix, plugins, modules) {
|
|||
menuName: '.cloudcmd.menu.js',
|
||||
}),
|
||||
|
||||
rest,
|
||||
route({
|
||||
rest(config),
|
||||
route(config, {
|
||||
html: defaultHtml,
|
||||
}),
|
||||
|
||||
|
|
|
|||
|
|
@ -4,17 +4,16 @@ const path = require('path');
|
|||
|
||||
const test = require('supertape');
|
||||
const stub = require('@cloudcmd/stub');
|
||||
const currify = require('currify');
|
||||
const {reRequire} = require('mock-require');
|
||||
|
||||
const DIR = './';
|
||||
const cloudcmdPath = DIR + 'cloudcmd';
|
||||
|
||||
const config = require(DIR + 'config');
|
||||
const cloudcmd = require(cloudcmdPath);
|
||||
const {
|
||||
createConfigManager,
|
||||
_getPrefix,
|
||||
_auth,
|
||||
_initAuth,
|
||||
} = cloudcmd;
|
||||
|
||||
const {request} = require('serve-once')(cloudcmd, {
|
||||
|
|
@ -41,25 +40,27 @@ test('cloudcmd: args: plugins: error', (t) => {
|
|||
});
|
||||
|
||||
test('cloudcmd: defaults: config', (t) => {
|
||||
const configDialog = config('configDialog');
|
||||
const configManager = createConfigManager();
|
||||
|
||||
config('configDialog', false);
|
||||
cloudcmd();
|
||||
t.notOk(config('configDialog'), 'should not override config with defaults');
|
||||
configManager('configDialog', false);
|
||||
|
||||
config('configDialog', configDialog);
|
||||
cloudcmd({
|
||||
configManager,
|
||||
});
|
||||
|
||||
t.notOk(configManager('configDialog'), 'should not override config with defaults');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: defaults: console', (t) => {
|
||||
const console = config('console');
|
||||
config('console', false);
|
||||
cloudcmd();
|
||||
t.notOk(config('console'), 'should not override config with defaults');
|
||||
const configManager = createConfigManager();
|
||||
configManager('console', false);
|
||||
|
||||
config('console', console);
|
||||
cloudcmd({
|
||||
configManager,
|
||||
});
|
||||
|
||||
t.notOk(configManager('console'), 'should not override config with defaults');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
@ -120,79 +121,61 @@ test('cloudcmd: replaceDist: !isDev', (t) => {
|
|||
});
|
||||
|
||||
test('cloudcmd: auth: reject', (t) => {
|
||||
const auth = config('auth');
|
||||
const accept = stub();
|
||||
const reject = stub();
|
||||
|
||||
const config = createConfigManager();
|
||||
|
||||
const username = 'root';
|
||||
const password = 'toor';
|
||||
|
||||
const set = credentials();
|
||||
const reset = set('hello', 'world');
|
||||
config('auth', true);
|
||||
config('username', username);
|
||||
config('password', password);
|
||||
|
||||
_auth(accept, reject, username, password);
|
||||
_initAuth(config, accept, reject, username, 'abc');
|
||||
|
||||
config('auth', auth);
|
||||
reset();
|
||||
|
||||
t.ok(reject.called, 'should accept');
|
||||
t.ok(reject.called, 'should reject');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: auth: accept', (t) => {
|
||||
const auth = config('auth');
|
||||
const accept = stub();
|
||||
const reject = stub();
|
||||
|
||||
const username = 'root';
|
||||
const password = 'toor';
|
||||
const auth = true;
|
||||
|
||||
const set = credentials();
|
||||
const reset = set(username, password);
|
||||
config('auth', true);
|
||||
|
||||
_auth(accept, reject, username, password);
|
||||
|
||||
const config = createConfigManager();
|
||||
config('username', username);
|
||||
config('password', password);
|
||||
config('auth', auth);
|
||||
reset();
|
||||
|
||||
_initAuth(config, accept, reject, username, password);
|
||||
|
||||
t.ok(accept.called, 'should accept');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: auth: accept: no auth', (t) => {
|
||||
const auth = config('auth');
|
||||
const accept = stub();
|
||||
const reject = stub();
|
||||
|
||||
const auth = false;
|
||||
const username = 'root';
|
||||
const password = 'toor';
|
||||
|
||||
config('auth', false);
|
||||
_auth(accept, reject, username, password);
|
||||
const config = createConfigManager();
|
||||
config('username', username);
|
||||
config('password', password);
|
||||
config('auth', auth);
|
||||
|
||||
_initAuth(config, accept, reject, username, password);
|
||||
|
||||
t.ok(accept.called, 'should accept');
|
||||
t.end();
|
||||
});
|
||||
|
||||
function credentials() {
|
||||
const username = config('username');
|
||||
const password = config('password');
|
||||
|
||||
const reset = () => {
|
||||
config('username', username);
|
||||
config('password', password);
|
||||
};
|
||||
|
||||
const set = currify((fn, a, b) => {
|
||||
config('username', a);
|
||||
config('password', b);
|
||||
|
||||
return fn;
|
||||
});
|
||||
|
||||
return set(reset);
|
||||
}
|
||||
|
||||
test('cloudcmd: getIndexPath: production', (t) => {
|
||||
const isDev = false;
|
||||
const name = path.join(__dirname, '..', 'dist', 'index.html');
|
||||
|
|
|
|||
184
server/config.js
184
server/config.js
|
|
@ -15,70 +15,73 @@ const CloudFunc = require(DIR_COMMON + 'cloudfunc');
|
|||
|
||||
const currify = require('currify');
|
||||
const wraptile = require('wraptile');
|
||||
const squad = require('squad');
|
||||
const tryToCatch = require('try-to-catch');
|
||||
const pullout = require('pullout');
|
||||
const ponse = require('ponse');
|
||||
const jonny = require('jonny');
|
||||
const jju = require('jju');
|
||||
const writejson = require('writejson');
|
||||
const writejson = promisify(require('writejson'));
|
||||
const tryCatch = require('try-catch');
|
||||
const criton = require('criton');
|
||||
const HOME = homedir();
|
||||
|
||||
const manageConfig = squad(traverse, cryptoPass);
|
||||
const save = promisify(_save);
|
||||
|
||||
const resolve = Promise.resolve.bind(Promise);
|
||||
const formatMsg = currify((a, b) => CloudFunc.formatMsg(a, b));
|
||||
|
||||
const {apiURL} = CloudFunc;
|
||||
const changeEmitter = new Emitter();
|
||||
|
||||
const key = (a) => Object.keys(a).pop();
|
||||
|
||||
const ConfigPath = path.join(DIR, 'json/config.json');
|
||||
const ConfigHome = path.join(HOME, '.cloudcmd.json');
|
||||
|
||||
const readjsonSync = (name) => {
|
||||
return jju.parse(fs.readFileSync(name, 'utf8'), {
|
||||
mode: 'json',
|
||||
});
|
||||
};
|
||||
const config = read();
|
||||
|
||||
const rootConfig = readjsonSync(ConfigPath);
|
||||
const key = (a) => Object.keys(a).pop();
|
||||
const connection = currify(_connection);
|
||||
const connectionWraped = wraptile(_connection);
|
||||
const middle = currify(_middle);
|
||||
|
||||
const [error, configHome] = tryCatch(readjsonSync, ConfigHome);
|
||||
|
||||
if (error && error.code !== 'ENOENT')
|
||||
exit(`cloudcmd --config ${ConfigHome}: ${error.message}`);
|
||||
|
||||
const config = {
|
||||
...rootConfig,
|
||||
...configHome,
|
||||
};
|
||||
|
||||
const connectionWraped = wraptile(connection);
|
||||
function read(filename = ConfigHome) {
|
||||
const readjsonSync = (name) => {
|
||||
return jju.parse(fs.readFileSync(name, 'utf8'), {
|
||||
mode: 'json',
|
||||
});
|
||||
};
|
||||
|
||||
const rootConfig = readjsonSync(ConfigPath);
|
||||
const [error, configHome] = tryCatch(readjsonSync, ConfigHome);
|
||||
|
||||
if (error && error.code !== 'ENOENT')
|
||||
exit(`cloudcmd --config ${filename}: ${error.message}`);
|
||||
|
||||
return {
|
||||
...rootConfig,
|
||||
...configHome,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = manage;
|
||||
module.exports.save = save;
|
||||
module.exports.middle = middle;
|
||||
module.exports.create = create;
|
||||
module.exports.middle = middle(manage);
|
||||
module.exports.subscribe = (fn) => {
|
||||
changeEmitter.on('change', fn);
|
||||
};
|
||||
|
||||
module.exports.path = ConfigHome;
|
||||
|
||||
module.exports.unsubscribe = (fn) => {
|
||||
changeEmitter.removeListener('change', fn);
|
||||
};
|
||||
|
||||
module.exports.listen = (socket, auth) => {
|
||||
check(socket, auth);
|
||||
|
||||
const manageListen = currify((manage, socket, auth) => {
|
||||
if (!manage('configDialog'))
|
||||
return middle;
|
||||
|
||||
listen(socket, auth);
|
||||
listen(manage, socket, auth);
|
||||
|
||||
return middle;
|
||||
};
|
||||
});
|
||||
|
||||
function manage(key, value) {
|
||||
if (!key)
|
||||
|
|
@ -97,25 +100,59 @@ function manage(key, value) {
|
|||
return `${key} = ${value}`;
|
||||
}
|
||||
|
||||
function _save(callback) {
|
||||
writejson(ConfigHome, config, {mode: 0o600}, callback);
|
||||
}
|
||||
|
||||
function listen(sock, auth) {
|
||||
const prefix = manage('prefixSocket');
|
||||
function initWrite(filename, configManager) {
|
||||
if (filename)
|
||||
return write.bind(null, filename, configManager);
|
||||
|
||||
sock.of(prefix + '/config')
|
||||
.on('connection', (socket) => {
|
||||
if (!manage('auth'))
|
||||
return connection(socket);
|
||||
|
||||
const reject = () => socket.emit('reject');
|
||||
socket.on('auth', auth(connectionWraped(socket), reject));
|
||||
});
|
||||
return resolve;
|
||||
}
|
||||
|
||||
function connection(socket) {
|
||||
socket.emit('config', config);
|
||||
function readConfig(filename) {
|
||||
if (filename)
|
||||
return read(filename);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
function create({filename} = {}) {
|
||||
const config = {};
|
||||
|
||||
const configManager = (key, value) => {
|
||||
if (key === '*')
|
||||
return {
|
||||
...config,
|
||||
};
|
||||
|
||||
if (value === undefined)
|
||||
return config[key];
|
||||
|
||||
config[key] = value;
|
||||
};
|
||||
|
||||
spread(configManager);
|
||||
Object.assign(config, readConfig(filename));
|
||||
|
||||
configManager.middle = middle(configManager);
|
||||
configManager.listen = manageListen(configManager);
|
||||
configManager.write = initWrite(filename, configManager);
|
||||
|
||||
return configManager;
|
||||
}
|
||||
|
||||
function spread(store) {
|
||||
const entries = Object.entries(config);
|
||||
|
||||
for (const [name, value] of entries) {
|
||||
store(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
const write = async (filename, config) => {
|
||||
return writejson(filename, config('*'), {mode: 0o600});
|
||||
};
|
||||
|
||||
function _connection(manage, socket) {
|
||||
socket.emit('config', manage('*'));
|
||||
|
||||
const emit = currify((socket, name, e) => {
|
||||
return socket.emit(name, e.message);
|
||||
|
|
@ -125,7 +162,7 @@ function connection(socket) {
|
|||
if (typeof json !== 'object')
|
||||
return socket.emit('err', 'Error: Wrong data type!');
|
||||
|
||||
manageConfig(json);
|
||||
traverse(cryptoPass(manage, json));
|
||||
|
||||
const send = () => {
|
||||
const data = CloudFunc.formatMsg('config', key(json));
|
||||
|
|
@ -134,13 +171,26 @@ function connection(socket) {
|
|||
socket.emit('log', data);
|
||||
};
|
||||
|
||||
save()
|
||||
manage.write()
|
||||
.then(send)
|
||||
.catch(emit(socket, 'err'));
|
||||
});
|
||||
}
|
||||
|
||||
function middle(req, res, next) {
|
||||
function listen(manage, sock, auth) {
|
||||
const prefix = manage('prefixSocket');
|
||||
|
||||
sock.of(prefix + '/config')
|
||||
.on('connection', (socket) => {
|
||||
if (!manage('auth'))
|
||||
return connection(manage, socket);
|
||||
|
||||
const reject = () => socket.emit('reject');
|
||||
socket.on('auth', auth(connectionWraped(manage, socket), reject));
|
||||
});
|
||||
}
|
||||
|
||||
function _middle(manage, req, res, next) {
|
||||
const noConfigDialog = !manage('configDialog');
|
||||
|
||||
if (req.url !== `${apiURL}/config`)
|
||||
|
|
@ -148,7 +198,7 @@ function middle(req, res, next) {
|
|||
|
||||
switch(req.method) {
|
||||
case 'GET':
|
||||
get(req, res, next);
|
||||
get(manage, req, res, next);
|
||||
break;
|
||||
|
||||
case 'PATCH':
|
||||
|
|
@ -157,7 +207,7 @@ function middle(req, res, next) {
|
|||
.status(404)
|
||||
.send('Config is disabled');
|
||||
|
||||
patch(req, res);
|
||||
patch(manage, req, res);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -165,8 +215,8 @@ function middle(req, res, next) {
|
|||
}
|
||||
}
|
||||
|
||||
function get(request, response) {
|
||||
const data = jonny.stringify(config);
|
||||
function get(manage, request, response) {
|
||||
const data = jonny.stringify(manage('*'));
|
||||
|
||||
ponse.send(data, {
|
||||
name : 'config.json',
|
||||
|
|
@ -176,7 +226,7 @@ function get(request, response) {
|
|||
});
|
||||
}
|
||||
|
||||
async function patch(request, response) {
|
||||
async function patch(manage, request, response) {
|
||||
const name = 'config.json';
|
||||
const cache = false;
|
||||
const options = {
|
||||
|
|
@ -186,18 +236,18 @@ async function patch(request, response) {
|
|||
cache,
|
||||
};
|
||||
|
||||
const [e] = await tryToCatch(patchConfig, options);
|
||||
const [e] = await tryToCatch(patchConfig, manage, options);
|
||||
|
||||
if (e)
|
||||
ponse.sendError(e, options);
|
||||
}
|
||||
|
||||
async function patchConfig({name, request, response, cache}) {
|
||||
async function patchConfig(manage, {name, request, response, cache}) {
|
||||
const str = await pullout(request);
|
||||
const json = jonny.parse(str);
|
||||
|
||||
manageConfig(json);
|
||||
await save();
|
||||
traverse(cryptoPass(manage, json));
|
||||
await manage.write();
|
||||
|
||||
const msg = formatMsg('config', key(json));
|
||||
ponse.send(msg, {
|
||||
|
|
@ -208,32 +258,24 @@ async function patchConfig({name, request, response, cache}) {
|
|||
});
|
||||
}
|
||||
|
||||
function traverse(json) {
|
||||
function traverse([manage, json]) {
|
||||
Object.keys(json).forEach((name) => {
|
||||
manage(name, json[name]);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports._cryptoPass = cryptoPass;
|
||||
function cryptoPass(json) {
|
||||
function cryptoPass(manage, json) {
|
||||
const algo = manage('algo');
|
||||
|
||||
if (!json.password)
|
||||
return json;
|
||||
return [manage, json];
|
||||
|
||||
const password = criton(json.password, algo);
|
||||
|
||||
return {
|
||||
return [manage, {
|
||||
...json,
|
||||
password,
|
||||
};
|
||||
}
|
||||
|
||||
function check(socket, auth) {
|
||||
if (!socket)
|
||||
throw Error('socket could not be empty!');
|
||||
|
||||
if (auth && typeof auth !== 'function')
|
||||
throw Error('auth should be function!');
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,11 @@ const root = '../';
|
|||
const configPath = './config';
|
||||
|
||||
const config = require(configPath);
|
||||
const {_cryptoPass} = config;
|
||||
const {
|
||||
_cryptoPass,
|
||||
create,
|
||||
} = config;
|
||||
|
||||
const {apiURL} = require(root + 'common/cloudfunc');
|
||||
|
||||
const fixture = require('./config.fixture');
|
||||
|
|
@ -54,27 +58,15 @@ test('config: manage: get: *', (t) => {
|
|||
t.end();
|
||||
});
|
||||
|
||||
test('config: listen: no socket', (t) => {
|
||||
t.throws(config.listen, 'should throw when no socket');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('config: listen: authCheck: not function', (t) => {
|
||||
const socket = {};
|
||||
const fn = () => config.listen(socket, 'hello');
|
||||
|
||||
t.throws(fn, 'should throw when authCheck not function');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('config: cryptoPass: no password', (t) => {
|
||||
const json = {
|
||||
hello: 'world',
|
||||
};
|
||||
|
||||
const result = _cryptoPass(json);
|
||||
const config = create();
|
||||
const result = _cryptoPass(config, json);
|
||||
|
||||
t.equal(result, json, 'should not change json');
|
||||
t.deepEqual(result, [config, json], 'should not change json');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
@ -89,9 +81,10 @@ test('config: cryptoPass', (t) => {
|
|||
password,
|
||||
};
|
||||
|
||||
const result = _cryptoPass(json);
|
||||
const config = create();
|
||||
const result = _cryptoPass(config, json);
|
||||
|
||||
t.deepEqual(result, expected, 'should crypt password');
|
||||
t.deepEqual(result, [config, expected], 'should crypt password');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ const wraptile = require('wraptile');
|
|||
const squad = require('squad');
|
||||
const omit = require('object.omit');
|
||||
|
||||
const config = require('../config');
|
||||
const log = require('./log');
|
||||
|
||||
const {
|
||||
|
|
@ -39,22 +38,23 @@ const omitList = [
|
|||
|
||||
const omitConfig = (config) => omit(config, omitList);
|
||||
|
||||
module.exports = (socket) => {
|
||||
module.exports = (config, socket) => {
|
||||
if (!config('export'))
|
||||
return;
|
||||
|
||||
const prefix = config('prefix');
|
||||
const distributePrefix = `${prefix}/distribute`;
|
||||
const isLog = config('log');
|
||||
|
||||
const onError = squad(
|
||||
logWraped(exportStr),
|
||||
logWraped(isLog, exportStr),
|
||||
getMessage,
|
||||
);
|
||||
|
||||
const onConnectError = squad(logWraped(exportStr), getDescription);
|
||||
const onConnectError = squad(logWraped(isLog, exportStr), getDescription);
|
||||
|
||||
socket.of(distributePrefix)
|
||||
.on('connection', onConnection(push))
|
||||
.on('connection', onConnection(push, config))
|
||||
.on('error', onError)
|
||||
.on('connect_error', onConnectError);
|
||||
};
|
||||
|
|
@ -83,41 +83,46 @@ function getHost(socket) {
|
|||
return `${colorName} [${remoteAddress}:${port}]`;
|
||||
}
|
||||
|
||||
const connectPush = wraptile((push, socket) => {
|
||||
const connectPush = wraptile((push, config, socket) => {
|
||||
socket.emit('accept');
|
||||
|
||||
const isLog = config('log');
|
||||
const host = getHost(socket);
|
||||
const subscription = push(socket);
|
||||
|
||||
socket.on('disconnect', onDisconnect(subscription, host));
|
||||
socket.on('disconnect', onDisconnect(subscription, config, host));
|
||||
|
||||
log(exportStr, `${connectedStr} to ${host}`);
|
||||
log(isLog, exportStr, `${connectedStr} to ${host}`);
|
||||
socket.emit('config', omitConfig(config('*')));
|
||||
log(exportStr, `config send to ${host}`);
|
||||
log(isLog, exportStr, `config send to ${host}`);
|
||||
|
||||
config.subscribe(subscription);
|
||||
});
|
||||
|
||||
const onConnection = currify((push, socket) => {
|
||||
const onConnection = currify((push, config, socket) => {
|
||||
const host = getHost(socket);
|
||||
const reject = () => {
|
||||
socket.emit('reject');
|
||||
socket.disconnect();
|
||||
};
|
||||
|
||||
log(exportStr, `${authTryStr} from ${host}`);
|
||||
socket.on('auth', auth(connectPush(push, socket), reject));
|
||||
const isLog = config('log');
|
||||
|
||||
log(isLog, exportStr, `${authTryStr} from ${host}`);
|
||||
socket.on('auth', auth(config, reject, connectPush(push, config, socket)));
|
||||
});
|
||||
|
||||
const auth = currify((fn, reject, token) => {
|
||||
const auth = currify((config, reject, fn, token) => {
|
||||
if (token === config('exportToken'))
|
||||
return fn();
|
||||
|
||||
reject();
|
||||
});
|
||||
|
||||
const onDisconnect = wraptile((subscription, host) => {
|
||||
const onDisconnect = wraptile((subscription, config, host) => {
|
||||
const isLog = config('log');
|
||||
|
||||
config.unsubscribe(subscription);
|
||||
log(exportStr, `${disconnectedStr} from ${host}`);
|
||||
log(isLog, exportStr, `${disconnectedStr} from ${host}`);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ const fullstore = require('fullstore');
|
|||
const io = require('socket.io-client');
|
||||
const forEachKey = currify(require('for-each-key'));
|
||||
|
||||
const config = require('../config');
|
||||
const log = require('./log');
|
||||
|
||||
const {
|
||||
|
|
@ -57,12 +56,13 @@ const done = wraptile((fn, store) => fn(null, {
|
|||
status: store(),
|
||||
}));
|
||||
|
||||
const emitAuth = wraptile((importUrl, socket) => {
|
||||
log(importStr, `${authTryStr} to ${importUrl}`);
|
||||
const emitAuth = wraptile((importUrl, config, socket) => {
|
||||
const isLog = config('log');
|
||||
log(isLog, importStr, `${authTryStr} to ${importUrl}`);
|
||||
socket.emit('auth', config('importToken'));
|
||||
});
|
||||
|
||||
module.exports = (options, fn) => {
|
||||
module.exports = (config, options, fn) => {
|
||||
fn = fn || options;
|
||||
|
||||
if (!config('import'))
|
||||
|
|
@ -72,6 +72,7 @@ module.exports = (options, fn) => {
|
|||
const importListen = config('importListen');
|
||||
const name = config('name');
|
||||
const port = config('port');
|
||||
const isLog = config('log');
|
||||
|
||||
const query = toLine({
|
||||
name,
|
||||
|
|
@ -93,30 +94,30 @@ module.exports = (options, fn) => {
|
|||
|
||||
const onConfig = squad(
|
||||
close,
|
||||
logWraped(importStr, `config received from ${colorUrl}`),
|
||||
logWraped(isLog, importStr, `config received from ${colorUrl}`),
|
||||
statusStoreWraped('received'),
|
||||
forEachKey(config),
|
||||
);
|
||||
|
||||
const onError = squad(
|
||||
superFn('error'),
|
||||
logWraped(importStr),
|
||||
logWraped(isLog, config, importStr),
|
||||
addUrl(colorUrl),
|
||||
getMessage,
|
||||
);
|
||||
|
||||
const onConnectError = squad(
|
||||
superFn('connect_error'),
|
||||
logWraped(importStr),
|
||||
logWraped(isLog, importStr),
|
||||
addUrl(colorUrl),
|
||||
getDescription,
|
||||
);
|
||||
|
||||
const onConnect = emitAuth(importUrl, socket);
|
||||
const onAccept = logWraped(importStr,`${connectedStr} to ${colorUrl}`);
|
||||
const onConnect = emitAuth(importUrl, config, socket);
|
||||
const onAccept = logWraped(isLog, importStr,`${connectedStr} to ${colorUrl}`);
|
||||
const onDisconnect = squad(
|
||||
done(fn, statusStore),
|
||||
logWraped(importStr, `${disconnectedStr} from ${colorUrl}`),
|
||||
logWraped(isLog, importStr, `${disconnectedStr} from ${colorUrl}`),
|
||||
rmListeners(socket, {
|
||||
onError,
|
||||
onConnect,
|
||||
|
|
@ -125,13 +126,13 @@ module.exports = (options, fn) => {
|
|||
);
|
||||
|
||||
const onChange = squad(
|
||||
logWraped(importStr),
|
||||
logWraped(isLog, importStr),
|
||||
config,
|
||||
);
|
||||
|
||||
const onReject = squad(
|
||||
superFn('reject'),
|
||||
logWraped(importStr, tokenRejectedStr),
|
||||
logWraped(isLog, importStr, tokenRejectedStr),
|
||||
);
|
||||
|
||||
socket.on('connect', onConnect);
|
||||
|
|
|
|||
|
|
@ -4,11 +4,13 @@ const test = require('supertape');
|
|||
const {promisify} = require('util');
|
||||
const tryToCatch = require('try-to-catch');
|
||||
const {connect} = require('../../test/before');
|
||||
const config = require('../config');
|
||||
const {createConfigManager} = require('../cloudcmd');
|
||||
const distribute = {
|
||||
import: promisify(require('./import')),
|
||||
};
|
||||
|
||||
const config = createConfigManager();
|
||||
|
||||
test('distribute: import: canceled', async (t) => {
|
||||
const {done} = await connect({
|
||||
config: {
|
||||
|
|
@ -19,7 +21,7 @@ test('distribute: import: canceled', async (t) => {
|
|||
},
|
||||
});
|
||||
|
||||
const {status} = await distribute.import();
|
||||
const {status} = await distribute.import(config);
|
||||
|
||||
await done();
|
||||
|
||||
|
|
@ -39,7 +41,7 @@ test('distribute: import: received: no error', async (t) => {
|
|||
|
||||
config('importUrl', `http://localhost:${port}`);
|
||||
|
||||
const [e] = await tryToCatch(distribute.import);
|
||||
const [e] = await tryToCatch(distribute.import, config);
|
||||
|
||||
await done();
|
||||
|
||||
|
|
@ -60,9 +62,10 @@ test('distribute: import: received', async (t) => {
|
|||
},
|
||||
});
|
||||
|
||||
const config = createConfigManager();
|
||||
config('importUrl', `http://localhost:${port}`);
|
||||
|
||||
const {status} = await distribute.import();
|
||||
const {status} = await distribute.import(config);
|
||||
await done();
|
||||
|
||||
t.equal(status, 'received','should equal');
|
||||
|
|
@ -82,12 +85,13 @@ test('distribute: import: received: auth: reject', async (t) => {
|
|||
},
|
||||
});
|
||||
|
||||
const config = createConfigManager();
|
||||
config('importUrl', `http://localhost:${port}`);
|
||||
|
||||
const {status} = await distribute.import();
|
||||
const {status} = await distribute.import(config);
|
||||
await done();
|
||||
|
||||
t.equal(status, 'reject','should equal');
|
||||
t.equal(status, 'reject', 'should equal');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
@ -104,9 +108,10 @@ test('distribute: import: received: auth: accept', async (t) => {
|
|||
},
|
||||
});
|
||||
|
||||
const config = createConfigManager();
|
||||
config('importUrl', `http://localhost:${port}`);
|
||||
|
||||
const {status} = await distribute.import();
|
||||
const {status} = await distribute.import(config);
|
||||
await done();
|
||||
|
||||
t.equal(status, 'received','should equal');
|
||||
|
|
@ -124,9 +129,10 @@ test('distribute: import: received: no name', async (t) => {
|
|||
},
|
||||
});
|
||||
|
||||
const config = createConfigManager();
|
||||
config('importUrl', `http://localhost:${port}`);
|
||||
|
||||
const {status} = await distribute.import();
|
||||
const {status} = await distribute.import(config);
|
||||
await done();
|
||||
|
||||
t.equal(status, 'received','should equal');
|
||||
|
|
@ -143,9 +149,10 @@ test('distribute: import: error', async (t) => {
|
|||
},
|
||||
});
|
||||
|
||||
const config = createConfigManager();
|
||||
config('importUrl', `http://localhost:0`);
|
||||
|
||||
const {status} = await distribute.import({
|
||||
const {status} = await distribute.import(config, {
|
||||
reconnection: false,
|
||||
});
|
||||
|
||||
|
|
@ -165,7 +172,9 @@ test('distribute: import: config:change: no export', async (t) => {
|
|||
},
|
||||
});
|
||||
|
||||
const {status} = await distribute.import({
|
||||
const config = createConfigManager();
|
||||
|
||||
const {status} = await distribute.import(config, {
|
||||
reconnection: false,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,9 @@
|
|||
const wraptile = require('wraptile');
|
||||
const chalk = require('chalk');
|
||||
|
||||
const config = require('../config');
|
||||
const datetime = require('../../common/datetime');
|
||||
|
||||
const log = (name, msg) => config('log') && console.log(`${datetime()} -> ${name}: ${msg}`);
|
||||
const log = (isLog, name, msg) => isLog && console.log(`${datetime()} -> ${name}: ${msg}`);
|
||||
const makeColor = (a, color) => chalk.rgb(...(color || stringToRGB(a)))(a);
|
||||
const getMessage = (e) => e.message || e;
|
||||
const getDescription = (e) => `${e.type}: ${e.description}`;
|
||||
|
|
|
|||
|
|
@ -15,32 +15,32 @@ const readFile = promisify(fs.readFile);
|
|||
|
||||
const root = require('./root');
|
||||
|
||||
module.exports = callbackify(async (name, request) => {
|
||||
module.exports = callbackify(async (name, rootDir, request) => {
|
||||
check(name, request);
|
||||
|
||||
const {method} = request;
|
||||
|
||||
switch(method) {
|
||||
case 'GET':
|
||||
return onGET(request, name);
|
||||
return onGET(request, name, rootDir);
|
||||
|
||||
case 'PUT':
|
||||
return onPUT(request);
|
||||
}
|
||||
});
|
||||
|
||||
function parseName(query, name) {
|
||||
function parseName(query, name, rootDir) {
|
||||
const shortName = name.replace('/markdown', '');
|
||||
|
||||
if (query === 'relative')
|
||||
return DIR_ROOT + shortName;
|
||||
|
||||
return root(shortName);
|
||||
return root(shortName, rootDir);
|
||||
}
|
||||
|
||||
async function onGET(request, name) {
|
||||
async function onGET(request, name, root) {
|
||||
const query = ponse.getQuery(request);
|
||||
const fileName = parseName(query, name);
|
||||
const fileName = parseName(query, name, root);
|
||||
const data = await readFile(fileName, 'utf8');
|
||||
|
||||
return parse(data);
|
||||
|
|
|
|||
|
|
@ -15,8 +15,12 @@ const cloudcmd = require('..');
|
|||
const config = {
|
||||
auth: false,
|
||||
};
|
||||
|
||||
const configManager = cloudcmd.createConfigManager();
|
||||
|
||||
const {request} = require('serve-once')(cloudcmd, {
|
||||
config,
|
||||
configManager,
|
||||
});
|
||||
|
||||
test('cloudcmd: markdown: error', async (t) => {
|
||||
|
|
@ -64,7 +68,7 @@ test('cloudcmd: markdown: put: error', async (t) => {
|
|||
mdStream.url = 'http://hello.world';
|
||||
mdStream.method = 'PUT';
|
||||
|
||||
const [e] = await tryToCatch(_markdown, name, mdStream);
|
||||
const [e] = await tryToCatch(_markdown, name, '/', mdStream);
|
||||
|
||||
t.ok(e.message.includes('ENOENT: no such file or directory'), 'should emit error');
|
||||
t.end();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ const path = require('path');
|
|||
const fs = require('fs');
|
||||
|
||||
const root = require(DIR + 'root');
|
||||
const config = require(DIR + 'config');
|
||||
const CloudFunc = require(DIR_COMMON + 'cloudfunc');
|
||||
const markdown = require(DIR + 'markdown');
|
||||
const info = require('./info');
|
||||
|
|
@ -16,6 +15,7 @@ const jaguar = require('jaguar');
|
|||
const onezip = require('onezip');
|
||||
const inly = require('inly');
|
||||
const wraptile = require('wraptile');
|
||||
const currify = require('currify');
|
||||
const pullout = require('pullout');
|
||||
const json = require('jonny');
|
||||
const ponse = require('ponse');
|
||||
|
|
@ -27,9 +27,7 @@ const swap = wraptile((fn, a, b) => fn(b, a));
|
|||
const isWin32 = process.platform === 'win32';
|
||||
const {apiURL} = CloudFunc;
|
||||
|
||||
module.exports = (request, response, next) => {
|
||||
check(request, response, next);
|
||||
|
||||
module.exports = currify((config, request, response, next) => {
|
||||
const name = ponse.getPathName(request);
|
||||
const regExp = RegExp('^' + apiURL);
|
||||
const is = regExp.test(name);
|
||||
|
|
@ -37,10 +35,10 @@ module.exports = (request, response, next) => {
|
|||
if (!is)
|
||||
return next();
|
||||
|
||||
rest(request, response);
|
||||
};
|
||||
rest(config, request, response);
|
||||
});
|
||||
|
||||
function rest(request, response) {
|
||||
function rest(config, request, response) {
|
||||
const name = ponse.getPathName(request);
|
||||
const params = {
|
||||
request,
|
||||
|
|
@ -48,7 +46,7 @@ function rest(request, response) {
|
|||
name: name.replace(apiURL, '') || '/',
|
||||
};
|
||||
|
||||
sendData(params, (error, options, data) => {
|
||||
sendData(params, config, (error, options, data) => {
|
||||
params.gzip = !error;
|
||||
|
||||
if (!data) {
|
||||
|
|
@ -65,9 +63,12 @@ function rest(request, response) {
|
|||
if (options.query)
|
||||
params.query = options.query;
|
||||
|
||||
if (error)
|
||||
if (error && error.code)
|
||||
return ponse.sendError(error, params);
|
||||
|
||||
if (error)
|
||||
return ponse.sendError(error.stack, params);
|
||||
|
||||
ponse.send(data, params);
|
||||
});
|
||||
}
|
||||
|
|
@ -77,44 +78,53 @@ function rest(request, response) {
|
|||
*
|
||||
* @param params {name, method, body, requrest, response}
|
||||
*/
|
||||
function sendData(params, callback) {
|
||||
function sendData(params, config, callback) {
|
||||
const p = params;
|
||||
const isMD = RegExp('^/markdown').test(p.name);
|
||||
const rootDir = config('root');
|
||||
|
||||
if (isMD)
|
||||
return markdown(p.name, p.request, callback);
|
||||
return markdown(p.name, rootDir, p.request, callback);
|
||||
|
||||
const {method} = p.request;
|
||||
|
||||
switch(method) {
|
||||
case 'GET':
|
||||
return onGET(params, callback);
|
||||
return onGET(params, config, callback);
|
||||
|
||||
case 'PUT':
|
||||
return pullout(p.request)
|
||||
.then((body) => {
|
||||
onPUT(p.name, body, callback);
|
||||
onPUT({
|
||||
name: p.name,
|
||||
config,
|
||||
body,
|
||||
callback,
|
||||
});
|
||||
})
|
||||
.catch(callback);
|
||||
}
|
||||
}
|
||||
|
||||
function onGET(params, callback) {
|
||||
function onGET(params, config, callback) {
|
||||
let cmd;
|
||||
const p = params;
|
||||
const packer = config('packer');
|
||||
const prefix = config('prefix');
|
||||
const rootDir = config('root');
|
||||
|
||||
if (p.name[0] === '/')
|
||||
cmd = p.name.replace('/', '');
|
||||
|
||||
if (/^pack/.test(cmd)) {
|
||||
cmd = cmd.replace(/^pack/, '');
|
||||
streamPack(root(cmd), p.response);
|
||||
streamPack(root(cmd, rootDir), p.response, packer);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(cmd) {
|
||||
case '':
|
||||
p.data = json.stringify(info());
|
||||
p.data = json.stringify(info(prefix));
|
||||
|
||||
callback(null, {name: 'api.json'}, p.data);
|
||||
break;
|
||||
|
|
@ -127,22 +137,22 @@ function onGET(params, callback) {
|
|||
}
|
||||
}
|
||||
|
||||
function getPackReg() {
|
||||
if (config('packer') === 'zip')
|
||||
function getPackReg(packer) {
|
||||
if (packer === 'zip')
|
||||
return /\.zip$/;
|
||||
|
||||
return /\.tar\.gz$/;
|
||||
}
|
||||
|
||||
function streamPack(cmd, response) {
|
||||
function streamPack(cmd, response, packer) {
|
||||
const noop = () => {};
|
||||
const filename = cmd.replace(getPackReg(), '');
|
||||
const filename = cmd.replace(getPackReg(packer), '');
|
||||
const dir = path.dirname(filename);
|
||||
const names = [
|
||||
path.basename(filename),
|
||||
];
|
||||
|
||||
operation('pack', dir, response, names, noop);
|
||||
operation('pack', packer, dir, response, names, noop);
|
||||
}
|
||||
|
||||
function getCMD(cmd) {
|
||||
|
|
@ -160,25 +170,26 @@ const getMoveMsg = (files) => {
|
|||
};
|
||||
|
||||
module.exports._onPUT = onPUT;
|
||||
function onPUT(name, body, callback) {
|
||||
function onPUT({name, config, body, callback}) {
|
||||
checkPut(name, body, callback);
|
||||
|
||||
const cmd = getCMD(name);
|
||||
const files = json.parse(body);
|
||||
const rootDir = config('root');
|
||||
|
||||
switch(cmd) {
|
||||
case 'mv': {
|
||||
if (!files.from || !files.to)
|
||||
return callback(body);
|
||||
|
||||
if (isRootAll([files.to, files.from]))
|
||||
if (isRootAll(rootDir, [files.to, files.from]))
|
||||
return callback(getWin32RootMsg());
|
||||
|
||||
const msg = getMoveMsg(files);
|
||||
const fn = swap(callback, msg);
|
||||
|
||||
const from = root(files.from);
|
||||
const to = root(files.to);
|
||||
const from = root(files.from, rootDir);
|
||||
const to = root(files.to, rootDir);
|
||||
const {names} = files;
|
||||
|
||||
if (!names)
|
||||
|
|
@ -191,11 +202,11 @@ function onPUT(name, body, callback) {
|
|||
if (!files.from || !files.names || !files.to)
|
||||
return callback(body);
|
||||
|
||||
if (isRootAll([files.to, files.from]))
|
||||
if (isRootAll(rootDir, [files.to, files.from]))
|
||||
return callback(getWin32RootMsg());
|
||||
|
||||
files.from = root(files.from);
|
||||
files.to = root(files.to);
|
||||
files.from = root(files.from, rootDir);
|
||||
files.to = root(files.to, rootDir);
|
||||
|
||||
copy(files.from, files.to, files.names, (error) => {
|
||||
const msg = formatMsg('copy', files.names);
|
||||
|
|
@ -207,14 +218,14 @@ function onPUT(name, body, callback) {
|
|||
if (!files.from)
|
||||
return callback(body);
|
||||
|
||||
pack(files.from, files.to, files.names, callback);
|
||||
pack(files.from, files.to, files.names, config, callback);
|
||||
break;
|
||||
|
||||
case 'extract':
|
||||
if (!files.from)
|
||||
return callback(body);
|
||||
|
||||
extract(files.from, files.to, callback);
|
||||
extract(files.from, files.to, config, callback);
|
||||
|
||||
break;
|
||||
|
||||
|
|
@ -224,9 +235,12 @@ function onPUT(name, body, callback) {
|
|||
}
|
||||
}
|
||||
|
||||
function pack(from, to, names, fn) {
|
||||
from = root(from);
|
||||
to = root(to);
|
||||
function pack(from, to, names, config, fn) {
|
||||
const rootDir = config('root');
|
||||
const packer = config('packer');
|
||||
|
||||
from = root(from, rootDir);
|
||||
to = root(to, rootDir);
|
||||
|
||||
if (!names) {
|
||||
names = [
|
||||
|
|
@ -236,31 +250,33 @@ function pack(from, to, names, fn) {
|
|||
from = path.dirname(from);
|
||||
}
|
||||
|
||||
operation('pack', from, to, names, fn);
|
||||
operation('pack', packer, from, to, names, fn);
|
||||
}
|
||||
|
||||
function extract(from, to, fn) {
|
||||
from = root(from);
|
||||
function extract(from, to, config, fn) {
|
||||
const rootDir = config('root');
|
||||
|
||||
from = root(from, rootDir);
|
||||
|
||||
if (to)
|
||||
to = root(to);
|
||||
to = root(to, rootDir);
|
||||
else
|
||||
to = from.replace(/\.tar\.gz$/, '');
|
||||
|
||||
operation('extract', from, to, fn);
|
||||
operation('extract', config('packer'), from, to, fn);
|
||||
}
|
||||
|
||||
function getPacker(operation) {
|
||||
function getPacker(operation, packer) {
|
||||
if (operation === 'extract')
|
||||
return inly;
|
||||
|
||||
if (config('packer') === 'zip')
|
||||
if (packer === 'zip')
|
||||
return onezip.pack;
|
||||
|
||||
return jaguar.pack;
|
||||
}
|
||||
|
||||
function operation(op, from, to, names, fn) {
|
||||
function operation(op, packer, from, to, names, fn) {
|
||||
if (!fn) {
|
||||
fn = names;
|
||||
names = [
|
||||
|
|
@ -268,8 +284,8 @@ function operation(op, from, to, names, fn) {
|
|||
];
|
||||
}
|
||||
|
||||
const packer = getPacker(op);
|
||||
const pack = packer(from, to, names);
|
||||
const packerFn = getPacker(op, packer);
|
||||
const pack = packerFn(from, to, names);
|
||||
|
||||
pack.on('error', fn);
|
||||
|
||||
|
|
@ -300,17 +316,18 @@ function copy(from, to, names, fn) {
|
|||
});
|
||||
}
|
||||
|
||||
module.exports._isRootWin32 = isRootWin32;
|
||||
function isRootWin32(path) {
|
||||
const isRootWin32 = currify((root, path) => {
|
||||
const isRoot = path === '/';
|
||||
const isConfig = config('root') === '/';
|
||||
const isConfig = root === '/';
|
||||
|
||||
return isWin32 && isRoot && isConfig;
|
||||
}
|
||||
});
|
||||
|
||||
module.exports._isRootWin32 = isRootWin32;
|
||||
module.exports._isRootAll = isRootAll;
|
||||
function isRootAll(names) {
|
||||
return names.some(isRootWin32);
|
||||
|
||||
function isRootAll(root, names) {
|
||||
return names.some(isRootWin32(root));
|
||||
}
|
||||
|
||||
module.exports._getWin32RootMsg = getWin32RootMsg;
|
||||
|
|
@ -339,17 +356,6 @@ function formatMsg(msg, data, status) {
|
|||
return CloudFunc.formatMsg(msg, value, status);
|
||||
}
|
||||
|
||||
function check(request, response, next) {
|
||||
if (typeof request !== 'object')
|
||||
throw Error('request should be an object!');
|
||||
|
||||
if (typeof response !== 'object')
|
||||
throw Error('response should be an object!');
|
||||
|
||||
if (typeof next !== 'function')
|
||||
throw Error('next should be a function!');
|
||||
}
|
||||
|
||||
function checkPut(name, body, callback) {
|
||||
if (typeof name !== 'string')
|
||||
throw Error('name should be a string!');
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
'use strict';
|
||||
|
||||
const test = require('supertape');
|
||||
const tryToCatch = require('try-to-catch');
|
||||
|
||||
const rest = require('.');
|
||||
const {
|
||||
_formatMsg,
|
||||
|
|
@ -34,50 +36,41 @@ test('rest: getWin32RootMsg', (t) => {
|
|||
});
|
||||
|
||||
test('rest: isRootWin32', (t) => {
|
||||
const result = _isRootWin32('/');
|
||||
const result = _isRootWin32('/', '/');
|
||||
|
||||
t.notOk(result, 'should equal');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('rest: isRootAll', (t) => {
|
||||
const result = _isRootAll(['/', '/h']);
|
||||
const result = _isRootAll('/', ['/', '/h']);
|
||||
|
||||
t.notOk(result, 'should equal');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('rest: onPUT: no args', (t) => {
|
||||
t.throws(_onPUT, /name should be a string!/, 'should throw when no args');
|
||||
test('rest: onPUT: no args', async (t) => {
|
||||
const [e] = await tryToCatch(_onPUT, {});
|
||||
t.equal(e.message, 'name should be a string!', 'should throw when no args');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('rest: onPUT: no body', (t) => {
|
||||
const fn = () => _onPUT('hello');
|
||||
t.throws(fn, /body should be a string!/, 'should throw when no body');
|
||||
test('rest: onPUT: no body', async (t) => {
|
||||
const [e] = await tryToCatch(_onPUT, {
|
||||
name: 'hello',
|
||||
});
|
||||
|
||||
t.equal(e.message, 'body should be a string!', 'should throw when no body');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('rest: onPUT: no callback', (t) => {
|
||||
const fn = () => _onPUT('hello', 'world');
|
||||
t.throws(fn, /callback should be a function!/, 'should throw when no callback');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('rest: no args', (t) => {
|
||||
t.throws(rest, /request should be an object!/, 'should throw when no args');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('rest: no response', (t) => {
|
||||
const fn = () => rest({});
|
||||
t.throws(fn, /response should be an object!/, 'should throw when no response');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('rest: no next', (t) => {
|
||||
const fn = () => rest({}, {});
|
||||
t.throws(fn, /next should be a function!/, 'should throw when no response');
|
||||
test('rest: onPUT: no callback', async (t) => {
|
||||
const [e] = await tryToCatch(_onPUT, {
|
||||
name: 'hello',
|
||||
body: 'world',
|
||||
});
|
||||
|
||||
t.equal(e.message, 'callback should be a function!', 'should throw when no callback');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -3,16 +3,15 @@
|
|||
const format = require('format-io');
|
||||
|
||||
const {version} = require('../../package');
|
||||
const config = require('../config');
|
||||
|
||||
const getMemory = () => {
|
||||
const {rss} = process.memoryUsage();
|
||||
return format.size(rss);
|
||||
};
|
||||
|
||||
module.exports = () => ({
|
||||
module.exports = (prefix) => ({
|
||||
version,
|
||||
prefix,
|
||||
memory: getMemory(),
|
||||
prefix: config('prefix'),
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
'use strict';
|
||||
|
||||
const config = require('./config');
|
||||
const mellow = require('mellow');
|
||||
|
||||
module.exports = (dir) => {
|
||||
const root = config('root') || '/';
|
||||
|
||||
return mellow.pathToWin(dir, root);
|
||||
module.exports = (dir, root) => {
|
||||
return mellow.pathToWin(dir, root || '/');
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -8,20 +8,6 @@ const {reRequire} = mockRequire;
|
|||
const pathConfig = './config';
|
||||
const pathRoot = './root';
|
||||
|
||||
test('cloudcmd: root: config', (t) => {
|
||||
const config = stub().returns(false);
|
||||
|
||||
mockRequire(pathConfig, config);
|
||||
const root = reRequire(pathRoot);
|
||||
|
||||
root('hello');
|
||||
|
||||
mockRequire.stop(pathConfig);
|
||||
|
||||
t.ok(config.calledWith('root'), 'should call config');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: root: mellow', (t) => {
|
||||
const config = stub().returns('');
|
||||
const pathToWin = stub();
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ const squad = require('squad');
|
|||
const apart = require('apart');
|
||||
const currify = require('currify');
|
||||
const tryToCatch = require('try-to-catch');
|
||||
const once = require('once');
|
||||
|
||||
const config = require(DIR_SERVER + 'config');
|
||||
const root = require(DIR_SERVER + 'root');
|
||||
|
|
@ -22,6 +23,8 @@ const CloudFunc = require(DIR_COMMON + 'cloudfunc');
|
|||
|
||||
const prefix = squad(prefixer, apart(config, 'prefix'));
|
||||
|
||||
const onceRequire = once(require);
|
||||
|
||||
const sendIndex = (params, data) => {
|
||||
const ponseParams = {
|
||||
...params,
|
||||
|
|
@ -36,36 +39,35 @@ const {FS} = CloudFunc;
|
|||
const Columns = require(`${DIR_SERVER}/columns`);
|
||||
const Template = require(`${DIR_SERVER}/template`);
|
||||
|
||||
const getReadDir = () => {
|
||||
const tokenize = (fn, a) => (b) => fn(a, b);
|
||||
const getReadDir = (config) => {
|
||||
if (!config('dropbox'))
|
||||
return promisify(flop.read);
|
||||
|
||||
const tokenize = (fn, a) => (b) => fn(a, b);
|
||||
const {readDir} = require('@cloudcmd/dropbox');
|
||||
const {readDir} = onceRequire('@cloudcmd/dropbox');
|
||||
|
||||
return tokenize(readDir, config('dropboxToken'));
|
||||
};
|
||||
|
||||
const read = getReadDir();
|
||||
const realpath = promisify(fs.realpath);
|
||||
|
||||
/**
|
||||
* routing of server queries
|
||||
*/
|
||||
module.exports = currify((options, request, response, next) => {
|
||||
module.exports = currify((config, options, request, response, next) => {
|
||||
const name = ponse.getPathName(request);
|
||||
const isFS = RegExp('^/$|^' + FS).test(name);
|
||||
|
||||
if (!isFS)
|
||||
return next();
|
||||
|
||||
route(options, request, response)
|
||||
route({config, options, request, response})
|
||||
.catch(next);
|
||||
});
|
||||
|
||||
module.exports._getReadDir = getReadDir;
|
||||
|
||||
async function route(options, request, response) {
|
||||
async function route({config, options, request, response}) {
|
||||
const name = ponse.getPathName(request);
|
||||
const gzip = true;
|
||||
const p = {
|
||||
|
|
@ -78,13 +80,14 @@ async function route(options, request, response) {
|
|||
config('prefix', prefixer(request.baseUrl));
|
||||
|
||||
const rootName = name.replace(CloudFunc.FS, '') || '/';
|
||||
const fullPath = root(rootName);
|
||||
const fullPath = root(rootName, config('root'));
|
||||
|
||||
const read = getReadDir(config);
|
||||
const [error, dir] = await tryToCatch(read, fullPath);
|
||||
const {html} = options;
|
||||
|
||||
if (!error)
|
||||
return sendIndex(p, buildIndex(html, {
|
||||
return sendIndex(p, buildIndex(config, html, {
|
||||
...dir,
|
||||
path: format.addSlashToEnd(rootName),
|
||||
}));
|
||||
|
|
@ -104,7 +107,7 @@ async function route(options, request, response) {
|
|||
/**
|
||||
* additional processing of index file
|
||||
*/
|
||||
function indexProcessing(options) {
|
||||
function indexProcessing(config, options) {
|
||||
const oneFilePanel = config('oneFilePanel');
|
||||
const noKeysPanel = !config('keysPanel');
|
||||
const noContact = !config('contact');
|
||||
|
|
@ -177,14 +180,14 @@ function indexProcessing(options) {
|
|||
return data;
|
||||
}
|
||||
|
||||
function buildIndex(html, json) {
|
||||
function buildIndex(config, html, json) {
|
||||
const panel = CloudFunc.buildFromJSON({
|
||||
data: json,
|
||||
prefix: prefix(),
|
||||
template: Template,
|
||||
});
|
||||
|
||||
return indexProcessing({
|
||||
return indexProcessing(config, {
|
||||
panel,
|
||||
data: html,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ const routePath = './route';
|
|||
const cloudcmdPath = './cloudcmd';
|
||||
|
||||
const cloudcmd = require(cloudcmdPath);
|
||||
const {createConfigManager} = cloudcmd;
|
||||
const serveOnce = require('serve-once');
|
||||
const defaultConfig = {
|
||||
auth: false,
|
||||
|
|
@ -476,21 +477,15 @@ test('cloudcmd: route: buttons: contact', async (t) => {
|
|||
});
|
||||
|
||||
test('cloudcmd: route: dropbox', async (t) => {
|
||||
const config = require('./config');
|
||||
const dropbox = config('dropbox');
|
||||
const dropboxToken = config('dropboxToken');
|
||||
|
||||
const config = createConfigManager();
|
||||
config('dropbox', true);
|
||||
config('dropboxToken', '');
|
||||
|
||||
const {_getReadDir} = reRequire(routePath);
|
||||
|
||||
const readdir = _getReadDir();
|
||||
const readdir = _getReadDir(config);
|
||||
const [e] = await tryToCatch(readdir, '/root');
|
||||
|
||||
config('dropbox', dropbox);
|
||||
config('dropboxToken', dropboxToken);
|
||||
|
||||
t.ok(/token/.test(e.message), 'should contain word token in message');
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -57,6 +57,9 @@ module.exports = async (options) => {
|
|||
app.use(prefix, cloudcmd({
|
||||
config: options,
|
||||
socket: socketServer,
|
||||
configManager: cloudcmd.createConfigManager({
|
||||
filename: cloudcmd.configPath,
|
||||
}),
|
||||
}));
|
||||
|
||||
if (port < 0 || port > 65535)
|
||||
|
|
|
|||
|
|
@ -1,17 +1,15 @@
|
|||
'use strict';
|
||||
|
||||
const tryCatch = require('try-catch');
|
||||
const config = require('./config');
|
||||
|
||||
const noop = (req, res, next) => {
|
||||
next && next();
|
||||
};
|
||||
|
||||
noop.listen = noop;
|
||||
|
||||
module.exports = (arg) => getTerminal(config('terminal'), arg);
|
||||
|
||||
function getTerminal(term, arg) {
|
||||
if (!term)
|
||||
module.exports = (config, arg) => {
|
||||
if (!config('terminal'))
|
||||
return noop;
|
||||
|
||||
const [e, terminalModule] = tryCatch(require, config('terminalPath'));
|
||||
|
|
@ -26,5 +24,5 @@ function getTerminal(term, arg) {
|
|||
console.log(`cloudcmd --terminal: ${e.message}`);
|
||||
|
||||
return noop;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,33 +4,26 @@ const test = require('supertape');
|
|||
const stub = require('@cloudcmd/stub');
|
||||
|
||||
const mockRequire = require('mock-require');
|
||||
const {reRequire} = mockRequire;
|
||||
|
||||
const configPath = '../../server/config';
|
||||
const terminalPath = '../../server/terminal';
|
||||
const terminalPath = './terminal';
|
||||
const terminal = require('./terminal');
|
||||
const {createConfigManager} = require('./cloudcmd');
|
||||
|
||||
test('cloudcmd: terminal: disabled', (t) => {
|
||||
mockRequire(configPath, () => {
|
||||
return false;
|
||||
});
|
||||
const config = createConfigManager();
|
||||
config('terminal', false);
|
||||
|
||||
const terminal = reRequire('../../server/terminal');
|
||||
const fn = terminal();
|
||||
|
||||
mockRequire.stop(configPath);
|
||||
const fn = terminal(config);
|
||||
|
||||
t.notOk(fn(), 'should return noop');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: terminal: disabled: listen', (t) => {
|
||||
mockRequire(configPath, () => false);
|
||||
const config = createConfigManager();
|
||||
config('terminal', false);
|
||||
|
||||
const terminal = reRequire(terminalPath);
|
||||
const fn = terminal().listen();
|
||||
|
||||
mockRequire.stop(configPath);
|
||||
reRequire(terminalPath);
|
||||
const fn = terminal(config).listen();
|
||||
|
||||
t.notOk(fn, 'should return noop');
|
||||
t.end();
|
||||
|
|
@ -40,15 +33,11 @@ test('cloudcmd: terminal: enabled', (t) => {
|
|||
const term = stub();
|
||||
const arg = 'hello';
|
||||
|
||||
mockRequire(configPath, () => '/terminal');
|
||||
mockRequire(terminalPath, term);
|
||||
|
||||
const terminal = require(terminalPath);
|
||||
terminal(arg);
|
||||
|
||||
mockRequire.stop(configPath);
|
||||
mockRequire.stop(terminalPath);
|
||||
|
||||
t.ok(term.calledWith(arg), 'should call terminal');
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -57,18 +46,16 @@ test('cloudcmd: terminal: enabled: no string', (t) => {
|
|||
const {log:originalLog} = console;
|
||||
const log = stub();
|
||||
|
||||
mockRequire(configPath, () => 'hello');
|
||||
|
||||
console.log = log;
|
||||
const terminal = reRequire(terminalPath);
|
||||
terminal();
|
||||
const config = createConfigManager();
|
||||
|
||||
config('terminal', true);
|
||||
config('terminalPath', 'hello');
|
||||
terminal(config);
|
||||
|
||||
console.log = originalLog;
|
||||
|
||||
mockRequire.stop(configPath);
|
||||
reRequire(terminalPath);
|
||||
|
||||
const msg = 'cloudcmd --terminal: Cannot find module \'hello\'';
|
||||
|
||||
const [arg] = log.args[0];
|
||||
|
||||
t.ok(arg.includes(msg), 'should call with msg');
|
||||
|
|
@ -79,19 +66,13 @@ test('cloudcmd: terminal: no arg', (t) => {
|
|||
const gritty = {};
|
||||
|
||||
mockRequire('gritty', gritty);
|
||||
mockRequire(configPath, (a) => {
|
||||
if (a === 'terminal')
|
||||
return true;
|
||||
|
||||
return 'gritty';
|
||||
});
|
||||
const config = createConfigManager();
|
||||
config('terminal', true);
|
||||
config('terminalPath', 'gritty');
|
||||
|
||||
const terminal = reRequire(terminalPath);
|
||||
const result = terminal();
|
||||
const result = terminal(config);
|
||||
|
||||
mockRequire.stop('gritty');
|
||||
mockRequire.stop(configPath);
|
||||
reRequire(terminalPath);
|
||||
|
||||
t.equal(result, gritty, 'should equal');
|
||||
t.end();
|
||||
|
|
@ -2,11 +2,10 @@
|
|||
|
||||
const tryCatch = require('try-catch');
|
||||
|
||||
const config = require('./config');
|
||||
const exit = require('./exit');
|
||||
const columns = require('./columns');
|
||||
|
||||
module.exports.root = (dir, fn) => {
|
||||
module.exports.root = (dir, config) => {
|
||||
if (typeof dir !== 'string')
|
||||
throw Error('dir should be a string');
|
||||
|
||||
|
|
@ -21,9 +20,6 @@ module.exports.root = (dir, fn) => {
|
|||
|
||||
if (error)
|
||||
return exit('cloudcmd --root: %s', error.message);
|
||||
|
||||
if (typeof fn === 'function')
|
||||
fn('root:', dir);
|
||||
};
|
||||
|
||||
module.exports.editor = (name) => {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ const validatePath = `${dir}/server/validate`;
|
|||
const exitPath = `${dir}/server/exit`;
|
||||
const columnsPath = `${dir}/server/columns`;
|
||||
const cloudcmdPath = `${dir}/server/cloudcmd`;
|
||||
const configPath = `${dir}/server/config`;
|
||||
|
||||
const validate = require(validatePath);
|
||||
const cloudcmd = require(cloudcmdPath);
|
||||
|
|
@ -30,17 +29,11 @@ test('validate: root: bad', (t) => {
|
|||
});
|
||||
|
||||
test('validate: root: config', (t) => {
|
||||
const configFn = stub()
|
||||
.returns(true);
|
||||
const config = stub().returns(true);
|
||||
|
||||
mockRequire(configPath, configFn);
|
||||
validate.root('/hello', config);
|
||||
|
||||
const validate = reRequire(validatePath);
|
||||
validate.root('/hello');
|
||||
|
||||
mockRequire.stop(configPath);
|
||||
|
||||
t.ok(configFn.calledWith('dropbox'), 'should call config');
|
||||
t.ok(config.calledWith('dropbox'), 'should call config');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
@ -52,17 +45,6 @@ test('validate: root: /', (t) => {
|
|||
t.end();
|
||||
});
|
||||
|
||||
test('validate: root: /home', (t) => {
|
||||
const fn = stub();
|
||||
|
||||
validate.root('/home', (...args) => {
|
||||
fn(...args);
|
||||
|
||||
t.ok(fn.calledWith('root:', '/home'), 'should not call fn');
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('validate: root: stat', (t) => {
|
||||
const fn = stub();
|
||||
const {statSync} = fs;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ const {request} = require('serve-once')(cloudcmd, {
|
|||
config: {
|
||||
auth: false,
|
||||
},
|
||||
configManager: cloudcmd.createConfigManager(),
|
||||
});
|
||||
|
||||
const manageConfig = require('../../server/config');
|
||||
|
|
|
|||
|
|
@ -11,8 +11,12 @@ const config = {
|
|||
};
|
||||
|
||||
const cloudcmd = require('../..');
|
||||
const configManager = cloudcmd.createConfigManager();
|
||||
configManager('auth', false);
|
||||
|
||||
const {request} = require('serve-once')(cloudcmd, {
|
||||
config,
|
||||
configManager,
|
||||
});
|
||||
|
||||
test('cloudcmd: rest: cp', async (t) => {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@
|
|||
const test = require('supertape');
|
||||
|
||||
const cloudcmd = require('../..');
|
||||
const {request} = require('serve-once')(cloudcmd);
|
||||
const {request} = require('serve-once')(cloudcmd, {
|
||||
config: {
|
||||
auth: false,
|
||||
},
|
||||
});
|
||||
|
||||
test('cloudcmd: rest: fs: path', async (t) => {
|
||||
const {body} = await request.get(`/api/v1/fs`, {
|
||||
|
|
|
|||
|
|
@ -33,11 +33,14 @@ test('cloudcmd: rest: mv', async (t) => {
|
|||
reRequire(restPath);
|
||||
|
||||
const cloudcmd = reRequire(cloudcmdPath);
|
||||
const {createConfigManager} = cloudcmd;
|
||||
|
||||
const configManager = createConfigManager();
|
||||
configManager('auth', false);
|
||||
configManager('root', '/');
|
||||
|
||||
const {request} = serveOnce(cloudcmd, {
|
||||
config: {
|
||||
root: '/',
|
||||
},
|
||||
configManager,
|
||||
});
|
||||
|
||||
const files = {
|
||||
|
|
@ -77,11 +80,14 @@ test('cloudcmd: rest: mv: rename', async (t) => {
|
|||
reRequire(restPath);
|
||||
|
||||
const cloudcmd = reRequire(cloudcmdPath);
|
||||
const {createConfigManager} = cloudcmd;
|
||||
const configManager = createConfigManager();
|
||||
|
||||
configManager('auth', false);
|
||||
configManager('root', '/');
|
||||
|
||||
const {request} = serveOnce(cloudcmd, {
|
||||
config: {
|
||||
root: '/',
|
||||
},
|
||||
configManager,
|
||||
});
|
||||
|
||||
const files = {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ const defaultOptions = {
|
|||
},
|
||||
};
|
||||
const cloudcmd = require(cloudcmdPath);
|
||||
|
||||
const serveOnce = require('serve-once');
|
||||
const {request} = serveOnce(cloudcmd);
|
||||
|
||||
|
|
@ -37,6 +38,7 @@ const once = promisify((name, extract, fn) => {
|
|||
test('cloudcmd: rest: pack: tar: get', async (t) => {
|
||||
const config = {
|
||||
packer: 'tar',
|
||||
auth: false,
|
||||
};
|
||||
|
||||
const options = {
|
||||
|
|
@ -202,6 +204,7 @@ test('cloudcmd: rest: pack: zip: put: response', async (t) => {
|
|||
test('cloudcmd: rest: pack: zip: put: error', async (t) => {
|
||||
const config = {
|
||||
packer: 'zip',
|
||||
auth: false,
|
||||
};
|
||||
|
||||
const options = {
|
||||
|
|
|
|||
|
|
@ -1,49 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
const test = require('supertape');
|
||||
const rest = require('../../server/rest');
|
||||
|
||||
const {
|
||||
_formatMsg,
|
||||
_getWin32RootMsg,
|
||||
_isRootWin32,
|
||||
_isRootAll,
|
||||
} = rest;
|
||||
|
||||
test('rest: formatMsg', (t) => {
|
||||
const result = _formatMsg('hello', 'world');
|
||||
|
||||
t.equal(result, 'hello: ok("world")', 'should be equal');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('rest: formatMsg: json', (t) => {
|
||||
const result = _formatMsg('hello', {
|
||||
name: 'world',
|
||||
});
|
||||
|
||||
t.equal(result, 'hello: ok("{"name":"world"}")', 'should parse json');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('rest: getWin32RootMsg', (t) => {
|
||||
const {message} = _getWin32RootMsg();
|
||||
|
||||
t.equal(message,'Could not copy from/to root on windows!', 'should return error');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('rest: isRootWin32', (t) => {
|
||||
const result = _isRootWin32('/');
|
||||
|
||||
t.notOk(result, 'should equal');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('rest: isRootAll', (t) => {
|
||||
const result = _isRootAll(['/', '/h']);
|
||||
|
||||
t.notOk(result, 'should equal');
|
||||
t.end();
|
||||
});
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue