feature(config-manager) add (#208)

This commit is contained in:
coderaiser 2019-05-30 19:27:21 +03:00
parent fe9723fa15
commit f9c659612a
33 changed files with 446 additions and 477 deletions

View file

@ -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);

View file

@ -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) {

View file

@ -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();
});

View file

@ -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",

View file

@ -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');

View file

@ -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,
}),

View file

@ -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');

View file

@ -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!');
}];
}

View file

@ -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();
});

View file

@ -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}`);
});

View file

@ -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);

View file

@ -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,
});

View file

@ -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}`;

View file

@ -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);

View file

@ -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();

View file

@ -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!');

View file

@ -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();
});

View file

@ -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'),
});

View file

@ -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 || '/');
};

View file

@ -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();

View file

@ -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,
});

View file

@ -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();
});

View file

@ -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)

View file

@ -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;
}
};

View file

@ -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();

View file

@ -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) => {

View file

@ -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;

View file

@ -12,6 +12,7 @@ const {request} = require('serve-once')(cloudcmd, {
config: {
auth: false,
},
configManager: cloudcmd.createConfigManager(),
});
const manageConfig = require('../../server/config');

View file

@ -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) => {

View file

@ -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`, {

View file

@ -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 = {

View file

@ -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 = {

View file

@ -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();
});