cloudcmd 18.5.2 → 18.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -319,7 +319,7 @@ eval("\n\nmodule.exports = (indexFrom, indexTo, files) => {\n if (indexFrom < i
319
319
  /***/ (function(module, exports, __webpack_require__) {
320
320
 
321
321
  "use strict";
322
- eval("/* global DOM, CloudCmd */\n\n\n\nconst exec = __webpack_require__(/*! execon */ \"./node_modules/execon/lib/exec.js\");\nconst itype = __webpack_require__(/*! itype */ \"./node_modules/itype/lib/itype.js\");\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\nconst tryToCatch = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\nconst clipboard = __webpack_require__(/*! @cloudcmd/clipboard */ \"./node_modules/@cloudcmd/clipboard/lib/clipboard.js\");\nconst getRange = __webpack_require__(/*! ./get-range */ \"./client/listeners/get-range.js\");\nconst uploadFiles = __webpack_require__(/*! ../dom/upload-files */ \"./client/dom/upload-files.js\");\nconst {\n FS\n} = __webpack_require__(/*! ../../common/cloudfunc */ \"./common/cloudfunc.js\");\nconst getIndex = currify(__webpack_require__(/*! ./get-index */ \"./client/listeners/get-index.js\"));\nconst NBSP_REG = RegExp(String.fromCharCode(160), 'g');\nconst SPACE = ' ';\nmodule.exports.init = async () => {\n await Promise.all([contextMenu(), dragndrop(), unload(), pop(), resize(), header(), config()]);\n};\nCloudCmd.Listeners = module.exports;\nconst unselect = event => {\n const isMac = /Mac/.test(window.navigator.platform);\n const {\n shiftKey,\n metaKey,\n ctrlKey\n } = event;\n if (shiftKey || isMac && metaKey || ctrlKey) return;\n DOM.unselectFiles();\n};\nconst execAll = currify((funcs, event) => {\n for (const fn of funcs) fn(event);\n});\nconst Info = DOM.CurrentInfo;\nconst {\n Events\n} = DOM;\nconst EventsFiles = {\n mousedown: exec.with(execIfNotUL, setCurrentFileByEvent),\n click: execAll([onClick, exec.with(execIfNotMobile, unselect)]),\n dragstart: exec.with(execIfNotUL, onDragStart),\n dblclick: exec.with(execIfNotUL, onDblClick),\n touchstart: exec.with(execIfNotUL, onTouch)\n};\nlet EXT;\nfunction header() {\n const fm = DOM.getFM();\n const isDataset = el => el.dataset;\n const isPanel = el => {\n return /^js-(left|right)$/.test(el.dataset.name);\n };\n Events.addClick(fm, event => {\n const el = event.target;\n const parent = el.parentElement;\n if (parent.dataset.name !== 'js-fm-header') return;\n const name = (el.dataset.name || '').replace('js-', '');\n if (!/^(name|size|date)$/.test(name)) return;\n const panel = getPath(el).filter(isDataset).filter(isPanel).pop();\n CloudCmd.sortPanel(name, panel);\n });\n}\nfunction getPath(el, path = []) {\n if (!el) return path;\n return getPath(el.parentElement, path.concat(el));\n}\nasync function config() {\n const [, config] = await tryToCatch(DOM.Files.get, 'config');\n const type = config === null || config === void 0 ? void 0 : config.packer;\n EXT = DOM.getPackerExt(type);\n}\nmodule.exports.initKeysPanel = () => {\n const keysElement = DOM.getById('js-keyspanel');\n if (!keysElement) return;\n Events.addClick(keysElement, ({\n target\n }) => {\n const {\n id\n } = target;\n const operation = name => {\n const {\n Operation\n } = CloudCmd;\n return Operation.show.bind(null, name);\n };\n const clickFuncs = {\n 'f1': CloudCmd.Help.show,\n 'f2': CloudCmd.UserMenu.show,\n 'f3': CloudCmd.View.show,\n 'f4': CloudCmd.EditFile.show,\n 'f5': operation('copy'),\n 'f6': operation('move'),\n 'f7': DOM.promptNewDir,\n 'f8': operation('delete'),\n 'f9': CloudCmd.Menu.show,\n 'f10': CloudCmd.Config.show,\n '~': CloudCmd.Konsole.show,\n 'shift~': CloudCmd.Terminal.show,\n 'contact': CloudCmd.Contact.show\n };\n exec(clickFuncs[id]);\n });\n};\nconst getPanel = side => {\n if (!itype.string(side)) return side;\n return DOM.getByDataName(`js-${side}`);\n};\nmodule.exports.setOnPanel = side => {\n const panel = getPanel(side);\n const filesElement = DOM.getByDataName('js-files', panel);\n const pathElement = DOM.getByDataName('js-path', panel);\n\n /* ставим загрузку гифа на клик*/\n Events.addClick(pathElement, getPathListener(panel));\n Events.add(filesElement, EventsFiles);\n};\nfunction getPathListener(panel) {\n return onPathElementClick.bind(null, panel);\n}\nfunction isNoCurrent(panel) {\n const infoPanel = Info.panel;\n if (!infoPanel) return true;\n const namePanel = panel.getAttribute('data-name');\n const nameInfoPanel = infoPanel.getAttribute('data-name');\n return namePanel !== nameInfoPanel;\n}\nfunction decodePath(path) {\n const url = CloudCmd.HOST;\n const {\n prefix\n } = CloudCmd;\n const prefixReg = RegExp('^' + prefix + FS);\n return decodeURI(path).replace(url, '').replace(prefixReg, '') // browser doesn't replace % -> %25% do it for him\n .replace('%%', '%25%').replace(NBSP_REG, SPACE) || '/';\n}\nasync function onPathElementClick(panel, event) {\n event.preventDefault();\n const element = event.target;\n const attr = element.getAttribute('data-name');\n const noCurrent = isNoCurrent(panel);\n if (attr === 'js-copy-path') return copyPath(element);\n if (attr === 'js-refresh') return CloudCmd.refresh({\n panel,\n noCurrent\n });\n if (attr !== 'js-path-link') return;\n const {\n href\n } = element;\n const path = decodePath(href);\n await CloudCmd.changeDir(path, {\n isRefresh: false,\n panel: noCurrent ? panel : Info.panel\n });\n}\nfunction copyPath(el) {\n clipboard.writeText(el.parentElement.title).then(CloudCmd.log).catch(CloudCmd.log);\n}\nfunction execIfNotMobile(callback, event) {\n const isMobile = DOM.getCSSVar('is-mobile');\n if (!isMobile) callback(event);\n}\nfunction execIfNotUL(callback, event) {\n const {\n target\n } = event;\n const {\n tagName\n } = target;\n if (tagName !== 'UL') callback(event);\n}\nfunction onClick(event) {\n event.preventDefault();\n changePanel(event.target);\n}\nfunction toggleSelect(key, files) {\n const isMac = /Mac/.test(window.navigator.platform);\n if (!key) throw Error('key should not be undefined!');\n const [file] = files;\n if (isMac && key.meta || key.ctrl) return DOM.toggleSelectedFile(file);\n if (key.shift) return files.map(DOM.selectFile);\n}\nfunction changePanel(element) {\n const {\n panel\n } = Info;\n const files = DOM.getByDataName('js-files', panel);\n const ul = getULElement(element);\n if (ul !== files) DOM.changePanel();\n}\nasync function onDblClick(event) {\n event.preventDefault();\n const current = getLIElement(event.target);\n const isDir = DOM.isCurrentIsDir(current);\n const path = DOM.getCurrentPath(current);\n if (!isDir) return CloudCmd.View.show();\n await CloudCmd.changeDir(path);\n}\nasync function onTouch(event) {\n const current = getLIElement(event.target);\n const isDir = DOM.isCurrentIsDir(current);\n if (!isDir) return;\n const isCurrent = DOM.isCurrentFile(current);\n if (!isCurrent) return;\n await CloudCmd.changeDir(DOM.getCurrentPath(current));\n}\n\n/*\n * download file from browser to desktop\n * in Chrome (HTML5)\n */\nfunction onDragStart(event) {\n const {\n prefixURL\n } = CloudCmd;\n const element = getLIElement(event.target);\n const {\n isDir\n } = Info;\n let link = DOM.getCurrentLink(element);\n let name = DOM.getCurrentName(element);\n\n /* if it's directory - adding json extension */\n if (isDir) {\n name += EXT;\n link = document.createElement('a');\n link.textContent = name;\n link.href = prefixURL + '/pack' + Info.path + EXT;\n }\n event.dataTransfer.setData('DownloadURL', 'application/octet-stream' + ':' + name + ':' + link);\n}\nfunction getLIElement(element) {\n if (!element) return element;\n while (element.tagName !== 'LI') element = element.parentElement;\n return element;\n}\nfunction getULElement(element) {\n while (element.tagName !== 'UL') element = element.parentElement;\n return element;\n}\nfunction setCurrentFileByEvent(event) {\n const BUTTON_LEFT = 0;\n const key = {\n alt: event.altKey,\n ctrl: event.ctrlKey,\n meta: event.metaKey,\n shift: event.shiftKey\n };\n const element = getLIElement(event.target);\n const fromName = Info.name;\n DOM.setCurrentFile(element);\n const toName = Info.name;\n let files = [];\n if (key.shift) files = getFilesRange(fromName, toName);else files.push(Info.element);\n if (event.button === BUTTON_LEFT) toggleSelect(key, files);\n}\nfunction getFilesRange(from, to) {\n const files = DOM.getAllFiles();\n const names = DOM.getFilenames(files);\n const getNameIndex = getIndex(names);\n const indexFrom = getNameIndex(from);\n const indexTo = getNameIndex(to);\n return getRange(indexFrom, indexTo, files);\n}\nfunction contextMenu() {\n const fm = DOM.getFM();\n Events.addOnce('contextmenu', fm, event => {\n CloudCmd.Menu.show({\n x: event.clientX,\n y: event.clientY\n });\n });\n Events.addContextMenu(fm, event => {\n CloudCmd.Menu.ENABLED || event.preventDefault();\n });\n}\nfunction dragndrop() {\n const panels = DOM.getByClassAll('panel');\n const select = ({\n target\n }) => {\n target.classList.add('selected-panel');\n };\n const unselect = ({\n target\n }) => {\n target.classList.remove('selected-panel');\n };\n const onDrop = event => {\n const {\n files,\n items\n } = event.dataTransfer;\n const {\n length: filesCount\n } = files;\n event.preventDefault();\n if (filesCount && (!items || !items.length || !items[0].webkitGetAsEntry)) return uploadFiles(files);\n const isFile = item => item.kind === 'file';\n const dirFiles = Array.from(items).filter(isFile);\n if (dirFiles.length) return DOM.uploadDirectory(dirFiles);\n const {\n Operation\n } = CloudCmd;\n const operation = event.shiftKey ? 'move' : 'copy';\n return Operation.show(operation);\n };\n\n /**\n * In Mac OS Chrome dropEffect = 'none'\n * so drop do not firing up when try\n * to upload file from download bar\n */\n const onDragOver = event => {\n const {\n dataTransfer\n } = event;\n const {\n effectAllowed\n } = dataTransfer;\n if (/move|linkMove/.test(effectAllowed)) dataTransfer.dropEffect = 'move';else dataTransfer.dropEffect = 'copy';\n event.preventDefault();\n };\n for (const panel of panels) Events.add('dragover', panel, onDragOver).add('drop', panel, onDrop).add('dragenter', select).add(['dragleave', 'drop'], unselect);\n}\nfunction unload() {\n DOM.Events.add(['unload', 'beforeunload'], event => {\n const {\n Key\n } = CloudCmd;\n const isBind = Key === null || Key === void 0 ? void 0 : Key.isBind();\n if (isBind) return;\n event.preventDefault();\n return 'Please make sure that you saved all work.';\n });\n}\nfunction pop() {\n Events.add('popstate', async ({\n state\n }) => {\n const path = (state || '').replace(FS, '');\n if (!path) return CloudCmd.route(location.hash);\n const history = false;\n await CloudCmd.changeDir(path, {\n history\n });\n });\n}\nfunction resize() {\n Events.add('resize', () => {\n const is = window.innerWidth < CloudCmd.MIN_ONE_PANEL_WIDTH;\n if (!is) return;\n const {\n panel\n } = Info;\n const isEmptyRoot = !panel;\n if (isEmptyRoot) return;\n const name = panel.getAttribute('data-name');\n const isLeft = name === 'js-left';\n if (isLeft) return;\n DOM.changePanel();\n });\n}\n\n//# sourceURL=file://cloudcmd/client/listeners/index.js");
322
+ eval("/* global DOM, CloudCmd */\n\n\n\nconst exec = __webpack_require__(/*! execon */ \"./node_modules/execon/lib/exec.js\");\nconst itype = __webpack_require__(/*! itype */ \"./node_modules/itype/lib/itype.js\");\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\nconst tryToCatch = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\nconst clipboard = __webpack_require__(/*! @cloudcmd/clipboard */ \"./node_modules/@cloudcmd/clipboard/lib/clipboard.js\");\nconst getRange = __webpack_require__(/*! ./get-range */ \"./client/listeners/get-range.js\");\nconst uploadFiles = __webpack_require__(/*! ../dom/upload-files */ \"./client/dom/upload-files.js\");\nconst {\n FS\n} = __webpack_require__(/*! ../../common/cloudfunc */ \"./common/cloudfunc.js\");\nconst getIndex = currify(__webpack_require__(/*! ./get-index */ \"./client/listeners/get-index.js\"));\nconst NBSP_REG = RegExp(String.fromCharCode(160), 'g');\nconst SPACE = ' ';\nmodule.exports.init = async () => {\n await Promise.all([contextMenu(), dragndrop(), unload(), pop(), resize(), header(), config()]);\n};\nCloudCmd.Listeners = module.exports;\nconst unselect = event => {\n const isMac = /Mac/.test(window.navigator.platform);\n const {\n shiftKey,\n metaKey,\n ctrlKey\n } = event;\n if (shiftKey || isMac && metaKey || ctrlKey) return;\n DOM.unselectFiles();\n};\nconst execAll = currify((funcs, event) => {\n for (const fn of funcs) fn(event);\n});\nconst Info = DOM.CurrentInfo;\nconst {\n Events\n} = DOM;\nconst EventsFiles = {\n mousedown: exec.with(execIfNotUL, setCurrentFileByEvent),\n click: execAll([onClick, exec.with(execIfNotMobile, unselect)]),\n dragstart: exec.with(execIfNotUL, onDragStart),\n dblclick: exec.with(execIfNotUL, onDblClick),\n touchstart: exec.with(execIfNotUL, onTouch)\n};\nlet EXT;\nfunction header() {\n const fm = DOM.getFM();\n const isDataset = el => el.dataset;\n const isPanel = el => {\n return /^js-(left|right)$/.test(el.dataset.name);\n };\n Events.addClick(fm, event => {\n const el = event.target;\n const parent = el.parentElement;\n if (parent.dataset.name !== 'js-fm-header') return;\n const name = (el.dataset.name || '').replace('js-', '');\n if (!/^(name|size|date)$/.test(name)) return;\n const panel = getPath(el).filter(isDataset).filter(isPanel).pop();\n CloudCmd.sortPanel(name, panel);\n });\n}\nfunction getPath(el, path = []) {\n if (!el) return path;\n return getPath(el.parentElement, path.concat(el));\n}\nasync function config() {\n const [, config] = await tryToCatch(DOM.Files.get, 'config');\n const type = config === null || config === void 0 ? void 0 : config.packer;\n EXT = DOM.getPackerExt(type);\n}\nmodule.exports.initKeysPanel = () => {\n const keysElement = DOM.getById('js-keyspanel');\n if (!keysElement) return;\n Events.addClick(keysElement, ({\n target\n }) => {\n const {\n id\n } = target;\n const operation = name => {\n const {\n Operation\n } = CloudCmd;\n return Operation.show.bind(null, name);\n };\n const clickFuncs = {\n 'f1': CloudCmd.Help.show,\n 'f2': CloudCmd.UserMenu.show,\n 'f3': CloudCmd.View.show,\n 'f4': CloudCmd.EditFile.show,\n 'f5': operation('copy'),\n 'f6': operation('move'),\n 'f7': DOM.promptNewDir,\n 'f8': operation('delete'),\n 'f9': CloudCmd.Menu.show,\n 'f10': CloudCmd.Config.show,\n '~': CloudCmd.Konsole.show,\n 'shift~': CloudCmd.Terminal.show,\n 'contact': CloudCmd.Contact.show\n };\n exec(clickFuncs[id]);\n });\n};\nconst getPanel = side => {\n if (!itype.string(side)) return side;\n return DOM.getByDataName(`js-${side}`);\n};\nmodule.exports.setOnPanel = side => {\n const panel = getPanel(side);\n const filesElement = DOM.getByDataName('js-files', panel);\n const pathElement = DOM.getByDataName('js-path', panel);\n\n /* ставим загрузку гифа на клик*/\n Events.addClick(pathElement, getPathListener(panel));\n Events.add(filesElement, EventsFiles);\n};\nfunction getPathListener(panel) {\n return onPathElementClick.bind(null, panel);\n}\nfunction isNoCurrent(panel) {\n const infoPanel = Info.panel;\n if (!infoPanel) return true;\n const namePanel = panel.getAttribute('data-name');\n const nameInfoPanel = infoPanel.getAttribute('data-name');\n return namePanel !== nameInfoPanel;\n}\nfunction decodePath(path) {\n const url = CloudCmd.HOST;\n const {\n prefix\n } = CloudCmd;\n const prefixReg = RegExp('^' + prefix + FS);\n return decodeURI(path).replace(url, '').replace(prefixReg, '') // browser doesn't replace % -> %25% do it for him\n .replace('%%', '%25%').replace(NBSP_REG, SPACE) || '/';\n}\nasync function onPathElementClick(panel, event) {\n event.preventDefault();\n const element = event.target;\n const attr = element.getAttribute('data-name');\n const noCurrent = isNoCurrent(panel);\n if (attr === 'js-copy-path') return copyPath(element);\n if (attr === 'js-refresh') return CloudCmd.refresh({\n panel,\n noCurrent\n });\n if (attr !== 'js-path-link') return;\n const {\n href\n } = element;\n const path = decodePath(href);\n await CloudCmd.changeDir(path, {\n isRefresh: false,\n panel: noCurrent ? panel : Info.panel\n });\n}\nfunction copyPath(el) {\n clipboard.writeText(el.parentElement.title).then(CloudCmd.log).catch(CloudCmd.log);\n}\nfunction execIfNotMobile(callback, event) {\n const isMobile = DOM.getCSSVar('is-mobile');\n if (!isMobile) callback(event);\n}\nfunction execIfNotUL(callback, event) {\n const {\n target\n } = event;\n const {\n tagName\n } = target;\n if (tagName !== 'UL') callback(event);\n}\nfunction onClick(event) {\n event.preventDefault();\n changePanel(event.target);\n}\nfunction toggleSelect(key, files) {\n const isMac = /Mac/.test(window.navigator.platform);\n if (!key) throw Error('key should not be undefined!');\n const [file] = files;\n if (isMac && key.meta || key.ctrl) return DOM.toggleSelectedFile(file);\n if (key.shift) return files.map(DOM.selectFile);\n}\nfunction changePanel(element) {\n const {\n panel\n } = Info;\n const files = DOM.getByDataName('js-files', panel);\n const ul = getULElement(element);\n if (ul !== files) DOM.changePanel();\n}\nasync function onDblClick(event) {\n event.preventDefault();\n const current = getLIElement(event.target);\n const isDir = DOM.isCurrentIsDir(current);\n const path = DOM.getCurrentPath(current);\n if (!isDir) return CloudCmd.View.show();\n await CloudCmd.changeDir(path);\n}\nasync function onTouch(event) {\n const current = getLIElement(event.target);\n const isDir = DOM.isCurrentIsDir(current);\n if (!isDir) return;\n const isCurrent = DOM.isCurrentFile(current);\n if (!isCurrent) return;\n await CloudCmd.changeDir(DOM.getCurrentPath(current));\n}\n\n/*\n * download file from browser to desktop\n * in Chrome (HTML5)\n */\nfunction onDragStart(event) {\n const {\n prefixURL\n } = CloudCmd;\n const element = getLIElement(event.target);\n const {\n isDir\n } = Info;\n let link = DOM.getCurrentLink(element);\n let name = DOM.getCurrentName(element);\n\n /* if it's directory - adding json extension */\n if (isDir) {\n name += EXT;\n link = document.createElement('a');\n link.textContent = name;\n link.href = prefixURL + '/pack' + Info.path + EXT;\n }\n event.dataTransfer.setData('DownloadURL', 'application/octet-stream' + ':' + name + ':' + link);\n}\nfunction getLIElement(element) {\n if (!element) return element;\n while (element.tagName !== 'LI') element = element.parentElement;\n return element;\n}\nfunction getULElement(element) {\n while (element.tagName !== 'UL') element = element.parentElement;\n return element;\n}\nfunction setCurrentFileByEvent(event) {\n const BUTTON_LEFT = 0;\n const key = {\n alt: event.altKey,\n ctrl: event.ctrlKey,\n meta: event.metaKey,\n shift: event.shiftKey\n };\n const element = getLIElement(event.target);\n const fromName = Info.name;\n DOM.setCurrentFile(element);\n const toName = Info.name;\n let files = [];\n if (key.shift) files = getFilesRange(fromName, toName);else files.push(Info.element);\n if (event.button === BUTTON_LEFT) toggleSelect(key, files);\n}\nfunction getFilesRange(from, to) {\n const files = DOM.getAllFiles();\n const names = DOM.getFilenames(files);\n const getNameIndex = getIndex(names);\n const indexFrom = getNameIndex(from);\n const indexTo = getNameIndex(to);\n return getRange(indexFrom, indexTo, files);\n}\nfunction contextMenu() {\n const fm = DOM.getFM();\n Events.addOnce('contextmenu', fm, event => {\n CloudCmd.Menu.show({\n x: event.clientX,\n y: event.clientY\n });\n });\n Events.addContextMenu(fm, event => {\n CloudCmd.Menu.ENABLED || event.preventDefault();\n });\n}\nfunction dragndrop() {\n const panels = DOM.getByClassAll('panel');\n const select = ({\n target\n }) => {\n target.classList.add('selected-panel');\n };\n const unselect = ({\n target\n }) => {\n target.classList.remove('selected-panel');\n };\n const onDrop = event => {\n const {\n files,\n items\n } = event.dataTransfer;\n const {\n length: filesCount\n } = files;\n event.preventDefault();\n if (filesCount && (!items || !items.length || !items[0].webkitGetAsEntry)) return uploadFiles(files);\n const isFile = item => item.kind === 'file';\n const dirFiles = Array.from(items).filter(isFile);\n if (dirFiles.length) return DOM.uploadDirectory(dirFiles);\n const {\n Operation\n } = CloudCmd;\n const operation = event.shiftKey ? 'move' : 'copy';\n return Operation.show(operation);\n };\n\n /**\n * In macOS Chrome dropEffect = 'none'\n * so drop do not firing up when try\n * to upload file from download bar\n */\n const onDragOver = event => {\n const {\n dataTransfer\n } = event;\n const {\n effectAllowed\n } = dataTransfer;\n if (/move|linkMove/.test(effectAllowed)) dataTransfer.dropEffect = 'move';else dataTransfer.dropEffect = 'copy';\n event.preventDefault();\n };\n for (const panel of panels) Events.add('dragover', panel, onDragOver).add('drop', panel, onDrop).add('dragenter', select).add(['dragleave', 'drop'], unselect);\n}\nfunction unload() {\n DOM.Events.add(['unload', 'beforeunload'], event => {\n const {\n Key\n } = CloudCmd;\n const isBind = Key === null || Key === void 0 ? void 0 : Key.isBind();\n if (isBind) return;\n event.preventDefault();\n return 'Please make sure that you saved all work.';\n });\n}\nfunction pop() {\n Events.add('popstate', async ({\n state\n }) => {\n const path = (state || '').replace(FS, '');\n if (!path) return CloudCmd.route(location.hash);\n const history = false;\n await CloudCmd.changeDir(path, {\n history\n });\n });\n}\nfunction resize() {\n Events.add('resize', () => {\n const is = window.innerWidth < CloudCmd.MIN_ONE_PANEL_WIDTH;\n if (!is) return;\n const {\n panel\n } = Info;\n const isEmptyRoot = !panel;\n if (isEmptyRoot) return;\n const name = panel.getAttribute('data-name');\n const isLeft = name === 'js-left';\n if (isLeft) return;\n DOM.changePanel();\n });\n}\n\n//# sourceURL=file://cloudcmd/client/listeners/index.js");
323
323
 
324
324
  /***/ }),
325
325
 
package/dist-dev/sw.js CHANGED
@@ -103,7 +103,7 @@ var serviceWorkerOption = {
103
103
  /***/ (function(module, exports, __webpack_require__) {
104
104
 
105
105
  "use strict";
106
- eval("\n\nconst process = __webpack_require__(/*! node:process */ \"./node_modules/process/browser.js\");\nconst tryToCatch = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\nconst isDev = process.env.NODE_ENV === 'development';\nconst isGet = a => a.method === 'GET';\nconst isBasic = a => a.type === 'basic';\nconst wait = currify((f, e) => e.waitUntil(f()));\nconst respondWith = currify((f, e) => {\n const {\n request\n } = e;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n if (url.endsWith('/') || /\\^\\/fs/.test(pathname)) return;\n if (!isGet(request)) return;\n if (!isBasic(request)) return;\n if (pathname.startsWith('/api')) return;\n if (/^socket.io/.test(pathname)) return;\n e.respondWith(f(e));\n});\nconst getPathName = url => new URL(url).pathname;\nconst date = \"Thu Apr 10 2025 17:24:08 GMT+0300 (Eastern European Summer Time)\";\nconst NAME = `cloudcmd: ${date}`;\nconst createRequest = a => new Request(a, {\n credentials: 'same-origin'\n});\nconst getRequest = (a, request) => {\n if (a !== '/') return request;\n return createRequest('/');\n};\nself.addEventListener('install', wait(onInstall));\nself.addEventListener('fetch', respondWith(onFetch));\nself.addEventListener('activate', wait(onActivate));\nasync function onActivate() {\n console.info(`cloudcmd: sw: activate: ${NAME}`);\n await self.clients.claim();\n const keys = await caches.keys();\n const deleteCache = caches.delete.bind(caches);\n await Promise.all(keys.map(deleteCache));\n}\nasync function onInstall() {\n console.info(`cloudcmd: sw: install: ${NAME}`);\n await self.skipWaiting();\n}\nasync function onFetch(event) {\n const {\n request\n } = event;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n const newRequest = getRequest(pathname, event.request);\n const cache = await caches.open(NAME);\n const response = await cache.match(request);\n if (!isDev && response) return response;\n const [e, resp] = await tryToCatch(fetch, newRequest, {\n credentials: 'same-origin'\n });\n if (e) return new Response(e.message);\n await addToCache(request, resp.clone());\n return resp;\n}\nasync function addToCache(request, response) {\n const cache = await caches.open(NAME);\n return cache.put(request, response);\n}\n\n//# sourceURL=file://cloudcmd/client/sw/sw.js");
106
+ eval("\n\nconst process = __webpack_require__(/*! node:process */ \"./node_modules/process/browser.js\");\nconst tryToCatch = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\nconst isDev = process.env.NODE_ENV === 'development';\nconst isGet = a => a.method === 'GET';\nconst isBasic = a => a.type === 'basic';\nconst wait = currify((f, e) => e.waitUntil(f()));\nconst respondWith = currify((f, e) => {\n const {\n request\n } = e;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n if (url.endsWith('/') || /\\^\\/fs/.test(pathname)) return;\n if (!isGet(request)) return;\n if (!isBasic(request)) return;\n if (pathname.startsWith('/api')) return;\n if (/^socket.io/.test(pathname)) return;\n e.respondWith(f(e));\n});\nconst getPathName = url => new URL(url).pathname;\nconst date = \"Fri Jul 04 2025 13:41:50 GMT+0300 (Eastern European Summer Time)\";\nconst NAME = `cloudcmd: ${date}`;\nconst createRequest = a => new Request(a, {\n credentials: 'same-origin'\n});\nconst getRequest = (a, request) => {\n if (a !== '/') return request;\n return createRequest('/');\n};\nself.addEventListener('install', wait(onInstall));\nself.addEventListener('fetch', respondWith(onFetch));\nself.addEventListener('activate', wait(onActivate));\nasync function onActivate() {\n console.info(`cloudcmd: sw: activate: ${NAME}`);\n await self.clients.claim();\n const keys = await caches.keys();\n const deleteCache = caches.delete.bind(caches);\n await Promise.all(keys.map(deleteCache));\n}\nasync function onInstall() {\n console.info(`cloudcmd: sw: install: ${NAME}`);\n await self.skipWaiting();\n}\nasync function onFetch(event) {\n const {\n request\n } = event;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n const newRequest = getRequest(pathname, event.request);\n const cache = await caches.open(NAME);\n const response = await cache.match(request);\n if (!isDev && response) return response;\n const [e, resp] = await tryToCatch(fetch, newRequest, {\n credentials: 'same-origin'\n });\n if (e) return new Response(e.message);\n await addToCache(request, resp.clone());\n return resp;\n}\nasync function addToCache(request, response) {\n const cache = await caches.open(NAME);\n return cache.put(request, response);\n}\n\n//# sourceURL=file://cloudcmd/client/sw/sw.js");
107
107
 
108
108
  /***/ }),
109
109
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudcmd",
3
- "version": "18.5.2",
3
+ "version": "18.6.1",
4
4
  "type": "commonjs",
5
5
  "author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
6
6
  "description": "File manager for the web with console and editor",
@@ -86,7 +86,6 @@
86
86
  },
87
87
  "subdomain": "cloudcmd",
88
88
  "dependencies": {
89
- "@babel/core": "^7.22.9",
90
89
  "@babel/plugin-transform-optional-chaining": "^7.21.0",
91
90
  "@cloudcmd/dropbox": "^5.0.1",
92
91
  "@cloudcmd/fileop": "^8.0.0",
@@ -106,13 +105,13 @@
106
105
  "edward": "^15.0.0",
107
106
  "es6-promisify": "^7.0.0",
108
107
  "execon": "^1.2.0",
109
- "express": "^4.13.0",
108
+ "express": "^5.1.0",
110
109
  "files-io": "^4.0.0",
111
110
  "find-up": "^7.0.0",
112
111
  "for-each-key": "^2.0.0",
113
112
  "format-io": "^2.0.0",
114
113
  "fullstore": "^3.0.0",
115
- "http-auth": "4.1.2 || > 4.1.3",
114
+ "http-auth": "^4.2.1",
116
115
  "inly": "^5.0.0",
117
116
  "jaguar": "^6.0.0",
118
117
  "jju": "^1.3.0",
@@ -120,6 +119,8 @@
120
119
  "just-snake-case": "^3.2.0",
121
120
  "markdown-it": "^14.0.0",
122
121
  "mellow": "^3.0.0",
122
+ "mime-types": "^3.0.1",
123
+ "montag": "^1.2.1",
123
124
  "nano-memoize": "^3.0.16",
124
125
  "nomine": "^4.0.0",
125
126
  "object.omit": "^3.0.0",
@@ -127,6 +128,7 @@
127
128
  "onezip": "^6.0.1",
128
129
  "open": "^10.0.3",
129
130
  "package-json": "^10.0.0",
131
+ "pipe-io": "^4.0.1",
130
132
  "ponse": "^7.0.0",
131
133
  "pullout": "^5.0.0",
132
134
  "putout": "^40.0.3",
@@ -140,16 +142,16 @@
140
142
  "socket.io-client": "^4.0.1",
141
143
  "squad": "^3.0.0",
142
144
  "table": "^6.0.1",
143
- "thread-it": "^2.0.0",
144
145
  "try-catch": "^3.0.0",
145
146
  "try-to-catch": "^3.0.0",
146
147
  "tryrequire": "^3.0.0",
147
148
  "win32": "^7.0.0",
148
149
  "wraptile": "^3.0.0",
149
150
  "writejson": "^3.0.0",
150
- "yargs-parser": "^21.0.0"
151
+ "yargs-parser": "^22.0.0"
151
152
  },
152
153
  "devDependencies": {
154
+ "@babel/core": "^7.22.5",
153
155
  "@babel/code-frame": "^7.22.5",
154
156
  "@babel/preset-env": "^7.0.0",
155
157
  "@cloudcmd/clipboard": "^2.0.0",
@@ -157,7 +159,8 @@
157
159
  "@cloudcmd/modal": "^3.0.0",
158
160
  "@cloudcmd/olark": "^3.0.2",
159
161
  "@cloudcmd/stub": "^4.0.1",
160
- "@putout/babel": "^3.0.0",
162
+ "@iocmd/wait": "^2.1.0",
163
+ "@putout/eslint-flat": "^3.0.1",
161
164
  "@putout/plugin-cloudcmd": "^4.0.0",
162
165
  "@types/node-fetch": "^2.6.11",
163
166
  "auto-globals": "^4.0.0",
@@ -173,8 +176,9 @@
173
176
  "emitify": "^4.0.1",
174
177
  "eslint": "^9.23.0",
175
178
  "eslint-plugin-n": "^17.0.0-4",
176
- "eslint-plugin-putout": "^26.1.0",
179
+ "eslint-plugin-putout": "^27.2.1",
177
180
  "extract-text-webpack-plugin": "^4.0.0-alpha.0",
181
+ "globals": "^16.3.0",
178
182
  "gritty": "^8.0.0",
179
183
  "gunzip-maybe": "^1.3.1",
180
184
  "html-looks-like": "^1.0.2",
@@ -188,7 +192,6 @@
188
192
  "memfs": "^4.2.0",
189
193
  "minor": "^1.2.2",
190
194
  "mock-require": "^3.0.1",
191
- "montag": "^1.2.1",
192
195
  "morgan": "^1.6.1",
193
196
  "multi-rename": "^2.0.0",
194
197
  "nodemon": "^3.0.1",
@@ -213,10 +216,10 @@
213
216
  "webpack": "^4.0.0",
214
217
  "webpack-cli": "^3.0.1",
215
218
  "webpack-merge": "^6.0.1",
216
- "webpackbar": "^5.0.0-3"
219
+ "webpackbar": "^7.0.0"
217
220
  },
218
221
  "engines": {
219
- "node": ">=20"
222
+ "node": ">=20.19"
220
223
  },
221
224
  "license": "MIT",
222
225
  "publishConfig": {
@@ -1,18 +1,16 @@
1
1
  'use strict';
2
2
 
3
- const {join} = require('node:path');
4
3
  const {callbackify} = require('node:util');
5
4
 
6
5
  const pullout = require('pullout');
7
6
  const ponse = require('ponse');
8
- const threadIt = require('thread-it');
9
7
  const {read} = require('redzip');
10
8
 
11
9
  const root = require('../root');
10
+
11
+ const parse = require('./worker');
12
12
  const isString = (a) => typeof a === 'string';
13
- const parse = threadIt(join(__dirname, 'worker'));
14
13
 
15
- threadIt.init();
16
14
  // warm up
17
15
  parse('');
18
16
 
package/server/repl.js CHANGED
@@ -6,22 +6,22 @@ const repl = require('node:repl');
6
6
 
7
7
  module.exports = net
8
8
  .createServer((socket) => {
9
- const {pid} = process;
10
- const addr = socket.remoteAddress;
11
- const port = socket.remotePort;
12
-
13
- const r = repl.start({
14
- prompt: `[${pid} ${addr}:${port}>`,
15
- input: socket,
16
- output: socket,
17
- terminal: true,
18
- useGlobal: false,
19
- });
20
-
21
- r.on('exit', () => {
22
- socket.end();
23
- });
24
-
25
- r.context.socket = socket;
26
- })
9
+ const {pid} = process;
10
+ const addr = socket.remoteAddress;
11
+ const port = socket.remotePort;
12
+
13
+ const r = repl.start({
14
+ prompt: `[${pid} ${addr}:${port}>`,
15
+ input: socket,
16
+ output: socket,
17
+ terminal: true,
18
+ useGlobal: false,
19
+ });
20
+
21
+ r.on('exit', () => {
22
+ socket.end();
23
+ });
24
+
25
+ r.context.socket = socket;
26
+ })
27
27
  .listen(1337);
package/server/server.mjs CHANGED
@@ -10,7 +10,6 @@ import {Server} from 'socket.io';
10
10
  import tryRequire from 'tryrequire';
11
11
  import wraptile from 'wraptile';
12
12
  import compression from 'compression';
13
- import threadIt from 'thread-it';
14
13
  import exit from './exit.js';
15
14
  import cloudcmd from './cloudcmd.mjs';
16
15
 
@@ -20,7 +19,6 @@ const two = currify((f, a, b) => f(a, b));
20
19
  const shutdown = wraptile(async (promises) => {
21
20
  console.log('closing cloudcmd...');
22
21
  await Promise.all(promises);
23
- threadIt.terminate();
24
22
  process.exit(0);
25
23
  });
26
24
 
@@ -11,9 +11,9 @@ module.exports = (config) => {
11
11
  const data = Object
12
12
  .keys(config)
13
13
  .map((name) => [
14
- name,
15
- config[name],
16
- ]);
14
+ name,
15
+ config[name],
16
+ ]);
17
17
 
18
18
  if (!data.length)
19
19
  return '';
@@ -1,17 +1,11 @@
1
- import {createRequire} from 'node:module';
2
1
  import {homedir} from 'node:os';
3
2
  import {readFile as _readFile} from 'node:fs/promises';
4
3
  import {join} from 'node:path';
5
4
  import montag from 'montag';
6
5
  import tryToCatch from 'try-to-catch';
7
6
  import currify from 'currify';
8
- import threadIt from 'thread-it';
9
- import {codeframe} from 'putout';
7
+ import {putout, codeframe} from 'putout';
10
8
 
11
- const require = createRequire(import.meta.url);
12
- const putout = threadIt(require.resolve('putout'));
13
-
14
- threadIt.init();
15
9
  // warm up worker cache
16
10
  transpile('');
17
11
 
@@ -80,10 +74,10 @@ async function onGET({req, res, menuName, readFile}) {
80
74
  function getError(error, source) {
81
75
  return montag`
82
76
  const e = Error(\`<pre>${codeframe({
83
- error,
84
- source,
85
- highlightCode: false,
86
- })}</pre>\`);
77
+ error,
78
+ source,
79
+ highlightCode: false,
80
+ })}</pre>\`);
87
81
 
88
82
  e.code = 'frame';
89
83
 
package/bin/release.mjs DELETED
@@ -1,75 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import {promisify} from 'node:util';
4
- import process from 'node:process';
5
- import tryToCatch from 'try-to-catch';
6
- import {createSimport} from 'simport';
7
- import minor from 'minor';
8
- import _place from 'place';
9
- import rendy from 'rendy';
10
- import shortdate from 'shortdate';
11
-
12
- const simport = createSimport(import.meta.url);
13
- const place = promisify(_place);
14
-
15
- const Info = await simport('../package.json');
16
-
17
- await main();
18
-
19
- async function main() {
20
- const history = '## Version history\n\n';
21
- const link = '//github.com/coderaiser/cloudcmd/releases/tag/';
22
- const template =
23
- '- *{{ date }}*, ' +
24
- '**[v{{ version }}]' +
25
- '(' + link +
26
- 'v{{ version }})**\n';
27
-
28
- const {version} = Info;
29
-
30
- const [error, versionNew] = await tryToCatch(cl);
31
-
32
- if (error)
33
- return console.error(error);
34
-
35
- await replaceVersion('README.md', version, versionNew);
36
- await replaceVersion('HELP.md', version, versionNew);
37
-
38
- const historyNew = history + rendy(template, {
39
- date: shortdate(),
40
- version: versionNew,
41
- });
42
-
43
- await replaceVersion('HELP.md', history, historyNew);
44
- }
45
-
46
- async function replaceVersion(name, version, versionNew) {
47
- const [error] = await tryToCatch(place, name, version, versionNew);
48
-
49
- if (error)
50
- return console.error(error);
51
-
52
- console.log(`done: ${name}`);
53
- }
54
-
55
- async function cl() {
56
- const {argv} = process;
57
- const length = argv.length - 1;
58
- const last = process.argv[length];
59
- const regExp = /^--(major|minor|patch)$/;
60
- const [, match] = last.match(regExp) || [];
61
-
62
- console.log(last);
63
-
64
- if (!regExp.test(last))
65
- throw Error('ERROR: version is missing. release --patch|--minor|--major');
66
-
67
- return getVersionNew(last, match);
68
- }
69
-
70
- function getVersionNew(last, match) {
71
- if (match)
72
- return minor(match, Info.version);
73
-
74
- return last.substr(3);
75
- }
@@ -1,197 +0,0 @@
1
- import path, {dirname} from 'node:path';
2
- import {fileURLToPath} from 'node:url';
3
- import serveOnce from 'serve-once';
4
- import {test, stub} from 'supertape';
5
- import cloudcmd, {
6
- _isDev,
7
- _replaceDist,
8
- createConfigManager,
9
- _getPrefix,
10
- _initAuth,
11
- _getIndexPath,
12
- } from './cloudcmd.mjs';
13
-
14
- const __filename = fileURLToPath(import.meta.url);
15
- const __dirname = dirname(__filename);
16
-
17
- const {request} = serveOnce(cloudcmd, {
18
- config: {
19
- auth: false,
20
- dropbox: false,
21
- },
22
- });
23
-
24
- test('cloudcmd: defaults: config', (t) => {
25
- const configManager = createConfigManager();
26
-
27
- configManager('configDialog', false);
28
-
29
- cloudcmd({
30
- configManager,
31
- });
32
-
33
- t.notOk(configManager('configDialog'), 'should not override config with defaults');
34
- t.end();
35
- });
36
-
37
- test('cloudcmd: defaults: console', (t) => {
38
- const configManager = createConfigManager();
39
- configManager('console', false);
40
-
41
- cloudcmd({
42
- configManager,
43
- });
44
-
45
- t.notOk(configManager('console'), 'should not override config with defaults');
46
- t.end();
47
- });
48
-
49
- test('cloudcmd: getPrefix', (t) => {
50
- const value = 'hello';
51
- const result = _getPrefix(value);
52
-
53
- t.equal(result, value);
54
- t.end();
55
- });
56
-
57
- test('cloudcmd: getPrefix: function', (t) => {
58
- const value = 'hello';
59
- const fn = () => value;
60
- const result = _getPrefix(fn);
61
-
62
- t.equal(result, value);
63
- t.end();
64
- });
65
-
66
- test('cloudcmd: getPrefix: function: empty', (t) => {
67
- const value = null;
68
- const fn = () => value;
69
- const result = _getPrefix(fn);
70
-
71
- t.equal(result, '');
72
- t.end();
73
- });
74
-
75
- test('cloudcmd: replaceDist', (t) => {
76
- const currentIsDev = _isDev();
77
-
78
- _isDev(true);
79
- const url = '/dist/hello';
80
- const result = _replaceDist(url);
81
- const expected = '/dist-dev/hello';
82
-
83
- _isDev(currentIsDev);
84
-
85
- t.equal(result, expected);
86
- t.end();
87
- });
88
-
89
- test('cloudcmd: replaceDist: !isDev', (t) => {
90
- const url = '/dist/hello';
91
-
92
- const currentIsDev = _isDev();
93
- _isDev(false);
94
- const result = _replaceDist(url);
95
-
96
- _isDev(currentIsDev);
97
-
98
- t.equal(result, url);
99
- t.end();
100
- });
101
-
102
- test('cloudcmd: auth: reject', (t) => {
103
- const accept = stub();
104
- const reject = stub();
105
-
106
- const config = createConfigManager();
107
-
108
- const username = 'root';
109
- const password = 'toor';
110
-
111
- config('auth', true);
112
- config('username', username);
113
- config('password', password);
114
-
115
- _initAuth(config, accept, reject, username, 'abc');
116
-
117
- t.ok(reject.called, 'should reject');
118
- t.end();
119
- });
120
-
121
- test('cloudcmd: auth: accept', (t) => {
122
- const accept = stub();
123
- const reject = stub();
124
-
125
- const username = 'root';
126
- const password = 'toor';
127
- const auth = true;
128
-
129
- const config = createConfigManager();
130
- config('username', username);
131
- config('password', password);
132
- config('auth', auth);
133
-
134
- _initAuth(config, accept, reject, username, password);
135
-
136
- t.ok(accept.called, 'should accept');
137
- t.end();
138
- });
139
-
140
- test('cloudcmd: auth: accept: no auth', (t) => {
141
- const accept = stub();
142
- const reject = stub();
143
-
144
- const auth = false;
145
- const username = 'root';
146
- const password = 'toor';
147
-
148
- const config = createConfigManager();
149
- config('username', username);
150
- config('password', password);
151
- config('auth', auth);
152
-
153
- _initAuth(config, accept, reject, username, password);
154
-
155
- t.ok(accept.called, 'should accept');
156
- t.end();
157
- });
158
-
159
- test('cloudcmd: getIndexPath: production', (t) => {
160
- const isDev = false;
161
- const name = path.join(__dirname, '..', 'dist', 'index.html');
162
-
163
- t.equal(_getIndexPath(isDev), name);
164
- t.end();
165
- });
166
-
167
- test('cloudcmd: getIndexPath: development', (t) => {
168
- const isDev = true;
169
- const name = path.join(__dirname, '..', 'dist-dev', 'index.html');
170
-
171
- t.equal(_getIndexPath(isDev), name);
172
- t.end();
173
- });
174
-
175
- test('cloudcmd: sw', async (t) => {
176
- const {status} = await request.get('/sw.js');
177
-
178
- t.equal(status, 200, 'should return sw');
179
- t.end();
180
- });
181
-
182
- test('cloudcmd: manifest.json', async (t) => {
183
- const config = {
184
- auth: true,
185
- };
186
-
187
- const options = {
188
- config,
189
- };
190
-
191
- const {status} = await request.get('/public/manifest.json', {
192
- options,
193
- });
194
-
195
- t.equal(status, 200, 'should return manifest.json even when authentication is enabled');
196
- t.end();
197
- });
@@ -1,40 +0,0 @@
1
- import {dirname} from 'node:path';
2
- import {fileURLToPath} from 'node:url';
3
- import fs from 'node:fs';
4
- import test from 'supertape';
5
- import {getColumns, isDev} from './columns.mjs';
6
-
7
- const __filename = fileURLToPath(import.meta.url);
8
- const __dirname = dirname(__filename);
9
-
10
- test('columns: prod', (t) => {
11
- const columns = getColumns({
12
- isDev: false,
13
- });
14
-
15
- t.equal(columns[''], '');
16
- t.end();
17
- });
18
-
19
- test('columns: dev', (t) => {
20
- const columns = getColumns({
21
- isDev: true,
22
- });
23
-
24
- const css = fs.readFileSync(`${__dirname}/../css/columns/name-size-date.css`, 'utf8');
25
-
26
- t.equal(columns['name-size-date'], css);
27
- t.end();
28
- });
29
-
30
- test('columns: no args', (t) => {
31
- const currentIsDev = isDev();
32
- isDev(true);
33
- const columns = getColumns();
34
-
35
- const css = fs.readFileSync(`${__dirname}/../css/columns/name-size-date.css`, 'utf8');
36
- isDev(currentIsDev);
37
-
38
- t.equal(columns['name-size-date'], css);
39
- t.end();
40
- });