mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-07-22 23:50:33 +00:00
Compare commits
No commits in common. "master" and "v19.1.12" have entirely different histories.
219 changed files with 2047 additions and 4292 deletions
|
|
@ -1,31 +1,45 @@
|
||||||
export default {
|
'use strict';
|
||||||
'F2 - Rename File': renameCurrent,
|
|
||||||
'L - Lint': run('npm run lint'),
|
module.exports = {
|
||||||
'F - Fix Lint': run('npm run fix:lint'),
|
'F2 - Rename file': async ({DOM}) => {
|
||||||
'T - Test': run('npm run test'),
|
await DOM.renameCurrent();
|
||||||
'C - Coverage': run('npm run coverage'),
|
},
|
||||||
'D - Build Dev': run('npm run build:client:dev'),
|
'L - Lint': async ({CloudCmd}) => {
|
||||||
'P - Build Prod': run('npm run build:client'),
|
const {TerminalRun} = CloudCmd;
|
||||||
|
await run(TerminalRun, 'npm run lint');
|
||||||
|
},
|
||||||
|
'F - Fix Lint': async ({CloudCmd}) => {
|
||||||
|
const {TerminalRun} = CloudCmd;
|
||||||
|
await run(TerminalRun, 'npm run fix:lint');
|
||||||
|
},
|
||||||
|
'T - Test': async ({CloudCmd}) => {
|
||||||
|
const {TerminalRun} = CloudCmd;
|
||||||
|
|
||||||
|
await run(TerminalRun, 'npm run test');
|
||||||
|
},
|
||||||
|
'C - Coverage': async ({CloudCmd}) => {
|
||||||
|
const {TerminalRun} = CloudCmd;
|
||||||
|
|
||||||
|
await run(TerminalRun, 'npm run coverage');
|
||||||
|
},
|
||||||
|
'D - Build Dev': async ({CloudCmd}) => {
|
||||||
|
const {TerminalRun} = CloudCmd;
|
||||||
|
|
||||||
|
await run(TerminalRun, 'npm run build:client:dev');
|
||||||
|
CloudCmd.refresh();
|
||||||
|
},
|
||||||
|
'P - Build Prod': async ({CloudCmd}) => {
|
||||||
|
const {TerminalRun} = CloudCmd;
|
||||||
|
|
||||||
|
await run(TerminalRun, 'npm run build:client');
|
||||||
|
CloudCmd.refresh();
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
async function renameCurrent(DOM) {
|
async function run(TerminalRun, command) {
|
||||||
await DOM.renameCurrent();
|
await TerminalRun.show({
|
||||||
}
|
command,
|
||||||
|
closeMessage: 'Press any key to close Terminal',
|
||||||
function run(command) {
|
autoClose: false,
|
||||||
return async ({CloudCmd, DOM}) => {
|
});
|
||||||
const {TerminalRun, config} = CloudCmd;
|
|
||||||
|
|
||||||
const {CurrentInfo} = DOM;
|
|
||||||
const {dirPath} = CurrentInfo;
|
|
||||||
|
|
||||||
const cwd = config('root') + dirPath;
|
|
||||||
|
|
||||||
return await TerminalRun.show({
|
|
||||||
cwd,
|
|
||||||
command,
|
|
||||||
closeMessage: 'Press any key to close Terminal',
|
|
||||||
autoClose: false,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
60
.github/workflows/docker-io.yml
vendored
60
.github/workflows/docker-io.yml
vendored
|
|
@ -1,60 +0,0 @@
|
||||||
name: Docker IO
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
on:
|
|
||||||
- push
|
|
||||||
jobs:
|
|
||||||
buildx:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
packages: write
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v5
|
|
||||||
- uses: oven-sh/setup-bun@v2
|
|
||||||
with:
|
|
||||||
bun-version: latest
|
|
||||||
- name: Use Node.js 24.x
|
|
||||||
uses: actions/setup-node@v6
|
|
||||||
with:
|
|
||||||
node-version: 24.x
|
|
||||||
- name: Install Redrun
|
|
||||||
run: bun i redrun -g --no-save
|
|
||||||
- name: NPM Install
|
|
||||||
run: bun i --no-save
|
|
||||||
- name: Lint
|
|
||||||
run: redrun lint
|
|
||||||
- name: Build
|
|
||||||
id: build
|
|
||||||
run: |
|
|
||||||
redrun build
|
|
||||||
VERSION=$(grep '"version":' package.json -m1 | cut -d\" -f4)
|
|
||||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
||||||
- name: Set up QEMU
|
|
||||||
uses: docker/setup-qemu-action@v4
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v4
|
|
||||||
- name: Login to DockerHub
|
|
||||||
uses: docker/login-action@v4
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKER_TOKEN }}
|
|
||||||
- name: Login to GitHub Container Registry
|
|
||||||
uses: docker/login-action@v4
|
|
||||||
with:
|
|
||||||
registry: ghcr.io
|
|
||||||
username: ${{ github.actor }}
|
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
- name: Build and push io-image
|
|
||||||
uses: docker/build-push-action@v7
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
file: docker/Dockerfile.io
|
|
||||||
platforms: linux/amd64,linux/arm64
|
|
||||||
push: true
|
|
||||||
tags: |
|
|
||||||
coderaiser/cloudcmd:io
|
|
||||||
coderaiser/cloudcmd:${{ steps.build.outputs.version }}-io
|
|
||||||
ghcr.io/${{ github.repository }}-io
|
|
||||||
ghcr.io/${{ github.repository }}:${{ steps.build.outputs.version }}-io
|
|
||||||
31
.github/workflows/docker.yml
vendored
31
.github/workflows/docker.yml
vendored
|
|
@ -1,6 +1,4 @@
|
||||||
name: Docker CI
|
name: Docker CI
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
|
|
@ -31,25 +29,24 @@ jobs:
|
||||||
id: build
|
id: build
|
||||||
run: |
|
run: |
|
||||||
redrun build
|
redrun build
|
||||||
VERSION=$(grep '"version":' package.json -m1 | cut -d\" -f4)
|
echo "::set-output name=version::$(grep '"version":' package.json -m1 | cut -d\" -f4)"
|
||||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v4
|
uses: docker/setup-qemu-action@v3
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v4
|
uses: docker/setup-buildx-action@v3
|
||||||
- name: Login to DockerHub
|
- name: Login to DockerHub
|
||||||
uses: docker/login-action@v4
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_TOKEN }}
|
password: ${{ secrets.DOCKER_TOKEN }}
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@v4
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Build and push base-image
|
- name: Build and push base-image
|
||||||
uses: docker/build-push-action@v7
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: docker/Dockerfile
|
file: docker/Dockerfile
|
||||||
|
|
@ -61,28 +58,14 @@ jobs:
|
||||||
ghcr.io/${{ github.repository }}:latest
|
ghcr.io/${{ github.repository }}:latest
|
||||||
ghcr.io/${{ github.repository }}:${{ steps.build.outputs.version }}
|
ghcr.io/${{ github.repository }}:${{ steps.build.outputs.version }}
|
||||||
- name: Build and push alpine-image
|
- name: Build and push alpine-image
|
||||||
uses: docker/build-push-action@v7
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: docker/Dockerfile.alpine
|
file: docker/Dockerfile.alpine
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: |
|
||||||
coderaiser/cloudcmd:alpine
|
|
||||||
coderaiser/cloudcmd:latest-alpine
|
coderaiser/cloudcmd:latest-alpine
|
||||||
coderaiser/cloudcmd:${{ steps.build.outputs.version }}-alpine
|
coderaiser/cloudcmd:${{ steps.build.outputs.version }}-alpine
|
||||||
ghcr.io/${{ github.repository }}:latest-alpine
|
ghcr.io/${{ github.repository }}:latest-alpine
|
||||||
ghcr.io/${{ github.repository }}:${{ steps.build.outputs.version }}-alpine
|
ghcr.io/${{ github.repository }}:${{ steps.build.outputs.version }}-alpine
|
||||||
- name: Build and push slim-image
|
|
||||||
uses: docker/build-push-action@v7
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
file: docker/Dockerfile.slim
|
|
||||||
platforms: linux/amd64,linux/arm64
|
|
||||||
push: true
|
|
||||||
tags: |
|
|
||||||
coderaiser/cloudcmd:slim
|
|
||||||
coderaiser/cloudcmd:latest-slim
|
|
||||||
coderaiser/cloudcmd:${{ steps.build.outputs.version }}-slim
|
|
||||||
ghcr.io/${{ github.repository }}-slim
|
|
||||||
ghcr.io/${{ github.repository }}:${{ steps.build.outputs.version }}-slim
|
|
||||||
|
|
|
||||||
25
.github/workflows/nodejs.yml
vendored
25
.github/workflows/nodejs.yml
vendored
|
|
@ -1,8 +1,6 @@
|
||||||
name: Node CI
|
name: Node CI
|
||||||
on:
|
on:
|
||||||
- push
|
- push
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
@ -13,7 +11,7 @@ jobs:
|
||||||
node-version:
|
node-version:
|
||||||
- 22.x
|
- 22.x
|
||||||
- 24.x
|
- 24.x
|
||||||
- 26.x
|
- 25.x
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
- uses: oven-sh/setup-bun@v2
|
- uses: oven-sh/setup-bun@v2
|
||||||
|
|
@ -24,19 +22,26 @@ jobs:
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
- name: Install Redrun
|
- name: Install Redrun
|
||||||
run: bun i redrun madrun -g --no-save
|
run: bun i redrun -g --no-save
|
||||||
- name: Install
|
- name: Install
|
||||||
run: bun i --no-save
|
run: bun i --no-save
|
||||||
- name: Init Madrun
|
|
||||||
run: madrun --init
|
|
||||||
- name: Lint
|
- name: Lint
|
||||||
run: redrun fix:lint
|
run: redrun fix:lint
|
||||||
- name: Typos
|
- uses: actions/cache@v4
|
||||||
uses: coderaiser/typos.ai@v1.1.8
|
|
||||||
with:
|
with:
|
||||||
key: ${{ secrets.TYPOS_AI_KEY }}
|
path: |
|
||||||
|
~/.cargo/bin/
|
||||||
|
~/.cargo/registry/index/
|
||||||
|
~/.cargo/registry/cache/
|
||||||
|
~/.cargo/git/db/
|
||||||
|
target/
|
||||||
|
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
- name: Typos Install
|
||||||
|
run: cargo install typos-cli || echo 'already installed'
|
||||||
|
- name: Typos
|
||||||
|
run: typos --write-changes
|
||||||
- name: Commit fixes
|
- name: Commit fixes
|
||||||
uses: EndBug/add-and-commit@v10
|
uses: EndBug/add-and-commit@v9
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
with:
|
with:
|
||||||
message: "chore: ${{ env.NAME }}: actions: lint ☘️"
|
message: "chore: ${{ env.NAME }}: actions: lint ☘️"
|
||||||
|
|
|
||||||
22
.gitignore
vendored
22
.gitignore
vendored
|
|
@ -1,17 +1,19 @@
|
||||||
*.swp
|
|
||||||
*.log
|
|
||||||
*.lock
|
|
||||||
|
|
||||||
.nyc_output
|
|
||||||
.DS_Store
|
|
||||||
.idea
|
|
||||||
|
|
||||||
package-lock.json
|
package-lock.json
|
||||||
npm-debug.log*
|
yarn.lock
|
||||||
|
yarn-error.log
|
||||||
node_modules
|
node_modules
|
||||||
|
npm-debug.log*
|
||||||
coverage
|
coverage
|
||||||
|
|
||||||
modules/execon
|
modules/execon
|
||||||
modules/emitify
|
modules/emitify
|
||||||
|
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
dist
|
dist
|
||||||
dist-dev
|
dist-dev
|
||||||
|
|
||||||
|
.idea
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,47 @@
|
||||||
|
import process from 'node:process';
|
||||||
import {run, cutEnv} from 'madrun';
|
import {run, cutEnv} from 'madrun';
|
||||||
import {defineEnv} from 'supertape/env';
|
|
||||||
|
|
||||||
const testEnv = defineEnv({
|
const testEnv = {
|
||||||
timeout: 7000,
|
SUPERTAPE_TIMEOUT: 7000,
|
||||||
css: true,
|
};
|
||||||
});
|
|
||||||
|
|
||||||
const buildEnv = {
|
const is17 = /^v1[789]/.test(process.version);
|
||||||
|
const is20 = process.version.startsWith('v2');
|
||||||
|
|
||||||
|
// fix for ERR_OSSL_EVP_UNSUPPORTED on node v17
|
||||||
|
// flag '--openssl-legacy-provider' not supported
|
||||||
|
// on earlier version of node.js
|
||||||
|
//
|
||||||
|
// https://stackoverflow.com/a/69746937/4536327
|
||||||
|
const buildEnv = (is17 || is20) && {
|
||||||
|
NODE_OPTIONS: '--openssl-legacy-provider',
|
||||||
NODE_ENV: 'production',
|
NODE_ENV: 'production',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
'start': () => 'node bin/cloudcmd.js',
|
'start': () => 'node bin/cloudcmd.mjs',
|
||||||
'start:dev': async () => await run('start', null, {
|
'start:dev': async () => await run('start', null, {
|
||||||
NODE_ENV: 'development',
|
NODE_ENV: 'development',
|
||||||
}),
|
}),
|
||||||
'build:start': () => run(['build:client', 'start']),
|
'build:start': () => run(['build:client', 'start']),
|
||||||
'build:start:dev': () => run([
|
'build:start:dev': () => run(['build:client:dev', 'start:dev']),
|
||||||
'build:client:dev',
|
|
||||||
'start:dev',
|
|
||||||
]),
|
|
||||||
'lint:all': () => run('lint:progress'),
|
'lint:all': () => run('lint:progress'),
|
||||||
'lint': () => 'redlint fix; putout .',
|
'lint': () => 'putout .',
|
||||||
'lint:progress': () => run('lint', '-f progress'),
|
'lint:progress': () => run('lint', '-f progress'),
|
||||||
'watch:lint': () => 'nodemon -w client -w server -w test -w common -w .webpack -x "putout -s"',
|
'watch:lint': () => 'nodemon -w client -w server -w test -w common -w .webpack -x "putout -s"',
|
||||||
'fresh:lint': () => run('lint', '--fresh'),
|
'fresh:lint': () => run('lint', '--fresh'),
|
||||||
'lint:fresh': () => run('lint', '--fresh'),
|
'lint:fresh': () => run('lint', '--fresh'),
|
||||||
'fix:lint': async () => `putout --fix . && redlint fix`,
|
'fix:lint': () => run('lint', '--fix'),
|
||||||
'lint:stream': () => run('lint', '-f stream'),
|
'lint:stream': () => run('lint', '-f stream'),
|
||||||
'test': () => [testEnv, `tape '{test}/**/*.js' '{bin,client,static,common,server}/**/*.spec.js' -f fail`],
|
'test': () => [testEnv, `tape 'test/**/*.{js,mjs}' '{client,static,common,server}/**/*.spec.{js,mjs}' -f fail`],
|
||||||
'test:e2e': () => `tape 'test-e2e/**/*.js'`,
|
|
||||||
'test:client': () => `tape 'test/client/**/*.js'`,
|
'test:client': () => `tape 'test/client/**/*.js'`,
|
||||||
'test:server': () => `tape 'test/**/*.js' 'server/**/*.spec.js' 'common/**/*.spec.js'`,
|
'test:server': () => `tape 'test/**/*.js' 'server/**/*.spec.js' 'common/**/*.spec.js'`,
|
||||||
'wisdom': async () => await run(['lint:all', 'build', 'test'], null, {
|
'wisdom': () => run(['lint:all', 'build', 'test']),
|
||||||
CI: 1,
|
'wisdom:type': () => 'bin/release.mjs',
|
||||||
}),
|
|
||||||
'wisdom:type': () => 'bin/release.js',
|
|
||||||
'coverage': async () => [testEnv, `c8 ${await cutEnv('test')}`],
|
'coverage': async () => [testEnv, `c8 ${await cutEnv('test')}`],
|
||||||
'coverage:report': () => 'c8 report --reporter=lcov',
|
'coverage:report': () => 'c8 report --reporter=lcov',
|
||||||
'report': () => 'c8 report --reporter=lcov',
|
'report': () => 'c8 report --reporter=lcov',
|
||||||
'6to5': () => [buildEnv, 'rspack build --config rspack.config.js'],
|
'6to5': () => [buildEnv, 'webpack --progress'],
|
||||||
'6to5:client': () => run('6to5', '--mode production'),
|
'6to5:client': () => run('6to5', '--mode production'),
|
||||||
'6to5:client:dev': async () => await run('6to5', '--mode development', {
|
'6to5:client:dev': async () => await run('6to5', '--mode development', {
|
||||||
NODE_ENV: 'development',
|
NODE_ENV: 'development',
|
||||||
|
|
@ -53,7 +55,6 @@ export default {
|
||||||
'watch:test:client': async () => `nodemon -w client -w test/client -x ${await run('test:client')}`,
|
'watch:test:client': async () => `nodemon -w client -w test/client -x ${await run('test:client')}`,
|
||||||
'watch:test:server': async () => `nodemon -w client -w test/client -x ${await run('test:server')}`,
|
'watch:test:server': async () => `nodemon -w client -w test/client -x ${await run('test:server')}`,
|
||||||
'watch:coverage': async () => [testEnv, `nodemon -w server -w test -w common -x ${await cutEnv('coverage')}`],
|
'watch:coverage': async () => [testEnv, `nodemon -w server -w test -w common -x ${await cutEnv('coverage')}`],
|
||||||
'watch:fix:lint': async () => `nodemon -w client -w server -w test -w common -x '${await run('fix:lint')}'`,
|
|
||||||
'build': async () => run('6to5:*'),
|
'build': async () => run('6to5:*'),
|
||||||
'build:dev': async () => run('build:client:dev'),
|
'build:dev': async () => run('build:client:dev'),
|
||||||
'build:client': () => run('6to5:client'),
|
'build:client': () => run('6to5:client'),
|
||||||
41
.npmignore
41
.npmignore
|
|
@ -1,29 +1,34 @@
|
||||||
|
.*
|
||||||
*.spec.*
|
*.spec.*
|
||||||
*.config.*
|
*.config.*
|
||||||
*.fixture.js*
|
*.fixture.js*
|
||||||
*.ai
|
|
||||||
*.cdr
|
|
||||||
*.eps
|
|
||||||
*.log
|
|
||||||
*.lock
|
|
||||||
|
|
||||||
.*
|
|
||||||
|
|
||||||
manifest.yml
|
manifest.yml
|
||||||
docker-compose.yml
|
|
||||||
now.json
|
|
||||||
app.json
|
|
||||||
bower.json
|
|
||||||
deno.json
|
|
||||||
bin/release.*
|
|
||||||
img/logo/cloudcmd-hq.png
|
|
||||||
webpack.config.js
|
|
||||||
|
|
||||||
docker
|
docker
|
||||||
test*
|
docker-compose.yml
|
||||||
|
test
|
||||||
fixture
|
fixture
|
||||||
fixture-*
|
fixture-*
|
||||||
coverage
|
coverage
|
||||||
css
|
css
|
||||||
html
|
html
|
||||||
|
yarn-error.log
|
||||||
|
yarn.lock
|
||||||
|
now.json
|
||||||
|
|
||||||
|
app.json
|
||||||
|
bower.json
|
||||||
|
manifest.yml
|
||||||
|
deno.json
|
||||||
|
|
||||||
|
bin/release.mjs
|
||||||
|
|
||||||
client
|
client
|
||||||
|
img/logo/cloudcmd-hq.png
|
||||||
|
|
||||||
|
webpack.config.js
|
||||||
|
|
||||||
|
*.ai
|
||||||
|
*.cdr
|
||||||
|
*.eps
|
||||||
|
|
||||||
|
*.config.*
|
||||||
|
|
|
||||||
1
.nvmrc
Normal file
1
.nvmrc
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
v20.15.1
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
{
|
{
|
||||||
"checkCoverage": false,
|
"check-coverage": false,
|
||||||
"all": false,
|
"all": false,
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"**/*.spec.js",
|
"**/*.spec.js",
|
||||||
|
"**/fixture",
|
||||||
"**/*.*.js",
|
"**/*.*.js",
|
||||||
"**/*.config.*",
|
"**/*.config.*",
|
||||||
"**/fixture",
|
|
||||||
"**/test/**"
|
"**/test/**"
|
||||||
],
|
],
|
||||||
"branches": 100,
|
"branches": 100,
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
{
|
{
|
||||||
"plugins": ["cloudcmd"],
|
"plugins": ["cloudcmd"],
|
||||||
"ignore": [
|
"ignore": [
|
||||||
"*.md",
|
"html",
|
||||||
|
"fixture*",
|
||||||
"app.json",
|
"app.json",
|
||||||
"fontello.json",
|
"fontello.json",
|
||||||
"html",
|
"*.md"
|
||||||
"fixture*"
|
|
||||||
],
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"package-json/add-type": "off"
|
"package-json/add-type": "off"
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
[files]
|
[files]
|
||||||
extend-exclude = ["ChangeLog"]
|
extend-exclude= ["ChangeLog", "*.js"]
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,21 @@
|
||||||
import {env} from 'node:process';
|
import {env} from 'node:process';
|
||||||
import {rspack} from '@rspack/core';
|
import OptimizeCssAssetsPlugin from 'optimize-css-assets-webpack-plugin';
|
||||||
|
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
||||||
|
|
||||||
const {CssExtractRspackPlugin} = rspack;
|
|
||||||
const isDev = env.NODE_ENV === 'development';
|
const isDev = env.NODE_ENV === 'development';
|
||||||
|
|
||||||
const plugins = [
|
const clean = (a) => a.filter(Boolean);
|
||||||
new CssExtractRspackPlugin({
|
|
||||||
|
const plugins = clean([
|
||||||
|
new MiniCssExtractPlugin({
|
||||||
filename: '[name].css',
|
filename: '[name].css',
|
||||||
}),
|
}),
|
||||||
];
|
!isDev && new OptimizeCssAssetsPlugin(),
|
||||||
|
]);
|
||||||
|
|
||||||
const rules = [{
|
const rules = [{
|
||||||
test: /\.css$/i,
|
test: /\.css$/i,
|
||||||
use: [CssExtractRspackPlugin.loader, {
|
use: [MiniCssExtractPlugin.loader, {
|
||||||
loader: 'css-loader',
|
loader: 'css-loader',
|
||||||
options: {
|
options: {
|
||||||
url: true,
|
url: true,
|
||||||
|
|
@ -24,15 +27,8 @@ const rules = [{
|
||||||
}];
|
}];
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mode: isDev ? 'development' : 'production',
|
|
||||||
plugins,
|
plugins,
|
||||||
module: {
|
module: {
|
||||||
rules,
|
rules,
|
||||||
},
|
},
|
||||||
optimization: {
|
|
||||||
minimize: !isDev,
|
|
||||||
minimizer: [
|
|
||||||
new rspack.LightningCssMinimizerRspackPlugin(),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
@ -1,15 +1,12 @@
|
||||||
import {resolve, sep} from 'node:path';
|
import {resolve, sep} from 'node:path';
|
||||||
import {fileURLToPath} from 'node:url';
|
|
||||||
import {env} from 'node:process';
|
import {env} from 'node:process';
|
||||||
import {rspack} from '@rspack/core';
|
import webpack from 'webpack';
|
||||||
|
import WebpackBar from 'webpackbar';
|
||||||
const resolveModule = (a) => fileURLToPath(import.meta.resolve(a));
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
EnvironmentPlugin,
|
EnvironmentPlugin,
|
||||||
NormalModuleReplacementPlugin,
|
NormalModuleReplacementPlugin,
|
||||||
ProvidePlugin,
|
} = webpack;
|
||||||
} = rspack;
|
|
||||||
|
|
||||||
const modules = './modules';
|
const modules = './modules';
|
||||||
const dirModules = './client/modules';
|
const dirModules = './client/modules';
|
||||||
|
|
@ -25,31 +22,27 @@ const dist = resolve(rootDir, 'dist');
|
||||||
const distDev = resolve(rootDir, 'dist-dev');
|
const distDev = resolve(rootDir, 'dist-dev');
|
||||||
const devtool = isDev ? 'eval' : 'source-map';
|
const devtool = isDev ? 'eval' : 'source-map';
|
||||||
|
|
||||||
const noParse = (a) => a.endsWith('.spec.js');
|
const notEmpty = (a) => a;
|
||||||
|
const clean = (array) => array.filter(notEmpty);
|
||||||
|
|
||||||
// codegen.macro is a babel-macro (build-time codegen), not supported by
|
const noParse = (a) => a.endsWith('.spec.js');
|
||||||
// Rspack's native SWC transform, so client/sw/sw.js (the only file that
|
const options = {
|
||||||
// uses it) keeps going through babel-loader. Everything else uses
|
babelrc: true,
|
||||||
// Rspack's built-in SWC loader, which is the main source of the speedup.
|
};
|
||||||
const rules = [{
|
|
||||||
test: /sw\/sw\.js$/,
|
const rules = clean([
|
||||||
exclude: /node_modules/,
|
!isDev && {
|
||||||
loader: 'babel-loader',
|
test: /\.[mc]?js$/,
|
||||||
}, {
|
exclude: /node_modules/,
|
||||||
test: /\.[mc]?js$/,
|
loader: 'babel-loader',
|
||||||
exclude: [/node_modules/, /sw\/sw\.js$/],
|
|
||||||
loader: 'builtin:swc-loader',
|
|
||||||
options: {
|
|
||||||
jsc: {
|
|
||||||
parser: {
|
|
||||||
syntax: 'ecmascript',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
env: {
|
|
||||||
targets: 'defaults',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}];
|
isDev && {
|
||||||
|
test: /\.[mc]?js$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
loader: 'babel-loader',
|
||||||
|
options,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
const plugins = [
|
const plugins = [
|
||||||
new NormalModuleReplacementPlugin(/^node:/, (resource) => {
|
new NormalModuleReplacementPlugin(/^node:/, (resource) => {
|
||||||
|
|
@ -59,9 +52,7 @@ const plugins = [
|
||||||
new EnvironmentPlugin({
|
new EnvironmentPlugin({
|
||||||
NODE_ENV,
|
NODE_ENV,
|
||||||
}),
|
}),
|
||||||
new ProvidePlugin({
|
new WebpackBar(),
|
||||||
process: 'process/browser',
|
|
||||||
}),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const splitChunks = {
|
const splitChunks = {
|
||||||
|
|
@ -83,8 +74,6 @@ const splitChunks = {
|
||||||
'themes/light',
|
'themes/light',
|
||||||
'columns/name-size',
|
'columns/name-size',
|
||||||
'columns/name-size-date',
|
'columns/name-size-date',
|
||||||
'columns/name-size-time',
|
|
||||||
'columns/name-size-date-time',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
return !lazyChunks.includes(chunk.name);
|
return !lazyChunks.includes(chunk.name);
|
||||||
|
|
@ -105,9 +94,8 @@ export default {
|
||||||
'node:path': 'path',
|
'node:path': 'path',
|
||||||
},
|
},
|
||||||
fallback: {
|
fallback: {
|
||||||
path: resolveModule('path-browserify'),
|
path: import.meta.resolve('path-browserify'),
|
||||||
process: resolveModule('process/browser'),
|
process: import.meta.resolve('process/browser'),
|
||||||
util: resolveModule('util'),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
devtool,
|
devtool,
|
||||||
|
|
@ -119,15 +107,14 @@ export default {
|
||||||
'themes/light': `${dirThemes}/light.css`,
|
'themes/light': `${dirThemes}/light.css`,
|
||||||
'columns/name-size': `${dirColumns}/name-size.css`,
|
'columns/name-size': `${dirColumns}/name-size.css`,
|
||||||
'columns/name-size-date': `${dirColumns}/name-size-date.css`,
|
'columns/name-size-date': `${dirColumns}/name-size-date.css`,
|
||||||
'columns/name-size-date-time': `${dirColumns}/name-size-date-time.css`,
|
|
||||||
'nojs': `${dirCss}/nojs.css`,
|
'nojs': `${dirCss}/nojs.css`,
|
||||||
'help': `${dirCss}/help.css`,
|
'help': `${dirCss}/help.css`,
|
||||||
'view': `${dirCss}/view.css`,
|
'view': `${dirCss}/view.css`,
|
||||||
'config': `${dirCss}/config.css`,
|
'config': `${dirCss}/config.css`,
|
||||||
'terminal': `${dirCss}/terminal.css`,
|
'terminal': `${dirCss}/terminal.css`,
|
||||||
'user-menu': `${dirCss}/user-menu.css`,
|
'user-menu': `${dirCss}/user-menu.css`,
|
||||||
'sw': `${dir}/sw/sw.js`,
|
'sw': `${dir}/sw/sw.mjs`,
|
||||||
'cloudcmd': `${dir}/cloudcmd.js`,
|
'cloudcmd': `${dir}/cloudcmd.mjs`,
|
||||||
[`${modules}/edit`]: `${dirModules}/edit.js`,
|
[`${modules}/edit`]: `${dirModules}/edit.js`,
|
||||||
[`${modules}/edit-file`]: `${dirModules}/edit-file.js`,
|
[`${modules}/edit-file`]: `${dirModules}/edit-file.js`,
|
||||||
[`${modules}/edit-file-vim`]: `${dirModules}/edit-file-vim.js`,
|
[`${modules}/edit-file-vim`]: `${dirModules}/edit-file-vim.js`,
|
||||||
|
|
@ -137,10 +124,10 @@ export default {
|
||||||
[`${modules}/view`]: `${dirModules}/view/index.js`,
|
[`${modules}/view`]: `${dirModules}/view/index.js`,
|
||||||
[`${modules}/help`]: `${dirModules}/help.js`,
|
[`${modules}/help`]: `${dirModules}/help.js`,
|
||||||
[`${modules}/markdown`]: `${dirModules}/markdown.js`,
|
[`${modules}/markdown`]: `${dirModules}/markdown.js`,
|
||||||
[`${modules}/config`]: `${dirModules}/config/index.js`,
|
[`${modules}/config`]: `${dirModules}/config/index.mjs`,
|
||||||
[`${modules}/contact`]: `${dirModules}/contact.js`,
|
[`${modules}/contact`]: `${dirModules}/contact.js`,
|
||||||
[`${modules}/upload`]: `${dirModules}/upload.js`,
|
[`${modules}/upload`]: `${dirModules}/upload.js`,
|
||||||
[`${modules}/operation`]: `${dirModules}/operation/index.js`,
|
[`${modules}/operation`]: `${dirModules}/operation/index.mjs`,
|
||||||
[`${modules}/konsole`]: `${dirModules}/konsole.js`,
|
[`${modules}/konsole`]: `${dirModules}/konsole.js`,
|
||||||
[`${modules}/terminal`]: `${dirModules}/terminal.js`,
|
[`${modules}/terminal`]: `${dirModules}/terminal.js`,
|
||||||
[`${modules}/terminal-run`]: `${dirModules}/terminal-run.js`,
|
[`${modules}/terminal-run`]: `${dirModules}/terminal-run.js`,
|
||||||
|
|
@ -162,7 +149,7 @@ export default {
|
||||||
},
|
},
|
||||||
plugins,
|
plugins,
|
||||||
performance: {
|
performance: {
|
||||||
maxEntrypointSize: 800_000,
|
maxEntrypointSize: 600_000,
|
||||||
maxAssetSize: 600_000,
|
maxAssetSize: 600_000,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
689
ChangeLog
689
ChangeLog
|
|
@ -1,686 +1,3 @@
|
||||||
2026.06.15, v19.19.1
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 78b206e0 client: key: Ctrl + L -> Ctrl + Shift + L: Log out (#466)
|
|
||||||
- b1492885 docker: io: NPM_CONFIG_PACKAGE_LOCK=false
|
|
||||||
- 76d7bf4d docker: typos, shellcheck: add
|
|
||||||
|
|
||||||
2026.05.26, v19.19.0
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 4ee38db6 client: view: flac: add support
|
|
||||||
|
|
||||||
2026.05.26, v19.18.1
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 40ecef5e cloudcmd: ratelimit: X-Forwarded-For (#437)
|
|
||||||
|
|
||||||
2026.05.26, v19.18.0
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- 161bede8 client: menu: @putout/bundle@5.5.
|
|
||||||
- 447d990f cloudcmd: server: rest: sendError
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 5d9628ce cloudcmd: rate limit: add support (#437)
|
|
||||||
- 2be395e6 cloudcmd: get rid of manifest: 401 basic auth
|
|
||||||
|
|
||||||
2026.05.17, v19.17.0
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- d96f6c46 css: query: hide time on mobile
|
|
||||||
- e7c55e05 docker: io: XDG_CONFIG_HOME
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- ae1ca0f8 cloudcmd: cssnano-preset-default v8.0.1
|
|
||||||
- 94d5096a style: owner, mode: improve
|
|
||||||
- 807f8346 cloudcmd: superc8 v12.6.0
|
|
||||||
- 67a95722 docker: io: cline: add
|
|
||||||
- 68eacb91 qword: add
|
|
||||||
- 4acd294b docker: io: tmux
|
|
||||||
- 05c80043 cloudcmd: @supertape/loader-css v1.0.0
|
|
||||||
- 800a6545 cloudcmd: eslint-plugin-n v18.0.1
|
|
||||||
- a985bb36 cloudcmd: supertape v13.0.0
|
|
||||||
- 4315ec61 docker: io XDG_CONFIG_HOME: /etc -> /usr/local/etc
|
|
||||||
|
|
||||||
2026.05.03, v19.16.0
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- d82d0335 client: vim: rr for rename file
|
|
||||||
- acfa27cf docker: io: nvchad: add
|
|
||||||
- 14f009f8 docker: io: bash-completion: add
|
|
||||||
- c6c60146 docker: io: f4
|
|
||||||
- 9a6b8935 docker: io: GOPATH
|
|
||||||
- a9bc22ce cloudcmd: operation: rm useless checks
|
|
||||||
- 36bacfe9 cloudcmd: client: key: vim: cc, mm
|
|
||||||
- 591da25c cloudcmd: ponse v8.0.0
|
|
||||||
- 1e1b073c docker: io: /usr/src/cloudcmd -> /usr/local/share/cloudcmd
|
|
||||||
|
|
||||||
2026.04.28, v19.15.0
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 9d97343b cloudcmd: operation: rm useless checks
|
|
||||||
- 46a88cfa cloudcmd: client: key: vim: cc, mm
|
|
||||||
|
|
||||||
2026.04.28, v19.14.0
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 36a8b641 cloudcmd: ponse v8.0.0
|
|
||||||
- 1c263c18 docker: io: /usr/src/cloudcmd -> /usr/local/share/cloudcmd
|
|
||||||
- ea7b828c docker: io: ubuntu: resolute
|
|
||||||
- cd6c11ac docker: io: far2l
|
|
||||||
- c4beeec6 docker: io: gdu: add
|
|
||||||
|
|
||||||
2026.04.21, v19.13.1
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- d5cd11e8 cloudcmd: montag v2.0.1
|
|
||||||
- dc94d2db docker: io: add latest git version
|
|
||||||
- 1637beee docker: io: /usr/local/src -> /usr/local/share
|
|
||||||
- b1bc4e73 Docker: io: pv
|
|
||||||
- 7c0dca60 docker: io: git: master
|
|
||||||
|
|
||||||
2026.04.15, v19.13.0
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- 48693d9e docker: io: XDG_CACHE_HOME
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 4b2395c5 cloudcmd: Ctrl + L: logout
|
|
||||||
- 977a8aaa docker: io: strace: add
|
|
||||||
- 7d0098fd docker: io: XDG_CACHE_HOME=/tmp/cache
|
|
||||||
- a89e901b actions: docker: io: add
|
|
||||||
|
|
||||||
2026.04.12, v19.12.5
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 1cfc1a6f docker: io: only amd64
|
|
||||||
|
|
||||||
2026.04.12, v19.12.4
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 3c2b5658 docker: io: haskell
|
|
||||||
- d37f8cd3 docker: io: palabra: node
|
|
||||||
|
|
||||||
2026.04.12, v19.12.3
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- cb6cabd4 docker: io: PALABRA_DIR
|
|
||||||
|
|
||||||
2026.04.11, v19.12.2
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 2ce11fa2 docker: io: get rid of haskell: to slow install
|
|
||||||
- aa741232 docker: io: rizin, yara
|
|
||||||
|
|
||||||
2026.04.09, v19.12.1
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 5bd03215 docker: io: add PREFIX
|
|
||||||
|
|
||||||
2026.04.09, v19.12.0
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 13b15b7b docker: io: palabra
|
|
||||||
|
|
||||||
2026.04.07, v19.11.14
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- a31beab0 docker: io: rustup env
|
|
||||||
|
|
||||||
2026.04.07, v19.11.13
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 6a08479a docker: io: BUN_INSTALL
|
|
||||||
|
|
||||||
2026.04.06, v19.11.12
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 46c65554 docker: io: npm_config_cache
|
|
||||||
|
|
||||||
2026.04.06, v19.11.11
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- ae2ce388 docker: io: $DENO_DIR
|
|
||||||
|
|
||||||
2026.04.06, v19.11.10
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 12ea14ac docker: io: nvm: node
|
|
||||||
|
|
||||||
2026.04.06, v19.11.9
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- ea96d13f docker: io: net-tools
|
|
||||||
|
|
||||||
2026.04.06, v19.11.8
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 5c08565f docker: io: debian -> ubuntu
|
|
||||||
|
|
||||||
2026.04.05, v19.11.7
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 36cdef37 docker: io: bookworm
|
|
||||||
|
|
||||||
2026.04.05, v19.11.6
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 845f9bd1 cloudcmd: gritty v10.2.0
|
|
||||||
|
|
||||||
2026.04.05, v19.11.5
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- f9c513cc docker: io: hexyl: add
|
|
||||||
|
|
||||||
2026.04.04, v19.11.4
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- e7347d25 docker: io: neovim: apt -> github
|
|
||||||
|
|
||||||
2026.04.04, v19.11.3
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 9970ff76 docker: io: btop
|
|
||||||
- 4395a471 docker: io: $PATH: add $HOME/.local/bin
|
|
||||||
|
|
||||||
2026.04.04, v19.11.2
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- c40ae8e4 docker: io: htop
|
|
||||||
- f463c5c5 docker: io: aptitude: add
|
|
||||||
- d1032f09 docker: io: remove unused
|
|
||||||
|
|
||||||
2026.04.04, v19.11.1
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 7787bfc2 cloudcmd: user-menu: runFromCDN
|
|
||||||
|
|
||||||
2026.04.04, v19.11.0
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 32f89d38 cloudcmd: user-menu: root
|
|
||||||
|
|
||||||
2026.04.04, v19.10.2
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- df4fb517 cloudcmd: aleman v2.0.1
|
|
||||||
|
|
||||||
2026.04.03, v19.10.1
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- ceb7ef4f docker: io: keep /var/lib/apt/lists
|
|
||||||
|
|
||||||
2026.04.02, v19.10.0
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- d12e7bd0 distribute: fix event listener leak on socket disconnect (#462)
|
|
||||||
|
|
||||||
2026.04.02, v19.9.24
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- c4d26c6a docker: io: apt-get upgrade
|
|
||||||
- 9ddb8c29 docker: io: get rid of nix
|
|
||||||
- e4d7d441 docker: io: nix
|
|
||||||
|
|
||||||
2026.04.01, v19.9.23
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 5a3413ce docker: io: nix
|
|
||||||
|
|
||||||
2026.03.31, v19.9.22
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- b4345ed4 docker: io: DENO_DIR
|
|
||||||
|
|
||||||
2026.03.31, v19.9.21
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- 5c6a9a95 css: columns: name: 40% -> 35%
|
|
||||||
|
|
||||||
2026.03.30, v19.9.20
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- cd0b5554 iocmd: io: nvm
|
|
||||||
|
|
||||||
2026.03.30, v19.9.19
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 6a52b11e docker: io: go, rust
|
|
||||||
|
|
||||||
2026.03.30, v19.9.18
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 738059f2 docker: io: fzf
|
|
||||||
- 3fc8932f docker: io: less, el_GR
|
|
||||||
|
|
||||||
2026.03.30, v19.9.17
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- cf424d6c docker: io: command-not-found update
|
|
||||||
|
|
||||||
2026.03.29, v19.9.16
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 19347a2b docker: io: add command-not-found
|
|
||||||
|
|
||||||
2026.03.29, v19.9.15
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- ee170552 docker: io: ubuntu
|
|
||||||
- e04c4594 docker: io: net-tools: add
|
|
||||||
|
|
||||||
2026.03.29, v19.9.14
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- 6c7709be docker: io: PS1
|
|
||||||
|
|
||||||
2026.03.29, v19.9.13
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- 439b3710 bin: currify
|
|
||||||
- e4182841 docker: io: xterm-256color
|
|
||||||
|
|
||||||
2026.03.29, v19.9.12
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 811a47fd cloudcmd: bin: get rid of require
|
|
||||||
|
|
||||||
2026.03.29, v19.9.11
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 1f95f188 cloudcmd: get rid of simport
|
|
||||||
|
|
||||||
2026.03.29, v19.9.10
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- f0deb323 docker: io: add ja_JP.UTF-8
|
|
||||||
|
|
||||||
2026.03.29, v19.9.9
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- f671f798 docker: io: PS1 environment variable in Dockerfile
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- cc7f9dc7 docker: io: use ubuntu
|
|
||||||
|
|
||||||
2026.03.28, v19.9.8
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 4d1cd8cd docker: io: ffmpeg
|
|
||||||
- 54b56fdc cloudcmd: vim: ESC: use only to enable, do not use to disable
|
|
||||||
|
|
||||||
2026.03.27, v19.9.7
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 110908e2 docker: io: apt-get
|
|
||||||
|
|
||||||
2026.03.26, v19.9.6
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 6450a2f8 docker: io: add UTF-8
|
|
||||||
|
|
||||||
2026.03.26, v19.9.5
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- e761cacb columns: name-size-date-time: 20% -> 19%
|
|
||||||
|
|
||||||
2026.03.26, v19.9.4
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 69498ed6 docker: io: pull.rebase by default
|
|
||||||
|
|
||||||
2026.03.24, v19.9.3
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 8763788b docker: io: healthcheck
|
|
||||||
|
|
||||||
2026.03.23, v19.9.2
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 09a02074 docker: io: git config: add
|
|
||||||
- c448eaa4 docker: io: buni
|
|
||||||
|
|
||||||
2026.03.23, v19.9.1
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- 6e5318fa client: modules: config: input: quote
|
|
||||||
|
|
||||||
2026.03.23, v19.9.0
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- a1216cdd cloudcmd: add ability to hide port configuration
|
|
||||||
|
|
||||||
2026.03.23, v19.8.15
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 68b2aa78 docker: io: cloudcmd_vim
|
|
||||||
|
|
||||||
2026.03.23, v19.8.14
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- 665ed9c2 docker: io: get back port
|
|
||||||
|
|
||||||
2026.03.23, v19.8.13
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 618a5615 docker: io: PS1
|
|
||||||
|
|
||||||
2026.03.23, v19.8.12
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 556b0150 docker: io: PS1
|
|
||||||
|
|
||||||
2026.03.23, v19.8.11
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- 97672ef5 docker: io: apt-get install -> apt-get
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 67f27d84 docker: io: bun, deno
|
|
||||||
|
|
||||||
2026.03.23, v19.8.10
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 025b005e docker: io: add PS1
|
|
||||||
|
|
||||||
2026.03.23, v19.8.9
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- b052cf22 cloudcmd: no time available: --.--.---- -> --:--:-- (#461)
|
|
||||||
|
|
||||||
2026.03.23, v19.8.8
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 02dbe56d server: user-menu: when error send it
|
|
||||||
|
|
||||||
2026.03.23, v19.8.7
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- ecc76e8b docker: io: renamify-cli, runny, redfork
|
|
||||||
|
|
||||||
2026.03.23, v19.8.6
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- 53c072ab @putout/plugin-cloudcmd: devDependencies -> dependnecies
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 4b9922bf docker: /usr/src: app -> cloudcmd
|
|
||||||
|
|
||||||
2026.03.23, v19.8.5
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- 56fc8b83 docker: gritty
|
|
||||||
|
|
||||||
2026.03.22, v19.8.4
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 5000227e docker: vim nvim
|
|
||||||
|
|
||||||
2026.03.22, v19.8.3
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- 01677e6a docker: io: slim -> io
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 7e35c606 docker: io: curl wget
|
|
||||||
|
|
||||||
2026.03.22, v19.8.2
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- e5b221f7 docker: io: add
|
|
||||||
|
|
||||||
2026.03.22, v19.8.1
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 708a4c6b docker: slim: add
|
|
||||||
- 80613f46 docker: slim: add
|
|
||||||
|
|
||||||
2026.03.20, v19.8.0
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- 59037f2c cloudcmd: bin: --show-config
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 10934b3a cloudcmd: add ability to show modification time (#230)
|
|
||||||
|
|
||||||
2026.03.18, v19.7.1
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- b0c1d36c cloudcmd: @cloudcmd/fileop v9.0.7 (#460)
|
|
||||||
|
|
||||||
2026.03.17, v19.7.0
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- daf83875 cloudfunc: override date format (#459)
|
|
||||||
|
|
||||||
2026.03.17, v19.6.9
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- b28a070a cloudcmd: redzip v4.6.1
|
|
||||||
- 43c5a011 cloudcmd: css-minimizer-webpack-plugin v8.0.0
|
|
||||||
- 15dcae5c cloudcmd: webpack-cli v7.0.2
|
|
||||||
- 5976da81 cloudcmd: @cloudcmd/fileop v9.0.5
|
|
||||||
- 37cb83f2 cloudcmd: redzip v4.6.0
|
|
||||||
|
|
||||||
2026.02.27, v19.6.8
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 15fab514 cloudcmd: copymitter v10.3.0 (#458)
|
|
||||||
|
|
||||||
2026.02.26, v19.6.7
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 68c7d0be cloudcmd: onezip v7.0.0
|
|
||||||
|
|
||||||
2026.02.26, v19.6.6
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 3987cc82 cloudcmd: redzip v4.5.1 (#457)
|
|
||||||
|
|
||||||
2026.02.26, v19.6.5
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 964ae989 cloudcmd: redzip v4.5.0 (#457)
|
|
||||||
|
|
||||||
2026.02.25, v19.6.4
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- a66eeda3 cloudcmd: copymitter v10.2.0 (coderaiser/cloudcmd#457)
|
|
||||||
- 4340533a cloudcmd: c8 v11.0.0
|
|
||||||
- 0857711f cloudcmd: redzip v4.2.0 (#457)
|
|
||||||
|
|
||||||
2026.02.24, v19.6.3
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 2234f1b4 cloudcmd: redzip v4.2.0 (#475)
|
|
||||||
|
|
||||||
2026.02.24, v19.6.2
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 321a54dd cloudcmd: @cloudcmd/fileop v9.0.2 (#457)
|
|
||||||
|
|
||||||
2026.02.24, v19.6.1
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 7c5ac408 cloudcmd: @cloudcmd/fileop v9.0.1 (#457)
|
|
||||||
|
|
||||||
2026.02.21, v19.6.0
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 6d19bf2e common: object.omit -> omit
|
|
||||||
|
|
||||||
2026.02.18, v19.5.1
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 6e1cf4ef cloudcmd: supermenu v5.0.0
|
|
||||||
|
|
||||||
2026.02.18, v19.5.0
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- b20539ef common: entity: encode {,}
|
|
||||||
- 7ef134f4 cloudcmd: rendy v5.0.0
|
|
||||||
|
|
||||||
2026.02.18, v19.4.1
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 1e18d513 cloudcmd: @cloudcmd/fileop v9.0.0
|
|
||||||
|
|
||||||
2026.02.18, v19.4.0
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- 45cf9baf menu: prefix (#456)
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 3e647290 cloudcmd: redlint v6.0.0
|
|
||||||
- 800ed012 cloudcmd: putout v42.0.5
|
|
||||||
- 525c17d4 cloudcmd: madrun v13.0.0
|
|
||||||
- 44247499 cloudcmd: eslint-plugin-putout v31.0.0
|
|
||||||
|
|
||||||
2026.02.15, v19.3.9
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 9ffe3ef1 cloudcmd: copymitter v10.0.0 (#457)
|
|
||||||
|
|
||||||
2026.02.15, v19.3.8
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- d274a2b3 spinner (#456)
|
|
||||||
|
|
||||||
2026.02.13, v19.3.7
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 8fd79a27 cloudcmd: win32 v8.0.0
|
|
||||||
|
|
||||||
2026.02.12, v19.3.6
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- ac94eccd cloudcmd: konsole: named
|
|
||||||
- 144e4a34 cloudcmd: gritty v10.0.0
|
|
||||||
- 938f9e76 cloudcmd: console-io v15.0.1
|
|
||||||
|
|
||||||
2026.02.08, v19.3.5
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- fb40bd9c rm cssnano: has no sense for spinner, option disabled by default (https://svgo.dev/docs/plugins/convertPathData/)
|
|
||||||
- 76125be9 cloudcmd: eslint v10.0.0
|
|
||||||
|
|
||||||
2026.02.06, v19.3.4
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 66a08c7f cloudcmd: deepword v11.0.0
|
|
||||||
|
|
||||||
2026.02.05, v19.3.3
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 4a5a56f4 cloudcmd: dword v16.0.0
|
|
||||||
|
|
||||||
2026.02.04, v19.3.2
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- 99d8435e cloudcmd: exports
|
|
||||||
- a266c145 cloudcmd: default -> named
|
|
||||||
- 6e3ba271 Closing X in editor disappeared (#455)
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 30f42e94 cloudcmd: restafary v13.0.1
|
|
||||||
- f84ce853 cloudcmd: edward v16.0.0
|
|
||||||
|
|
||||||
2026.02.03, v19.3.1
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- 5661bc4f Closing X in editor disappeared (#455)
|
|
||||||
|
|
||||||
2026.02.03, v19.3.0
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 4533a25c cloudcmd: migrate to ESM
|
|
||||||
- e8a81c49 client: dom: events: migrate to ESM
|
|
||||||
- 071141bc client: terminal-run: migrate to ESM
|
|
||||||
|
|
||||||
2026.02.03, v19.2.0
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- bb32f7c4 client: dom: migrate to ESM
|
|
||||||
- 457c83db client: migrate to ESM
|
|
||||||
- f8a941bd client: modules: markdown: migrate to ESM
|
|
||||||
- 9d6cffaf client: polifyll: migrate to ESM
|
|
||||||
- 5b704d06 client: edit-names: migrate to ESM
|
|
||||||
- 2c2ca8eb client: edit-file: migrate to ESM
|
|
||||||
- c9f57c5f client: modules: edit-file-vim: migrate to ESM
|
|
||||||
- 327ac9de client: modules: help: migrate to ESM
|
|
||||||
- dc34ee87 cloudcmd: @putout/plugin-cloudcmd v5.0.0
|
|
||||||
- 3cd3695b client: modules: edit-names-vim: migrate to ESM
|
|
||||||
- dfcbfd63 client: modules: terminal: migrate to ESM
|
|
||||||
|
|
||||||
2026.02.02, v19.1.21
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- e3ad330e client: konsole: migrate to ESM
|
|
||||||
- 983fd9af client: edit: migrate to ESM
|
|
||||||
- ebabad94 common: entity: migrate to ESM
|
|
||||||
- c3b71653 client: dom: images -> #images
|
|
||||||
- 8cad7514 common: cloudfunc -> #common/cloudfunc
|
|
||||||
- 1f174870 client: view: migrate to ESM
|
|
||||||
- 7173f6cb cloudcmd: smalltalk v5.0.0
|
|
||||||
|
|
||||||
2026.01.31, v19.1.20
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- c1014c9c client: dom: operations: rename-current: migrate to ESM
|
|
||||||
- 2e486f8b cloudcmd: restafary v13.0.0
|
|
||||||
- 6addb29f cloudcmd: redzip v4.0.0
|
|
||||||
|
|
||||||
2026.01.30, v19.1.19
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 2a0feac7 cloudcmd: @cloudcmd/modal v4.0.0
|
|
||||||
|
|
||||||
2026.01.30, v19.1.18
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 73fa4961 client: modules: user-menu: migrate to ESM
|
|
||||||
- ebfdf8c0 client: modules: operation: migrate to ESM
|
|
||||||
- ad683171 client: modules: menu: migrate to ESM
|
|
||||||
- 0054cfa3 client: dom: load-remote: migrate to ESM
|
|
||||||
- e4d0ece0 client: dom: rest: migrate to ESM
|
|
||||||
- c704ffe4 client: dom: storage: migrate to ESM
|
|
||||||
- 5182cb81 client: modules: upload: migrate to ESM
|
|
||||||
- 9543f1ad client: dom: upload-files: migrate to ESM
|
|
||||||
|
|
||||||
2026.01.29, v19.1.17
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- f9c28319 client: dom: migrate to ESM
|
|
||||||
- 9d2c4e4a client: dom: cmd: move out
|
|
||||||
- 5a2aa70f client: dom: simplify require
|
|
||||||
- dee50a85 client: dom: files: migrate to ESM
|
|
||||||
- 23c0d770 client: dom: dom-tree: migrate to ESM
|
|
||||||
- cf2c6415 client: directory: migrate to ESM
|
|
||||||
- 0eb802e7 client: dom: dialog: migrate to ESM
|
|
||||||
|
|
||||||
2026.01.28, v19.1.16
|
|
||||||
|
|
||||||
fix:
|
|
||||||
- 4c242631 css: spinner: do not minify svg
|
|
||||||
|
|
||||||
2026.01.28, v19.1.15
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 265c0b49 client: key: vim: migrate to ESM
|
|
||||||
- 3bc49f02 client: set-current-by-char: migrate to ESM
|
|
||||||
|
|
||||||
2026.01.28, v19.1.14
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- f8a63b5a client: key: binder: migrate to ESM
|
|
||||||
- 2cc97f33 client: cloud: migrate to ESM
|
|
||||||
|
|
||||||
2026.01.27, v19.1.13
|
|
||||||
|
|
||||||
feature:
|
|
||||||
- 41b5a96f client: load: migrate to ESM
|
|
||||||
|
|
||||||
2026.01.27, v19.1.12
|
2026.01.27, v19.1.12
|
||||||
|
|
||||||
feature:
|
feature:
|
||||||
|
|
@ -7778,7 +7095,7 @@ with clicks on files.
|
||||||
- Removed allowed from cache property in config.
|
- Removed allowed from cache property in config.
|
||||||
|
|
||||||
- Added ability to hide "Upload To" menu item if
|
- Added ability to hide "Upload To" menu item if
|
||||||
no storage modules set up in modules.json.
|
no storage modules setted up in modules.json.
|
||||||
|
|
||||||
- From now any file minifying only if last modified
|
- From now any file minifying only if last modified
|
||||||
time was changed.
|
time was changed.
|
||||||
|
|
@ -7984,7 +7301,7 @@ in any position in anyLoadOnLoad function.
|
||||||
- Added chainable to Cache object in DOM.
|
- Added chainable to Cache object in DOM.
|
||||||
|
|
||||||
- Changed default ip to null so IP would be geted from
|
- Changed default ip to null so IP would be geted from
|
||||||
config.json only if it set up.
|
config.json only if it setted up.
|
||||||
|
|
||||||
- Fixed bug with starting node from other then projects dir.
|
- Fixed bug with starting node from other then projects dir.
|
||||||
|
|
||||||
|
|
@ -8293,7 +7610,7 @@ time was possible.
|
||||||
|
|
||||||
- Fixed bug with undefined size on root directory of Cloud Commander.
|
- Fixed bug with undefined size on root directory of Cloud Commander.
|
||||||
Now Cloud Commander writes size 0, if can't get size, and besides will
|
Now Cloud Commander writes size 0, if can't get size, and besides will
|
||||||
set b char: "0b".
|
setted b char: "0b".
|
||||||
|
|
||||||
- Added supporting of Russian language in directory names.
|
- Added supporting of Russian language in directory names.
|
||||||
|
|
||||||
|
|
|
||||||
172
HELP.md
172
HELP.md
|
|
@ -1,6 +1,6 @@
|
||||||
# Cloud Commander v19.19.1
|
# Cloud Commander v19.1.12
|
||||||
|
|
||||||
### [Main][MainURL] [Blog][BlogURL] [Demo][DemoURL] [Deploy](#deploy)
|
### [Main][MainURL] [Blog][BlogURL] [Support][SupportURL] [Demo][DemoURL]
|
||||||
|
|
||||||
[MainURL]: https://cloudcmd.io "Main"
|
[MainURL]: https://cloudcmd.io "Main"
|
||||||
[BlogURL]: https://blog.cloudcmd.io "Blog"
|
[BlogURL]: https://blog.cloudcmd.io "Blog"
|
||||||
|
|
@ -9,17 +9,13 @@
|
||||||
[DWORD]: https://github.com/cloudcmd/dword "Editor based on CodeMirror"
|
[DWORD]: https://github.com/cloudcmd/dword "Editor based on CodeMirror"
|
||||||
[EDWARD]: https://github.com/cloudcmd/edward "Editor based on Ace"
|
[EDWARD]: https://github.com/cloudcmd/edward "Editor based on Ace"
|
||||||
[DEEPWORD]: https://github.com/cloudcmd/deepword "Editor based on Monaco"
|
[DEEPWORD]: https://github.com/cloudcmd/deepword "Editor based on Monaco"
|
||||||
[QWORD]: https://github.com/cloudcmd/qword "Editor based on CodeMirror 6"
|
|
||||||
[EDWARD_KEYS]: https://github.com/cloudcmd/edward/#hot-keys "Edward Hot keys"
|
[EDWARD_KEYS]: https://github.com/cloudcmd/edward/#hot-keys "Edward Hot keys"
|
||||||
[TERMUX]: https://termux.com "Termux"
|
[TERMUX]: https://termux.com "Termux"
|
||||||
[INLY]: https://github.com/coderaiser/node-inly "Extract archive"
|
[INLY]: https://github.com/coderaiser/node-inly "Extract archive"
|
||||||
|
|
||||||
[DeployInstaPodsIMG]: https://img.shields.io/badge/deploy%20on-InstaPods-blue
|
|
||||||
[DeployInstaPodsURL]: https://app.instapods.com/dashboard/pods/create?app=cloudcmd&ref=cloudcmd
|
|
||||||
|
|
||||||
**Cloud Commander** is a file manager for the web. It includes a command-line console and a text editor. Cloud Commander helps you manage your server and work with files, directories and programs in a web browser from any computer, mobile or tablet.
|
**Cloud Commander** is a file manager for the web. It includes a command-line console and a text editor. Cloud Commander helps you manage your server and work with files, directories and programs in a web browser from any computer, mobile or tablet.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Benefits
|
## Benefits
|
||||||
|
|
||||||
|
|
@ -30,7 +26,7 @@
|
||||||
- Server works on **Windows**, **Linux**, **Mac OS** and **Android** (with help of [Termux][TERMUX]).
|
- Server works on **Windows**, **Linux**, **Mac OS** and **Android** (with help of [Termux][TERMUX]).
|
||||||
- Can be used local or remotely.
|
- Can be used local or remotely.
|
||||||
- Adapts to screen size.
|
- Adapts to screen size.
|
||||||
- **3 built-in editors** with support of **syntax highlighting**: [Dword][DWORD], [Edward][EDWARD] [Deepword][DEEPWORD] and [Qword][QWORD].
|
- **3 built-in editors** with support of **syntax highlighting**: [Dword][DWORD], [Edward][EDWARD] and [Deepword][DEEPWORD].
|
||||||
- [Console](https://github.com/cloudcmd/console "Console") with support of the default OS command line.
|
- [Console](https://github.com/cloudcmd/console "Console") with support of the default OS command line.
|
||||||
- Written in **JavaScript/Node.js**.
|
- Written in **JavaScript/Node.js**.
|
||||||
- Built-in archives pack: **zip** and **tar.gz**.
|
- Built-in archives pack: **zip** and **tar.gz**.
|
||||||
|
|
@ -92,7 +88,6 @@ Cloud Commander supports the following command-line parameters:
|
||||||
| `--contact` | enable contact
|
| `--contact` | enable contact
|
||||||
| `--config-dialog` | enable config dialog
|
| `--config-dialog` | enable config dialog
|
||||||
| `--config-auth` | enable auth change in config dialog
|
| `--config-auth` | enable auth change in config dialog
|
||||||
| `--config-port` | enable port change in config dialog
|
|
||||||
| `--console` | enable console
|
| `--console` | enable console
|
||||||
| `--sync-console-path` | sync console path
|
| `--sync-console-path` | sync console path
|
||||||
| `--terminal` | enable terminal
|
| `--terminal` | enable terminal
|
||||||
|
|
@ -123,7 +118,6 @@ Cloud Commander supports the following command-line parameters:
|
||||||
| `--no-confirm-move` | do not confirm move
|
| `--no-confirm-move` | do not confirm move
|
||||||
| `--no-config-dialog` | disable config dialog
|
| `--no-config-dialog` | disable config dialog
|
||||||
| `--no-config-auth` | disable auth change in config dialog
|
| `--no-config-auth` | disable auth change in config dialog
|
||||||
| `--no-config-port` | disable port change in config dialog
|
|
||||||
| `--no-console` | disable console
|
| `--no-console` | disable console
|
||||||
| `--no-sync-console-path` | do not sync console path
|
| `--no-sync-console-path` | do not sync console path
|
||||||
| `--no-contact` | disable contact
|
| `--no-contact` | disable contact
|
||||||
|
|
@ -195,7 +189,6 @@ Then, start the server again with `cloudcmd` and reload the page.
|
||||||
| `Ctrl + F3` | sort by name
|
| `Ctrl + F3` | sort by name
|
||||||
| `Ctrl + F5` | sort by date
|
| `Ctrl + F5` | sort by date
|
||||||
| `Ctrl + F6` | sort by size
|
| `Ctrl + F6` | sort by size
|
||||||
| `Ctrl + Shift + L` | logout
|
|
||||||
| `Ctrl + Command + .` | show/hide dot files
|
| `Ctrl + Command + .` | show/hide dot files
|
||||||
| `Up` | move cursor up
|
| `Up` | move cursor up
|
||||||
| `Down` | move cursor down
|
| `Down` | move cursor down
|
||||||
|
|
@ -218,27 +211,24 @@ Then, start the server again with `cloudcmd` and reload the page.
|
||||||
|
|
||||||
When the `--vim` option is provided, or the configuration parameter `vim` is set, the following hotkeys become available:
|
When the `--vim` option is provided, or the configuration parameter `vim` is set, the following hotkeys become available:
|
||||||
|
|
||||||
| Key |Operation
|
|Key |Operation
|
||||||
|:------------|:--------------------------------------------
|
|:----------------------|:--------------------------------------------
|
||||||
| `j` | navigate to next file
|
| `j` | navigate to next file
|
||||||
| `k` | navigate to previous file
|
| `k` | navigate to previous file
|
||||||
| `dd` | remove current file
|
| `dd` | remove current file
|
||||||
| `G` or `$` | navigate to bottom file
|
| `G` or `$` | navigate to bottom file
|
||||||
| `gg` or `^` | navigate to top file
|
| `gg` or `^` | navigate to top file
|
||||||
| `v` | visual mode
|
| `v` | visual mode
|
||||||
| `y` | copy (selected in visual mode files)
|
| `y` | copy (selected in visual mode files)
|
||||||
| `p` | paste files
|
| `p` | paste files
|
||||||
| `Esc` | unselect all
|
| `Esc` | unselect all
|
||||||
| `/` | find file in current directory
|
| `/` | find file in current directory
|
||||||
| `n` | navigate to next found file
|
| `n` | navigate to next found file
|
||||||
| `N` | navigate to previous found file
|
| `N` | navigate to previous found file
|
||||||
| `md` | make directory
|
| `md` | make directory
|
||||||
| `mf` | make file
|
| `mf` | make file
|
||||||
| `tt` | show terminal
|
| `tt` | show terminal
|
||||||
| `e` | edit file
|
| `e` | edit file
|
||||||
| `cc` | copy
|
|
||||||
| `mm` | move
|
|
||||||
| `rr` | rename file
|
|
||||||
|
|
||||||
Commands can be joined, for example:
|
Commands can be joined, for example:
|
||||||
|
|
||||||
|
|
@ -450,7 +440,6 @@ Some config options can be overridden with environment variables, such as:
|
||||||
- `CLOUDCMD_CONTACT` - enable contact
|
- `CLOUDCMD_CONTACT` - enable contact
|
||||||
- `CLOUDCMD_CONFIG_DIALOG` - enable config dialog
|
- `CLOUDCMD_CONFIG_DIALOG` - enable config dialog
|
||||||
- `CLOUDCMD_CONFIG_AUTH` - enable auth change in config dialog
|
- `CLOUDCMD_CONFIG_AUTH` - enable auth change in config dialog
|
||||||
- `CLOUDCMD_CONFIG_PORT` - enable port change in config dialog
|
|
||||||
- `CLOUDCMD_CONSOLE` - enable console
|
- `CLOUDCMD_CONSOLE` - enable console
|
||||||
- `CLOUDCMD_SYNC_CONSOLE_PATH` - sync console path
|
- `CLOUDCMD_SYNC_CONSOLE_PATH` - sync console path
|
||||||
- `CLOUDCMD_TERMINAL` - enable terminal
|
- `CLOUDCMD_TERMINAL` - enable terminal
|
||||||
|
|
@ -699,7 +688,7 @@ And create `index.js`:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import http from 'node:http';
|
import http from 'node:http';
|
||||||
import {cloudcmd} from 'cloudcmd';
|
import cloudcmd from 'cloudcmd';
|
||||||
import {Server} from 'socket.io';
|
import {Server} from 'socket.io';
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
|
|
||||||
|
|
@ -933,9 +922,9 @@ ln -s ./sites-available/io.cloudcmd.io ./sites-enabled
|
||||||
|
|
||||||
## Deploy
|
## Deploy
|
||||||
|
|
||||||
`Cloud Commander` can be easily deployed to [InstaPods][DeployInstaPodsURL]. After deploy you receive email with credentials.
|
`Cloud Commander` can be easily deployed to [Heroku](https://heroku.com/deploy?template=https://github.com/coderaiser/cloudcmd "Deploy to Heroku").
|
||||||
|
|
||||||
[](https://app.instapods.com/dashboard/pods/create?app=cloudcmd&ref=cloudcmd)
|
[](https://heroku.com/deploy?template=https://github.com/coderaiser/cloudcmd)
|
||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
|
|
||||||
|
|
@ -1122,117 +1111,6 @@ There are a lot of ways to be involved in `Cloud Commander` development:
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|
||||||
- *2026.06.15*, **[v19.19.1](//github.com/coderaiser/cloudcmd/releases/tag/v19.19.1)**
|
|
||||||
- *2026.05.26*, **[v19.19.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.19.0)**
|
|
||||||
- *2026.05.26*, **[v19.18.1](//github.com/coderaiser/cloudcmd/releases/tag/v19.18.1)**
|
|
||||||
- *2026.05.26*, **[v19.18.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.18.0)**
|
|
||||||
- *2026.05.17*, **[v19.17.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.17.0)**
|
|
||||||
- *2026.05.03*, **[v19.16.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.16.0)**
|
|
||||||
- *2026.04.28*, **[v19.15.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.15.0)**
|
|
||||||
- *2026.04.28*, **[v19.14.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.14.0)**
|
|
||||||
- *2026.04.21*, **[v19.13.1](//github.com/coderaiser/cloudcmd/releases/tag/v19.13.1)**
|
|
||||||
- *2026.04.15*, **[v19.13.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.13.0)**
|
|
||||||
- *2026.04.12*, **[v19.12.5](//github.com/coderaiser/cloudcmd/releases/tag/v19.12.5)**
|
|
||||||
- *2026.04.12*, **[v19.12.4](//github.com/coderaiser/cloudcmd/releases/tag/v19.12.4)**
|
|
||||||
- *2026.04.12*, **[v19.12.3](//github.com/coderaiser/cloudcmd/releases/tag/v19.12.3)**
|
|
||||||
- *2026.04.11*, **[v19.12.2](//github.com/coderaiser/cloudcmd/releases/tag/v19.12.2)**
|
|
||||||
- *2026.04.09*, **[v19.12.1](//github.com/coderaiser/cloudcmd/releases/tag/v19.12.1)**
|
|
||||||
- *2026.04.09*, **[v19.12.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.12.0)**
|
|
||||||
- *2026.04.07*, **[v19.11.14](//github.com/coderaiser/cloudcmd/releases/tag/v19.11.14)**
|
|
||||||
- *2026.04.07*, **[v19.11.13](//github.com/coderaiser/cloudcmd/releases/tag/v19.11.13)**
|
|
||||||
- *2026.04.06*, **[v19.11.12](//github.com/coderaiser/cloudcmd/releases/tag/v19.11.12)**
|
|
||||||
- *2026.04.06*, **[v19.11.11](//github.com/coderaiser/cloudcmd/releases/tag/v19.11.11)**
|
|
||||||
- *2026.04.06*, **[v19.11.10](//github.com/coderaiser/cloudcmd/releases/tag/v19.11.10)**
|
|
||||||
- *2026.04.06*, **[v19.11.9](//github.com/coderaiser/cloudcmd/releases/tag/v19.11.9)**
|
|
||||||
- *2026.04.06*, **[v19.11.8](//github.com/coderaiser/cloudcmd/releases/tag/v19.11.8)**
|
|
||||||
- *2026.04.05*, **[v19.11.7](//github.com/coderaiser/cloudcmd/releases/tag/v19.11.7)**
|
|
||||||
- *2026.04.05*, **[v19.11.6](//github.com/coderaiser/cloudcmd/releases/tag/v19.11.6)**
|
|
||||||
- *2026.04.05*, **[v19.11.5](//github.com/coderaiser/cloudcmd/releases/tag/v19.11.5)**
|
|
||||||
- *2026.04.04*, **[v19.11.4](//github.com/coderaiser/cloudcmd/releases/tag/v19.11.4)**
|
|
||||||
- *2026.04.04*, **[v19.11.3](//github.com/coderaiser/cloudcmd/releases/tag/v19.11.3)**
|
|
||||||
- *2026.04.04*, **[v19.11.2](//github.com/coderaiser/cloudcmd/releases/tag/v19.11.2)**
|
|
||||||
- *2026.04.04*, **[v19.11.1](//github.com/coderaiser/cloudcmd/releases/tag/v19.11.1)**
|
|
||||||
- *2026.04.04*, **[v19.11.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.11.0)**
|
|
||||||
- *2026.04.04*, **[v19.10.2](//github.com/coderaiser/cloudcmd/releases/tag/v19.10.2)**
|
|
||||||
- *2026.04.03*, **[v19.10.1](//github.com/coderaiser/cloudcmd/releases/tag/v19.10.1)**
|
|
||||||
- *2026.04.02*, **[v19.10.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.10.0)**
|
|
||||||
- *2026.04.02*, **[v19.9.24](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.24)**
|
|
||||||
- *2026.04.01*, **[v19.9.23](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.23)**
|
|
||||||
- *2026.03.31*, **[v19.9.22](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.22)**
|
|
||||||
- *2026.03.31*, **[v19.9.21](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.21)**
|
|
||||||
- *2026.03.30*, **[v19.9.20](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.20)**
|
|
||||||
- *2026.03.30*, **[v19.9.19](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.19)**
|
|
||||||
- *2026.03.30*, **[v19.9.18](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.18)**
|
|
||||||
- *2026.03.30*, **[v19.9.17](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.17)**
|
|
||||||
- *2026.03.29*, **[v19.9.16](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.16)**
|
|
||||||
- *2026.03.29*, **[v19.9.15](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.15)**
|
|
||||||
- *2026.03.29*, **[v19.9.14](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.14)**
|
|
||||||
- *2026.03.29*, **[v19.9.13](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.13)**
|
|
||||||
- *2026.03.29*, **[v19.9.12](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.12)**
|
|
||||||
- *2026.03.29*, **[v19.9.11](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.11)**
|
|
||||||
- *2026.03.29*, **[v19.9.10](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.10)**
|
|
||||||
- *2026.03.29*, **[v19.9.9](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.9)**
|
|
||||||
- *2026.03.28*, **[v19.9.8](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.8)**
|
|
||||||
- *2026.03.27*, **[v19.9.7](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.7)**
|
|
||||||
- *2026.03.26*, **[v19.9.6](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.6)**
|
|
||||||
- *2026.03.26*, **[v19.9.5](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.5)**
|
|
||||||
- *2026.03.26*, **[v19.9.4](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.4)**
|
|
||||||
- *2026.03.24*, **[v19.9.3](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.3)**
|
|
||||||
- *2026.03.23*, **[v19.9.2](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.2)**
|
|
||||||
- *2026.03.23*, **[v19.9.1](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.1)**
|
|
||||||
- *2026.03.23*, **[v19.9.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.9.0)**
|
|
||||||
- *2026.03.23*, **[v19.8.15](//github.com/coderaiser/cloudcmd/releases/tag/v19.8.15)**
|
|
||||||
- *2026.03.23*, **[v19.8.14](//github.com/coderaiser/cloudcmd/releases/tag/v19.8.14)**
|
|
||||||
- *2026.03.23*, **[v19.8.13](//github.com/coderaiser/cloudcmd/releases/tag/v19.8.13)**
|
|
||||||
- *2026.03.23*, **[v19.8.12](//github.com/coderaiser/cloudcmd/releases/tag/v19.8.12)**
|
|
||||||
- *2026.03.23*, **[v19.8.11](//github.com/coderaiser/cloudcmd/releases/tag/v19.8.11)**
|
|
||||||
- *2026.03.23*, **[v19.8.10](//github.com/coderaiser/cloudcmd/releases/tag/v19.8.10)**
|
|
||||||
- *2026.03.23*, **[v19.8.9](//github.com/coderaiser/cloudcmd/releases/tag/v19.8.9)**
|
|
||||||
- *2026.03.23*, **[v19.8.8](//github.com/coderaiser/cloudcmd/releases/tag/v19.8.8)**
|
|
||||||
- *2026.03.23*, **[v19.8.7](//github.com/coderaiser/cloudcmd/releases/tag/v19.8.7)**
|
|
||||||
- *2026.03.23*, **[v19.8.6](//github.com/coderaiser/cloudcmd/releases/tag/v19.8.6)**
|
|
||||||
- *2026.03.23*, **[v19.8.5](//github.com/coderaiser/cloudcmd/releases/tag/v19.8.5)**
|
|
||||||
- *2026.03.22*, **[v19.8.4](//github.com/coderaiser/cloudcmd/releases/tag/v19.8.4)**
|
|
||||||
- *2026.03.22*, **[v19.8.3](//github.com/coderaiser/cloudcmd/releases/tag/v19.8.3)**
|
|
||||||
- *2026.03.22*, **[v19.8.2](//github.com/coderaiser/cloudcmd/releases/tag/v19.8.2)**
|
|
||||||
- *2026.03.22*, **[v19.8.1](//github.com/coderaiser/cloudcmd/releases/tag/v19.8.1)**
|
|
||||||
- *2026.03.20*, **[v19.8.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.8.0)**
|
|
||||||
- *2026.03.18*, **[v19.7.1](//github.com/coderaiser/cloudcmd/releases/tag/v19.7.1)**
|
|
||||||
- *2026.03.17*, **[v19.7.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.7.0)**
|
|
||||||
- *2026.03.17*, **[v19.6.9](//github.com/coderaiser/cloudcmd/releases/tag/v19.6.9)**
|
|
||||||
- *2026.02.27*, **[v19.6.8](//github.com/coderaiser/cloudcmd/releases/tag/v19.6.8)**
|
|
||||||
- *2026.02.26*, **[v19.6.7](//github.com/coderaiser/cloudcmd/releases/tag/v19.6.7)**
|
|
||||||
- *2026.02.26*, **[v19.6.6](//github.com/coderaiser/cloudcmd/releases/tag/v19.6.6)**
|
|
||||||
- *2026.02.26*, **[v19.6.5](//github.com/coderaiser/cloudcmd/releases/tag/v19.6.5)**
|
|
||||||
- *2026.02.25*, **[v19.6.4](//github.com/coderaiser/cloudcmd/releases/tag/v19.6.4)**
|
|
||||||
- *2026.02.24*, **[v19.6.3](//github.com/coderaiser/cloudcmd/releases/tag/v19.6.3)**
|
|
||||||
- *2026.02.24*, **[v19.6.2](//github.com/coderaiser/cloudcmd/releases/tag/v19.6.2)**
|
|
||||||
- *2026.02.24*, **[v19.6.1](//github.com/coderaiser/cloudcmd/releases/tag/v19.6.1)**
|
|
||||||
- *2026.02.21*, **[v19.6.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.6.0)**
|
|
||||||
- *2026.02.18*, **[v19.5.1](//github.com/coderaiser/cloudcmd/releases/tag/v19.5.1)**
|
|
||||||
- *2026.02.18*, **[v19.5.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.5.0)**
|
|
||||||
- *2026.02.18*, **[v19.4.1](//github.com/coderaiser/cloudcmd/releases/tag/v19.4.1)**
|
|
||||||
- *2026.02.18*, **[v19.4.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.4.0)**
|
|
||||||
- *2026.02.15*, **[v19.3.9](//github.com/coderaiser/cloudcmd/releases/tag/v19.3.9)**
|
|
||||||
- *2026.02.15*, **[v19.3.8](//github.com/coderaiser/cloudcmd/releases/tag/v19.3.8)**
|
|
||||||
- *2026.02.13*, **[v19.3.7](//github.com/coderaiser/cloudcmd/releases/tag/v19.3.7)**
|
|
||||||
- *2026.02.12*, **[v19.3.6](//github.com/coderaiser/cloudcmd/releases/tag/v19.3.6)**
|
|
||||||
- *2026.02.08*, **[v19.3.5](//github.com/coderaiser/cloudcmd/releases/tag/v19.3.5)**
|
|
||||||
- *2026.02.06*, **[v19.3.4](//github.com/coderaiser/cloudcmd/releases/tag/v19.3.4)**
|
|
||||||
- *2026.02.05*, **[v19.3.3](//github.com/coderaiser/cloudcmd/releases/tag/v19.3.3)**
|
|
||||||
- *2026.02.04*, **[v19.3.2](//github.com/coderaiser/cloudcmd/releases/tag/v19.3.2)**
|
|
||||||
- *2026.02.03*, **[v19.3.1](//github.com/coderaiser/cloudcmd/releases/tag/v19.3.1)**
|
|
||||||
- *2026.02.03*, **[v19.3.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.3.0)**
|
|
||||||
- *2026.02.03*, **[v19.2.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.2.0)**
|
|
||||||
- *2026.02.02*, **[v19.1.21](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.21)**
|
|
||||||
- *2026.01.31*, **[v19.1.20](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.20)**
|
|
||||||
- *2026.01.30*, **[v19.1.19](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.19)**
|
|
||||||
- *2026.01.30*, **[v19.1.18](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.18)**
|
|
||||||
- *2026.01.29*, **[v19.1.17](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.17)**
|
|
||||||
- *2026.01.28*, **[v19.1.16](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.16)**
|
|
||||||
- *2026.01.28*, **[v19.1.15](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.15)**
|
|
||||||
- *2026.01.28*, **[v19.1.14](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.14)**
|
|
||||||
- *2026.01.27*, **[v19.1.13](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.13)**
|
|
||||||
- *2026.01.27*, **[v19.1.12](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.12)**
|
- *2026.01.27*, **[v19.1.12](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.12)**
|
||||||
- *2026.01.25*, **[v19.1.11](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.11)**
|
- *2026.01.25*, **[v19.1.11](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.11)**
|
||||||
- *2026.01.25*, **[v19.1.10](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.10)**
|
- *2026.01.25*, **[v19.1.10](//github.com/coderaiser/cloudcmd/releases/tag/v19.1.10)**
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# Cloud Commander v19.19.1 [![Build Status][BuildStatusIMGURL]][BuildStatusURL] [![Codacy][CodacyIMG]][CodacyURL] [![Gitter][GitterIMGURL]][GitterURL] [![Deploy on InstaPods][DeployInstaPodsIMG]][DeployInstaPodsURL]
|
# Cloud Commander v19.1.12 [![Build Status][BuildStatusIMGURL]][BuildStatusURL] [![Codacy][CodacyIMG]][CodacyURL] [![Gitter][GitterIMGURL]][GitterURL]
|
||||||
|
|
||||||
### [Main][MainURL] [Blog][BlogURL] [Support][SupportURL] [Demo][DemoURL]
|
### [Main][MainURL] [Blog][BlogURL] [Support][SupportURL] [Demo][DemoURL]
|
||||||
|
|
||||||
|
|
@ -15,8 +15,6 @@
|
||||||
[GitterIMGURL]: https://img.shields.io/gitter/room/coderaiser/cloudcmd.js.svg
|
[GitterIMGURL]: https://img.shields.io/gitter/room/coderaiser/cloudcmd.js.svg
|
||||||
[DeployURL]: https://heroku.com/deploy?template=https://github.com/coderaiser/cloudcmd "Deploy"
|
[DeployURL]: https://heroku.com/deploy?template=https://github.com/coderaiser/cloudcmd "Deploy"
|
||||||
[DeployIMG]: https://www.herokucdn.com/deploy/button.png
|
[DeployIMG]: https://www.herokucdn.com/deploy/button.png
|
||||||
[DeployInstaPodsIMG]: https://img.shields.io/badge/deploy%20on-InstaPods-blue
|
|
||||||
[DeployInstaPodsURL]: https://app.instapods.com/dashboard/pods/create?app=cloudcmd&ref=cloudcmd
|
|
||||||
|
|
||||||
**Cloud Commander** a file manager for the web with console and editor.
|
**Cloud Commander** a file manager for the web with console and editor.
|
||||||
|
|
||||||
|
|
@ -71,7 +69,7 @@ And create `index.js`:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import http from 'node:http';
|
import http from 'node:http';
|
||||||
import {cloudcmd} from 'cloudcmd';
|
import cloudcmd from 'cloudcmd';
|
||||||
import {Server} from 'socket.io';
|
import {Server} from 'socket.io';
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,24 @@
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
|
import {createRequire} from 'node:module';
|
||||||
import {promisify} from 'node:util';
|
import {promisify} from 'node:util';
|
||||||
import {tryToCatch} from 'try-to-catch';
|
import {tryToCatch} from 'try-to-catch';
|
||||||
|
import {createSimport} from 'simport';
|
||||||
import parse from 'yargs-parser';
|
import parse from 'yargs-parser';
|
||||||
import exit from '../server/exit.js';
|
import exit from '../server/exit.js';
|
||||||
import {createConfig, configPath} from '../server/config.js';
|
import {createConfig, configPath} from '../server/config.mjs';
|
||||||
import * as env from '../server/env.js';
|
import * as env from '../server/env.mjs';
|
||||||
import prefixer from '../server/prefixer.js';
|
import prefixer from '../server/prefixer.js';
|
||||||
import * as validate from '../server/validate.js';
|
import * as validate from '../server/validate.mjs';
|
||||||
import Info from '../package.json' with {
|
|
||||||
type: 'json',
|
|
||||||
};
|
|
||||||
|
|
||||||
process.on('unhandledRejection', exit);
|
process.on('unhandledRejection', exit);
|
||||||
|
|
||||||
|
const require = createRequire(import.meta.url);
|
||||||
|
|
||||||
|
const Info = require('../package.json');
|
||||||
const isUndefined = (a) => typeof a === 'undefined';
|
const isUndefined = (a) => typeof a === 'undefined';
|
||||||
|
const simport = createSimport(import.meta.url);
|
||||||
|
|
||||||
const choose = (a, b) => {
|
const choose = (a, b) => {
|
||||||
if (isUndefined(a))
|
if (isUndefined(a))
|
||||||
|
|
@ -28,6 +31,8 @@ const config = createConfig({
|
||||||
configPath,
|
configPath,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const DIR_SERVER = '../server/';
|
||||||
|
|
||||||
const maybeRoot = (a) => {
|
const maybeRoot = (a) => {
|
||||||
if (a === '.')
|
if (a === '.')
|
||||||
return process.cwd();
|
return process.cwd();
|
||||||
|
|
@ -73,7 +78,6 @@ const yargsOptions = {
|
||||||
'open',
|
'open',
|
||||||
'config-dialog',
|
'config-dialog',
|
||||||
'config-auth',
|
'config-auth',
|
||||||
'config-port',
|
|
||||||
'console',
|
'console',
|
||||||
'sync-console-path',
|
'sync-console-path',
|
||||||
'contact',
|
'contact',
|
||||||
|
|
@ -115,7 +119,7 @@ const yargsOptions = {
|
||||||
'columns': env.parse('columns') || config('columns') || '',
|
'columns': env.parse('columns') || config('columns') || '',
|
||||||
'theme': env.parse('theme') || config('theme') || '',
|
'theme': env.parse('theme') || config('theme') || '',
|
||||||
'vim': choose(env.bool('vim'), config('vim')),
|
'vim': choose(env.bool('vim'), config('vim')),
|
||||||
'log': choose(env.bool('log'), config('log')),
|
'log': config('log'),
|
||||||
|
|
||||||
'import-url': env.parse('import_url') || config('importUrl'),
|
'import-url': env.parse('import_url') || config('importUrl'),
|
||||||
'import-listen': choose(env.bool('import_listen'), config('importListen')),
|
'import-listen': choose(env.bool('import_listen'), config('importListen')),
|
||||||
|
|
@ -128,7 +132,6 @@ const yargsOptions = {
|
||||||
'sync-console-path': choose(env.bool('sync_console_path'), config('syncConsolePath')),
|
'sync-console-path': choose(env.bool('sync_console_path'), config('syncConsolePath')),
|
||||||
'config-dialog': choose(env.bool('config_dialog'), config('configDialog')),
|
'config-dialog': choose(env.bool('config_dialog'), config('configDialog')),
|
||||||
'config-auth': choose(env.bool('config_auth'), config('configAuth')),
|
'config-auth': choose(env.bool('config_auth'), config('configAuth')),
|
||||||
'config-port': choose(env.bool('config_port'), config('configPort')),
|
|
||||||
'terminal-path': env.parse('terminal_path') || config('terminalPath'),
|
'terminal-path': env.parse('terminal_path') || config('terminalPath'),
|
||||||
'terminal-command': env.parse('terminal_command') || config('terminalCommand'),
|
'terminal-command': env.parse('terminal_command') || config('terminalCommand'),
|
||||||
'terminal-auto-restart': choose(env.bool('terminal_auto_restart'), config('terminalAutoRestart')),
|
'terminal-auto-restart': choose(env.bool('terminal_auto_restart'), config('terminalAutoRestart')),
|
||||||
|
|
@ -165,7 +168,7 @@ else
|
||||||
main();
|
main();
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const {validateArgs} = await import('@putout/cli-validate-args');
|
const {validateArgs} = await simport('@putout/cli-validate-args');
|
||||||
|
|
||||||
const error = await validateArgs(args, [
|
const error = await validateArgs(args, [
|
||||||
...yargsOptions.boolean,
|
...yargsOptions.boolean,
|
||||||
|
|
@ -176,7 +179,7 @@ async function main() {
|
||||||
return exit(error);
|
return exit(error);
|
||||||
|
|
||||||
if (args.repl)
|
if (args.repl)
|
||||||
await repl();
|
repl();
|
||||||
|
|
||||||
validate.columns(args.columns);
|
validate.columns(args.columns);
|
||||||
validate.theme(args.theme);
|
validate.theme(args.theme);
|
||||||
|
|
@ -211,7 +214,6 @@ async function main() {
|
||||||
config('oneFilePanel', args.oneFilePanel);
|
config('oneFilePanel', args.oneFilePanel);
|
||||||
config('configDialog', args.configDialog);
|
config('configDialog', args.configDialog);
|
||||||
config('configAuth', args.configAuth);
|
config('configAuth', args.configAuth);
|
||||||
config('configPort', args.configPort);
|
|
||||||
config('keysPanel', args.keysPanel);
|
config('keysPanel', args.keysPanel);
|
||||||
config('export', args.export);
|
config('export', args.export);
|
||||||
config('exportToken', args.exportToken);
|
config('exportToken', args.exportToken);
|
||||||
|
|
@ -246,7 +248,7 @@ async function main() {
|
||||||
if (args.showConfig)
|
if (args.showConfig)
|
||||||
await showConfig();
|
await showConfig();
|
||||||
|
|
||||||
const {distributeImport} = await import('../server/distribute/import.js');
|
const {distributeImport} = await simport('../server/distribute/import.mjs');
|
||||||
const importConfig = promisify(distributeImport);
|
const importConfig = promisify(distributeImport);
|
||||||
|
|
||||||
await start(options, config);
|
await start(options, config);
|
||||||
|
|
@ -264,12 +266,11 @@ function validateRoot(root, config) {
|
||||||
if (root === '/')
|
if (root === '/')
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (config('log'))
|
console.log(`root: ${root}`);
|
||||||
console.log(`root: ${root}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getPassword(password) {
|
async function getPassword(password) {
|
||||||
const {default: criton} = await import('criton');
|
const criton = await simport('criton');
|
||||||
return criton(password, config('algo'));
|
return criton(password, config('algo'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -278,10 +279,12 @@ function version() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function start(options, config) {
|
async function start(options, config) {
|
||||||
|
const SERVER = `${DIR_SERVER}server.mjs`;
|
||||||
|
|
||||||
if (!args.server)
|
if (!args.server)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const {default: server} = await import('../server/server.js');
|
const server = await simport(SERVER);
|
||||||
server(options, config);
|
server(options, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -295,8 +298,8 @@ function port(arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function showConfig() {
|
async function showConfig() {
|
||||||
const {showConfig} = await import('../server/show-config.js');
|
const show = await simport('../server/show-config');
|
||||||
const data = showConfig(config('*'));
|
const data = show(config('*'));
|
||||||
|
|
||||||
console.log(data);
|
console.log(data);
|
||||||
}
|
}
|
||||||
|
|
@ -305,13 +308,13 @@ async function readConfig(name) {
|
||||||
if (!name)
|
if (!name)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const {default: forEachKey} = await import('for-each-key');
|
const tryToCatch = await simport('try-to-catch');
|
||||||
|
const forEachKey = await simport('for-each-key');
|
||||||
|
|
||||||
const data = await import(name, {
|
const [error, data] = await tryToCatch(simport, name);
|
||||||
with: {
|
|
||||||
type: 'json',
|
if (error)
|
||||||
},
|
return exit(error.message);
|
||||||
});
|
|
||||||
|
|
||||||
forEachKey(config, data);
|
forEachKey(config, data);
|
||||||
}
|
}
|
||||||
|
|
@ -323,8 +326,8 @@ async function help() {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const {default: forEachKey} = await import('for-each-key');
|
const forEachKey = await simport('for-each-key');
|
||||||
const {default: currify} = await import('currify');
|
const currify = await simport('currify');
|
||||||
|
|
||||||
const usage = 'Usage: cloudcmd [options]';
|
const usage = 'Usage: cloudcmd [options]';
|
||||||
const url = Info.homepage;
|
const url = Info.homepage;
|
||||||
|
|
@ -336,15 +339,15 @@ async function help() {
|
||||||
console.log('\nGeneral help using Cloud Commander: <%s>', url);
|
console.log('\nGeneral help using Cloud Commander: <%s>', url);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function repl() {
|
function repl() {
|
||||||
console.log('REPL mode enabled (telnet localhost 1337)');
|
console.log('REPL mode enabled (telnet localhost 1337)');
|
||||||
await import('../server/repl.js');
|
require(`${DIR_SERVER}repl`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkUpdate() {
|
async function checkUpdate() {
|
||||||
const {default: load} = await import('package-json');
|
const load = await simport('package-json');
|
||||||
const {version} = await load(Info.name, 'latest');
|
|
||||||
|
|
||||||
|
const {version} = await load(Info.name, 'latest');
|
||||||
await showUpdateInfo(version);
|
await showUpdateInfo(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -352,7 +355,7 @@ async function showUpdateInfo(version) {
|
||||||
if (version === Info.version)
|
if (version === Info.version)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const {default: chalk} = await import('chalk');
|
const chalk = await simport('chalk');
|
||||||
|
|
||||||
const latestVersion = chalk.green.bold(`v${version}`);
|
const latestVersion = chalk.green.bold(`v${version}`);
|
||||||
const latest = `update available: ${latestVersion}`;
|
const latest = `update available: ${latestVersion}`;
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
import {spawnSync} from 'node:child_process';
|
|
||||||
import {test} from 'supertape';
|
|
||||||
import info from '../package.json' with {
|
|
||||||
type: 'json',
|
|
||||||
};
|
|
||||||
|
|
||||||
const cliPath = new URL('cloudcmd.js', import.meta.url).pathname;
|
|
||||||
|
|
||||||
test('cloudcmd: bin: cli: -h', (t) => {
|
|
||||||
const {stdout} = spawnSync(cliPath, ['-h'], {
|
|
||||||
encoding: 'utf8',
|
|
||||||
});
|
|
||||||
|
|
||||||
t.match(stdout, `Options`);
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('cloudcmd: bin: cli: -v', (t) => {
|
|
||||||
const {version} = info;
|
|
||||||
const {stdout} = spawnSync(cliPath, ['-v'], {
|
|
||||||
encoding: 'utf8',
|
|
||||||
});
|
|
||||||
|
|
||||||
t.match(stdout, `v${version}`);
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
@ -3,27 +3,26 @@
|
||||||
import {promisify} from 'node:util';
|
import {promisify} from 'node:util';
|
||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
import {tryToCatch} from 'try-to-catch';
|
import {tryToCatch} from 'try-to-catch';
|
||||||
|
import {createSimport} from 'simport';
|
||||||
import minor from 'minor';
|
import minor from 'minor';
|
||||||
import _place from 'place';
|
import _place from 'place';
|
||||||
import {rendy} from 'rendy';
|
import rendy from 'rendy';
|
||||||
import shortdate from 'shortdate';
|
import shortdate from 'shortdate';
|
||||||
import Info from '../package.json' with {
|
|
||||||
type: 'json',
|
|
||||||
};
|
|
||||||
|
|
||||||
|
const simport = createSimport(import.meta.url);
|
||||||
const place = promisify(_place);
|
const place = promisify(_place);
|
||||||
|
|
||||||
|
const Info = await simport('../package.json');
|
||||||
|
|
||||||
await main();
|
await main();
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const history = '## Version history\n\n';
|
const history = '## Version history\n\n';
|
||||||
const link = '//github.com/coderaiser/cloudcmd/releases/tag/';
|
const link = '//github.com/coderaiser/cloudcmd/releases/tag/';
|
||||||
|
|
||||||
const template = '- ' +
|
const template = '- ' +
|
||||||
'*{{ date }}*, ' +
|
'*{{ date }}*, ' +
|
||||||
'**[v{{ version }}]' +
|
'**[v{{ version }}]' +
|
||||||
'(' +
|
'(' + link +
|
||||||
link +
|
|
||||||
'v{{ version }})**\n';
|
'v{{ version }})**\n';
|
||||||
|
|
||||||
const {version} = Info;
|
const {version} = Info;
|
||||||
|
|
@ -36,11 +35,10 @@ async function main() {
|
||||||
await replaceVersion('README.md', version, versionNew);
|
await replaceVersion('README.md', version, versionNew);
|
||||||
await replaceVersion('HELP.md', version, versionNew);
|
await replaceVersion('HELP.md', version, versionNew);
|
||||||
|
|
||||||
const historyNew = history +
|
const historyNew = history + rendy(template, {
|
||||||
rendy(template, {
|
date: shortdate(),
|
||||||
date: shortdate(),
|
version: versionNew,
|
||||||
version: versionNew,
|
});
|
||||||
});
|
|
||||||
|
|
||||||
await replaceVersion('HELP.md', history, historyNew);
|
await replaceVersion('HELP.md', history, historyNew);
|
||||||
}
|
}
|
||||||
|
|
@ -1,22 +1,24 @@
|
||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
|
|
||||||
|
/* global DOM */
|
||||||
import Emitify from 'emitify';
|
import Emitify from 'emitify';
|
||||||
import inherits from 'inherits';
|
import inherits from 'inherits';
|
||||||
import {rendy} from 'rendy';
|
import rendy from 'rendy';
|
||||||
import load from 'load.js';
|
import load from 'load.js';
|
||||||
import {tryToCatch} from 'try-to-catch';
|
import {tryToCatch} from 'try-to-catch';
|
||||||
import {addSlashToEnd} from 'format-io';
|
import {addSlashToEnd} from 'format-io';
|
||||||
import pascalCase from 'just-pascal-case';
|
import pascalCase from 'just-pascal-case';
|
||||||
import currify from 'currify';
|
import currify from 'currify';
|
||||||
|
import * as Images from './dom/images.mjs';
|
||||||
|
import {unregisterSW} from './sw/register.mjs';
|
||||||
|
import {getJsonFromFileTable} from './get-json-from-file-table.mjs';
|
||||||
|
import {Key} from './key/index.mjs';
|
||||||
import {
|
import {
|
||||||
apiURL,
|
apiURL,
|
||||||
formatMsg,
|
formatMsg,
|
||||||
buildFromJSON,
|
buildFromJSON,
|
||||||
} from '#common/cloudfunc';
|
} from '../common/cloudfunc.mjs';
|
||||||
import * as Images from '#dom/images';
|
import {loadModule} from './load-module.mjs';
|
||||||
import {unregisterSW} from './sw/register.js';
|
|
||||||
import {getJsonFromFileTable} from './get-json-from-file-table.js';
|
|
||||||
import {Key} from './key/index.js';
|
|
||||||
import {loadModule} from './load-module.js';
|
|
||||||
|
|
||||||
const noJS = (a) => a.replace(/.js$/, '');
|
const noJS = (a) => a.replace(/.js$/, '');
|
||||||
|
|
||||||
|
|
@ -348,12 +350,7 @@ function CloudCmdProto({DOM, Listeners}) {
|
||||||
'pathLink',
|
'pathLink',
|
||||||
];
|
];
|
||||||
|
|
||||||
const [error, [
|
const [error, [file, path, link, pathLink]] = await tryToCatch(Files.get, names);
|
||||||
file,
|
|
||||||
path,
|
|
||||||
link,
|
|
||||||
pathLink,
|
|
||||||
]] = await tryToCatch(Files.get, names);
|
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
return DOM.Dialog.alert(error.responseText);
|
return DOM.Dialog.alert(error.responseText);
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
import '../css/main.css';
|
|
||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
import wraptile from 'wraptile';
|
import wraptile from 'wraptile';
|
||||||
import load from 'load.js';
|
import load from 'load.js';
|
||||||
import * as Util from '#common/util';
|
import '../css/main.css';
|
||||||
import * as CloudFunc from '#common/cloudfunc';
|
import {registerSW, listenSW} from './sw/register.mjs';
|
||||||
import DOM from '#dom';
|
import {initSortPanel, sortPanel} from './sort.mjs';
|
||||||
import {registerSW, listenSW} from './sw/register.js';
|
import Util from '../common/util.js';
|
||||||
import {initSortPanel, sortPanel} from './sort.js';
|
import * as CloudFunc from '../common/cloudfunc.mjs';
|
||||||
import {createCloudCmd} from './client.js';
|
import DOM from './dom/index.js';
|
||||||
import * as Listeners from './listeners/index.js';
|
import {createCloudCmd} from './client.mjs';
|
||||||
|
import * as Listeners from './listeners/index.mjs';
|
||||||
|
|
||||||
const isDev = process.env.NODE_ENV === 'development';
|
const isDev = process.env.NODE_ENV === 'development';
|
||||||
|
|
||||||
|
|
@ -36,7 +36,7 @@ async function init(config) {
|
||||||
if (globalThis.CloudCmd.config('menu') === 'aleman')
|
if (globalThis.CloudCmd.config('menu') === 'aleman')
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
import('https://esm.sh/@putout/processor-html');
|
import('https://esm.sh/@putout/processor-html');
|
||||||
import('https://esm.sh/@putout/bundle@5.5');
|
import('https://esm.sh/@putout/bundle');
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* global CloudCmd*/
|
/* global CloudCmd*/
|
||||||
import * as Storage from '#dom/storage';
|
|
||||||
import tryToPromiseAll from '../../common/try-to-promise-all.js';
|
import tryToPromiseAll from '../../common/try-to-promise-all.js';
|
||||||
|
import Storage from './storage.js';
|
||||||
|
|
||||||
const CLASS = 'cut-file';
|
const CLASS = 'cut-file';
|
||||||
const COPY = 'copy';
|
const COPY = 'copy';
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
/* global DOM */
|
|
||||||
const SELECTED_FILE = 'selected-file';
|
|
||||||
const Cmd = {
|
|
||||||
getSelectedFiles,
|
|
||||||
isSelected,
|
|
||||||
unselectFile,
|
|
||||||
selectFile,
|
|
||||||
selectAllFiles,
|
|
||||||
toggleSelectedFile,
|
|
||||||
toggleAllSelectedFiles,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* selected file check
|
|
||||||
*
|
|
||||||
* @param currentFile
|
|
||||||
*/
|
|
||||||
export function isSelected(currentFile) {
|
|
||||||
if (!currentFile)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return DOM.isContainClass(currentFile, SELECTED_FILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* select current file
|
|
||||||
* @param currentFile
|
|
||||||
*/
|
|
||||||
export function selectFile(currentFile) {
|
|
||||||
const current = currentFile || DOM.getCurrentFile();
|
|
||||||
|
|
||||||
current.classList.add(SELECTED_FILE);
|
|
||||||
|
|
||||||
return Cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function unselectFile(currentFile) {
|
|
||||||
const current = currentFile || DOM.getCurrentFile();
|
|
||||||
|
|
||||||
current.classList.remove(SELECTED_FILE);
|
|
||||||
|
|
||||||
return Cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toggleSelectedFile(currentFile) {
|
|
||||||
const current = currentFile || DOM.getCurrentFile();
|
|
||||||
const name = DOM.getCurrentName(current);
|
|
||||||
|
|
||||||
if (name === '..')
|
|
||||||
return Cmd;
|
|
||||||
|
|
||||||
current.classList.toggle(SELECTED_FILE);
|
|
||||||
|
|
||||||
return Cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toggleAllSelectedFiles() {
|
|
||||||
DOM
|
|
||||||
.getAllFiles()
|
|
||||||
.map(DOM.toggleSelectedFile);
|
|
||||||
|
|
||||||
return Cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function selectAllFiles() {
|
|
||||||
DOM
|
|
||||||
.getAllFiles()
|
|
||||||
.map(DOM.selectFile);
|
|
||||||
|
|
||||||
return Cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* unified way to get selected files
|
|
||||||
*
|
|
||||||
* @currentFile
|
|
||||||
*/
|
|
||||||
export function getSelectedFiles() {
|
|
||||||
const panel = DOM.getPanel();
|
|
||||||
const selected = DOM.getByClassAll(SELECTED_FILE, panel);
|
|
||||||
|
|
||||||
return Array.from(selected);
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
/* global DOM */
|
/* global DOM */
|
||||||
/* global CloudCmd */
|
/* global CloudCmd */
|
||||||
import createElement from '@cloudcmd/create-element';
|
import createElement from '@cloudcmd/create-element';
|
||||||
import {getTitle, FS} from '#common/cloudfunc';
|
import {encode, decode} from '../../common/entity.js';
|
||||||
import {encode, decode} from '#common/entity';
|
import {getTitle, FS} from '../../common/cloudfunc.mjs';
|
||||||
|
|
||||||
let Title;
|
let Title;
|
||||||
|
|
||||||
|
|
@ -77,7 +77,7 @@ const parseHrefAttribute = (prefix, attribute) => {
|
||||||
export const _parseHrefAttribute = parseHrefAttribute;
|
export const _parseHrefAttribute = parseHrefAttribute;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get current directory path
|
* get current direcotory path
|
||||||
*/
|
*/
|
||||||
export const getCurrentDirPath = (panel = DOM.getPanel()) => {
|
export const getCurrentDirPath = (panel = DOM.getPanel()) => {
|
||||||
const path = DOM.getByDataName('js-path', panel);
|
const path = DOM.getByDataName('js-path', panel);
|
||||||
|
|
@ -98,7 +98,7 @@ export const getCurrentPath = (currentFile) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get current directory name
|
* get current direcotory name
|
||||||
*/
|
*/
|
||||||
export const getCurrentDirName = () => {
|
export const getCurrentDirName = () => {
|
||||||
const href = DOM
|
const href = DOM
|
||||||
|
|
@ -111,7 +111,7 @@ export const getCurrentDirName = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get current directory path
|
* get current direcotory path
|
||||||
*/
|
*/
|
||||||
export const getParentDirPath = (panel) => {
|
export const getParentDirPath = (panel) => {
|
||||||
const path = DOM.getCurrentDirPath(panel);
|
const path = DOM.getCurrentDirPath(panel);
|
||||||
|
|
@ -125,7 +125,7 @@ export const getParentDirPath = (panel) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get not current directory path
|
* get not current direcotory path
|
||||||
*/
|
*/
|
||||||
export const getNotCurrentDirPath = () => {
|
export const getNotCurrentDirPath = () => {
|
||||||
const panel = DOM.getPanel({
|
const panel = DOM.getPanel({
|
||||||
|
|
@ -153,7 +153,7 @@ export const getCurrentByName = (name, panel = DOM.CurrentInfo.panel) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* private function that unset currentFile
|
* private function thet unset currentfile
|
||||||
*
|
*
|
||||||
* @currentFile
|
* @currentFile
|
||||||
*/
|
*/
|
||||||
|
|
@ -302,7 +302,6 @@ export const isCurrentIsDir = (currentFile) => {
|
||||||
export const getCurrentType = (currentFile) => {
|
export const getCurrentType = (currentFile) => {
|
||||||
const current = currentFile || DOM.getCurrentFile();
|
const current = currentFile || DOM.getCurrentFile();
|
||||||
const el = DOM.getByDataName('js-type', current);
|
const el = DOM.getByDataName('js-type', current);
|
||||||
|
|
||||||
const type = el.className
|
const type = el.className
|
||||||
.split(' ')
|
.split(' ')
|
||||||
.pop();
|
.pop();
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import {test, stub} from 'supertape';
|
import {test, stub} from 'supertape';
|
||||||
import {create} from 'auto-globals';
|
import {create} from 'auto-globals';
|
||||||
import wraptile from 'wraptile';
|
import wraptile from 'wraptile';
|
||||||
import * as currentFile from './current-file.js';
|
import * as currentFile from './current-file.mjs';
|
||||||
|
|
||||||
const id = (a) => a;
|
const id = (a) => a;
|
||||||
|
|
||||||
|
|
@ -19,13 +19,11 @@ test('current-file: setCurrentName: setAttribute', (t) => {
|
||||||
|
|
||||||
currentFile.setCurrentName('hello', current);
|
currentFile.setCurrentName('hello', current);
|
||||||
|
|
||||||
|
t.calledWith(setAttribute, ['data-name', 'js-file-aGVsbG8='], 'should call setAttribute');
|
||||||
|
|
||||||
globalThis.DOM = DOM;
|
globalThis.DOM = DOM;
|
||||||
globalThis.CloudCmd = CloudCmd;
|
globalThis.CloudCmd = CloudCmd;
|
||||||
|
|
||||||
t.calledWith(setAttribute, [
|
|
||||||
'data-name',
|
|
||||||
'js-file-aGVsbG8=',
|
|
||||||
], 'should call setAttribute');
|
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -40,13 +38,11 @@ test('current-file: setCurrentName: setAttribute: cyrillic', (t) => {
|
||||||
|
|
||||||
currentFile.setCurrentName('ай', current);
|
currentFile.setCurrentName('ай', current);
|
||||||
|
|
||||||
|
t.calledWith(setAttribute, ['data-name', 'js-file-JUQwJUIwJUQwJUI5'], 'should call setAttribute');
|
||||||
|
|
||||||
globalThis.DOM = DOM;
|
globalThis.DOM = DOM;
|
||||||
globalThis.CloudCmd = CloudCmd;
|
globalThis.CloudCmd = CloudCmd;
|
||||||
|
|
||||||
t.calledWith(setAttribute, [
|
|
||||||
'data-name',
|
|
||||||
'js-file-JUQwJUIwJUQwJUI5',
|
|
||||||
], 'should call setAttribute');
|
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -74,10 +70,11 @@ test('current-file: emit', (t) => {
|
||||||
|
|
||||||
currentFile.setCurrentName('hello', current);
|
currentFile.setCurrentName('hello', current);
|
||||||
|
|
||||||
|
t.calledWith(emit, ['current-file', current], 'should call emit');
|
||||||
|
|
||||||
globalThis.DOM = DOM;
|
globalThis.DOM = DOM;
|
||||||
globalThis.CloudCmd = CloudCmd;
|
globalThis.CloudCmd = CloudCmd;
|
||||||
|
|
||||||
t.calledWith(emit, ['current-file', current], 'should call emit');
|
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -93,12 +90,14 @@ test('current-file: setCurrentName: return', (t) => {
|
||||||
globalThis.CloudCmd = getCloudCmd();
|
globalThis.CloudCmd = getCloudCmd();
|
||||||
|
|
||||||
const current = create();
|
const current = create();
|
||||||
|
|
||||||
const result = currentFile.setCurrentName('hello', current);
|
const result = currentFile.setCurrentName('hello', current);
|
||||||
|
|
||||||
|
t.equal(result, link, 'should return link');
|
||||||
|
|
||||||
globalThis.DOM = DOM;
|
globalThis.DOM = DOM;
|
||||||
globalThis.CloudCmd = CloudCmd;
|
globalThis.CloudCmd = CloudCmd;
|
||||||
|
|
||||||
t.equal(result, link, 'should return link');
|
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1,18 +1,26 @@
|
||||||
import {tryToCatch} from 'try-to-catch';
|
'use strict';
|
||||||
import * as smalltalk from 'smalltalk';
|
|
||||||
|
const {tryToCatch} = require('try-to-catch');
|
||||||
|
|
||||||
|
const {
|
||||||
|
alert,
|
||||||
|
prompt,
|
||||||
|
confirm,
|
||||||
|
progress,
|
||||||
|
} = require('smalltalk');
|
||||||
|
|
||||||
const title = 'Cloud Commander';
|
const title = 'Cloud Commander';
|
||||||
|
|
||||||
export const alert = (...a) => smalltalk.alert(title, ...a, {
|
module.exports.alert = (...a) => alert(title, ...a, {
|
||||||
cancel: false,
|
cancel: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const prompt = (...a) => tryToCatch(smalltalk.prompt, title, ...a);
|
module.exports.prompt = (...a) => tryToCatch(prompt, title, ...a);
|
||||||
export const confirm = (...a) => tryToCatch(smalltalk.confirm, title, ...a);
|
module.exports.confirm = (...a) => tryToCatch(confirm, title, ...a);
|
||||||
export const progress = (...a) => smalltalk.progress(title, ...a);
|
module.exports.progress = (...a) => progress(title, ...a);
|
||||||
|
|
||||||
alert.noFiles = () => {
|
module.exports.alert.noFiles = () => {
|
||||||
return smalltalk.alert(title, 'No files selected!', {
|
return alert(title, 'No files selected!', {
|
||||||
cancel: false,
|
cancel: false,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,16 @@
|
||||||
/* global DOM, CloudCmd */
|
'use strict';
|
||||||
import philip from 'philip';
|
|
||||||
import * as Dialog from '#dom/dialog';
|
|
||||||
import {FS} from '#common/cloudfunc';
|
|
||||||
import * as Images from '#dom/images';
|
|
||||||
|
|
||||||
export const uploadDirectory = (items) => {
|
/* global CloudCmd */
|
||||||
|
const philip = require('philip');
|
||||||
|
|
||||||
|
const Images = require('./images.mjs');
|
||||||
|
const {FS} = require('../../common/cloudfunc.mjs');
|
||||||
|
const DOM = require('.');
|
||||||
|
const Dialog = require('./dialog');
|
||||||
|
|
||||||
|
const {getCurrentDirPath: getPathWhenRootEmpty} = DOM;
|
||||||
|
|
||||||
|
module.exports = (items) => {
|
||||||
if (items.length)
|
if (items.length)
|
||||||
Images.show('top');
|
Images.show('top');
|
||||||
|
|
||||||
|
|
@ -12,7 +18,7 @@ export const uploadDirectory = (items) => {
|
||||||
.from(items)
|
.from(items)
|
||||||
.map((item) => item.webkitGetAsEntry());
|
.map((item) => item.webkitGetAsEntry());
|
||||||
|
|
||||||
const dirPath = DOM.getCurrentDirPath();
|
const dirPath = getPathWhenRootEmpty();
|
||||||
const path = dirPath.replace(/\/$/, '');
|
const path = dirPath.replace(/\/$/, '');
|
||||||
|
|
||||||
const progress = Dialog.progress('Uploading...');
|
const progress = Dialog.progress('Uploading...');
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,8 @@
|
||||||
import currify from 'currify';
|
'use strict';
|
||||||
|
|
||||||
const DOM = {
|
const currify = require('currify');
|
||||||
show,
|
|
||||||
hide,
|
const DOM = module.exports;
|
||||||
getByClass,
|
|
||||||
getByClassAll,
|
|
||||||
getByDataName,
|
|
||||||
getById,
|
|
||||||
getByTag,
|
|
||||||
isContainClass,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check class of element
|
* check class of element
|
||||||
|
|
@ -17,7 +10,7 @@ const DOM = {
|
||||||
* @param element
|
* @param element
|
||||||
* @param className
|
* @param className
|
||||||
*/
|
*/
|
||||||
export function isContainClass(element, className) {
|
const isContainClass = (element, className) => {
|
||||||
if (!element)
|
if (!element)
|
||||||
throw Error('element could not be empty!');
|
throw Error('element could not be empty!');
|
||||||
|
|
||||||
|
|
@ -33,60 +26,58 @@ export function isContainClass(element, className) {
|
||||||
const {classList} = element;
|
const {classList} = element;
|
||||||
|
|
||||||
return classList.contains(className);
|
return classList.contains(className);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
module.exports.isContainClass = isContainClass;
|
||||||
/**
|
/**
|
||||||
* Function search element by tag
|
* Function search element by tag
|
||||||
* @param tag - className
|
* @param tag - className
|
||||||
* @param element - element
|
* @param element - element
|
||||||
*/
|
*/
|
||||||
export function getByTag(tag, element = document) {
|
module.exports.getByTag = (tag, element = document) => {
|
||||||
return element.getElementsByTagName(tag);
|
return element.getElementsByTagName(tag);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function search element by id
|
* Function search element by id
|
||||||
* @param id
|
* @param Id - id
|
||||||
* @param element
|
|
||||||
*/
|
*/
|
||||||
export function getById(id, element = document) {
|
module.exports.getById = (id, element = document) => {
|
||||||
return element.querySelector(`#${id}`);
|
return element.querySelector(`#${id}`);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function search first element by class name
|
* Function search first element by class name
|
||||||
* @param className - className
|
* @param className - className
|
||||||
* @param element - element
|
* @param element - element
|
||||||
*/
|
*/
|
||||||
export function getByClass(className, element = document) {
|
module.exports.getByClass = (className, element = document) => DOM.getByClassAll(className, element)[0];
|
||||||
return DOM.getByClassAll(className, element)[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getByDataName(attribute, element = document) {
|
module.exports.getByDataName = (attribute, element = document) => {
|
||||||
const selector = '[' + 'data-name="' + attribute + '"]';
|
const selector = '[' + 'data-name="' + attribute + '"]';
|
||||||
return element.querySelector(selector);
|
return element.querySelector(selector);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function search element by class name
|
* Function search element by class name
|
||||||
* @param className
|
* @param pClass - className
|
||||||
* @param element
|
* @param element - element
|
||||||
*/
|
*/
|
||||||
export function getByClassAll(className, element) {
|
module.exports.getByClassAll = (className, element) => {
|
||||||
return (element || document).getElementsByClassName(className);
|
return (element || document).getElementsByClassName(className);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add class=hidden to element
|
* add class=hidden to element
|
||||||
*
|
*
|
||||||
* @param element
|
* @param element
|
||||||
*/
|
*/
|
||||||
export function hide(element) {
|
module.exports.hide = (element) => {
|
||||||
element.classList.add('hidden');
|
element.classList.add('hidden');
|
||||||
return DOM;
|
return DOM;
|
||||||
}
|
};
|
||||||
|
|
||||||
export function show(element) {
|
module.exports.show = (element) => {
|
||||||
element.classList.remove('hidden');
|
element.classList.remove('hidden');
|
||||||
return DOM;
|
return DOM;
|
||||||
}
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,10 @@
|
||||||
import {test, stub} from 'supertape';
|
'use strict';
|
||||||
import {create} from 'auto-globals';
|
|
||||||
import {tryCatch} from 'try-catch';
|
const test = require('supertape');
|
||||||
import {
|
const {create} = require('auto-globals');
|
||||||
isContainClass,
|
const {tryCatch} = require('try-catch');
|
||||||
getByTag,
|
|
||||||
getById,
|
const {isContainClass} = require('./dom-tree');
|
||||||
getByClass,
|
|
||||||
getByDataName,
|
|
||||||
getByClassAll,
|
|
||||||
hide,
|
|
||||||
show,
|
|
||||||
} from './dom-tree.js';
|
|
||||||
|
|
||||||
test('dom: isContainClass: no element', (t) => {
|
test('dom: isContainClass: no element', (t) => {
|
||||||
const [e] = tryCatch(isContainClass);
|
const [e] = tryCatch(isContainClass);
|
||||||
|
|
@ -47,106 +41,3 @@ test('dom: isContainClass: contains: array', (t) => {
|
||||||
t.calledWith(contains, [className], 'should call contains');
|
t.calledWith(contains, [className], 'should call contains');
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dom: getByTag', (t) => {
|
|
||||||
const getElementsByTagName = stub();
|
|
||||||
const element = {
|
|
||||||
getElementsByTagName,
|
|
||||||
};
|
|
||||||
|
|
||||||
getByTag('div', element);
|
|
||||||
|
|
||||||
t.calledWith(getElementsByTagName, ['div'], 'should call getElementsByTagName');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('dom: getById', (t) => {
|
|
||||||
const querySelector = stub();
|
|
||||||
const element = {
|
|
||||||
querySelector,
|
|
||||||
};
|
|
||||||
|
|
||||||
getById('my-id', element);
|
|
||||||
|
|
||||||
t.calledWith(querySelector, ['#my-id'], 'should call querySelector with id selector');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('dom: getByClassAll', (t) => {
|
|
||||||
const getElementsByClassName = stub();
|
|
||||||
const element = {
|
|
||||||
getElementsByClassName,
|
|
||||||
};
|
|
||||||
|
|
||||||
getByClassAll('my-class', element);
|
|
||||||
|
|
||||||
t.calledWith(getElementsByClassName, ['my-class'], 'should call getElementsByClassName');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('dom: getByClass: calls getByClassAll', (t) => {
|
|
||||||
const element = {
|
|
||||||
getElementsByClassName: stub().returns(['first']),
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = getByClass('my-class', element);
|
|
||||||
|
|
||||||
t.equal(result, 'first', 'should return first element from class list');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('dom: getByDataName', (t) => {
|
|
||||||
const querySelector = stub();
|
|
||||||
const element = {
|
|
||||||
querySelector,
|
|
||||||
};
|
|
||||||
|
|
||||||
getByDataName('hello', element);
|
|
||||||
|
|
||||||
t.calledWith(querySelector, ['[data-name="hello"]'], 'should call querySelector with data-name selector');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('dom: hide', (t) => {
|
|
||||||
const add = stub();
|
|
||||||
const element = {
|
|
||||||
classList: {
|
|
||||||
add,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
hide(element);
|
|
||||||
|
|
||||||
t.calledWith(add, ['hidden'], 'should add hidden class');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('dom: show', (t) => {
|
|
||||||
const remove = stub();
|
|
||||||
const element = {
|
|
||||||
classList: {
|
|
||||||
remove,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
show(element);
|
|
||||||
|
|
||||||
t.calledWith(remove, ['hidden'], 'should remove hidden class');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('dom: getByClassAll: without element uses document', (t) => {
|
|
||||||
const getElementsByClassName = stub();
|
|
||||||
const prevDocument = globalThis.document;
|
|
||||||
|
|
||||||
globalThis.document = {
|
|
||||||
getElementsByClassName,
|
|
||||||
};
|
|
||||||
|
|
||||||
getByClassAll('my-class');
|
|
||||||
|
|
||||||
globalThis.document = prevDocument;
|
|
||||||
|
|
||||||
t.calledWith(getElementsByClassName, ['my-class'], 'should fallback to document when no element');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
let list = [];
|
let list = [];
|
||||||
|
|
||||||
export const add = (el, name, fn) => {
|
module.exports.add = (el, name, fn) => {
|
||||||
list.push([
|
list.push([
|
||||||
el,
|
el,
|
||||||
name,
|
name,
|
||||||
|
|
@ -8,8 +10,8 @@ export const add = (el, name, fn) => {
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const clear = () => {
|
module.exports.clear = () => {
|
||||||
list = [];
|
list = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const get = () => list;
|
module.exports.get = () => list;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
import {test} from 'supertape';
|
'use strict';
|
||||||
import * as eventStore from './event-store.js';
|
|
||||||
|
const test = require('supertape');
|
||||||
|
const eventStore = require('./event-store');
|
||||||
|
|
||||||
test('event-store: get', (t) => {
|
test('event-store: get', (t) => {
|
||||||
const el = {};
|
const el = {};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import itype from 'itype';
|
import itype from 'itype';
|
||||||
import * as EventStore from './event-store.js';
|
import EventStore from './event-store.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* safe add event listener
|
* safe add event listener
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
/* global CloudCmd */
|
/* global CloudCmd */
|
||||||
import itype from 'itype';
|
const itype = require('itype');
|
||||||
import {promisify} from 'es6-promisify';
|
const {promisify} = require('es6-promisify');
|
||||||
import * as load from '#dom/load';
|
|
||||||
import * as RESTful from '#dom/rest';
|
const load = require('./load');
|
||||||
|
const RESTful = require('./rest');
|
||||||
|
|
||||||
const Promises = {};
|
const Promises = {};
|
||||||
const FILES_JSON = 'config|modules';
|
const FILES_JSON = 'config|modules';
|
||||||
|
|
@ -13,7 +16,7 @@ const DIR_HTML_FS = `${DIR_HTML}fs/`;
|
||||||
const DIR_JSON = '/json/';
|
const DIR_JSON = '/json/';
|
||||||
const timeout = getTimeoutOnce(2000);
|
const timeout = getTimeoutOnce(2000);
|
||||||
|
|
||||||
export const get = getFile;
|
module.exports.get = getFile;
|
||||||
|
|
||||||
function getFile(name) {
|
function getFile(name) {
|
||||||
const type = itype(name);
|
const type = itype(name);
|
||||||
|
|
|
||||||
|
|
@ -102,13 +102,13 @@ export function show(position, panel) {
|
||||||
/**
|
/**
|
||||||
* hide load image
|
* hide load image
|
||||||
*/
|
*/
|
||||||
export function hide() {
|
export const hide = () => {
|
||||||
const element = Images.get();
|
const element = Images.get();
|
||||||
|
|
||||||
DOM.hide(element);
|
DOM.hide(element);
|
||||||
|
|
||||||
return Images;
|
return Images;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const setProgress = (value, title) => {
|
export const setProgress = (value, title) => {
|
||||||
const DATA = 'data-progress';
|
const DATA = 'data-progress';
|
||||||
|
|
@ -1,121 +1,70 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
/* global CloudCmd */
|
/* global CloudCmd */
|
||||||
import * as load from '#dom/load';
|
const Util = require('../../common/util');
|
||||||
import * as Files from '#dom/files';
|
|
||||||
import * as Dialog from '#dom/dialog';
|
|
||||||
import * as Events from '#dom/events';
|
|
||||||
import {getExt} from '#common/util';
|
|
||||||
import * as Storage from '#dom/storage';
|
|
||||||
import * as RESTful from '#dom/rest';
|
|
||||||
import * as Images from '#dom/images';
|
|
||||||
import renameCurrent from './operations/rename-current.js';
|
|
||||||
import * as CurrentFile from './current-file.js';
|
|
||||||
import * as DOMTree from './dom-tree.js';
|
|
||||||
import * as Cmd from './cmd.js';
|
|
||||||
import * as IO from './io/index.js';
|
|
||||||
import {uploadDirectory} from './directory.js';
|
|
||||||
import * as Buffer from './buffer.js';
|
|
||||||
import {loadRemote as _loadRemote} from './load-remote.js';
|
|
||||||
import {selectByPattern} from './select-by-pattern.js';
|
|
||||||
|
|
||||||
const {assign} = Object;
|
const Images = require('./images.mjs');
|
||||||
|
const RESTful = require('./rest');
|
||||||
|
const Storage = require('./storage');
|
||||||
|
const renameCurrent = require('./operations/rename-current');
|
||||||
|
|
||||||
|
const CurrentFile = require('./current-file.mjs');
|
||||||
|
const DOMTree = require('./dom-tree');
|
||||||
|
|
||||||
|
const Cmd = module.exports;
|
||||||
const DOM = {
|
const DOM = {
|
||||||
getCurrentDirName,
|
|
||||||
getNotCurrentDirPath,
|
|
||||||
getParentDirPath,
|
|
||||||
loadRemote,
|
|
||||||
loadSocket,
|
|
||||||
promptNewDir,
|
|
||||||
promptNewFile,
|
|
||||||
unselectFiles,
|
|
||||||
getActiveFiles,
|
|
||||||
getCurrentDate,
|
|
||||||
getCurrentSize,
|
|
||||||
loadCurrentSize,
|
|
||||||
loadCurrentHash,
|
|
||||||
setCurrentSize,
|
|
||||||
getCurrentMode,
|
|
||||||
getCurrentOwner,
|
|
||||||
getCurrentData,
|
|
||||||
getRefreshButton,
|
|
||||||
getAllFiles,
|
|
||||||
expandSelection,
|
|
||||||
shrinkSelection,
|
|
||||||
setHistory,
|
|
||||||
getCurrentLink,
|
|
||||||
getFilenames,
|
|
||||||
checkStorageHash,
|
|
||||||
saveDataToStorage,
|
|
||||||
getFM,
|
|
||||||
getPanelPosition,
|
|
||||||
getCSSVar,
|
|
||||||
getPanel,
|
|
||||||
getFiles,
|
|
||||||
showPanel,
|
|
||||||
hidePanel,
|
|
||||||
remove,
|
|
||||||
deleteCurrent,
|
|
||||||
deleteSelected,
|
|
||||||
renameCurrent,
|
|
||||||
scrollIntoViewIfNeeded,
|
|
||||||
scrollByPages,
|
|
||||||
changePanel,
|
|
||||||
getPackerExt,
|
|
||||||
goToDirectory,
|
|
||||||
duplicatePanel,
|
|
||||||
swapPanels,
|
|
||||||
updateCurrentInfo,
|
|
||||||
};
|
|
||||||
|
|
||||||
assign(DOM, {
|
|
||||||
...DOMTree,
|
...DOMTree,
|
||||||
...CurrentFile,
|
...CurrentFile,
|
||||||
...Cmd,
|
...Cmd,
|
||||||
});
|
};
|
||||||
|
|
||||||
export const CurrentInfo = {};
|
const CurrentInfo = {};
|
||||||
|
|
||||||
DOM.Images = Images;
|
DOM.Images = Images;
|
||||||
DOM.load = load;
|
DOM.load = require('./load');
|
||||||
DOM.Files = Files;
|
DOM.Files = require('./files');
|
||||||
DOM.RESTful = RESTful;
|
DOM.RESTful = RESTful;
|
||||||
DOM.IO = IO;
|
DOM.IO = require('./io');
|
||||||
DOM.Storage = Storage;
|
DOM.Storage = Storage;
|
||||||
DOM.Dialog = Dialog;
|
DOM.Dialog = require('./dialog');
|
||||||
DOM.CurrentInfo = CurrentInfo;
|
DOM.CurrentInfo = CurrentInfo;
|
||||||
|
|
||||||
export default DOM;
|
module.exports = DOM;
|
||||||
|
|
||||||
DOM.uploadDirectory = uploadDirectory;
|
DOM.uploadDirectory = require('./directory');
|
||||||
DOM.Buffer = Buffer;
|
DOM.Buffer = require('./buffer.mjs');
|
||||||
DOM.Events = Events;
|
DOM.Events = require('#dom/events');
|
||||||
|
|
||||||
|
const loadRemote = require('./load-remote');
|
||||||
|
const selectByPattern = require('./select-by-pattern');
|
||||||
const isString = (a) => typeof a === 'string';
|
const isString = (a) => typeof a === 'string';
|
||||||
|
const SELECTED_FILE = 'selected-file';
|
||||||
|
|
||||||
const TabPanel = {
|
const TabPanel = {
|
||||||
'js-left': null,
|
'js-left': null,
|
||||||
'js-right': null,
|
'js-right': null,
|
||||||
};
|
};
|
||||||
|
|
||||||
export function loadRemote(name, options, callback) {
|
module.exports.loadRemote = (name, options, callback) => {
|
||||||
_loadRemote(name, options, callback);
|
loadRemote(name, options, callback);
|
||||||
return DOM;
|
return DOM;
|
||||||
}
|
};
|
||||||
|
|
||||||
export function loadSocket(callback) {
|
module.exports.loadSocket = (callback) => {
|
||||||
DOM.loadRemote('socket', {
|
DOM.loadRemote('socket', {
|
||||||
name: 'io',
|
name: 'io',
|
||||||
}, callback);
|
}, callback);
|
||||||
|
|
||||||
return DOM;
|
return DOM;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create new folder
|
* create new folder
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export async function promptNewDir() {
|
module.exports.promptNewDir = async function() {
|
||||||
await promptNew('directory');
|
await promptNew('directory');
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create new file
|
* create new file
|
||||||
|
|
@ -123,9 +72,9 @@ export async function promptNewDir() {
|
||||||
* @typeName
|
* @typeName
|
||||||
* @type
|
* @type
|
||||||
*/
|
*/
|
||||||
export async function promptNewFile() {
|
module.exports.promptNewFile = async () => {
|
||||||
await promptNew('file');
|
await promptNew('file');
|
||||||
}
|
};
|
||||||
|
|
||||||
async function promptNew(typeName) {
|
async function promptNew(typeName) {
|
||||||
const {Dialog} = DOM;
|
const {Dialog} = DOM;
|
||||||
|
|
@ -160,9 +109,9 @@ async function promptNew(typeName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get current directory name
|
* get current direcotory name
|
||||||
*/
|
*/
|
||||||
export function getCurrentDirName() {
|
module.exports.getCurrentDirName = () => {
|
||||||
const href = DOM
|
const href = DOM
|
||||||
.getCurrentDirPath()
|
.getCurrentDirPath()
|
||||||
.replace(/\/$/, '');
|
.replace(/\/$/, '');
|
||||||
|
|
@ -170,12 +119,12 @@ export function getCurrentDirName() {
|
||||||
const substr = href.substr(href, href.lastIndexOf('/'));
|
const substr = href.substr(href, href.lastIndexOf('/'));
|
||||||
|
|
||||||
return href.replace(`${substr}/`, '') || '/';
|
return href.replace(`${substr}/`, '') || '/';
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get current directory path
|
* get current direcotory path
|
||||||
*/
|
*/
|
||||||
export function getParentDirPath(panel) {
|
module.exports.getParentDirPath = (panel) => {
|
||||||
const path = DOM.getCurrentDirPath(panel);
|
const path = DOM.getCurrentDirPath(panel);
|
||||||
const dirName = DOM.getCurrentDirName() + '/';
|
const dirName = DOM.getCurrentDirName() + '/';
|
||||||
const index = path.lastIndexOf(dirName);
|
const index = path.lastIndexOf(dirName);
|
||||||
|
|
@ -184,36 +133,48 @@ export function getParentDirPath(panel) {
|
||||||
return path.slice(0, index);
|
return path.slice(0, index);
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get not current directory path
|
* get not current direcotory path
|
||||||
*/
|
*/
|
||||||
export function getNotCurrentDirPath() {
|
module.exports.getNotCurrentDirPath = () => {
|
||||||
const panel = DOM.getPanel({
|
const panel = DOM.getPanel({
|
||||||
active: false,
|
active: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
return DOM.getCurrentDirPath(panel);
|
return DOM.getCurrentDirPath(panel);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unified way to get selected files
|
||||||
|
*
|
||||||
|
* @currentFile
|
||||||
|
*/
|
||||||
|
module.exports.getSelectedFiles = () => {
|
||||||
|
const panel = DOM.getPanel();
|
||||||
|
const selected = DOM.getByClassAll(SELECTED_FILE, panel);
|
||||||
|
|
||||||
|
return Array.from(selected);
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* unselect all files
|
* unselect all files
|
||||||
*/
|
*/
|
||||||
export function unselectFiles(files) {
|
module.exports.unselectFiles = (files) => {
|
||||||
files = files || DOM.getSelectedFiles();
|
files = files || DOM.getSelectedFiles();
|
||||||
|
|
||||||
Array
|
Array
|
||||||
.from(files)
|
.from(files)
|
||||||
.forEach(DOM.toggleSelectedFile);
|
.forEach(DOM.toggleSelectedFile);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get all selected files or current when none selected
|
* get all selected files or current when none selected
|
||||||
*
|
*
|
||||||
* @currentFile
|
* @currentFile
|
||||||
*/
|
*/
|
||||||
export function getActiveFiles() {
|
module.exports.getActiveFiles = () => {
|
||||||
const current = DOM.getCurrentFile();
|
const current = DOM.getCurrentFile();
|
||||||
const files = DOM.getSelectedFiles();
|
const files = DOM.getSelectedFiles();
|
||||||
const name = DOM.getCurrentName(current);
|
const name = DOM.getCurrentName(current);
|
||||||
|
|
@ -222,19 +183,19 @@ export function getActiveFiles() {
|
||||||
return [current];
|
return [current];
|
||||||
|
|
||||||
return files;
|
return files;
|
||||||
}
|
};
|
||||||
|
|
||||||
export function getCurrentDate(currentFile) {
|
module.exports.getCurrentDate = (currentFile) => {
|
||||||
const current = currentFile || DOM.getCurrentFile();
|
const current = currentFile || DOM.getCurrentFile();
|
||||||
|
|
||||||
return DOM.getByDataName('js-date', current).textContent;
|
return DOM.getByDataName('js-date', current).textContent;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get size
|
* get size
|
||||||
* @currentFile
|
* @currentFile
|
||||||
*/
|
*/
|
||||||
export function getCurrentSize(currentFile) {
|
module.exports.getCurrentSize = (currentFile) => {
|
||||||
const current = currentFile || DOM.getCurrentFile();
|
const current = currentFile || DOM.getCurrentFile();
|
||||||
|
|
||||||
/* если это папка - возвращаем слово dir вместо размера*/
|
/* если это папка - возвращаем слово dir вместо размера*/
|
||||||
|
|
@ -244,13 +205,13 @@ export function getCurrentSize(currentFile) {
|
||||||
.replace(/^<|>$/g, '');
|
.replace(/^<|>$/g, '');
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get size
|
* get size
|
||||||
* @currentFile
|
* @currentFile
|
||||||
*/
|
*/
|
||||||
export async function loadCurrentSize(currentFile) {
|
module.exports.loadCurrentSize = async (currentFile) => {
|
||||||
const current = currentFile || DOM.getCurrentFile();
|
const current = currentFile || DOM.getCurrentFile();
|
||||||
const query = '?size';
|
const query = '?size';
|
||||||
const link = DOM.getCurrentPath(current);
|
const link = DOM.getCurrentPath(current);
|
||||||
|
|
@ -266,14 +227,14 @@ export async function loadCurrentSize(currentFile) {
|
||||||
Images.hide();
|
Images.hide();
|
||||||
|
|
||||||
return current;
|
return current;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* load hash
|
* load hash
|
||||||
* @callback
|
* @callback
|
||||||
* @currentFile
|
* @currentFile
|
||||||
*/
|
*/
|
||||||
export async function loadCurrentHash(currentFile) {
|
module.exports.loadCurrentHash = async (currentFile) => {
|
||||||
const current = currentFile || DOM.getCurrentFile();
|
const current = currentFile || DOM.getCurrentFile();
|
||||||
const query = '?hash';
|
const query = '?hash';
|
||||||
const link = DOM.getCurrentPath(current);
|
const link = DOM.getCurrentPath(current);
|
||||||
|
|
@ -281,45 +242,45 @@ export async function loadCurrentHash(currentFile) {
|
||||||
const [, data] = await RESTful.read(link + query);
|
const [, data] = await RESTful.read(link + query);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set size
|
* set size
|
||||||
* @currentFile
|
* @currentFile
|
||||||
*/
|
*/
|
||||||
export function setCurrentSize(size, currentFile) {
|
module.exports.setCurrentSize = (size, currentFile) => {
|
||||||
const current = currentFile || DOM.getCurrentFile();
|
const current = currentFile || DOM.getCurrentFile();
|
||||||
const sizeElement = DOM.getByDataName('js-size', current);
|
const sizeElement = DOM.getByDataName('js-size', current);
|
||||||
|
|
||||||
sizeElement.textContent = size;
|
sizeElement.textContent = size;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @currentFile
|
* @currentFile
|
||||||
*/
|
*/
|
||||||
export function getCurrentMode(currentFile) {
|
module.exports.getCurrentMode = (currentFile) => {
|
||||||
const current = currentFile || DOM.getCurrentFile();
|
const current = currentFile || DOM.getCurrentFile();
|
||||||
const mode = DOM.getByDataName('js-mode', current);
|
const mode = DOM.getByDataName('js-mode', current);
|
||||||
|
|
||||||
return mode.textContent;
|
return mode.textContent;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @currentFile
|
* @currentFile
|
||||||
*/
|
*/
|
||||||
export function getCurrentOwner(currentFile) {
|
module.exports.getCurrentOwner = (currentFile) => {
|
||||||
const current = currentFile || DOM.getCurrentFile();
|
const current = currentFile || DOM.getCurrentFile();
|
||||||
const owner = DOM.getByDataName('js-owner', current);
|
const owner = DOM.getByDataName('js-owner', current);
|
||||||
|
|
||||||
return owner.textContent;
|
return owner.textContent;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* unified way to get current file content
|
* unified way to get current file content
|
||||||
*
|
*
|
||||||
* @param currentFile
|
* @param currentFile
|
||||||
*/
|
*/
|
||||||
export async function getCurrentData(currentFile) {
|
module.exports.getCurrentData = async (currentFile) => {
|
||||||
const {Dialog} = DOM;
|
const {Dialog} = DOM;
|
||||||
const Info = DOM.CurrentInfo;
|
const Info = DOM.CurrentInfo;
|
||||||
const current = currentFile || DOM.getCurrentFile();
|
const current = currentFile || DOM.getCurrentFile();
|
||||||
|
|
@ -361,16 +322,64 @@ export async function getCurrentData(currentFile) {
|
||||||
await DOM.saveDataToStorage(path, data, hashNew);
|
await DOM.saveDataToStorage(path, data, hashNew);
|
||||||
|
|
||||||
return [null, data];
|
return [null, data];
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* unified way to get RefreshButton
|
* unified way to get RefreshButton
|
||||||
*/
|
*/
|
||||||
export function getRefreshButton(panel = DOM.getPanel()) {
|
module.exports.getRefreshButton = (panel = DOM.getPanel()) => {
|
||||||
return DOM.getByDataName('js-refresh', panel);
|
return DOM.getByDataName('js-refresh', panel);
|
||||||
}
|
};
|
||||||
|
|
||||||
export function getAllFiles() {
|
/**
|
||||||
|
* select current file
|
||||||
|
* @param currentFile
|
||||||
|
*/
|
||||||
|
module.exports.selectFile = (currentFile) => {
|
||||||
|
const current = currentFile || DOM.getCurrentFile();
|
||||||
|
|
||||||
|
current.classList.add(SELECTED_FILE);
|
||||||
|
|
||||||
|
return Cmd;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.unselectFile = (currentFile) => {
|
||||||
|
const current = currentFile || DOM.getCurrentFile();
|
||||||
|
|
||||||
|
current.classList.remove(SELECTED_FILE);
|
||||||
|
|
||||||
|
return Cmd;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.toggleSelectedFile = (currentFile) => {
|
||||||
|
const current = currentFile || DOM.getCurrentFile();
|
||||||
|
const name = DOM.getCurrentName(current);
|
||||||
|
|
||||||
|
if (name === '..')
|
||||||
|
return Cmd;
|
||||||
|
|
||||||
|
current.classList.toggle(SELECTED_FILE);
|
||||||
|
|
||||||
|
return Cmd;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.toggleAllSelectedFiles = () => {
|
||||||
|
DOM
|
||||||
|
.getAllFiles()
|
||||||
|
.map(DOM.toggleSelectedFile);
|
||||||
|
|
||||||
|
return Cmd;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.selectAllFiles = () => {
|
||||||
|
DOM
|
||||||
|
.getAllFiles()
|
||||||
|
.map(DOM.selectFile);
|
||||||
|
|
||||||
|
return Cmd;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.getAllFiles = () => {
|
||||||
const panel = DOM.getPanel();
|
const panel = DOM.getPanel();
|
||||||
const files = DOM.getFiles(panel);
|
const files = DOM.getFiles(panel);
|
||||||
const name = DOM.getCurrentName(files[0]);
|
const name = DOM.getCurrentName(files[0]);
|
||||||
|
|
@ -381,32 +390,32 @@ export function getAllFiles() {
|
||||||
return Array
|
return Array
|
||||||
.from(files)
|
.from(files)
|
||||||
.slice(i);
|
.slice(i);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* open dialog with expand selection
|
* open dialog with expand selection
|
||||||
*/
|
*/
|
||||||
export async function expandSelection() {
|
module.exports.expandSelection = () => {
|
||||||
const msg = 'expand';
|
const msg = 'expand';
|
||||||
const {files} = CurrentInfo;
|
const {files} = CurrentInfo;
|
||||||
|
|
||||||
await selectByPattern(msg, files);
|
selectByPattern(msg, files);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* open dialog with shrink selection
|
* open dialog with shrink selection
|
||||||
*/
|
*/
|
||||||
export async function shrinkSelection() {
|
module.exports.shrinkSelection = () => {
|
||||||
const msg = 'shrink';
|
const msg = 'shrink';
|
||||||
const {files} = CurrentInfo;
|
const {files} = CurrentInfo;
|
||||||
|
|
||||||
await selectByPattern(msg, files);
|
selectByPattern(msg, files);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* setting history wrapper
|
* setting history wrapper
|
||||||
*/
|
*/
|
||||||
export function setHistory(data, title, url) {
|
module.exports.setHistory = (data, title, url) => {
|
||||||
const ret = globalThis.history;
|
const ret = globalThis.history;
|
||||||
const {prefix} = CloudCmd;
|
const {prefix} = CloudCmd;
|
||||||
|
|
||||||
|
|
@ -416,21 +425,33 @@ export function setHistory(data, title, url) {
|
||||||
history.pushState(data, title, url);
|
history.pushState(data, title, url);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* selected file check
|
||||||
|
*
|
||||||
|
* @param currentFile
|
||||||
|
*/
|
||||||
|
module.exports.isSelected = (selected) => {
|
||||||
|
if (!selected)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return DOM.isContainClass(selected, SELECTED_FILE);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get link from current (or param) file
|
* get link from current (or param) file
|
||||||
*
|
*
|
||||||
* @param currentFile - current file by default
|
* @param currentFile - current file by default
|
||||||
*/
|
*/
|
||||||
export function getCurrentLink(currentFile) {
|
module.exports.getCurrentLink = (currentFile) => {
|
||||||
const current = currentFile || DOM.getCurrentFile();
|
const current = currentFile || DOM.getCurrentFile();
|
||||||
const link = DOM.getByTag('a', current);
|
const link = DOM.getByTag('a', current);
|
||||||
|
|
||||||
return link[0];
|
return link[0];
|
||||||
}
|
};
|
||||||
|
|
||||||
export function getFilenames(files) {
|
module.exports.getFilenames = (files) => {
|
||||||
if (!files)
|
if (!files)
|
||||||
throw Error('AllFiles could not be empty');
|
throw Error('AllFiles could not be empty');
|
||||||
|
|
||||||
|
|
@ -442,13 +463,17 @@ export function getFilenames(files) {
|
||||||
if (name === '..')
|
if (name === '..')
|
||||||
allFiles.shift();
|
allFiles.shift();
|
||||||
|
|
||||||
return allFiles.map(DOM.getCurrentName);
|
const names = allFiles.map((current) => {
|
||||||
}
|
return DOM.getCurrentName(current);
|
||||||
|
});
|
||||||
|
|
||||||
|
return names;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check storage hash
|
* check storage hash
|
||||||
*/
|
*/
|
||||||
export async function checkStorageHash(name) {
|
module.exports.checkStorageHash = async (name) => {
|
||||||
const nameHash = `${name}-hash`;
|
const nameHash = `${name}-hash`;
|
||||||
|
|
||||||
if (!isString(name))
|
if (!isString(name))
|
||||||
|
|
@ -460,7 +485,7 @@ export async function checkStorageHash(name) {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return [loadHash, storeHash];
|
return [loadHash, storeHash];
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* save data to storage
|
* save data to storage
|
||||||
|
|
@ -468,8 +493,9 @@ export async function checkStorageHash(name) {
|
||||||
* @param name
|
* @param name
|
||||||
* @param data
|
* @param data
|
||||||
* @param hash
|
* @param hash
|
||||||
|
* @param callback
|
||||||
*/
|
*/
|
||||||
export async function saveDataToStorage(name, data, hash) {
|
module.exports.saveDataToStorage = async (name, data, hash) => {
|
||||||
const isDir = DOM.isCurrentIsDir();
|
const isDir = DOM.isCurrentIsDir();
|
||||||
|
|
||||||
if (isDir)
|
if (isDir)
|
||||||
|
|
@ -484,28 +510,25 @@ export async function saveDataToStorage(name, data, hash) {
|
||||||
await Storage.set(nameData, data);
|
await Storage.set(nameData, data);
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
};
|
||||||
|
|
||||||
export function getFM() {
|
module.exports.getFM = () => DOM.getPanel().parentElement;
|
||||||
const {parentElement} = DOM.getPanel();
|
|
||||||
return parentElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getPanelPosition(panel) {
|
module.exports.getPanelPosition = (panel) => {
|
||||||
panel = panel || DOM.getPanel();
|
panel = panel || DOM.getPanel();
|
||||||
|
|
||||||
return panel.dataset.name.replace('js-', '');
|
return panel.dataset.name.replace('js-', '');
|
||||||
}
|
};
|
||||||
|
|
||||||
export function getCSSVar(name, {body = document.body} = {}) {
|
module.exports.getCSSVar = (name, {body = document.body} = {}) => {
|
||||||
const bodyStyle = getComputedStyle(body);
|
const bodyStyle = getComputedStyle(body);
|
||||||
return bodyStyle.getPropertyValue(`--${name}`);
|
return bodyStyle.getPropertyValue(`--${name}`);
|
||||||
}
|
};
|
||||||
|
|
||||||
/** function getting panel active, or passive
|
/** function getting panel active, or passive
|
||||||
* @param options = {active: true}
|
* @param options = {active: true}
|
||||||
*/
|
*/
|
||||||
export function getPanel(options) {
|
module.exports.getPanel = (options) => {
|
||||||
let files;
|
let files;
|
||||||
let panel;
|
let panel;
|
||||||
let isLeft;
|
let isLeft;
|
||||||
|
|
@ -538,17 +561,17 @@ export function getPanel(options) {
|
||||||
throw Error('can not find Active Panel!');
|
throw Error('can not find Active Panel!');
|
||||||
|
|
||||||
return panel;
|
return panel;
|
||||||
}
|
};
|
||||||
|
|
||||||
export function getFiles(element) {
|
module.exports.getFiles = (element) => {
|
||||||
const files = DOM.getByDataName('js-files', element);
|
const files = DOM.getByDataName('js-files', element);
|
||||||
return files.children || [];
|
return files.children || [];
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shows panel right or left (or active)
|
* shows panel right or left (or active)
|
||||||
*/
|
*/
|
||||||
export function showPanel(active) {
|
module.exports.showPanel = (active) => {
|
||||||
const panel = DOM.getPanel({
|
const panel = DOM.getPanel({
|
||||||
active,
|
active,
|
||||||
});
|
});
|
||||||
|
|
@ -559,12 +582,12 @@ export function showPanel(active) {
|
||||||
DOM.show(panel);
|
DOM.show(panel);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hides panel right or left (or active)
|
* hides panel right or left (or active)
|
||||||
*/
|
*/
|
||||||
export function hidePanel(active) {
|
module.exports.hidePanel = (active) => {
|
||||||
const panel = DOM.getPanel({
|
const panel = DOM.getPanel({
|
||||||
active,
|
active,
|
||||||
});
|
});
|
||||||
|
|
@ -573,27 +596,27 @@ export function hidePanel(active) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return DOM.hide(panel);
|
return DOM.hide(panel);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove child of element
|
* remove child of element
|
||||||
* @param child
|
* @param pChild
|
||||||
* @param element
|
* @param element
|
||||||
*/
|
*/
|
||||||
export function remove(child, element) {
|
module.exports.remove = (child, element) => {
|
||||||
const parent = element || document.body;
|
const parent = element || document.body;
|
||||||
|
|
||||||
parent.removeChild(child);
|
parent.removeChild(child);
|
||||||
|
|
||||||
return DOM;
|
return DOM;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove current file from file table
|
* remove current file from file table
|
||||||
* @param current
|
* @param current
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export function deleteCurrent(current) {
|
module.exports.deleteCurrent = (current) => {
|
||||||
if (!current)
|
if (!current)
|
||||||
DOM.getCurrentFile();
|
DOM.getCurrentFile();
|
||||||
|
|
||||||
|
|
@ -607,44 +630,51 @@ export function deleteCurrent(current) {
|
||||||
DOM.setCurrentFile(next || prev);
|
DOM.setCurrentFile(next || prev);
|
||||||
parent.removeChild(current);
|
parent.removeChild(current);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove selected files from file table
|
* remove selected files from file table
|
||||||
* @Selected
|
* @Selected
|
||||||
*/
|
*/
|
||||||
export function deleteSelected(selected) {
|
module.exports.deleteSelected = (selected) => {
|
||||||
selected = selected || DOM.getSelectedFiles();
|
selected = selected || DOM.getSelectedFiles();
|
||||||
|
|
||||||
if (!selected)
|
if (!selected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
selected.map(DOM.deleteCurrent);
|
selected.map(DOM.deleteCurrent);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rename current file
|
* rename current file
|
||||||
*
|
*
|
||||||
* @currentFile
|
* @currentFile
|
||||||
*/
|
*/
|
||||||
export function scrollIntoViewIfNeeded(element, center = false) {
|
module.exports.renameCurrent = renameCurrent;
|
||||||
|
/**
|
||||||
|
* unified way to scrollIntoViewIfNeeded
|
||||||
|
* (native suporte by webkit only)
|
||||||
|
* @param element
|
||||||
|
* @param center - to scroll as small as possible param should be false
|
||||||
|
*/
|
||||||
|
module.exports.scrollIntoViewIfNeeded = (element, center = false) => {
|
||||||
if (!element || !element.scrollIntoViewIfNeeded)
|
if (!element || !element.scrollIntoViewIfNeeded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
element.scrollIntoViewIfNeeded(center);
|
element.scrollIntoViewIfNeeded(center);
|
||||||
}
|
};
|
||||||
|
|
||||||
/* scroll on one page */
|
/* scroll on one page */
|
||||||
export function scrollByPages(element, pPages) {
|
module.exports.scrollByPages = (element, pPages) => {
|
||||||
const ret = element?.scrollByPages && pPages;
|
const ret = element?.scrollByPages && pPages;
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
element.scrollByPages(pPages);
|
element.scrollByPages(pPages);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
};
|
||||||
|
|
||||||
export function changePanel() {
|
module.exports.changePanel = () => {
|
||||||
const Info = CurrentInfo;
|
const Info = CurrentInfo;
|
||||||
let panel = DOM.getPanel();
|
let panel = DOM.getPanel();
|
||||||
|
|
||||||
|
|
@ -690,21 +720,18 @@ export function changePanel() {
|
||||||
CloudCmd.emit('active-dir', Info.dirPath);
|
CloudCmd.emit('active-dir', Info.dirPath);
|
||||||
|
|
||||||
return DOM;
|
return DOM;
|
||||||
}
|
};
|
||||||
|
|
||||||
export function getPackerExt(type) {
|
module.exports.getPackerExt = (type) => {
|
||||||
if (type === 'zip')
|
if (type === 'zip')
|
||||||
return '.zip';
|
return '.zip';
|
||||||
|
|
||||||
return '.tar.gz';
|
return '.tar.gz';
|
||||||
}
|
};
|
||||||
|
|
||||||
export async function goToDirectory(overrides = {}) {
|
module.exports.goToDirectory = async (overrides = {}) => {
|
||||||
const {Dialog} = DOM;
|
const {Dialog} = DOM;
|
||||||
const {
|
const {prompt = Dialog.prompt, changeDir = CloudCmd.changeDir} = overrides;
|
||||||
prompt = Dialog.prompt,
|
|
||||||
changeDir = CloudCmd.changeDir,
|
|
||||||
} = overrides;
|
|
||||||
|
|
||||||
const msg = 'Go to directory:';
|
const msg = 'Go to directory:';
|
||||||
const {dirPath} = CurrentInfo;
|
const {dirPath} = CurrentInfo;
|
||||||
|
|
@ -715,9 +742,9 @@ export async function goToDirectory(overrides = {}) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
await changeDir(path);
|
await changeDir(path);
|
||||||
}
|
};
|
||||||
|
|
||||||
export async function duplicatePanel() {
|
module.exports.duplicatePanel = async () => {
|
||||||
const Info = CurrentInfo;
|
const Info = CurrentInfo;
|
||||||
const {isDir} = Info;
|
const {isDir} = Info;
|
||||||
const panel = Info.panelPassive;
|
const panel = Info.panelPassive;
|
||||||
|
|
@ -736,9 +763,9 @@ export async function duplicatePanel() {
|
||||||
panel,
|
panel,
|
||||||
noCurrent,
|
noCurrent,
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export async function swapPanels() {
|
module.exports.swapPanels = async () => {
|
||||||
const Info = CurrentInfo;
|
const Info = CurrentInfo;
|
||||||
const {
|
const {
|
||||||
panel,
|
panel,
|
||||||
|
|
@ -769,9 +796,11 @@ export async function swapPanels() {
|
||||||
const el = Info.files[currentIndex];
|
const el = Info.files[currentIndex];
|
||||||
|
|
||||||
DOM.setCurrentFile(el);
|
DOM.setCurrentFile(el);
|
||||||
}
|
};
|
||||||
|
|
||||||
export function updateCurrentInfo(currentFile) {
|
module.exports.CurrentInfo = CurrentInfo;
|
||||||
|
|
||||||
|
module.exports.updateCurrentInfo = (currentFile) => {
|
||||||
const info = DOM.CurrentInfo;
|
const info = DOM.CurrentInfo;
|
||||||
const current = currentFile || DOM.getCurrentFile();
|
const current = currentFile || DOM.getCurrentFile();
|
||||||
const files = current.parentElement;
|
const files = current.parentElement;
|
||||||
|
|
@ -787,7 +816,7 @@ export function updateCurrentInfo(currentFile) {
|
||||||
info.dirPath = DOM.getCurrentDirPath();
|
info.dirPath = DOM.getCurrentDirPath();
|
||||||
info.parentDirPath = DOM.getParentDirPath();
|
info.parentDirPath = DOM.getParentDirPath();
|
||||||
info.element = current;
|
info.element = current;
|
||||||
info.ext = getExt(name);
|
info.ext = Util.getExt(name);
|
||||||
info.files = Array.from(files.children);
|
info.files = Array.from(files.children);
|
||||||
info.filesPassive = Array.from(filesPassive);
|
info.filesPassive = Array.from(filesPassive);
|
||||||
info.first = files.firstChild;
|
info.first = files.firstChild;
|
||||||
|
|
@ -808,4 +837,4 @@ export function updateCurrentInfo(currentFile) {
|
||||||
.name
|
.name
|
||||||
.replace('js-', '');
|
.replace('js-', '');
|
||||||
info.isOnePanel = info.panel.getAttribute('data-name') === info.panelPassive.getAttribute('data-name');
|
info.isOnePanel = info.panel.getAttribute('data-name') === info.panelPassive.getAttribute('data-name');
|
||||||
}
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
import {test, stub} from 'supertape';
|
'use strict';
|
||||||
import {getCSSVar, goToDirectory} from '#dom';
|
|
||||||
|
require('css-modules-require-hook/preset');
|
||||||
|
|
||||||
|
const {test, stub} = require('supertape');
|
||||||
|
const {getCSSVar, goToDirectory} = require('./index');
|
||||||
|
|
||||||
globalThis.CloudCmd = {};
|
globalThis.CloudCmd = {};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,24 @@
|
||||||
import {FS} from '#common/cloudfunc';
|
'use strict';
|
||||||
import {sendRequest as _sendRequest} from './send-request.js';
|
|
||||||
|
|
||||||
const {assign} = Object;
|
const {FS} = require('../../../common/cloudfunc.mjs');
|
||||||
|
const _sendRequest = require('./send-request');
|
||||||
|
|
||||||
const imgPosition = {
|
const imgPosition = {
|
||||||
top: true,
|
top: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const remove = async (url, data, overrides = {}) => {
|
module.exports.delete = async (url, data) => {
|
||||||
const {
|
return await _sendRequest({
|
||||||
sendRequest = _sendRequest,
|
|
||||||
} = overrides;
|
|
||||||
|
|
||||||
const request = {
|
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
url: FS + url,
|
url: FS + url,
|
||||||
|
data,
|
||||||
imgPosition: {
|
imgPosition: {
|
||||||
top: Boolean(data),
|
top: Boolean(data),
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
|
|
||||||
if (data)
|
|
||||||
assign(request, {
|
|
||||||
data,
|
|
||||||
url: `${request.url}?files`,
|
|
||||||
});
|
|
||||||
|
|
||||||
return await sendRequest(request);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const patch = async (url, data) => {
|
module.exports.patch = async (url, data) => {
|
||||||
return await _sendRequest({
|
return await _sendRequest({
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
url: FS + url,
|
url: FS + url,
|
||||||
|
|
@ -38,7 +27,7 @@ export const patch = async (url, data) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const write = async (url, data) => {
|
module.exports.write = async (url, data) => {
|
||||||
return await _sendRequest({
|
return await _sendRequest({
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
url: FS + url,
|
url: FS + url,
|
||||||
|
|
@ -47,7 +36,7 @@ export const write = async (url, data) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createDirectory = async (url, overrides = {}) => {
|
module.exports.createDirectory = async (url, overrides = {}) => {
|
||||||
const {
|
const {
|
||||||
sendRequest = _sendRequest,
|
sendRequest = _sendRequest,
|
||||||
} = overrides;
|
} = overrides;
|
||||||
|
|
@ -59,7 +48,7 @@ export const createDirectory = async (url, overrides = {}) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const read = async (url, dataType = 'text') => {
|
module.exports.read = async (url, dataType = 'text') => {
|
||||||
const notLog = !url.includes('?');
|
const notLog = !url.includes('?');
|
||||||
|
|
||||||
return await _sendRequest({
|
return await _sendRequest({
|
||||||
|
|
@ -70,7 +59,7 @@ export const read = async (url, dataType = 'text') => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const copy = async (from, to, names) => {
|
module.exports.copy = async (from, to, names) => {
|
||||||
return await _sendRequest({
|
return await _sendRequest({
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
url: '/copy',
|
url: '/copy',
|
||||||
|
|
@ -83,7 +72,7 @@ export const copy = async (from, to, names) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const pack = async (data) => {
|
module.exports.pack = async (data) => {
|
||||||
return await _sendRequest({
|
return await _sendRequest({
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
url: '/pack',
|
url: '/pack',
|
||||||
|
|
@ -91,7 +80,7 @@ export const pack = async (data) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const extract = async (data) => {
|
module.exports.extract = async (data) => {
|
||||||
return await _sendRequest({
|
return await _sendRequest({
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
url: '/extract',
|
url: '/extract',
|
||||||
|
|
@ -99,7 +88,7 @@ export const extract = async (data) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const move = async (from, to, names) => {
|
module.exports.move = async (from, to, names) => {
|
||||||
return await _sendRequest({
|
return await _sendRequest({
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
url: '/move',
|
url: '/move',
|
||||||
|
|
@ -112,7 +101,7 @@ export const move = async (from, to, names) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const rename = async (from, to) => {
|
module.exports.rename = async (from, to) => {
|
||||||
return await _sendRequest({
|
return await _sendRequest({
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
url: '/rename',
|
url: '/rename',
|
||||||
|
|
@ -124,7 +113,7 @@ export const rename = async (from, to) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Config = {
|
module.exports.Config = {
|
||||||
read: async () => {
|
read: async () => {
|
||||||
return await _sendRequest({
|
return await _sendRequest({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
|
@ -144,7 +133,7 @@ export const Config = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Markdown = {
|
module.exports.Markdown = {
|
||||||
read: async (url) => {
|
read: async (url) => {
|
||||||
return await _sendRequest({
|
return await _sendRequest({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
import {test, stub} from 'supertape';
|
'use strict';
|
||||||
import * as io from './index.js';
|
|
||||||
|
const {test, stub} = require('supertape');
|
||||||
|
const io = require('.');
|
||||||
|
|
||||||
test('client: dom: io', (t) => {
|
test('client: dom: io', (t) => {
|
||||||
const sendRequest = stub();
|
const sendRequest = stub();
|
||||||
|
|
@ -19,43 +21,3 @@ test('client: dom: io', (t) => {
|
||||||
t.calledWith(sendRequest, [expected]);
|
t.calledWith(sendRequest, [expected]);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('client: dom: io: remove: no files', async (t) => {
|
|
||||||
const sendRequest = stub();
|
|
||||||
|
|
||||||
await io.remove('/hello', null, {
|
|
||||||
sendRequest,
|
|
||||||
});
|
|
||||||
|
|
||||||
const expected = {
|
|
||||||
imgPosition: {
|
|
||||||
top: false,
|
|
||||||
},
|
|
||||||
method: 'DELETE',
|
|
||||||
url: '/fs/hello',
|
|
||||||
};
|
|
||||||
|
|
||||||
t.calledWith(sendRequest, [expected]);
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('client: dom: io: remove: files', async (t) => {
|
|
||||||
const sendRequest = stub();
|
|
||||||
const files = ['world'];
|
|
||||||
|
|
||||||
await io.remove('/hello', files, {
|
|
||||||
sendRequest,
|
|
||||||
});
|
|
||||||
|
|
||||||
const expected = {
|
|
||||||
imgPosition: {
|
|
||||||
top: true,
|
|
||||||
},
|
|
||||||
data: ['world'],
|
|
||||||
method: 'DELETE',
|
|
||||||
url: '/fs/hello?files',
|
|
||||||
};
|
|
||||||
|
|
||||||
t.calledWith(sendRequest, [expected]);
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
/* global CloudCmd */
|
'use strict';
|
||||||
import {promisify} from 'es6-promisify';
|
|
||||||
import * as Images from '#dom/images';
|
|
||||||
import * as load from '#dom/load';
|
|
||||||
|
|
||||||
export const sendRequest = promisify((params, callback) => {
|
/* global CloudCmd */
|
||||||
|
const {promisify} = require('es6-promisify');
|
||||||
|
|
||||||
|
const Images = require('../images.mjs');
|
||||||
|
const load = require('../load');
|
||||||
|
|
||||||
|
module.exports = promisify((params, callback) => {
|
||||||
const p = params;
|
const p = params;
|
||||||
const {prefixURL} = CloudCmd;
|
const {prefixURL} = CloudCmd;
|
||||||
|
|
||||||
|
|
@ -37,8 +40,7 @@ export const sendRequest = promisify((params, callback) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
export const _replaceHash = replaceHash;
|
module.exports._replaceHash = replaceHash;
|
||||||
|
|
||||||
function replaceHash(url) {
|
function replaceHash(url) {
|
||||||
/*
|
/*
|
||||||
* if we send ajax request -
|
* if we send ajax request -
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
import {test} from 'supertape';
|
'use strict';
|
||||||
import {_replaceHash} from './send-request.js';
|
|
||||||
|
const test = require('supertape');
|
||||||
|
const {_replaceHash} = require('./send-request');
|
||||||
|
|
||||||
test('cloudcmd: client: io: replaceHash', (t) => {
|
test('cloudcmd: client: io: replaceHash', (t) => {
|
||||||
const url = '/hello/####world';
|
const url = '/hello/####world';
|
||||||
|
|
|
||||||
|
|
@ -1,58 +1,56 @@
|
||||||
/* global CloudCmd */
|
'use strict';
|
||||||
import {callbackify} from 'node:util';
|
|
||||||
import {rendy} from 'rendy';
|
|
||||||
import itype from 'itype';
|
|
||||||
import * as load from 'load.js';
|
|
||||||
import {tryToCatch} from 'try-to-catch';
|
|
||||||
import {findObjByNameInArr} from '#common/util';
|
|
||||||
import * as Files from '#dom/files';
|
|
||||||
|
|
||||||
export const loadRemote = callbackify(async (name, options) => {
|
/* global CloudCmd */
|
||||||
|
const rendy = require('rendy');
|
||||||
|
const itype = require('itype');
|
||||||
|
const load = require('load.js');
|
||||||
|
const {tryToCatch} = require('try-to-catch');
|
||||||
|
|
||||||
|
const {findObjByNameInArr} = require('../../common/util');
|
||||||
|
|
||||||
|
const Files = require('./files');
|
||||||
|
|
||||||
|
module.exports = (name, options, callback = options) => {
|
||||||
const {prefix, config} = CloudCmd;
|
const {prefix, config} = CloudCmd;
|
||||||
const o = options;
|
const o = options;
|
||||||
|
|
||||||
if (o.name && window[o.name])
|
if (o.name && window[o.name])
|
||||||
return;
|
return callback();
|
||||||
|
|
||||||
const modules = await Files.get('modules');
|
Files.get('modules').then(async (modules) => {
|
||||||
|
const online = config('online') && navigator.onLine;
|
||||||
|
const module = findObjByNameInArr(modules.remote, name);
|
||||||
|
|
||||||
const online = config('online') && navigator.onLine;
|
const isArray = itype.array(module.local);
|
||||||
const module = findObjByNameInArr(modules.remote, name);
|
const {version} = module;
|
||||||
|
|
||||||
const isArray = itype.array(module.local);
|
let remoteTmpls;
|
||||||
const {version} = module;
|
let local;
|
||||||
|
|
||||||
let remoteTmpls;
|
if (isArray) {
|
||||||
let local;
|
remoteTmpls = module.remote;
|
||||||
|
({local} = module);
|
||||||
|
} else {
|
||||||
|
remoteTmpls = [module.remote];
|
||||||
|
local = [module.local];
|
||||||
|
}
|
||||||
|
|
||||||
if (isArray) {
|
const localURL = local.map((url) => prefix + url);
|
||||||
remoteTmpls = module.remote;
|
|
||||||
({local} = module);
|
|
||||||
} else {
|
|
||||||
remoteTmpls = [module.remote];
|
|
||||||
local = [module.local];
|
|
||||||
}
|
|
||||||
|
|
||||||
const localURL = [];
|
const remoteURL = remoteTmpls.map((tmpl) => {
|
||||||
|
return rendy(tmpl, {
|
||||||
|
version,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
for (const url of local) {
|
if (online) {
|
||||||
localURL.push(prefix + url);
|
const [e] = await tryToCatch(load.parallel, remoteURL);
|
||||||
}
|
|
||||||
|
|
||||||
const remoteURL = [];
|
if (!e)
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
|
||||||
for (const tmpl of remoteTmpls) {
|
const [e] = await tryToCatch(load.parallel, localURL);
|
||||||
remoteURL.push(rendy(tmpl, {
|
callback(e);
|
||||||
version,
|
});
|
||||||
}));
|
};
|
||||||
}
|
|
||||||
|
|
||||||
if (online) {
|
|
||||||
const [e] = await tryToCatch(load.parallel, remoteURL);
|
|
||||||
|
|
||||||
if (!e)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await load.parallel(localURL);
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,19 @@
|
||||||
import itype from 'itype';
|
'use strict';
|
||||||
import jonny from 'jonny';
|
|
||||||
import Emitify from 'emitify';
|
|
||||||
import exec from 'execon';
|
|
||||||
import * as Images from '#dom/images';
|
|
||||||
|
|
||||||
|
const itype = require('itype');
|
||||||
|
const jonny = require('jonny');
|
||||||
|
const Emitify = require('emitify');
|
||||||
|
const exec = require('execon');
|
||||||
|
const Images = require('./images.mjs');
|
||||||
|
|
||||||
|
module.exports.getIdBySrc = getIdBySrc;
|
||||||
/**
|
/**
|
||||||
* Function gets id by src
|
* Function gets id by src
|
||||||
* @param src
|
* @param src
|
||||||
*
|
*
|
||||||
* Example: http://domain.com/1.js -> 1_js
|
* Example: http://domain.com/1.js -> 1_js
|
||||||
*/
|
*/
|
||||||
export function getIdBySrc(src) {
|
function getIdBySrc(src) {
|
||||||
const isStr = itype.string(src);
|
const isStr = itype.string(src);
|
||||||
|
|
||||||
if (!isStr)
|
if (!isStr)
|
||||||
|
|
@ -34,7 +37,7 @@ export function getIdBySrc(src) {
|
||||||
*
|
*
|
||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
export const ajax = (params) => {
|
module.exports.ajax = (params) => {
|
||||||
const p = params;
|
const p = params;
|
||||||
const isObject = itype.object(p.data);
|
const isObject = itype.object(p.data);
|
||||||
const isArray = itype.array(p.data);
|
const isArray = itype.array(p.data);
|
||||||
|
|
@ -91,11 +94,11 @@ export const ajax = (params) => {
|
||||||
xhr.send(data);
|
xhr.send(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const put = (url, body) => {
|
module.exports.put = (url, body) => {
|
||||||
const emitter = Emitify();
|
const emitter = Emitify();
|
||||||
const xhr = new XMLHttpRequest();
|
const xhr = new XMLHttpRequest();
|
||||||
|
|
||||||
url = encodeURI(url).replace(/#/g, '#');
|
url = encodeURI(url).replace(/#/g, '%23');
|
||||||
|
|
||||||
xhr.open('put', url, true);
|
xhr.open('put', url, true);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
/* global CloudCmd */
|
'use strict';
|
||||||
import capitalize from 'just-capitalize';
|
|
||||||
import * as _Dialog from '#dom/dialog';
|
|
||||||
import * as Storage from '#dom/storage';
|
|
||||||
import * as RESTful from '#dom/rest';
|
|
||||||
import * as _currentFile from '../current-file.js';
|
|
||||||
|
|
||||||
export default async (current, overrides = {}) => {
|
/* global CloudCmd */
|
||||||
|
const capitalize = require('just-capitalize');
|
||||||
|
|
||||||
|
const _Dialog = require('../dialog');
|
||||||
|
const Storage = require('../storage');
|
||||||
|
const RESTful = require('../rest');
|
||||||
|
|
||||||
|
const _currentFile = require('../current-file.mjs');
|
||||||
|
|
||||||
|
module.exports = async (current, overrides = {}) => {
|
||||||
const {
|
const {
|
||||||
refresh = CloudCmd.refresh,
|
refresh = CloudCmd.refresh,
|
||||||
Dialog = _Dialog,
|
Dialog = _Dialog,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
import {test, stub} from 'supertape';
|
'use strict';
|
||||||
import renameCurrent from './rename-current.js';
|
|
||||||
|
const {test, stub} = require('supertape');
|
||||||
|
|
||||||
|
const renameCurrent = require('./rename-current');
|
||||||
|
|
||||||
test('cloudcmd: client: dom: renameCurrent: isCurrentFile', async (t) => {
|
test('cloudcmd: client: dom: renameCurrent: isCurrentFile', async (t) => {
|
||||||
const current = {};
|
const current = {};
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
import {tryToCatch} from 'try-to-catch';
|
'use strict';
|
||||||
import * as Dialog from '#dom/dialog';
|
|
||||||
import * as Images from '#dom/images';
|
const {tryToCatch} = require('try-to-catch');
|
||||||
import {encode} from '#common/entity';
|
|
||||||
import * as IO from './io/index.js';
|
const {encode} = require('../../common/entity');
|
||||||
|
|
||||||
|
const Images = require('./images.mjs');
|
||||||
|
const IO = require('./io');
|
||||||
|
const Dialog = require('./dialog');
|
||||||
|
|
||||||
const handleError = (promise) => async (...args) => {
|
const handleError = (promise) => async (...args) => {
|
||||||
const [e, data] = await tryToCatch(promise, ...args);
|
const [e, data] = await tryToCatch(promise, ...args);
|
||||||
|
|
@ -18,23 +22,23 @@ const handleError = (promise) => async (...args) => {
|
||||||
return [e, data];
|
return [e, data];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const remove = handleError(IO.remove);
|
module.exports.delete = handleError(IO.delete);
|
||||||
export const patch = handleError(IO.patch);
|
module.exports.patch = handleError(IO.patch);
|
||||||
export const write = handleError(IO.write);
|
module.exports.write = handleError(IO.write);
|
||||||
export const createDirectory = handleError(IO.createDirectory);
|
module.exports.createDirectory = handleError(IO.createDirectory);
|
||||||
export const read = handleError(IO.read);
|
module.exports.read = handleError(IO.read);
|
||||||
export const copy = handleError(IO.copy);
|
module.exports.copy = handleError(IO.copy);
|
||||||
export const pack = handleError(IO.pack);
|
module.exports.pack = handleError(IO.pack);
|
||||||
export const extract = handleError(IO.extract);
|
module.exports.extract = handleError(IO.extract);
|
||||||
export const move = handleError(IO.move);
|
module.exports.move = handleError(IO.move);
|
||||||
export const rename = handleError(IO.rename);
|
module.exports.rename = handleError(IO.rename);
|
||||||
|
|
||||||
export const Config = {
|
module.exports.Config = {
|
||||||
read: handleError(IO.Config.read),
|
read: handleError(IO.Config.read),
|
||||||
write: handleError(IO.Config.write),
|
write: handleError(IO.Config.write),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Markdown = {
|
module.exports.Markdown = {
|
||||||
read: handleError(IO.Markdown.read),
|
read: handleError(IO.Markdown.read),
|
||||||
render: handleError(IO.Markdown.render),
|
render: handleError(IO.Markdown.render),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
import {alert, prompt} from '#dom/dialog';
|
'use strict';
|
||||||
import {getRegExp} from '#common/util';
|
|
||||||
import {getCurrentName} from './current-file.js';
|
|
||||||
import {
|
|
||||||
isSelected,
|
|
||||||
toggleSelectedFile,
|
|
||||||
} from './cmd.js';
|
|
||||||
|
|
||||||
let SelectType = '*.*';
|
let SelectType = '*.*';
|
||||||
|
|
||||||
export const selectByPattern = async (msg, files) => {
|
const {getRegExp} = require('../../common/util');
|
||||||
|
const {alert, prompt} = require('./dialog');
|
||||||
|
|
||||||
|
const DOM = require('.');
|
||||||
|
|
||||||
|
module.exports = async (msg, files) => {
|
||||||
if (!files)
|
if (!files)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -24,21 +23,21 @@ export const selectByPattern = async (msg, files) => {
|
||||||
let matches = 0;
|
let matches = 0;
|
||||||
|
|
||||||
for (const current of files) {
|
for (const current of files) {
|
||||||
const name = getCurrentName(current);
|
const name = DOM.getCurrentName(current);
|
||||||
|
|
||||||
if (name === '..' || !regExp.test(name))
|
if (name === '..' || !regExp.test(name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
++matches;
|
++matches;
|
||||||
|
|
||||||
let selected = isSelected(current);
|
let isSelected = DOM.isSelected(current);
|
||||||
const shouldSel = msg === 'expand';
|
const shouldSel = msg === 'expand';
|
||||||
|
|
||||||
if (shouldSel)
|
if (shouldSel)
|
||||||
selected = !selected;
|
isSelected = !isSelected;
|
||||||
|
|
||||||
if (selected)
|
if (isSelected)
|
||||||
toggleSelectedFile(current);
|
DOM.toggleSelectedFile(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!matches)
|
if (!matches)
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,28 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
const {parse, stringify} = JSON;
|
const {parse, stringify} = JSON;
|
||||||
|
|
||||||
export const set = (name, data) => {
|
module.exports.set = async (name, data) => {
|
||||||
localStorage.setItem(name, data);
|
localStorage.setItem(name, data);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setJson = (name, data) => {
|
module.exports.setJson = async (name, data) => {
|
||||||
localStorage.setItem(name, stringify(data));
|
localStorage.setItem(name, stringify(data));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const get = (name) => {
|
module.exports.get = async (name) => {
|
||||||
return localStorage.getItem(name);
|
return localStorage.getItem(name);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getJson = (name) => {
|
module.exports.getJson = async (name) => {
|
||||||
const data = localStorage.getItem(name);
|
const data = localStorage.getItem(name);
|
||||||
return parse(data);
|
return parse(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const clear = () => {
|
module.exports.clear = () => {
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const remove = (item) => {
|
module.exports.remove = (item) => {
|
||||||
localStorage.removeItem(item);
|
localStorage.removeItem(item);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
import {test, stub} from 'supertape';
|
'use strict';
|
||||||
import * as storage from '#dom/storage';
|
|
||||||
|
const {test, stub} = require('supertape');
|
||||||
|
|
||||||
|
const storage = require('./storage');
|
||||||
|
|
||||||
const {stringify} = JSON;
|
const {stringify} = JSON;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,24 @@
|
||||||
/* global CloudCmd */
|
'use strict';
|
||||||
import {eachSeries} from 'execon';
|
|
||||||
import wraptile from 'wraptile';
|
|
||||||
import * as load from '#dom/load';
|
|
||||||
import {alert} from '#dom/dialog';
|
|
||||||
import {FS} from '#common/cloudfunc';
|
|
||||||
import * as Images from '#dom/images';
|
|
||||||
import {getCurrentDirPath} from './current-file.js';
|
|
||||||
|
|
||||||
|
/* global CloudCmd */
|
||||||
|
const {eachSeries} = require('execon');
|
||||||
|
const wraptile = require('wraptile');
|
||||||
|
|
||||||
|
const load = require('./load');
|
||||||
|
const Images = require('./images.mjs');
|
||||||
|
const {alert} = require('./dialog');
|
||||||
|
|
||||||
|
const {FS} = require('../../common/cloudfunc.mjs');
|
||||||
|
|
||||||
|
const {getCurrentDirPath: getPathWhenRootEmpty} = require('.');
|
||||||
const loadFile = wraptile(_loadFile);
|
const loadFile = wraptile(_loadFile);
|
||||||
|
|
||||||
const onEnd = wraptile(_onEnd);
|
const onEnd = wraptile(_onEnd);
|
||||||
|
|
||||||
export const uploadFiles = (dir, files) => {
|
module.exports = (dir, files) => {
|
||||||
if (!files) {
|
if (!files) {
|
||||||
files = dir;
|
files = dir;
|
||||||
dir = getCurrentDirPath();
|
dir = getPathWhenRootEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
const n = files.length;
|
const n = files.length;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
export const createBinder = () => {
|
'use strict';
|
||||||
|
|
||||||
|
module.exports.createBinder = () => {
|
||||||
let binded = false;
|
let binded = false;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import {test} from 'supertape';
|
|
||||||
import {createBinder} from './binder.js';
|
|
||||||
|
|
||||||
test('client: key: binder: isBind: default', (t) => {
|
|
||||||
const binder = createBinder();
|
|
||||||
|
|
||||||
t.notOk(binder.isBind(), 'should not be bind by default');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('client: key: binder: setBind', (t) => {
|
|
||||||
const binder = createBinder();
|
|
||||||
|
|
||||||
binder.setBind();
|
|
||||||
|
|
||||||
t.ok(binder.isBind(), 'should be bind');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('client: key: binder: unsetBind', (t) => {
|
|
||||||
const binder = createBinder();
|
|
||||||
|
|
||||||
binder.setBind();
|
|
||||||
binder.unsetBind();
|
|
||||||
|
|
||||||
t.notOk(binder.isBind(), 'should not be bind');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
@ -2,8 +2,8 @@
|
||||||
import clipboard from '@cloudcmd/clipboard';
|
import clipboard from '@cloudcmd/clipboard';
|
||||||
import {fullstore} from 'fullstore';
|
import {fullstore} from 'fullstore';
|
||||||
import * as Events from '#dom/events';
|
import * as Events from '#dom/events';
|
||||||
import * as Buffer from '../dom/buffer.js';
|
import * as Buffer from '../dom/buffer.mjs';
|
||||||
import * as KEY from './key.js';
|
import * as KEY from './key.mjs';
|
||||||
import _vim from './vim/index.js';
|
import _vim from './vim/index.js';
|
||||||
import setCurrentByChar from './set-current-by-char.js';
|
import setCurrentByChar from './set-current-by-char.js';
|
||||||
import {createBinder} from './binder.js';
|
import {createBinder} from './binder.js';
|
||||||
|
|
@ -13,8 +13,8 @@ const Chars = fullstore();
|
||||||
const toggleVim = (keyCode, overrides = {}) => {
|
const toggleVim = (keyCode, overrides = {}) => {
|
||||||
const {_config, config} = overrides;
|
const {_config, config} = overrides;
|
||||||
|
|
||||||
if (!config('vim') && keyCode === KEY.ESC)
|
if (keyCode === KEY.ESC)
|
||||||
_config('vim', true);
|
_config('vim', !config('vim'));
|
||||||
};
|
};
|
||||||
|
|
||||||
const isUndefined = (a) => typeof a === 'undefined';
|
const isUndefined = (a) => typeof a === 'undefined';
|
||||||
|
|
@ -63,7 +63,7 @@ async function listener(event, overrides = {}) {
|
||||||
|
|
||||||
const {keyCode} = event;
|
const {keyCode} = event;
|
||||||
|
|
||||||
// strange chrome bug calls listener twice
|
// strange chrome bug calles listener twice
|
||||||
// in second time event misses a lot fields
|
// in second time event misses a lot fields
|
||||||
if (isUndefined(event.altKey))
|
if (isUndefined(event.altKey))
|
||||||
return;
|
return;
|
||||||
|
|
@ -442,14 +442,6 @@ async function _switchKey(event) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEY.L:
|
|
||||||
if (ctrlMeta && shift) {
|
|
||||||
CloudCmd.logOut();
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY.M:
|
case KEY.M:
|
||||||
if (ctrlMeta) {
|
if (ctrlMeta) {
|
||||||
if (config('vim'))
|
if (config('vim'))
|
||||||
|
|
@ -1,9 +1,15 @@
|
||||||
import autoGlobals from 'auto-globals';
|
'use strict';
|
||||||
import supertape from 'supertape';
|
|
||||||
import {ESC} from './key.js';
|
|
||||||
import {Key, _listener} from './index.js';
|
|
||||||
import {getDOM, getCloudCmd} from './vim/globals.fixture.js';
|
|
||||||
|
|
||||||
|
require('css-modules-require-hook/preset');
|
||||||
|
|
||||||
|
const autoGlobals = require('auto-globals');
|
||||||
|
const supertape = require('supertape');
|
||||||
|
|
||||||
|
const {ESC} = require('./key.mjs');
|
||||||
|
|
||||||
|
const {Key, _listener} = require('./index.mjs');
|
||||||
|
|
||||||
|
const {getDOM, getCloudCmd} = require('./vim/globals.fixture');
|
||||||
const test = autoGlobals(supertape);
|
const test = autoGlobals(supertape);
|
||||||
const {stub} = supertape;
|
const {stub} = supertape;
|
||||||
|
|
||||||
|
|
@ -37,7 +43,6 @@ test('cloudcmd: client: key: enable vim', async (t) => {
|
||||||
test('cloudcmd: client: key: disable vim', async (t) => {
|
test('cloudcmd: client: key: disable vim', async (t) => {
|
||||||
const _config = stub();
|
const _config = stub();
|
||||||
const config = stub();
|
const config = stub();
|
||||||
|
|
||||||
const event = {
|
const event = {
|
||||||
keyCode: ESC,
|
keyCode: ESC,
|
||||||
key: 'Escape',
|
key: 'Escape',
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ export const D = 68;
|
||||||
export const G = 71;
|
export const G = 71;
|
||||||
export const J = 74;
|
export const J = 74;
|
||||||
export const K = 75;
|
export const K = 75;
|
||||||
export const L = 76;
|
|
||||||
export const M = 77;
|
export const M = 77;
|
||||||
export const O = 79;
|
export const O = 79;
|
||||||
export const P = 80;
|
export const P = 80;
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
/* global DOM */
|
/* global DOM */
|
||||||
import {escapeRegExp} from '#common/util';
|
|
||||||
|
|
||||||
export default function setCurrentByChar(char, charStore) {
|
'use strict';
|
||||||
|
|
||||||
|
const {escapeRegExp} = require('../../common/util');
|
||||||
|
|
||||||
|
module.exports = function setCurrentByChar(char, charStore) {
|
||||||
const Info = DOM.CurrentInfo;
|
const Info = DOM.CurrentInfo;
|
||||||
let firstByName;
|
let firstByName;
|
||||||
let skipCount = 0;
|
let skipCount = 0;
|
||||||
let set = false;
|
let setted = false;
|
||||||
let i = 0;
|
let i = 0;
|
||||||
|
|
||||||
const escapeChar = escapeRegExp(char);
|
const escapeChar = escapeRegExp(char);
|
||||||
|
|
@ -33,7 +36,7 @@ export default function setCurrentByChar(char, charStore) {
|
||||||
const byName = DOM.getCurrentByName(name);
|
const byName = DOM.getCurrentByName(name);
|
||||||
|
|
||||||
if (!skipCount) {
|
if (!skipCount) {
|
||||||
set = true;
|
setted = true;
|
||||||
DOM.setCurrentFile(byName);
|
DOM.setCurrentFile(byName);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -50,8 +53,8 @@ export default function setCurrentByChar(char, charStore) {
|
||||||
.filter(not(isRoot))
|
.filter(not(isRoot))
|
||||||
.some(setCurrent);
|
.some(setCurrent);
|
||||||
|
|
||||||
if (!set) {
|
if (!setted) {
|
||||||
DOM.setCurrentFile(firstByName);
|
DOM.setCurrentFile(firstByName);
|
||||||
charStore([char]);
|
charStore([char]);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
import {fullstore} from 'fullstore';
|
'use strict';
|
||||||
import limier from 'limier';
|
|
||||||
|
const {fullstore} = require('fullstore');
|
||||||
|
const limier = require('limier');
|
||||||
|
|
||||||
const searchStore = fullstore([]);
|
const searchStore = fullstore([]);
|
||||||
const searchIndex = fullstore(0);
|
const searchIndex = fullstore(0);
|
||||||
|
|
||||||
export const find = (value, names) => {
|
module.exports.find = (value, names) => {
|
||||||
const result = limier(value, names);
|
const result = limier(value, names);
|
||||||
|
|
||||||
searchStore(result);
|
searchStore(result);
|
||||||
|
|
@ -13,7 +15,7 @@ export const find = (value, names) => {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const findNext = () => {
|
module.exports.findNext = () => {
|
||||||
const names = searchStore();
|
const names = searchStore();
|
||||||
const index = next(searchIndex(), names.length);
|
const index = next(searchIndex(), names.length);
|
||||||
|
|
||||||
|
|
@ -21,7 +23,7 @@ export const findNext = () => {
|
||||||
return names[searchIndex()];
|
return names[searchIndex()];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const findPrevious = () => {
|
module.exports.findPrevious = () => {
|
||||||
const names = searchStore();
|
const names = searchStore();
|
||||||
const index = previous(searchIndex(), names.length);
|
const index = previous(searchIndex(), names.length);
|
||||||
|
|
||||||
|
|
@ -29,8 +31,8 @@ export const findPrevious = () => {
|
||||||
return names[index];
|
return names[index];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const _next = next;
|
module.exports._next = next;
|
||||||
export const _previous = previous;
|
module.exports._previous = previous;
|
||||||
|
|
||||||
function next(index, length) {
|
function next(index, length) {
|
||||||
if (index === length - 1)
|
if (index === length - 1)
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,14 @@
|
||||||
import test from 'supertape';
|
'use strict';
|
||||||
import {getDOM} from './globals.fixture.js';
|
|
||||||
import {
|
const test = require('supertape');
|
||||||
_next,
|
const dir = './';
|
||||||
_previous,
|
|
||||||
find,
|
const {getDOM} = require('./globals.fixture');
|
||||||
findNext,
|
|
||||||
findPrevious,
|
|
||||||
} from './find.js';
|
|
||||||
|
|
||||||
globalThis.DOM = getDOM();
|
globalThis.DOM = getDOM();
|
||||||
|
|
||||||
|
const {_next, _previous} = require(`${dir}find`);
|
||||||
|
|
||||||
test('cloudcmd: client: vim: _next', (t) => {
|
test('cloudcmd: client: vim: _next', (t) => {
|
||||||
const result = _next(1, 2);
|
const result = _next(1, 2);
|
||||||
|
|
||||||
|
|
@ -17,39 +16,9 @@ test('cloudcmd: client: vim: _next', (t) => {
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('cloudcmd: client: vim: _next: increment', (t) => {
|
|
||||||
const result = _next(0, 2);
|
|
||||||
|
|
||||||
t.equal(result, 1, 'should return 1');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('cloudcmd: client: vim: _previous', (t) => {
|
test('cloudcmd: client: vim: _previous', (t) => {
|
||||||
const result = _previous(0, 2);
|
const result = _previous(0, 2);
|
||||||
|
|
||||||
t.equal(result, 1, 'should return 1');
|
t.equal(result, 1, 'should return 1');
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('cloudcmd: client: vim: _previous: decrement', (t) => {
|
|
||||||
const result = _previous(1, 2);
|
|
||||||
|
|
||||||
t.equal(result, 0, 'should return 0');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('cloudcmd: client: vim: findNext: after find', (t) => {
|
|
||||||
find('a', ['alpha', 'beta', 'apple']);
|
|
||||||
const result = findNext();
|
|
||||||
|
|
||||||
t.equal(result, 'beta', 'should return next found name');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('cloudcmd: client: vim: findPrevious: after find', (t) => {
|
|
||||||
find('a', ['alpha', 'beta', 'apple']);
|
|
||||||
const result = findPrevious();
|
|
||||||
|
|
||||||
t.equal(result, 'apple', 'should return previous found name');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
const noop = () => {};
|
const noop = () => {};
|
||||||
|
|
||||||
export const getDOM = () => {
|
module.exports.getDOM = () => {
|
||||||
const prompt = Promise.resolve.bind(Promise);
|
const prompt = Promise.resolve.bind(Promise);
|
||||||
const CurrentInfo = {
|
const CurrentInfo = {
|
||||||
element: {},
|
element: {},
|
||||||
|
|
@ -32,7 +34,7 @@ export const getDOM = () => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getCloudCmd = () => {
|
module.exports.getCloudCmd = () => {
|
||||||
const show = () => {};
|
const show = () => {};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
import vim from './vim.js';
|
'use strict';
|
||||||
import * as finder from './find.js';
|
|
||||||
import {
|
/* global CloudCmd */
|
||||||
|
/* global DOM */
|
||||||
|
const vim = require('./vim');
|
||||||
|
const finder = require('./find');
|
||||||
|
const {
|
||||||
setCurrent,
|
setCurrent,
|
||||||
selectFileNotParent,
|
selectFileNotParent,
|
||||||
} from './set-current.js';
|
} = require('./set-current');
|
||||||
|
|
||||||
export default (key, event, overrides = {}) => {
|
module.exports = (key, event, overrides = {}) => {
|
||||||
const defaults = {
|
const defaults = {
|
||||||
...globalThis.DOM,
|
...globalThis.DOM,
|
||||||
...globalThis.CloudCmd,
|
...globalThis.CloudCmd,
|
||||||
|
|
@ -33,13 +37,13 @@ const getOperations = (event, deps) => {
|
||||||
prompt = globalThis.DOM.Dialog.prompt,
|
prompt = globalThis.DOM.Dialog.prompt,
|
||||||
preventDefault = event?.preventDefault?.bind(event),
|
preventDefault = event?.preventDefault?.bind(event),
|
||||||
stopImmediatePropagation = event?.preventDefault?.bind(event),
|
stopImmediatePropagation = event?.preventDefault?.bind(event),
|
||||||
promptNewFile = globalThis.DOM.promptNewFile,
|
promptNewFile = DOM.promptNewFile,
|
||||||
|
|
||||||
toggleSelectedFile,
|
toggleSelectedFile,
|
||||||
Buffer = {},
|
Buffer = {},
|
||||||
createFindNext = _createFindNext,
|
createFindNext = _createFindNext,
|
||||||
createFindPrevious = _createFindPrevious,
|
createFindPrevious = _createFindPrevious,
|
||||||
createMakeFile = _createMakeFile,
|
createMakeFile = _createMakeFile,
|
||||||
renameCurrent,
|
|
||||||
} = deps;
|
} = deps;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -55,26 +59,15 @@ const getOperations = (event, deps) => {
|
||||||
setCurrentByName,
|
setCurrentByName,
|
||||||
}),
|
}),
|
||||||
escape: unselectFiles,
|
escape: unselectFiles,
|
||||||
rename: () => {
|
|
||||||
event.preventDefault();
|
|
||||||
renameCurrent();
|
|
||||||
},
|
|
||||||
remove: () => {
|
remove: () => {
|
||||||
Operation.show('delete');
|
Operation.show('delete');
|
||||||
},
|
},
|
||||||
operationCopy: () => {
|
|
||||||
event.preventDefault();
|
|
||||||
Operation.show('copy');
|
|
||||||
},
|
|
||||||
operationMove: () => {
|
|
||||||
event.preventDefault();
|
|
||||||
Operation.show('move');
|
|
||||||
},
|
|
||||||
|
|
||||||
makeDirectory: () => {
|
makeDirectory: () => {
|
||||||
event.stopImmediatePropagation();
|
event.stopImmediatePropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
globalThis.DOM.promptNewDir();
|
DOM.promptNewDir();
|
||||||
},
|
},
|
||||||
|
|
||||||
terminal: () => {
|
terminal: () => {
|
||||||
|
|
@ -138,7 +131,7 @@ const getOperations = (event, deps) => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const selectFile = selectFileNotParent;
|
module.exports.selectFile = selectFileNotParent;
|
||||||
|
|
||||||
const _createFindPrevious = (overrides = {}) => () => {
|
const _createFindPrevious = (overrides = {}) => () => {
|
||||||
const {setCurrentByName} = overrides;
|
const {setCurrentByName} = overrides;
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,25 @@
|
||||||
import {test, stub} from 'supertape';
|
'use strict';
|
||||||
import {getDOM, getCloudCmd} from './globals.fixture.js';
|
|
||||||
import vim, {selectFile as vimSelectFile} from './index.js';
|
const {join} = require('node:path');
|
||||||
import * as finder from './find.js';
|
const {test, stub} = require('supertape');
|
||||||
|
|
||||||
|
const dir = '../';
|
||||||
|
|
||||||
|
const pathVim = join(dir, 'vim');
|
||||||
|
|
||||||
|
const {getDOM, getCloudCmd} = require('./globals.fixture');
|
||||||
|
|
||||||
globalThis.DOM = getDOM();
|
globalThis.DOM = getDOM();
|
||||||
globalThis.CloudCmd = getCloudCmd();
|
globalThis.CloudCmd = getCloudCmd();
|
||||||
|
|
||||||
|
const vim = require('./index.js');
|
||||||
|
|
||||||
const {assign} = Object;
|
const {assign} = Object;
|
||||||
const {DOM} = globalThis;
|
const {DOM} = globalThis;
|
||||||
const {Buffer} = DOM;
|
const {Buffer} = DOM;
|
||||||
|
|
||||||
|
const {reRequire, stopAll} = require('mock-require');
|
||||||
|
|
||||||
test('cloudcmd: client: key: set next file: no', (t) => {
|
test('cloudcmd: client: key: set next file: no', (t) => {
|
||||||
const element = {};
|
const element = {};
|
||||||
const setCurrentFile = stub();
|
const setCurrentFile = stub();
|
||||||
|
|
@ -309,7 +319,7 @@ test('cloudcmd: client: key: selectFile: ..', (t) => {
|
||||||
const selectFile = stub();
|
const selectFile = stub();
|
||||||
const current = {};
|
const current = {};
|
||||||
|
|
||||||
vimSelectFile(current, {
|
vim.selectFile(current, {
|
||||||
selectFile,
|
selectFile,
|
||||||
getCurrentName,
|
getCurrentName,
|
||||||
});
|
});
|
||||||
|
|
@ -323,7 +333,7 @@ test('cloudcmd: client: key: selectFile', (t) => {
|
||||||
const getCurrentName = stub().returns('x');
|
const getCurrentName = stub().returns('x');
|
||||||
const current = {};
|
const current = {};
|
||||||
|
|
||||||
vimSelectFile(current, {
|
vim.selectFile(current, {
|
||||||
selectFile,
|
selectFile,
|
||||||
getCurrentName,
|
getCurrentName,
|
||||||
});
|
});
|
||||||
|
|
@ -448,7 +458,6 @@ test('cloudcmd: client: key: set first file current: ^', async (t) => {
|
||||||
test('cloudcmd: client: key: visual', (t) => {
|
test('cloudcmd: client: key: visual', (t) => {
|
||||||
const element = {};
|
const element = {};
|
||||||
const toggleSelectedFile = stub();
|
const toggleSelectedFile = stub();
|
||||||
|
|
||||||
const Info = {
|
const Info = {
|
||||||
element,
|
element,
|
||||||
};
|
};
|
||||||
|
|
@ -465,7 +474,6 @@ test('cloudcmd: client: key: visual', (t) => {
|
||||||
test('cloudcmd: client: key: ESC', (t) => {
|
test('cloudcmd: client: key: ESC', (t) => {
|
||||||
const element = {};
|
const element = {};
|
||||||
const unselectFiles = stub();
|
const unselectFiles = stub();
|
||||||
|
|
||||||
const Info = {
|
const Info = {
|
||||||
element,
|
element,
|
||||||
};
|
};
|
||||||
|
|
@ -511,7 +519,6 @@ test('cloudcmd: client: key: Enter', async (t) => {
|
||||||
test('cloudcmd: client: key: /', (t) => {
|
test('cloudcmd: client: key: /', (t) => {
|
||||||
const preventDefault = stub();
|
const preventDefault = stub();
|
||||||
const element = {};
|
const element = {};
|
||||||
|
|
||||||
const Info = {
|
const Info = {
|
||||||
element,
|
element,
|
||||||
files: [],
|
files: [],
|
||||||
|
|
@ -546,12 +553,16 @@ test('cloudcmd: client: find', (t) => {
|
||||||
setCurrentByName,
|
setCurrentByName,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const vim = reRequire(pathVim);
|
||||||
|
|
||||||
const event = {
|
const event = {
|
||||||
preventDefault: stub(),
|
preventDefault: stub(),
|
||||||
};
|
};
|
||||||
|
|
||||||
vim('/', event);
|
vim('/', event);
|
||||||
|
|
||||||
|
stopAll();
|
||||||
|
|
||||||
t.notCalled(setCurrentByName);
|
t.notCalled(setCurrentByName);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
@ -584,6 +595,7 @@ test('cloudcmd: client: key: N', (t) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('cloudcmd: client: key: make directory', async (t) => {
|
test('cloudcmd: client: key: make directory', async (t) => {
|
||||||
|
const vim = reRequire(pathVim);
|
||||||
const {DOM} = globalThis;
|
const {DOM} = globalThis;
|
||||||
|
|
||||||
assign(DOM, {
|
assign(DOM, {
|
||||||
|
|
@ -658,99 +670,3 @@ test('cloudcmd: client: vim: edit', async (t) => {
|
||||||
t.calledWithNoArgs(CloudCmd.EditFileVim.show);
|
t.calledWithNoArgs(CloudCmd.EditFileVim.show);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('cloudcmd: client: vim: rename', async (t) => {
|
|
||||||
const DOM = getDOM();
|
|
||||||
const renameCurrent = stub();
|
|
||||||
|
|
||||||
assign(DOM, {
|
|
||||||
renameCurrent,
|
|
||||||
});
|
|
||||||
|
|
||||||
const event = {
|
|
||||||
preventDefault: stub(),
|
|
||||||
};
|
|
||||||
|
|
||||||
await vim('rr', event, DOM);
|
|
||||||
|
|
||||||
t.calledWithNoArgs(renameCurrent);
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('cloudcmd: client: key: cc: operationCopy', (t) => {
|
|
||||||
const show = stub();
|
|
||||||
const preventDefault = stub();
|
|
||||||
|
|
||||||
const Operation = {
|
|
||||||
show,
|
|
||||||
};
|
|
||||||
|
|
||||||
const event = {
|
|
||||||
preventDefault,
|
|
||||||
};
|
|
||||||
|
|
||||||
vim('c', event, {
|
|
||||||
Operation,
|
|
||||||
});
|
|
||||||
|
|
||||||
vim('c', event, {
|
|
||||||
Operation,
|
|
||||||
});
|
|
||||||
|
|
||||||
t.calledWith(show, ['copy'], 'should show copy operation');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('cloudcmd: client: key: mm: operationMove', (t) => {
|
|
||||||
const show = stub();
|
|
||||||
const preventDefault = stub();
|
|
||||||
|
|
||||||
const Operation = {
|
|
||||||
show,
|
|
||||||
};
|
|
||||||
|
|
||||||
const event = {
|
|
||||||
preventDefault,
|
|
||||||
};
|
|
||||||
|
|
||||||
vim('m', event, {
|
|
||||||
Operation,
|
|
||||||
});
|
|
||||||
|
|
||||||
vim('m', event, {
|
|
||||||
Operation,
|
|
||||||
});
|
|
||||||
|
|
||||||
t.calledWith(show, ['move'], 'should show move operation');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('cloudcmd: client: key: n: findNext: real', (t) => {
|
|
||||||
const setCurrentByName = stub();
|
|
||||||
|
|
||||||
finder.find('a', ['alpha', 'beta', 'apple']);
|
|
||||||
|
|
||||||
const event = {};
|
|
||||||
|
|
||||||
vim('n', event, {
|
|
||||||
setCurrentByName,
|
|
||||||
});
|
|
||||||
|
|
||||||
t.calledWith(setCurrentByName, ['beta'], 'should set current by next found name');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('cloudcmd: client: key: N: findPrevious: real', (t) => {
|
|
||||||
const setCurrentByName = stub();
|
|
||||||
|
|
||||||
finder.find('a', ['alpha', 'beta', 'apple']);
|
|
||||||
|
|
||||||
const event = {};
|
|
||||||
|
|
||||||
vim('N', event, {
|
|
||||||
setCurrentByName,
|
|
||||||
});
|
|
||||||
|
|
||||||
t.calledWith(setCurrentByName, ['apple'], 'should set current by previous found name');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
/* global DOM */
|
/* global DOM */
|
||||||
export function selectFileNotParent(current, {getCurrentName, selectFile} = DOM) {
|
module.exports.selectFileNotParent = selectFileNotParent;
|
||||||
|
function selectFileNotParent(current, {getCurrentName, selectFile} = DOM) {
|
||||||
const name = getCurrentName(current);
|
const name = getCurrentName(current);
|
||||||
|
|
||||||
if (name === '..')
|
if (name === '..')
|
||||||
|
|
@ -8,7 +11,7 @@ export function selectFileNotParent(current, {getCurrentName, selectFile} = DOM)
|
||||||
selectFile(current);
|
selectFile(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const setCurrent = (sibling, {count, isVisual, isDelete}, {Info, setCurrentFile, unselectFiles, Operation}) => {
|
module.exports.setCurrent = (sibling, {count, isVisual, isDelete}, {Info, setCurrentFile, unselectFiles, Operation}) => {
|
||||||
let current = Info.element;
|
let current = Info.element;
|
||||||
const select = isVisual ? selectFileNotParent : unselectFiles;
|
const select = isVisual ? selectFileNotParent : unselectFiles;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import {fullstore} from 'fullstore';
|
'use strict';
|
||||||
|
|
||||||
|
const {fullstore} = require('fullstore');
|
||||||
const store = fullstore('');
|
const store = fullstore('');
|
||||||
const visual = fullstore(false);
|
const visual = fullstore(false);
|
||||||
|
|
||||||
|
|
@ -20,7 +21,7 @@ const rmFirst = (a) => {
|
||||||
|
|
||||||
const noop = () => {};
|
const noop = () => {};
|
||||||
|
|
||||||
export default (key, operations = {}) => {
|
module.exports = (key, operations = {}) => {
|
||||||
const prevStore = store();
|
const prevStore = store();
|
||||||
const isVisual = visual();
|
const isVisual = visual();
|
||||||
const value = store(prevStore.concat(key));
|
const value = store(prevStore.concat(key));
|
||||||
|
|
@ -40,9 +41,6 @@ export default (key, operations = {}) => {
|
||||||
makeDirectory = noop,
|
makeDirectory = noop,
|
||||||
terminal = noop,
|
terminal = noop,
|
||||||
edit = noop,
|
edit = noop,
|
||||||
operationCopy = noop,
|
|
||||||
operationMove = noop,
|
|
||||||
rename = noop,
|
|
||||||
} = operations;
|
} = operations;
|
||||||
|
|
||||||
if (key === 'Enter')
|
if (key === 'Enter')
|
||||||
|
|
@ -114,26 +112,11 @@ export default (key, operations = {}) => {
|
||||||
return end();
|
return end();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value === 'cc') {
|
|
||||||
operationCopy();
|
|
||||||
return end();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value === 'mm') {
|
|
||||||
operationMove();
|
|
||||||
return end();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value === 'mf') {
|
if (value === 'mf') {
|
||||||
makeFile();
|
makeFile();
|
||||||
return end();
|
return end();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value === 'rr') {
|
|
||||||
rename();
|
|
||||||
return end();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key === 'd' && (visual() || prevStore === 'd')) {
|
if (key === 'd' && (visual() || prevStore === 'd')) {
|
||||||
stopVisual();
|
stopVisual();
|
||||||
remove();
|
remove();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
import {test, stub} from 'supertape';
|
'use strict';
|
||||||
import vim from './vim.js';
|
|
||||||
|
const {test, stub} = require('supertape');
|
||||||
|
|
||||||
|
const vim = require('./vim');
|
||||||
|
|
||||||
test('vim: no operations', (t) => {
|
test('vim: no operations', (t) => {
|
||||||
const result = vim('hello', {});
|
const result = vim('hello', {});
|
||||||
|
|
@ -43,28 +46,6 @@ test('vim: ^', (t) => {
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('vim: cc', (t) => {
|
|
||||||
const operationCopy = stub();
|
|
||||||
|
|
||||||
vim('cc', {
|
|
||||||
operationCopy,
|
|
||||||
});
|
|
||||||
|
|
||||||
t.calledWithNoArgs(operationCopy);
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('vim: mm', (t) => {
|
|
||||||
const operationMove = stub();
|
|
||||||
|
|
||||||
vim('mm', {
|
|
||||||
operationMove,
|
|
||||||
});
|
|
||||||
|
|
||||||
t.calledWithNoArgs(operationMove);
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('vim: w', (t) => {
|
test('vim: w', (t) => {
|
||||||
const moveNext = stub();
|
const moveNext = stub();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import test from 'supertape';
|
import test from 'supertape';
|
||||||
import {getIndex} from './get-index.js';
|
import {getIndex} from './get-index.mjs';
|
||||||
|
|
||||||
test('cloudcmd: client: listeners: getIndex: not found', (t) => {
|
test('cloudcmd: client: listeners: getIndex: not found', (t) => {
|
||||||
const array = ['hello'];
|
const array = ['hello'];
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import test from 'supertape';
|
import test from 'supertape';
|
||||||
import {getRange} from './get-range.js';
|
import {getRange} from './get-range.mjs';
|
||||||
|
|
||||||
test('cloudcmd: client: listeners: getRange: direct', (t) => {
|
test('cloudcmd: client: listeners: getRange: direct', (t) => {
|
||||||
const expected = [
|
const expected = [
|
||||||
|
|
@ -5,15 +5,15 @@ import currify from 'currify';
|
||||||
import {tryToCatch} from 'try-to-catch';
|
import {tryToCatch} from 'try-to-catch';
|
||||||
import clipboard from '@cloudcmd/clipboard';
|
import clipboard from '@cloudcmd/clipboard';
|
||||||
import * as Events from '#dom/events';
|
import * as Events from '#dom/events';
|
||||||
import {uploadFiles} from '#dom/upload-files';
|
import {getRange} from './get-range.mjs';
|
||||||
import {FS} from '#common/cloudfunc';
|
import uploadFiles from '../dom/upload-files.js';
|
||||||
import {getRange} from './get-range.js';
|
import {FS} from '../../common/cloudfunc.mjs';
|
||||||
import {getIndex} from './get-index.js';
|
import {getIndex} from './get-index.mjs';
|
||||||
|
|
||||||
const NBSP_REG = RegExp(String.fromCharCode(160), 'g');
|
const NBSP_REG = RegExp(String.fromCharCode(160), 'g');
|
||||||
const SPACE = ' ';
|
const SPACE = ' ';
|
||||||
|
|
||||||
export async function init() {
|
export const init = async () => {
|
||||||
contextMenu();
|
contextMenu();
|
||||||
dragndrop();
|
dragndrop();
|
||||||
unload();
|
unload();
|
||||||
|
|
@ -21,7 +21,7 @@ export async function init() {
|
||||||
resize();
|
resize();
|
||||||
header();
|
header();
|
||||||
await config();
|
await config();
|
||||||
}
|
};
|
||||||
|
|
||||||
const unselect = (event) => {
|
const unselect = (event) => {
|
||||||
const isMac = /Mac/.test(globalThis.navigator.platform);
|
const isMac = /Mac/.test(globalThis.navigator.platform);
|
||||||
|
|
@ -55,7 +55,6 @@ let EXT;
|
||||||
function header() {
|
function header() {
|
||||||
const fm = DOM.getFM();
|
const fm = DOM.getFM();
|
||||||
const isDataset = (el) => el.dataset;
|
const isDataset = (el) => el.dataset;
|
||||||
|
|
||||||
const isPanel = (el) => {
|
const isPanel = (el) => {
|
||||||
return /^js-(left|right)$/.test(el.dataset.name);
|
return /^js-(left|right)$/.test(el.dataset.name);
|
||||||
};
|
};
|
||||||
|
|
@ -310,12 +309,8 @@ function onDragStart(event) {
|
||||||
link.href = prefixURL + '/pack' + Info.path + EXT;
|
link.href = prefixURL + '/pack' + Info.path + EXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.dataTransfer.setData(
|
event.dataTransfer.setData('DownloadURL', 'application/octet-stream' + ':' + name +
|
||||||
'DownloadURL',
|
':' + link);
|
||||||
'application/octet-stream' + ':' + name +
|
|
||||||
':' +
|
|
||||||
link,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLIElement(element) {
|
function getLIElement(element) {
|
||||||
|
|
@ -1,32 +1,32 @@
|
||||||
/* global CloudCmd, filepicker */
|
/* global CloudCmd, filepicker */
|
||||||
import exec from 'execon';
|
|
||||||
import currify from 'currify';
|
|
||||||
import load from 'load.js';
|
|
||||||
import {ajax} from '#dom/load';
|
|
||||||
import * as Files from '#dom/files';
|
|
||||||
import * as Images from '#dom/images';
|
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const exec = require('execon');
|
||||||
|
const currify = require('currify');
|
||||||
|
const load = require('load.js');
|
||||||
|
|
||||||
|
const {ajax} = require('../dom/load');
|
||||||
|
|
||||||
|
const Files = require('../dom/files');
|
||||||
|
const Images = require('../dom/images.mjs');
|
||||||
const {log} = CloudCmd;
|
const {log} = CloudCmd;
|
||||||
|
|
||||||
const upload = currify(_upload);
|
const upload = currify(_upload);
|
||||||
|
|
||||||
const Name = 'Cloud';
|
const Name = 'Cloud';
|
||||||
|
|
||||||
CloudCmd[Name] = {
|
CloudCmd[Name] = module.exports;
|
||||||
init,
|
|
||||||
uploadFile,
|
|
||||||
saveFile,
|
|
||||||
};
|
|
||||||
|
|
||||||
export async function init() {
|
module.exports.init = async () => {
|
||||||
const [modules] = await loadFiles();
|
const [modules] = await loadFiles();
|
||||||
const {key} = modules.data.FilePicker;
|
const {key} = modules.data.FilePicker;
|
||||||
|
|
||||||
filepicker.setKey(key);
|
filepicker.setKey(key);
|
||||||
Images.hide();
|
Images.hide();
|
||||||
}
|
};
|
||||||
|
|
||||||
export function uploadFile(filename, data) {
|
module.exports.uploadFile = (filename, data) => {
|
||||||
const mimetype = '';
|
const mimetype = '';
|
||||||
|
|
||||||
filepicker.store(data, {
|
filepicker.store(data, {
|
||||||
|
|
@ -35,11 +35,11 @@ export function uploadFile(filename, data) {
|
||||||
}, (fpFile) => {
|
}, (fpFile) => {
|
||||||
filepicker.exportFile(fpFile, log, log);
|
filepicker.exportFile(fpFile, log, log);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export function saveFile(callback) {
|
module.exports.saveFile = (callback) => {
|
||||||
filepicker.pick(upload(callback));
|
filepicker.pick(upload(callback));
|
||||||
}
|
};
|
||||||
|
|
||||||
function _upload(callback, file) {
|
function _upload(callback, file) {
|
||||||
const {url, filename} = file;
|
const {url, filename} = file;
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,18 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
/* global CloudCmd */
|
/* global CloudCmd */
|
||||||
import * as Dialog from '#dom/dialog';
|
CloudCmd.CommandLine = exports;
|
||||||
|
|
||||||
export function init() {}
|
const Dialog = require('../dom/dialog');
|
||||||
CloudCmd.CommandLine = {
|
|
||||||
init,
|
|
||||||
show,
|
|
||||||
hide,
|
|
||||||
};
|
|
||||||
|
|
||||||
export async function show() {
|
const noop = () => {};
|
||||||
|
|
||||||
|
module.exports.init = noop;
|
||||||
|
|
||||||
|
module.exports.show = show;
|
||||||
|
module.exports.hide = hide;
|
||||||
|
|
||||||
|
async function show() {
|
||||||
const [, cmd] = await Dialog.prompt('Command Line', '');
|
const [, cmd] = await Dialog.prompt('Command Line', '');
|
||||||
const TERMINAL = '^(t|terminal)';
|
const TERMINAL = '^(t|terminal)';
|
||||||
|
|
||||||
|
|
@ -28,4 +32,4 @@ export async function show() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hide() {}
|
function hide() {}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import '../../../css/config.css';
|
/* global CloudCmd, DOM, io */
|
||||||
import {rendy} from 'rendy';
|
import rendy from 'rendy';
|
||||||
import currify from 'currify';
|
import currify from 'currify';
|
||||||
import wraptile from 'wraptile';
|
import wraptile from 'wraptile';
|
||||||
import squad from 'squad';
|
import squad from 'squad';
|
||||||
|
|
@ -8,12 +8,11 @@ import {tryToCatch} from 'try-to-catch';
|
||||||
import load from 'load.js';
|
import load from 'load.js';
|
||||||
import createElement from '@cloudcmd/create-element';
|
import createElement from '@cloudcmd/create-element';
|
||||||
import * as Events from '#dom/events';
|
import * as Events from '#dom/events';
|
||||||
import * as Files from '#dom/files';
|
import '../../../css/config.css';
|
||||||
import {getTitle} from '#common/cloudfunc';
|
import * as input from './input.mjs';
|
||||||
import * as Images from '#dom/images';
|
import * as Images from '../../dom/images.mjs';
|
||||||
import * as input from './input.js';
|
import Files from '../../dom/files.js';
|
||||||
|
import {getTitle} from '../../../common/cloudfunc.mjs';
|
||||||
const {CloudCmd, DOM} = globalThis;
|
|
||||||
|
|
||||||
const {Dialog, setTitle} = DOM;
|
const {Dialog, setTitle} = DOM;
|
||||||
|
|
||||||
|
|
@ -41,7 +40,7 @@ let Template;
|
||||||
|
|
||||||
const loadCSS = load.css;
|
const loadCSS = load.css;
|
||||||
|
|
||||||
export async function init() {
|
export const init = async () => {
|
||||||
if (!CloudCmd.config('configDialog'))
|
if (!CloudCmd.config('configDialog'))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -57,7 +56,7 @@ export async function init() {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
initSocket();
|
initSocket();
|
||||||
}
|
};
|
||||||
|
|
||||||
const {config, Key} = CloudCmd;
|
const {config, Key} = CloudCmd;
|
||||||
|
|
||||||
|
|
@ -79,7 +78,7 @@ function initSocket() {
|
||||||
|
|
||||||
const ONE_MINUTE = 60 * 1000;
|
const ONE_MINUTE = 60 * 1000;
|
||||||
|
|
||||||
const socket = globalThis.io.connect(href + prefixSocket + '/config', {
|
const socket = io.connect(href + prefixSocket + '/config', {
|
||||||
reconnectionAttempts: Infinity,
|
reconnectionAttempts: Infinity,
|
||||||
reconnectionDelay: ONE_MINUTE,
|
reconnectionDelay: ONE_MINUTE,
|
||||||
path: `${prefix}/socket.io`,
|
path: `${prefix}/socket.io`,
|
||||||
|
|
@ -133,7 +132,6 @@ async function fillTemplate() {
|
||||||
columns,
|
columns,
|
||||||
theme,
|
theme,
|
||||||
configAuth,
|
configAuth,
|
||||||
configPort,
|
|
||||||
...obj
|
...obj
|
||||||
} = input.convert(config);
|
} = input.convert(config);
|
||||||
|
|
||||||
|
|
@ -143,7 +141,6 @@ async function fillTemplate() {
|
||||||
obj[`${columns}-selected`] = 'selected';
|
obj[`${columns}-selected`] = 'selected';
|
||||||
obj[`${theme}-selected`] = 'selected';
|
obj[`${theme}-selected`] = 'selected';
|
||||||
obj.configAuth = configAuth ? '' : 'hidden';
|
obj.configAuth = configAuth ? '' : 'hidden';
|
||||||
obj.configPort = configPort ? '' : 'hidden';
|
|
||||||
|
|
||||||
const innerHTML = rendy(Template, obj);
|
const innerHTML = rendy(Template, obj);
|
||||||
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
import {encode} from '#common/entity';
|
import currify from 'currify';
|
||||||
|
|
||||||
const isBool = (a) => typeof a === 'boolean';
|
const isType = currify((type, object, name) => type === typeof object[name]);
|
||||||
const isString = (a) => typeof a === 'string';
|
const isBool = isType('boolean');
|
||||||
|
|
||||||
const {keys} = Object;
|
|
||||||
|
|
||||||
export function getElementByName(selector, element) {
|
export function getElementByName(selector, element) {
|
||||||
const str = `[data-name="js-${selector}"]`;
|
const str = `[data-name="js-${selector}"]`;
|
||||||
|
|
@ -21,19 +19,13 @@ export const getName = (element) => {
|
||||||
|
|
||||||
export const convert = (config) => {
|
export const convert = (config) => {
|
||||||
const result = config;
|
const result = config;
|
||||||
|
const array = Object.keys(config);
|
||||||
|
|
||||||
for (const name of keys(config)) {
|
const filtered = array.filter(isBool(config));
|
||||||
|
|
||||||
|
for (const name of filtered) {
|
||||||
const item = config[name];
|
const item = config[name];
|
||||||
|
result[name] = setState(item);
|
||||||
if (isBool(item)) {
|
|
||||||
result[name] = setState(item);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isString(item)) {
|
|
||||||
result[name] = encode(item);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -1,140 +0,0 @@
|
||||||
import {test, stub} from 'supertape';
|
|
||||||
import {
|
|
||||||
convert,
|
|
||||||
getName,
|
|
||||||
getValue,
|
|
||||||
setValue,
|
|
||||||
} from './input.js';
|
|
||||||
|
|
||||||
test('cloudcmd: client: config: input: convert', (t) => {
|
|
||||||
const result = convert({
|
|
||||||
name: 'hello <world>',
|
|
||||||
});
|
|
||||||
|
|
||||||
const expected = {
|
|
||||||
name: 'hello <world>',
|
|
||||||
};
|
|
||||||
|
|
||||||
t.deepEqual(result, expected);
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('cloudcmd: client: config: input: convert: bool', (t) => {
|
|
||||||
const result = convert({
|
|
||||||
auth: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const expected = {
|
|
||||||
auth: ' checked',
|
|
||||||
};
|
|
||||||
|
|
||||||
t.deepEqual(result, expected);
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('cloudcmd: client: config: input: convert: bool false', (t) => {
|
|
||||||
const result = convert({
|
|
||||||
auth: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const expected = {
|
|
||||||
auth: '',
|
|
||||||
};
|
|
||||||
|
|
||||||
t.deepEqual(result, expected);
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('cloudcmd: client: config: input: getName', (t) => {
|
|
||||||
const getAttribute = stub().returns('js-hello');
|
|
||||||
const element = {
|
|
||||||
getAttribute,
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = getName(element);
|
|
||||||
|
|
||||||
t.equal(result, 'hello', 'should strip js- prefix');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('cloudcmd: client: config: input: getValue: checkbox', (t) => {
|
|
||||||
const querySelector = stub().returns({
|
|
||||||
type: 'checkbox',
|
|
||||||
checked: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const element = {
|
|
||||||
querySelector,
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = getValue('auth', element);
|
|
||||||
|
|
||||||
t.ok(result, 'should return checked value');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('cloudcmd: client: config: input: getValue: number', (t) => {
|
|
||||||
const querySelector = stub().returns({
|
|
||||||
type: 'number',
|
|
||||||
value: '42',
|
|
||||||
});
|
|
||||||
|
|
||||||
const element = {
|
|
||||||
querySelector,
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = getValue('port', element);
|
|
||||||
|
|
||||||
t.equal(result, 42, 'should return number');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('cloudcmd: client: config: input: getValue: default', (t) => {
|
|
||||||
const querySelector = stub().returns({
|
|
||||||
type: 'text',
|
|
||||||
value: 'hello',
|
|
||||||
});
|
|
||||||
|
|
||||||
const element = {
|
|
||||||
querySelector,
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = getValue('name', element);
|
|
||||||
|
|
||||||
t.equal(result, 'hello', 'should return value as is');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('cloudcmd: client: config: input: setValue: checkbox', (t) => {
|
|
||||||
const el = {
|
|
||||||
type: 'checkbox',
|
|
||||||
checked: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
const querySelector = stub().returns(el);
|
|
||||||
const element = {
|
|
||||||
querySelector,
|
|
||||||
};
|
|
||||||
|
|
||||||
setValue('auth', true, element);
|
|
||||||
|
|
||||||
t.ok(el.checked, 'should set checked');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('cloudcmd: client: config: input: setValue: default', (t) => {
|
|
||||||
const el = {
|
|
||||||
type: 'text',
|
|
||||||
value: 'old',
|
|
||||||
};
|
|
||||||
|
|
||||||
const querySelector = stub().returns(el);
|
|
||||||
const element = {
|
|
||||||
querySelector,
|
|
||||||
};
|
|
||||||
|
|
||||||
setValue('name', 'new', element);
|
|
||||||
|
|
||||||
t.equal(el.value, 'new', 'should set value');
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
|
|
@ -1,34 +1,36 @@
|
||||||
/* global CloudCmd */
|
/* global CloudCmd */
|
||||||
/* global DOM */
|
/* global DOM */
|
||||||
import olark from '@cloudcmd/olark';
|
|
||||||
import * as Images from '#dom/images';
|
|
||||||
|
|
||||||
CloudCmd.Contact = {
|
'use strict';
|
||||||
init,
|
|
||||||
show,
|
CloudCmd.Contact = exports;
|
||||||
hide,
|
|
||||||
};
|
const olark = require('@cloudcmd/olark');
|
||||||
|
const Images = require('../dom/images.mjs');
|
||||||
|
|
||||||
const {Events} = DOM;
|
const {Events} = DOM;
|
||||||
const {Key} = CloudCmd;
|
const {Key} = CloudCmd;
|
||||||
|
|
||||||
export function init() {
|
module.exports.show = show;
|
||||||
|
module.exports.hide = hide;
|
||||||
|
|
||||||
|
module.exports.init = () => {
|
||||||
Events.addKey(onKey);
|
Events.addKey(onKey);
|
||||||
|
|
||||||
olark.identify('6216-545-10-4223');
|
olark.identify('6216-545-10-4223');
|
||||||
olark('api.box.onExpand', show);
|
olark('api.box.onExpand', show);
|
||||||
olark('api.box.onShow', show);
|
olark('api.box.onShow', show);
|
||||||
olark('api.box.onShrink', hide);
|
olark('api.box.onShrink', hide);
|
||||||
}
|
};
|
||||||
|
|
||||||
export function show() {
|
function show() {
|
||||||
Key.unsetBind();
|
Key.unsetBind();
|
||||||
Images.hide();
|
Images.hide();
|
||||||
|
|
||||||
olark('api.box.expand');
|
olark('api.box.expand');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hide() {
|
function hide() {
|
||||||
Key.setBind();
|
Key.setBind();
|
||||||
olark('api.box.hide');
|
olark('api.box.hide');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,9 @@
|
||||||
import * as Events from '#dom/events';
|
'use strict';
|
||||||
|
|
||||||
const {CloudCmd} = globalThis;
|
/* global CloudCmd */
|
||||||
|
CloudCmd.EditFileVim = exports;
|
||||||
|
|
||||||
CloudCmd.EditFileVim = {
|
const Events = require('#dom/events');
|
||||||
init,
|
|
||||||
show,
|
|
||||||
hide,
|
|
||||||
};
|
|
||||||
|
|
||||||
const {Key} = CloudCmd;
|
const {Key} = CloudCmd;
|
||||||
|
|
||||||
|
|
@ -18,11 +15,11 @@ const ConfigView = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function init() {
|
module.exports.init = async () => {
|
||||||
await CloudCmd.EditFile();
|
await CloudCmd.EditFile();
|
||||||
}
|
};
|
||||||
|
|
||||||
export async function show() {
|
module.exports.show = async () => {
|
||||||
Events.addKey(listener);
|
Events.addKey(listener);
|
||||||
|
|
||||||
const editFile = await CloudCmd.EditFile.show(ConfigView);
|
const editFile = await CloudCmd.EditFile.show(ConfigView);
|
||||||
|
|
@ -30,9 +27,11 @@ export async function show() {
|
||||||
editFile
|
editFile
|
||||||
.getEditor()
|
.getEditor()
|
||||||
.setKeyMap('vim');
|
.setKeyMap('vim');
|
||||||
}
|
};
|
||||||
|
|
||||||
export function hide() {
|
module.exports.hide = hide;
|
||||||
|
|
||||||
|
function hide() {
|
||||||
CloudCmd.Edit.hide();
|
CloudCmd.Edit.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,12 @@
|
||||||
/* global CloudCmd, DOM*/
|
'use strict';
|
||||||
import Format from 'format-io';
|
|
||||||
import {fullstore} from 'fullstore';
|
|
||||||
import exec from 'execon';
|
|
||||||
import {supermenu} from 'supermenu';
|
|
||||||
|
|
||||||
CloudCmd.EditFile = {
|
/* global CloudCmd, DOM*/
|
||||||
init,
|
CloudCmd.EditFile = exports;
|
||||||
show,
|
|
||||||
hide,
|
const Format = require('format-io');
|
||||||
isChanged,
|
const {fullstore} = require('fullstore');
|
||||||
};
|
const exec = require('execon');
|
||||||
|
const supermenu = require('supermenu');
|
||||||
|
|
||||||
const Info = DOM.CurrentInfo;
|
const Info = DOM.CurrentInfo;
|
||||||
|
|
||||||
|
|
@ -29,7 +26,7 @@ const ConfigView = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function init() {
|
module.exports.init = async () => {
|
||||||
isLoading(true);
|
isLoading(true);
|
||||||
|
|
||||||
await CloudCmd.Edit();
|
await CloudCmd.Edit();
|
||||||
|
|
@ -39,7 +36,7 @@ export async function init() {
|
||||||
setListeners(editor);
|
setListeners(editor);
|
||||||
|
|
||||||
isLoading(false);
|
isLoading(false);
|
||||||
}
|
};
|
||||||
|
|
||||||
function getName() {
|
function getName() {
|
||||||
const {name, isDir} = Info;
|
const {name, isDir} = Info;
|
||||||
|
|
@ -50,7 +47,7 @@ function getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function show(options) {
|
module.exports.show = async (options) => {
|
||||||
if (isLoading())
|
if (isLoading())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -89,9 +86,11 @@ export async function show(options) {
|
||||||
CloudCmd.Edit.show(optionsEdit);
|
CloudCmd.Edit.show(optionsEdit);
|
||||||
|
|
||||||
return CloudCmd.Edit;
|
return CloudCmd.Edit;
|
||||||
}
|
};
|
||||||
|
|
||||||
export function hide() {
|
module.exports.hide = hide;
|
||||||
|
|
||||||
|
function hide() {
|
||||||
CloudCmd.Edit.hide();
|
CloudCmd.Edit.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -177,7 +176,9 @@ function setMsgChanged(name) {
|
||||||
MSG_CHANGED = `Do you want to save changes to ${name}?`;
|
MSG_CHANGED = `Do you want to save changes to ${name}?`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function isChanged() {
|
module.exports.isChanged = isChanged;
|
||||||
|
|
||||||
|
async function isChanged() {
|
||||||
const editor = CloudCmd.Edit.getEditor();
|
const editor = CloudCmd.Edit.getEditor();
|
||||||
const is = editor.isChanged();
|
const is = editor.isChanged();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,9 @@
|
||||||
import * as Events from '#dom/events';
|
'use strict';
|
||||||
|
|
||||||
const {CloudCmd} = globalThis;
|
/* global CloudCmd */
|
||||||
|
CloudCmd.EditNamesVim = exports;
|
||||||
|
|
||||||
CloudCmd.EditNamesVim = {
|
const Events = require('#dom/events');
|
||||||
init,
|
|
||||||
show,
|
|
||||||
hide,
|
|
||||||
};
|
|
||||||
const {Key} = CloudCmd;
|
const {Key} = CloudCmd;
|
||||||
|
|
||||||
const ConfigView = {
|
const ConfigView = {
|
||||||
|
|
@ -17,20 +14,22 @@ const ConfigView = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function init() {
|
module.exports.init = async () => {
|
||||||
await CloudCmd.EditNames();
|
await CloudCmd.EditNames();
|
||||||
}
|
};
|
||||||
|
|
||||||
export function show() {
|
module.exports.show = () => {
|
||||||
Events.addKey(listener);
|
Events.addKey(listener);
|
||||||
|
|
||||||
CloudCmd.EditNames
|
CloudCmd.EditNames
|
||||||
.show(ConfigView)
|
.show(ConfigView)
|
||||||
.getEditor()
|
.getEditor()
|
||||||
.setKeyMap('vim');
|
.setKeyMap('vim');
|
||||||
}
|
};
|
||||||
|
|
||||||
export function hide() {
|
module.exports.hide = hide;
|
||||||
|
|
||||||
|
function hide() {
|
||||||
CloudCmd.Edit.hide();
|
CloudCmd.Edit.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,13 @@
|
||||||
import {tryToCatch} from 'try-to-catch';
|
'use strict';
|
||||||
import exec from 'execon';
|
|
||||||
import {supermenu} from 'supermenu';
|
|
||||||
import {multiRename} from 'multi-rename';
|
|
||||||
|
|
||||||
const {CloudCmd, DOM} = globalThis;
|
const {tryToCatch} = require('try-to-catch');
|
||||||
|
|
||||||
CloudCmd.EditNames = {
|
/* global CloudCmd, DOM */
|
||||||
init,
|
CloudCmd.EditNames = exports;
|
||||||
show,
|
|
||||||
hide,
|
const exec = require('execon');
|
||||||
isChanged,
|
const supermenu = require('supermenu');
|
||||||
};
|
const {multiRename} = require('multi-rename');
|
||||||
|
|
||||||
const Info = DOM.CurrentInfo;
|
const Info = DOM.CurrentInfo;
|
||||||
const {Dialog} = DOM;
|
const {Dialog} = DOM;
|
||||||
|
|
@ -25,13 +22,13 @@ const ConfigView = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function init() {
|
module.exports.init = async () => {
|
||||||
await CloudCmd.Edit();
|
await CloudCmd.Edit();
|
||||||
|
|
||||||
setListeners();
|
setListeners();
|
||||||
}
|
};
|
||||||
|
|
||||||
export function show(options) {
|
module.exports.show = (options) => {
|
||||||
const names = getActiveNames().join('\n');
|
const names = getActiveNames().join('\n');
|
||||||
const config = {
|
const config = {
|
||||||
...ConfigView,
|
...ConfigView,
|
||||||
|
|
@ -53,7 +50,7 @@ export function show(options) {
|
||||||
CloudCmd.Edit.show(config);
|
CloudCmd.Edit.show(config);
|
||||||
|
|
||||||
return CloudCmd.Edit;
|
return CloudCmd.Edit;
|
||||||
}
|
};
|
||||||
|
|
||||||
async function keyListener(event) {
|
async function keyListener(event) {
|
||||||
const ctrl = event.ctrlKey;
|
const ctrl = event.ctrlKey;
|
||||||
|
|
@ -63,10 +60,7 @@ async function keyListener(event) {
|
||||||
|
|
||||||
if (ctrlMeta && event.keyCode === Key.S) {
|
if (ctrlMeta && event.keyCode === Key.S) {
|
||||||
hide();
|
hide();
|
||||||
return;
|
} else if (ctrlMeta && event.keyCode === Key.P) {
|
||||||
}
|
|
||||||
|
|
||||||
if (ctrlMeta && event.keyCode === Key.P) {
|
|
||||||
const [, pattern] = await Dialog.prompt('Apply pattern:', '[n][e]');
|
const [, pattern] = await Dialog.prompt('Apply pattern:', '[n][e]');
|
||||||
pattern && applyPattern(pattern);
|
pattern && applyPattern(pattern);
|
||||||
}
|
}
|
||||||
|
|
@ -83,7 +77,9 @@ function getActiveNames() {
|
||||||
return DOM.getFilenames(DOM.getActiveFiles());
|
return DOM.getFilenames(DOM.getActiveFiles());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hide() {
|
module.exports.hide = hide;
|
||||||
|
|
||||||
|
function hide() {
|
||||||
CloudCmd.Edit.hide();
|
CloudCmd.Edit.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,7 +201,9 @@ function setMenu(event) {
|
||||||
Menu.show(position.x, position.y);
|
Menu.show(position.x, position.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function isChanged() {
|
module.exports.isChanged = isChanged;
|
||||||
|
|
||||||
|
async function isChanged() {
|
||||||
const editor = CloudCmd.Edit.getEditor();
|
const editor = CloudCmd.Edit.getEditor();
|
||||||
const msg = 'Apply new names?';
|
const msg = 'Apply new names?';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,23 @@
|
||||||
/* global CloudCmd */
|
/* global CloudCmd */
|
||||||
import {montag} from 'montag';
|
|
||||||
import {promisify} from 'es6-promisify';
|
|
||||||
import {tryToCatch} from 'try-to-catch';
|
|
||||||
import createElement from '@cloudcmd/create-element';
|
|
||||||
import load from 'load.js';
|
|
||||||
import {MAX_FILE_SIZE as maxSize} from '#common/cloudfunc';
|
|
||||||
import {time, timeEnd} from '#common/util';
|
|
||||||
|
|
||||||
export function getEditor() {
|
'use strict';
|
||||||
return editor;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const montag = require('montag');
|
||||||
|
|
||||||
|
const {promisify} = require('es6-promisify');
|
||||||
|
const {tryToCatch} = require('try-to-catch');
|
||||||
|
const createElement = require('@cloudcmd/create-element');
|
||||||
|
const load = require('load.js');
|
||||||
|
const {MAX_FILE_SIZE: maxSize} = require('../../common/cloudfunc.mjs');
|
||||||
|
|
||||||
|
const {time, timeEnd} = require('../../common/util');
|
||||||
|
const getEditor = () => editor;
|
||||||
const isFn = (a) => typeof a === 'function';
|
const isFn = (a) => typeof a === 'function';
|
||||||
const loadJS = load.js;
|
const loadJS = load.js;
|
||||||
|
|
||||||
const Name = 'Edit';
|
const Name = 'Edit';
|
||||||
|
|
||||||
CloudCmd[Name] = {
|
CloudCmd[Name] = exports;
|
||||||
init,
|
|
||||||
show,
|
|
||||||
hide,
|
|
||||||
getEditor,
|
|
||||||
getElement,
|
|
||||||
};
|
|
||||||
|
|
||||||
const EditorName = CloudCmd.config('editor');
|
const EditorName = CloudCmd.config('editor');
|
||||||
|
|
||||||
|
|
@ -38,12 +33,12 @@ const ConfigView = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function init() {
|
module.exports.init = async () => {
|
||||||
const element = create();
|
const element = create();
|
||||||
|
|
||||||
await CloudCmd.View();
|
await CloudCmd.View();
|
||||||
await loadFiles(element);
|
await loadFiles(element);
|
||||||
}
|
};
|
||||||
|
|
||||||
function create() {
|
function create() {
|
||||||
const element = createElement('div', {
|
const element = createElement('div', {
|
||||||
|
|
@ -84,7 +79,7 @@ function initConfig(options = {}) {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function show(options) {
|
module.exports.show = (options) => {
|
||||||
if (Loading)
|
if (Loading)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -93,15 +88,15 @@ export function show(options) {
|
||||||
getEditor().setOptions({
|
getEditor().setOptions({
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export function getElement() {
|
module.exports.getEditor = getEditor;
|
||||||
return Element;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function hide() {
|
module.exports.getElement = () => Element;
|
||||||
|
|
||||||
|
module.exports.hide = () => {
|
||||||
CloudCmd.View.hide();
|
CloudCmd.View.hide();
|
||||||
}
|
};
|
||||||
|
|
||||||
const loadFiles = async (element) => {
|
const loadFiles = async (element) => {
|
||||||
const prefix = `${CloudCmd.prefix}/${EditorName}`;
|
const prefix = `${CloudCmd.prefix}/${EditorName}`;
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
import * as Images from '#dom/images';
|
'use strict';
|
||||||
|
|
||||||
const {CloudCmd} = globalThis;
|
/* global CloudCmd */
|
||||||
|
CloudCmd.Help = exports;
|
||||||
|
|
||||||
CloudCmd.Help = {
|
const Images = require('../dom/images.mjs');
|
||||||
init,
|
|
||||||
show,
|
module.exports.init = () => {
|
||||||
hide,
|
Images.show.load('top');
|
||||||
};
|
};
|
||||||
|
|
||||||
export function init() {
|
module.exports.show = show;
|
||||||
Images.show.load('top');
|
module.exports.hide = hide;
|
||||||
}
|
|
||||||
|
|
||||||
export function show() {
|
function show() {
|
||||||
const positionLoad = 'top';
|
const positionLoad = 'top';
|
||||||
const relative = true;
|
const relative = true;
|
||||||
|
|
||||||
|
|
@ -22,6 +22,6 @@ export function show() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hide() {
|
function hide() {
|
||||||
CloudCmd.View.hide();
|
CloudCmd.View.hide();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,18 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
/* global CloudCmd */
|
/* global CloudCmd */
|
||||||
/* global Util */
|
/* global Util */
|
||||||
/* global DOM */
|
/* global DOM */
|
||||||
/* global Console */
|
/* global Console */
|
||||||
import exec from 'execon';
|
CloudCmd.Konsole = exports;
|
||||||
import currify from 'currify';
|
|
||||||
import {tryToCatch} from 'try-to-catch';
|
|
||||||
import {js as loadJS} from 'load.js';
|
|
||||||
import createElement from '@cloudcmd/create-element';
|
|
||||||
import * as Images from '#dom/images';
|
|
||||||
|
|
||||||
CloudCmd.Konsole = {
|
const exec = require('execon');
|
||||||
init,
|
const currify = require('currify');
|
||||||
show,
|
const {tryToCatch} = require('try-to-catch');
|
||||||
hide,
|
const loadJS = require('load.js').js;
|
||||||
};
|
const createElement = require('@cloudcmd/create-element');
|
||||||
|
|
||||||
|
const Images = require('../dom/images.mjs');
|
||||||
const {Dialog, CurrentInfo: Info} = DOM;
|
const {Dialog, CurrentInfo: Info} = DOM;
|
||||||
|
|
||||||
const rmLastSlash = (a) => a.replace(/\/$/, '') || '/';
|
const rmLastSlash = (a) => a.replace(/\/$/, '') || '/';
|
||||||
|
|
@ -29,7 +27,7 @@ const Name = 'Konsole';
|
||||||
let Element;
|
let Element;
|
||||||
let Loaded;
|
let Loaded;
|
||||||
|
|
||||||
export async function init() {
|
module.exports.init = async () => {
|
||||||
if (!config('console'))
|
if (!config('console'))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -38,13 +36,13 @@ export async function init() {
|
||||||
await CloudCmd.View();
|
await CloudCmd.View();
|
||||||
await load();
|
await load();
|
||||||
await create();
|
await create();
|
||||||
}
|
};
|
||||||
|
|
||||||
export function hide() {
|
module.exports.hide = () => {
|
||||||
CloudCmd.View.hide();
|
CloudCmd.View.hide();
|
||||||
}
|
};
|
||||||
|
|
||||||
export const clear = () => {
|
module.exports.clear = () => {
|
||||||
konsole.clear();
|
konsole.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -111,7 +109,7 @@ function authCheck(konsole) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function show(callback) {
|
module.exports.show = (callback) => {
|
||||||
if (!Loaded)
|
if (!Loaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -124,7 +122,7 @@ export function show(callback) {
|
||||||
exec(callback);
|
exec(callback);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
const load = async () => {
|
const load = async () => {
|
||||||
Util.time(`${Name} load`);
|
Util.time(`${Name} load`);
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,26 @@
|
||||||
import createElement from '@cloudcmd/create-element';
|
'use strict';
|
||||||
import * as Images from '#dom/images';
|
|
||||||
import {Markdown} from '#dom/rest';
|
|
||||||
import {alert} from '#dom/dialog';
|
|
||||||
|
|
||||||
const {CloudCmd} = globalThis;
|
/* global CloudCmd */
|
||||||
|
CloudCmd.Markdown = exports;
|
||||||
|
|
||||||
CloudCmd.Markdown = {
|
const createElement = require('@cloudcmd/create-element');
|
||||||
init,
|
|
||||||
show,
|
|
||||||
hide,
|
|
||||||
};
|
|
||||||
|
|
||||||
export async function init() {
|
const Images = require('../dom/images.mjs');
|
||||||
|
const {Markdown} = require('../dom/rest');
|
||||||
|
const {alert} = require('../dom/dialog');
|
||||||
|
|
||||||
|
module.exports.init = async () => {
|
||||||
Images.show.load('top');
|
Images.show.load('top');
|
||||||
await CloudCmd.View();
|
await CloudCmd.View();
|
||||||
}
|
};
|
||||||
|
|
||||||
export function hide() {
|
module.exports.show = show;
|
||||||
|
|
||||||
|
module.exports.hide = () => {
|
||||||
CloudCmd.View.hide();
|
CloudCmd.View.hide();
|
||||||
}
|
};
|
||||||
|
|
||||||
export async function show(name, options = {}) {
|
async function show(name, options = {}) {
|
||||||
const {positionLoad, relative} = options;
|
const {positionLoad, relative} = options;
|
||||||
|
|
||||||
Images.show.load(positionLoad);
|
Images.show.load(positionLoad);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import {supermenu} from 'supermenu';
|
import supermenu from 'supermenu';
|
||||||
|
|
||||||
const noop = () => {};
|
const noop = () => {};
|
||||||
const {CloudCmd} = globalThis;
|
const {CloudCmd} = globalThis;
|
||||||
|
|
@ -14,9 +14,8 @@ export const createCloudMenu = async (fm, options, menuData) => {
|
||||||
|
|
||||||
async function loadMenu() {
|
async function loadMenu() {
|
||||||
if (CloudCmd.config('menu') === 'aleman') {
|
if (CloudCmd.config('menu') === 'aleman') {
|
||||||
const {prefix} = CloudCmd;
|
|
||||||
const {host, protocol} = globalThis.location;
|
const {host, protocol} = globalThis.location;
|
||||||
const url = `${protocol}//${host}${prefix}/node_modules/aleman/menu/menu.js`;
|
const url = `${protocol}//${host}/node_modules/aleman/menu/menu.js`;
|
||||||
const {createMenu} = await import(/* webpackIgnore: true */url);
|
const {createMenu} = await import(/* webpackIgnore: true */url);
|
||||||
|
|
||||||
return createMenu;
|
return createMenu;
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
import exec from 'execon';
|
/* global CloudCmd, DOM */
|
||||||
import wrap from 'wraptile';
|
|
||||||
import createElement from '@cloudcmd/create-element';
|
'use strict';
|
||||||
import {getIdBySrc} from '#dom/load';
|
|
||||||
import * as RESTful from '#dom/rest';
|
const exec = require('execon');
|
||||||
import {FS} from '#common/cloudfunc';
|
const wrap = require('wraptile');
|
||||||
|
const createElement = require('@cloudcmd/create-element');
|
||||||
|
|
||||||
|
const {FS} = require('../../../common/cloudfunc.mjs');
|
||||||
|
const {getIdBySrc} = require('../../dom/load');
|
||||||
|
const RESTful = require('../../dom/rest');
|
||||||
|
|
||||||
const {CloudCmd, DOM} = globalThis;
|
|
||||||
const {config, Key} = CloudCmd;
|
const {config, Key} = CloudCmd;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|
@ -23,15 +27,11 @@ let MenuShowedName;
|
||||||
let MenuContext;
|
let MenuContext;
|
||||||
let MenuContextFile;
|
let MenuContextFile;
|
||||||
|
|
||||||
export const ENABLED = false;
|
module.exports.ENABLED = false;
|
||||||
|
|
||||||
CloudCmd.Menu = {
|
CloudCmd.Menu = exports;
|
||||||
init,
|
|
||||||
show,
|
|
||||||
hide,
|
|
||||||
};
|
|
||||||
|
|
||||||
export async function init() {
|
module.exports.init = async () => {
|
||||||
const {isAuth, menuDataFile} = getFileMenuData();
|
const {isAuth, menuDataFile} = getFileMenuData();
|
||||||
|
|
||||||
const fm = DOM.getFM();
|
const fm = DOM.getFM();
|
||||||
|
|
@ -45,7 +45,7 @@ export async function init() {
|
||||||
type: 'file',
|
type: 'file',
|
||||||
});
|
});
|
||||||
|
|
||||||
const {createCloudMenu} = await import('./cloudmenu.js');
|
const {createCloudMenu} = await import('./cloudmenu.mjs');
|
||||||
|
|
||||||
const {name} = fm.dataset;
|
const {name} = fm.dataset;
|
||||||
|
|
||||||
|
|
@ -56,21 +56,23 @@ export async function init() {
|
||||||
MenuContextFile.addContextMenuListener();
|
MenuContextFile.addContextMenuListener();
|
||||||
|
|
||||||
Events.addKey(listener);
|
Events.addKey(listener);
|
||||||
}
|
};
|
||||||
|
|
||||||
export function hide() {
|
module.exports.hide = hide;
|
||||||
|
|
||||||
|
function hide() {
|
||||||
MenuContext.hide();
|
MenuContext.hide();
|
||||||
MenuContextFile.hide();
|
MenuContextFile.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function show(position) {
|
module.exports.show = (position) => {
|
||||||
const {x, y} = getPosition(position);
|
const {x, y} = getPosition(position);
|
||||||
|
|
||||||
MenuContext.show(x, y);
|
MenuContext.show(x, y);
|
||||||
MenuContextFile.show(x, y);
|
MenuContextFile.show(x, y);
|
||||||
|
|
||||||
Images.hide();
|
Images.hide();
|
||||||
}
|
};
|
||||||
|
|
||||||
function getPosition(position) {
|
function getPosition(position) {
|
||||||
if (position)
|
if (position)
|
||||||
|
|
@ -296,7 +298,7 @@ function download(type) {
|
||||||
* no need in hash so we escape #
|
* no need in hash so we escape #
|
||||||
* and all other characters, like "%"
|
* and all other characters, like "%"
|
||||||
*/
|
*/
|
||||||
const encodedPath = encodeURI(path).replace(/#/g, '#');
|
const encodedPath = encodeURI(path).replace(/#/g, '%23');
|
||||||
const id = getIdBySrc(path);
|
const id = getIdBySrc(path);
|
||||||
|
|
||||||
let src;
|
let src;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
export const format = (operation, from, to) => {
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = (operation, from, to) => {
|
||||||
if (!to)
|
if (!to)
|
||||||
return `${operation} ${from}`;
|
return `${operation} ${from}`;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
import currify from 'currify';
|
'use strict';
|
||||||
|
|
||||||
|
const currify = require('currify');
|
||||||
|
|
||||||
const not = currify((array, value) => !array.includes(value));
|
const not = currify((array, value) => !array.includes(value));
|
||||||
const notOneOf = currify((a, b) => a.filter(not(b)));
|
const notOneOf = currify((a, b) => a.filter(not(b)));
|
||||||
|
|
||||||
export const getNextCurrentName = (currentName, names, removedNames) => {
|
module.exports = (currentName, names, removedNames) => {
|
||||||
const i = names.indexOf(currentName);
|
const i = names.indexOf(currentName);
|
||||||
|
|
||||||
const nextNames = notOneOf(names, removedNames);
|
const nextNames = notOneOf(names, removedNames);
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,10 @@ import {promisify} from 'es6-promisify';
|
||||||
import exec from 'execon';
|
import exec from 'execon';
|
||||||
import load from 'load.js';
|
import load from 'load.js';
|
||||||
import {tryToCatch} from 'try-to-catch';
|
import {tryToCatch} from 'try-to-catch';
|
||||||
import {encode} from '#common/entity';
|
import {encode} from '../../../common/entity.js';
|
||||||
import {removeExtension} from './remove-extension.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';
|
import getNextCurrentName from './get-next-current-name.js';
|
||||||
|
|
||||||
const {DOM, CloudCmd} = globalThis;
|
const {DOM, CloudCmd} = globalThis;
|
||||||
|
|
||||||
|
|
@ -190,11 +190,11 @@ function getPacker(type) {
|
||||||
return packTarFn;
|
return packTarFn;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hide() {
|
export const hide = () => {
|
||||||
CloudCmd.View.hide();
|
CloudCmd.View.hide();
|
||||||
}
|
};
|
||||||
|
|
||||||
export function show(operation, data) {
|
export const show = (operation, data) => {
|
||||||
if (!Loaded)
|
if (!Loaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -215,7 +215,7 @@ export function show(operation, data) {
|
||||||
|
|
||||||
if (operation === 'extract')
|
if (operation === 'extract')
|
||||||
return Operation.extract();
|
return Operation.extract();
|
||||||
}
|
};
|
||||||
|
|
||||||
Operation.copy = processFiles({
|
Operation.copy = processFiles({
|
||||||
type: 'copy',
|
type: 'copy',
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import {getExt} from '#common/util';
|
'use strict';
|
||||||
|
|
||||||
export const removeExtension = (name) => {
|
const {getExt} = require('../../../common/util');
|
||||||
|
|
||||||
|
module.exports = (name) => {
|
||||||
const ext = getExtension(name);
|
const ext = getExtension(name);
|
||||||
|
|
||||||
return name.replace(ext, '');
|
return name.replace(ext, '');
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
import test from 'supertape';
|
'use strict';
|
||||||
import {removeExtension} from './remove-extension.js';
|
|
||||||
|
const test = require('supertape');
|
||||||
|
const removeExtension = require(`./remove-extension`);
|
||||||
|
|
||||||
test('cloudcmd: client: modules: operation: removeExtension: .tar.gz', (t) => {
|
test('cloudcmd: client: modules: operation: removeExtension: .tar.gz', (t) => {
|
||||||
const name = 'hello';
|
const name = 'hello';
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/* global DOM */
|
/* global DOM */
|
||||||
import forEachKey from 'for-each-key';
|
import forEachKey from 'for-each-key';
|
||||||
import wraptile from 'wraptile';
|
import wraptile from 'wraptile';
|
||||||
import {format} from './format.js';
|
import format from './format.js';
|
||||||
|
|
||||||
const {Dialog, Images} = DOM;
|
const {Dialog, Images} = DOM;
|
||||||
|
|
||||||
|
|
@ -15,12 +15,15 @@ export const setListeners = (options) => (emitter) => {
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
let done;
|
let done;
|
||||||
|
let lastError;
|
||||||
|
|
||||||
const onAbort = wraptile(({emitter, operation}) => {
|
const onAbort = wraptile(({emitter, operation}) => {
|
||||||
emitter.abort();
|
emitter.abort();
|
||||||
|
|
||||||
const msg = `${operation} aborted`;
|
const msg = `${operation} aborted`;
|
||||||
|
|
||||||
|
lastError = true;
|
||||||
|
|
||||||
Dialog.alert(msg, {
|
Dialog.alert(msg, {
|
||||||
cancel: false,
|
cancel: false,
|
||||||
});
|
});
|
||||||
|
|
@ -37,10 +40,13 @@ export const setListeners = (options) => (emitter) => {
|
||||||
operation,
|
operation,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
let noProgress = true;
|
||||||
|
|
||||||
const listeners = {
|
const listeners = {
|
||||||
progress: (value) => {
|
progress: (value) => {
|
||||||
done = value === 100;
|
done = value === 100;
|
||||||
progress.setProgress(value);
|
progress.setProgress(value);
|
||||||
|
noProgress = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
end: () => {
|
end: () => {
|
||||||
|
|
@ -48,10 +54,13 @@ export const setListeners = (options) => (emitter) => {
|
||||||
forEachKey(removeListener, listeners);
|
forEachKey(removeListener, listeners);
|
||||||
progress.remove();
|
progress.remove();
|
||||||
|
|
||||||
callback();
|
if (lastError || done || noProgress)
|
||||||
|
callback();
|
||||||
},
|
},
|
||||||
|
|
||||||
error: async (error) => {
|
error: async (error) => {
|
||||||
|
lastError = error;
|
||||||
|
|
||||||
if (noContinue) {
|
if (noContinue) {
|
||||||
listeners.end(error);
|
listeners.end(error);
|
||||||
Dialog.alert(error);
|
Dialog.alert(error);
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
import _scrollIntoViewIfNeeded from 'scroll-into-view-if-needed';
|
'use strict';
|
||||||
|
|
||||||
|
require('domtokenlist-shim');
|
||||||
|
|
||||||
|
const _scrollIntoViewIfNeeded = require('scroll-into-view-if-needed');
|
||||||
|
|
||||||
globalThis.DOM = globalThis.DOM || {};
|
globalThis.DOM = globalThis.DOM || {};
|
||||||
|
|
||||||
export const scrollIntoViewIfNeeded = (el, overrides = {}) => {
|
const scrollIntoViewIfNeeded = (el, overrides = {}) => {
|
||||||
const {
|
const {
|
||||||
scroll = _scrollIntoViewIfNeeded,
|
scroll = _scrollIntoViewIfNeeded,
|
||||||
} = overrides;
|
} = overrides;
|
||||||
|
|
@ -13,3 +17,4 @@ export const scrollIntoViewIfNeeded = (el, overrides = {}) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
globalThis.DOM.scrollIntoViewIfNeeded = scrollIntoViewIfNeeded;
|
globalThis.DOM.scrollIntoViewIfNeeded = scrollIntoViewIfNeeded;
|
||||||
|
module.exports.scrollIntoViewIfNeeded = scrollIntoViewIfNeeded;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import {test, stub} from 'supertape';
|
'use strict';
|
||||||
import {scrollIntoViewIfNeeded} from './polyfill.js';
|
|
||||||
|
|
||||||
test('cloudcmd: client: polyfill: scrollIntoViewIfNeeded', (t) => {
|
const {test, stub} = require('supertape');
|
||||||
|
const {scrollIntoViewIfNeeded} = require('./polyfill');
|
||||||
|
|
||||||
|
test('cloudcmd: client: polyfill: scrollIntoViewIfNeaded', (t) => {
|
||||||
const scroll = stub();
|
const scroll = stub();
|
||||||
const el = {};
|
const el = {};
|
||||||
|
|
||||||
|
|
@ -15,6 +17,6 @@ test('cloudcmd: client: polyfill: scrollIntoViewIfNeeded', (t) => {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
t.calledWith(scroll, args, 'should call scrollIntoViewIfNeeded');
|
t.calledWith(scroll, args, 'should call scrollIntoViewIfNeaded');
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,21 @@
|
||||||
import '../../css/terminal.css';
|
'use strict';
|
||||||
import {promisify} from 'es6-promisify';
|
|
||||||
import {tryToCatch} from 'try-to-catch';
|
/* global CloudCmd, gritty */
|
||||||
import {fullstore} from 'fullstore';
|
const {promisify} = require('es6-promisify');
|
||||||
import exec from 'execon';
|
const {tryToCatch} = require('try-to-catch');
|
||||||
import load from 'load.js';
|
const {fullstore} = require('fullstore');
|
||||||
import DOM from '#dom';
|
|
||||||
import * as Images from '#dom/images';
|
require('../../css/terminal.css');
|
||||||
|
|
||||||
|
const exec = require('execon');
|
||||||
|
const load = require('load.js');
|
||||||
|
const DOM = require('../dom');
|
||||||
|
const Images = require('../dom/images.mjs');
|
||||||
|
|
||||||
const {Dialog} = DOM;
|
const {Dialog} = DOM;
|
||||||
const {CloudCmd} = globalThis;
|
|
||||||
const {Key, config} = CloudCmd;
|
const {Key, config} = CloudCmd;
|
||||||
|
|
||||||
CloudCmd.TerminalRun = {
|
CloudCmd.TerminalRun = exports;
|
||||||
init,
|
|
||||||
show,
|
|
||||||
hide,
|
|
||||||
};
|
|
||||||
|
|
||||||
let Loaded;
|
let Loaded;
|
||||||
let Terminal;
|
let Terminal;
|
||||||
|
|
@ -40,7 +40,7 @@ const loadAll = async () => {
|
||||||
Loaded = true;
|
Loaded = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function init() {
|
module.exports.init = async () => {
|
||||||
if (!config('terminal'))
|
if (!config('terminal'))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -48,13 +48,9 @@ export async function init() {
|
||||||
|
|
||||||
await CloudCmd.View();
|
await CloudCmd.View();
|
||||||
await loadAll();
|
await loadAll();
|
||||||
}
|
};
|
||||||
|
|
||||||
export async function show(options = {}) {
|
module.exports.show = promisify((options = {}, fn) => {
|
||||||
return await runTerminal(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
const runTerminal = promisify((options, fn) => {
|
|
||||||
if (!Loaded)
|
if (!Loaded)
|
||||||
return fn(null, -1);
|
return fn(null, -1);
|
||||||
|
|
||||||
|
|
@ -73,7 +69,9 @@ const runTerminal = promisify((options, fn) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
export function hide() {
|
module.exports.hide = hide;
|
||||||
|
|
||||||
|
function hide() {
|
||||||
CloudCmd.View.hide();
|
CloudCmd.View.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,7 +108,7 @@ function create(createOptions) {
|
||||||
|
|
||||||
let commandExit = false;
|
let commandExit = false;
|
||||||
|
|
||||||
const {socket, terminal} = globalThis.gritty(document.body, options);
|
const {socket, terminal} = gritty(document.body, options);
|
||||||
|
|
||||||
Socket = socket;
|
Socket = socket;
|
||||||
Terminal = terminal;
|
Terminal = terminal;
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
import '#css/terminal.css';
|
'use strict';
|
||||||
import {tryToCatch} from 'try-to-catch';
|
|
||||||
import exec from 'execon';
|
/* global CloudCmd */
|
||||||
import load from 'load.js';
|
/* global gritty */
|
||||||
import * as Images from '#dom/images';
|
const {tryToCatch} = require('try-to-catch');
|
||||||
import DOM from '#dom';
|
|
||||||
|
require('../../css/terminal.css');
|
||||||
|
|
||||||
|
const exec = require('execon');
|
||||||
|
const load = require('load.js');
|
||||||
|
const DOM = require('../dom');
|
||||||
|
const Images = require('../dom/images.mjs');
|
||||||
|
|
||||||
const loadParallel = load.parallel;
|
const loadParallel = load.parallel;
|
||||||
|
|
||||||
const {CloudCmd} = globalThis;
|
|
||||||
|
|
||||||
const {Dialog} = DOM;
|
const {Dialog} = DOM;
|
||||||
const {Key, config} = globalThis.CloudCmd;
|
const {Key, config} = CloudCmd;
|
||||||
|
|
||||||
CloudCmd.Terminal = {
|
CloudCmd.Terminal = exports;
|
||||||
init,
|
|
||||||
show,
|
|
||||||
hide,
|
|
||||||
};
|
|
||||||
|
|
||||||
let Loaded;
|
let Loaded;
|
||||||
let Terminal;
|
let Terminal;
|
||||||
|
|
@ -39,7 +39,7 @@ const loadAll = async () => {
|
||||||
Loaded = true;
|
Loaded = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function init() {
|
module.exports.init = async () => {
|
||||||
if (!config('terminal'))
|
if (!config('terminal'))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -48,9 +48,12 @@ export async function init() {
|
||||||
await CloudCmd.View();
|
await CloudCmd.View();
|
||||||
await loadAll();
|
await loadAll();
|
||||||
create();
|
create();
|
||||||
}
|
};
|
||||||
|
|
||||||
export function hide() {
|
module.exports.show = show;
|
||||||
|
module.exports.hide = hide;
|
||||||
|
|
||||||
|
function hide() {
|
||||||
CloudCmd.View.hide();
|
CloudCmd.View.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,7 +78,7 @@ function create() {
|
||||||
fontFamily: 'Droid Sans Mono',
|
fontFamily: 'Droid Sans Mono',
|
||||||
};
|
};
|
||||||
|
|
||||||
const {socket, terminal} = globalThis.gritty(document.body, options);
|
const {socket, terminal} = gritty(document.body, options);
|
||||||
|
|
||||||
Socket = socket;
|
Socket = socket;
|
||||||
Terminal = terminal;
|
Terminal = terminal;
|
||||||
|
|
@ -98,7 +101,7 @@ function authCheck(spawn) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function show() {
|
function show() {
|
||||||
if (!Loaded)
|
if (!Loaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,23 @@
|
||||||
/* global CloudCmd, DOM */
|
/* global CloudCmd, DOM */
|
||||||
import createElement from '@cloudcmd/create-element';
|
|
||||||
import * as Files from '#dom/files';
|
|
||||||
import {uploadFiles} from '#dom/upload-files';
|
|
||||||
import * as Images from '#dom/images';
|
|
||||||
|
|
||||||
CloudCmd.Upload = {
|
'use strict';
|
||||||
init,
|
|
||||||
show,
|
|
||||||
hide,
|
|
||||||
};
|
|
||||||
|
|
||||||
export async function init() {
|
CloudCmd.Upload = exports;
|
||||||
|
|
||||||
|
const createElement = require('@cloudcmd/create-element');
|
||||||
|
const Files = require('../dom/files');
|
||||||
|
const Images = require('../dom/images.mjs');
|
||||||
|
const uploadFiles = require('../dom/upload-files');
|
||||||
|
|
||||||
|
module.exports.init = async () => {
|
||||||
Images.show.load('top');
|
Images.show.load('top');
|
||||||
await CloudCmd.View();
|
await CloudCmd.View();
|
||||||
}
|
};
|
||||||
|
|
||||||
export async function show() {
|
module.exports.show = show;
|
||||||
|
module.exports.hide = hide;
|
||||||
|
|
||||||
|
async function show() {
|
||||||
Images.show.load('top');
|
Images.show.load('top');
|
||||||
|
|
||||||
const innerHTML = await Files.get('upload');
|
const innerHTML = await Files.get('upload');
|
||||||
|
|
@ -47,7 +49,7 @@ export async function show() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hide() {
|
function hide() {
|
||||||
CloudCmd.View.hide();
|
CloudCmd.View.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
export const getUserMenu = (menuFn) => {
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = (menuFn) => {
|
||||||
const module = {};
|
const module = {};
|
||||||
const fn = Function('module', menuFn);
|
const fn = Function('module', menuFn);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
import test from 'supertape';
|
'use strict';
|
||||||
import {getUserMenu} from './get-user-menu.js';
|
|
||||||
|
const test = require('supertape');
|
||||||
|
const getUserMenu = require('./get-user-menu');
|
||||||
|
|
||||||
test('user-menu: getUserMenu', (t) => {
|
test('user-menu: getUserMenu', (t) => {
|
||||||
const menu = `module.exports = {
|
const menu = `module.exports = {
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue