cht-conf 3.9.2 → 3.10.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/CHANGELOG.md CHANGED
@@ -1,3 +1,31 @@
1
+ # [3.10.0](https://github.com/medic/cht-conf/compare/v3.9.5...v3.10.0) (2022-02-02)
2
+
3
+
4
+ ### Features
5
+
6
+ * **#431:** track form version ([9d0b8d7](https://github.com/medic/cht-conf/commit/9d0b8d7df2c04140b9e84cd044d5583695c4e1c0)), closes [#431](https://github.com/medic/cht-conf/issues/431)
7
+
8
+ ## [3.9.5](https://github.com/medic/cht-conf/compare/v3.9.4...v3.9.5) (2022-01-30)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **#458:** return non-zero code when exiting with failure ([516bff0](https://github.com/medic/cht-conf/commit/516bff0eabec2d3c13a16a994212280d77358c7e)), closes [#458](https://github.com/medic/cht-conf/issues/458)
14
+
15
+ ## [3.9.4](https://github.com/medic/cht-conf/compare/v3.9.3...v3.9.4) (2022-01-05)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * **#460:** log useful error messages when api connection fails ([#461](https://github.com/medic/cht-conf/issues/461)) ([095a55c](https://github.com/medic/cht-conf/commit/095a55c9254c6872696cbee2fe42f244fc1fc4a8)), closes [#460](https://github.com/medic/cht-conf/issues/460) [#460](https://github.com/medic/cht-conf/issues/460)
21
+
22
+ ## [3.9.3](https://github.com/medic/cht-conf/compare/v3.9.2...v3.9.3) (2021-12-16)
23
+
24
+
25
+ ### Bug Fixes
26
+
27
+ * **#455:** allow empty translation constants ([ac170d7](https://github.com/medic/cht-conf/commit/ac170d7cce13a6a500d89884d4ca63801f06a969)), closes [#455](https://github.com/medic/cht-conf/issues/455)
28
+
1
29
  ## [3.9.2](https://github.com/medic/cht-conf/compare/v3.9.1...v3.9.2) (2021-12-08)
2
30
 
3
31
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cht-conf",
3
- "version": "3.9.2",
3
+ "version": "3.10.0",
4
4
  "description": "Configure CHT deployments",
5
5
  "main": "./src/lib/main.js",
6
6
  "engines": {
@@ -36,7 +36,7 @@
36
36
  "homepage": "https://github.com/medic/cht-conf#readme",
37
37
  "dependencies": {
38
38
  "@hapi/joi": "^16.1.8",
39
- "@medic/translation-checker": "1.0.0",
39
+ "@medic/translation-checker": "^1.0.1",
40
40
  "canonical-json": "0.0.4",
41
41
  "csv-parse": "^4.16.0",
42
42
  "dom-compare": "^0.6.0",
package/src/bin/index.js CHANGED
@@ -12,7 +12,7 @@ const main = require('../lib/main');
12
12
  }
13
13
  catch (e) {
14
14
  error(e);
15
- returnCode = -1;
15
+ returnCode = 1;
16
16
  }
17
17
  finally {
18
18
  process.exit(returnCode);
@@ -18,7 +18,7 @@ module.exports = {
18
18
  warn('Changes untracked or to be committed:\n' + status);
19
19
  if (!userPrompt.keyInYN('Are you sure you want to continue?')) {
20
20
  error('User failed to confirm action.');
21
- process.exit(-1);
21
+ process.exit(1);
22
22
  }
23
23
  }
24
24
  info('Fetching git upstream...');
@@ -27,7 +27,7 @@ module.exports = {
27
27
  warn(syncStatus);
28
28
  if (!userPrompt.keyInYN('Are you sure you want to continue?')) {
29
29
  error('User failed to confirm action.');
30
- process.exit(-1);
30
+ process.exit(1);
31
31
  }
32
32
  }
33
33
  }
@@ -126,7 +126,7 @@ const prepareDocumentDirectory = ({ docDirectoryPath, force }) => {
126
126
  fs.deleteFilesInFolder(docDirectoryPath);
127
127
  } else {
128
128
  error('User failed to confirm action.');
129
- process.exit(-1);
129
+ process.exit(1);
130
130
  }
131
131
  }
132
132
  };
@@ -66,7 +66,7 @@ const execute = async () => {
66
66
  errMsg += '\nYou can use messages-ex.properties to add placeholders missing from the reference context.';
67
67
  }
68
68
  log.error(errMsg);
69
- return process.exit(-1);
69
+ return process.exit(1);
70
70
  }
