cht-conf 5.1.0 → 5.2.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 CHANGED
@@ -1,3 +1,17 @@
1
+ ## [5.2.1](https://github.com/medic/cht-conf/compare/v5.2.0...v5.2.1) (2025-08-27)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **#390:** notify user of new cht-conf versions ([#730](https://github.com/medic/cht-conf/issues/730)) ([9d36c21](https://github.com/medic/cht-conf/commit/9d36c215f5b6406233b856b6348fe949757ab0b8)), closes [#390](https://github.com/medic/cht-conf/issues/390)
7
+
8
+ # [5.2.0](https://github.com/medic/cht-conf/compare/v5.1.0...v5.2.0) (2025-08-07)
9
+
10
+
11
+ ### Features
12
+
13
+ * refactor requests from freetexts views to other similar views ([#660](https://github.com/medic/cht-conf/issues/660)) ([292565d](https://github.com/medic/cht-conf/commit/292565de488e05e630a21d5046215fa19910a1fb))
14
+
1
15
  # [5.1.0](https://github.com/medic/cht-conf/compare/v5.0.0...v5.1.0) (2025-07-02)
2
16
 
3
17
 
package/README.md CHANGED
@@ -293,24 +293,6 @@ To achieve this, create a file called `settings.inherit.json` in your project's
293
293
  }
294
294
  }
295
295
 
296
- # Fetching logs
297
-
298
- Fetch logs from a CHT v2.x production server.
299
-
300
- This is a standalone command installed alongside `cht-conf`. For usage information, run `cht-logs --help`.
301
-
302
- ## Usage
303
-
304
- cht-logs <instance-name> <log-types...>
305
-
306
- Accepted log types:
307
-
308
- api
309
- couchdb
310
- gardener
311
- nginx
312
- sentinel
313
-
314
296
  # Development
315
297
 
316
298
  To develop a new action or improve an existing one, check the ["Actions" doc](src/fn/README.md).
@@ -1 +1 @@
1
- module.exports = {extends: ['@commitlint/config-conventional']}
1
+ module.exports = {extends: ['@commitlint/config-conventional']};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cht-conf",
3
- "version": "5.1.0",
3
+ "version": "5.2.1",
4
4
  "description": "Configure CHT deployments",
5
5
  "main": "./src/lib/main.js",
