mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-23 02:35:49 +00:00
feature(cloudcmd) add ability to read zip files like directories (#309)
This commit is contained in:
parent
0037ec9606
commit
b35a3e029f
9 changed files with 53 additions and 68 deletions
|
|
@ -7,6 +7,7 @@ const inherits = require('inherits');
|
|||
const rendy = require('rendy');
|
||||
const load = require('load.js');
|
||||
const tryToCatch = require('try-to-catch');
|
||||
const {addSlashToEnd} = require('format-io');
|
||||
|
||||
const pascalCase = require('just-pascal-case');
|
||||
const isDev = process.env.NODE_ENV === 'development';
|
||||
|
|
@ -114,9 +115,11 @@ function CloudCmdProto(DOM) {
|
|||
imgPosition = 'top';
|
||||
|
||||
Images.show.load(imgPosition, panel);
|
||||
const path = addSlashToEnd(p.path);
|
||||
console.log(path);
|
||||
|
||||
/* загружаем содержимое каталога */
|
||||
await ajaxLoad(p.path, {
|
||||
await ajaxLoad(path, {
|
||||
refresh,
|
||||
history,
|
||||
noCurrent,
|
||||
|
|
|
|||
|
|
@ -287,9 +287,13 @@ module.exports.setTitle = (name) => {
|
|||
*/
|
||||
module.exports.isCurrentIsDir = (currentFile) => {
|
||||
const current = currentFile || DOM.getCurrentFile();
|
||||
const path = DOM.getCurrentPath(current);
|
||||
const fileType = DOM.getCurrentType(current);
|
||||
|
||||
return /^directory(-link)?/.test(fileType);
|
||||
const isZip = /\.zip$/.test(path);
|
||||
const isDir = /^directory(-link)?/.test(fileType);
|
||||
|
||||
return isDir || isZip;
|
||||
};
|
||||
|
||||
module.exports.getCurrentType = (currentFile) => {
|
||||
|
|
|
|||
|
|
@ -299,10 +299,12 @@ function getDOM({
|
|||
getByDataName = stub(),
|
||||
isContainClass = stub(),
|
||||
getCurrentType = stub(),
|
||||
getCurrentPath = stub(),
|
||||
} = {}) {
|
||||
return {
|
||||
getCurrentDirPath,
|
||||
getCurrentDirName,
|
||||
getCurrentPath,
|
||||
getByDataName,
|
||||
isContainClass,
|
||||
getCurrentType,
|
||||
|
|
|
|||
|
|
@ -267,21 +267,18 @@ function changePanel(element) {
|
|||
}
|
||||
|
||||
async function onDblClick(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const current = getLIElement(event.target);
|
||||
const isDir = DOM.isCurrentIsDir(current);
|
||||
const path = DOM.getCurrentPath(current);
|
||||
|
||||
if (isDir) {
|
||||
await CloudCmd.loadDir({
|
||||
path: path === '/' ? '/' : path + '/',
|
||||
});
|
||||
|
||||
event.preventDefault();
|
||||
} else {
|
||||
CloudCmd.View.show();
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
if (!isDir)
|
||||
return CloudCmd.View.show();
|
||||
|
||||
await CloudCmd.loadDir({
|
||||
path,
|
||||
});
|
||||
}
|
||||
|
||||
async function onTouch(event) {
|
||||
|
|
|
|||
|
|
@ -157,8 +157,9 @@
|
|||
"ponse": "^5.0.0",
|
||||
"pullout": "^4.0.0",
|
||||
"putout": "^13.0.0",
|
||||
"redzip": "^1.0.2",
|
||||
"rendy": "^3.0.0",
|
||||
"restafary": "^9.0.1",
|
||||
"restafary": "^9.1.0",
|
||||
"restbox": "^2.0.0",
|
||||
"shortdate": "^2.0.0",
|
||||
"simport": "^1.0.1",
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ const dword = require('dword');
|
|||
const deepword = require('deepword');
|
||||
const nomine = require('nomine');
|
||||
const fileop = require('@cloudcmd/fileop');
|
||||
//const readzip = require('readzip/lib/middle.js');
|
||||
|
||||
const isDev = process.env.NODE_ENV === 'development';
|
||||
const getDist = (isDev) => isDev ? 'dist-dev' : 'dist';
|
||||
|
|
@ -238,6 +239,13 @@ function cloudcmd({modules, config}) {
|
|||
token: dropboxToken,
|
||||
}),
|
||||
|
||||
/*
|
||||
readzip({
|
||||
prefix: cloudfunc.apiURL + '/fs',
|
||||
root,
|
||||
}),
|
||||
*/
|
||||
|
||||
restafary({
|
||||
prefix: cloudfunc.apiURL + '/fs',
|
||||
root,
|
||||
|
|
|
|||
|
|
@ -3,15 +3,17 @@
|
|||
const DIR_SERVER = './';
|
||||
const DIR_COMMON = '../common/';
|
||||
|
||||
const {realpath} = require('fs').promises;
|
||||
const {extname} = require('path');
|
||||
|
||||
const {read} = require('flop');
|
||||
const {read} = require('redzip');
|
||||
const ponse = require('ponse');
|
||||
const rendy = require('rendy');
|
||||
const format = require('format-io');
|
||||
const currify = require('currify');
|
||||
const tryToCatch = require('try-to-catch');
|
||||
const once = require('once');
|
||||
const pipe = require('pipe-io');
|
||||
const {contentType} = require('mime-types');
|
||||
|
||||
const root = require(DIR_SERVER + 'root');
|
||||
const prefixer = require(DIR_SERVER + 'prefixer');
|
||||
|
|
@ -77,25 +79,27 @@ async function route({config, options, request, response}) {
|
|||
const fullPath = root(rootName, config('root'));
|
||||
|
||||
const read = getReadDir(config);
|
||||
const [error, dir] = await tryToCatch(read, fullPath);
|
||||
const [error, stream] = await tryToCatch(read, fullPath);
|
||||
const {html} = options;
|
||||
|
||||
if (!error)
|
||||
return sendIndex(p, buildIndex(config, html, {
|
||||
...dir,
|
||||
path: format.addSlashToEnd(rootName),
|
||||
}));
|
||||
|
||||
if (error.code !== 'ENOTDIR')
|
||||
if (error)
|
||||
return ponse.sendError(error, p);
|
||||
|
||||
const [realPathError, pathReal] = await tryToCatch(realpath, fullPath);
|
||||
if (stream.type === 'directory') {
|
||||
const {files} = stream;
|
||||
|
||||
return sendIndex(p, buildIndex(config, html, {
|
||||
files,
|
||||
path: format.addSlashToEnd(rootName),
|
||||
}));
|
||||
}
|
||||
|
||||
ponse.sendFile({
|
||||
...p,
|
||||
name: realPathError ? name : pathReal,
|
||||
gzip: false,
|
||||
});
|
||||
response.setHeader('Content-Type', contentType(extname(fullPath)));
|
||||
|
||||
await pipe([
|
||||
stream,
|
||||
response,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ const path = require('path');
|
|||
const fs = require('fs');
|
||||
|
||||
const tryToCatch = require('try-to-catch');
|
||||
const test = require('supertape');
|
||||
const {test, stub} = require('supertape');
|
||||
const mockRequire = require('mock-require');
|
||||
const {reRequire, stopAll} = mockRequire;
|
||||
|
||||
|
|
@ -219,39 +219,6 @@ test('cloudcmd: route: not found', async (t) => {
|
|||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: realpath: error', async (t) => {
|
||||
const error = 'realpath error';
|
||||
const {realpath} = fs.promises;
|
||||
|
||||
fs.promises.realpath = async () => {
|
||||
throw error;
|
||||
};
|
||||
|
||||
const config = {
|
||||
root: fixtureDir,
|
||||
};
|
||||
|
||||
const options = {
|
||||
config,
|
||||
};
|
||||
|
||||
reRequire(routePath);
|
||||
const cloudcmd = reRequire(cloudcmdPath);
|
||||
|
||||
const {request} = serveOnce(cloudcmd, {
|
||||
config: defaultConfig,
|
||||
});
|
||||
|
||||
const {body} = await request.get('/fs/empty-file', {
|
||||
options,
|
||||
});
|
||||
|
||||
fs.promises.realpath = realpath;
|
||||
|
||||
t.ok(/^ENOENT/.test(body), 'should return error');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: route: sendIndex: encode', async (t) => {
|
||||
const name = '"><svg onload=alert(3);>';
|
||||
const nameEncoded = '"><svg onload=alert(3);>';
|
||||
|
|
@ -259,12 +226,12 @@ test('cloudcmd: route: sendIndex: encode', async (t) => {
|
|||
name,
|
||||
}];
|
||||
|
||||
const read = async (path) => ({
|
||||
path,
|
||||
const read = stub().returns({
|
||||
type: 'directory',
|
||||
files,
|
||||
});
|
||||
|
||||
mockRequire('flop', {
|
||||
mockRequire('redzip', {
|
||||
read,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ test('cloudcmd: console: enabled', async (t) => {
|
|||
t.end();
|
||||
});
|
||||
|
||||
// need options to close socket faster
|
||||
test('cloudcmd: console: disabled', async (t) => {
|
||||
const config = {
|
||||
console: false,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue