@dynamicweb/cli 1.0.1 → 1.0.3
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/bin/commands/env.js +15 -3
- package/bin/commands/files.js +71 -10
- package/bin/commands/install.js +2 -2
- package/bin/commands/login.js +17 -3
- package/bin/index.js +9 -0
- package/package.json +1 -1
package/bin/commands/env.js
CHANGED
|
@@ -40,15 +40,27 @@ export function envCommand() {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
export async function setupEnv(argv) {
|
|
43
|
-
let env;
|
|
44
|
-
|
|
43
|
+
let env = {};
|
|
44
|
+
let askEnv = true;
|
|
45
|
+
|
|
46
|
+
if (argv.host) {
|
|
47
|
+
askEnv = false;
|
|
48
|
+
env.host = argv.host;
|
|
49
|
+
if (argv.protocol) {
|
|
50
|
+
env.protocol = argv.protocol;
|
|
51
|
+
} else {
|
|
52
|
+
env.protocol = 'https';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (askEnv && getConfig().env) {
|
|
45
57
|
env = getConfig().env[argv.env] || getConfig().env[getConfig()?.current?.env];
|
|
46
58
|
if (!env.protocol) {
|
|
47
59
|
console.log('Protocol for environment not set, defaulting to https');
|
|
48
60
|
env.protocol = 'https';
|
|
49
61
|
}
|
|
50
62
|
}
|
|
51
|
-
if (
|
|
63
|
+
else if (askEnv) {
|
|
52
64
|
console.log('Current environment not set, please set it')
|
|
53
65
|
await interactiveEnv(argv, {
|
|
54
66
|
environment: {
|
package/bin/commands/files.js
CHANGED
|
@@ -35,19 +35,28 @@ export function filesCommand() {
|
|
|
35
35
|
type: 'boolean',
|
|
36
36
|
describe: 'Imports the file at [dirPath] to [outPath]'
|
|
37
37
|
})
|
|
38
|
+
.option('overwrite', {
|
|
39
|
+
alias: 'o',
|
|
40
|
+
type: 'boolean',
|
|
41
|
+
describe: 'Used with import, will overwrite existing files at destrination if set to true'
|
|
42
|
+
})
|
|
43
|
+
.option('createEmpty', {
|
|
44
|
+
type: 'boolean',
|
|
45
|
+
describe: 'Used with import, will create a file even if its empty'
|
|
46
|
+
})
|
|
38
47
|
.option('includeFiles', {
|
|
39
48
|
alias: 'f',
|
|
40
49
|
type: 'boolean',
|
|
41
|
-
describe: '
|
|
50
|
+
describe: 'Used with export, includes files in list of directories and files'
|
|
42
51
|
})
|
|
43
52
|
.option('recursive', {
|
|
44
53
|
alias: 'r',
|
|
45
54
|
type: 'boolean',
|
|
46
|
-
describe: '
|
|
55
|
+
describe: 'Used with list, import and export, handles all directories recursively'
|
|
47
56
|
})
|
|
48
57
|
.option('raw', {
|
|
49
58
|
type: 'boolean',
|
|
50
|
-
describe: '
|
|
59
|
+
describe: 'Used with export, keeps zip file instead of unpacking it'
|
|
51
60
|
})
|
|
52
61
|
.option('iamstupid', {
|
|
53
62
|
type: 'boolean',
|
|
@@ -91,12 +100,61 @@ async function handleFiles(argv) {
|
|
|
91
100
|
}
|
|
92
101
|
} else if (argv.import) {
|
|
93
102
|
if (argv.dirPath && argv.outPath) {
|
|
94
|
-
let resolvedPath = path.resolve(argv.dirPath)
|
|
95
|
-
|
|
103
|
+
let resolvedPath = path.resolve(argv.dirPath);
|
|
104
|
+
let files;
|
|
105
|
+
if (!argv.overwrite) {
|
|
106
|
+
files = (await getFilesStructure(env, user, argv.outPath, argv.recursive, true)).model;
|
|
107
|
+
}
|
|
108
|
+
if (argv.recursive) {
|
|
109
|
+
await processDirectory(env, user, resolvedPath, argv.outPath, files, resolvedPath, argv.createEmpty, true);
|
|
110
|
+
} else {
|
|
111
|
+
let filesInDir = getFilesInDirectory(resolvedPath);
|
|
112
|
+
if (files)
|
|
113
|
+
filesInDir = getFilesNotInData(filesInDir, files.files.data, resolvedPath);
|
|
114
|
+
await uploadFiles(env, user, filesInDir, argv.outPath, argv.createEmpty);
|
|
115
|
+
}
|
|
96
116
|
}
|
|
97
117
|
}
|
|
98
118
|
}
|
|
99
119
|
|
|
120
|
+
function convertToDataFormat(filePath, resolvedPath) {
|
|
121
|
+
const relativePath = `/Files${filePath.substring(resolvedPath.length)}`;
|
|
122
|
+
return path.format(path.parse(relativePath)).replace(/\\/g, '/');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function getFilesNotInData(filesInDir, data, resolvedPath) {
|
|
126
|
+
const existingPaths = data.map(file => file.filePath);
|
|
127
|
+
return filesInDir.filter(filePath => {
|
|
128
|
+
const convertedPath = convertToDataFormat(filePath, resolvedPath);
|
|
129
|
+
return !existingPaths.includes(convertedPath);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function getFilesInDirectory(dirPath) {
|
|
134
|
+
return fs.readdirSync(dirPath)
|
|
135
|
+
.map(file => path.join(dirPath, file))
|
|
136
|
+
.filter(file => fs.statSync(file).isFile());
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async function processDirectory(env, user, dirPath, outPath, files, originalDir, createEmpty, isRoot = false) {
|
|
140
|
+
let filesInDir = getFilesInDirectory(dirPath);
|
|
141
|
+
let missingFiles;
|
|
142
|
+
if (files === undefined)
|
|
143
|
+
missingFiles = filesInDir;
|
|
144
|
+
else
|
|
145
|
+
missingFiles = getFilesNotInData(filesInDir, files.files.data, originalDir);
|
|
146
|
+
if (missingFiles.length > 0)
|
|
147
|
+
await uploadFiles(env, user, missingFiles, isRoot ? outPath : path.join(outPath, path.basename(dirPath)), createEmpty);
|
|
148
|
+
|
|
149
|
+
const subDirectories = fs.readdirSync(dirPath)
|
|
150
|
+
.map(subDir => path.join(dirPath, subDir))
|
|
151
|
+
.filter(subDir => fs.statSync(subDir).isDirectory());
|
|
152
|
+
for (let subDir of subDirectories) {
|
|
153
|
+
const remoteSubDir = files?.directories.find(dir => dir.name === path.basename(subDir));
|
|
154
|
+
await processDirectory(env, user, subDir, isRoot ? outPath : path.join(outPath, path.basename(dirPath)), remoteSubDir, originalDir, createEmpty);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
100
158
|
function resolveTree(dirs, indentLevel, parentHasFiles) {
|
|
101
159
|
let end = `└──`
|
|
102
160
|
let mid = `├──`
|
|
@@ -208,12 +266,15 @@ async function getFilesStructure(env, user, dirPath, recursive, includeFiles) {
|
|
|
208
266
|
}
|
|
209
267
|
}
|
|
210
268
|
|
|
211
|
-
export async function
|
|
212
|
-
console.log('Uploading
|
|
269
|
+
export async function uploadFiles(env, user, localFilePaths, destinationPath, createEmpty = false) {
|
|
270
|
+
console.log('Uploading files')
|
|
213
271
|
let form = new FormData();
|
|
214
272
|
form.append('path', destinationPath);
|
|
215
|
-
|
|
216
|
-
|
|
273
|
+
localFilePaths.forEach((localPath, index) => {
|
|
274
|
+
console.log(localPath)
|
|
275
|
+
form.append('files', fs.createReadStream(path.resolve(localPath)));
|
|
276
|
+
});
|
|
277
|
+
let res = await fetch(`${env.protocol}://${env.host}/Admin/Api/Upload?` + new URLSearchParams({"createEmptyFiles": createEmpty}), {
|
|
217
278
|
method: 'POST',
|
|
218
279
|
body: form,
|
|
219
280
|
headers: {
|
|
@@ -223,7 +284,7 @@ export async function uploadFile(env, user, localFilePath, destinationPath) {
|
|
|
223
284
|
});
|
|
224
285
|
if (res.ok) {
|
|
225
286
|
if (env.verbose) console.log(await res.json())
|
|
226
|
-
console.log(`
|
|
287
|
+
console.log(`Files uploaded`)
|
|
227
288
|
}
|
|
228
289
|
else {
|
|
229
290
|
console.log(res)
|
package/bin/commands/install.js
CHANGED
|
@@ -2,7 +2,7 @@ import fetch from 'node-fetch';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { setupEnv, getAgent } from './env.js';
|
|
4
4
|
import { setupUser } from './login.js';
|
|
5
|
-
import {
|
|
5
|
+
import { uploadFiles } from './files.js';
|
|
6
6
|
|
|
7
7
|
export function installCommand() {
|
|
8
8
|
return {
|
|
@@ -25,7 +25,7 @@ async function handleInstall(argv) {
|
|
|
25
25
|
let env = await setupEnv(argv);
|
|
26
26
|
let user = await setupUser(argv, env);
|
|
27
27
|
let resolvedPath = path.resolve(argv.filePath)
|
|
28
|
-
await
|
|
28
|
+
await uploadFiles(env, user, [resolvedPath], 'System/AddIns/Local');
|
|
29
29
|
await installAddin(env, user, resolvedPath)
|
|
30
30
|
}
|
|
31
31
|
|
package/bin/commands/login.js
CHANGED
|
@@ -18,11 +18,24 @@ export function loginCommand() {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export async function setupUser(argv, env) {
|
|
21
|
-
let user;
|
|
22
|
-
|
|
21
|
+
let user = {};
|
|
22
|
+
let askLogin = true;
|
|
23
|
+
|
|
24
|
+
if (argv.apiKey) {
|
|
25
|
+
user.apiKey = argv.apiKey;
|
|
26
|
+
askLogin = false;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (!user.apiKey && env.users) {
|
|
23
30
|
user = env.users[argv.user] || env.users[env.current.user];
|
|
31
|
+
askLogin = false;
|
|
24
32
|
}
|
|
25
|
-
|
|
33
|
+
|
|
34
|
+
if (askLogin && argv.host) {
|
|
35
|
+
console.log('Please add an --apiKey to the command as overriding the host requires that.')
|
|
36
|
+
process.exit();
|
|
37
|
+
}
|
|
38
|
+
else if (askLogin) {
|
|
26
39
|
console.log('Current user not set, please login')
|
|
27
40
|
await interactiveLogin(argv, {
|
|
28
41
|
environment: {
|
|
@@ -42,6 +55,7 @@ export async function setupUser(argv, env) {
|
|
|
42
55
|
})
|
|
43
56
|
user = env.users[env.current.user];
|
|
44
57
|
}
|
|
58
|
+
|
|
45
59
|
return user;
|
|
46
60
|
}
|
|
47
61
|
|
package/bin/index.js
CHANGED
|
@@ -31,6 +31,15 @@ yargs(hideBin(process.argv))
|
|
|
31
31
|
type: 'boolean',
|
|
32
32
|
description: 'Run with verbose logging'
|
|
33
33
|
})
|
|
34
|
+
.option('protocol', {
|
|
35
|
+
description: 'Allows setting the protocol used, only used together with --host, defaulting to https'
|
|
36
|
+
})
|
|
37
|
+
.option('host', {
|
|
38
|
+
description: 'Allows setting the host used, only allowed if an --apiKey is specified'
|
|
39
|
+
})
|
|
40
|
+
.option('apiKey', {
|
|
41
|
+
description: 'Allows setting the apiKey for an environmentless execution of the CLI command'
|
|
42
|
+
})
|
|
34
43
|
.demandCommand()
|
|
35
44
|
.parse()
|
|
36
45
|
|
package/package.json
CHANGED