71
71
  } else {
72
72
  throw err;
@@ -78,7 +78,7 @@ const execute = async () => {
78
78
  const languageCode = id.substring('messages-'.length);
79
79
  if (!isLanguageCodeValid(languageCode)) {
80
80
  log.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.`);
81
- return process.exit(-1);
81
+ return process.exit(1);
82
82
  }
83
83
 
84
84
  let languageName = iso639.getName(languageCode);
package/src/lib/api.js CHANGED
@@ -99,8 +99,19 @@ const api = {
99
99
  await request.get(url);
100
100
  return true;
101
101
  } catch (err) {
102
- log.error(`Failed to get a response from ${url}. Maybe you entered the wrong URL, `
103
- + 'wrong port or the instance is not started? Please check and try again.');
102
+ if (err.statusCode === 401) {
103
+ log.error(`Authentication failed connecting to ${url}. `
104
+ + 'Check the supplied username and password and try again.');
105
+ } else if (err.statusCode === 403) {
106
+ log.error(`Insufficient permissions connecting to ${url}. `
107
+ + 'You need to use admin permissions to execute this command.');
108
+ } else if (err.statusCode) {
109
+ log.error(`Received error code ${err.statusCode} connecting to ${url}. `
110
+ + 'Check the server and and try again.');
111
+ } else {
112
+ log.error(`Failed to get a response from ${url}. Maybe you entered the wrong URL, `
113
+ + 'wrong port or the instance is not started. Please check and try again.');
114
+ }
104
115
  return false;
105
116
  }
106
117
  },
package/src/lib/main.js CHANGED
@@ -57,7 +57,7 @@ module.exports = async (argv, env) => {
57
57
 
58
58
  if(argv.length <= 2) {
59
59
  usage(0);
60
- return -1;
60
+ return 1;
61
61
  }
62
62
 
63
63
  const cmdArgs = require('minimist')(argv.slice(2), {
@@ -94,7 +94,7 @@ module.exports = async (argv, env) => {
94
94
 
95
95
  if (cmdArgs.archive && !cmdArgs.destination) {
96
96
  error('--destination=<path to save files> is required with --archive.');
97
- return -1;
97
+ return 1;
98
98
  }
99
99
 
100
100
  if (cmdArgs['accept-self-signed-certs']) {
@@ -131,7 +131,7 @@ module.exports = async (argv, env) => {
131
131
  const unsupported = actions.filter(a => !supportedActions.includes(a));
132
132
  if(unsupported.length) {
133
133
  error(`Unsupported action(s): ${unsupported.join(' ')}`);
134
- return -1;
134
+ return 1;
135
135
  }
136
136
 
137
137
  if (cmdArgs['skip-git-check']) {
@@ -164,7 +164,7 @@ module.exports = async (argv, env) => {
164
164
  apiUrl = getApiUrl(cmdArgs, env);
165
165
  if (!apiUrl) {
166
166
  error('Failed to obtain a url to the API');
167
- return -1;
167
+ return 1;
168
168
  }
169
169
  }
170
170
 
@@ -184,7 +184,7 @@ module.exports = async (argv, env) => {
184
184
  );
185
185
 
186
186
  if (apiUrl && !await api().available()) {
187
- return false;
187
+ return 1;
188
188
  }
189
189
 
190
190
  const productionUrlMatch = environment.instanceUrl && environment.instanceUrl.match(/^https:\/\/(?:[^@]*@)?(.*)\.(app|dev)\.medicmobile\.org(?:$|\/)/);
@@ -194,7 +194,7 @@ module.exports = async (argv, env) => {
194
194
  `against non-matching instance: \x1b[31m${redactBasicAuth(environment.instanceUrl)}\x1b[33m`);
195
195
  if(!userPrompt.keyInYN()) {
196
196
  error('User failed to confirm action.');
197
- return false;
197
+ return 1;
198
198
  }
199
199
  }
200
200
 
@@ -218,6 +218,8 @@ module.exports = async (argv, env) => {
218
218
  if (actions.length > 1) {
219
219
  await info('All actions completed.');
220
220
  }
221
+
222
+ return 0;
221
223
  };
222
224
 
223
225
  // Exists for generic mocking purposes
@@ -97,6 +97,7 @@ module.exports = {
97
97
  recurseFiles,
98
98
  deleteFilesInFolder: folderPath => recurseFiles(folderPath).forEach(filePath => fs.unlinkSync(filePath)),
99
99
  readdir: fs.readdirSync,
100
+ statSync: fs.statSync,
100
101
  withoutExtension,
101
102
  write: (path, data, options = 'utf8') => fs.writeFileSync(path, data, options),
102
103
  writeBinary: (path, content) => fs.writeFileSync(path, content),
@@ -1,6 +1,7 @@
1
1
  const argsFormFilter = require('./args-form-filter');
2
2
  const attachmentsFromDir = require('./attachments-from-dir');
3
3
  const attachmentFromFile = require('./attachment-from-file');
4
+ const crypto = require('crypto');
4
5
  const fs = require('./sync-fs');
5
6
  const log = require('./log');
6
7
  const insertOrReplace = require('./insert-or-replace');
@@ -38,7 +39,13 @@ module.exports = async (projectDir, subDirectory, options) => {
38
39
  log.info(`No media directory found at ${mediaDir} for form ${xformPath}`);
39
40
  }
40
41
 
42
+ const hashSum = crypto.createHash('sha256');
41
43
  const xml = fs.read(xformPath);
44
+ hashSum.update(xml);
45
+ const xmlVersion = {
46
+ time: Date.now(),
47
+ sha256: hashSum.digest('hex'),
48
+ };
42
49
 
43
50
  const internalId = readIdFrom(xml);
44
51
  if(internalId !== baseDocId) log.warn('DEPRECATED', 'Form:', fileName, 'Bad ID set in XML. Expected:', baseDocId, 'but saw:', internalId, ' Support for setting these values differently will be dropped. Please see https://github.com/medic/cht-core/issues/3342.');
@@ -48,6 +55,7 @@ module.exports = async (projectDir, subDirectory, options) => {
48
55
  _id: docId,
49
56
  type: 'form',
50
57
  internalId: internalId,
58
+ xmlVersion: xmlVersion,
51
59
  title: readTitleFrom(xml),
52
60
  context: options.default_context,
53
61
  };