@magentrix-corp/magentrix-cli 1.3.15 → 1.3.16

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magentrix-corp/magentrix-cli",
3
- "version": "1.3.15",
3
+ "version": "1.3.16",
4
4
  "description": "CLI tool for synchronizing local files with Magentrix cloud platform",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -1,3 +1,4 @@
1
+ import { lookup } from 'node:dns/promises';
1
2
  import debug from '../debug.js';
2
3
 
3
4
  /**
@@ -11,11 +12,25 @@ import debug from '../debug.js';
11
12
  */
12
13
  export const checkInstanceUrl = async (instanceUrl) => {
13
14
  debug.log('URL-CHECK', `Checking reachability: GET ${instanceUrl}`);
15
+
16
+ // Resolve DNS first to help diagnose hosts file / local server issues
17
+ const hostname = new URL(instanceUrl).hostname;
18
+ try {
19
+ const { address, family } = await lookup(hostname);
20
+ debug.log('URL-CHECK', `DNS resolved: ${hostname} -> ${address} (IPv${family})`);
21
+ } catch (dnsErr) {
22
+ debug.log('URL-CHECK', `DNS lookup failed for ${hostname}: ${dnsErr.code || dnsErr.message}`);
23
+ }
24
+
25
+ const controller = new AbortController();
26
+ const timeout = setTimeout(() => {
27
+ debug.log('URL-CHECK', `Timeout after 15s — aborting request to ${instanceUrl}. If this is a local server (hosts file), check: (1) IIS has an HTTPS binding on port 443 for this hostname, (2) the SSL certificate is valid/trusted for "${hostname}", (3) Node.js trusts the certificate (self-signed certs require NODE_EXTRA_CA_CERTS or NODE_TLS_REJECT_UNAUTHORIZED=0)`);
28
+ controller.abort();
29
+ }, 15000);
14
30
  try {
15
- // Native fetch is available in Node 18+; for older versions, use node-fetch.
16
31
  const response = await fetch(instanceUrl, {
17
32
  method: "GET",
18
- // You can add a small timeout here using AbortController if needed.
33
+ signal: controller.signal,
19
34
  });
20
35
 
21
36
  debug.log('URL-CHECK', `Response: ${response.status} ${response.statusText}`);
@@ -30,7 +45,19 @@ export const checkInstanceUrl = async (instanceUrl) => {
30
45
  const cause = err.cause || {};
31
46
  const rootCode = cause.code || '';
32
47
  const rootMsg = cause.message || '';
33
- const detail = rootCode ? `${rootCode}: ${rootMsg}` : (err.message || String(err));
48
+ const isTimeout = err.name === 'AbortError' || rootCode === 'ABORT_ERR';
49
+ const isTLS = rootCode === 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' || rootCode === 'CERT_HAS_EXPIRED'
50
+ || rootCode === 'DEPTH_ZERO_SELF_SIGNED_CERT' || rootCode === 'ERR_TLS_CERT_ALTNAME_INVALID'
51
+ || rootCode === 'SELF_SIGNED_CERT_IN_CHAIN' || (rootMsg && rootMsg.includes('certificate'));
52
+
53
+ let detail;
54
+ if (isTimeout) {
55
+ detail = `Connection timed out after 15s. The server at "${hostname}" did not respond. Check the debug log for DNS resolution and troubleshooting hints.`;
56
+ } else if (isTLS) {
57
+ detail = `SSL/TLS error (${rootCode}). If using a local server with a self-signed certificate, set NODE_TLS_REJECT_UNAUTHORIZED=0 or use NODE_EXTRA_CA_CERTS. Detail: ${rootMsg}`;
58
+ } else {
59
+ detail = rootCode ? `${rootCode}: ${rootMsg}` : (err.message || String(err));
60
+ }
34
61
 
35
62
  debug.log('URL-CHECK', `Failed: ${detail}`);
36
63
  if (cause.code) debug.log('URL-CHECK', `Error code: ${cause.code}`);
@@ -41,5 +68,7 @@ export const checkInstanceUrl = async (instanceUrl) => {
41
68
  throw new Error(
42
69
  `Failed to reach instance URL "${instanceUrl}": ${detail}`
43
70
  );
71
+ } finally {
72
+ clearTimeout(timeout);
44
73
  }
45
74
  };