cloudcmd 19.17.0 → 19.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/ChangeLog +15 -0
  2. package/HELP.md +3 -1
  3. package/README.md +1 -1
  4. package/bin/cloudcmd.js +3 -2
  5. package/dist/cloudcmd.common.js +196 -159
  6. package/dist/cloudcmd.common.js.map +1 -1
  7. package/dist/cloudcmd.js +8 -0
  8. package/dist/cloudcmd.js.map +1 -1
  9. package/dist/index.html +2 -2
  10. package/dist/modules/cloud.js +8 -0
  11. package/dist/modules/cloud.js.map +1 -1
  12. package/dist/modules/command-line.js +8 -0
  13. package/dist/modules/command-line.js.map +1 -1
  14. package/dist/modules/config.js +8 -0
  15. package/dist/modules/config.js.map +1 -1
  16. package/dist/modules/contact.js +8 -0
  17. package/dist/modules/contact.js.map +1 -1
  18. package/dist/modules/edit-file-vim.js +8 -0
  19. package/dist/modules/edit-file-vim.js.map +1 -1
  20. package/dist/modules/edit-file.js +8 -0
  21. package/dist/modules/edit-file.js.map +1 -1
  22. package/dist/modules/edit-names-vim.js +8 -0
  23. package/dist/modules/edit-names-vim.js.map +1 -1
  24. package/dist/modules/edit-names.js +8 -0
  25. package/dist/modules/edit-names.js.map +1 -1
  26. package/dist/modules/edit.js +8 -0
  27. package/dist/modules/edit.js.map +1 -1
  28. package/dist/modules/help.js +8 -0
  29. package/dist/modules/help.js.map +1 -1
  30. package/dist/modules/konsole.js +8 -0
  31. package/dist/modules/konsole.js.map +1 -1
  32. package/dist/modules/markdown.js +8 -0
  33. package/dist/modules/markdown.js.map +1 -1
  34. package/dist/modules/menu.js +8 -0
  35. package/dist/modules/menu.js.map +1 -1
  36. package/dist/modules/operation.js +8 -0
  37. package/dist/modules/operation.js.map +1 -1
  38. package/dist/modules/polyfill.js +8 -0
  39. package/dist/modules/polyfill.js.map +1 -1
  40. package/dist/modules/terminal-run.js +8 -0
  41. package/dist/modules/terminal-run.js.map +1 -1
  42. package/dist/modules/terminal.js +8 -0
  43. package/dist/modules/terminal.js.map +1 -1
  44. package/dist/modules/upload.js +8 -0
  45. package/dist/modules/upload.js.map +1 -1
  46. package/dist/modules/user-menu.js +8 -0
  47. package/dist/modules/user-menu.js.map +1 -1
  48. package/dist/modules/view.js +8 -0
  49. package/dist/modules/view.js.map +1 -1
  50. package/dist/sw.js +1 -1
  51. package/dist-dev/cloudcmd.common.js +27 -16
  52. package/dist-dev/cloudcmd.js +8 -0
  53. package/dist-dev/index.html +1 -2
  54. package/dist-dev/modules/cloud.js +8 -0
  55. package/dist-dev/modules/command-line.js +8 -0
  56. package/dist-dev/modules/config.js +8 -0
  57. package/dist-dev/modules/contact.js +8 -0
  58. package/dist-dev/modules/edit-file-vim.js +8 -0
  59. package/dist-dev/modules/edit-file.js +8 -0
  60. package/dist-dev/modules/edit-names-vim.js +8 -0
  61. package/dist-dev/modules/edit-names.js +8 -0
  62. package/dist-dev/modules/edit.js +8 -0
  63. package/dist-dev/modules/help.js +8 -0
  64. package/dist-dev/modules/konsole.js +8 -0
  65. package/dist-dev/modules/markdown.js +8 -0
  66. package/dist-dev/modules/menu.js +8 -0
  67. package/dist-dev/modules/operation.js +8 -0
  68. package/dist-dev/modules/polyfill.js +8 -0
  69. package/dist-dev/modules/terminal-run.js +8 -0
  70. package/dist-dev/modules/terminal.js +8 -0
  71. package/dist-dev/modules/upload.js +8 -0
  72. package/dist-dev/modules/user-menu.js +8 -0
  73. package/dist-dev/modules/view.js +8 -0
  74. package/dist-dev/sw.js +1 -1
  75. package/package.json +3 -1
  76. package/server/rest/index.js +1 -1
  77. package/server/server.js +24 -7
  78. package/server/validate.js +1 -1
  79. package/public/manifest.json +0 -11
