cht-conf 3.10.0 → 3.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +2 -0
- package/package.json +2 -1
- package/src/bin/index.js +14 -12
- package/src/cli/check-node-version.js +9 -7
- package/src/cli/shell-completion-setup.js +5 -8
- package/src/fn/check-git.js +3 -5
- package/src/fn/compress-images.js +1 -0
- package/src/fn/create-users.js +4 -7
- package/src/fn/move-contacts.js +2 -3
- package/src/fn/upload-custom-translations.js +2 -4
- package/src/fn/upload-docs.js +3 -4
- package/src/lib/api.js +13 -14
- package/src/lib/main.js +16 -22
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [3.10.1](https://github.com/medic/cht-conf/compare/v3.10.0...v3.10.1) (2022-02-23)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **#465:** remove process.exit and extraneous require ([058e651](https://github.com/medic/cht-conf/commit/058e65182928cdefdd5bb8fb41849fb9b5164631)), closes [#465](https://github.com/medic/cht-conf/issues/465)
|
|
7
|
+
|
|
1
8
|
# [3.10.0](https://github.com/medic/cht-conf/compare/v3.9.5...v3.10.0) (2022-02-02)
|
|
2
9
|
|
|
3
10
|
|
package/README.md
CHANGED
|
@@ -91,6 +91,8 @@ If a different username is required, add the `--user` switch:
|
|
|
91
91
|
|
|
92
92
|
cht --url=https://username:password@example.com:12345
|
|
93
93
|
|
|
94
|
+
**NB** - When specifying the URL with `--url`, be sure not to specify the CouchDB database name in the URL. The CHT API will find the correct database.
|
|
95
|
+
|
|
94
96
|
### Into an archive to be uploaded later
|
|
95
97
|
|
|
96
98
|
cht --archive
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cht-conf",
|
|
3
|
-
"version": "3.10.
|
|
3
|
+
"version": "3.10.1",
|
|
4
4
|
"description": "Configure CHT deployments",
|
|
5
5
|
"main": "./src/lib/main.js",
|
|
6
6
|
"engines": {
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"request-promise-native": "^1.0.9",
|
|
63
63
|
"semver": "^6.1.1",
|
|
64
64
|
"svgo": "^1.3.2",
|
|
65
|
+
"terser-webpack-plugin": "^1.4.3",
|
|
65
66
|
"uuid": "^8.3.2",
|
|
66
67
|
"webpack": "^4.46.0",
|
|
67
68
|
"xmldom": "^0.6.0"
|
package/src/bin/index.js
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const { error } = require('../lib/log');
|
|
4
|
-
require('../cli/check-node-version');
|
|
3
|
+
const { info, error } = require('../lib/log');
|
|
4
|
+
const checkNodeVersion = require('../cli/check-node-version');
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
try {
|
|
7
|
+
checkNodeVersion();
|
|
8
|
+
} catch (e) {
|
|
9
|
+
error(e.message);
|
|
10
|
+
process.exitCode = 1;
|
|
11
|
+
}
|
|
7
12
|
|
|
13
|
+
const main = require('../lib/main');
|
|
8
14
|
(async () => {
|
|
9
|
-
let returnCode;
|
|
10
15
|
try {
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
error(e);
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
finally {
|
|
18
|
-
process.exit(returnCode);
|
|
16
|
+
await main(process.argv, process.env);
|
|
17
|
+
} catch (e) {
|
|
18
|
+
info(e); // log the details for debugging
|
|
19
|
+
error(e.message); // error the message to make it clear
|
|
20
|
+
process.exitCode = 1; // emit a non-zero exit code for scripting
|
|
19
21
|
}
|
|
20
22
|
})();
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
const MIN_NODE_VERSION = 6;
|
|
2
2
|
const currentNodeVersion = process.versions.node;
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
module.exports = () => {
|
|
5
|
+
const currentMajor = process.versions.node.split('.')[0];
|
|
6
|
+
if(Number.parseInt(currentMajor) < MIN_NODE_VERSION) {
|
|
7
|
+
throw new Error(`Your NodeJS is too old.
|
|
8
|
+
You are running node version: ${currentNodeVersion}
|
|
9
|
+
cht-conf requires version: ${MIN_NODE_VERSION}
|
|
10
|
+
Please upgrade node to continue.`);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
const fs = require('../lib/sync-fs');
|
|
2
|
-
const { error } = require('../lib/log');
|
|
3
2
|
|
|
4
|
-
const
|
|
3
|
+
const SUPPORTED_SHELLS = ['bash'];
|
|
5
4
|
|
|
6
5
|
module.exports = shell => {
|
|
7
|
-
|
|
8
|
-
if (supported_shells.includes(shell)){
|
|
6
|
+
if (SUPPORTED_SHELLS.includes(shell)){
|
|
9
7
|
const completionFile = `${__dirname}/shell-completion.${shell}`;
|
|
10
8
|
if (fs.exists(completionFile)){
|
|
11
9
|
console.log(fs.read(completionFile));
|
|
12
|
-
|
|
10
|
+
return;
|
|
13
11
|
}
|
|
14
12
|
} else if (shell === true){
|
|
15
|
-
|
|
13
|
+
throw new Error('shell type argument not specified e.g. --shell-completion=bash');
|
|
16
14
|
} else {
|
|
17
|
-
|
|
15
|
+
throw new Error(`completion not yet supported for '${shell}' shell`);
|
|
18
16
|
}
|
|
19
|
-
process.exit(1);
|
|
20
17
|
};
|
package/src/fn/check-git.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const git = require('../lib/git-exec');
|
|
2
|
-
const { info, warn
|
|
2
|
+
const { info, warn } = require('../lib/log');
|
|
3
3
|
const userPrompt = require('../lib/user-prompt');
|
|
4
4
|
const environment = require('../lib/environment');
|
|
5
5
|
|
|
@@ -17,8 +17,7 @@ module.exports = {
|
|
|
17
17
|
'not staged for commit.');
|
|
18
18
|
warn('Changes untracked or to be committed:\n' + status);
|
|
19
19
|
if (!userPrompt.keyInYN('Are you sure you want to continue?')) {
|
|
20
|
-
|
|
21
|
-
process.exit(1);
|
|
20
|
+
throw new Error('User aborted execution.');
|
|
22
21
|
}
|
|
23
22
|
}
|
|
24
23
|
info('Fetching git upstream...');
|
|
@@ -26,8 +25,7 @@ module.exports = {
|
|
|
26
25
|
if (syncStatus) {
|
|
27
26
|
warn(syncStatus);
|
|
28
27
|
if (!userPrompt.keyInYN('Are you sure you want to continue?')) {
|
|
29
|
-
|
|
30
|
-
process.exit(1);
|
|
28
|
+
throw new Error('User aborted execution.');
|
|
31
29
|
}
|
|
32
30
|
}
|
|
33
31
|
}
|
package/src/fn/create-users.js
CHANGED
|
@@ -4,7 +4,7 @@ const userPrompt = require('../../src/lib/user-prompt');
|
|
|
4
4
|
const api = require('../lib/api');
|
|
5
5
|
const environment = require('../lib/environment');
|
|
6
6
|
const fs = require('../lib/sync-fs');
|
|
7
|
-
const { info, warn
|
|
7
|
+
const { info, warn } = require('../lib/log');
|
|
8
8
|
|
|
9
9
|
const nestPrefixedProperties = (obj, name) => {
|
|
10
10
|
const nested = {};
|
|
@@ -61,7 +61,7 @@ const getUserInfo = async (user) => {
|
|
|
61
61
|
|
|
62
62
|
const execute = async () => {
|
|
63
63
|
const csvPath = `${environment.pathToProject}/users.csv`;
|
|
64
|
-
if(!fs.exists(csvPath)) {
|
|
64
|
+
if (!fs.exists(csvPath)) {
|
|
65
65
|
throw new Error(`User csv file not found at ${csvPath}`);
|
|
66
66
|
}
|
|
67
67
|
|
|
@@ -76,11 +76,8 @@ const execute = async () => {
|
|
|
76
76
|
if (warnings.length) {
|
|
77
77
|
warnings.forEach(warning => warn(warning));
|
|
78
78
|
warn('Are you sure you want to continue?');
|
|
79
|
-
if(!userPrompt.keyInYN()) {
|
|
80
|
-
|
|
81
|
-
process.exit(1);
|
|
82
|
-
// stop execution in tests
|
|
83
|
-
return; // eslint-disable-line no-unreachable
|
|
79
|
+
if (!userPrompt.keyInYN()) {
|
|
80
|
+
throw new Error('User aborted execution.');
|
|
84
81
|
}
|
|
85
82
|
}
|
|
86
83
|
|
package/src/fn/move-contacts.js
CHANGED
|
@@ -7,7 +7,7 @@ const fs = require('../lib/sync-fs');
|
|
|
7
7
|
const lineageManipulation = require('../lib/lineage-manipulation');
|
|
8
8
|
const lineageConstraints = require('../lib/lineage-constraints');
|
|
9
9
|
const pouch = require('../lib/db');
|
|
10
|
-
const { warn, trace, info
|
|
10
|
+
const { warn, trace, info } = require('../lib/log');
|
|
11
11
|
|
|
12
12
|
const HIERARCHY_ROOT = 'root';
|
|
13
13
|
const BATCH_SIZE = 10000;
|
|
@@ -125,8 +125,7 @@ const prepareDocumentDirectory = ({ docDirectoryPath, force }) => {
|
|
|
125
125
|
if(userPrompt.keyInYN()) {
|
|
126
126
|
fs.deleteFilesInFolder(docDirectoryPath);
|
|
127
127
|
} else {
|
|
128
|
-
|
|
129
|
-
process.exit(1);
|
|
128
|
+
throw new Error('User aborted execution.');
|
|
130
129
|
}
|
|
131
130
|
}
|
|
132
131
|
};
|
|
@@ -65,8 +65,7 @@ const execute = async () => {
|
|
|
65
65
|
if (placeholderErrorsFound > 0) {
|
|
66
66
|
errMsg += '\nYou can use messages-ex.properties to add placeholders missing from the reference context.';
|
|
67
67
|
}
|
|
68
|
-
|
|
69
|
-
return process.exit(1);
|
|
68
|
+
throw new Error(errMsg);
|
|
70
69
|
}
|
|
71
70
|
} else {
|
|
72
71
|
throw err;
|
|
@@ -77,8 +76,7 @@ const execute = async () => {
|
|
|
77
76
|
const id = idFor(fileName);
|
|
78
77
|
const languageCode = id.substring('messages-'.length);
|
|
79
78
|
if (!isLanguageCodeValid(languageCode)) {
|
|
80
|
-
|
|
81
|
-
return process.exit(1);
|
|
79
|
+
throw new Error(`The language code '${languageCode}' is not valid. It must begin with a letter(a-z, A-Z), followed by any number of hyphens, underscores, letters, or numbers.`);
|
|
82
80
|
}
|
|
83
81
|
|
|
84
82
|
let languageName = iso639.getName(languageCode);
|
package/src/fn/upload-docs.js
CHANGED
|
@@ -8,7 +8,7 @@ const log = require('../lib/log');
|
|
|
8
8
|
const pouch = require('../lib/db');
|
|
9
9
|
const progressBar = require('../lib/progress-bar');
|
|
10
10
|
|
|
11
|
-
const { info, trace, warn
|
|
11
|
+
const { info, trace, warn } = log;
|
|
12
12
|
|
|
13
13
|
const FILE_EXTENSION = '.doc.json';
|
|
14
14
|
const INITIAL_BATCH_SIZE = 100;
|
|
@@ -34,9 +34,8 @@ const execute = async () => {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
warn(`This operation will permanently write ${totalCount} docs. Are you sure you want to continue?`);
|
|
37
|
-
if(!userPrompt.keyInYN()) {
|
|
38
|
-
|
|
39
|
-
process.exit(1);
|
|
37
|
+
if (!userPrompt.keyInYN()) {
|
|
38
|
+
throw new Error('User aborted execution.');
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
const results = { ok:[], failed:{} };
|
package/src/lib/api.js
CHANGED
|
@@ -94,25 +94,24 @@ const api = {
|
|
|
94
94
|
*/
|
|
95
95
|
available: async () => {
|
|
96
96
|
const url = `${environment.apiUrl}/`;
|
|
97
|
+
log.info(`Checking that ${url} is available...`);
|
|
97
98
|
try {
|
|
98
|
-
log.info(`Checking that ${url} is available...`);
|
|
99
99
|
await request.get(url);
|
|
100
|
-
return true;
|
|
101
100
|
} catch (err) {
|
|
102
101
|
if (err.statusCode === 401) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
+ 'wrong port or the instance is not started. Please check and try again.');
|
|
102
|
+
throw new Error(`Authentication failed connecting to ${url}. `
|
|
103
|
+
+ 'Check the supplied username and password and try again.');
|
|
104
|
+
}
|
|
105
|
+
if (err.statusCode === 403) {
|
|
106
|
+
throw new Error(`Insufficient permissions connecting to ${url}. `
|
|
107
|
+
+ 'You need to use admin permissions to execute this command.');
|
|
108
|
+
}
|
|
109
|
+
if (err.statusCode) {
|
|
110
|
+
throw new Error(`Received error code ${err.statusCode} connecting to ${url}. `
|
|
111
|
+
+ 'Check the server and and try again.');
|
|
114
112
|
}
|
|
115
|
-
|
|
113
|
+
throw new Error(`Failed to get a response from ${url}. Maybe you entered the wrong URL, `
|
|
114
|
+
+ 'wrong port or the instance is not started. Please check and try again.');
|
|
116
115
|
}
|
|
117
116
|
},
|
|
118
117
|
|
package/src/lib/main.js
CHANGED
|
@@ -12,7 +12,7 @@ const supportedActions = require('../cli/supported-actions');
|
|
|
12
12
|
const usage = require('../cli/usage');
|
|
13
13
|
const api = require('../lib/api');
|
|
14
14
|
|
|
15
|
-
const {
|
|
15
|
+
const { info, warn } = log;
|
|
16
16
|
const defaultActions = [
|
|
17
17
|
'check-git',
|
|
18
18
|
'compile-app-settings',
|
|
@@ -55,9 +55,9 @@ module.exports = async (argv, env) => {
|
|
|
55
55
|
warn('The "medic-conf" cli command is deprecated. Please use "cht" instead');
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
if(argv.length <= 2) {
|
|
59
|
-
usage(
|
|
60
|
-
|
|
58
|
+
if (argv.length <= 2) {
|
|
59
|
+
usage();
|
|
60
|
+
throw new Error('Invalid number of arguments.');
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
const cmdArgs = require('minimist')(argv.slice(2), {
|
|
@@ -69,8 +69,8 @@ module.exports = async (argv, env) => {
|
|
|
69
69
|
// General single use actions
|
|
70
70
|
//
|
|
71
71
|
if (cmdArgs.help) {
|
|
72
|
-
usage(
|
|
73
|
-
return
|
|
72
|
+
usage();
|
|
73
|
+
return;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
if (cmdArgs['shell-completion']) {
|
|
@@ -79,22 +79,21 @@ module.exports = async (argv, env) => {
|
|
|
79
79
|
|
|
80
80
|
if (cmdArgs['supported-actions']) {
|
|
81
81
|
info('Supported actions:\n', supportedActions.join('\n '));
|
|
82
|
-
return
|
|
82
|
+
return;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
if (cmdArgs.version) {
|
|
86
86
|
info(require('../../package.json').version);
|
|
87
|
-
return
|
|
87
|
+
return;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
if (cmdArgs.changelog) {
|
|
91
91
|
await open('https://github.com/medic/cht-conf/releases', { url: true });
|
|
92
|
-
return
|
|
92
|
+
return;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
if (cmdArgs.archive && !cmdArgs.destination) {
|
|
96
|
-
|
|
97
|
-
return 1;
|
|
96
|
+
throw new Error('--destination=<path to save files> is required with --archive.');
|
|
98
97
|
}
|
|
99
98
|
|
|
100
99
|
if (cmdArgs['accept-self-signed-certs']) {
|
|
@@ -130,8 +129,7 @@ module.exports = async (argv, env) => {
|
|
|
130
129
|
|
|
131
130
|
const unsupported = actions.filter(a => !supportedActions.includes(a));
|
|
132
131
|
if(unsupported.length) {
|
|
133
|
-
|
|
134
|
-
return 1;
|
|
132
|
+
throw new Error(`Unsupported action(s): ${unsupported.join(' ')}`);
|
|
135
133
|
}
|
|
136
134
|
|
|
137
135
|
if (cmdArgs['skip-git-check']) {
|
|
@@ -163,8 +161,7 @@ module.exports = async (argv, env) => {
|
|
|
163
161
|
if (actions.some(action => action.requiresInstance)) {
|
|
164
162
|
apiUrl = getApiUrl(cmdArgs, env);
|
|
165
163
|
if (!apiUrl) {
|
|
166
|
-
|
|
167
|
-
return 1;
|
|
164
|
+
throw new Error('Failed to obtain a url to the API');
|
|
168
165
|
}
|
|
169
166
|
}
|
|
170
167
|
|
|
@@ -183,8 +180,8 @@ module.exports = async (argv, env) => {
|
|
|
183
180
|
cmdArgs['skip-translation-check']
|
|
184
181
|
);
|
|
185
182
|
|
|
186
|
-
if (apiUrl
|
|
187
|
-
|
|
183
|
+
if (apiUrl) {
|
|
184
|
+
await api().available();
|
|
188
185
|
}
|
|
189
186
|
|
|
190
187
|
const productionUrlMatch = environment.instanceUrl && environment.instanceUrl.match(/^https:\/\/(?:[^@]*@)?(.*)\.(app|dev)\.medicmobile\.org(?:$|\/)/);
|
|
@@ -192,9 +189,8 @@ module.exports = async (argv, env) => {
|
|
|
192
189
|
if (productionUrlMatch && !expectedOptions.includes(productionUrlMatch[1])) {
|
|
193
190
|
warn(`Attempting to use project for \x1b[31m${projectName}\x1b[33m`,
|
|
194
191
|
`against non-matching instance: \x1b[31m${redactBasicAuth(environment.instanceUrl)}\x1b[33m`);
|
|
195
|
-
if(!userPrompt.keyInYN()) {
|
|
196
|
-
|
|
197
|
-
return 1;
|
|
192
|
+
if (!userPrompt.keyInYN()) {
|
|
193
|
+
throw new Error('User aborted execution.');
|
|
198
194
|
}
|
|
199
195
|
}
|
|
200
196
|
|
|
@@ -218,8 +214,6 @@ module.exports = async (argv, env) => {
|
|
|
218
214
|
if (actions.length > 1) {
|
|
219
215
|
await info('All actions completed.');
|
|
220
216
|
}
|
|
221
|
-
|
|
222
|
-
return 0;
|
|
223
217
|
};
|
|
224
218
|
|
|
225
219
|
// Exists for generic mocking purposes
|