cloudcmd 17.1.6 → 17.2.0
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.
- package/ChangeLog +10 -1
- package/HELP.md +3 -2
- package/README.md +1 -1
- package/dist/sw.js +1 -1
- package/dist-dev/sw.js +1 -1
- package/package.json +3 -2
- package/server/{cloudcmd.js → cloudcmd.mjs} +52 -48
- package/server/cloudcmd.spec.mjs +180 -0
- package/server/config.spec.mjs +105 -0
- package/server/distribute/export.spec.mjs +68 -0
- package/server/distribute/import.spec.mjs +287 -0
- package/server/markdown/index.spec.mjs +126 -0
- package/server/rest/index.js +21 -18
- package/server/route.spec.mjs +458 -0
- package/server/server.mjs +6 -6
- package/server/terminal.js +6 -2
- package/server/terminal.spec.mjs +73 -0
- package/server/{user-menu.js → user-menu.mjs} +17 -17
- package/server/user-menu.spec.mjs +74 -0
- package/server/validate.spec.mjs +104 -0
package/ChangeLog
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
2024.03.22, v17.2.0
|
|
2
|
+
|
|
3
|
+
feature:
|
|
4
|
+
- 3e565109 convert to ESM
|
|
5
|
+
- 770a0812 pack: get rid of mock-require
|
|
6
|
+
- 25d8faea rest: get rid of mock-require
|
|
7
|
+
- 401a669a user-menu: get rid of mock-require
|
|
8
|
+
- 4e32241d terminal: get rid of mock-require
|
|
9
|
+
|
|
1
10
|
2024.03.21, v17.1.6
|
|
2
11
|
|
|
3
12
|
feature:
|
|
@@ -5587,7 +5596,7 @@ fix:
|
|
|
5587
5596
|
- (rest) onDelete: func(null, body) -> func
|
|
5588
5597
|
- (rest) onStat: add var
|
|
5589
5598
|
- (cloudcmd) change index path
|
|
5590
|
-
- (server) start: url ->
|
|
5599
|
+
- (server) start: url -> PREFIX
|
|
5591
5600
|
- (server) start: SSLPort -> sslPort
|
|
5592
5601
|
- (server) start: Port -> port
|
|
5593
5602
|
- (dom) getCurrentDirPath: "," -> ";"
|
package/HELP.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Cloud Commander v17.
|
|
1
|
+
# Cloud Commander v17.2.0
|
|
2
2
|
|
|
3
3
|
### [Main][MainURL] [Blog][BlogURL] [Support][SupportURL] [Demo][DemoURL]
|
|
4
4
|
|
|
@@ -133,7 +133,7 @@ Cloud Commander supports the following command-line parameters:
|
|
|
133
133
|
|
|
134
134
|
For options not specified by command-line parameters, Cloud Commander then reads configuration data from `~/.cloudcmd.json`. It uses port `8000` by default.
|
|
135
135
|
|
|
136
|
-
To begin using the web client, go to this
|
|
136
|
+
To begin using the web client, go to this PREFIX in your browser:
|
|
137
137
|
|
|
138
138
|
```
|
|
139
139
|
http://localhost:8000
|
|
@@ -1093,6 +1093,7 @@ There are a lot of ways to be involved in `Cloud Commander` development:
|
|
|
1093
1093
|
|
|
1094
1094
|
## Version history
|
|
1095
1095
|
|
|
1096
|
+
- *2024.03.22*, **[v17.2.0](//github.com/coderaiser/cloudcmd/releases/tag/v17.2.0)**
|
|
1096
1097
|
- *2024.03.21*, **[v17.1.6](//github.com/coderaiser/cloudcmd/releases/tag/v17.1.6)**
|
|
1097
1098
|
- *2024.03.20*, **[v17.1.5](//github.com/coderaiser/cloudcmd/releases/tag/v17.1.5)**
|
|
1098
1099
|
- *2024.03.20*, **[v17.1.4](//github.com/coderaiser/cloudcmd/releases/tag/v17.1.4)**
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Cloud Commander v17.
|
|
1
|
+
# Cloud Commander v17.2.0 [![Build Status][BuildStatusIMGURL]][BuildStatusURL] [![Codacy][CodacyIMG]][CodacyURL] [![Gitter][GitterIMGURL]][GitterURL]
|
|
2
2
|
|
|
3
3
|
### [Main][MainURL] [Blog][BlogURL] [Support][SupportURL] [Demo][DemoURL]
|
|
4
4
|
|
package/dist/sw.js
CHANGED
|
@@ -5,5 +5,5 @@ var serviceWorkerOption = {
|
|
|
5
5
|
]
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
-
!function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/dist/",n(n.s=0)}([function(t,e,n){"use strict";const r=n(1),o=n(2),i=n(3),u="development"===r.env.NODE_ENV,c=i((t,e)=>e.waitUntil(t())),s=i((t,e)=>{const{request:n}=e,{url:r}=n,o=a(r);r.endsWith("/")||/\^\/fs/.test(o)||"GET"===n.method&&(t=>"basic"===t.type)(n)&&(o.startsWith("/api")||/^socket.io/.test(o)||e.respondWith(t(e)))}),a=t=>new URL(t).pathname,f="cloudcmd:
|
|
8
|
+
!function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/dist/",n(n.s=0)}([function(t,e,n){"use strict";const r=n(1),o=n(2),i=n(3),u="development"===r.env.NODE_ENV,c=i((t,e)=>e.waitUntil(t())),s=i((t,e)=>{const{request:n}=e,{url:r}=n,o=a(r);r.endsWith("/")||/\^\/fs/.test(o)||"GET"===n.method&&(t=>"basic"===t.type)(n)&&(o.startsWith("/api")||/^socket.io/.test(o)||e.respondWith(t(e)))}),a=t=>new URL(t).pathname,f="cloudcmd: Fri Mar 22 2024 23:00:43 GMT+0200 (Eastern European Standard Time)",l=(t,e)=>"/"!==t?e:(t=>new Request(t,{credentials:"same-origin"}))("/");self.addEventListener("install",c((async function(){console.info("cloudcmd: sw: install: "+f),await self.skipWaiting()}))),self.addEventListener("fetch",s((async function(t){const{request:e}=t,{url:n}=e,r=a(n),i=l(r,t.request),c=await caches.open(f),s=await c.match(e);if(!u&&s)return s;const[d,h]=await o(fetch,i,{credentials:"same-origin"});return d?new Response(d.message):(await async function(t,e){return(await caches.open(f)).put(t,e)}(e,h.clone()),h)}))),self.addEventListener("activate",c((async function(){console.info("cloudcmd: sw: activate: "+f),await self.clients.claim();const t=await caches.keys(),e=caches.delete.bind(caches);await Promise.all(t.map(e))})))},function(t,e){var n,r,o=t.exports={};function i(){throw new Error("setTimeout has not been defined")}function u(){throw new Error("clearTimeout has not been defined")}function c(t){if(n===setTimeout)return setTimeout(t,0);if((n===i||!n)&&setTimeout)return n=setTimeout,setTimeout(t,0);try{return n(t,0)}catch(e){try{return n.call(null,t,0)}catch(e){return n.call(this,t,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:i}catch(t){n=i}try{r="function"==typeof clearTimeout?clearTimeout:u}catch(t){r=u}}();var s,a=[],f=!1,l=-1;function d(){f&&s&&(f=!1,s.length?a=s.concat(a):l=-1,a.length&&h())}function h(){if(!f){var t=c(d);f=!0;for(var e=a.length;e;){for(s=a,a=[];++l<e;)s&&s[l].run();l=-1,e=a.length}s=null,f=!1,function(t){if(r===clearTimeout)return clearTimeout(t);if((r===u||!r)&&clearTimeout)return r=clearTimeout,clearTimeout(t);try{r(t)}catch(e){try{return r.call(null,t)}catch(e){return r.call(this,t)}}}(t)}}function p(t,e){this.fun=t,this.array=e}function m(){}o.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)e[n-1]=arguments[n];a.push(new p(t,e)),1!==a.length||f||c(h)},p.prototype.run=function(){this.fun.apply(null,this.array)},o.title="browser",o.browser=!0,o.env={},o.argv=[],o.version="",o.versions={},o.on=m,o.addListener=m,o.once=m,o.off=m,o.removeListener=m,o.removeAllListeners=m,o.emit=m,o.prependListener=m,o.prependOnceListener=m,o.listeners=function(t){return[]},o.binding=function(t){throw new Error("process.binding is not supported")},o.cwd=function(){return"/"},o.chdir=function(t){throw new Error("process.chdir is not supported")},o.umask=function(){return 0}},function(t,e,n){"use strict";t.exports=async(t,...e)=>{!function(t){if("function"!=typeof t)throw Error("fn should be a function!")}(t);try{return[null,await t(...e)]}catch(t){return[t]}}},function(t,e,n){"use strict";const r=(t,...e)=>{if(function(t){if("function"!=typeof t)throw Error("fn should be function!")}(t),e.length>=t.length)return t(...e);const n=(...n)=>r(t,...e,...n),o=t.length-e.length-1;return(t=>[function(e){return t(...arguments)},function(e,n){return t(...arguments)},function(e,n,r){return t(...arguments)},function(e,n,r,o){return t(...arguments)},function(e,n,r,o,i){return t(...arguments)}])(n)[o]||n};t.exports=r}]);
|
|
9
9
|
//# sourceMappingURL=sw.js.map
|
package/dist-dev/sw.js
CHANGED
|
@@ -101,7 +101,7 @@ var serviceWorkerOption = {
|
|
|
101
101
|
/***/ (function(module, exports, __webpack_require__) {
|
|
102
102
|
|
|
103
103
|
"use strict";
|
|
104
|
-
eval("\n\nconst process = __webpack_require__(/*! node:process */ \"./node_modules/process/browser.js\");\nconst tryToCatch = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\nconst isDev = process.env.NODE_ENV === 'development';\nconst isGet = a => a.method === 'GET';\nconst isBasic = a => a.type === 'basic';\nconst wait = currify((f, e) => e.waitUntil(f()));\nconst respondWith = currify((f, e) => {\n const {\n request\n } = e;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n if (url.endsWith('/') || /\\^\\/fs/.test(pathname)) return;\n if (!isGet(request)) return;\n if (!isBasic(request)) return;\n if (pathname.startsWith('/api')) return;\n if (/^socket.io/.test(pathname)) return;\n e.respondWith(f(e));\n});\nconst getPathName = url => new URL(url).pathname;\nconst date = \"
|
|
104
|
+
eval("\n\nconst process = __webpack_require__(/*! node:process */ \"./node_modules/process/browser.js\");\nconst tryToCatch = __webpack_require__(/*! try-to-catch */ \"./node_modules/try-to-catch/lib/try-to-catch.js\");\nconst currify = __webpack_require__(/*! currify */ \"./node_modules/currify/lib/currify.js\");\nconst isDev = process.env.NODE_ENV === 'development';\nconst isGet = a => a.method === 'GET';\nconst isBasic = a => a.type === 'basic';\nconst wait = currify((f, e) => e.waitUntil(f()));\nconst respondWith = currify((f, e) => {\n const {\n request\n } = e;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n if (url.endsWith('/') || /\\^\\/fs/.test(pathname)) return;\n if (!isGet(request)) return;\n if (!isBasic(request)) return;\n if (pathname.startsWith('/api')) return;\n if (/^socket.io/.test(pathname)) return;\n e.respondWith(f(e));\n});\nconst getPathName = url => new URL(url).pathname;\nconst date = \"Fri Mar 22 2024 23:00:51 GMT+0200 (Eastern European Standard Time)\";\nconst NAME = `cloudcmd: ${date}`;\nconst createRequest = a => new Request(a, {\n credentials: 'same-origin'\n});\nconst getRequest = (a, request) => {\n if (a !== '/') return request;\n return createRequest('/');\n};\nself.addEventListener('install', wait(onInstall));\nself.addEventListener('fetch', respondWith(onFetch));\nself.addEventListener('activate', wait(onActivate));\nasync function onActivate() {\n console.info(`cloudcmd: sw: activate: ${NAME}`);\n await self.clients.claim();\n const keys = await caches.keys();\n const deleteCache = caches.delete.bind(caches);\n await Promise.all(keys.map(deleteCache));\n}\nasync function onInstall() {\n console.info(`cloudcmd: sw: install: ${NAME}`);\n await self.skipWaiting();\n}\nasync function onFetch(event) {\n const {\n request\n } = event;\n const {\n url\n } = request;\n const pathname = getPathName(url);\n const newRequest = getRequest(pathname, event.request);\n const cache = await caches.open(NAME);\n const response = await cache.match(request);\n if (!isDev && response) return response;\n const [e, resp] = await tryToCatch(fetch, newRequest, {\n credentials: 'same-origin'\n });\n if (e) return new Response(e.message);\n await addToCache(request, resp.clone());\n return resp;\n}\nasync function addToCache(request, response) {\n const cache = await caches.open(NAME);\n return cache.put(request, response);\n}\n\n//# sourceURL=file://cloudcmd/client/sw/sw.js");
|
|
105
105
|
|
|
106
106
|
/***/ }),
|
|
107
107
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cloudcmd",
|
|
3
|
-
"version": "17.
|
|
3
|
+
"version": "17.2.0",
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
|
|
6
6
|
"description": "File manager for the web with console and editor",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"type": "git",
|
|
11
11
|
"url": "git://github.com/coderaiser/cloudcmd.git"
|
|
12
12
|
},
|
|
13
|
-
"main": "server/cloudcmd.
|
|
13
|
+
"main": "server/cloudcmd.mjs",
|
|
14
14
|
"keywords": [
|
|
15
15
|
"console",
|
|
16
16
|
"terminal",
|
|
@@ -188,6 +188,7 @@
|
|
|
188
188
|
"memfs": "^4.2.0",
|
|
189
189
|
"minor": "^1.2.2",
|
|
190
190
|
"mock-require": "^3.0.1",
|
|
191
|
+
"montag": "^1.2.1",
|
|
191
192
|
"morgan": "^1.6.1",
|
|
192
193
|
"multi-rename": "^2.0.0",
|
|
193
194
|
"nodemon": "^3.0.1",
|
|
@@ -1,38 +1,34 @@
|
|
|
1
|
-
|
|
1
|
+
import path, {dirname, join} from 'node:path';
|
|
2
|
+
import {fileURLToPath} from 'node:url';
|
|
3
|
+
import process from 'node:process';
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import fullstore from 'fullstore';
|
|
6
|
+
import currify from 'currify';
|
|
7
|
+
import apart from 'apart';
|
|
8
|
+
import ponse from 'ponse';
|
|
9
|
+
import restafary from 'restafary';
|
|
10
|
+
import restbox from 'restbox';
|
|
11
|
+
import konsole from 'console-io';
|
|
12
|
+
import edward from 'edward';
|
|
13
|
+
import dword from 'dword';
|
|
14
|
+
import deepword from 'deepword';
|
|
15
|
+
import nomine from 'nomine';
|
|
16
|
+
import fileop from '@cloudcmd/fileop';
|
|
17
|
+
import cloudfunc from '../common/cloudfunc.js';
|
|
18
|
+
import authentication from './auth.js';
|
|
19
|
+
import {createConfig, configPath} from './config.js';
|
|
20
|
+
import modulas from './modulas.js';
|
|
21
|
+
import userMenu from './user-menu.mjs';
|
|
22
|
+
import rest from './rest/index.js';
|
|
23
|
+
import route from './route.js';
|
|
24
|
+
import validate from './validate.js';
|
|
25
|
+
import prefixer from './prefixer.js';
|
|
26
|
+
import terminal from './terminal.js';
|
|
27
|
+
import distribute from './distribute/index.js';
|
|
28
|
+
import {createDepStore} from './depstore.js';
|
|
2
29
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const process = require('node:process');
|
|
6
|
-
const path = require('node:path');
|
|
7
|
-
const fs = require('node:fs');
|
|
8
|
-
|
|
9
|
-
const currify = require('currify');
|
|
10
|
-
const apart = require('apart');
|
|
11
|
-
const ponse = require('ponse');
|
|
12
|
-
const restafary = require('restafary');
|
|
13
|
-
const restbox = require('restbox');
|
|
14
|
-
const konsole = require('console-io');
|
|
15
|
-
const edward = require('edward');
|
|
16
|
-
const dword = require('dword');
|
|
17
|
-
const deepword = require('deepword');
|
|
18
|
-
const nomine = require('nomine');
|
|
19
|
-
const fileop = require('@cloudcmd/fileop');
|
|
20
|
-
|
|
21
|
-
const cloudfunc = require('../common/cloudfunc');
|
|
22
|
-
|
|
23
|
-
const authentication = require('./auth');
|
|
24
|
-
const {createConfig, configPath} = require(`./config`);
|
|
25
|
-
|
|
26
|
-
const modulas = require(`./modulas`);
|
|
27
|
-
|
|
28
|
-
const userMenu = require(`./user-menu`);
|
|
29
|
-
const rest = require(`./rest`);
|
|
30
|
-
const route = require(`./route`);
|
|
31
|
-
const validate = require(`./validate`);
|
|
32
|
-
const prefixer = require(`./prefixer`);
|
|
33
|
-
const terminal = require(`./terminal`);
|
|
34
|
-
const distribute = require(`./distribute`);
|
|
35
|
-
const {createDepStore} = require('./depstore');
|
|
30
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
31
|
+
const __dirname = dirname(__filename);
|
|
36
32
|
const {assign} = Object;
|
|
37
33
|
const DIR = `${__dirname}/`;
|
|
38
34
|
const DIR_ROOT = join(DIR, '..');
|
|
@@ -50,7 +46,7 @@ const clean = (a) => a.filter(notEmpty);
|
|
|
50
46
|
const isUndefined = (a) => typeof a === 'undefined';
|
|
51
47
|
const isFn = (a) => typeof a === 'function';
|
|
52
48
|
|
|
53
|
-
|
|
49
|
+
export default cloudcmd;
|
|
54
50
|
|
|
55
51
|
function cloudcmd(params) {
|
|
56
52
|
const p = params || {};
|
|
@@ -97,14 +93,12 @@ function cloudcmd(params) {
|
|
|
97
93
|
|
|
98
94
|
const depStore = createDepStore();
|
|
99
95
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
module.exports.createConfigManager = createConfig;
|
|
105
|
-
module.exports.configPath = configPath;
|
|
96
|
+
export const createConfigManager = createConfig;
|
|
97
|
+
export {
|
|
98
|
+
configPath,
|
|
99
|
+
};
|
|
106
100
|
|
|
107
|
-
|
|
101
|
+
export const _getIndexPath = getIndexPath;
|
|
108
102
|
|
|
109
103
|
function defaultValue(config, name, options) {
|
|
110
104
|
const value = options[name];
|
|
@@ -116,7 +110,8 @@ function defaultValue(config, name, options) {
|
|
|
116
110
|
return value;
|
|
117
111
|
}
|
|
118
112
|
|
|
119
|
-
|
|
113
|
+
export const _getPrefix = getPrefix;
|
|
114
|
+
|
|
120
115
|
function getPrefix(prefix) {
|
|
121
116
|
if (isFn(prefix))
|
|
122
117
|
return prefix() || '';
|
|
@@ -124,8 +119,7 @@ function getPrefix(prefix) {
|
|
|
124
119
|
return prefix || '';
|
|
125
120
|
}
|
|
126
121
|
|
|
127
|
-
|
|
128
|
-
function _initAuth(config, accept, reject, username, password) {
|
|
122
|
+
export function _initAuth(config, accept, reject, username, password) {
|
|
129
123
|
if (!config('auth'))
|
|
130
124
|
return accept();
|
|
131
125
|
|
|
@@ -248,7 +242,11 @@ function cloudcmdMiddle({modules, config}) {
|
|
|
248
242
|
userMenu({
|
|
249
243
|
menuName: '.cloudcmd.menu.js',
|
|
250
244
|
}),
|
|
251
|
-
rest(
|
|
245
|
+
rest({
|
|
246
|
+
config,
|
|
247
|
+
fs: depStore('fs'),
|
|
248
|
+
moveFiles: depStore('moveFiles'),
|
|
249
|
+
}),
|
|
252
250
|
route(config, {
|
|
253
251
|
html,
|
|
254
252
|
win32: depStore('win32'),
|
|
@@ -266,8 +264,9 @@ function logout(req, res, next) {
|
|
|
266
264
|
res.sendStatus(401);
|
|
267
265
|
}
|
|
268
266
|
|
|
269
|
-
|
|
270
|
-
|
|
267
|
+
export const _isDev = isDev;
|
|
268
|
+
export const _replaceDist = replaceDist;
|
|
269
|
+
|
|
271
270
|
function replaceDist(url) {
|
|
272
271
|
if (!isDev())
|
|
273
272
|
return url;
|
|
@@ -293,3 +292,8 @@ function setSW(req, res, next) {
|
|
|
293
292
|
|
|
294
293
|
next();
|
|
295
294
|
}
|
|
295
|
+
|
|
296
|
+
assign(cloudcmd, {
|
|
297
|
+
depStore,
|
|
298
|
+
createConfigManager,
|
|
299
|
+
});
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import path, {dirname} from 'node:path';
|
|
2
|
+
import {fileURLToPath} from 'node:url';
|
|
3
|
+
import serveOnce from 'serve-once';
|
|
4
|
+
import {test, stub} from 'supertape';
|
|
5
|
+
import cloudcmd, {
|
|
6
|
+
_isDev,
|
|
7
|
+
_replaceDist,
|
|
8
|
+
createConfigManager,
|
|
9
|
+
_getPrefix,
|
|
10
|
+
_initAuth,
|
|
11
|
+
_getIndexPath,
|
|
12
|
+
} from './cloudcmd.mjs';
|
|
13
|
+
|
|
14
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
15
|
+
const __dirname = dirname(__filename);
|
|
16
|
+
|
|
17
|
+
const {request} = serveOnce(cloudcmd, {
|
|
18
|
+
config: {
|
|
19
|
+
auth: false,
|
|
20
|
+
dropbox: false,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('cloudcmd: defaults: config', (t) => {
|
|
25
|
+
const configManager = createConfigManager();
|
|
26
|
+
|
|
27
|
+
configManager('configDialog', false);
|
|
28
|
+
|
|
29
|
+
cloudcmd({
|
|
30
|
+
configManager,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
t.notOk(configManager('configDialog'), 'should not override config with defaults');
|
|
34
|
+
t.end();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('cloudcmd: defaults: console', (t) => {
|
|
38
|
+
const configManager = createConfigManager();
|
|
39
|
+
configManager('console', false);
|
|
40
|
+
|
|
41
|
+
cloudcmd({
|
|
42
|
+
configManager,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
t.notOk(configManager('console'), 'should not override config with defaults');
|
|
46
|
+
t.end();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('cloudcmd: getPrefix', (t) => {
|
|
50
|
+
const value = 'hello';
|
|
51
|
+
const result = _getPrefix(value);
|
|
52
|
+
|
|
53
|
+
t.equal(result, value);
|
|
54
|
+
t.end();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('cloudcmd: getPrefix: function', (t) => {
|
|
58
|
+
const value = 'hello';
|
|
59
|
+
const fn = () => value;
|
|
60
|
+
const result = _getPrefix(fn);
|
|
61
|
+
|
|
62
|
+
t.equal(result, value);
|
|
63
|
+
t.end();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('cloudcmd: getPrefix: function: empty', (t) => {
|
|
67
|
+
const value = null;
|
|
68
|
+
const fn = () => value;
|
|
69
|
+
const result = _getPrefix(fn);
|
|
70
|
+
|
|
71
|
+
t.equal(result, '');
|
|
72
|
+
t.end();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test('cloudcmd: replaceDist', (t) => {
|
|
76
|
+
const currentIsDev = _isDev();
|
|
77
|
+
|
|
78
|
+
_isDev(true);
|
|
79
|
+
const url = '/dist/hello';
|
|
80
|
+
const result = _replaceDist(url);
|
|
81
|
+
const expected = '/dist-dev/hello';
|
|
82
|
+
|
|
83
|
+
_isDev(currentIsDev);
|
|
84
|
+
|
|
85
|
+
t.equal(result, expected);
|
|
86
|
+
t.end();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('cloudcmd: replaceDist: !isDev', (t) => {
|
|
90
|
+
const url = '/dist/hello';
|
|
91
|
+
|
|
92
|
+
const currentIsDev = _isDev();
|
|
93
|
+
_isDev(false);
|
|
94
|
+
const result = _replaceDist(url);
|
|
95
|
+
|
|
96
|
+
_isDev(currentIsDev);
|
|
97
|
+
|
|
98
|
+
t.equal(result, url);
|
|
99
|
+
t.end();
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test('cloudcmd: auth: reject', (t) => {
|
|
103
|
+
const accept = stub();
|
|
104
|
+
const reject = stub();
|
|
105
|
+
|
|
106
|
+
const config = createConfigManager();
|
|
107
|
+
|
|
108
|
+
const username = 'root';
|
|
109
|
+
const password = 'toor';
|
|
110
|
+
|
|
111
|
+
config('auth', true);
|
|
112
|
+
config('username', username);
|
|
113
|
+
config('password', password);
|
|
114
|
+
|
|
115
|
+
_initAuth(config, accept, reject, username, 'abc');
|
|
116
|
+
|
|
117
|
+
t.ok(reject.called, 'should reject');
|
|
118
|
+
t.end();
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test('cloudcmd: auth: accept', (t) => {
|
|
122
|
+
const accept = stub();
|
|
123
|
+
const reject = stub();
|
|
124
|
+
|
|
125
|
+
const username = 'root';
|
|
126
|
+
const password = 'toor';
|
|
127
|
+
const auth = true;
|
|
128
|
+
|
|
129
|
+
const config = createConfigManager();
|
|
130
|
+
config('username', username);
|
|
131
|
+
config('password', password);
|
|
132
|
+
config('auth', auth);
|
|
133
|
+
|
|
134
|
+
_initAuth(config, accept, reject, username, password);
|
|
135
|
+
|
|
136
|
+
t.ok(accept.called, 'should accept');
|
|
137
|
+
t.end();
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
test('cloudcmd: auth: accept: no auth', (t) => {
|
|
141
|
+
const accept = stub();
|
|
142
|
+
const reject = stub();
|
|
143
|
+
|
|
144
|
+
const auth = false;
|
|
145
|
+
const username = 'root';
|
|
146
|
+
const password = 'toor';
|
|
147
|
+
|
|
148
|
+
const config = createConfigManager();
|
|
149
|
+
config('username', username);
|
|
150
|
+
config('password', password);
|
|
151
|
+
config('auth', auth);
|
|
152
|
+
|
|
153
|
+
_initAuth(config, accept, reject, username, password);
|
|
154
|
+
|
|
155
|
+
t.ok(accept.called, 'should accept');
|
|
156
|
+
t.end();
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test('cloudcmd: getIndexPath: production', (t) => {
|
|
160
|
+
const isDev = false;
|
|
161
|
+
const name = path.join(__dirname, '..', 'dist', 'index.html');
|
|
162
|
+
|
|
163
|
+
t.equal(_getIndexPath(isDev), name);
|
|
164
|
+
t.end();
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test('cloudcmd: getIndexPath: development', (t) => {
|
|
168
|
+
const isDev = true;
|
|
169
|
+
const name = path.join(__dirname, '..', 'dist-dev', 'index.html');
|
|
170
|
+
|
|
171
|
+
t.equal(_getIndexPath(isDev), name);
|
|
172
|
+
t.end();
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
test('cloudcmd: sw', async (t) => {
|
|
176
|
+
const {status} = await request.get('/sw.js');
|
|
177
|
+
|
|
178
|
+
t.equal(status, 200, 'should return sw');
|
|
179
|
+
t.end();
|
|
180
|
+
});
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import {createRequire} from 'node:module';
|
|
2
|
+
import {test, stub} from 'supertape';
|
|
3
|
+
import {createConfig, _cryptoPass} from './config.js';
|
|
4
|
+
import {apiURL} from '../common/cloudfunc.js';
|
|
5
|
+
import {connect} from '../test/before.mjs';
|
|
6
|
+
|
|
7
|
+
const require = createRequire(import.meta.url);
|
|
8
|
+
const fixture = require('./config.fixture.json');
|
|
9
|
+
|
|
10
|
+
const config = createConfig();
|
|
11
|
+
|
|
12
|
+
test('config: manage', (t) => {
|
|
13
|
+
t.equal(undefined, config(), 'should return "undefined"');
|
|
14
|
+
t.end();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('config: manage: get', async (t) => {
|
|
18
|
+
const editor = 'deepword';
|
|
19
|
+
const configManager = createConfig();
|
|
20
|
+
|
|
21
|
+
const {done} = await connect({
|
|
22
|
+
config: {
|
|
23
|
+
editor,
|
|
24
|
+
},
|
|
25
|
+
configManager,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
done();
|
|
29
|
+
|
|
30
|
+
t.equal(configManager('editor'), editor, 'should get config');
|
|
31
|
+
t.end();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('config: manage: get: config', async (t) => {
|
|
35
|
+
const editor = 'deepword';
|
|
36
|
+
const conf = {
|
|
37
|
+
editor,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const {done} = await connect({
|
|
41
|
+
config: conf,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
config('editor', 'dword');
|
|
45
|
+
done();
|
|
46
|
+
|
|
47
|
+
t.equal('dword', config('editor'), 'should set config');
|
|
48
|
+
t.end();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test('config: manage: get: *', (t) => {
|
|
52
|
+
const data = config('*');
|
|
53
|
+
const keys = Object.keys(data);
|
|
54
|
+
|
|
55
|
+
t.ok(keys.length > 1, 'should return config data');
|
|
56
|
+
t.end();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('config: cryptoPass: no password', (t) => {
|
|
60
|
+
const json = {
|
|
61
|
+
hello: 'world',
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const config = createConfig();
|
|
65
|
+
const result = _cryptoPass(config, json);
|
|
66
|
+
|
|
67
|
+
t.deepEqual(result, [config, json], 'should not change json');
|
|
68
|
+
t.end();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('config: cryptoPass', (t) => {
|
|
72
|
+
const json = {
|
|
73
|
+
password: 'hello',
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const {password} = fixture;
|
|
77
|
+
|
|
78
|
+
const expected = {
|
|
79
|
+
password,
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const config = createConfig();
|
|
83
|
+
const result = _cryptoPass(config, json);
|
|
84
|
+
|
|
85
|
+
t.deepEqual(result, [config, expected], 'should crypt password');
|
|
86
|
+
t.end();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('config: middle: no', (t) => {
|
|
90
|
+
const {middle} = config;
|
|
91
|
+
const next = stub();
|
|
92
|
+
const res = null;
|
|
93
|
+
const url = `${apiURL}/config`;
|
|
94
|
+
const method = 'POST';
|
|
95
|
+
|
|
96
|
+
const req = {
|
|
97
|
+
url,
|
|
98
|
+
method,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
middle(req, res, next);
|
|
102
|
+
|
|
103
|
+
t.calledWithNoArgs(next, 'should call next');
|
|
104
|
+
t.end();
|
|
105
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import Config from '../config.js';
|
|
2
|
+
import {once} from 'node:events';
|
|
3
|
+
import test from 'supertape';
|
|
4
|
+
import io from 'socket.io-client';
|
|
5
|
+
import {connect} from '../../test/before.mjs';
|
|
6
|
+
|
|
7
|
+
const config = Config.createConfig();
|
|
8
|
+
|
|
9
|
+
test('distribute: export', async (t) => {
|
|
10
|
+
const defaultConfig = {
|
|
11
|
+
export: true,
|
|
12
|
+
exportToken: 'a',
|
|
13
|
+
vim: true,
|
|
14
|
+
log: false,
|
|
15
|
+
prefix: '',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const {port, done} = await connect({
|
|
19
|
+
config: defaultConfig,
|
|
20
|
+
configManager: config,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const url = `http://localhost:${port}/distribute?port=1111`;
|
|
24
|
+
const socket = io.connect(url);
|
|
25
|
+
|
|
26
|
+
await once(socket, 'connect');
|
|
27
|
+
socket.emit('auth', 'a');
|
|
28
|
+
|
|
29
|
+
await once(socket, 'accept');
|
|
30
|
+
config('vim', false);
|
|
31
|
+
config('auth', true);
|
|
32
|
+
|
|
33
|
+
await once(socket, 'change');
|
|
34
|
+
|
|
35
|
+
socket.close();
|
|
36
|
+
await done();
|
|
37
|
+
|
|
38
|
+
t.pass('should emit change');
|
|
39
|
+
t.end();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('distribute: export: config', async (t) => {
|
|
43
|
+
const defaultConfig = {
|
|
44
|
+
export: true,
|
|
45
|
+
exportToken: 'a',
|
|
46
|
+
vim: true,
|
|
47
|
+
log: false,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const {port, done} = await connect({
|
|
51
|
+
config: defaultConfig,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const url = `http://localhost:${port}/distribute?port=1111`;
|
|
55
|
+
const socket = io.connect(url);
|
|
56
|
+
|
|
57
|
+
socket.once('connect', () => {
|
|
58
|
+
socket.emit('auth', 'a');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const data = await once(socket, 'config');
|
|
62
|
+
|
|
63
|
+
socket.close();
|
|
64
|
+
await done();
|
|
65
|
+
|
|
66
|
+
t.equal(typeof data, 'object', 'should emit object');
|
|
67
|
+
t.end();
|
|
68
|
+
});
|