@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/commands/config.js
CHANGED
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
import os from 'os';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
|
|
4
|
-
const configLocation = os.homedir() + '/.dwc';
|
|
5
|
-
let localConfig;
|
|
6
|
-
|
|
7
|
-
export function configCommand() {
|
|
8
|
-
return {
|
|
9
|
-
command: 'config',
|
|
10
|
-
describe: 'Edit the configs located in
|
|
11
|
-
handler: (argv) => handleConfig(argv),
|
|
12
|
-
builder: {
|
|
13
|
-
prop: {
|
|
14
|
-
type: 'string',
|
|
15
|
-
describe: 'Path to your config property, i.e --env.dev.host=newHost:1000'
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function setupConfig() {
|
|
22
|
-
try {
|
|
23
|
-
localConfig = JSON.parse(fs.readFileSync(configLocation));
|
|
24
|
-
} catch (e) {
|
|
25
|
-
localConfig = {}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function getConfig() {
|
|
30
|
-
return localConfig;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function handleConfig(argv) {
|
|
34
|
-
Object.keys(argv).forEach(a => {
|
|
35
|
-
if (a != '_' && a != '$0') {
|
|
36
|
-
resolveConfig(a, argv[a],
|
|
37
|
-
updateConfig();
|
|
38
|
-
}
|
|
39
|
-
})
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function updateConfig() {
|
|
43
|
-
fs.writeFileSync(configLocation, JSON.stringify(localConfig));
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function resolveConfig(key, obj, conf) {
|
|
47
|
-
if (typeof obj !== 'object' || !(obj instanceof Object)) {
|
|
48
|
-
return obj;
|
|
49
|
-
}
|
|
50
|
-
Object.keys(obj).forEach(a => {
|
|
51
|
-
conf[a] = conf[a] || {};
|
|
52
|
-
conf[a] = resolveConfig(key, obj[a], conf[a]);
|
|
53
|
-
})
|
|
54
|
-
return conf;
|
|
1
|
+
import os from 'os';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
|
|
4
|
+
const configLocation = os.homedir() + '/.dwc';
|
|
5
|
+
let localConfig;
|
|
6
|
+
|
|
7
|
+
export function configCommand() {
|
|
8
|
+
return {
|
|
9
|
+
command: 'config',
|
|
10
|
+
describe: 'Edit the configs located in ~/.dwc',
|
|
11
|
+
handler: (argv) => handleConfig(argv),
|
|
12
|
+
builder: {
|
|
13
|
+
prop: {
|
|
14
|
+
type: 'string',
|
|
15
|
+
describe: 'Path to your config property, i.e --env.dev.host=newHost:1000'
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function setupConfig() {
|
|
22
|
+
try {
|
|
23
|
+
localConfig = JSON.parse(fs.readFileSync(configLocation));
|
|
24
|
+
} catch (e) {
|
|
25
|
+
localConfig = {}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function getConfig() {
|
|
30
|
+
return localConfig;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function handleConfig(argv) {
|
|
34
|
+
Object.keys(argv).forEach(a => {
|
|
35
|
+
if (a != '_' && a != '$0') {
|
|
36
|
+
localConfig[a] = resolveConfig(a, argv[a], localConfig[a] || {});
|
|
37
|
+
updateConfig();
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function updateConfig() {
|
|
43
|
+
fs.writeFileSync(configLocation, JSON.stringify(localConfig));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function resolveConfig(key, obj, conf) {
|
|
47
|
+
if (typeof obj !== 'object' || !(obj instanceof Object)) {
|
|
48
|
+
return obj;
|
|
49
|
+
}
|
|
50
|
+
Object.keys(obj).forEach(a => {
|
|
51
|
+
conf[a] = conf[a] || {};
|
|
52
|
+
conf[a] = resolveConfig(key, obj[a], conf[a]);
|
|
53
|
+
})
|
|
54
|
+
return conf;
|
|
55
55
|
}
|
package/bin/commands/database.js
CHANGED
|
@@ -1,72 +1,66 @@
|
|
|
1
|
-
import fetch from 'node-fetch';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import _path from 'path';
|
|
4
|
-
import { setupEnv, getAgent } from './env.js';
|
|
5
|
-
import { setupUser } from './login.js';
|
|
6
|
-
|
|
7
|
-
export function databaseCommand() {
|
|
8
|
-
return {
|
|
9
|
-
command: 'database [path]',
|
|
10
|
-
describe: 'Handles database',
|
|
11
|
-
builder: (yargs) => {
|
|
12
|
-
return yargs
|
|
13
|
-
.positional('path', {
|
|
14
|
-
describe: 'Path to the .bacpac file',
|
|
15
|
-
default: '.'
|
|
16
|
-
})
|
|
17
|
-
.option('export', {
|
|
18
|
-
alias: 'e',
|
|
19
|
-
type: 'boolean',
|
|
20
|
-
description: 'Exports the solutions database to a .bacpac file at [path]'
|
|
21
|
-
})
|
|
22
|
-
},
|
|
23
|
-
handler: (argv) => {
|
|
24
|
-
if (argv.verbose) console.info(`Handling database with path: ${argv.path}`)
|
|
25
|
-
handleDatabase(argv)
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async function handleDatabase(argv) {
|
|
31
|
-
let env = await setupEnv(argv);
|
|
32
|
-
let user = await setupUser(argv, env);
|
|
33
|
-
|
|
34
|
-
if (argv.export) {
|
|
35
|
-
await download(env, user, argv.path, argv.verbose);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async function download(env, user, path, verbose) {
|
|
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
|
-
res.body.on("error", reject);
|
|
67
|
-
fileStream.on("finish", resolve);
|
|
68
|
-
});
|
|
69
|
-
console.log(`Finished downloading`);
|
|
70
|
-
return res;
|
|
71
|
-
});
|
|
1
|
+
import fetch from 'node-fetch';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import _path from 'path';
|
|
4
|
+
import { setupEnv, getAgent } from './env.js';
|
|
5
|
+
import { setupUser } from './login.js';
|
|
6
|
+
|
|
7
|
+
export function databaseCommand() {
|
|
8
|
+
return {
|
|
9
|
+
command: 'database [path]',
|
|
10
|
+
describe: 'Handles database',
|
|
11
|
+
builder: (yargs) => {
|
|
12
|
+
return yargs
|
|
13
|
+
.positional('path', {
|
|
14
|
+
describe: 'Path to the .bacpac file',
|
|
15
|
+
default: '.'
|
|
16
|
+
})
|
|
17
|
+
.option('export', {
|
|
18
|
+
alias: 'e',
|
|
19
|
+
type: 'boolean',
|
|
20
|
+
description: 'Exports the solutions database to a .bacpac file at [path]'
|
|
21
|
+
})
|
|
22
|
+
},
|
|
23
|
+
handler: async (argv) => {
|
|
24
|
+
if (argv.verbose) console.info(`Handling database with path: ${argv.path}`)
|
|
25
|
+
await handleDatabase(argv)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function handleDatabase(argv) {
|
|
31
|
+
let env = await setupEnv(argv);
|
|
32
|
+
let user = await setupUser(argv, env);
|
|
33
|
+
|
|
34
|
+
if (argv.export) {
|
|
35
|
+
await download(env, user, argv.path, argv.verbose);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function download(env, user, path, verbose) {
|
|
40
|
+
const res = await fetch(`${env.protocol}://${env.host}/Admin/Api/DatabaseDownload`, {
|
|
41
|
+
method: 'POST',
|
|
42
|
+
headers: {
|
|
43
|
+
'Authorization': `Bearer ${user.apiKey}`,
|
|
44
|
+
'content-type': 'application/json'
|
|
45
|
+
},
|
|
46
|
+
agent: getAgent(env.protocol)
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
if (verbose) console.log(res)
|
|
50
|
+
const header = res.headers.get('Content-Disposition');
|
|
51
|
+
const parts = header?.split(';');
|
|
52
|
+
if (!parts || !header.includes('attachment')) {
|
|
53
|
+
console.log('Failed download, check users database permissions')
|
|
54
|
+
if (verbose) console.log(await res.json())
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const filename = parts[1].split('=')[1];
|
|
59
|
+
const fileStream = fs.createWriteStream(_path.resolve(`${_path.resolve(path)}/${filename}`));
|
|
60
|
+
await new Promise((resolve, reject) => {
|
|
61
|
+
res.body.pipe(fileStream);
|
|
62
|
+
res.body.on("error", reject);
|
|
63
|
+
fileStream.on("finish", resolve);
|
|
64
|
+
});
|
|
65
|
+
console.log(`Finished downloading`);
|
|
72
66
|
}
|
package/bin/commands/env.js
CHANGED
|
@@ -1,155 +1,174 @@
|
|
|
1
|
-
import { updateConfig, getConfig } from './config.js'
|
|
2
|
-
import { Agent as HttpAgent } from 'http';
|
|
3
|
-
import { Agent as HttpsAgent } from 'https';
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
const httpAgent = new HttpAgent({
|
|
7
|
-
|
|
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
|
-
environment
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
environment
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
console.log(`
|
|
154
|
-
|
|
155
|
-
|
|
1
|
+
import { updateConfig, getConfig } from './config.js'
|
|
2
|
+
import { Agent as HttpAgent } from 'http';
|
|
3
|
+
import { Agent as HttpsAgent } from 'https';
|
|
4
|
+
import { input } from '@inquirer/prompts';
|
|
5
|
+
|
|
6
|
+
const httpAgent = new HttpAgent({
|
|
7
|
+
keepAlive: true,
|
|
8
|
+
maxSockets: 8,
|
|
9
|
+
maxFreeSockets: 4,
|
|
10
|
+
keepAliveMsecs: 10_000
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const httpsAgent = new HttpsAgent({
|
|
14
|
+
keepAlive: true,
|
|
15
|
+
maxSockets: 8,
|
|
16
|
+
maxFreeSockets: 4,
|
|
17
|
+
keepAliveMsecs: 10_000,
|
|
18
|
+
rejectUnauthorized: false
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export function getAgent(protocol) {
|
|
22
|
+
return protocol === 'http' ? httpAgent : httpsAgent;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function envCommand() {
|
|
26
|
+
return {
|
|
27
|
+
command: 'env [env]',
|
|
28
|
+
describe: 'If environment is specified, changes the current environment to the environment specified, otherwise sets up the config for a new environment',
|
|
29
|
+
builder: (yargs) => {
|
|
30
|
+
return yargs
|
|
31
|
+
.positional('env', {
|
|
32
|
+
describe: 'Environment'
|
|
33
|
+
})
|
|
34
|
+
.option('list', {
|
|
35
|
+
alias: 'l',
|
|
36
|
+
type: 'boolean',
|
|
37
|
+
description: 'List all existing environments'
|
|
38
|
+
})
|
|
39
|
+
.option('users', {
|
|
40
|
+
alias: 'u',
|
|
41
|
+
type: 'boolean',
|
|
42
|
+
description: 'List all users in environment, uses positional [env] if used, otherwise current env'
|
|
43
|
+
})
|
|
44
|
+
},
|
|
45
|
+
handler: (argv) => handleEnv(argv)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export async function setupEnv(argv) {
|
|
50
|
+
let env = {};
|
|
51
|
+
let askEnv = true;
|
|
52
|
+
|
|
53
|
+
if (argv.host) {
|
|
54
|
+
askEnv = false;
|
|
55
|
+
env.host = argv.host;
|
|
56
|
+
if (argv.protocol) {
|
|
57
|
+
env.protocol = argv.protocol;
|
|
58
|
+
} else {
|
|
59
|
+
env.protocol = 'https';
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (askEnv && getConfig().env) {
|
|
64
|
+
env = getConfig().env[argv.env] || getConfig().env[getConfig()?.current?.env];
|
|
65
|
+
if (!env.protocol) {
|
|
66
|
+
console.log('Protocol for environment not set, defaulting to https');
|
|
67
|
+
env.protocol = 'https';
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else if (askEnv) {
|
|
71
|
+
console.log('Current environment not set, please set it')
|
|
72
|
+
await interactiveEnv(argv, {
|
|
73
|
+
environment: {
|
|
74
|
+
type: 'input'
|
|
75
|
+
},
|
|
76
|
+
interactive: {
|
|
77
|
+
default: true
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
env = getConfig().env[getConfig()?.current?.env];
|
|
81
|
+
}
|
|
82
|
+
return env;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async function handleEnv(argv) {
|
|
86
|
+
if (argv.users) {
|
|
87
|
+
let env = argv.env || getConfig().current.env;
|
|
88
|
+
console.log(`Users in environment ${env}: ${Object.keys(getConfig().env[env].users || {})}`);
|
|
89
|
+
} else if (argv.env) {
|
|
90
|
+
changeEnv(argv)
|
|
91
|
+
} else if (argv.list) {
|
|
92
|
+
console.log(`Existing environments: ${Object.keys(getConfig().env || {})}`)
|
|
93
|
+
} else {
|
|
94
|
+
await interactiveEnv(argv, {
|
|
95
|
+
environment: {
|
|
96
|
+
type: 'input'
|
|
97
|
+
},
|
|
98
|
+
host: {
|
|
99
|
+
describe: 'Enter your host including protocol, i.e "https://yourHost.com":',
|
|
100
|
+
type: 'input'
|
|
101
|
+
},
|
|
102
|
+
interactive: {
|
|
103
|
+
default: true
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export async function interactiveEnv(argv, options) {
|
|
110
|
+
if (argv.verbose) console.info('Setting up new environment')
|
|
111
|
+
const result = {};
|
|
112
|
+
for (const [key, config] of Object.entries(options)) {
|
|
113
|
+
if (key === 'interactive') continue;
|
|
114
|
+
if (config.prompt === 'never') {
|
|
115
|
+
result[key] = config.default;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
result[key] = await input({
|
|
119
|
+
message: config.describe || key,
|
|
120
|
+
default: config.default
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
getConfig().env = getConfig().env || {};
|
|
124
|
+
if (!result.environment || !result.environment.trim()) {
|
|
125
|
+
console.log('Environment name cannot be empty');
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
getConfig().env[result.environment] = getConfig().env[result.environment] || {};
|
|
129
|
+
if (result.host) {
|
|
130
|
+
const hostSplit = result.host.split("://");
|
|
131
|
+
if (hostSplit.length == 1) {
|
|
132
|
+
getConfig().env[result.environment].protocol = 'https';
|
|
133
|
+
getConfig().env[result.environment].host = hostSplit[0];
|
|
134
|
+
} else if (hostSplit.length == 2) {
|
|
135
|
+
getConfig().env[result.environment].protocol = hostSplit[0];
|
|
136
|
+
getConfig().env[result.environment].host = hostSplit[1];
|
|
137
|
+
} else {
|
|
138
|
+
console.log(`Issues resolving host ${result.host}`);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (result.environment) {
|
|
143
|
+
getConfig().current = getConfig().current || {};
|
|
144
|
+
getConfig().current.env = result.environment;
|
|
145
|
+
}
|
|
146
|
+
updateConfig();
|
|
147
|
+
console.log(`Your current environment is now ${getConfig().current.env}`);
|
|
148
|
+
console.log(`To change the host of your environment, use the command 'dw env'`)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function changeEnv(argv) {
|
|
152
|
+
if (!Object.keys(getConfig().env).includes(argv.env)) {
|
|
153
|
+
console.log(`The specified environment ${argv.env} doesn't exist, please create it`);
|
|
154
|
+
await interactiveEnv(argv, {
|
|
155
|
+
environment: {
|
|
156
|
+
type: 'input',
|
|
157
|
+
default: argv.env,
|
|
158
|
+
prompt: 'never'
|
|
159
|
+
},
|
|
160
|
+
host: {
|
|
161
|
+
describe: 'Enter your host including protocol, i.e "https://yourHost.com":',
|
|
162
|
+
type: 'input',
|
|
163
|
+
prompt: 'always'
|
|
164
|
+
},
|
|
165
|
+
interactive: {
|
|
166
|
+
default: true
|
|
167
|
+
}
|
|
168
|
+
})
|
|
169
|
+
} else {
|
|
170
|
+
getConfig().current.env = argv.env;
|
|
171
|
+
updateConfig();
|
|
172
|
+
console.log(`Your current environment is now ${getConfig().current.env}`);
|
|
173
|
+
}
|
|
174
|
+
}
|