@@ -112,6 +112,14 @@
112
112
  /******/ };
113
113
  /******/ })();
114
114
  /******/
115
+ /******/ /* webpack/runtime/set anonymous default export name */
116
+ /******/ (() => {
117
+ /******/ // set .name for anonymous default exports per ES spec
118
+ /******/ __webpack_require__.dn = (x) => {
119
+ /******/ (Object.getOwnPropertyDescriptor(x, "name") || {}).writable || Object.defineProperty(x, "name", { value: "default", configurable: true });
120
+ /******/ };
121
+ /******/ })();
122
+ /******/
115
123
  /******/ /* webpack/runtime/jsonp chunk loading */
116
124
  /******/ (() => {
117
125
  /******/ // no baseURI
@@ -112,6 +112,14 @@
112
112
  /******/ };
113
113
  /******/ })();
114
114
  /******/
115
+ /******/ /* webpack/runtime/set anonymous default export name */
116
+ /******/ (() => {
117
+ /******/ // set .name for anonymous default exports per ES spec
118
+ /******/ __webpack_require__.dn = (x) => {
119
+ /******/ (Object.getOwnPropertyDescriptor(x, "name") || {}).writable || Object.defineProperty(x, "name", { value: "default", configurable: true });
120
+ /******/ };
121
+ /******/ })();
122
+ /******/
115
123
  /******/ /* webpack/runtime/jsonp chunk loading */
116
124
  /******/ (() => {
117
125
  /******/ // no baseURI
@@ -112,6 +112,14 @@
112
112
  /******/ };
113
113
  /******/ })();
114
114
  /******/
115
+ /******/ /* webpack/runtime/set anonymous default export name */
116
+ /******/ (() => {
117
+ /******/ // set .name for anonymous default exports per ES spec
118
+ /******/ __webpack_require__.dn = (x) => {
119
+ /******/ (Object.getOwnPropertyDescriptor(x, "name") || {}).writable || Object.defineProperty(x, "name", { value: "default", configurable: true });
120
+ /******/ };
121
+ /******/ })();
122
+ /******/
115
123
  /******/ /* webpack/runtime/jsonp chunk loading */
