@abtnode/util 1.15.17 → 1.16.0-beta-b16cb035
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/lib/async-pm2.js +13 -0
- package/lib/axios.js +32 -4
- package/lib/base32.js +14 -0
- package/lib/can-pkg-rw.js +1 -1
- package/lib/check-domain-match.js +8 -3
- package/lib/did-document.js +128 -0
- package/lib/download-file.js +51 -9
- package/lib/ensure-endpoint-healthy.js +1 -1
- package/lib/format-back-slash.js +9 -0
- package/lib/format-context.js +28 -0
- package/lib/format-name.js +5 -0
- package/lib/get-folder-size.js +16 -1
- package/lib/get-ip.js +6 -6
- package/lib/is-ec2.js +9 -8
- package/lib/is-path-prefix-equal.js +3 -0
- package/lib/locate-npm-global-by-binary.js +16 -6
- package/lib/log.js +391 -0
- package/lib/logo-middleware.js +136 -0
- package/lib/nft.js +15 -0
- package/lib/run-script.js +131 -0
- package/lib/security.js +45 -0
- package/lib/sleep.js +1 -0
- package/lib/url-evaluation/check-accessible-browser.js +17 -0
- package/lib/url-evaluation/check-accessible-node.js +14 -0
- package/lib/url-evaluation/index.js +86 -0
- package/lib/user-avatar.js +69 -0
- package/package.json +42 -19
- package/lib/sys-info.js +0 -56
- /package/lib/{get-node-wallet.js → get-app-wallet.js} +0 -0
package/lib/async-pm2.js
CHANGED
|
@@ -20,6 +20,19 @@ const api = [
|
|
|
20
20
|
'stop',
|
|
21
21
|
];
|
|
22
22
|
|
|
23
|
+
const nodeArgs = [];
|
|
24
|
+
|
|
25
|
+
const originStart = pm2.start.bind(pm2);
|
|
26
|
+
pm2.start = (opts, cb) => {
|
|
27
|
+
if (opts.node_args) {
|
|
28
|
+
opts.node_args = `${opts.node_args} ${nodeArgs.join(' ')}`.trim();
|
|
29
|
+
} else {
|
|
30
|
+
opts.node_args = nodeArgs.join(' ');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return originStart(opts, cb);
|
|
34
|
+
};
|
|
35
|
+
|
|
23
36
|
api.forEach((x) => {
|
|
24
37
|
if (typeof pm2[x] === 'function') {
|
|
25
38
|
pm2[`${x}Async`] = promisify(pm2[x]).bind(pm2);
|
package/lib/axios.js
CHANGED
|
@@ -1,7 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const axios = require('axios');
|
|
1
|
+
const axios = require('axios').default;
|
|
2
|
+
const { HttpProxyAgent, HttpsProxyAgent } = require('hpagent');
|
|
4
3
|
|
|
5
|
-
|
|
4
|
+
function proxyInterceptor(config) {
|
|
5
|
+
/* istanbul ignore if */
|
|
6
|
+
if (config.socketPath != null) return config;
|
|
7
|
+
|
|
8
|
+
const { proxy } = config;
|
|
9
|
+
|
|
10
|
+
/* istanbul ignore if */
|
|
11
|
+
if (proxy === false) return config;
|
|
12
|
+
|
|
13
|
+
const httpProxyUrl = process.env.HTTP_PROXY || process.env.http_proxy;
|
|
14
|
+
const httpsProxyUrl = process.env.HTTPS_PROXY || process.env.https_proxy;
|
|
15
|
+
|
|
16
|
+
const proxyOptions = Object.assign(
|
|
17
|
+
{ keepAlive: true, keepAliveMsecs: 1000, maxSockets: 256, maxFreeSockets: 256 },
|
|
18
|
+
config.proxyOptions || {}
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
if (httpProxyUrl) {
|
|
22
|
+
config.proxy = false;
|
|
23
|
+
config.httpAgent = new HttpProxyAgent({ proxy: httpProxyUrl, ...proxyOptions });
|
|
24
|
+
}
|
|
25
|
+
if (httpsProxyUrl) {
|
|
26
|
+
config.proxy = false;
|
|
27
|
+
config.httpsAgent = new HttpsProxyAgent({ proxy: httpsProxyUrl, ...proxyOptions });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return config;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
axios.interceptors.request.use(proxyInterceptor);
|
|
6
34
|
|
|
7
35
|
module.exports = axios;
|
package/lib/base32.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const { toBuffer } = require('@ocap/util');
|
|
2
|
+
const { base32 } = require('multiformats/bases/base32');
|
|
3
|
+
|
|
4
|
+
const encode = (did) => {
|
|
5
|
+
if (!did) {
|
|
6
|
+
return did;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const buffer = toBuffer(did);
|
|
10
|
+
|
|
11
|
+
return base32.encode(buffer);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
module.exports = { encode };
|
package/lib/can-pkg-rw.js
CHANGED
|
@@ -3,7 +3,7 @@ const locateNpmGlobalByBinary = require('./locate-npm-global-by-binary');
|
|
|
3
3
|
const { canReadAndWriteDir } = require('./fs');
|
|
4
4
|
|
|
5
5
|
module.exports = (cmdName, packageName) => {
|
|
6
|
-
const installDir = locateNpmGlobalByBinary(cmdName);
|
|
6
|
+
const installDir = locateNpmGlobalByBinary(cmdName, packageName);
|
|
7
7
|
if (!installDir) {
|
|
8
8
|
throw new Error(`${packageName} is not installed as a global package`);
|
|
9
9
|
}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
+
const toLower = require('lodash/toLower');
|
|
2
|
+
|
|
1
3
|
const WILDCARD = '*';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* check two domains match or not. e.g. *.arcblock.io matches www.arcblock.io
|
|
5
|
-
* @param {String}
|
|
6
|
-
* @param {String}
|
|
7
|
+
* @param {String} domainX
|
|
8
|
+
* @param {String} domainY
|
|
7
9
|
*/
|
|
8
|
-
const checkDomainMatch = (
|
|
10
|
+
const checkDomainMatch = (domainX, domainY) => {
|
|
11
|
+
const domain1 = toLower(domainX);
|
|
12
|
+
const domain2 = toLower(domainY);
|
|
13
|
+
|
|
9
14
|
if (!domain1 || !domain2) return false;
|
|
10
15
|
if (typeof domain1 !== 'string' || typeof domain2 !== 'string') return false;
|
|
11
16
|
if (domain1 === domain2) return true;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
const stringify = require('json-stable-stringify');
|
|
2
|
+
const { toBase64, toBase58 } = require('@ocap/util');
|
|
3
|
+
const joinUrl = require('url-join');
|
|
4
|
+
const pRetry = require('p-retry');
|
|
5
|
+
const debug = require('debug')('@abtnode/util:did-document');
|
|
6
|
+
const axios = require('./axios');
|
|
7
|
+
const { encode: encodeBase32 } = require('./base32');
|
|
8
|
+
|
|
9
|
+
const getDID = (address) => {
|
|
10
|
+
if (!address || typeof address !== 'string') {
|
|
11
|
+
return address;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (address.startsWith('did:abt:')) {
|
|
15
|
+
return address;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return `did:abt:${address}`;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const update = async ({ services, didRegistryUrl, wallet, alsoKnownAs = [] }) => {
|
|
22
|
+
debug('update did document', { didRegistryUrl });
|
|
23
|
+
|
|
24
|
+
const did = getDID(wallet.address);
|
|
25
|
+
const time = new Date().toISOString();
|
|
26
|
+
|
|
27
|
+
const document = {
|
|
28
|
+
'@context': 'https://www.w3.org/ns/did/v1',
|
|
29
|
+
id: did,
|
|
30
|
+
controller: did,
|
|
31
|
+
service: services,
|
|
32
|
+
alsoKnownAs,
|
|
33
|
+
verificationMethod: [
|
|
34
|
+
{
|
|
35
|
+
id: `${did}#key-1`,
|
|
36
|
+
type: 'Ed25519Signature',
|
|
37
|
+
controller: did,
|
|
38
|
+
publicKeyMultibase: toBase58(wallet.publicKey),
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
authentication: [`${did}#key-1`],
|
|
42
|
+
created: time,
|
|
43
|
+
updated: time,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const proof = {
|
|
47
|
+
type: 'Ed25519Signature',
|
|
48
|
+
created: time,
|
|
49
|
+
verificationMethod: `${did}#key-1`,
|
|
50
|
+
jws: toBase64(wallet.sign(stringify(document))),
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
document.proof = proof;
|
|
54
|
+
|
|
55
|
+
return axios.post(joinUrl(didRegistryUrl, '/.well-known/did-resolver/registries'), document, { timeout: 10 * 1000 });
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const updateWithRetry = async (...args) => pRetry(() => update(...args), { retries: 3 });
|
|
59
|
+
|
|
60
|
+
const getServerServices = ({ ips, wallet, domain }) => {
|
|
61
|
+
const records = ips.map((ip) => ({
|
|
62
|
+
type: 'A',
|
|
63
|
+
rr: encodeBase32(wallet.address),
|
|
64
|
+
value: ip,
|
|
65
|
+
domain,
|
|
66
|
+
}));
|
|
67
|
+
|
|
68
|
+
const services = [
|
|
69
|
+
{
|
|
70
|
+
id: getDID(wallet.address),
|
|
71
|
+
type: 'DNSRecords',
|
|
72
|
+
records,
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
return services;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const getBlockletServices = ({ appPid, daemonDidDomain, domain }) => {
|
|
80
|
+
return [
|
|
81
|
+
{
|
|
82
|
+
id: getDID(appPid),
|
|
83
|
+
type: 'DNSRecords',
|
|
84
|
+
records: [
|
|
85
|
+
{
|
|
86
|
+
type: 'CNAME',
|
|
87
|
+
rr: encodeBase32(appPid),
|
|
88
|
+
value: daemonDidDomain,
|
|
89
|
+
domain,
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const updateServerDocument = async ({ ips, wallet, didRegistryUrl, domain }) => {
|
|
97
|
+
const filteredIps = (ips || []).filter(Boolean);
|
|
98
|
+
if (filteredIps.length === 0) {
|
|
99
|
+
throw new Error('No DID Document to update');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const services = getServerServices({ ips: filteredIps, domain, wallet });
|
|
103
|
+
|
|
104
|
+
return updateWithRetry({ services, didRegistryUrl, wallet });
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const updateBlockletDocument = async ({
|
|
108
|
+
wallet,
|
|
109
|
+
didRegistryUrl,
|
|
110
|
+
domain,
|
|
111
|
+
daemonDidDomain,
|
|
112
|
+
appPid,
|
|
113
|
+
alsoKnownAs = [],
|
|
114
|
+
}) => {
|
|
115
|
+
const services = getBlockletServices({ appPid, daemonDidDomain, domain });
|
|
116
|
+
return updateWithRetry({ services, didRegistryUrl, alsoKnownAs, wallet });
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const disableDNS = async ({ wallet, didRegistryUrl }) => updateWithRetry({ services: [], didRegistryUrl, wallet });
|
|
120
|
+
|
|
121
|
+
module.exports = {
|
|
122
|
+
updateServerDocument,
|
|
123
|
+
updateBlockletDocument,
|
|
124
|
+
disableDNS,
|
|
125
|
+
getDID,
|
|
126
|
+
getServerServices,
|
|
127
|
+
getBlockletServices,
|
|
128
|
+
};
|
package/lib/download-file.js
CHANGED
|
@@ -7,18 +7,56 @@ const axios = require('./axios');
|
|
|
7
7
|
const CANCEL = '__cancel__';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* @param {
|
|
13
|
-
* @
|
|
14
|
-
* @param {CancelCtrl} cancelCtrl
|
|
10
|
+
*
|
|
11
|
+
*
|
|
12
|
+
* @param {Stream} stream
|
|
13
|
+
* @returns {Promise<string>}
|
|
15
14
|
*/
|
|
16
|
-
|
|
15
|
+
async function getErrorMessageFromStream(stream) {
|
|
16
|
+
const str = await streamToString(stream);
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
const json = JSON.parse(str);
|
|
20
|
+
return json.error;
|
|
21
|
+
} catch (error) {
|
|
22
|
+
return str;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
*
|
|
28
|
+
*
|
|
29
|
+
* @param {*} stream
|
|
30
|
+
* @return {Promise<string>}
|
|
31
|
+
*/
|
|
32
|
+
async function streamToString(stream) {
|
|
33
|
+
const chunks = [];
|
|
34
|
+
|
|
35
|
+
for await (const chunk of stream) {
|
|
36
|
+
chunks.push(Buffer.from(chunk));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return Buffer.concat(chunks).toString('utf-8');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
*
|
|
44
|
+
*
|
|
45
|
+
* @param {*} url
|
|
46
|
+
* @param {*} dest directory
|
|
47
|
+
* @param {{
|
|
48
|
+
* timeout: number; // unit: ms
|
|
49
|
+
* cancelCtrl: any;
|
|
50
|
+
* }} [{ timeout = 600 * 1000, cancelCtrl, data }={}]
|
|
51
|
+
* @param {{}} context
|
|
52
|
+
* @return {*}
|
|
53
|
+
*/
|
|
54
|
+
const downloadFile = async (url, dest, { timeout = 600 * 1000, cancelCtrl } = {}, context = {}) => {
|
|
17
55
|
const CONNECTION_TIMEOUT = 20 * 1000;
|
|
18
56
|
const source = CancelToken.source();
|
|
19
57
|
|
|
20
58
|
try {
|
|
21
|
-
|
|
59
|
+
return await tryWithTimeout(async () => {
|
|
22
60
|
const timer = setTimeout(() => {
|
|
23
61
|
source.cancel(`Connection timeout: ${Math.ceil(CONNECTION_TIMEOUT / 1000)}s`);
|
|
24
62
|
}, CONNECTION_TIMEOUT);
|
|
@@ -39,6 +77,7 @@ const downloadFile = async (url, dest, { timeout = 600 * 1000, cancelCtrl } = {}
|
|
|
39
77
|
|
|
40
78
|
const response = await axios({
|
|
41
79
|
url,
|
|
80
|
+
headers: context?.headers,
|
|
42
81
|
method: 'GET',
|
|
43
82
|
responseType: 'stream',
|
|
44
83
|
cancelToken: source.token,
|
|
@@ -61,8 +100,6 @@ const downloadFile = async (url, dest, { timeout = 600 * 1000, cancelCtrl } = {}
|
|
|
61
100
|
|
|
62
101
|
return dest;
|
|
63
102
|
}, timeout);
|
|
64
|
-
|
|
65
|
-
return result;
|
|
66
103
|
} catch (err) {
|
|
67
104
|
if (fs.existsSync(dest)) {
|
|
68
105
|
fs.unlinkSync(dest);
|
|
@@ -76,6 +113,11 @@ const downloadFile = async (url, dest, { timeout = 600 * 1000, cancelCtrl } = {}
|
|
|
76
113
|
}
|
|
77
114
|
|
|
78
115
|
source.cancel();
|
|
116
|
+
|
|
117
|
+
if (err?.response?.data) {
|
|
118
|
+
throw new Error(await getErrorMessageFromStream(err.response.data));
|
|
119
|
+
}
|
|
120
|
+
|
|
79
121
|
throw err;
|
|
80
122
|
}
|
|
81
123
|
};
|
|
@@ -62,7 +62,7 @@ module.exports = async ({
|
|
|
62
62
|
host = '127.0.0.1',
|
|
63
63
|
port,
|
|
64
64
|
timeout = 10 * ONE_SECOND,
|
|
65
|
-
minConsecutiveTime = 5 * ONE_SECOND,
|
|
65
|
+
minConsecutiveTime = (+process.env.ENDPOINT_CONSECUTIVE_TIME || 5) * ONE_SECOND,
|
|
66
66
|
}) => {
|
|
67
67
|
debug('ensure endpoint healthy', { port, minConsecutiveTime });
|
|
68
68
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const lodash = require('lodash');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Replace the back slack('\') with forward slash('/')
|
|
5
|
+
* @param {*} str
|
|
6
|
+
* @param {*} flag RegExp flag, default is 'g'
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
module.exports = (str) => lodash.replace(str, new RegExp(lodash.escapeRegExp('\\'), 'g'), '/');
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const get = require('lodash/get');
|
|
2
|
+
|
|
3
|
+
// Format context: https://github.com/graphql/express-graphql
|
|
4
|
+
module.exports = (ctx = {}) => {
|
|
5
|
+
if (ctx && ctx.user) {
|
|
6
|
+
delete ctx.user.avatar;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const safeGet = (key, _default = '') =>
|
|
10
|
+
(typeof ctx.get === 'function' ? ctx.get(key) : get(ctx, `headers[${key}]`)) || _default;
|
|
11
|
+
const port = process.env.NODE_ENV === 'production' ? safeGet('x-real-port') : '';
|
|
12
|
+
const result = {
|
|
13
|
+
ip: safeGet('x-real-ip', '127.0.0.1'),
|
|
14
|
+
ua: safeGet('user-agent'),
|
|
15
|
+
protocol: safeGet('x-real-protocol').replace(/:$/, '') || 'http',
|
|
16
|
+
user: ctx.user || {},
|
|
17
|
+
url: ctx.originalUrl,
|
|
18
|
+
query: ctx.query,
|
|
19
|
+
hostname: safeGet('x-real-hostname'),
|
|
20
|
+
port: Number(port) === 80 ? '' : Number(port),
|
|
21
|
+
nodeMode: ctx.nodeMode,
|
|
22
|
+
referrer: safeGet('referrer'),
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// 警告,尽量不要在这里传递整个 headers 对象,因为可能会影响后续流程
|
|
26
|
+
|
|
27
|
+
return result;
|
|
28
|
+
};
|
package/lib/get-folder-size.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
const getSize = require('get-folder-size');
|
|
1
2
|
const exec = require('child_process').execFile;
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
const getOnUnixLike = (dir) => {
|
|
4
5
|
const regex = /^(\d*)/;
|
|
5
6
|
|
|
6
7
|
return new Promise((resolve, reject) => {
|
|
@@ -16,3 +17,17 @@ module.exports = (dir) => {
|
|
|
16
17
|
});
|
|
17
18
|
});
|
|
18
19
|
};
|
|
20
|
+
|
|
21
|
+
const getOnWindows = (dir) => {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
getSize(dir, (err, size) => {
|
|
24
|
+
if (err) {
|
|
25
|
+
return reject(err);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return resolve(size);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
module.exports = process.platform === 'win32' ? getOnWindows : getOnUnixLike;
|
package/lib/get-ip.js
CHANGED
|
@@ -14,23 +14,23 @@ const getExternalIp = async ({ v6 = false, timeout = 5000 } = {}) => {
|
|
|
14
14
|
}
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
const getIP = async ({ includeV6 = false, timeout = 5000 } = {}) => {
|
|
17
|
+
const getIP = async ({ includeV6 = false, timeout = 5000, includeExternal = true } = {}) => {
|
|
18
18
|
try {
|
|
19
|
-
if (isEC2()) {
|
|
19
|
+
if (await isEC2()) {
|
|
20
20
|
const [internal, external, internalV6, externalV6] = await Promise.all([
|
|
21
21
|
getEc2Meta('local-ipv4', timeout),
|
|
22
|
-
getEc2Meta('public-ipv4', timeout),
|
|
22
|
+
includeExternal ? getEc2Meta('public-ipv4', timeout) : '',
|
|
23
23
|
includeV6 ? getEc2Meta('local-ipv6', timeout) : '',
|
|
24
|
-
includeV6 ? getEc2Meta('public-ipv6', timeout) : '',
|
|
24
|
+
includeV6 && includeExternal ? getEc2Meta('public-ipv6', timeout) : '',
|
|
25
25
|
]);
|
|
26
26
|
return { internal, external, internalV6, externalV6 };
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
const [internal, external, internalV6, externalV6] = await Promise.all([
|
|
30
30
|
internalIp.v4(),
|
|
31
|
-
getExternalIp({ timeout }),
|
|
31
|
+
includeExternal ? getExternalIp({ timeout }) : '',
|
|
32
32
|
includeV6 ? internalIp.v6() : '',
|
|
33
|
-
includeV6 ? getExternalIp({ v6: true, timeout }) : '',
|
|
33
|
+
includeV6 && includeExternal ? getExternalIp({ v6: true, timeout }) : '',
|
|
34
34
|
]);
|
|
35
35
|
return { internal, external, internalV6, externalV6 };
|
|
36
36
|
} catch (err) {
|
package/lib/is-ec2.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
const
|
|
1
|
+
const axios = require('./axios');
|
|
2
2
|
|
|
3
3
|
// Whether we are running in an pre-baked image
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
4
|
+
// refer: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/identify_ec2_instances.html
|
|
5
|
+
async function isEC2() {
|
|
6
|
+
try {
|
|
7
|
+
const url = 'http://169.254.169.254/latest/dynamic/instance-identity/document';
|
|
8
|
+
const { status } = await axios.get(url, { timeout: 1000 });
|
|
9
|
+
return status === 200;
|
|
10
|
+
} catch {
|
|
11
|
+
return false;
|
|
9
12
|
}
|
|
10
|
-
|
|
11
|
-
return false;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
module.exports = isEC2;
|
|
@@ -1,22 +1,32 @@
|
|
|
1
|
-
/* eslint-disable no-unused-vars, no-console */
|
|
2
|
-
|
|
3
1
|
const fs = require('fs');
|
|
4
2
|
const path = require('path');
|
|
5
|
-
const
|
|
3
|
+
const shell = require('shelljs');
|
|
6
4
|
|
|
7
|
-
module.exports = (binaryName) => {
|
|
5
|
+
module.exports = (binaryName, packageName) => {
|
|
8
6
|
if (!binaryName) {
|
|
9
7
|
throw new Error('binaryName is required');
|
|
10
8
|
}
|
|
11
9
|
|
|
12
|
-
|
|
10
|
+
let result = shell.which(binaryName);
|
|
13
11
|
if (!result || !result.stdout) {
|
|
14
12
|
return '';
|
|
15
13
|
}
|
|
16
14
|
|
|
17
|
-
const binPath = result.stdout;
|
|
15
|
+
const binPath = result.stdout.trim();
|
|
18
16
|
|
|
17
|
+
// Check if the package is installed via pnpm: only if we have packageName set
|
|
19
18
|
let binDir = path.dirname(fs.realpathSync(binPath));
|
|
19
|
+
if (packageName) {
|
|
20
|
+
const { stdout: pnpmPath } = shell.which('pnpm') || {};
|
|
21
|
+
if (pnpmPath) {
|
|
22
|
+
result = shell.exec('pnpm bin -g', { silent: true });
|
|
23
|
+
const pnpmBinDir = result.stdout.trim();
|
|
24
|
+
if (binDir === pnpmBinDir) {
|
|
25
|
+
result = shell.exec(`pnpm root -g ${packageName}`, { silent: true });
|
|
26
|
+
return path.join(result.stdout.trim(), packageName);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
20
30
|
|
|
21
31
|
while (binDir && binDir !== path.sep && path.basename(binDir) !== 'node_modules') {
|
|
22
32
|
const packageJsonPath = path.join(binDir, 'package.json');
|