@dynamicweb/cli 1.0.15 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +244 -171
- package/bin/commands/command.js +88 -88
- package/bin/commands/config.js +54 -54
- package/bin/commands/database.js +65 -71
- package/bin/commands/env.js +174 -155
- package/bin/commands/files.js +378 -300
- package/bin/commands/install.js +64 -63
- package/bin/commands/login.js +228 -218
- package/bin/commands/query.js +99 -101
- package/bin/commands/swift.js +78 -78
- package/bin/downloader.js +66 -66
- package/bin/extractor.js +28 -28
- package/bin/index.js +73 -61
- package/bin/utils.js +112 -125
- package/package.json +51 -42
package/bin/index.js
CHANGED
|
@@ -1,61 +1,73 @@
|
|
|
1
|
-
#! /usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import yargs from 'yargs/yargs';
|
|
4
|
-
import { hideBin } from 'yargs/helpers';
|
|
5
|
-
import { loginCommand } from './commands/login.js';
|
|
6
|
-
import { envCommand } from './commands/env.js';
|
|
7
|
-
import { configCommand, setupConfig, getConfig } from './commands/config.js';
|
|
8
|
-
import { installCommand } from './commands/install.js';
|
|
9
|
-
import { filesCommand } from './commands/files.js';
|
|
10
|
-
import { swiftCommand } from './commands/swift.js';
|
|
11
|
-
import { databaseCommand } from './commands/database.js';
|
|
12
|
-
import { queryCommand } from './commands/query.js';
|
|
13
|
-
import { commandCommand } from './commands/command.js';
|
|
14
|
-
|
|
15
|
-
setupConfig();
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
.
|
|
20
|
-
.command(
|
|
21
|
-
.command(
|
|
22
|
-
.command(
|
|
23
|
-
.command(
|
|
24
|
-
.command(
|
|
25
|
-
.command(
|
|
26
|
-
.command(
|
|
27
|
-
.command(
|
|
28
|
-
.command(
|
|
29
|
-
.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
console.log(`
|
|
57
|
-
console.log(`
|
|
58
|
-
console.log(`
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import yargs from 'yargs/yargs';
|
|
4
|
+
import { hideBin } from 'yargs/helpers';
|
|
5
|
+
import { loginCommand } from './commands/login.js';
|
|
6
|
+
import { envCommand } from './commands/env.js';
|
|
7
|
+
import { configCommand, setupConfig, getConfig } from './commands/config.js';
|
|
8
|
+
import { installCommand } from './commands/install.js';
|
|
9
|
+
import { filesCommand } from './commands/files.js';
|
|
10
|
+
import { swiftCommand } from './commands/swift.js';
|
|
11
|
+
import { databaseCommand } from './commands/database.js';
|
|
12
|
+
import { queryCommand } from './commands/query.js';
|
|
13
|
+
import { commandCommand } from './commands/command.js';
|
|
14
|
+
|
|
15
|
+
setupConfig();
|
|
16
|
+
showGitBashRelativePathWarning();
|
|
17
|
+
|
|
18
|
+
yargs(hideBin(process.argv))
|
|
19
|
+
.scriptName('dw')
|
|
20
|
+
.command(baseCommand())
|
|
21
|
+
.command(loginCommand())
|
|
22
|
+
.command(envCommand())
|
|
23
|
+
.command(installCommand())
|
|
24
|
+
.command(configCommand())
|
|
25
|
+
.command(filesCommand())
|
|
26
|
+
.command(swiftCommand())
|
|
27
|
+
.command(databaseCommand())
|
|
28
|
+
.command(queryCommand())
|
|
29
|
+
.command(commandCommand())
|
|
30
|
+
.option('verbose', {
|
|
31
|
+
alias: 'v',
|
|
32
|
+
type: 'boolean',
|
|
33
|
+
description: 'Run with verbose logging'
|
|
34
|
+
})
|
|
35
|
+
.option('protocol', {
|
|
36
|
+
description: 'Allows setting the protocol used, only used together with --host, defaulting to https'
|
|
37
|
+
})
|
|
38
|
+
.option('host', {
|
|
39
|
+
description: 'Allows setting the host used, only allowed if an --apiKey is specified'
|
|
40
|
+
})
|
|
41
|
+
.option('apiKey', {
|
|
42
|
+
description: 'Allows setting the apiKey for an environmentless execution of the CLI command'
|
|
43
|
+
})
|
|
44
|
+
.demandCommand()
|
|
45
|
+
.parse()
|
|
46
|
+
|
|
47
|
+
function baseCommand() {
|
|
48
|
+
return {
|
|
49
|
+
command: '$0',
|
|
50
|
+
describe: 'Shows the current env and user being used',
|
|
51
|
+
handler: () => {
|
|
52
|
+
if (Object.keys(getConfig()).length === 0) {
|
|
53
|
+
console.log('To login to a solution use `dw login`')
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
console.log(`Environment: ${getConfig()?.current?.env}`)
|
|
57
|
+
console.log(`User: ${getConfig()?.env[getConfig()?.current?.env]?.current?.user}`)
|
|
58
|
+
console.log(`Protocol: ${getConfig()?.env[getConfig()?.current?.env]?.protocol}`)
|
|
59
|
+
console.log(`Host: ${getConfig()?.env[getConfig()?.current?.env]?.host}`)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function showGitBashRelativePathWarning() {
|
|
65
|
+
const isGitBash = !!process.env.MSYSTEM;
|
|
66
|
+
const pathConversionDisabled = process.env.MSYS_NO_PATHCONV === '1';
|
|
67
|
+
|
|
68
|
+
if (isGitBash && !pathConversionDisabled) {
|
|
69
|
+
console.warn('You appear to have path conversion turned on in your shell.');
|
|
70
|
+
console.warn('If you are using relative paths, this may interfere.');
|
|
71
|
+
console.warn('Please see https://doc.dynamicweb.dev/documentation/fundamentals/code/CLI.html for more information.');
|
|
72
|
+
}
|
|
73
|
+
}
|
package/bin/utils.js
CHANGED
|
@@ -1,125 +1,112 @@
|
|
|
1
|
-
import
|
|
2
|
-
import logUpdate from 'log-update';
|
|
3
|
-
|
|
4
|
-
const WRITE_THROTTLE_MS = 500;
|
|
5
|
-
|
|
6
|
-
export async function interactiveConfirm(question, func) {
|
|
7
|
-
await
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
* - "Zs" if the duration is less than 1 minute.
|
|
114
|
-
*
|
|
115
|
-
* @param {number} ms - The duration in milliseconds.
|
|
116
|
-
* @returns {string} The formatted elapsed time string.
|
|
117
|
-
*/
|
|
118
|
-
export function formatElapsed(ms) {
|
|
119
|
-
const sec = Math.floor(ms / 1000);
|
|
120
|
-
const min = Math.floor(sec / 60);
|
|
121
|
-
const hr = Math.floor(min / 60);
|
|
122
|
-
if (hr > 0) return `${hr}h ${min % 60}m ${sec % 60}s`;
|
|
123
|
-
if (min > 0) return `${min}m ${sec % 60}s`;
|
|
124
|
-
return `${sec}s`;
|
|
125
|
-
}
|
|
1
|
+
import { confirm } from '@inquirer/prompts';
|
|
2
|
+
import logUpdate from 'log-update';
|
|
3
|
+
|
|
4
|
+
const WRITE_THROTTLE_MS = 500;
|
|
5
|
+
|
|
6
|
+
export async function interactiveConfirm(question, func) {
|
|
7
|
+
const result = await confirm({ message: question, default: true });
|
|
8
|
+
if (!result) return;
|
|
9
|
+
await func();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Creates a throttled status updater that periodically logs status messages and elapsed time.
|
|
14
|
+
*
|
|
15
|
+
* The updater allows you to update the displayed status message at any time, but throttles the actual log updates
|
|
16
|
+
* to the specified interval. When called with no message, the updater stops and finalizes the log output.
|
|
17
|
+
*
|
|
18
|
+
* @param {number} [intervalMs=WRITE_THROTTLE_MS] - The interval in milliseconds at which to update the log output.
|
|
19
|
+
* @returns {{
|
|
20
|
+
* update: (message?: string) => void,
|
|
21
|
+
* stop: () => void
|
|
22
|
+
* }} An object with `update` and `stop` methods:
|
|
23
|
+
* - `update(message)`: Updates the status message and starts the updater if not already running. If called with no message, stops the updater.
|
|
24
|
+
* - `stop()`: Stops the updater and finalizes the log output.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* const updater = createThrottledStatusUpdater(500);
|
|
28
|
+
* updater.update('Processing...');
|
|
29
|
+
* // ... later
|
|
30
|
+
* updater.update('Still working...');
|
|
31
|
+
* // ... when done
|
|
32
|
+
* updater.update(); // or updater.stop();
|
|
33
|
+
*/
|
|
34
|
+
export function createThrottledStatusUpdater(intervalMs = WRITE_THROTTLE_MS) {
|
|
35
|
+
let latestMessage;
|
|
36
|
+
let timer = null;
|
|
37
|
+
let stopped = false;
|
|
38
|
+
let startTime;
|
|
39
|
+
|
|
40
|
+
function write() {
|
|
41
|
+
const elapsed = `Elapsed:\t${formatElapsed(Date.now() - startTime)}`;
|
|
42
|
+
const lines = latestMessage ? [latestMessage, elapsed] : [elapsed];
|
|
43
|
+
logUpdate(lines.join('\n'));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function start() {
|
|
47
|
+
if (timer) return;
|
|
48
|
+
|
|
49
|
+
startTime = Date.now();
|
|
50
|
+
|
|
51
|
+
timer = setInterval(() => {
|
|
52
|
+
if (stopped) return;
|
|
53
|
+
write();
|
|
54
|
+
}, intervalMs);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function stop() {
|
|
58
|
+
stopped = true;
|
|
59
|
+
if (timer) clearInterval(timer);
|
|
60
|
+
write();
|
|
61
|
+
logUpdate.done();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// The updater function you call from anywhere
|
|
65
|
+
function update(message) {
|
|
66
|
+
if (!message) {
|
|
67
|
+
stop();
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
latestMessage = message;
|
|
71
|
+
start();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
update,
|
|
76
|
+
stop
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Converts a number of bytes into a human-readable string with appropriate units.
|
|
82
|
+
*
|
|
83
|
+
* @param {number} bytes - The number of bytes to format.
|
|
84
|
+
* @returns {string} The formatted string representing the size in appropriate units (Bytes, KB, MB, GB, TB, PB).
|
|
85
|
+
*/
|
|
86
|
+
export function formatBytes(bytes) {
|
|
87
|
+
if (bytes === 0) return '0 Bytes';
|
|
88
|
+
const k = 1024;
|
|
89
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];
|
|
90
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
91
|
+
return (bytes / Math.pow(k, i)).toFixed(2) + ' ' + sizes[i];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Formats a duration given in milliseconds into a human-readable string.
|
|
96
|
+
*
|
|
97
|
+
* The output is in the format:
|
|
98
|
+
* - "Xh Ym Zs" if the duration is at least 1 hour,
|
|
99
|
+
* - "Ym Zs" if the duration is at least 1 minute but less than 1 hour,
|
|
100
|
+
* - "Zs" if the duration is less than 1 minute.
|
|
101
|
+
*
|
|
102
|
+
* @param {number} ms - The duration in milliseconds.
|
|
103
|
+
* @returns {string} The formatted elapsed time string.
|
|
104
|
+
*/
|
|
105
|
+
export function formatElapsed(ms) {
|
|
106
|
+
const sec = Math.floor(ms / 1000);
|
|
107
|
+
const min = Math.floor(sec / 60);
|
|
108
|
+
const hr = Math.floor(min / 60);
|
|
109
|
+
if (hr > 0) return `${hr}h ${min % 60}m ${sec % 60}s`;
|
|
110
|
+
if (min > 0) return `${min}m ${sec % 60}s`;
|
|
111
|
+
return `${sec}s`;
|
|
112
|
+
}
|
package/package.json
CHANGED
|
@@ -1,42 +1,51 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@dynamicweb/cli",
|
|
3
|
-
"type": "module",
|
|
4
|
-
"description": "
|
|
5
|
-
"version": "1.0
|
|
6
|
-
"main": "bin/index.js",
|
|
7
|
-
"files": [
|
|
8
|
-
"bin
|
|
9
|
-
],
|
|
10
|
-
"keywords": [
|
|
11
|
-
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
}
|
|
42
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@dynamicweb/cli",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"description": "CLI for interacting with Dynamicweb 10 solutions from the command line.",
|
|
5
|
+
"version": "1.1.0",
|
|
6
|
+
"main": "bin/index.js",
|
|
7
|
+
"files": [
|
|
8
|
+
"bin/**"
|
|
9
|
+
],
|
|
10
|
+
"keywords": [
|
|
11
|
+
"dynamicweb",
|
|
12
|
+
"cli",
|
|
13
|
+
"dynamicweb10",
|
|
14
|
+
"cms",
|
|
15
|
+
"devops"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
19
|
+
},
|
|
20
|
+
"author": "Dynamicweb A/S (https://www.dynamicweb.com)",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/dynamicweb/CLI.git"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/dynamicweb/CLI#readme",
|
|
26
|
+
"contributors": [
|
|
27
|
+
"Dynamicweb A/S"
|
|
28
|
+
],
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"bin": {
|
|
31
|
+
"dw": "bin/index.js"
|
|
32
|
+
},
|
|
33
|
+
"bugs": {
|
|
34
|
+
"url": "https://github.com/dynamicweb/CLI/issues"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=20.12.0"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@inquirer/prompts": "^8.4.1",
|
|
44
|
+
"degit": "^2.8.4",
|
|
45
|
+
"extract-zip": "^2.0.1",
|
|
46
|
+
"form-data": "^4.0.0",
|
|
47
|
+
"log-update": "^6.1.0",
|
|
48
|
+
"node-fetch": "^3.2.10",
|
|
49
|
+
"yargs": "^17.5.1"
|
|
50
|
+
}
|
|
51
|
+
}
|