@criticalmanufacturing/cli 5.8.0 → 5.9.0-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.
Files changed (2) hide show
  1. package/package.json +12 -2
  2. package/postinstall.js +67 -31
package/package.json CHANGED
@@ -1,13 +1,17 @@
1
1
  {
2
2
  "name": "@criticalmanufacturing/cli",
3
- "version": "5.8.0",
3
+ "version": "5.9.0-1",
4
4
  "description": "Critical Manufacturing command line client",
5
5
  "bin": {
6
6
  "cmf": "./run.js"
7
7
  },
8
8
  "scripts": {
9
9
  "postinstall": "node postinstall.js install",
10
- "preuninstall": "node postinstall.js uninstall"
10
+ "preuninstall": "node postinstall.js uninstall",
11
+ "test": "jest",
12
+ "test:watch": "jest --watch",
13
+ "test:coverage": "jest --coverage",
14
+ "test:integration": "node integration-test.js"
11
15
  },
12
16
  "author": "Critical Manufacturing, SA",
13
17
  "license": "BSD-3-Clause",
@@ -37,5 +41,11 @@
37
41
  "node_modules-path": "^2.0.7",
38
42
  "rimraf": "^3.0.2",
39
43
  "tmp": "0.2.1"
44
+ },
45
+ "devDependencies": {
46
+ "jest": "^27.5.1",
47
+ "http-proxy-agent": "^5.0.0",
48
+ "https-proxy-agent": "^5.0.1",
49
+ "proxy-from-env": "^1.1.0"
40
50
  }
41
51
  }
package/postinstall.js CHANGED
@@ -7,8 +7,8 @@ const path = require('path'),
7
7
  rimraf = require('rimraf'),
8
8
  fs = require('fs'),
9
9
  axios = require('axios'),
10
- httpsProxyAgent = require('https-proxy-agent'),
11
- httpProxyAgent = require('http-proxy-agent'),
10
+ HttpsProxyAgent = require('https-proxy-agent'),
11
+ HttpProxyAgent = require('http-proxy-agent'),
12
12
  proxyFromEnv = require('proxy-from-env'),
13
13
  AdmZip = require("adm-zip"),
14
14
  tmp = require('tmp'),
@@ -33,6 +33,41 @@ async function verifyAndPlaceBinary(binName, binPath, callback) {
33
33
  return callback(null);
34
34
  }
35
35
 
