-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexec.js
More file actions
62 lines (49 loc) · 1.87 KB
/
exec.js
File metadata and controls
62 lines (49 loc) · 1.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
const fs = require('fs');
const child_process = require('child_process');
const crypto = require('crypto');
module.exports = { exec };
const scriptHashes = [];
const NODE_MODULES_DIR = (process.env.NODE_MODULES_DIR || '/mnt');
async function exec(script, args) {
const scriptHash = hash(script);
if (!exists(scriptHash)) {
await install(script);
}
const code = '(async function run () {' + Object.keys(args).map(key => `${key} = ${JSON.stringify(args[key])};`).join(';') + script + '})();';
return eval(code);
}
function hash(script) {
return sha256(script);
}
function exists(hash) {
return scriptHashes.indexOf(hash) !== -1;
}
async function install(script) {
const deps = [];
// extract the import dependecies from the script
const importRegex = /import(?:(?:(?:[ \n\t]+([^ *\n\t\{\},]+)[ \n\t]*(?:,|[ \n\t]+))?([ \n\t]*\{(?:[ \n\t]*[^ \n\t"'\{\}]+[ \n\t]*,?)+\})?[ \n\t]*)|[ \n\t]*\*[ \n\t]*as[ \n\t]+([^ \n\t\{\}]+)[ \n\t]+)from[ \n\t]*(?:['"])([^'"\n]+)(['"])/ig;
const importMatches = script.matchAll(importRegex);
for (const match of importMatches) {
deps.push(match[4]);
}
// extract the require depdencies from the script
const requireRegex = /require\(['"](.*?)['"]\)/g;
const requireMatches = script.matchAll(requireRegex);
for (const match of requireMatches) {
deps.push(match[1]);
}
// check to see which dependencies are already installed
const missingDeps = [];
deps.forEach(dep => {
const exists = fs.existsSync(`${NODE_MODULES_DIR}/node_modules/${dep}`);
if (!exists) {
missingDeps.push(dep);
}
});
for (dep of missingDeps) {
child_process.execSync(`cd ${NODE_MODULES_DIR} && npm install ${dep}`, {stdio: [0, 1, 2]});
}
}
function sha256(message) {
return crypto.createHash('sha256').update(message).digest('hex');
}