Skip to content

Instantly share code, notes, and snippets.

@ryancdotorg
Created December 22, 2023 18:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryancdotorg/163f778bf91877cceac1fb07139754f1 to your computer and use it in GitHub Desktop.
Save ryancdotorg/163f778bf91877cceac1fb07139754f1 to your computer and use it in GitHub Desktop.
#!/usr/bin/env node
const vm = require('vm');
const fs = require('fs');
const tty = require('tty');
const path = require('path');
const repl = require('repl');
const homedir = require('os').homedir();
const startup = path.join(homedir, '.fnode.js');
const start = function(input, code) {
console.log('Welcome to Node.js '+process.version+' ('+process.argv[0]+')');
const init = function(context) {
try {
// check whether the getter for 'crypto' works
context.crypto;
} catch (e) {
// 'Value of "this" must be of type nullish or must be the global object'
const crypto = global.crypto;
Object.defineProperty(context, 'crypto', {
get: () => crypto, enumerable: true, configurable: true
});
}
vm.runInContext(code, context);
};
const r = repl.start({
breakEvalOnSigint: true,
prompt: '> ',
input: input,
// if input is set but output isn't things break
output: process.stdout
});
// FIXME Windows support?
if (r.setupHistory && process.env['NODE_REPL_HISTORY'] !== '') {
let hist = process.env['NODE_REPL_HISTORY'] || path.join(homedir, '.node_repl_history');
r.setupHistory(hist, function(){});
}
// re-run the init code if the session is reset
r.on('reset', init);
// without this, sometimes one needs to press enter after Ctrl-D to exit.
r.on('exit', function(){ process.exit(0); });
init(r.context);
}
const readFiles = function(i) {
let fileName;
if (i == 1) {
if (fs.existsSync(startup)) {
fileName = startup;
} else {
readFiles(2);
}
} else if (i < process.argv.length) {
fileName = process.argv[i];
} else {
return start(replInput, code);
}
//console.log('filename', fileName, process.argv, i, process.argv.length);
fs.readFile(fileName, function(err, data) {
if (err) throw err;
code += ';\n' + data.toString();
readFiles(i+1);
});
}
let code = '', replInput = process.stdin;
// If stdin is a pipe, open the tty to read commands, and read
// startup code from stdin
if (!Boolean(process.stdin.isTTY)) {
replInput = tty.ReadStream(fs.openSync('/dev/tty', 'r'));
//replInput.setRawMode(false);
let buf = Buffer.alloc(0);
process.stdin.on('data', function(data) {
buf = Buffer.concat([buf, data]);
});
process.stdin.on('end', function() {
code += ';\n' + buf.toString();
readFiles(1);
});
} else {
readFiles(1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment