From 6b0bd2e1debb3e53d5c75039d39bf98ccd4115b6 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 16 Jan 2026 23:24:31 +0100 Subject: [PATCH 01/23] refactor: client: move out inner functions --- client/get-json-from-file-table.mjs | 46 ++++++++++++++--------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/client/get-json-from-file-table.mjs b/client/get-json-from-file-table.mjs index 86edebf9..416dda12 100644 --- a/client/get-json-from-file-table.mjs +++ b/client/get-json-from-file-table.mjs @@ -8,29 +8,6 @@ export const getJsonFromFileTable = () => { const path = DOM.getCurrentDirPath(); const infoFiles = Info.files || []; - const notParent = (current) => { - const name = DOM.getCurrentName(current); - return name !== '..'; - }; - - const parse = (current) => { - const name = DOM.getCurrentName(current); - const size = DOM.getCurrentSize(current); - const owner = DOM.getCurrentOwner(current); - const mode = DOM.getCurrentMode(current); - const date = DOM.getCurrentDate(current); - const type = DOM.getCurrentType(current); - - return { - name, - size, - mode, - owner, - date, - type, - }; - }; - const files = infoFiles .filter(notParent) .map(parse); @@ -42,3 +19,26 @@ export const getJsonFromFileTable = () => { return fileTable; }; + +const notParent = (current) => { + const name = DOM.getCurrentName(current); + return name !== '..'; +}; + +const parse = (current) => { + const name = DOM.getCurrentName(current); + const size = DOM.getCurrentSize(current); + const owner = DOM.getCurrentOwner(current); + const mode = DOM.getCurrentMode(current); + const date = DOM.getCurrentDate(current); + const type = DOM.getCurrentType(current); + + return { + name, + size, + mode, + owner, + date, + type, + }; +}; From 0ccd109a50ef4e5a37375a3b5a11b260f3a929a1 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 16 Jan 2026 22:25:24 +0000 Subject: [PATCH 02/23] =?UTF-8?q?chore:=20cloudcmd:=20actions:=20lint=20?= =?UTF-8?q?=E2=98=98=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/get-json-from-file-table.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/get-json-from-file-table.mjs b/client/get-json-from-file-table.mjs index 416dda12..ea90f366 100644 --- a/client/get-json-from-file-table.mjs +++ b/client/get-json-from-file-table.mjs @@ -24,7 +24,7 @@ const notParent = (current) => { const name = DOM.getCurrentName(current); return name !== '..'; }; - + const parse = (current) => { const name = DOM.getCurrentName(current); const size = DOM.getCurrentSize(current); @@ -32,7 +32,7 @@ const parse = (current) => { const mode = DOM.getCurrentMode(current); const date = DOM.getCurrentDate(current); const type = DOM.getCurrentType(current); - + return { name, size, From 3bdf47a5bb56fa2bf5ec643b884e9f58f70c8d81 Mon Sep 17 00:00:00 2001 From: coderiaser Date: Sat, 17 Jan 2026 13:50:26 +0200 Subject: [PATCH 03/23] feature: client: migrate to ESM --- client/{client.js => client.mjs} | 46 ++++++++++++++----------------- client/cloudcmd.js | 22 +++++++++------ client/key/index.js | 2 +- client/key/set-current-by-char.js | 2 +- 4 files changed, 36 insertions(+), 36 deletions(-) rename client/{client.js => client.mjs} (93%) diff --git a/client/client.js b/client/client.mjs similarity index 93% rename from client/client.js rename to client/client.mjs index 529b904b..daf55ca5 100644 --- a/client/client.js +++ b/client/client.mjs @@ -1,30 +1,24 @@ -'use strict'; - -const process = require('node:process'); +import process from 'node:process'; /* global DOM */ -const Emitify = require('emitify'); -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 currify = require('currify'); - -const Images = require('./dom/images'); - -const {unregisterSW} = require('./sw/register'); -const {getJsonFromFileTable} = require('./get-json-from-file-table.mjs'); -const Key = require('./key'); - -const { +import Emitify from 'emitify'; +import inherits from 'inherits'; +import rendy from 'rendy'; +import load from 'load.js'; +import {tryToCatch} from 'try-to-catch'; +import {addSlashToEnd} from 'format-io'; +import pascalCase from 'just-pascal-case'; +import currify from 'currify'; +import Images from './dom/images.js'; +import {unregisterSW} from './sw/register.js'; +import {getJsonFromFileTable} from './get-json-from-file-table.mjs'; +import Key from './key/index.js'; +import { apiURL, formatMsg, buildFromJSON, -} = require('../common/cloudfunc.mjs'); - -const {loadModule} = require('./load-module.mjs'); +} from '../common/cloudfunc.mjs'; +import {loadModule} from './load-module.mjs'; const noJS = (a) => a.replace(/.js$/, ''); @@ -32,7 +26,9 @@ const isDev = process.env.NODE_ENV === 'development'; inherits(CloudCmdProto, Emitify); -module.exports = new CloudCmdProto(DOM); +export const createCloudCmd = (DOM) => { + return new CloudCmdProto(DOM); +}; load.addErrorListener((e, src) => { const msg = `file ${src} could not be loaded`; @@ -49,11 +45,9 @@ function CloudCmdProto(DOM) { const {Storage, Files} = DOM; - this.log = (...a) => { + this.log = () => { if (!isDev) return; - - console.log(...a); }; this.prefix = ''; this.prefixSocket = ''; diff --git a/client/cloudcmd.js b/client/cloudcmd.js index 8c3de848..32b3bc1a 100644 --- a/client/cloudcmd.js +++ b/client/cloudcmd.js @@ -8,15 +8,20 @@ const load = require('load.js'); const {registerSW, listenSW} = require('./sw/register'); const {initSortPanel, sortPanel} = require('./sort.mjs'); +const Util = require('../common/util'); +const CloudFunc = require('../common/cloudfunc.mjs'); +const DOM = require('./dom'); +const {createCloudCmd} = require('./client.mjs'); const isDev = process.env.NODE_ENV === 'development'; -module.exports = async (config) => { - globalThis.Util = require('../common/util'); - globalThis.CloudFunc = require('../common/cloudfunc.mjs'); - - globalThis.DOM = require('./dom'); - globalThis.CloudCmd = require('./client'); +module.exports = init; + +async function init(config) { + globalThis.CloudCmd = createCloudCmd(DOM); + globalThis.DOM = DOM; + globalThis.Util = Util; + globalThis.CloudFunc = CloudFunc; await register(config); @@ -34,8 +39,9 @@ module.exports = async (config) => { import('https://esm.sh/@putout/processor-html'); import('https://esm.sh/@putout/bundle'); }, 100); -}; -globalThis.CloudCmd = module.exports; +} + +globalThis.CloudCmd = init; function getPrefix(prefix) { if (!prefix) diff --git a/client/key/index.js b/client/key/index.js index 3e8aeeab..df55f035 100644 --- a/client/key/index.js +++ b/client/key/index.js @@ -12,7 +12,6 @@ const _vim = require('./vim'); const setCurrentByChar = require('./set-current-by-char'); const {createBinder} = require('./binder'); -const Info = DOM.CurrentInfo; const Chars = fullstore(); const toggleVim = (keyCode, overrides = {}) => { @@ -124,6 +123,7 @@ function fromCharCode(keyIdentifier) { } async function _switchKey(event) { + const Info = DOM.CurrentInfo; let i; let isSelected; let prev; diff --git a/client/key/set-current-by-char.js b/client/key/set-current-by-char.js index f54881a3..ab9329f3 100644 --- a/client/key/set-current-by-char.js +++ b/client/key/set-current-by-char.js @@ -3,9 +3,9 @@ 'use strict'; const {escapeRegExp} = require('../../common/util'); -const Info = DOM.CurrentInfo; module.exports = function setCurrentByChar(char, charStore) { + const Info = DOM.CurrentInfo; let firstByName; let skipCount = 0; let setted = false; From a94fa0d465cf4c1aa3a9d5c96288842a9ab10859 Mon Sep 17 00:00:00 2001 From: coderiaser Date: Sat, 17 Jan 2026 14:09:03 +0200 Subject: [PATCH 04/23] feature: client: cloudcmd: migrate to ESM --- .webpack/js.mjs | 2 +- client/client.mjs | 12 ++++----- client/{cloudcmd.js => cloudcmd.mjs} | 40 +++++++++++++--------------- client/listeners/index.js | 21 ++++++++++----- 4 files changed, 40 insertions(+), 35 deletions(-) rename client/{cloudcmd.js => cloudcmd.mjs} (70%) diff --git a/.webpack/js.mjs b/.webpack/js.mjs index 5788300b..d616745a 100644 --- a/.webpack/js.mjs +++ b/.webpack/js.mjs @@ -114,7 +114,7 @@ export default { 'terminal': `${dirCss}/terminal.css`, 'user-menu': `${dirCss}/user-menu.css`, 'sw': `${dir}/sw/sw.js`, - 'cloudcmd': `${dir}/cloudcmd.js`, + 'cloudcmd': `${dir}/cloudcmd.mjs`, [`${modules}/edit`]: `${dirModules}/edit.js`, [`${modules}/edit-file`]: `${dirModules}/edit-file.js`, [`${modules}/edit-file-vim`]: `${dirModules}/edit-file-vim.js`, diff --git a/client/client.mjs b/client/client.mjs index daf55ca5..b1d9edd6 100644 --- a/client/client.mjs +++ b/client/client.mjs @@ -26,8 +26,11 @@ const isDev = process.env.NODE_ENV === 'development'; inherits(CloudCmdProto, Emitify); -export const createCloudCmd = (DOM) => { - return new CloudCmdProto(DOM); +export const createCloudCmd = ({DOM, Listeners}) => { + return new CloudCmdProto({ + DOM, + Listeners, + }); }; load.addErrorListener((e, src) => { @@ -35,9 +38,7 @@ load.addErrorListener((e, src) => { Images.show.error(msg); }); -function CloudCmdProto(DOM) { - let Listeners; - +function CloudCmdProto({DOM, Listeners}) { Emitify.call(this); const CloudCmd = this; @@ -224,7 +225,6 @@ function CloudCmdProto(DOM) { const dirPath = DOM.getCurrentDirPath(); - ({Listeners} = CloudCmd); Listeners.init(); const panels = getPanels(); diff --git a/client/cloudcmd.js b/client/cloudcmd.mjs similarity index 70% rename from client/cloudcmd.js rename to client/cloudcmd.mjs index 32b3bc1a..7ad6995b 100644 --- a/client/cloudcmd.js +++ b/client/cloudcmd.mjs @@ -1,33 +1,32 @@ -'use strict'; - -const process = require('node:process'); -require('../css/main.css'); - -const wraptile = require('wraptile'); -const load = require('load.js'); - -const {registerSW, listenSW} = require('./sw/register'); -const {initSortPanel, sortPanel} = require('./sort.mjs'); -const Util = require('../common/util'); -const CloudFunc = require('../common/cloudfunc.mjs'); -const DOM = require('./dom'); -const {createCloudCmd} = require('./client.mjs'); +import process from 'node:process'; +import wraptile from 'wraptile'; +import load from 'load.js'; +import '../css/main.css'; +import {registerSW, listenSW} from './sw/register.js'; +import {initSortPanel, sortPanel} from './sort.mjs'; +import Util from '../common/util.js'; +import * as CloudFunc from '../common/cloudfunc.mjs'; +import DOM from './dom/index.js'; +import {createCloudCmd} from './client.mjs'; +import * as Listeners from './listeners/index.js'; const isDev = process.env.NODE_ENV === 'development'; -module.exports = init; +export default init; + +globalThis.CloudCmd = init; async function init(config) { - globalThis.CloudCmd = createCloudCmd(DOM); + globalThis.CloudCmd = createCloudCmd({ + DOM, + Listeners, + }); globalThis.DOM = DOM; globalThis.Util = Util; globalThis.CloudFunc = CloudFunc; await register(config); - require('./listeners'); - require('./key'); - initSortPanel(); globalThis.CloudCmd.sortPanel = sortPanel; const prefix = getPrefix(config.prefix); @@ -41,8 +40,6 @@ async function init(config) { }, 100); } -globalThis.CloudCmd = init; - function getPrefix(prefix) { if (!prefix) return ''; @@ -75,3 +72,4 @@ async function register(config) { listenSW(sw, 'updatefound', onUpdateFound(config)); } + diff --git a/client/listeners/index.js b/client/listeners/index.js index f3b99f70..a953f1d7 100644 --- a/client/listeners/index.js +++ b/client/listeners/index.js @@ -29,8 +29,6 @@ module.exports.init = async () => { ]); }; -CloudCmd.Listeners = module.exports; - const unselect = (event) => { const isMac = /Mac/.test(globalThis.navigator.platform); const { @@ -50,9 +48,6 @@ const execAll = currify((funcs, event) => { fn(event); }); -const Info = DOM.CurrentInfo; -const {Events} = DOM; - const EventsFiles = { mousedown: exec.with(execIfNotUL, setCurrentFileByEvent), click: execAll([onClick, exec.with(execIfNotMobile, unselect)]), @@ -70,6 +65,8 @@ function header() { return /^js-(left|right)$/.test(el.dataset.name); }; + const {Events} = DOM; + Events.addClick(fm, (event) => { const el = event.target; const parent = el.parentElement; @@ -106,6 +103,7 @@ async function config() { } module.exports.initKeysPanel = () => { + const {Events} = DOM; const keysElement = DOM.getById('js-keyspanel'); if (!keysElement) @@ -152,6 +150,7 @@ const getPanel = (side) => { }; module.exports.setOnPanel = (side) => { + const {Events} = DOM; const panel = getPanel(side); const filesElement = DOM.getByDataName('js-files', panel); @@ -167,6 +166,7 @@ function getPathListener(panel) { } function isNoCurrent(panel) { + const Info = DOM.CurrentInfo; const infoPanel = Info.panel; if (!infoPanel) @@ -191,6 +191,7 @@ function decodePath(path) { } async function onPathElementClick(panel, event) { + const Info = DOM.CurrentInfo; event.preventDefault(); const element = event.target; @@ -261,6 +262,7 @@ function toggleSelect(key, files) { } function changePanel(element) { + const Info = DOM.CurrentInfo; const {panel} = Info; const files = DOM.getByDataName('js-files', panel); const ul = getULElement(element); @@ -302,6 +304,7 @@ async function onTouch(event) { * in Chrome (HTML5) */ function onDragStart(event) { + const Info = DOM.CurrentInfo; const {prefixURL} = CloudCmd; const element = getLIElement(event.target); const {isDir} = Info; @@ -338,6 +341,7 @@ function getULElement(element) { } function setCurrentFileByEvent(event) { + const Info = DOM.CurrentInfo; const BUTTON_LEFT = 0; const key = { @@ -376,6 +380,7 @@ function getFilesRange(from, to) { } function contextMenu() { + const {Events} = DOM; const fm = DOM.getFM(); Events.addOnce('contextmenu', fm, (event) => { @@ -391,6 +396,7 @@ function contextMenu() { } function dragndrop() { + const {Events} = DOM; const panels = DOM.getByClassAll('panel'); const select = ({target}) => { target.classList.add('selected-panel'); @@ -464,7 +470,7 @@ function unload() { } function pop() { - Events.add('popstate', async ({state}) => { + DOM.Events.add('popstate', async ({state}) => { const path = (state || '').replace(FS, ''); if (!path) @@ -479,7 +485,8 @@ function pop() { } function resize() { - Events.add('resize', () => { + DOM.Events.add('resize', () => { + const Info = DOM.CurrentInfo; const is = globalThis.innerWidth < CloudCmd.MIN_ONE_PANEL_WIDTH; if (!is) From 9cebb2416fbd653c0f3d076a9eef2d5384430fba Mon Sep 17 00:00:00 2001 From: coderiaser Date: Sat, 17 Jan 2026 14:16:46 +0200 Subject: [PATCH 05/23] feature: client: dom: events: migrate to ESM --- client/dom/events/index.js | 198 ------------------------------ client/dom/events/index.mjs | 204 +++++++++++++++++++++++++++++++ client/dom/index.js | 2 +- client/key/index.js | 2 +- client/listeners/index.js | 13 +- client/modules/config/index.js | 2 +- client/modules/edit-file-vim.js | 2 +- client/modules/edit-names-vim.js | 2 +- client/modules/view/index.js | 2 +- package.json | 1 + 10 files changed, 215 insertions(+), 213 deletions(-) delete mode 100644 client/dom/events/index.js create mode 100644 client/dom/events/index.mjs diff --git a/client/dom/events/index.js b/client/dom/events/index.js deleted file mode 100644 index 22e9261e..00000000 --- a/client/dom/events/index.js +++ /dev/null @@ -1,198 +0,0 @@ -'use strict'; - -const itype = require('itype'); -const EventStore = require('./event-store'); - -module.exports = new EventsProto(); - -function EventsProto() { - const Events = this; - - const getEventOptions = (eventName) => { - if (eventName !== 'touchstart') - return false; - - return { - passive: true, - }; - }; - - function parseArgs(eventName, element, listener, callback) { - let isFunc; - const args = [ - eventName, - element, - listener, - callback, - ]; - - const EVENT_NAME = 1; - const ELEMENT = 0; - const type = itype(eventName); - - switch(type) { - default: - if (!type.endsWith('element')) - throw Error(`unknown eventName: ${type}`); - - parseArgs(args[EVENT_NAME], args[ELEMENT], listener, callback); - break; - - case 'string': - isFunc = itype.function(element); - - if (isFunc) { - listener = element; - element = null; - } - - if (!element) - element = window; - - callback(element, [ - eventName, - listener, - getEventOptions(eventName), - ]); - break; - - case 'array': - - for (const name of eventName) { - parseArgs(name, element, listener, callback); - } - - break; - - case 'object': - - for (const name of Object.keys(eventName)) { - const eventListener = eventName[name]; - - parseArgs(name, element, eventListener, callback); - } - - break; - } - } - - /** - * safe add event listener - * - * @param type - * @param element - document by default - * @param listener - */ - this.add = (type, element, listener) => { - checkType(type); - - parseArgs(type, element, listener, (element, args) => { - const [name, fn, options] = args; - - element.addEventListener(name, fn, options); - EventStore.add(element, name, fn); - }); - - return Events; - }; - - /** - * safe add event listener - * - * @param type - * @param listener - * @param element - document by default - */ - this.addOnce = (type, element, listener) => { - const once = (event) => { - Events.remove(type, element, once); - listener(event); - }; - - if (!listener) { - listener = element; - element = null; - } - - this.add(type, element, once); - - return Events; - }; - - /** - * safe remove event listener - * - * @param type - * @param listener - * @param element - document by default - */ - this.remove = (type, element, listener) => { - checkType(type); - - parseArgs(type, element, listener, (element, args) => { - element.removeEventListener(...args); - }); - - return Events; - }; - - /** - * remove all added event listeners - */ - this.removeAll = () => { - const events = EventStore.get(); - - for (const [el, name, fn] of events) - el.removeEventListener(name, fn); - - EventStore.clear(); - }; - - /** - * safe add event keydown listener - * - * @param args - */ - this.addKey = function(...args) { - return Events.add('keydown', ...args); - }; - - /** - * safe remove event click listener - * - * @param args - */ - this.rmKey = function(...args) { - return Events.remove('keydown', ...args); - }; - - /** - * safe add event click listener - */ - this.addClick = function(...args) { - return Events.add('click', ...args); - }; - - /** - * safe remove event click listener - */ - this.rmClick = function(...args) { - return Events.remove('click', ...args); - }; - - this.addContextMenu = function(...args) { - return Events.add('contextmenu', ...args); - }; - - /** - * safe add load listener - */ - this.addLoad = function(...args) { - return Events.add('load', ...args); - }; - - function checkType(type) { - if (!type) - throw Error('type could not be empty!'); - } -} diff --git a/client/dom/events/index.mjs b/client/dom/events/index.mjs new file mode 100644 index 00000000..218d81b5 --- /dev/null +++ b/client/dom/events/index.mjs @@ -0,0 +1,204 @@ +import itype from 'itype'; +import EventStore from './event-store.js'; + +/** + * safe add event listener + * + * @param type + * @param element - document by default + * @param listener + */ +export const add = (type, element, listener) => { + checkType(type); + + parseArgs(type, element, listener, (element, args) => { + const [name, fn, options] = args; + + element.addEventListener(name, fn, options); + EventStore.add(element, name, fn); + }); + + return Events; +}; + +/** + * safe add event listener + * + * @param type + * @param listener + * @param element - document by default + */ +export const addOnce = (type, element, listener) => { + const once = (event) => { + Events.remove(type, element, once); + listener(event); + }; + + if (!listener) { + listener = element; + element = null; + } + + add(type, element, once); + + return Events; +}; + +/** + * safe remove event listener + * + * @param type + * @param listener + * @param element - document by default + */ +export const remove = (type, element, listener) => { + checkType(type); + + parseArgs(type, element, listener, (element, args) => { + element.removeEventListener(...args); + }); + + return Events; +}; + +/** + * remove all added event listeners + */ +export const removeAll = () => { + const events = EventStore.get(); + + for (const [el, name, fn] of events) + el.removeEventListener(name, fn); + + EventStore.clear(); +}; + +/** + * safe add event keydown listener + * + * @param args + */ +export const addKey = function(...args) { + return add('keydown', ...args); +}; + +/** + * safe remove event click listener + * + * @param args + */ +export const rmKey = function(...args) { + return Events.remove('keydown', ...args); +}; + +/** + * safe add event click listener + */ +export const addClick = function(...args) { + return Events.add('click', ...args); +}; + +/** + * safe remove event click listener + */ +export const rmClick = function(...args) { + return remove('click', ...args); +}; + +export const addContextMenu = function(...args) { + return add('contextmenu', ...args); +}; + +/** + * safe add load listener + */ +export const addLoad = function(...args) { + return add('load', ...args); +}; + +function checkType(type) { + if (!type) + throw Error('type could not be empty!'); +} + +const getEventOptions = (eventName) => { + if (eventName !== 'touchstart') + return false; + + return { + passive: true, + }; +}; + +function parseArgs(eventName, element, listener, callback) { + let isFunc; + const args = [ + eventName, + element, + listener, + callback, + ]; + + const EVENT_NAME = 1; + const ELEMENT = 0; + const type = itype(eventName); + + switch(type) { + default: + if (!type.endsWith('element')) + throw Error(`unknown eventName: ${type}`); + + parseArgs(args[EVENT_NAME], args[ELEMENT], listener, callback); + break; + + case 'string': + isFunc = itype.function(element); + + if (isFunc) { + listener = element; + element = null; + } + + if (!element) + element = window; + + callback(element, [ + eventName, + listener, + getEventOptions(eventName), + ]); + break; + + case 'array': + + for (const name of eventName) { + parseArgs(name, element, listener, callback); + } + + break; + + case 'object': + + for (const name of Object.keys(eventName)) { + const eventListener = eventName[name]; + + parseArgs(name, element, eventListener, callback); + } + + break; + } +} + +const Events = { + add, + addClick, + addContextMenu, + addKey, + addLoad, + addOnce, + remove, + removeAll, + rmClick, + rmKey, +}; + diff --git a/client/dom/index.js b/client/dom/index.js index 965f1972..0170b970 100644 --- a/client/dom/index.js +++ b/client/dom/index.js @@ -33,7 +33,7 @@ module.exports = DOM; DOM.uploadDirectory = require('./directory'); DOM.Buffer = require('./buffer'); -DOM.Events = require('./events'); +DOM.Events = require('./events/index.mjs'); const loadRemote = require('./load-remote'); const selectByPattern = require('./select-by-pattern'); diff --git a/client/key/index.js b/client/key/index.js index df55f035..45472061 100644 --- a/client/key/index.js +++ b/client/key/index.js @@ -5,7 +5,7 @@ const clipboard = require('@cloudcmd/clipboard'); const {fullstore} = require('fullstore'); const Buffer = require('../dom/buffer'); -const Events = require('../dom/events'); +const Events = require('../dom/events/index.mjs'); const KEY = require('./key'); const _vim = require('./vim'); diff --git a/client/listeners/index.js b/client/listeners/index.js index a953f1d7..1d5ad118 100644 --- a/client/listeners/index.js +++ b/client/listeners/index.js @@ -11,6 +11,7 @@ const clipboard = require('@cloudcmd/clipboard'); const getRange = require('./get-range'); const uploadFiles = require('../dom/upload-files'); const {FS} = require('../../common/cloudfunc.mjs'); +const Events = require('../dom/events/index.mjs'); const getIndex = currify(require('./get-index')); @@ -65,8 +66,6 @@ function header() { return /^js-(left|right)$/.test(el.dataset.name); }; - const {Events} = DOM; - Events.addClick(fm, (event) => { const el = event.target; const parent = el.parentElement; @@ -103,7 +102,6 @@ async function config() { } module.exports.initKeysPanel = () => { - const {Events} = DOM; const keysElement = DOM.getById('js-keyspanel'); if (!keysElement) @@ -150,7 +148,6 @@ const getPanel = (side) => { }; module.exports.setOnPanel = (side) => { - const {Events} = DOM; const panel = getPanel(side); const filesElement = DOM.getByDataName('js-files', panel); @@ -380,7 +377,6 @@ function getFilesRange(from, to) { } function contextMenu() { - const {Events} = DOM; const fm = DOM.getFM(); Events.addOnce('contextmenu', fm, (event) => { @@ -396,7 +392,6 @@ function contextMenu() { } function dragndrop() { - const {Events} = DOM; const panels = DOM.getByClassAll('panel'); const select = ({target}) => { target.classList.add('selected-panel'); @@ -457,7 +452,7 @@ function dragndrop() { } function unload() { - DOM.Events.add(['unload', 'beforeunload'], (event) => { + Events.add(['unload', 'beforeunload'], (event) => { const {Key} = CloudCmd; const isBind = Key?.isBind(); @@ -470,7 +465,7 @@ function unload() { } function pop() { - DOM.Events.add('popstate', async ({state}) => { + Events.add('popstate', async ({state}) => { const path = (state || '').replace(FS, ''); if (!path) @@ -485,7 +480,7 @@ function pop() { } function resize() { - DOM.Events.add('resize', () => { + Events.add('resize', () => { const Info = DOM.CurrentInfo; const is = globalThis.innerWidth < CloudCmd.MIN_ONE_PANEL_WIDTH; diff --git a/client/modules/config/index.js b/client/modules/config/index.js index a92594ef..ee4945cb 100644 --- a/client/modules/config/index.js +++ b/client/modules/config/index.js @@ -14,7 +14,7 @@ const createElement = require('@cloudcmd/create-element'); const input = require('./input'); const Images = require('../../dom/images'); -const Events = require('../../dom/events'); +const Events = require('../../dom/events/index.mjs'); const Files = require('../../dom/files'); const {getTitle} = require('../../../common/cloudfunc.mjs'); diff --git a/client/modules/edit-file-vim.js b/client/modules/edit-file-vim.js index 48cfd93e..227309b7 100644 --- a/client/modules/edit-file-vim.js +++ b/client/modules/edit-file-vim.js @@ -3,7 +3,7 @@ /* global CloudCmd */ CloudCmd.EditFileVim = exports; -const Events = require('../dom/events'); +const Events = require('../dom/events/index.mjs'); const {Key} = CloudCmd; diff --git a/client/modules/edit-names-vim.js b/client/modules/edit-names-vim.js index 266dc9dc..55ad712a 100644 --- a/client/modules/edit-names-vim.js +++ b/client/modules/edit-names-vim.js @@ -3,7 +3,7 @@ /* global CloudCmd */ CloudCmd.EditNamesVim = exports; -const Events = require('../dom/events'); +const Events = require('../dom/events/index.mjs'); const {Key} = CloudCmd; const ConfigView = { diff --git a/client/modules/view/index.js b/client/modules/view/index.js index 5262f85a..94d492f1 100644 --- a/client/modules/view/index.js +++ b/client/modules/view/index.js @@ -26,7 +26,7 @@ const { } = require('./types'); const Files = require('../../dom/files'); -const Events = require('../../dom/events'); +const Events = require('../../dom/events/index.mjs'); const Images = require('../../dom/images'); const {encode} = require('../../../common/entity'); diff --git a/package.json b/package.json index 3cc979f3..2d142b68 100644 --- a/package.json +++ b/package.json @@ -180,6 +180,7 @@ "gunzip-maybe": "^1.3.1", "html-webpack-plugin": "^5.6.3", "inherits": "^2.0.3", + "itype": "^3.0.1", "just-capitalize": "^3.2.0", "just-pascal-case": "^3.2.0", "limier": "^3.0.0", From 23a6a6981aa9b7c5f4124ef55f7a396a0ddf464f Mon Sep 17 00:00:00 2001 From: coderiaser Date: Sat, 17 Jan 2026 14:22:32 +0200 Subject: [PATCH 06/23] feature: client: dom/events -> #dom/events --- .putout.json | 2 +- client/cloudcmd.mjs | 1 - client/dom/index.js | 2 +- client/key/index.js | 2 +- client/listeners/index.js | 2 +- client/modules/config/index.js | 2 +- client/modules/edit-file-vim.js | 2 +- client/modules/edit-names-vim.js | 2 +- client/modules/view/index.js | 2 +- package.json | 5 +++++ 10 files changed, 13 insertions(+), 9 deletions(-) diff --git a/.putout.json b/.putout.json index bc60b230..d43c63d4 100644 --- a/.putout.json +++ b/.putout.json @@ -30,7 +30,7 @@ "server/{server,exit,terminal,distribute/log}.{js,mjs}": { "remove-console": "off" }, - "client/{client,cloudcmd,load-module}.js": { + "client/{client,cloudcmd,load-module}.{js,mjs}": { "remove-console": "off" }, "client": { diff --git a/client/cloudcmd.mjs b/client/cloudcmd.mjs index 7ad6995b..0dac1a03 100644 --- a/client/cloudcmd.mjs +++ b/client/cloudcmd.mjs @@ -72,4 +72,3 @@ async function register(config) { listenSW(sw, 'updatefound', onUpdateFound(config)); } - diff --git a/client/dom/index.js b/client/dom/index.js index 0170b970..b6f128e7 100644 --- a/client/dom/index.js +++ b/client/dom/index.js @@ -33,7 +33,7 @@ module.exports = DOM; DOM.uploadDirectory = require('./directory'); DOM.Buffer = require('./buffer'); -DOM.Events = require('./events/index.mjs'); +DOM.Events = require('#dom/events'); const loadRemote = require('./load-remote'); const selectByPattern = require('./select-by-pattern'); diff --git a/client/key/index.js b/client/key/index.js index 45472061..c01c23c8 100644 --- a/client/key/index.js +++ b/client/key/index.js @@ -5,7 +5,7 @@ const clipboard = require('@cloudcmd/clipboard'); const {fullstore} = require('fullstore'); const Buffer = require('../dom/buffer'); -const Events = require('../dom/events/index.mjs'); +const Events = require('#dom/events'); const KEY = require('./key'); const _vim = require('./vim'); diff --git a/client/listeners/index.js b/client/listeners/index.js index 1d5ad118..c12c62ed 100644 --- a/client/listeners/index.js +++ b/client/listeners/index.js @@ -11,7 +11,7 @@ const clipboard = require('@cloudcmd/clipboard'); const getRange = require('./get-range'); const uploadFiles = require('../dom/upload-files'); const {FS} = require('../../common/cloudfunc.mjs'); -const Events = require('../dom/events/index.mjs'); +const Events = require('#dom/events'); const getIndex = currify(require('./get-index')); diff --git a/client/modules/config/index.js b/client/modules/config/index.js index ee4945cb..4bb4bd5b 100644 --- a/client/modules/config/index.js +++ b/client/modules/config/index.js @@ -14,7 +14,7 @@ const createElement = require('@cloudcmd/create-element'); const input = require('./input'); const Images = require('../../dom/images'); -const Events = require('../../dom/events/index.mjs'); +const Events = require('#dom/events'); const Files = require('../../dom/files'); const {getTitle} = require('../../../common/cloudfunc.mjs'); diff --git a/client/modules/edit-file-vim.js b/client/modules/edit-file-vim.js index 227309b7..0edd203b 100644 --- a/client/modules/edit-file-vim.js +++ b/client/modules/edit-file-vim.js @@ -3,7 +3,7 @@ /* global CloudCmd */ CloudCmd.EditFileVim = exports; -const Events = require('../dom/events/index.mjs'); +const Events = require('#dom/events'); const {Key} = CloudCmd; diff --git a/client/modules/edit-names-vim.js b/client/modules/edit-names-vim.js index 55ad712a..0dbd92b2 100644 --- a/client/modules/edit-names-vim.js +++ b/client/modules/edit-names-vim.js @@ -3,7 +3,7 @@ /* global CloudCmd */ CloudCmd.EditNamesVim = exports; -const Events = require('../dom/events/index.mjs'); +const Events = require('#dom/events'); const {Key} = CloudCmd; const ConfigView = { diff --git a/client/modules/view/index.js b/client/modules/view/index.js index 94d492f1..2aa3e0c7 100644 --- a/client/modules/view/index.js +++ b/client/modules/view/index.js @@ -26,7 +26,7 @@ const { } = require('./types'); const Files = require('../../dom/files'); -const Events = require('../../dom/events/index.mjs'); +const Events = require('#dom/events'); const Images = require('../../dom/images'); const {encode} = require('../../../common/entity'); diff --git a/package.json b/package.json index 2d142b68..6f4483c2 100644 --- a/package.json +++ b/package.json @@ -217,6 +217,11 @@ "webpack-merge": "^6.0.1", "webpackbar": "^7.0.0" }, + "imports": { + "#dom/events": { + "default": "./client/dom/events/index.mjs" + } + }, "engines": { "node": ">=22" }, From 4b945c004748ad05f72f190873745602ae5a8555 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Sat, 17 Jan 2026 12:23:41 +0000 Subject: [PATCH 07/23] =?UTF-8?q?chore:=20cloudcmd:=20actions:=20lint=20?= =?UTF-8?q?=E2=98=98=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/dom/events/index.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/client/dom/events/index.mjs b/client/dom/events/index.mjs index 218d81b5..0762d560 100644 --- a/client/dom/events/index.mjs +++ b/client/dom/events/index.mjs @@ -201,4 +201,3 @@ const Events = { rmClick, rmKey, }; - From dd240ba9b2b53ab4a803c6fcbc5bb1a672b18915 Mon Sep 17 00:00:00 2001 From: coderiaser Date: Sat, 17 Jan 2026 14:26:45 +0200 Subject: [PATCH 08/23] test: client: key: vim: rm skip --- client/key/index.js | 2 +- client/key/vim/index.js | 29 +++++++++++++++-------------- client/key/vim/index.spec.js | 16 +++++++++------- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/client/key/index.js b/client/key/index.js index c01c23c8..5c1fa2b7 100644 --- a/client/key/index.js +++ b/client/key/index.js @@ -97,7 +97,7 @@ async function listener(event, overrides = {}) { return; if (isVim) - await vim(char, event); + vim(char, event); } function getSymbol(shift, keyCode) { diff --git a/client/key/vim/index.js b/client/key/vim/index.js index 4509ae13..a38e9970 100644 --- a/client/key/vim/index.js +++ b/client/key/vim/index.js @@ -9,30 +9,31 @@ const { selectFileNotParent, } = require('./set-current'); -const {DOM = {}, CloudCmd = {}, -} = globalThis; - -const {Dialog = {}} = DOM; - -const DEPS = { - ...DOM, - ...CloudCmd, -}; - -module.exports = async (key, event, deps = DEPS) => { +module.exports = (key, event, overrides = {}) => { + const defaults = { + ...globalThis.DOM, + ...globalThis.CloudCmd, + }; + + const deps = { + ...defaults, + ...overrides, + }; + const operations = getOperations(event, deps); - await vim(key, operations, deps); + vim(key, operations, deps); }; const getOperations = (event, deps) => { const { - Info = DOM.CurrentInfo, + Info = globalThis.DOM.CurrentInfo, + CloudCmd = globalThis.CloudCmd, Operation, unselectFiles, setCurrentFile, setCurrentByName, getCurrentName, - prompt = Dialog.prompt, + prompt = globalThis.DOM.Dialog.prompt, preventDefault = event?.preventDefault?.bind(event), toggleSelectedFile, diff --git a/client/key/vim/index.spec.js b/client/key/vim/index.spec.js index 384f3aea..ee7fabe0 100644 --- a/client/key/vim/index.spec.js +++ b/client/key/vim/index.spec.js @@ -644,19 +644,21 @@ test('cloudcmd: client: key: make file', (t) => { t.end(); }); -test.skip('cloudcmd: client: vim: terminal', (t) => { - const {CloudCmd} = globalThis; - - assign(CloudCmd, { +test('cloudcmd: client: vim: terminal', (t) => { + const CloudCmd = { Terminal: { show: stub(), }, - }); + }; const event = {}; - vim('t', event); - vim('t', event); + vim('t', event, { + CloudCmd, + }); + vim('t', event, { + CloudCmd, + }); t.calledWithNoArgs(CloudCmd.Terminal.show); t.end(); From 242820b7cfe71c5e1a0baadf06201907d3ecda0e Mon Sep 17 00:00:00 2001 From: coderiaser Date: Sat, 17 Jan 2026 14:35:58 +0200 Subject: [PATCH 09/23] chore: cloudcmd: v19.1.7 --- ChangeLog | 8 ++++++++ HELP.md | 3 ++- README.md | 2 +- package.json | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 040474d5..235cd94d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2026.01.17, v19.1.7 + +feature: +- 23a6a698 client: dom/events -> #dom/events +- 9cebb241 client: dom: events: migrate to ESM +- a94fa0d4 client: cloudcmd: migrate to ESM +- 3bdf47a5 client: migrate to ESM + 2026.01.16, v19.1.6 fix: diff --git a/HELP.md b/HELP.md index b62cc360..7f9d7a58 100644 --- a/HELP.md +++ b/HELP.md @@ -1,4 +1,4 @@ -# Cloud Commander v19.1.6 +# Cloud Commander v19.1.7 ### [Main][MainURL] [Blog][BlogURL] [Support][SupportURL] [Demo][DemoURL] @@ -1111,6 +1111,7 @@ There are a lot of ways to be involved in `Cloud Commander` development: ## Version history +- *2026.01.17*, **[v19.1.7](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.7)** - *2026.01.16*, **[v19.1.6](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.6)** - *2026.01.16*, **[v19.1.5](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.5)** - *2026.01.15*, **[v19.1.4](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.4)** diff --git a/README.md b/README.md index ea3baa8b..62a40452 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Cloud Commander v19.1.6 [![Build Status][BuildStatusIMGURL]][BuildStatusURL] [![Codacy][CodacyIMG]][CodacyURL] [![Gitter][GitterIMGURL]][GitterURL] +# Cloud Commander v19.1.7 [![Build Status][BuildStatusIMGURL]][BuildStatusURL] [![Codacy][CodacyIMG]][CodacyURL] [![Gitter][GitterIMGURL]][GitterURL] ### [Main][MainURL] [Blog][BlogURL] [Support][SupportURL] [Demo][DemoURL] diff --git a/package.json b/package.json index 6f4483c2..9b3034e6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cloudcmd", - "version": "19.1.6", + "version": "19.1.7", "author": "coderaiser (https://github.com/coderaiser)", "description": "File manager for the web with console and editor", "homepage": "http://cloudcmd.io", From f61b21eeccd27d6ff5c4bbb4f17119ae2efc8700 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Sat, 17 Jan 2026 12:36:49 +0000 Subject: [PATCH 10/23] =?UTF-8?q?chore:=20cloudcmd:=20actions:=20lint=20?= =?UTF-8?q?=E2=98=98=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/key/vim/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/client/key/vim/index.js b/client/key/vim/index.js index a38e9970..89582b19 100644 --- a/client/key/vim/index.js +++ b/client/key/vim/index.js @@ -21,6 +21,7 @@ module.exports = (key, event, overrides = {}) => { }; const operations = getOperations(event, deps); + vim(key, operations, deps); }; From 8507282d55dacfa3888a4628501901c682ff41c8 Mon Sep 17 00:00:00 2001 From: coderiaser Date: Tue, 20 Jan 2026 17:25:20 +0200 Subject: [PATCH 11/23] test: cloudcmd: client: key: rm skip --- .putout.json | 1 - client/key/vim/index.spec.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.putout.json b/.putout.json index d43c63d4..b868f59d 100644 --- a/.putout.json +++ b/.putout.json @@ -8,7 +8,6 @@ "*.md" ], "rules": { - "tape/remove-skip": "off", "package-json/add-type": "off" }, "match": { diff --git a/client/key/vim/index.spec.js b/client/key/vim/index.spec.js index ee7fabe0..152550ad 100644 --- a/client/key/vim/index.spec.js +++ b/client/key/vim/index.spec.js @@ -664,7 +664,7 @@ test('cloudcmd: client: vim: terminal', (t) => { t.end(); }); -test.skip('cloudcmd: client: vim: edit', async (t) => { +test('cloudcmd: client: vim: edit', async (t) => { globalThis.DOM = getDOM(); globalThis.CloudCmd = getCloudCmd(); From 8876f050e012a1ac35998f3a1629f20598a2996e Mon Sep 17 00:00:00 2001 From: coderiaser Date: Tue, 20 Jan 2026 18:40:56 +0200 Subject: [PATCH 12/23] feature: cloudcmd: eslint-plugin-putout v30.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9b3034e6..ac3561d4 100644 --- a/package.json +++ b/package.json @@ -174,7 +174,7 @@ "emitify": "^4.0.1", "eslint": "^9.23.0", "eslint-plugin-n": "^17.0.0-4", - "eslint-plugin-putout": "^29.0.2", + "eslint-plugin-putout": "^30.0.0", "globals": "^17.0.0", "gritty": "^9.0.0", "gunzip-maybe": "^1.3.1", From 3b6b0b5a5b00a3c7a89669016f5bb3bf17befce8 Mon Sep 17 00:00:00 2001 From: coderiaser Date: Tue, 20 Jan 2026 18:54:48 +0200 Subject: [PATCH 13/23] feature: client: buffer: migrate to ESM --- client/dom/buffer.js | 135 ------------- client/dom/buffer.mjs | 120 +++++++++++ client/dom/index.js | 2 +- client/key/index.js | 2 +- package.json | 459 +++++++++++++++++++++--------------------- 5 files changed, 352 insertions(+), 366 deletions(-) delete mode 100644 client/dom/buffer.js create mode 100644 client/dom/buffer.mjs diff --git a/client/dom/buffer.js b/client/dom/buffer.js deleted file mode 100644 index afa78dd7..00000000 --- a/client/dom/buffer.js +++ /dev/null @@ -1,135 +0,0 @@ -'use strict'; - -/* global CloudCmd */ -const tryToPromiseAll = require('../../common/try-to-promise-all'); -const Storage = require('./storage'); -const DOM = require('./'); - -module.exports = new BufferProto(); - -function BufferProto() { - const Info = DOM.CurrentInfo; - const CLASS = 'cut-file'; - const COPY = 'copy'; - const CUT = 'cut'; - - const Buffer = { - cut: callIfEnabled.bind(null, cut), - copy: callIfEnabled.bind(null, copy), - clear: callIfEnabled.bind(null, clear), - paste: callIfEnabled.bind(null, paste), - }; - - function showMessage(msg) { - DOM.Dialog.alert(msg); - } - - function getNames() { - const files = DOM.getActiveFiles(); - - return DOM.getFilenames(files); - } - - function addCutClass() { - const files = DOM.getActiveFiles(); - - for (const element of files) { - element.classList.add(CLASS); - } - } - - function rmCutClass() { - const files = DOM.getByClassAll(CLASS); - - for (const element of files) { - element.classList.remove(CLASS); - } - } - - function callIfEnabled(callback) { - const is = CloudCmd.config('buffer'); - - if (is) - return callback(); - - showMessage('Buffer disabled in config!'); - } - - async function readBuffer() { - const [e, cp, ct] = await tryToPromiseAll([ - Storage.getJson(COPY), - Storage.getJson(CUT), - ]); - - return [ - e, - cp, - ct, - ]; - } - - async function copy() { - const names = getNames(); - const from = Info.dirPath; - - await clear(); - - if (!names.length) - return; - - await Storage.remove(CUT); - await Storage.setJson(COPY, { - from, - names, - }); - } - - async function cut() { - const names = getNames(); - const from = Info.dirPath; - - await clear(); - - if (!names.length) - return; - - addCutClass(); - - await Storage.setJson(CUT, { - from, - names, - }); - } - - async function clear() { - await Storage.remove(COPY); - await Storage.remove(CUT); - - rmCutClass(); - } - - async function paste() { - const [error, cp, ct] = await readBuffer(); - - if (error || !cp && !ct) - return showMessage(error || 'Buffer is empty!'); - - const opStr = cp ? 'copy' : 'move'; - const data = cp || ct; - const {Operation} = CloudCmd; - const msg = 'Path is same!'; - const to = Info.dirPath; - - if (data.from === to) - return showMessage(msg); - - Operation.show(opStr, { - ...data, - to, - }); - - await clear(); - } - - return Buffer; -} diff --git a/client/dom/buffer.mjs b/client/dom/buffer.mjs new file mode 100644 index 00000000..a75b4f2f --- /dev/null +++ b/client/dom/buffer.mjs @@ -0,0 +1,120 @@ +/* global CloudCmd */ +import tryToPromiseAll from '../../common/try-to-promise-all.js'; +import Storage from './storage.js'; +import DOM from './index.js'; + +const Info = DOM.CurrentInfo; +const CLASS = 'cut-file'; +const COPY = 'copy'; +const CUT = 'cut'; + +function showMessage(msg) { + DOM.Dialog.alert(msg); +} + +function getNames() { + const files = DOM.getActiveFiles(); + + return DOM.getFilenames(files); +} + +function addCutClass() { + const files = DOM.getActiveFiles(); + + for (const element of files) { + element.classList.add(CLASS); + } +} + +function rmCutClass() { + const files = DOM.getByClassAll(CLASS); + + for (const element of files) { + element.classList.remove(CLASS); + } +} + +const checkEnabled = (fn) => () => { + const is = CloudCmd.config('buffer'); + + if (is) + return fn(); + + showMessage('Buffer disabled in config!'); +}; + +async function readBuffer() { + const [e, cp, ct] = await tryToPromiseAll([ + Storage.getJson(COPY), + Storage.getJson(CUT), + ]); + + return [ + e, + cp, + ct, + ]; +} + +export const copy = checkEnabled(async () => { + const names = getNames(); + const from = Info.dirPath; + + await clear(); + + if (!names.length) + return; + + await Storage.remove(CUT); + await Storage.setJson(COPY, { + from, + names, + }); +}); + +export const cut = checkEnabled(async () => { + const names = getNames(); + const from = Info.dirPath; + + await clear(); + + if (!names.length) + return; + + addCutClass(); + + await Storage.setJson(CUT, { + from, + names, + }); +}); + +export const clear = checkEnabled(async () => { + await Storage.remove(COPY); + await Storage.remove(CUT); + + rmCutClass(); +}); + +export const paste = checkEnabled(async () => { + const [error, cp, ct] = await readBuffer(); + + if (error || !cp && !ct) + return showMessage(error || 'Buffer is empty!'); + + const opStr = cp ? 'copy' : 'move'; + const data = cp || ct; + const {Operation} = CloudCmd; + const msg = 'Path is same!'; + const to = Info.dirPath; + + if (data.from === to) + return showMessage(msg); + + Operation.show(opStr, { + ...data, + to, + }); + + await clear(); +}); diff --git a/client/dom/index.js b/client/dom/index.js index b6f128e7..6e37887e 100644 --- a/client/dom/index.js +++ b/client/dom/index.js @@ -32,7 +32,7 @@ DOM.CurrentInfo = CurrentInfo; module.exports = DOM; DOM.uploadDirectory = require('./directory'); -DOM.Buffer = require('./buffer'); +DOM.Buffer = require('./buffer.mjs'); DOM.Events = require('#dom/events'); const loadRemote = require('./load-remote'); diff --git a/client/key/index.js b/client/key/index.js index 5c1fa2b7..c13f9d41 100644 --- a/client/key/index.js +++ b/client/key/index.js @@ -4,7 +4,7 @@ const clipboard = require('@cloudcmd/clipboard'); const {fullstore} = require('fullstore'); -const Buffer = require('../dom/buffer'); +const Buffer = require('../dom/buffer.mjs'); const Events = require('#dom/events'); const KEY = require('./key'); diff --git a/package.json b/package.json index ac3561d4..09ea9725 100644 --- a/package.json +++ b/package.json @@ -1,232 +1,233 @@ { - "name": "cloudcmd", - "version": "19.1.7", - "author": "coderaiser (https://github.com/coderaiser)", - "description": "File manager for the web with console and editor", - "homepage": "http://cloudcmd.io", - "funding": "https://opencollective.com/cloudcmd", - "repository": { - "type": "git", - "url": "git+https://github.com/coderaiser/cloudcmd.git" - }, - "main": "server/cloudcmd.mjs", - "keywords": [ - "console", - "terminal", - "edit", - "editor", - "file", - "file manager", - "folder", - "orthodox", - "view", - "viewer", - "copy", - "rename", - "move", - "rm", - "mv", - "cp", - "delete", - "delete file", - "delete directory", - "remove", - "remove file", - "remove directory", - "file operation", - "pack", - "server" - ], - "bin": { - "cloudcmd": "bin/cloudcmd.mjs" - }, - "scripts": { - "start": "madrun start", - "start:dev": "madrun start:dev", - "build:start": "madrun build:start", - "build:start:dev": "madrun build:start:dev", - "lint:all": "madrun lint:all", - "lint": "madrun lint", - "lint:progress": "madrun lint:progress", - "watch:lint": "madrun watch:lint", - "fresh:lint": "madrun fresh:lint", - "lint:fresh": "madrun lint:fresh", - "fix:lint": "madrun fix:lint", - "lint:stream": "madrun lint:stream", - "test": "madrun test", - "test:client": "madrun test:client", - "test:server": "madrun test:server", - "wisdom": "madrun wisdom", - "wisdom:type": "madrun wisdom:type", - "coverage": "madrun coverage", - "coverage:report": "madrun coverage:report", - "report": "madrun report", - "6to5": "madrun 6to5", - "6to5:client": "madrun 6to5:client", - "6to5:client:dev": "madrun 6to5:client:dev", - "watch:client": "madrun watch:client", - "watch:client:dev": "madrun watch:client:dev", - "watch:server": "madrun watch:server", - "watch:test": "madrun watch:test", - "watch:test:client": "madrun watch:test:client", - "watch:test:server": "madrun watch:test:server", - "watch:coverage": "madrun watch:coverage", - "build": "madrun build", - "build:dev": "madrun build:dev", - "build:client": "madrun build:client", - "build:client:dev": "madrun build:client:dev", - "heroku-postbuild": "madrun heroku-postbuild" - }, - "directories": { - "man": "man" - }, - "subdomain": "cloudcmd", - "dependencies": { - "@babel/plugin-transform-optional-chaining": "^7.21.0", - "@cloudcmd/dropbox": "^5.0.1", - "@cloudcmd/fileop": "^8.0.0", - "@cloudcmd/move-files": "^8.0.0", - "@cloudcmd/read-files-sync": "^2.0.0", - "@putout/cli-validate-args": "^2.0.0", - "aleman": "^1.16.5", - "apart": "^2.0.0", - "chalk": "^5.3.0", - "compression": "^1.7.4", - "console-io": "^14.0.0", - "copymitter": "^9.0.0", - "criton": "^2.0.0", - "currify": "^4.0.0", - "deepmerge": "^4.0.0", - "deepword": "^10.0.0", - "dword": "^15.0.0", - "edward": "^15.0.0", - "es6-promisify": "^7.0.0", - "execon": "^1.2.0", - "express": "^5.1.0", - "files-io": "^4.0.0", - "find-up": "^8.0.0", - "for-each-key": "^2.0.0", - "format-io": "^2.0.0", - "fullstore": "^4.0.0", - "http-auth": "^4.2.1", - "inly": "^5.0.0", - "jaguar": "^6.0.0", - "jju": "^1.3.0", - "jonny": "^3.0.0", - "just-snake-case": "^3.2.0", - "markdown-it": "^14.0.0", - "mellow": "^3.0.0", - "mime-types": "^3.0.1", - "montag": "^1.2.1", - "nano-memoize": "^3.0.16", - "nomine": "^4.0.0", - "object.omit": "^3.0.0", - "once": "^1.4.0", - "onezip": "^6.0.1", - "open": "^11.0.0", - "package-json": "^10.0.0", - "pipe-io": "^4.0.1", - "ponse": "^7.0.0", - "pullout": "^5.0.0", - "putout": "^41.0.0", - "redzip": "^3.0.0", - "rendy": "^4.1.3", - "restafary": "^12.0.0", - "restbox": "^4.0.0", - "shortdate": "^2.0.0", - "simport": "^1.0.1", - "socket.io": "^4.0.0", - "socket.io-client": "^4.0.1", - "squad": "^3.0.0", - "table": "^6.0.1", - "try-catch": "^4.0.4", - "try-to-catch": "^4.0.0", - "tryrequire": "^3.0.0", - "win32": "^7.0.0", - "wraptile": "^3.0.0", - "writejson": "^3.0.0", - "yargs-parser": "^22.0.0" - }, - "devDependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/core": "^7.22.5", - "@babel/preset-env": "^7.0.0", - "@cloudcmd/clipboard": "^2.0.0", - "@cloudcmd/create-element": "^2.0.0", - "@cloudcmd/modal": "^3.0.0", - "@cloudcmd/olark": "^3.0.2", - "@cloudcmd/stub": "^5.0.0", - "@iocmd/wait": "^2.1.0", - "@putout/eslint-flat": "^3.0.1", - "@putout/plugin-cloudcmd": "^4.0.0", - "@types/node-fetch": "^2.6.11", - "auto-globals": "^4.0.0", - "babel-loader": "^10.0.0", - "babel-plugin-macros": "^3.0.0", - "c8": "^10.1.2", - "cheerio": "^1.0.0-rc.5", - "clean-css-loader": "^4.2.1", - "codegen.macro": "^4.0.0", - "css-loader": "^7.1.2", - "css-modules-require-hook": "^4.2.3", - "cssnano-preset-default": "^7.0.10", - "domtokenlist-shim": "^1.2.0", - "emitify": "^4.0.1", - "eslint": "^9.23.0", - "eslint-plugin-n": "^17.0.0-4", - "eslint-plugin-putout": "^30.0.0", - "globals": "^17.0.0", - "gritty": "^9.0.0", - "gunzip-maybe": "^1.3.1", - "html-webpack-plugin": "^5.6.3", - "inherits": "^2.0.3", - "itype": "^3.0.1", - "just-capitalize": "^3.2.0", - "just-pascal-case": "^3.2.0", - "limier": "^3.0.0", - "load.js": "^3.0.0", - "madrun": "^12.1.0", - "memfs": "^4.2.0", - "mini-css-extract-plugin": "^2.9.2", - "minor": "^1.2.2", - "mock-require": "^3.0.1", - "morgan": "^1.6.1", - "multi-rename": "^3.0.0", - "nodemon": "^3.0.1", - "optimize-css-assets-webpack-plugin": "^6.0.1", - "path-browserify": "^1.0.1", - "philip": "^3.0.0", - "place": "^1.1.4", - "postcss": "^8.5.3", - "process": "^0.11.10", - "readjson": "^2.0.1", - "redlint": "^5.0.0", - "request": "^2.76.0", - "rimraf": "^6.0.1", - "scroll-into-view-if-needed": "^3.0.4", - "serve-once": "^3.0.1", - "smalltalk": "^4.0.0", - "style-loader": "^4.0.0", - "supermenu": "^4.0.1", - "supertape": "^12.0.0", - "tar-stream": "^3.0.0", - "unionfs": "^4.0.0", - "url-loader": "^4.0.0", - "webpack": "^5.99.9", - "webpack-cli": "^6.0.1", - "webpack-merge": "^6.0.1", - "webpackbar": "^7.0.0" - }, - "imports": { - "#dom/events": { - "default": "./client/dom/events/index.mjs" + "name": "cloudcmd", + "version": "19.1.7", + "type": "commonjs", + "author": "coderaiser (https://github.com/coderaiser)", + "description": "File manager for the web with console and editor", + "homepage": "http://cloudcmd.io", + "funding": "https://opencollective.com/cloudcmd", + "repository": { + "type": "git", + "url": "git+https://github.com/coderaiser/cloudcmd.git" + }, + "main": "server/cloudcmd.mjs", + "keywords": [ + "console", + "terminal", + "edit", + "editor", + "file", + "file manager", + "folder", + "orthodox", + "view", + "viewer", + "copy", + "rename", + "move", + "rm", + "mv", + "cp", + "delete", + "delete file", + "delete directory", + "remove", + "remove file", + "remove directory", + "file operation", + "pack", + "server" + ], + "bin": { + "cloudcmd": "bin/cloudcmd.mjs" + }, + "scripts": { + "start": "madrun start", + "start:dev": "madrun start:dev", + "build:start": "madrun build:start", + "build:start:dev": "madrun build:start:dev", + "lint:all": "madrun lint:all", + "lint": "madrun lint", + "lint:progress": "madrun lint:progress", + "watch:lint": "madrun watch:lint", + "fresh:lint": "madrun fresh:lint", + "lint:fresh": "madrun lint:fresh", + "fix:lint": "madrun fix:lint", + "lint:stream": "madrun lint:stream", + "test": "madrun test", + "test:client": "madrun test:client", + "test:server": "madrun test:server", + "wisdom": "madrun wisdom", + "wisdom:type": "madrun wisdom:type", + "coverage": "madrun coverage", + "coverage:report": "madrun coverage:report", + "report": "madrun report", + "6to5": "madrun 6to5", + "6to5:client": "madrun 6to5:client", + "6to5:client:dev": "madrun 6to5:client:dev", + "watch:client": "madrun watch:client", + "watch:client:dev": "madrun watch:client:dev", + "watch:server": "madrun watch:server", + "watch:test": "madrun watch:test", + "watch:test:client": "madrun watch:test:client", + "watch:test:server": "madrun watch:test:server", + "watch:coverage": "madrun watch:coverage", + "build": "madrun build", + "build:dev": "madrun build:dev", + "build:client": "madrun build:client", + "build:client:dev": "madrun build:client:dev", + "heroku-postbuild": "madrun heroku-postbuild" + }, + "directories": { + "man": "man" + }, + "subdomain": "cloudcmd", + "dependencies": { + "@babel/plugin-transform-optional-chaining": "^7.21.0", + "@cloudcmd/dropbox": "^5.0.1", + "@cloudcmd/fileop": "^8.0.0", + "@cloudcmd/move-files": "^8.0.0", + "@cloudcmd/read-files-sync": "^2.0.0", + "@putout/cli-validate-args": "^2.0.0", + "aleman": "^1.16.5", + "apart": "^2.0.0", + "chalk": "^5.3.0", + "compression": "^1.7.4", + "console-io": "^14.0.0", + "copymitter": "^9.0.0", + "criton": "^2.0.0", + "currify": "^4.0.0", + "deepmerge": "^4.0.0", + "deepword": "^10.0.0", + "dword": "^15.0.0", + "edward": "^15.0.0", + "es6-promisify": "^7.0.0", + "execon": "^1.2.0", + "express": "^5.1.0", + "files-io": "^4.0.0", + "find-up": "^8.0.0", + "for-each-key": "^2.0.0", + "format-io": "^2.0.0", + "fullstore": "^4.0.0", + "http-auth": "^4.2.1", + "inly": "^5.0.0", + "jaguar": "^6.0.0", + "jju": "^1.3.0", + "jonny": "^3.0.0", + "just-snake-case": "^3.2.0", + "markdown-it": "^14.0.0", + "mellow": "^3.0.0", + "mime-types": "^3.0.1", + "montag": "^1.2.1", + "nano-memoize": "^3.0.16", + "nomine": "^4.0.0", + "object.omit": "^3.0.0", + "once": "^1.4.0", + "onezip": "^6.0.1", + "open": "^11.0.0", + "package-json": "^10.0.0", + "pipe-io": "^4.0.1", + "ponse": "^7.0.0", + "pullout": "^5.0.0", + "putout": "^41.0.0", + "redzip": "^3.0.0", + "rendy": "^4.1.3", + "restafary": "^12.0.0", + "restbox": "^4.0.0", + "shortdate": "^2.0.0", + "simport": "^1.0.1", + "socket.io": "^4.0.0", + "socket.io-client": "^4.0.1", + "squad": "^3.0.0", + "table": "^6.0.1", + "try-catch": "^4.0.4", + "try-to-catch": "^4.0.0", + "tryrequire": "^3.0.0", + "win32": "^7.0.0", + "wraptile": "^3.0.0", + "writejson": "^3.0.0", + "yargs-parser": "^22.0.0" + }, + "devDependencies": { + "@babel/code-frame": "^7.22.5", + "@babel/core": "^7.22.5", + "@babel/preset-env": "^7.0.0", + "@cloudcmd/clipboard": "^2.0.0", + "@cloudcmd/create-element": "^2.0.0", + "@cloudcmd/modal": "^3.0.0", + "@cloudcmd/olark": "^3.0.2", + "@cloudcmd/stub": "^5.0.0", + "@iocmd/wait": "^2.1.0", + "@putout/eslint-flat": "^3.0.1", + "@putout/plugin-cloudcmd": "^4.0.0", + "@types/node-fetch": "^2.6.11", + "auto-globals": "^4.0.0", + "babel-loader": "^10.0.0", + "babel-plugin-macros": "^3.0.0", + "c8": "^10.1.2", + "cheerio": "^1.0.0-rc.5", + "clean-css-loader": "^4.2.1", + "codegen.macro": "^4.0.0", + "css-loader": "^7.1.2", + "css-modules-require-hook": "^4.2.3", + "cssnano-preset-default": "^7.0.10", + "domtokenlist-shim": "^1.2.0", + "emitify": "^4.0.1", + "eslint": "^9.23.0", + "eslint-plugin-n": "^17.0.0-4", + "eslint-plugin-putout": "^30.0.0", + "globals": "^17.0.0", + "gritty": "^9.0.0", + "gunzip-maybe": "^1.3.1", + "html-webpack-plugin": "^5.6.3", + "inherits": "^2.0.3", + "itype": "^3.0.1", + "just-capitalize": "^3.2.0", + "just-pascal-case": "^3.2.0", + "limier": "^3.0.0", + "load.js": "^3.0.0", + "madrun": "^12.1.0", + "memfs": "^4.2.0", + "mini-css-extract-plugin": "^2.9.2", + "minor": "^1.2.2", + "mock-require": "^3.0.1", + "morgan": "^1.6.1", + "multi-rename": "^3.0.0", + "nodemon": "^3.0.1", + "optimize-css-assets-webpack-plugin": "^6.0.1", + "path-browserify": "^1.0.1", + "philip": "^3.0.0", + "place": "^1.1.4", + "postcss": "^8.5.3", + "process": "^0.11.10", + "readjson": "^2.0.1", + "redlint": "^5.0.0", + "request": "^2.76.0", + "rimraf": "^6.0.1", + "scroll-into-view-if-needed": "^3.0.4", + "serve-once": "^3.0.1", + "smalltalk": "^4.0.0", + "style-loader": "^4.0.0", + "supermenu": "^4.0.1", + "supertape": "^12.0.0", + "tar-stream": "^3.0.0", + "unionfs": "^4.0.0", + "url-loader": "^4.0.0", + "webpack": "^5.99.9", + "webpack-cli": "^6.0.1", + "webpack-merge": "^6.0.1", + "webpackbar": "^7.0.0" + }, + "imports": { + "#dom/events": { + "default": "./client/dom/events/index.mjs" + } + }, + "engines": { + "node": ">=22" + }, + "license": "MIT", + "publishConfig": { + "access": "public" } - }, - "engines": { - "node": ">=22" - }, - "license": "MIT", - "publishConfig": { - "access": "public" - } } From 3b409074c16b7fd736f0f0d49c8e5c99b778e811 Mon Sep 17 00:00:00 2001 From: coderiaser Date: Tue, 20 Jan 2026 18:59:27 +0200 Subject: [PATCH 14/23] feature: client: modules: operation: migrate to ESM --- .webpack/js.mjs | 2 +- .../modules/operation/{index.js => index.mjs} | 49 ++++++++++--------- 2 files changed, 26 insertions(+), 25 deletions(-) rename client/modules/operation/{index.js => index.mjs} (93%) diff --git a/.webpack/js.mjs b/.webpack/js.mjs index d616745a..d52e0388 100644 --- a/.webpack/js.mjs +++ b/.webpack/js.mjs @@ -127,7 +127,7 @@ export default { [`${modules}/config`]: `${dirModules}/config/index.js`, [`${modules}/contact`]: `${dirModules}/contact.js`, [`${modules}/upload`]: `${dirModules}/upload.js`, - [`${modules}/operation`]: `${dirModules}/operation/index.js`, + [`${modules}/operation`]: `${dirModules}/operation/index.mjs`, [`${modules}/konsole`]: `${dirModules}/konsole.js`, [`${modules}/terminal`]: `${dirModules}/terminal.js`, [`${modules}/terminal-run`]: `${dirModules}/terminal-run.js`, diff --git a/client/modules/operation/index.js b/client/modules/operation/index.mjs similarity index 93% rename from client/modules/operation/index.js rename to client/modules/operation/index.mjs index 3cce60d8..555433f6 100644 --- a/client/modules/operation/index.js +++ b/client/modules/operation/index.mjs @@ -1,28 +1,20 @@ -/* global CloudCmd */ -/* global Util */ -/* global DOM */ -/* global fileop */ +import currify from 'currify'; +import wraptile from 'wraptile'; +import {promisify} from 'es6-promisify'; +import exec from 'execon'; +import load from 'load.js'; +import {tryToCatch} from 'try-to-catch'; +import {encode} from '../../../common/entity.js'; +import removeExtension from './remove-extension.js'; +import setListeners from './set-listeners.js'; +import getNextCurrentName from './get-next-current-name.js'; -'use strict'; - -const currify = require('currify'); -const wraptile = require('wraptile'); -const {promisify} = require('es6-promisify'); -const exec = require('execon'); -const load = require('load.js'); -const {tryToCatch} = require('try-to-catch'); - -const {encode} = require('../../../common/entity'); -const removeExtension = require('./remove-extension'); -const setListeners = require('./set-listeners'); -const getNextCurrentName = require('./get-next-current-name'); +const {DOM, CloudCmd} = globalThis; const removeQuery = (a) => a.replace(/\?.*/, ''); const Name = 'Operation'; -CloudCmd[Name] = exports; - const {config} = CloudCmd; const {Dialog, Images} = DOM; @@ -53,7 +45,7 @@ const noFilesCheck = () => { return is; }; -module.exports.init = promisify((callback) => { +export const init = promisify((callback) => { showLoad(); exec.series([ @@ -92,7 +84,7 @@ const onConnect = currify((fn, operator) => { async function initOperations(prefix, socketPrefix, fn) { socketPrefix = `${socketPrefix}/fileop`; - const operator = await fileop({ + const operator = await globalThis.fileop({ prefix, socketPrefix, }); @@ -198,11 +190,11 @@ function getPacker(type) { return packTarFn; } -module.exports.hide = () => { +export const hide = () => { CloudCmd.View.hide(); }; -module.exports.show = (operation, data) => { +export const show = (operation, data) => { if (!Loaded) return; @@ -411,8 +403,11 @@ async function _processFiles(options, data) { to, names, }; + debugger; operation(files, async () => { + console.log('sssss'); + debugger; await DOM.Storage.remove(from); const {panel, panelPassive} = Info; @@ -505,8 +500,14 @@ async function prompt(msg, to, names) { return await Dialog.prompt(msg, to); } +globalThis.CloudCmd[Name] = { + init, + hide, + show, +}; + async function loadAll() { - const {prefix} = CloudCmd; + const {prefix} = globalThis.CloudCmd; const file = `${prefix}/fileop/fileop.js`; const [error] = await tryToCatch(load.js, file); From 8a769fd5124f5bd4fdd6420e16dc7c38b031cd1c Mon Sep 17 00:00:00 2001 From: coderiaser Date: Tue, 20 Jan 2026 19:05:41 +0200 Subject: [PATCH 15/23] fix: client: modules: operation: no update after copy --- client/modules/operation/index.mjs | 2 +- .../{set-listeners.js => set-listeners.mjs} | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) rename client/modules/operation/{set-listeners.js => set-listeners.mjs} (86%) diff --git a/client/modules/operation/index.mjs b/client/modules/operation/index.mjs index 555433f6..48b6fa02 100644 --- a/client/modules/operation/index.mjs +++ b/client/modules/operation/index.mjs @@ -6,7 +6,7 @@ import load from 'load.js'; import {tryToCatch} from 'try-to-catch'; import {encode} from '../../../common/entity.js'; import removeExtension from './remove-extension.js'; -import setListeners from './set-listeners.js'; +import {setListeners} from './set-listeners.mjs'; import getNextCurrentName from './get-next-current-name.js'; const {DOM, CloudCmd} = globalThis; diff --git a/client/modules/operation/set-listeners.js b/client/modules/operation/set-listeners.mjs similarity index 86% rename from client/modules/operation/set-listeners.js rename to client/modules/operation/set-listeners.mjs index 495cd04b..f9785ca2 100644 --- a/client/modules/operation/set-listeners.js +++ b/client/modules/operation/set-listeners.mjs @@ -1,14 +1,11 @@ -'use strict'; - /* global DOM */ -const forEachKey = require('for-each-key'); - -const wraptile = require('wraptile'); -const format = require('./format'); +import forEachKey from 'for-each-key'; +import wraptile from 'wraptile'; +import format from './format.js'; const {Dialog, Images} = DOM; -module.exports = (options) => (emitter) => { +export const setListeners = (options) => (emitter) => { const { operation, callback, @@ -43,10 +40,12 @@ module.exports = (options) => (emitter) => { operation, })); + let noProgress = true; const listeners = { progress: (value) => { done = value === 100; progress.setProgress(value); + noProgress = false; }, end: () => { @@ -54,7 +53,7 @@ module.exports = (options) => (emitter) => { forEachKey(removeListener, listeners); progress.remove(); - if (lastError || done) + if (lastError || done || noProgress) callback(); }, From d574a93d6d9652d8e528ceb11f800078a1ddbd25 Mon Sep 17 00:00:00 2001 From: coderiaser Date: Tue, 20 Jan 2026 23:11:14 +0200 Subject: [PATCH 16/23] feature: client: key: migrate to ESM --- client/client.mjs | 2 +- client/dom/buffer.mjs | 7 +- client/key/{index.js => index.mjs} | 29 +- client/key/index.spec.js | 7 +- client/modules/operation/index.mjs | 3 - package.json | 460 ++++++++++++++--------------- 6 files changed, 252 insertions(+), 256 deletions(-) rename client/key/{index.js => index.mjs} (96%) diff --git a/client/client.mjs b/client/client.mjs index b1d9edd6..e7a4f87d 100644 --- a/client/client.mjs +++ b/client/client.mjs @@ -12,7 +12,7 @@ import currify from 'currify'; import Images from './dom/images.js'; import {unregisterSW} from './sw/register.js'; import {getJsonFromFileTable} from './get-json-from-file-table.mjs'; -import Key from './key/index.js'; +import {Key} from './key/index.mjs'; import { apiURL, formatMsg, diff --git a/client/dom/buffer.mjs b/client/dom/buffer.mjs index a75b4f2f..d7faf043 100644 --- a/client/dom/buffer.mjs +++ b/client/dom/buffer.mjs @@ -1,9 +1,7 @@ -/* global CloudCmd */ +/* global CloudCmd*/ import tryToPromiseAll from '../../common/try-to-promise-all.js'; import Storage from './storage.js'; -import DOM from './index.js'; -const Info = DOM.CurrentInfo; const CLASS = 'cut-file'; const COPY = 'copy'; const CUT = 'cut'; @@ -57,6 +55,7 @@ async function readBuffer() { } export const copy = checkEnabled(async () => { + const Info = globalThis.DOM.CurrentInfo; const names = getNames(); const from = Info.dirPath; @@ -73,6 +72,7 @@ export const copy = checkEnabled(async () => { }); export const cut = checkEnabled(async () => { + const Info = globalThis.DOM.CurrentInfo; const names = getNames(); const from = Info.dirPath; @@ -97,6 +97,7 @@ export const clear = checkEnabled(async () => { }); export const paste = checkEnabled(async () => { + const Info = globalThis.DOM.CurrentInfo; const [error, cp, ct] = await readBuffer(); if (error || !cp && !ct) diff --git a/client/key/index.js b/client/key/index.mjs similarity index 96% rename from client/key/index.js rename to client/key/index.mjs index c13f9d41..64fd1bc3 100644 --- a/client/key/index.js +++ b/client/key/index.mjs @@ -1,16 +1,12 @@ -'use strict'; - /* global CloudCmd, DOM */ -const clipboard = require('@cloudcmd/clipboard'); -const {fullstore} = require('fullstore'); - -const Buffer = require('../dom/buffer.mjs'); -const Events = require('#dom/events'); -const KEY = require('./key'); - -const _vim = require('./vim'); -const setCurrentByChar = require('./set-current-by-char'); -const {createBinder} = require('./binder'); +import clipboard from '@cloudcmd/clipboard'; +import {fullstore} from 'fullstore'; +import * as Events from '#dom/events'; +import * as Buffer from '../dom/buffer.mjs'; +import KEY from './key.js'; +import _vim from './vim/index.js'; +import setCurrentByChar from './set-current-by-char.js'; +import {createBinder} from './binder.js'; const Chars = fullstore(); @@ -28,13 +24,16 @@ Chars([]); const {assign} = Object; const binder = createBinder(); -module.exports = assign(binder, KEY); -module.exports.bind = () => { +const bind = () => { Events.addKey(listener, true); binder.setBind(); }; -module.exports._listener = listener; +export const Key = assign(binder, KEY, { + bind, +}); + +export const _listener = listener; function getChar(event) { /* diff --git a/client/key/index.spec.js b/client/key/index.spec.js index 3e52e5ac..d8167079 100644 --- a/client/key/index.spec.js +++ b/client/key/index.spec.js @@ -7,7 +7,8 @@ const supertape = require('supertape'); const {ESC} = require('./key'); -const {_listener, setBind} = require('.'); +const {Key, _listener} = require('./index.mjs'); + const {getDOM, getCloudCmd} = require('./vim/globals.fixture'); const test = autoGlobals(supertape); const {stub} = supertape; @@ -26,7 +27,7 @@ test('cloudcmd: client: key: enable vim', async (t) => { altKey: false, }; - setBind(); + Key.setBind(); await _listener(event, { vim, @@ -48,7 +49,7 @@ test('cloudcmd: client: key: disable vim', async (t) => { altKey: false, }; - setBind(); + Key.setBind(); await _listener(event, { config, _config, diff --git a/client/modules/operation/index.mjs b/client/modules/operation/index.mjs index 48b6fa02..8e8149e5 100644 --- a/client/modules/operation/index.mjs +++ b/client/modules/operation/index.mjs @@ -403,11 +403,8 @@ async function _processFiles(options, data) { to, names, }; - debugger; operation(files, async () => { - console.log('sssss'); - debugger; await DOM.Storage.remove(from); const {panel, panelPassive} = Info; diff --git a/package.json b/package.json index 09ea9725..94eecb56 100644 --- a/package.json +++ b/package.json @@ -1,233 +1,231 @@ { - "name": "cloudcmd", - "version": "19.1.7", - "type": "commonjs", - "author": "coderaiser (https://github.com/coderaiser)", - "description": "File manager for the web with console and editor", - "homepage": "http://cloudcmd.io", - "funding": "https://opencollective.com/cloudcmd", - "repository": { - "type": "git", - "url": "git+https://github.com/coderaiser/cloudcmd.git" - }, - "main": "server/cloudcmd.mjs", - "keywords": [ - "console", - "terminal", - "edit", - "editor", - "file", - "file manager", - "folder", - "orthodox", - "view", - "viewer", - "copy", - "rename", - "move", - "rm", - "mv", - "cp", - "delete", - "delete file", - "delete directory", - "remove", - "remove file", - "remove directory", - "file operation", - "pack", - "server" - ], - "bin": { - "cloudcmd": "bin/cloudcmd.mjs" - }, - "scripts": { - "start": "madrun start", - "start:dev": "madrun start:dev", - "build:start": "madrun build:start", - "build:start:dev": "madrun build:start:dev", - "lint:all": "madrun lint:all", - "lint": "madrun lint", - "lint:progress": "madrun lint:progress", - "watch:lint": "madrun watch:lint", - "fresh:lint": "madrun fresh:lint", - "lint:fresh": "madrun lint:fresh", - "fix:lint": "madrun fix:lint", - "lint:stream": "madrun lint:stream", - "test": "madrun test", - "test:client": "madrun test:client", - "test:server": "madrun test:server", - "wisdom": "madrun wisdom", - "wisdom:type": "madrun wisdom:type", - "coverage": "madrun coverage", - "coverage:report": "madrun coverage:report", - "report": "madrun report", - "6to5": "madrun 6to5", - "6to5:client": "madrun 6to5:client", - "6to5:client:dev": "madrun 6to5:client:dev", - "watch:client": "madrun watch:client", - "watch:client:dev": "madrun watch:client:dev", - "watch:server": "madrun watch:server", - "watch:test": "madrun watch:test", - "watch:test:client": "madrun watch:test:client", - "watch:test:server": "madrun watch:test:server", - "watch:coverage": "madrun watch:coverage", - "build": "madrun build", - "build:dev": "madrun build:dev", - "build:client": "madrun build:client", - "build:client:dev": "madrun build:client:dev", - "heroku-postbuild": "madrun heroku-postbuild" - }, - "directories": { - "man": "man" - }, - "subdomain": "cloudcmd", - "dependencies": { - "@babel/plugin-transform-optional-chaining": "^7.21.0", - "@cloudcmd/dropbox": "^5.0.1", - "@cloudcmd/fileop": "^8.0.0", - "@cloudcmd/move-files": "^8.0.0", - "@cloudcmd/read-files-sync": "^2.0.0", - "@putout/cli-validate-args": "^2.0.0", - "aleman": "^1.16.5", - "apart": "^2.0.0", - "chalk": "^5.3.0", - "compression": "^1.7.4", - "console-io": "^14.0.0", - "copymitter": "^9.0.0", - "criton": "^2.0.0", - "currify": "^4.0.0", - "deepmerge": "^4.0.0", - "deepword": "^10.0.0", - "dword": "^15.0.0", - "edward": "^15.0.0", - "es6-promisify": "^7.0.0", - "execon": "^1.2.0", - "express": "^5.1.0", - "files-io": "^4.0.0", - "find-up": "^8.0.0", - "for-each-key": "^2.0.0", - "format-io": "^2.0.0", - "fullstore": "^4.0.0", - "http-auth": "^4.2.1", - "inly": "^5.0.0", - "jaguar": "^6.0.0", - "jju": "^1.3.0", - "jonny": "^3.0.0", - "just-snake-case": "^3.2.0", - "markdown-it": "^14.0.0", - "mellow": "^3.0.0", - "mime-types": "^3.0.1", - "montag": "^1.2.1", - "nano-memoize": "^3.0.16", - "nomine": "^4.0.0", - "object.omit": "^3.0.0", - "once": "^1.4.0", - "onezip": "^6.0.1", - "open": "^11.0.0", - "package-json": "^10.0.0", - "pipe-io": "^4.0.1", - "ponse": "^7.0.0", - "pullout": "^5.0.0", - "putout": "^41.0.0", - "redzip": "^3.0.0", - "rendy": "^4.1.3", - "restafary": "^12.0.0", - "restbox": "^4.0.0", - "shortdate": "^2.0.0", - "simport": "^1.0.1", - "socket.io": "^4.0.0", - "socket.io-client": "^4.0.1", - "squad": "^3.0.0", - "table": "^6.0.1", - "try-catch": "^4.0.4", - "try-to-catch": "^4.0.0", - "tryrequire": "^3.0.0", - "win32": "^7.0.0", - "wraptile": "^3.0.0", - "writejson": "^3.0.0", - "yargs-parser": "^22.0.0" - }, - "devDependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/core": "^7.22.5", - "@babel/preset-env": "^7.0.0", - "@cloudcmd/clipboard": "^2.0.0", - "@cloudcmd/create-element": "^2.0.0", - "@cloudcmd/modal": "^3.0.0", - "@cloudcmd/olark": "^3.0.2", - "@cloudcmd/stub": "^5.0.0", - "@iocmd/wait": "^2.1.0", - "@putout/eslint-flat": "^3.0.1", - "@putout/plugin-cloudcmd": "^4.0.0", - "@types/node-fetch": "^2.6.11", - "auto-globals": "^4.0.0", - "babel-loader": "^10.0.0", - "babel-plugin-macros": "^3.0.0", - "c8": "^10.1.2", - "cheerio": "^1.0.0-rc.5", - "clean-css-loader": "^4.2.1", - "codegen.macro": "^4.0.0", - "css-loader": "^7.1.2", - "css-modules-require-hook": "^4.2.3", - "cssnano-preset-default": "^7.0.10", - "domtokenlist-shim": "^1.2.0", - "emitify": "^4.0.1", - "eslint": "^9.23.0", - "eslint-plugin-n": "^17.0.0-4", - "eslint-plugin-putout": "^30.0.0", - "globals": "^17.0.0", - "gritty": "^9.0.0", - "gunzip-maybe": "^1.3.1", - "html-webpack-plugin": "^5.6.3", - "inherits": "^2.0.3", - "itype": "^3.0.1", - "just-capitalize": "^3.2.0", - "just-pascal-case": "^3.2.0", - "limier": "^3.0.0", - "load.js": "^3.0.0", - "madrun": "^12.1.0", - "memfs": "^4.2.0", - "mini-css-extract-plugin": "^2.9.2", - "minor": "^1.2.2", - "mock-require": "^3.0.1", - "morgan": "^1.6.1", - "multi-rename": "^3.0.0", - "nodemon": "^3.0.1", - "optimize-css-assets-webpack-plugin": "^6.0.1", - "path-browserify": "^1.0.1", - "philip": "^3.0.0", - "place": "^1.1.4", - "postcss": "^8.5.3", - "process": "^0.11.10", - "readjson": "^2.0.1", - "redlint": "^5.0.0", - "request": "^2.76.0", - "rimraf": "^6.0.1", - "scroll-into-view-if-needed": "^3.0.4", - "serve-once": "^3.0.1", - "smalltalk": "^4.0.0", - "style-loader": "^4.0.0", - "supermenu": "^4.0.1", - "supertape": "^12.0.0", - "tar-stream": "^3.0.0", - "unionfs": "^4.0.0", - "url-loader": "^4.0.0", - "webpack": "^5.99.9", - "webpack-cli": "^6.0.1", - "webpack-merge": "^6.0.1", - "webpackbar": "^7.0.0" - }, - "imports": { - "#dom/events": { - "default": "./client/dom/events/index.mjs" - } - }, - "engines": { - "node": ">=22" - }, - "license": "MIT", - "publishConfig": { - "access": "public" - } + "name": "cloudcmd", + "version": "19.1.7", + "type": "commonjs", + "author": "coderaiser (https://github.com/coderaiser)", + "description": "File manager for the web with console and editor", + "homepage": "http://cloudcmd.io", + "funding": "https://opencollective.com/cloudcmd", + "repository": { + "type": "git", + "url": "git+https://github.com/coderaiser/cloudcmd.git" + }, + "main": "server/cloudcmd.mjs", + "keywords": [ + "console", + "terminal", + "edit", + "editor", + "file", + "file manager", + "folder", + "orthodox", + "view", + "viewer", + "copy", + "rename", + "move", + "rm", + "mv", + "cp", + "delete", + "delete file", + "delete directory", + "remove", + "remove file", + "remove directory", + "file operation", + "pack", + "server" + ], + "bin": { + "cloudcmd": "bin/cloudcmd.mjs" + }, + "scripts": { + "start": "madrun start", + "start:dev": "madrun start:dev", + "build:start": "madrun build:start", + "build:start:dev": "madrun build:start:dev", + "lint:all": "madrun lint:all", + "lint": "madrun lint", + "lint:progress": "madrun lint:progress", + "watch:lint": "madrun watch:lint", + "fresh:lint": "madrun fresh:lint", + "lint:fresh": "madrun lint:fresh", + "fix:lint": "madrun fix:lint", + "lint:stream": "madrun lint:stream", + "test": "madrun test", + "test:client": "madrun test:client", + "test:server": "madrun test:server", + "wisdom": "madrun wisdom", + "wisdom:type": "madrun wisdom:type", + "coverage": "madrun coverage", + "coverage:report": "madrun coverage:report", + "report": "madrun report", + "6to5": "madrun 6to5", + "6to5:client": "madrun 6to5:client", + "6to5:client:dev": "madrun 6to5:client:dev", + "watch:client": "madrun watch:client", + "watch:client:dev": "madrun watch:client:dev", + "watch:server": "madrun watch:server", + "watch:test": "madrun watch:test", + "watch:test:client": "madrun watch:test:client", + "watch:test:server": "madrun watch:test:server", + "watch:coverage": "madrun watch:coverage", + "build": "madrun build", + "build:dev": "madrun build:dev", + "build:client": "madrun build:client", + "build:client:dev": "madrun build:client:dev", + "heroku-postbuild": "madrun heroku-postbuild" + }, + "directories": { + "man": "man" + }, + "subdomain": "cloudcmd", + "dependencies": { + "@babel/plugin-transform-optional-chaining": "^7.21.0", + "@cloudcmd/dropbox": "^5.0.1", + "@cloudcmd/fileop": "^8.0.0", + "@cloudcmd/move-files": "^8.0.0", + "@cloudcmd/read-files-sync": "^2.0.0", + "@putout/cli-validate-args": "^2.0.0", + "aleman": "^1.16.5", + "apart": "^2.0.0", + "chalk": "^5.3.0", + "compression": "^1.7.4", + "console-io": "^14.0.0", + "copymitter": "^9.0.0", + "criton": "^2.0.0", + "currify": "^4.0.0", + "deepmerge": "^4.0.0", + "deepword": "^10.0.0", + "dword": "^15.0.0", + "edward": "^15.0.0", + "es6-promisify": "^7.0.0", + "execon": "^1.2.0", + "express": "^5.1.0", + "files-io": "^4.0.0", + "find-up": "^8.0.0", + "for-each-key": "^2.0.0", + "format-io": "^2.0.0", + "fullstore": "^4.0.0", + "http-auth": "^4.2.1", + "inly": "^5.0.0", + "jaguar": "^6.0.0", + "jju": "^1.3.0", + "jonny": "^3.0.0", + "just-snake-case": "^3.2.0", + "markdown-it": "^14.0.0", + "mellow": "^3.0.0", + "mime-types": "^3.0.1", + "montag": "^1.2.1", + "nano-memoize": "^3.0.16", + "nomine": "^4.0.0", + "object.omit": "^3.0.0", + "once": "^1.4.0", + "onezip": "^6.0.1", + "open": "^11.0.0", + "package-json": "^10.0.0", + "pipe-io": "^4.0.1", + "ponse": "^7.0.0", + "pullout": "^5.0.0", + "putout": "^41.0.0", + "redzip": "^3.0.0", + "rendy": "^4.1.3", + "restafary": "^12.0.0", + "restbox": "^4.0.0", + "shortdate": "^2.0.0", + "simport": "^1.0.1", + "socket.io": "^4.0.0", + "socket.io-client": "^4.0.1", + "squad": "^3.0.0", + "table": "^6.0.1", + "try-catch": "^4.0.4", + "try-to-catch": "^4.0.0", + "tryrequire": "^3.0.0", + "win32": "^7.0.0", + "wraptile": "^3.0.0", + "writejson": "^3.0.0", + "yargs-parser": "^22.0.0" + }, + "devDependencies": { + "@babel/code-frame": "^7.22.5", + "@babel/core": "^7.22.5", + "@babel/preset-env": "^7.0.0", + "@cloudcmd/clipboard": "^2.0.0", + "@cloudcmd/create-element": "^2.0.0", + "@cloudcmd/modal": "^3.0.0", + "@cloudcmd/olark": "^3.0.2", + "@cloudcmd/stub": "^5.0.0", + "@iocmd/wait": "^2.1.0", + "@putout/eslint-flat": "^3.0.1", + "@putout/plugin-cloudcmd": "^4.0.0", + "@types/node-fetch": "^2.6.11", + "auto-globals": "^4.0.0", + "babel-loader": "^10.0.0", + "babel-plugin-macros": "^3.0.0", + "c8": "^10.1.2", + "cheerio": "^1.0.0-rc.5", + "clean-css-loader": "^4.2.1", + "codegen.macro": "^4.0.0", + "css-loader": "^7.1.2", + "css-modules-require-hook": "^4.2.3", + "cssnano-preset-default": "^7.0.10", + "domtokenlist-shim": "^1.2.0", + "emitify": "^4.0.1", + "eslint": "^9.23.0", + "eslint-plugin-n": "^17.0.0-4", + "eslint-plugin-putout": "^30.0.0", + "globals": "^17.0.0", + "gritty": "^9.0.0", + "gunzip-maybe": "^1.3.1", + "html-webpack-plugin": "^5.6.3", + "inherits": "^2.0.3", + "itype": "^3.0.1", + "just-capitalize": "^3.2.0", + "just-pascal-case": "^3.2.0", + "limier": "^3.0.0", + "load.js": "^3.0.0", + "madrun": "^12.1.0", + "memfs": "^4.2.0", + "mini-css-extract-plugin": "^2.9.2", + "minor": "^1.2.2", + "mock-require": "^3.0.1", + "morgan": "^1.6.1", + "multi-rename": "^3.0.0", + "nodemon": "^3.0.1", + "optimize-css-assets-webpack-plugin": "^6.0.1", + "path-browserify": "^1.0.1", + "philip": "^3.0.0", + "place": "^1.1.4", + "postcss": "^8.5.3", + "process": "^0.11.10", + "readjson": "^2.0.1", + "redlint": "^5.0.0", + "request": "^2.76.0", + "rimraf": "^6.0.1", + "scroll-into-view-if-needed": "^3.0.4", + "serve-once": "^3.0.1", + "smalltalk": "^4.0.0", + "style-loader": "^4.0.0", + "supermenu": "^4.0.1", + "supertape": "^12.0.0", + "tar-stream": "^3.0.0", + "unionfs": "^4.0.0", + "url-loader": "^4.0.0", + "webpack": "^5.99.9", + "webpack-cli": "^6.0.1", + "webpack-merge": "^6.0.1", + "webpackbar": "^7.0.0" + }, + "imports": { + "#dom/events": "./client/dom/events/index.mjs" + }, + "engines": { + "node": ">=22" + }, + "license": "MIT", + "publishConfig": { + "access": "public" + } } From e8cf3c92f995d0c92d28a899cbc3ed1676488e45 Mon Sep 17 00:00:00 2001 From: coderiaser Date: Tue, 20 Jan 2026 23:43:06 +0200 Subject: [PATCH 17/23] chore: lint --- client/dom/buffer.mjs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/dom/buffer.mjs b/client/dom/buffer.mjs index d7faf043..01e8142a 100644 --- a/client/dom/buffer.mjs +++ b/client/dom/buffer.mjs @@ -7,16 +7,18 @@ const COPY = 'copy'; const CUT = 'cut'; function showMessage(msg) { - DOM.Dialog.alert(msg); + globalThis.DOM.Dialog.alert(msg); } function getNames() { + const {DOM} = globalThis; const files = DOM.getActiveFiles(); return DOM.getFilenames(files); } function addCutClass() { + const {DOM} = globalThis; const files = DOM.getActiveFiles(); for (const element of files) { @@ -25,6 +27,7 @@ function addCutClass() { } function rmCutClass() { + const {DOM} = globalThis; const files = DOM.getByClassAll(CLASS); for (const element of files) { From b9dd4f2676e220fc5d75ef3a070d3377bd32edb2 Mon Sep 17 00:00:00 2001 From: coderiaser Date: Tue, 20 Jan 2026 23:43:51 +0200 Subject: [PATCH 18/23] chore: cloudcmd: v19.1.8 --- ChangeLog | 11 +++++++++++ HELP.md | 3 ++- README.md | 2 +- package.json | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 235cd94d..5970ecb9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2026.01.20, v19.1.8 + +fix: +- 8a769fd5 client: modules: operation: no update after copy + +feature: +- d574a93d client: key: migrate to ESM +- 3b409074 client: modules: operation: migrate to ESM +- 3b6b0b5a client: buffer: migrate to ESM +- 8876f050 cloudcmd: eslint-plugin-putout v30.0.0 + 2026.01.17, v19.1.7 feature: diff --git a/HELP.md b/HELP.md index 7f9d7a58..2de324c6 100644 --- a/HELP.md +++ b/HELP.md @@ -1,4 +1,4 @@ -# Cloud Commander v19.1.7 +# Cloud Commander v19.1.8 ### [Main][MainURL] [Blog][BlogURL] [Support][SupportURL] [Demo][DemoURL] @@ -1111,6 +1111,7 @@ There are a lot of ways to be involved in `Cloud Commander` development: ## Version history +- *2026.01.20*, **[v19.1.8](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.8)** - *2026.01.17*, **[v19.1.7](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.7)** - *2026.01.16*, **[v19.1.6](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.6)** - *2026.01.16*, **[v19.1.5](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.5)** diff --git a/README.md b/README.md index 62a40452..c26b24f2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Cloud Commander v19.1.7 [![Build Status][BuildStatusIMGURL]][BuildStatusURL] [![Codacy][CodacyIMG]][CodacyURL] [![Gitter][GitterIMGURL]][GitterURL] +# Cloud Commander v19.1.8 [![Build Status][BuildStatusIMGURL]][BuildStatusURL] [![Codacy][CodacyIMG]][CodacyURL] [![Gitter][GitterIMGURL]][GitterURL] ### [Main][MainURL] [Blog][BlogURL] [Support][SupportURL] [Demo][DemoURL] diff --git a/package.json b/package.json index 94eecb56..6ef7fbd2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cloudcmd", - "version": "19.1.7", + "version": "19.1.8", "type": "commonjs", "author": "coderaiser (https://github.com/coderaiser)", "description": "File manager for the web with console and editor", From 7192a56e9498fbf103f5baf4efb78117fecac582 Mon Sep 17 00:00:00 2001 From: coderiaser Date: Wed, 21 Jan 2026 19:50:30 +0200 Subject: [PATCH 19/23] feature: client: dom: current-file: migrate to ESM --- .../dom/{current-file.js => current-file.mjs} | 48 +++++++++---------- ...ent-file.spec.js => current-file.spec.mjs} | 11 ++--- client/dom/index.js | 2 +- client/dom/operations/rename-current.js | 2 +- 4 files changed, 31 insertions(+), 32 deletions(-) rename client/dom/{current-file.js => current-file.mjs} (84%) rename client/dom/{current-file.spec.js => current-file.spec.mjs} (97%) diff --git a/client/dom/current-file.js b/client/dom/current-file.mjs similarity index 84% rename from client/dom/current-file.js rename to client/dom/current-file.mjs index 963b2a29..e55acbe9 100644 --- a/client/dom/current-file.js +++ b/client/dom/current-file.mjs @@ -1,10 +1,8 @@ -'use strict'; - /* global DOM */ /* global CloudCmd */ -const createElement = require('@cloudcmd/create-element'); -const {encode, decode} = require('../../common/entity'); -const {getTitle, FS} = require('../../common/cloudfunc.mjs'); +import createElement from '@cloudcmd/create-element'; +import {encode, decode} from '../../common/entity.js'; +import {getTitle, FS} from '../../common/cloudfunc.mjs'; let Title; @@ -12,14 +10,15 @@ const CURRENT_FILE = 'current-file'; const encodeNBSP = (a) => a?.replace('\xa0', ' '); const decodeNBSP = (a) => a?.replace(' ', '\xa0'); -module.exports._CURRENT_FILE = CURRENT_FILE; +export const _CURRENT_FILE = CURRENT_FILE; + /** * set name from current (or param) file * * @param name * @param current */ -module.exports.setCurrentName = (name, current) => { +export const setCurrentName = (name, current) => { const Info = DOM.CurrentInfo; const {link} = Info; const {prefix} = CloudCmd; @@ -41,7 +40,7 @@ module.exports.setCurrentName = (name, current) => { * * @param currentFile */ -module.exports.getCurrentName = (currentFile) => { +export const getCurrentName = (currentFile) => { const current = currentFile || DOM.getCurrentFile(); if (!current) @@ -68,18 +67,19 @@ const parseNameAttribute = (attribute) => { return decodeNBSP(decodeURI(atob(attribute))); }; -module.exports._parseNameAttribute = parseNameAttribute; +export const _parseNameAttribute = parseNameAttribute; const parseHrefAttribute = (prefix, attribute) => { attribute = attribute.replace(RegExp('^' + prefix + FS), ''); return decode(decodeNBSP(attribute)); }; -module.exports._parseHrefAttribute = parseHrefAttribute; +export const _parseHrefAttribute = parseHrefAttribute; + /** * get current direcotory path */ -module.exports.getCurrentDirPath = (panel = DOM.getPanel()) => { +export const getCurrentDirPath = (panel = DOM.getPanel()) => { const path = DOM.getByDataName('js-path', panel); return path.textContent; }; @@ -89,7 +89,7 @@ module.exports.getCurrentDirPath = (panel = DOM.getPanel()) => { * * @param currentFile - current file by default */ -module.exports.getCurrentPath = (currentFile) => { +export const getCurrentPath = (currentFile) => { const current = currentFile || DOM.getCurrentFile(); const [element] = DOM.getByTag('a', current); const {prefix} = CloudCmd; @@ -100,7 +100,7 @@ module.exports.getCurrentPath = (currentFile) => { /** * get current direcotory name */ -module.exports.getCurrentDirName = () => { +export const getCurrentDirName = () => { const href = DOM .getCurrentDirPath() .replace(/\/$/, ''); @@ -113,7 +113,7 @@ module.exports.getCurrentDirName = () => { /** * get current direcotory path */ -module.exports.getParentDirPath = (panel) => { +export const getParentDirPath = (panel) => { const path = DOM.getCurrentDirPath(panel); const dirName = DOM.getCurrentDirName() + '/'; const index = path.lastIndexOf(dirName); @@ -127,7 +127,7 @@ module.exports.getParentDirPath = (panel) => { /** * get not current direcotory path */ -module.exports.getNotCurrentDirPath = () => { +export const getNotCurrentDirPath = () => { const panel = DOM.getPanel({ active: false, }); @@ -140,14 +140,14 @@ module.exports.getNotCurrentDirPath = () => { * * @currentFile */ -module.exports.getCurrentFile = () => { +export const getCurrentFile = () => { return DOM.getByClass(CURRENT_FILE); }; /** * get current file by name */ -module.exports.getCurrentByName = (name, panel = DOM.CurrentInfo.panel) => { +export const getCurrentByName = (name, panel = DOM.CurrentInfo.panel) => { const dataName = 'js-file-' + btoa(encodeURI(encodeNBSP(name))); return DOM.getByDataName(dataName, panel); }; @@ -169,7 +169,7 @@ function unsetCurrentFile(currentFile) { /** * unified way to set current file */ -module.exports.setCurrentFile = (currentFile, options) => { +export const setCurrentFile = (currentFile, options) => { const o = options; const currentFileWas = DOM.getCurrentFile(); @@ -216,7 +216,7 @@ module.exports.setCurrentFile = (currentFile, options) => { return DOM; }; -this.setCurrentByName = (name) => { +export const setCurrentByName = (name) => { const current = DOM.getCurrentByName(name); return DOM.setCurrentFile(current); }; @@ -227,7 +227,7 @@ this.setCurrentByName = (name) => { * @param layer - element * @param - position {x, y} */ -module.exports.getCurrentByPosition = ({x, y}) => { +export const getCurrentByPosition = ({x, y}) => { const element = document.elementFromPoint(x, y); const getEl = (el) => { @@ -259,7 +259,7 @@ module.exports.getCurrentByPosition = ({x, y}) => { * * @param currentFile */ -module.exports.isCurrentFile = (currentFile) => { +export const isCurrentFile = (currentFile) => { if (!currentFile) return false; @@ -271,7 +271,7 @@ module.exports.isCurrentFile = (currentFile) => { * * @param name */ -module.exports.setTitle = (name) => { +export const setTitle = (name) => { if (!Title) Title = DOM.getByTag('title')[0] || createElement('title', { innerHTML: name, @@ -288,7 +288,7 @@ module.exports.setTitle = (name) => { * * @param currentFile */ -module.exports.isCurrentIsDir = (currentFile) => { +export const isCurrentIsDir = (currentFile) => { const current = currentFile || DOM.getCurrentFile(); const path = DOM.getCurrentPath(current); const fileType = DOM.getCurrentType(current); @@ -299,7 +299,7 @@ module.exports.isCurrentIsDir = (currentFile) => { return isDir || isZip; }; -module.exports.getCurrentType = (currentFile) => { +export const getCurrentType = (currentFile) => { const current = currentFile || DOM.getCurrentFile(); const el = DOM.getByDataName('js-type', current); const type = el.className diff --git a/client/dom/current-file.spec.js b/client/dom/current-file.spec.mjs similarity index 97% rename from client/dom/current-file.spec.js rename to client/dom/current-file.spec.mjs index 88d966e7..bb910dff 100644 --- a/client/dom/current-file.spec.js +++ b/client/dom/current-file.spec.mjs @@ -1,10 +1,8 @@ -'use strict'; +import {test, stub} from 'supertape'; +import {create} from 'auto-globals'; +import wraptile from 'wraptile'; +import * as currentFile from './current-file.mjs'; -const {test, stub} = require('supertape'); - -const {create} = require('auto-globals'); -const wraptile = require('wraptile'); -const currentFile = require('./current-file'); const id = (a) => a; const returns = wraptile(id); @@ -307,3 +305,4 @@ function getDOM(overrides = {}) { }, }; } + diff --git a/client/dom/index.js b/client/dom/index.js index 6e37887e..02afa3e0 100644 --- a/client/dom/index.js +++ b/client/dom/index.js @@ -8,7 +8,7 @@ const RESTful = require('./rest'); const Storage = require('./storage'); const renameCurrent = require('./operations/rename-current'); -const CurrentFile = require('./current-file'); +const CurrentFile = require('./current-file.mjs'); const DOMTree = require('./dom-tree'); const Cmd = module.exports; diff --git a/client/dom/operations/rename-current.js b/client/dom/operations/rename-current.js index 1293dc33..ab658edf 100644 --- a/client/dom/operations/rename-current.js +++ b/client/dom/operations/rename-current.js @@ -7,7 +7,7 @@ const _Dialog = require('../dialog'); const Storage = require('../storage'); const RESTful = require('../rest'); -const _currentFile = require('../current-file'); +const _currentFile = require('../current-file.mjs'); module.exports = async (current, overrides = {}) => { const { From f437a52ff05093c68850cd5531c2b35d7ca92c15 Mon Sep 17 00:00:00 2001 From: coderiaser Date: Wed, 21 Jan 2026 19:59:27 +0200 Subject: [PATCH 20/23] feature: client: images: migrate to EMS --- client/client.mjs | 2 +- client/dom/current-file.spec.mjs | 1 - client/dom/directory.js | 2 +- client/dom/{images.js => images.mjs} | 54 ++++++++++++---------- client/dom/index.js | 2 +- client/dom/io/send-request.js | 2 +- client/dom/load.js | 2 +- client/dom/rest.js | 2 +- client/dom/upload-files.js | 2 +- client/modules/cloud.js | 2 +- client/modules/config/index.js | 2 +- client/modules/contact.js | 2 +- client/modules/help.js | 2 +- client/modules/konsole.js | 2 +- client/modules/markdown.js | 2 +- client/modules/operation/set-listeners.mjs | 1 + client/modules/terminal-run.js | 2 +- client/modules/terminal.js | 2 +- client/modules/upload.js | 2 +- client/modules/user-menu/index.js | 2 +- client/modules/view/index.js | 2 +- eslint.config.mjs | 4 +- 22 files changed, 49 insertions(+), 47 deletions(-) rename client/dom/{images.js => images.mjs} (84%) diff --git a/client/client.mjs b/client/client.mjs index e7a4f87d..b6c3a436 100644 --- a/client/client.mjs +++ b/client/client.mjs @@ -9,7 +9,7 @@ import {tryToCatch} from 'try-to-catch'; import {addSlashToEnd} from 'format-io'; import pascalCase from 'just-pascal-case'; import currify from 'currify'; -import Images from './dom/images.js'; +import * as Images from './dom/images.mjs'; import {unregisterSW} from './sw/register.js'; import {getJsonFromFileTable} from './get-json-from-file-table.mjs'; import {Key} from './key/index.mjs'; diff --git a/client/dom/current-file.spec.mjs b/client/dom/current-file.spec.mjs index bb910dff..2a576dce 100644 --- a/client/dom/current-file.spec.mjs +++ b/client/dom/current-file.spec.mjs @@ -305,4 +305,3 @@ function getDOM(overrides = {}) { }, }; } - diff --git a/client/dom/directory.js b/client/dom/directory.js index 6efd989c..bedb7e95 100644 --- a/client/dom/directory.js +++ b/client/dom/directory.js @@ -3,7 +3,7 @@ /* global CloudCmd */ const philip = require('philip'); -const Images = require('./images'); +const Images = require('./images.mjs'); const {FS} = require('../../common/cloudfunc.mjs'); const DOM = require('.'); const Dialog = require('./dialog'); diff --git a/client/dom/images.js b/client/dom/images.mjs similarity index 84% rename from client/dom/images.js rename to client/dom/images.mjs index bb5579c1..9682e666 100644 --- a/client/dom/images.js +++ b/client/dom/images.mjs @@ -1,10 +1,5 @@ /* global DOM */ - -'use strict'; - -const createElement = require('@cloudcmd/create-element'); - -const Images = module.exports; +import createElement from '@cloudcmd/create-element'; const LOADING = 'loading'; const HIDDEN = 'hidden'; @@ -12,7 +7,8 @@ const ERROR = 'error'; const getLoadingType = () => isSVG() ? '-svg' : '-gif'; -module.exports.get = getElement; +export const get = getElement; + /** * check SVG SMIL animation support */ @@ -40,7 +36,7 @@ function getElement() { } /* Функция создаёт картинку загрузки */ -module.exports.loading = () => { +export const loading = () => { const element = getElement(); const {classList} = element; const loadingImage = LOADING + getLoadingType(); @@ -52,7 +48,7 @@ module.exports.loading = () => { }; /* Функция создаёт картинку ошибки загрузки */ -module.exports.error = () => { +export const error = () => { const element = getElement(); const {classList} = element; const loadingImage = LOADING + getLoadingType(); @@ -63,14 +59,21 @@ module.exports.error = () => { return element; }; -module.exports.show = show; -module.exports.show.load = show; -module.exports.show.error = error; +show.load = show; +show.error = (text) => { + const image = Images.error(); + + DOM.show(image); + image.title = text; + + return image; +}; + /** * Function shows loading spinner * position = {top: true}; */ -function show(position, panel) { +export function show(position, panel) { const image = Images.loading(); const parent = image.parentElement; const refreshButton = DOM.getRefreshButton(panel); @@ -96,19 +99,10 @@ function show(position, panel) { return image; } -function error(text) { - const image = Images.error(); - - DOM.show(image); - image.title = text; - - return image; -} - /** * hide load image */ -module.exports.hide = () => { +export const hide = () => { const element = Images.get(); DOM.hide(element); @@ -116,7 +110,7 @@ module.exports.hide = () => { return Images; }; -module.exports.setProgress = (value, title) => { +export const setProgress = (value, title) => { const DATA = 'data-progress'; const element = Images.get(); @@ -131,7 +125,7 @@ module.exports.setProgress = (value, title) => { return Images; }; -module.exports.clearProgress = () => { +export const clearProgress = () => { const DATA = 'data-progress'; const element = Images.get(); @@ -143,3 +137,13 @@ module.exports.clearProgress = () => { return Images; }; + +const Images = { + clearProgress, + setProgress, + show, + hide, + get, + error, + loading, +}; diff --git a/client/dom/index.js b/client/dom/index.js index 02afa3e0..27a1a5c6 100644 --- a/client/dom/index.js +++ b/client/dom/index.js @@ -3,7 +3,7 @@ /* global CloudCmd */ const Util = require('../../common/util'); -const Images = require('./images'); +const Images = require('./images.mjs'); const RESTful = require('./rest'); const Storage = require('./storage'); const renameCurrent = require('./operations/rename-current'); diff --git a/client/dom/io/send-request.js b/client/dom/io/send-request.js index bc52d667..c61544f1 100644 --- a/client/dom/io/send-request.js +++ b/client/dom/io/send-request.js @@ -3,7 +3,7 @@ /* global CloudCmd */ const {promisify} = require('es6-promisify'); -const Images = require('../images'); +const Images = require('../images.mjs'); const load = require('../load'); module.exports = promisify((params, callback) => { diff --git a/client/dom/load.js b/client/dom/load.js index 03c25d73..d060a92c 100644 --- a/client/dom/load.js +++ b/client/dom/load.js @@ -4,7 +4,7 @@ const itype = require('itype'); const jonny = require('jonny'); const Emitify = require('emitify'); const exec = require('execon'); -const Images = require('./images'); +const Images = require('./images.mjs'); module.exports.getIdBySrc = getIdBySrc; /** diff --git a/client/dom/rest.js b/client/dom/rest.js index 444fce15..7596f620 100644 --- a/client/dom/rest.js +++ b/client/dom/rest.js @@ -4,7 +4,7 @@ const {tryToCatch} = require('try-to-catch'); const {encode} = require('../../common/entity'); -const Images = require('./images'); +const Images = require('./images.mjs'); const IO = require('./io'); const Dialog = require('./dialog'); diff --git a/client/dom/upload-files.js b/client/dom/upload-files.js index 1a64fb6c..a1206282 100644 --- a/client/dom/upload-files.js +++ b/client/dom/upload-files.js @@ -5,7 +5,7 @@ const {eachSeries} = require('execon'); const wraptile = require('wraptile'); const load = require('./load'); -const Images = require('./images'); +const Images = require('./images.mjs'); const {alert} = require('./dialog'); const {FS} = require('../../common/cloudfunc.mjs'); diff --git a/client/modules/cloud.js b/client/modules/cloud.js index 81498c4b..53a6d9e9 100644 --- a/client/modules/cloud.js +++ b/client/modules/cloud.js @@ -9,7 +9,7 @@ const load = require('load.js'); const {ajax} = require('../dom/load'); const Files = require('../dom/files'); -const Images = require('../dom/images'); +const Images = require('../dom/images.mjs'); const {log} = CloudCmd; const upload = currify(_upload); diff --git a/client/modules/config/index.js b/client/modules/config/index.js index 4bb4bd5b..db778cbc 100644 --- a/client/modules/config/index.js +++ b/client/modules/config/index.js @@ -13,7 +13,7 @@ const load = require('load.js'); const createElement = require('@cloudcmd/create-element'); const input = require('./input'); -const Images = require('../../dom/images'); +const Images = require('../../dom/images.mjs'); const Events = require('#dom/events'); const Files = require('../../dom/files'); diff --git a/client/modules/contact.js b/client/modules/contact.js index 76a07d30..c6266de0 100644 --- a/client/modules/contact.js +++ b/client/modules/contact.js @@ -6,7 +6,7 @@ CloudCmd.Contact = exports; const olark = require('@cloudcmd/olark'); -const Images = require('../dom/images'); +const Images = require('../dom/images.mjs'); const {Events} = DOM; const {Key} = CloudCmd; diff --git a/client/modules/help.js b/client/modules/help.js index 785bb32c..242b7c16 100644 --- a/client/modules/help.js +++ b/client/modules/help.js @@ -3,7 +3,7 @@ /* global CloudCmd */ CloudCmd.Help = exports; -const Images = require('../dom/images'); +const Images = require('../dom/images.mjs'); module.exports.init = () => { Images.show.load('top'); diff --git a/client/modules/konsole.js b/client/modules/konsole.js index 3de160fd..ae5bc42c 100644 --- a/client/modules/konsole.js +++ b/client/modules/konsole.js @@ -12,7 +12,7 @@ const {tryToCatch} = require('try-to-catch'); const loadJS = require('load.js').js; const createElement = require('@cloudcmd/create-element'); -const Images = require('../dom/images'); +const Images = require('../dom/images.mjs'); const {Dialog, CurrentInfo: Info} = DOM; const rmLastSlash = (a) => a.replace(/\/$/, '') || '/'; diff --git a/client/modules/markdown.js b/client/modules/markdown.js index 6c5c3282..9dc224af 100644 --- a/client/modules/markdown.js +++ b/client/modules/markdown.js @@ -5,7 +5,7 @@ CloudCmd.Markdown = exports; const createElement = require('@cloudcmd/create-element'); -const Images = require('../dom/images'); +const Images = require('../dom/images.mjs'); const {Markdown} = require('../dom/rest'); const {alert} = require('../dom/dialog'); diff --git a/client/modules/operation/set-listeners.mjs b/client/modules/operation/set-listeners.mjs index f9785ca2..d5052cff 100644 --- a/client/modules/operation/set-listeners.mjs +++ b/client/modules/operation/set-listeners.mjs @@ -41,6 +41,7 @@ export const setListeners = (options) => (emitter) => { })); let noProgress = true; + const listeners = { progress: (value) => { done = value === 100; diff --git a/client/modules/terminal-run.js b/client/modules/terminal-run.js index 33b5dbae..4dcf24ac 100644 --- a/client/modules/terminal-run.js +++ b/client/modules/terminal-run.js @@ -10,7 +10,7 @@ require('../../css/terminal.css'); const exec = require('execon'); const load = require('load.js'); const DOM = require('../dom'); -const Images = require('../dom/images'); +const Images = require('../dom/images.mjs'); const {Dialog} = DOM; const {Key, config} = CloudCmd; diff --git a/client/modules/terminal.js b/client/modules/terminal.js index 7b9197ca..6a355560 100644 --- a/client/modules/terminal.js +++ b/client/modules/terminal.js @@ -9,7 +9,7 @@ require('../../css/terminal.css'); const exec = require('execon'); const load = require('load.js'); const DOM = require('../dom'); -const Images = require('../dom/images'); +const Images = require('../dom/images.mjs'); const loadParallel = load.parallel; diff --git a/client/modules/upload.js b/client/modules/upload.js index 63a2cd0f..23fbdaf5 100644 --- a/client/modules/upload.js +++ b/client/modules/upload.js @@ -6,7 +6,7 @@ CloudCmd.Upload = exports; const createElement = require('@cloudcmd/create-element'); const Files = require('../dom/files'); -const Images = require('../dom/images'); +const Images = require('../dom/images.mjs'); const uploadFiles = require('../dom/upload-files'); module.exports.init = async () => { diff --git a/client/modules/user-menu/index.js b/client/modules/user-menu/index.js index 713bdb8a..1dba5d23 100644 --- a/client/modules/user-menu/index.js +++ b/client/modules/user-menu/index.js @@ -12,7 +12,7 @@ const {tryCatch} = require('try-catch'); const {tryToCatch} = require('try-to-catch'); const {codeFrameColumns} = require('@babel/code-frame'); -const Images = require('../../dom/images'); +const Images = require('../../dom/images.mjs'); const Dialog = require('../../dom/dialog'); const getUserMenu = require('./get-user-menu'); const navigate = require('./navigate'); diff --git a/client/modules/view/index.js b/client/modules/view/index.js index 2aa3e0c7..89d68ee4 100644 --- a/client/modules/view/index.js +++ b/client/modules/view/index.js @@ -27,7 +27,7 @@ const { const Files = require('../../dom/files'); const Events = require('#dom/events'); -const Images = require('../../dom/images'); +const Images = require('../../dom/images.mjs'); const {encode} = require('../../../common/entity'); const isString = (a) => typeof a === 'string'; diff --git a/eslint.config.mjs b/eslint.config.mjs index d445c4a9..cf7a6a2d 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -33,9 +33,7 @@ export default defineConfig([ }, { files: ['{client,common,static}/**/*.js'], languageOptions: { - globals: { - ...globals.browser, - }, + globals: globals.browser, }, }, ...matchToFlat(match), From c5d9bd7c1fcff2ea30038e64752ab9f67dcc6535 Mon Sep 17 00:00:00 2001 From: coderiaser Date: Wed, 21 Jan 2026 20:06:35 +0200 Subject: [PATCH 21/23] feature: client: key: vim: get rid of mock-require --- client/key/vim/index.js | 16 +++++++++++----- client/key/vim/index.spec.js | 12 ++++-------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/client/key/vim/index.js b/client/key/vim/index.js index 89582b19..ddfe49c3 100644 --- a/client/key/vim/index.js +++ b/client/key/vim/index.js @@ -39,9 +39,13 @@ const getOperations = (event, deps) => { toggleSelectedFile, Buffer = {}, + createFindNext = _createFindNext, } = deps; return { + findNext: createFindNext({ + setCurrentByName, + }), escape: unselectFiles, remove: () => { @@ -119,11 +123,6 @@ const getOperations = (event, deps) => { setCurrentByName(result); }, - findNext: () => { - const name = finder.findNext(); - setCurrentByName(name); - }, - findPrevious: () => { const name = finder.findPrevious(); setCurrentByName(name); @@ -132,3 +131,10 @@ const getOperations = (event, deps) => { }; module.exports.selectFile = selectFileNotParent; + +const _createFindNext = (overrides = {}) => () => { + const {setCurrentByName} = overrides; + const name = finder.findNext(); + + setCurrentByName(name); +}; diff --git a/client/key/vim/index.spec.js b/client/key/vim/index.spec.js index 152550ad..6fcad11e 100644 --- a/client/key/vim/index.spec.js +++ b/client/key/vim/index.spec.js @@ -570,17 +570,13 @@ test('cloudcmd: client: find', (t) => { test('cloudcmd: client: key: n', (t) => { const findNext = stub(); + const createFindNext = stub().returns(findNext); - mockRequire(pathFind, { - findNext, - }); - - const vim = reRequire(pathVim); const event = {}; - vim('n', event); - - stopAll(); + vim('n', event, { + createFindNext, + }); t.calledWithNoArgs(findNext, 'should call findNext'); t.end(); From 75ad4415c4944bc138d8b9d3d02a4cced4411f57 Mon Sep 17 00:00:00 2001 From: coderiaser Date: Wed, 21 Jan 2026 20:06:53 +0200 Subject: [PATCH 22/23] feature: cloudcmd: @putout/eslint-flat v4.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6ef7fbd2..0d8c4efb 100644 --- a/package.json +++ b/package.json @@ -158,7 +158,7 @@ "@cloudcmd/olark": "^3.0.2", "@cloudcmd/stub": "^5.0.0", "@iocmd/wait": "^2.1.0", - "@putout/eslint-flat": "^3.0.1", + "@putout/eslint-flat": "^4.0.0", "@putout/plugin-cloudcmd": "^4.0.0", "@types/node-fetch": "^2.6.11", "auto-globals": "^4.0.0", From 78e87796df25872705f1c359e6b56c1b936b5cb4 Mon Sep 17 00:00:00 2001 From: coderiaser Date: Wed, 21 Jan 2026 20:08:24 +0200 Subject: [PATCH 23/23] chore: cloudcmd: v19.1.9 --- ChangeLog | 8 ++++++++ HELP.md | 3 ++- README.md | 2 +- package.json | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5970ecb9..edf5330e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2026.01.21, v19.1.9 + +feature: +- 75ad4415 cloudcmd: @putout/eslint-flat v4.0.0 +- c5d9bd7c client: key: vim: get rid of mock-require +- f437a52f client: images: migrate to EMS +- 7192a56e client: dom: current-file: migrate to ESM + 2026.01.20, v19.1.8 fix: diff --git a/HELP.md b/HELP.md index 2de324c6..68087875 100644 --- a/HELP.md +++ b/HELP.md @@ -1,4 +1,4 @@ -# Cloud Commander v19.1.8 +# Cloud Commander v19.1.9 ### [Main][MainURL] [Blog][BlogURL] [Support][SupportURL] [Demo][DemoURL] @@ -1111,6 +1111,7 @@ There are a lot of ways to be involved in `Cloud Commander` development: ## Version history +- *2026.01.21*, **[v19.1.9](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.9)** - *2026.01.20*, **[v19.1.8](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.8)** - *2026.01.17*, **[v19.1.7](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.7)** - *2026.01.16*, **[v19.1.6](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.6)** diff --git a/README.md b/README.md index c26b24f2..8e510161 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Cloud Commander v19.1.8 [![Build Status][BuildStatusIMGURL]][BuildStatusURL] [![Codacy][CodacyIMG]][CodacyURL] [![Gitter][GitterIMGURL]][GitterURL] +# Cloud Commander v19.1.9 [![Build Status][BuildStatusIMGURL]][BuildStatusURL] [![Codacy][CodacyIMG]][CodacyURL] [![Gitter][GitterIMGURL]][GitterURL] ### [Main][MainURL] [Blog][BlogURL] [Support][SupportURL] [Demo][DemoURL] diff --git a/package.json b/package.json index 0d8c4efb..c9760653 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cloudcmd", - "version": "19.1.8", + "version": "19.1.9", "type": "commonjs", "author": "coderaiser (https://github.com/coderaiser)", "description": "File manager for the web with console and editor",