install-nix-action/node_modules/ts-node/dist/bin.js
Domen Kožar 08403cd828
v5
2019-11-13 17:14:48 +01:00

345 lines
10 KiB
JavaScript
Executable File

#!/usr/bin/env node
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = require("path");
const repl_1 = require("repl");
const util_1 = require("util");
const Module = require("module");
const arg = require("arg");
const diff_1 = require("diff");
const vm_1 = require("vm");
const fs_1 = require("fs");
const index_1 = require("./index");
const args = arg({
// Node.js-like options.
'--eval': String,
'--print': Boolean,
'--require': [String],
// CLI options.
'--files': Boolean,
'--help': Boolean,
'--version': arg.COUNT,
// Project options.
'--compiler': String,
'--compiler-options': index_1.parse,
'--project': String,
'--ignore-diagnostics': [String],
'--ignore': [String],
'--transpile-only': Boolean,
'--type-check': Boolean,
'--pretty': Boolean,
'--skip-project': Boolean,
'--skip-ignore': Boolean,
'--prefer-ts-exts': Boolean,
'--log-error': Boolean,
// Aliases.
'-e': '--eval',
'-p': '--print',
'-r': '--require',
'-h': '--help',
'-v': '--version',
'-T': '--transpile-only',
'-I': '--ignore',
'-P': '--project',
'-C': '--compiler',
'-D': '--ignore-diagnostics',
'-O': '--compiler-options'
}, {
stopAtPositional: true
});
const { '--help': help = false, '--version': version = 0, '--files': files = index_1.DEFAULTS.files, '--compiler': compiler = index_1.DEFAULTS.compiler, '--compiler-options': compilerOptions = index_1.DEFAULTS.compilerOptions, '--project': project = index_1.DEFAULTS.project, '--ignore-diagnostics': ignoreDiagnostics = index_1.DEFAULTS.ignoreDiagnostics, '--ignore': ignore = index_1.DEFAULTS.ignore, '--transpile-only': transpileOnly = index_1.DEFAULTS.transpileOnly, '--type-check': typeCheck = index_1.DEFAULTS.typeCheck, '--pretty': pretty = index_1.DEFAULTS.pretty, '--skip-project': skipProject = index_1.DEFAULTS.skipProject, '--skip-ignore': skipIgnore = index_1.DEFAULTS.skipIgnore, '--prefer-ts-exts': preferTsExts = index_1.DEFAULTS.preferTsExts, '--log-error': logError = index_1.DEFAULTS.logError } = args;
if (help) {
console.log(`
Usage: ts-node [options] [ -e script | script.ts ] [arguments]
Options:
-e, --eval [code] Evaluate code
-p, --print Print result of \`--eval\`
-r, --require [path] Require a node module before execution
-h, --help Print CLI usage
-v, --version Print module version information
-T, --transpile-only Use TypeScript's faster \`transpileModule\`
-I, --ignore [pattern] Override the path patterns to skip compilation
-P, --project [path] Path to TypeScript JSON project file
-C, --compiler [name] Specify a custom TypeScript compiler
-D, --ignore-diagnostics [code] Ignore TypeScript warnings by diagnostic code
-O, --compiler-options [opts] JSON object to merge with compiler options
--files Load files from \`tsconfig.json\` on startup
--pretty Use pretty diagnostic formatter
--skip-project Skip reading \`tsconfig.json\`
--skip-ignore Skip \`--ignore\` checks
--prefer-ts-exts Prefer importing TypeScript files over JavaScript files
`);
process.exit(0);
}
// Output project information.
if (version === 1) {
console.log(`v${index_1.VERSION}`);
process.exit(0);
}
const cwd = process.cwd();
const code = args['--eval'];
const isPrinted = args['--print'] !== undefined;
/**
* Eval helpers.
*/
const EVAL_FILENAME = `[eval].ts`;
const EVAL_PATH = path_1.join(cwd, EVAL_FILENAME);
const EVAL_INSTANCE = { input: '', output: '', version: 0, lines: 0 };
// Register the TypeScript compiler instance.
const service = index_1.register({
files,
pretty,
typeCheck,
transpileOnly,
ignore,
project,
skipIgnore,
preferTsExts,
logError,
skipProject,
compiler,
ignoreDiagnostics,
compilerOptions,
readFile: code ? readFileEval : undefined,
fileExists: code ? fileExistsEval : undefined
});
// Output project information.
if (version >= 2) {
console.log(`ts-node v${index_1.VERSION}`);
console.log(`node ${process.version}`);
console.log(`compiler v${service.ts.version}`);
process.exit(0);
}
// Require specified modules before start-up.
if (args['--require'])
Module._preloadModules(args['--require']);
// Prepend `ts-node` arguments to CLI for child processes.
process.execArgv.unshift(__filename, ...process.argv.slice(2, process.argv.length - args._.length));
process.argv = [process.argv[1]].concat(args._.length ? path_1.resolve(cwd, args._[0]) : []).concat(args._.slice(1));
// Execute the main contents (either eval, script or piped).
if (code) {
evalAndExit(code, isPrinted);
}
else {
if (args._.length) {
Module.runMain();
}
else {
// Piping of execution _only_ occurs when no other script is specified.
if (process.stdin.isTTY) {
startRepl();
}
else {
let code = '';
process.stdin.on('data', (chunk) => code += chunk);
process.stdin.on('end', () => evalAndExit(code, isPrinted));
}
}
}
/**
* Evaluate a script.
*/
function evalAndExit(code, isPrinted) {
const module = new Module(EVAL_FILENAME);
module.filename = EVAL_FILENAME;
module.paths = Module._nodeModulePaths(cwd);
global.__filename = EVAL_FILENAME;
global.__dirname = cwd;
global.exports = module.exports;
global.module = module;
global.require = module.require.bind(module);
let result;
try {
result = _eval(code);
}
catch (error) {
if (error instanceof index_1.TSError) {
console.error(error.diagnosticText);
process.exit(1);
}
throw error;
}
if (isPrinted) {
console.log(typeof result === 'string' ? result : util_1.inspect(result));
}
}
/**
* Evaluate the code snippet.
*/
function _eval(input) {
const lines = EVAL_INSTANCE.lines;
const isCompletion = !/\n$/.test(input);
const undo = appendEval(input);
let output;
try {
output = service.compile(EVAL_INSTANCE.input, EVAL_PATH, -lines);
}
catch (err) {
undo();
throw err;
}
// Use `diff` to check for new JavaScript to execute.
const changes = diff_1.diffLines(EVAL_INSTANCE.output, output);
if (isCompletion) {
undo();
}
else {
EVAL_INSTANCE.output = output;
}
return changes.reduce((result, change) => {
return change.added ? exec(change.value, EVAL_FILENAME) : result;
}, undefined);
}
/**
* Execute some code.
*/
function exec(code, filename) {
const script = new vm_1.Script(code, { filename: filename });
return script.runInThisContext();
}
/**
* Start a CLI REPL.
*/
function startRepl() {
const repl = repl_1.start({
prompt: '> ',
input: process.stdin,
output: process.stdout,
terminal: process.stdout.isTTY,
eval: replEval,
useGlobal: true
});
// Bookmark the point where we should reset the REPL state.
const resetEval = appendEval('');
function reset() {
resetEval();
// Hard fix for TypeScript forcing `Object.defineProperty(exports, ...)`.
exec('exports = module.exports', EVAL_FILENAME);
}
reset();
repl.on('reset', reset);
repl.defineCommand('type', {
help: 'Check the type of a TypeScript identifier',
action: function (identifier) {
if (!identifier) {
repl.displayPrompt();
return;
}
const undo = appendEval(identifier);
const { name, comment } = service.getTypeInfo(EVAL_INSTANCE.input, EVAL_PATH, EVAL_INSTANCE.input.length);
undo();
repl.outputStream.write(`${name}\n${comment ? `${comment}\n` : ''}`);
repl.displayPrompt();
}
});
}
/**
* Eval code from the REPL.
*/
function replEval(code, _context, _filename, callback) {
let err = null;
let result;
// TODO: Figure out how to handle completion here.
if (code === '.scope') {
callback(err);
return;
}
try {
result = _eval(code);
}
catch (error) {
if (error instanceof index_1.TSError) {
// Support recoverable compilations using >= node 6.
if (repl_1.Recoverable && isRecoverable(error)) {
err = new repl_1.Recoverable(error);
}
else {
console.error(error.diagnosticText);
}
}
else {
err = error;
}
}
callback(err, result);
}
/**
* Append to the eval instance and return an undo function.
*/
function appendEval(input) {
const undoInput = EVAL_INSTANCE.input;
const undoVersion = EVAL_INSTANCE.version;
const undoOutput = EVAL_INSTANCE.output;
const undoLines = EVAL_INSTANCE.lines;
// Handle ASI issues with TypeScript re-evaluation.
if (undoInput.charAt(undoInput.length - 1) === '\n' && /^\s*[\[\(\`]/.test(input) && !/;\s*$/.test(undoInput)) {
EVAL_INSTANCE.input = `${EVAL_INSTANCE.input.slice(0, -1)};\n`;
}
EVAL_INSTANCE.input += input;
EVAL_INSTANCE.lines += lineCount(input);
EVAL_INSTANCE.version++;
return function () {
EVAL_INSTANCE.input = undoInput;
EVAL_INSTANCE.output = undoOutput;
EVAL_INSTANCE.version = undoVersion;
EVAL_INSTANCE.lines = undoLines;
};
}
/**
* Count the number of lines.
*/
function lineCount(value) {
let count = 0;
for (const char of value) {
if (char === '\n') {
count++;
}
}
return count;
}
/**
* Get the file text, checking for eval first.
*/
function readFileEval(path) {
if (path === EVAL_PATH)
return EVAL_INSTANCE.input;
try {
return fs_1.readFileSync(path, 'utf8');
}
catch (err) { /* Ignore. */ }
}
/**
* Get whether the file exists.
*/
function fileExistsEval(path) {
if (path === EVAL_PATH)
return true;
try {
const stats = fs_1.statSync(path);
return stats.isFile() || stats.isFIFO();
}
catch (err) {
return false;
}
}
const RECOVERY_CODES = new Set([
1003,
1005,
1109,
1126,
1160,
1161,
2355 // "A function whose declared type is neither 'void' nor 'any' must return a value."
]);
/**
* Check if a function can recover gracefully.
*/
function isRecoverable(error) {
return error.diagnosticCodes.every(code => RECOVERY_CODES.has(code));
}
//# sourceMappingURL=bin.js.map