6
6
  "engines": {
@@ -16,8 +16,6 @@
16
16
  "bin": {
17
17
  "medic-conf": "src/bin/index.js",
18
18
  "cht": "src/bin/index.js",
19
- "medic-logs": "src/bin/cht-logs.bash",
20
- "cht-logs": "src/bin/cht-logs.bash",
21
19
  "shell-completion-for-medic-conf": "src/bin/shell-completion.js",
22
20
  "shell-completion-for-cht": "src/bin/shell-completion.js",
23
21
  "pngout-medic": "bin/pngout",
package/src/cli/usage.js CHANGED
@@ -8,9 +8,13 @@ ${bold('NAME')}
8
8
 
9
9
  ${bold('SYNOPSIS')}
10
10
  cht <--local|--instance=instance-name|--url=url>
11
- Or:
11
+
12
+ Or
13
+
12
14
  cht <--local|--instance=instance-name|--url=url|--archive> <actions> <options> -- <params>
13
15
 
16
+ ${underscore('Note')}: If <actions>,<options> or <params> are ${bold('not')} passed but one of --local or --instance or --url ${bold('is')} passed, ${bold('all')} supported actions are called.
17
+
14
18
  ${bold('DESCRIPTION')}
15
19
  This script updates and uploads a project's configuration.
16
20
 
@@ -58,6 +62,9 @@ ${bold('OPTIONS')}
58
62
  --skip-dependency-check
59
63
  Skips checking the version running is set to the same version in the package.json
60
64
 
65
+ --skip-version-check
66
+ Skips the automatic check for new cht-conf versions
67
+
61
68
  --skip-git-check
62
69
  Skips checking the status of the current repository that holds the configuration
63
70
 
@@ -65,12 +72,13 @@ ${bold('OPTIONS')}
65
72
  Skips checking message translations
66
73
 
67
74
  --skip-validate
68
- Skips form validation
75
+ Skips form validation
69
76
 
70
77
  --force
71
- CAN BE DANGEROUS! Passes yes to all commands and any where that would prompt to overwrite changes will overwrite automatically.
78
+ CAN BE DANGEROUS! Passes yes to all commands and any where that would prompt to overwrite changes will overwrite automatically.
72
79
  `);
73
80
  /* eslint-enable max-len */
74
81
  };
75
82
 
76
83
  const bold = text => `\x1b[1m${text}\x1b[0m`;
84
+ const underscore = text => `\x1b[4m${text}\x1b[0m`;
package/src/lib/api.js CHANGED
@@ -254,6 +254,22 @@ const api = {
254
254
  }
255
255
  return [];
256
256
  }
257
+ },
258
+
259
+ async getReportsByCreatedByIds (createdByIds, limit, skip) {
260
+ const queryString = createdByIds.map(id => `exact_match:"contact:${id}"`).join(' OR ');
261
+ const res = await request.get(`${environment.apiUrl}/_design/medic/_nouveau/reports_by_freetext`, {
262
+ qs: {
263
+ // sorting by this field ensures that the output are same with the clouseau views
264
+ // https://github.com/medic/cht-core/pull/9541
265
+ sort: '"reported_date"',
266
+ q: queryString,
267
+ include_docs: true,
268
+ limit,
269
+ skip
270
+ }, json: true
271
+ });
272
+ return res.hits.map(item => item.doc);
257
273
  }
258
274
  };
259
275
 
@@ -1,39 +1,35 @@
1
- const info = require('../lib/log').info;
2
1
  const request = require('request-promise-native');
3
- const warn = require('../lib/log').warn;
4
-
5
- module.exports = (options) => {
6
- const current = require('../../package').version;
7
- info(`Current version: ${current}. Checking NPM for updates…`);
8
-
9
- if (!options) {
10
- options = {};
11
- }
2
+ const log = require('../lib/log');
3
+ const current = require('../../package.json').version;
12
4
 
5
+ module.exports = (options = {}) => {
13
6
  return request
14
7
  .get('https://registry.npmjs.org/cht-conf')
15
8
  .then(res => {
16
9
  const json = JSON.parse(res);
17
- const latest = json['dist-tags'].latest;
18
-
19
- if (latest === current) {
20
- info('You are already on the latest version :¬)');
21
- } else {
22
- warn(`New version available!
10
+ return json['dist-tags'].latest;
11
+ })
12
+ .catch(err => {
13
+ log.warn(`Could not check NPM for updates: ${err.message}`);
14
+ if (!options.nonFatal) {
15
+ throw err;
16
+ }
17
+ })
18
+ .then(latest => {
19
+ if (latest && latest !== current) {
20
+ log.warn(`New version available!
23
21
 
24
- ${current} -> ${latest}
22
+ ${current} -> ${latest}
25
23
 
26
- To install:
24
+ To install:
27
25
 
28
- npm install -g cht-conf
29
- `);
30
- }
31
- })
32
- .catch(err => {
33
- if (options.nonFatal && err.cause && err.cause.code === 'ENOTFOUND') {
34
- warn('Could not check NPM for updates. You may be offline.');
35
- } else {
36
- warn(`Could not check NPM for updates. Error: ${err.message}`);
26
+ npm install -g cht-conf
27
+ `);
28
+ if (!options.nonFatal) {
29
+ throw new Error('You are not running the latest version of cht-conf!');
30
+ }
31
+ } else if (!options.nonFatal) {
32
+ log.info('You are already on the latest version :¬)');
37
33
  }
38
34
  });
39
35
  };
@@ -1,7 +1,11 @@
1
1
  const lineageManipulation = require('./lineage-manipulation');
2
+ const {getValidApiVersion} = require('../get-api-version');
3
+ const semver = require('semver');
4
+ const api = require('../api');
2
5
 
3
6
  const HIERARCHY_ROOT = 'root';
4
7
  const BATCH_SIZE = 10000;
8
+ const NOUVEAU_MIN_VERSION = '5.0.0';
5
9
 
6
10
  /*
7
11
  Fetches all of the documents associated with the "contactIds" and confirms they exist.
@@ -56,28 +60,48 @@ async function getContactWithDescendants(db, contactId) {
56
60
  .filter(doc => doc && doc.type !== 'tombstone');
57
61
  }
58
62
 
59
- async function getReportsForContacts(db, createdByIds, createdAtId, skip) {
60
- const createdByKeys = createdByIds.map(id => [`contact:${id}`]);
61
- const createdAtKeys = createdAtId ? [
62
- [`patient_id:${createdAtId}`],
63
- [`patient_uuid:${createdAtId}`],
64
- [`place_id:${createdAtId}`],
65
- [`place_uuid:${createdAtId}`]
66
- ] : [];
67
-
68
- const reports = await db.query('medic-client/reports_by_freetext', {
69
- keys: [
70
- ...createdByKeys,
71
- ...createdAtKeys,
72
- ],
63
+ const getFromDbView = async (db, view, keys, skip) => {
64
+ const res = await db.query(view, {
65
+ keys,
73
66
  include_docs: true,
74
67
  limit: BATCH_SIZE,
75
- skip,
68
+ skip
76
69
  });
70
+ return res.rows.map(row => row.doc);
71
+ };
72
+
73
+ const fetchReportsByCreator = async (db, createdByIds, skip) => {
74
+ if (createdByIds.length === 0) {
75
+ return [];
76
+ }
77
+
78
+ const coreVersion = await getValidApiVersion();
79
+ if (coreVersion && semver.gte(coreVersion, NOUVEAU_MIN_VERSION)) {
80
+ return await api().getReportsByCreatedByIds(createdByIds, BATCH_SIZE, skip);
81
+ }
82
+
83
+ const createdByKeys = createdByIds.map(id => [`contact:${id}`]);
84
+ return await getFromDbView(db, 'medic-client/reports_by_freetext', createdByKeys, skip);
85
+ };
86
+
87
+ const fetchReportsBySubject = async (db, createdAtId, skip) => {
88
+ if (!createdAtId) {
89
+ return [];
90
+ }
91
+ return await getFromDbView(db, 'medic-client/reports_by_subject', [createdAtId], skip);
92
+ };
77
93
 
78
- const docsWithId = reports.rows.map(({ doc }) => [doc._id, doc]);
94
+ const getReportsForContacts = async (db, createdByIds, createdAtId, skip) => {
95
+ const [creatorReports, subjectReports] = await Promise.all([
96
+ fetchReportsByCreator(db, createdByIds, skip),
97
+ fetchReportsBySubject(db, createdAtId, skip)
98
+ ]);
99
+
100
+ const allRows = [...creatorReports, ...subjectReports];
101
+
102
+ const docsWithId = allRows.map(( doc ) => [doc._id, doc]);
79
103
  return Array.from(new Map(docsWithId).values());
80
- }
104
+ };
81
105
 
82
106
  async function getAncestorsOf(db, contactDoc) {
83
107
  const ancestorIds = lineageManipulation.pluckIdsFromLineage(contactDoc.parent);
package/src/lib/main.js CHANGED
@@ -187,11 +187,6 @@ module.exports = async (argv, env) => {
187
187
  info(`Processing config in ${projectName}.`);
188
188
  info('Actions:\n -', actions.map(({name}) => name).join('\n - '));
189
189
 
190
- const skipCheckForUpdates = cmdArgs.check === false;
191
- if (actions.some(action => action.name === 'check-for-updates') && !skipCheckForUpdates) {
192
- await checkForUpdates({ nonFatal: true });
193
- }
194
-
195
190
  for (const action of actions) {
196
191
  info(`Starting action: ${action.name}…`);
197
192
  await executeAction(action);
@@ -201,6 +196,9 @@ module.exports = async (argv, env) => {
201
196
  if (actions.length > 1) {
202
197
  await info('All actions completed.');
203
198
  }
199
+ if (!actions.some(action => action.name === 'check-for-updates') && !cmdArgs['skip-version-check']) {
200
+ await checkForUpdates({ nonFatal: true });
201
+ }
204
202
  };
205
203
 
206
204
  function buildActions(cmdArgs, skipValidate) {
@@ -1,62 +0,0 @@
1
- #!/bin/bash -eu
2
-
3
- usage() {
4
- cat <<EOF
5
- cht-logs
6
- ==========
7
-
8
- Fetch logs from production CHT servers.
9
-
10
- USAGE
11
- $0 <instance-name> <log-types...>
12
-
13
- Accepted log types:
14
-
15
- api
16
- couchdb
17
- gardener
18
- nginx
19
- sentinel
20
- EOF
21
- }
22
-
23
- if [[ $# = 0 ]]; then usage; exit 1; fi
24
- if [[ "$1" = "--help" ]]; then usage; exit; fi
25
- if [[ $# < 2 ]]; then usage; exit 1; fi
26
-
27
- instanceName="$1"
28
- shift
29
-
30
- domain="${instanceName}.medicmobile.org"
31
-
32
- localRoot="fetched-logs/${instanceName}"
33
-
34
- while [[ $# > 0 ]]; do
35
- logType="$1"
36
- shift
37
-
38
- case "$logType" in
39
- nginx) logPath="/var/log/medic-core/nginx"; realLogType=nginx ;;
40
-
41
- gardener) logPath="/var/log/gardener"; realLogType=gardener ;;
42
- api) logPath="/var/log/gardener"; realLogType=gardener ;;
43
- medic-api) logPath="/var/log/gardener"; realLogType=gardener ;;
44
- sentinel) logPath="/var/log/gardener"; realLogType=gardener ;;
45
-
46
- couch) logPath="/var/log/medic-core/couchdb";realLogType=couchdb ;;
47
- couchdb) logPath="/var/log/medic-core/couchdb";realLogType=couchdb ;;
48
-
49
- *) echo "ERROR: Cannot fetch logs of type: $logType"; exit 1 ;;
50
- esac
51
-
52
- localDir="${localRoot}/${realLogType}"
53
- mkdir -p "$localDir"
54
-
55
- echo "[logs:$logType] Fetching logs to ${localDir}..."
56
- rsync -az --progress -e 'ssh -p 33696' "vm@${domain}:${logPath}/*" "$localDir"
57
-
58
- echo "[logs:$logType] Decompressing logs..."
59
- (cd "$localDir" && find . -name \*.bz2 | xargs bzip2 -dk)
60
-
61
- echo "[logs:$logType] Completed. Logs saved in: ${localDir}"
62
- done