cht-conf 3.18.2 → 3.19.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,17 @@
1
+ # [3.19.0](https://github.com/medic/cht-conf/compare/v3.18.3...v3.19.0) (2023-10-17)
2
+
3
+
4
+ ### Features
5
+
6
+ * **#580:** publish recent commits to npm ([db734e1](https://github.com/medic/cht-conf/commit/db734e1818f8501988a5457237dc32c5667b368c)), closes [#580](https://github.com/medic/cht-conf/issues/580)
7
+
8
+ ## [3.18.3](https://github.com/medic/cht-conf/compare/v3.18.2...v3.18.3) (2023-04-27)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **#554:** revert change to docker creds after fixing Hub perms ([#559](https://github.com/medic/cht-conf/issues/559)) ([f0ea5ea](https://github.com/medic/cht-conf/commit/f0ea5ea7330d5c5cd9e1516da1f2b60ec85bfc24)), closes [#554](https://github.com/medic/cht-conf/issues/554)
14
+
1
15
  ## [3.18.2](https://github.com/medic/cht-conf/compare/v3.18.1...v3.18.2) (2023-04-27)
2
16
 
3
17
 
package/README.md CHANGED
@@ -343,7 +343,7 @@ Builds brought to you courtesy of GitHub actions.
343
343
 
344
344
  # Copyright
345
345
 
346
- Copyright 2013-2022 Medic Mobile, Inc. <hello@medic.org>
346
+ Copyright 2013-2023 Medic Mobile, Inc. <hello@medic.org>
347
347
 
348
348
  # License
349
349
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cht-conf",
3
- "version": "3.18.2",
3
+ "version": "3.19.0",
4
4
  "description": "Configure CHT deployments",
5
5
  "main": "./src/lib/main.js",