116
124
  /******/ (() => {
117
125
  /******/ // no baseURI
package/dist-dev/sw.js CHANGED
@@ -37,7 +37,7 @@ eval("{// shim for using process in browser\nvar process = module.exports = {};\
37
37
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
38
38
 
39
39
  "use strict";
40
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var node_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! node:process */ \"./node_modules/process/browser.js\");\n/* harmony import */ var try_to_catch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\n/* harmony import */ var currify__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\n\n\n\nconst isDev = \"development\" === 'development';\nconst isGet = a => a.method === 'GET';\nconst isBasic = a => a.type === 'basic';\nconst wait = currify__WEBPACK_IMPORTED_MODULE_2__((f, e) => e.waitUntil(f()));\nconst respondWith = currify__WEBPACK_IMPORTED_MODULE_2__((f, e) => {\n const {\n request\n } = e;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n if (url.endsWith('/') || /\\^\\/fs/.test(pathname)) return;\n if (!isGet(request)) return;\n if (!isBasic(request)) return;\n if (pathname.startsWith('/api')) return;\n if (/^socket.io/.test(pathname)) return;\n e.respondWith(f(e));\n});\nconst getPathName = url => new URL(url).pathname;\nconst date = \"Sun May 17 2026 01:48:22 GMT+0300 (Eastern European Summer Time)\";\nconst NAME = `cloudcmd: ${date}`;\nconst createRequest = a => new Request(a, {\n credentials: 'same-origin'\n});\nconst getRequest = (a, request) => {\n if (a !== '/') return request;\n return createRequest('/');\n};\nglobalThis.addEventListener('install', wait(onInstall));\nglobalThis.addEventListener('fetch', respondWith(onFetch));\nglobalThis.addEventListener('activate', wait(onActivate));\nasync function onActivate() {\n console.info(`cloudcmd: sw: activate: ${NAME}`);\n await globalThis.clients.claim();\n const keys = await caches.keys();\n const deleteCache = caches.delete.bind(caches);\n await Promise.all(keys.map(deleteCache));\n}\nasync function onInstall() {\n console.info(`cloudcmd: sw: install: ${NAME}`);\n await globalThis.skipWaiting();\n}\nasync function onFetch(event) {\n const {\n request\n } = event;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n const newRequest = getRequest(pathname, event.request);\n const cache = await caches.open(NAME);\n const response = await cache.match(request);\n if (!isDev && response) return response;\n const [e, resp] = await (0,try_to_catch__WEBPACK_IMPORTED_MODULE_1__.tryToCatch)(fetch, newRequest, {\n credentials: 'same-origin'\n });\n if (e) return new Response(e.message);\n await addToCache(request, resp.clone());\n return resp;\n}\nasync function addToCache(request, response) {\n const cache = await caches.open(NAME);\n return cache.put(request, response);\n}\n\n//# sourceURL=file://cloudcmd//Users/coderaiser/cloudcmd/client/sw/sw.js\n}");
40
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var node_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! node:process */ \"./node_modules/process/browser.js\");\n/* harmony import */ var try_to_catch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\n/* harmony import */ var currify__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\n\n\n\nconst isDev = \"development\" === 'development';\nconst isGet = a => a.method === 'GET';\nconst isBasic = a => a.type === 'basic';\nconst wait = currify__WEBPACK_IMPORTED_MODULE_2__((f, e) => e.waitUntil(f()));\nconst respondWith = currify__WEBPACK_IMPORTED_MODULE_2__((f, e) => {\n const {\n request\n } = e;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n if (url.endsWith('/') || /\\^\\/fs/.test(pathname)) return;\n if (!isGet(request)) return;\n if (!isBasic(request)) return;\n if (pathname.startsWith('/api')) return;\n if (/^socket.io/.test(pathname)) return;\n e.respondWith(f(e));\n});\nconst getPathName = url => new URL(url).pathname;\nconst date = \"Tue May 26 2026 22:09:22 GMT+0300 (Eastern European Summer Time)\";\nconst NAME = `cloudcmd: ${date}`;\nconst createRequest = a => new Request(a, {\n credentials: 'same-origin'\n});\nconst getRequest = (a, request) => {\n if (a !== '/') return request;\n return createRequest('/');\n};\nglobalThis.addEventListener('install', wait(onInstall));\nglobalThis.addEventListener('fetch', respondWith(onFetch));\nglobalThis.addEventListener('activate', wait(onActivate));\nasync function onActivate() {\n console.info(`cloudcmd: sw: activate: ${NAME}`);\n await globalThis.clients.claim();\n const keys = await caches.keys();\n const deleteCache = caches.delete.bind(caches);\n await Promise.all(keys.map(deleteCache));\n}\nasync function onInstall() {\n console.info(`cloudcmd: sw: install: ${NAME}`);\n await globalThis.skipWaiting();\n}\nasync function onFetch(event) {\n const {\n request\n } = event;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n const newRequest = getRequest(pathname, event.request);\n const cache = await caches.open(NAME);\n const response = await cache.match(request);\n if (!isDev && response) return response;\n const [e, resp] = await (0,try_to_catch__WEBPACK_IMPORTED_MODULE_1__.tryToCatch)(fetch, newRequest, {\n credentials: 'same-origin'\n });\n if (e) return new Response(e.message);\n await addToCache(request, resp.clone());\n return resp;\n}\nasync function addToCache(request, response) {\n const cache = await caches.open(NAME);\n return cache.put(request, response);\n}\n\n//# sourceURL=file://cloudcmd//Users/coderaiser/cloudcmd/client/sw/sw.js\n}");
41
41
 
42
42
  /***/ },
43
43
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudcmd",
3
- "version": "19.17.0",
3
+ "version": "19.18.1",
4
4
  "type": "module",
5
5
  "author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
6
6
  "description": "File manager for the web with console and editor",
@@ -55,6 +55,7 @@
55
55
  "fix:lint": "madrun fix:lint",
56
56
  "lint:stream": "madrun lint:stream",
57
57
  "test": "madrun test",
58
+ "test:e2e": "madrun test:e2e",
58
59
  "test:client": "madrun test:client",
59
60
  "test:server": "madrun test:server",
60
61
  "wisdom": "madrun wisdom",
@@ -105,6 +106,7 @@
105
106
  "es6-promisify": "^7.0.0",
106
107
  "execon": "^1.2.0",
107
108
  "express": "^5.1.0",
109
+ "express-rate-limit": "^8.5.2",
108
110
  "files-io": "^4.0.0",
109
111
  "find-up": "^8.0.0",
110
112
  "for-each-key": "^2.0.0",
@@ -72,7 +72,7 @@ function rest({fs, config, moveFiles}, request, response) {
72
72
  return ponse.sendError(error, params);
73
73
 
74
74
  if (error)
75
- return ponse.sendError(error.stack, params);
75
+ return ponse.sendError(error, params);
76
76
 
77
77
  ponse.send(data, params);
78
78
  });