36
+ /**
37
+ * Downloads and extracts a zip file from the given URL to the destination path
38
+ * @param {string} pkgUrl - The URL to download from
39
+ * @param {string} dest - The destination path to extract to
40
+ * @returns {Promise<void>}
41
+ */
42
+ async function downloadAndExtract(pkgUrl, dest) {
43
+ console.info(`Fetching release archive from ${pkgUrl}`);
44
+
45
+ // support for http/s proxies through env vars
46
+ const proxy = proxyFromEnv.getProxyForUrl(pkgUrl);
47
+ let httpAgent, httpsAgent;
48
+ if (proxy) {
49
+ httpAgent = new HttpProxyAgent(proxy);
50
+ httpsAgent = new HttpsProxyAgent(proxy);
51
+ }
52
+
53
+ // make req (override axios automatic proxy since it is not working properly)
54
+ const response = await axios({
55
+ url: pkgUrl,
56
+ method: 'GET',
57
+ proxy: false,
58
+ httpAgent: httpAgent,
59
+ httpsAgent: httpsAgent,
60
+ responseType: 'arraybuffer',
61
+ });
62
+
63
+ const zip = tmp.tmpNameSync();
64
+ debug(`Writing temporary zip file to ${zip}`);
65
+ fs.writeFileSync(zip, response.data);
66
+ debug(`Extracting zip file ${zip} to ${dest}`);
67
+ (new AdmZip(zip)).extractAllTo(dest);
68
+ rimraf.sync(zip);
69
+ }
70
+
36
71
  /**
37
72
  * Reads the configuration from application's package.json,
38
73
  * validates properties, copied the binary from the package and stores at
@@ -49,36 +84,37 @@ async function install(callback) {
49
84
  const src= `./dist/${PLATFORM_MAPPING[process.platform]}-${ARCH_MAPPING[process.arch]}`;
50
85
 
51
86
  if (!fs.existsSync("./dist")) {
52
- // download respective release zip from github
53
- const pkgUrl = opts.binUrl.replace("{{version}}", opts.version).replace("{{platform}}", PLATFORM_MAPPING[process.platform]).replace("{{arch}}", ARCH_MAPPING[process.arch]);
54
- console.info(`Getting release archive from ${pkgUrl} into ${path.resolve(src)}`);
55
- try {
56
- // support for http/s proxies through env vars
57
- const proxy = proxyFromEnv.getProxyForUrl(pkgUrl);
58
- let httpAgent, httpsAgent;
59
- if (proxy) {
60
- httpAgent = new httpProxyAgent.HttpProxyAgent(proxy);
61
- httpsAgent = new httpsProxyAgent.HttpsProxyAgent(proxy);
87
+ // download respective release zip from github or fallback repositories
88
+ const primaryUrl = opts.binUrl.replace("{{version}}", opts.version).replace("{{platform}}", PLATFORM_MAPPING[process.platform]).replace("{{arch}}", ARCH_MAPPING[process.arch]);
89
+ const versionedFallbackName = `cmf-cli.${PLATFORM_MAPPING[process.platform]}-${ARCH_MAPPING[process.arch]}-${opts.version}.zip`;
90
+ const legacyFallbackName = `cmf-cli.${PLATFORM_MAPPING[process.platform]}-${ARCH_MAPPING[process.arch]}.zip`;
91
+
92
+ // Fallback URLs for alternative repositories
93
+ const fallbackUrls = [
94
+ `https://criticalmanufacturing.io/repository/tools/${versionedFallbackName}`,
95
+ `https://criticalmanufacturing.io/repository/tools/${legacyFallbackName}`,
96
+ `https://repository.criticalmanufacturing.com.cn/repository/tools/${versionedFallbackName}`,
97
+ `https://repository.criticalmanufacturing.com.cn/repository/tools/${legacyFallbackName}`
98
+ ];
99
+
100
+ // Try downloading from primary URL and fallbacks
101
+ const allUrls = [primaryUrl, ...fallbackUrls];
102
+ let downloadSucceeded = false;
103
+
104
+ for (const pkgUrl of allUrls) {
105
+ try {
106
+ await downloadAndExtract(pkgUrl, src);
107
+ console.info(`Package downloaded successfully from ${pkgUrl}`);
108
+ downloadSucceeded = true;
109
+ break;
110
+ } catch (e) {
111
+ error(`Failed to download from ${pkgUrl}: ${e.message}`);
62
112
  }
63
-
64
- // make req (override axios automatic proxy since it is not working properly)
65
- const response = await axios({
66
- url: pkgUrl,
67
- method: 'GET',
68
- proxy: false,
69
- httpAgent: httpAgent,
70
- httpsAgent: httpsAgent,
71
- responseType: 'arraybuffer', // to do this with streaming we must deal with chunking
72
- });
73
- const zip = tmp.tmpNameSync();
74
- debug(`Writing temporary zip file to ${zip}`);
75
- fs.writeFileSync(zip, response.data);
76
- debug(`Extracting zip file ${zip} to ${src}`);
77
- (new AdmZip(zip)).extractAllTo(src);
78
- rimraf.sync(zip);
79
- } catch (e) {
80
- error(e);
81
- callback(`Could not install version ${opts.version} on your platform ${process.platform}/${process.arch}: ${e.message}`);
113
+ }
114
+
115
+ if (!downloadSucceeded) {
116
+ callback(`Could not install version ${opts.version} on your platform ${process.platform}/${process.arch} from any repository.`);
117
+ return;
82
118
  }
83
119
  }
84
120