6
6
  "engines": {
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "homepage": "https://github.com/medic/cht-conf#readme",
37
37
  "dependencies": {
38
- "@hapi/joi": "^16.1.8",
38
+ "joi": "^17.9.2",
39
39
  "@medic/translation-checker": "^1.0.1",
40
40
  "@parcel/watcher": "^2.0.5",
41
41
  "@xmldom/xmldom": "^0.8.2",
@@ -1,16 +1,16 @@
1
1
  const minimist = require('minimist');
2
2
  const path = require('path');
3
- const compileContactSummary = require('../lib/compile-contact-summary');
4
- const compileNoolsRules = require('../lib/compile-nools-rules');
3
+
4
+ const compilation = require('../lib/compilation');
5
5
  const environment = require('../lib/environment');
6
6
  const fs = require('../lib/sync-fs');
7
+ const parsePurge = require('../lib/parse-purge');
7
8
  const parseTargets = require('../lib/parse-targets');
8
9
  const { warn } = require('../lib/log');
9
- const parsePurge = require('../lib/parse-purge');
10
10
  const validateAppSettings = require('../lib/validate-app-settings');
11
11
  const { APP_SETTINGS_DIR_PATH, APP_SETTINGS_JSON_PATH } = require('../lib/project-paths');
12
12
 
13
- // we can't used named capture groups yet
13
+ // we can't use named capture groups yet
14
14
  const JS_FILE_MATCHER = /^(.+)(\.js)$/; // 2 groups get the file name and extension
15
15
  const JSON_FILE_MATCHER = /^(.+)(\.json)$/;
16
16
  const configFileMatcher = (fileName) => {
@@ -100,9 +100,11 @@ const compileAppSettingsForProject = async (projectDir, options) => {
100
100
  Please create a base_settings.json file in app_settings folder and move any manually defined configurations there.`);
101
101
  appSettings = fs.readJson(appSettingsPath);
102
102
  }
103
- appSettings.contact_summary = await compileContactSummary(projectDir, options);
103
+ appSettings.contact_summary = await compilation.compileContactSummary(projectDir, options);
104
+ const compiledTasksAndTargets = await compilation.compileTasksAndTargets(projectDir, options);
104
105
  appSettings.tasks = {
105
- rules: await compileNoolsRules(projectDir, options),
106
+ rules: compiledTasksAndTargets.rules,
107
+ isDeclarative: compiledTasksAndTargets.isDeclarative,
106
108
  schedules: readOptionalJson(taskSchedulesPath),
107
109
  targets: parseTargets(projectDir),
108
110
  };
@@ -1,32 +1,53 @@
1
+ const semver = require('semver');
2
+
1
3
  const api = require('../lib/api');
2
4
  const environment = require('../lib/environment');
3
5
  const fs = require('../lib/sync-fs');
6
+ const { getValidApiVersion } = require('../lib/get-api-version');
4
7
  const { info } = require('../lib/log');
8
+ const nools = require('../lib/nools-utils');
5
9
  const { APP_SETTINGS_DIR_PATH, APP_SETTINGS_JSON_PATH } = require('../lib/project-paths');
6
10
 
7
- const uploadAppSettings = (api) => {
8
- const settings = fs.read(`${environment.pathToProject}/${APP_SETTINGS_JSON_PATH}`);
9
- return api.updateAppSettings(settings)
10
- .then(JSON.parse)
11
- .then(json => {
12
- // As per https://github.com/medic/cht-core/issues/3674, this endpoint
13
- // will return 200 even when upload fails.
14
- if (!json.success) {
15
- throw new Error(json.error);
16
- }
11
+ const uploadAppSettings = async api => {
12
+ const appSettings = JSON.parse(fs.read(`${environment.pathToProject}/${APP_SETTINGS_JSON_PATH}`));
13
+ await augmentDeclarativeWithNoolsBoilerplate(appSettings);
14
+
15
+ const requestResult = await api.updateAppSettings(JSON.stringify(appSettings));
16
+ const json = JSON.parse(requestResult);
17
+ // As per https://github.com/medic/cht-core/issues/3674, this endpoint
18
+ // will return 200 even when upload fails.
19
+ if (!json.success) {
20
+ throw new Error(json.error);
21
+ }
17
22
 
18
- if ('updated' in json) {
19
- // the `updated` param was added in 3.9
20
- // https://github.com/medic/cht-core/issues/6315
21
- if (!json.updated) {
22
- info('Settings not updated - no changes detected');
23
- } else {
24
- info('Settings updated successfully');
25
- }
26
- }
27
- });
23
+ if ('updated' in json) {
24
+ // the `updated` param was added in 3.9
25
+ // https://github.com/medic/cht-core/issues/6315
26
+ if (!json.updated) {
27
+ info('Settings not updated - no changes detected');
28
+ } else {
29
+ info('Settings updated successfully');
30
+ }
31
+ }
28
32
  };
29
33
 
34
+ // https://github.com/medic/cht-core/issues/6506 added in 4.2
35
+ // augmented during upload so compile-app-settings doesn't require a url on the command-line
36
+ async function augmentDeclarativeWithNoolsBoilerplate(appSettings) {
37
+ if (!appSettings || !appSettings.tasks || !appSettings.tasks.isDeclarative) {
38
+ return;
39
+ }
40
+
41
+ const actualCoreVersion = await getValidApiVersion(appSettings);
42
+ const addNoolsBoilerplate = semver.lt(actualCoreVersion, '4.2.0-dev');
43
+ if (addNoolsBoilerplate) {
44
+ appSettings.tasks.rules = nools.addBoilerplateToCode(appSettings.tasks.rules);
45
+
46
+ // do not set the isDeclarative flag when the code has nools boilerplate
47
+ delete appSettings.tasks.isDeclarative;
48
+ }
49
+ }
50
+
30
51
  module.exports = {
31
52
  uploadAppSettings,
32
53
  APP_SETTINGS_DIR_PATH,
@@ -1,6 +1,6 @@
1
1
  const path = require('path');
2
- const fs = require('./sync-fs');
3
- const pack = require('../lib/package-lib');
2
+ const fs = require('../sync-fs');
3
+ const pack = require('./package-lib');
4
4
 
5
5
  module.exports = async (projectDir, options) => {
6
6
  const freeformPath = `${projectDir}/contact-summary.js`;
@@ -12,8 +12,8 @@ module.exports = async (projectDir, options) => {
12
12
  if (!freeformPathExists && !structuredPathExists) throw new Error(`Could not find contact-summary javascript at either of ${freeformPath} or ${structuredPath}. Please create one xor other of these files.`);
13
13
  if (freeformPathExists && structuredPathExists) throw new Error(`Found contact-summary javascript at both ${freeformPath} and ${structuredPath}. Only one of these files should exist.`);
14
14
 
15
- const baseEslintPath = path.join(__dirname, '../contact-summary/.eslintrc');
16
- const pathToDeclarativeLib = path.join(__dirname, '../contact-summary/lib.js');
15
+ const baseEslintPath = path.join(__dirname, '../../contact-summary/.eslintrc');
16
+ const pathToDeclarativeLib = path.join(__dirname, '../../contact-summary/lib.js');
17
17
  const pathToPack = freeformPathExists ? freeformPath : pathToDeclarativeLib;
18
18
 
19
19
  /*
@@ -1,13 +1,13 @@
1
1
  const path = require('path');
2
2
 
3
- const fs = require('./sync-fs');
3
+ const fs = require('../sync-fs');
4
4
  const pack = require('./package-lib');
5
- const minifyNools = require('./minify-nools');
5
+ const nools = require('../nools-utils');
6
6
  const validateDeclarativeSchema = require('./validate-declarative-schema');
7
7
 
8
8
  const DECLARATIVE_NOOLS_FILES = [ 'tasks.js', 'targets.js' ];
9
9
 
10
- const compileNoolsRules = async (projectDir, options = {}) => {
10
+ const compileTasksAndTargets = async (projectDir, options = {}) => {
11
11
  const tryLoadLegacyRules = legacyNoolsFilePath => {
12
12
  let result;
13
13
  if (fs.exists(legacyNoolsFilePath)) {
@@ -25,10 +25,14 @@ const compileNoolsRules = async (projectDir, options = {}) => {
25
25
  throw new Error(`Both legacy and declarative files found. You should either have rules.nools.js xor ${DECLARATIVE_NOOLS_FILES} files.`);
26
26
  }
27
27
 
28
- return options.minifyScripts ? minifyNools(legacyRules) : legacyRules;
29
- } else {
30
- return compileDeclarativeFiles(projectDir, options);
28
+ const rules = options.minifyScripts ? nools.minify(legacyRules) : legacyRules;
29
+ return { rules };
31
30
  }
31
+
32
+ return {
33
+ rules: await compileDeclarativeFiles(projectDir, options),
34
+ isDeclarative: true,
35
+ };
32
36
  };
33
37
 
34
38
  const findMissingDeclarativeFiles = projectDir => DECLARATIVE_NOOLS_FILES.filter(filename => {
@@ -44,16 +48,10 @@ const compileDeclarativeFiles = async (projectDir, options) => {
44
48
 
45
49
  validateDeclarativeSchema(projectDir, options.haltOnSchemaError);
46
50
 
47
- const pathToDeclarativeLib = path.join(__dirname, '../nools/lib.js');
48
- const baseEslintPath = path.join(__dirname, '../nools/.eslintrc');
51
+ const pathToDeclarativeLib = path.join(__dirname, '../../nools/lib.js');
52
+ const baseEslintPath = path.join(__dirname, '../../nools/.eslintrc');
49
53
 
50
- const code = await pack(projectDir, pathToDeclarativeLib, baseEslintPath, options);
51
- return `define Target { _id: null, contact: null, deleted: null, type: null, pass: null, date: null, groupBy: null }
52
- define Contact { contact: null, reports: null, tasks: null }
53
- define Task { _id: null, deleted: null, doc: null, contact: null, icon: null, date: null, readyStart: null, readyEnd: null, title: null, fields: null, resolved: null, priority: null, priorityLabel: null, reports: null, actions: null }
54
- rule GenerateEvents {
55
- when { c: Contact } then { ${code} }
56
- }`;
54
+ return pack(projectDir, pathToDeclarativeLib, baseEslintPath, options);
57
55
  };
58
56
 
59
- module.exports = compileNoolsRules;
57
+ module.exports = compileTasksAndTargets;
@@ -0,0 +1,7 @@
1
+ const compileContactSummary = require('./compile-contact-summary');
2
+ const compileTasksAndTargets = require('./compile-tasks-and-targets');
3
+
4
+ module.exports = {
5
+ compileContactSummary,
6
+ compileTasksAndTargets,
7
+ };
@@ -4,8 +4,8 @@ const path = require('path');
4
4
  const TerserPlugin = require('terser-webpack-plugin');
5
5
  const webpack = require('webpack');
6
6
 
7
- const fsUtils = require('../lib/sync-fs');
8
- const { info, warn, error } = require('./log');
7
+ const fsUtils = require('../sync-fs');
8
+ const { info, warn, error } = require('../log');
9
9
 
10
10
  module.exports = (pathToProject, entry, baseEslintPath, options = {}) => {
11
11
  const baseEslintConfig = fsUtils.readJson(baseEslintPath);
@@ -1,6 +1,6 @@
1
1
  const path = require('path');
2
- const joi = require('@hapi/joi');
3
- const { error, warn } = require('./log');
2
+ const joi = require('joi');
3
+ const { error, warn } = require('../log');
4
4
 
5
5
  const err = (filename, message) => details => {
6
6
  const acceptedValues = details[0].local.valids ? ` but only ${JSON.stringify(details[0].local.valids)} are allowed` : '';
@@ -0,0 +1,21 @@
1
+ const minify = js =>
2
+ js.split('\n')
3
+ .map(s =>
4
+ s.trim()
5
+ .replace(/\s*\/\/.*/, '') // single-line comments (like this one)
6
+ ).join('')
7
+ .replace(/\s*\/\*(?:(?!\*\/).)*\*\/\s*/g, '') /* this kind of comment */
8
+ .replace(/function \(/g, 'function(') // different node versions do function.toString() differently :\
9
+ ;
10
+
11
+ const addBoilerplateToCode = code => `define Target { _id: null, contact: null, deleted: null, type: null, pass: null, date: null, groupBy: null }
12
+ define Contact { contact: null, reports: null, tasks: null }
13
+ define Task { _id: null, deleted: null, doc: null, contact: null, icon: null, date: null, readyStart: null, readyEnd: null, title: null, fields: null, resolved: null, priority: null, priorityLabel: null, reports: null, actions: null }
14
+ rule GenerateEvents {
15
+ when { c: Contact } then { ${code} }
16
+ }`;
17
+
18
+ module.exports = {
19
+ addBoilerplateToCode,
20
+ minify,
21
+ };
@@ -1,4 +1,4 @@
1
- const joi = require('@hapi/joi');
1
+ const joi = require('joi');
2
2
 
3
3
  const FormsSchema = joi.object().pattern(
4
4
  joi.string().min(1),
@@ -1,9 +0,0 @@
1
- module.exports = js =>
2
- js.split('\n')
3
- .map(s =>
4
- s.trim()
5
- .replace(/\s*\/\/.*/, '') // single-line comments (like this one)
6
- ).join('')
7
- .replace(/\s*\/\*(?:(?!\*\/).)*\*\/\s*/g, '') /* this kind of comment */
8
- .replace(/function \(/g, 'function(') // different node versions do function.toString() differently :\
9
- ;