package/server/server.js CHANGED
@@ -1,23 +1,29 @@
1
1
  import http from 'node:http';
2
2
  import {promisify} from 'node:util';
3
3
  import process from 'node:process';
4
+ import {rateLimit} from 'express-rate-limit';
4
5
  import currify from 'currify';
5
6
  import squad from 'squad';
6
7
  import {tryToCatch} from 'try-to-catch';
7
8
  import opn from 'open';
8
9
  import express from 'express';
9
10
  import {Server} from 'socket.io';
10
- import tryRequire from 'tryrequire';
11
11
  import wraptile from 'wraptile';
12
12
  import compression from 'compression';
13
+ import tryRequire from 'tryrequire';
13
14
  import {cloudcmd} from '#server/cloudcmd';
14
15
  import exit from './exit.js';
15
16
 
17
+ const RATE_LIMIT = 1000;
18
+ const RATE_WINDOW = 15 * 60 * 1000;
19
+
16
20
  const bind = (f, self) => f.bind(self);
17
21
 
18
22
  const two = currify((f, a, b) => f(a, b));
19
- const shutdown = wraptile(async (promises) => {
20
- console.log('closing cloudcmd...');
23
+ const shutdown = wraptile(async (config, promises) => {
24
+ if (config('log'))
25
+ console.log('closing cloudcmd...');
26
+
21
27
  await Promise.all(promises);
22
28
  process.exit(0);
23
29
  });
@@ -25,6 +31,7 @@ const shutdown = wraptile(async (promises) => {
25
31
  const promisifySelf = squad(promisify, bind);
26
32
 
27
33
  const exitPort = two(exit, 'cloudcmd --port: %s');
34
+
28
35
  const logger = tryRequire('morgan');
29
36
 
30
37
  export default async (options, config) => {
@@ -36,7 +43,7 @@ export default async (options, config) => {
36
43
  const app = express();
37
44
  const server = http.createServer(app);
38
45
 
39
- if (logger)
46
+ if (config('log') && logger)
40
47
  app.use(logger('dev'));
41
48
 
42
49
  if (prefix)
@@ -46,8 +53,15 @@ export default async (options, config) => {
46
53
  path: `${prefix}/socket.io`,
47
54
  });
48
55
 
49
- app.use(compression());
56
+ const limiter = rateLimit({
57
+ windowMs: RATE_WINDOW,
58
+ limit: RATE_LIMIT,
59
+ });
60
+
61
+ app.set('trust proxy', 1);
50
62
 
63
+ app.use(compression());
64
+ app.use(limiter);
51
65
  app.use(prefix, cloudcmd({
52
66
  config: options,
53
67
  socket: socketServer,
@@ -64,14 +78,17 @@ export default async (options, config) => {
64
78
  server.on('error', exitPort);
65
79
  await listen(port, ip);
66
80
 
67
- const close = shutdown([closeServer, closeSocket]);
81
+ const close = shutdown(config, [closeServer, closeSocket]);
82
+
68
83
  process.on('SIGINT', close);
84
+ process.on('SIGUSR1', close);
69
85
 
70
86
  const host = config('ip') || 'localhost';
71
87
  const port0 = port || server.address().port;
72
88
  const url = `http://${host}:${port0}${prefix}/`;
73
89
 
74
- console.log(`url: ${url}`);
90
+ if (config('log'))
91
+ console.log(`url: ${url}`);
75
92
 
76
93
  if (!config('open'))
77
94
  return;
@@ -31,7 +31,7 @@ export const editor = (name, {exit = _exit} = {}) => {
31
31
  const reg = /^(dword|edward|deepword|qword)$/;
32
32
 
33
33
  if (!reg.test(name))
34
- exit(`cloudcmd --editor: could be "dword", "edward", "deepword" or "qword" only, recieved: "${name}"`);
34
+ exit(`cloudcmd --editor: could be "dword", "edward", "deepword" or "qword" only, received: "${name}"`);
35
35
  };
36
36
 
37
37
  export const menu = (name, {exit = _exit} = {}) => {
@@ -1,11 +0,0 @@
1
- {
2
- "short_name": "CloudCMD",
3
- "name": "Cloud Commander",
4
- "display": "standalone",
5
- "start_url": "..",
6
- "icons": [{
7
- "src": "../img/favicon/favicon-256.png",
8
- "type": "image/png",
9
- "sizes": "256x256"
10
- }]
11
- }