1 | #!/usr/bin/env node
|
2 | "use strict";
|
3 | Object.defineProperty(exports, "__esModule", { value: true });
|
4 | var path_1 = require("path");
|
5 | var repl_1 = require("repl");
|
6 | var util_1 = require("util");
|
7 | var arrify = require("arrify");
|
8 | var Module = require("module");
|
9 | var minimist = require("minimist");
|
10 | var chalk_1 = require("chalk");
|
11 | var diff_1 = require("diff");
|
12 | var vm_1 = require("vm");
|
13 | var fs_1 = require("fs");
|
14 | var index_1 = require("./index");
|
15 | var argv = minimist(process.argv.slice(2), {
|
16 | stopEarly: true,
|
17 | string: ['eval', 'print', 'compiler', 'project', 'ignoreDiagnostics', 'require', 'cacheDirectory', 'ignore'],
|
18 | boolean: ['help', 'transpileOnly', 'typeCheck', 'version', 'cache', 'skipProject', 'skipIgnore'],
|
19 | alias: {
|
20 | eval: ['e'],
|
21 | print: ['p'],
|
22 | require: ['r'],
|
23 | help: ['h'],
|
24 | version: ['v'],
|
25 | typeCheck: ['type-check'],
|
26 | transpileOnly: ['T', 'transpile-only'],
|
27 | cacheDirectory: ['cache-directory'],
|
28 | ignore: ['I'],
|
29 | project: ['P'],
|
30 | skipIgnore: ['skip-ignore'],
|
31 | skipProject: ['skip-project'],
|
32 | compiler: ['C'],
|
33 | ignoreDiagnostics: ['D', 'ignore-diagnostics'],
|
34 | compilerOptions: ['O', 'compiler-options']
|
35 | },
|
36 | default: {
|
37 | cache: index_1.DEFAULTS.cache,
|
38 | typeCheck: index_1.DEFAULTS.typeCheck,
|
39 | transpileOnly: index_1.DEFAULTS.transpileOnly,
|
40 | skipIgnore: index_1.DEFAULTS.skipIgnore,
|
41 | skipProject: index_1.DEFAULTS.skipProject
|
42 | }
|
43 | });
|
44 | if (argv.help) {
|
45 | console.log("\nUsage: ts-node [options] [ -e script | script.ts ] [arguments]\n\nOptions:\n\n -e, --eval [code] Evaluate code\n -p, --print [code] Evaluate code and print result\n -r, --require [path] Require a node module before execution\n\n -h, --help Print CLI usage\n -v, --version Print module version information\n\n -T, --transpile-only Use TypeScript's faster `transpileModule`\n --cache-directory Configure the output file cache directory\n -I, --ignore [pattern] Override the path patterns to skip compilation\n -P, --project [path] Path to TypeScript JSON project file\n -C, --compiler [name] Specify a custom TypeScript compiler\n -D, --ignoreDiagnostics [code] Ignore TypeScript warnings by diagnostic code\n -O, --compilerOptions [opts] JSON object to merge with compiler options\n\n --no-cache Disable the local TypeScript Node cache\n --skip-project Skip reading `tsconfig.json`\n --skip-ignore Skip `--ignore` checks\n");
|
46 | process.exit(0);
|
47 | }
|
48 | var cwd = process.cwd();
|
49 | var code = argv.eval === undefined ? argv.print : argv.eval;
|
50 | var isEval = typeof argv.eval === 'string' || !!argv.print;
|
51 | var isPrinted = argv.print !== undefined;
|
52 |
|
53 | var service = index_1.register({
|
54 | typeCheck: argv.typeCheck,
|
55 | transpileOnly: argv.transpileOnly,
|
56 | cache: argv.cache,
|
57 | cacheDirectory: argv.cacheDirectory,
|
58 | ignore: argv.ignore,
|
59 | project: argv.project,
|
60 | skipIgnore: argv.skipIgnore,
|
61 | skipProject: argv.skipProject,
|
62 | compiler: argv.compiler,
|
63 | ignoreDiagnostics: argv.ignoreDiagnostics,
|
64 | compilerOptions: index_1.parse(argv.compilerOptions),
|
65 | readFile: isEval ? readFileEval : undefined,
|
66 | fileExists: isEval ? fileExistsEval : undefined
|
67 | });
|
68 |
|
69 | if (argv.version) {
|
70 | console.log("ts-node v" + index_1.VERSION);
|
71 | console.log("node " + process.version);
|
72 | console.log("typescript v" + service.ts.version);
|
73 | console.log("cache " + JSON.stringify(service.cachedir));
|
74 | process.exit(0);
|
75 | }
|
76 |
|
77 | Module._preloadModules(arrify(argv.require));
|
78 |
|
79 |
|
80 |
|
81 | var EVAL_FILENAME = "[eval].ts";
|
82 | var EVAL_PATH = path_1.join(cwd, EVAL_FILENAME);
|
83 | var EVAL_INSTANCE = { input: '', output: '', version: 0, lines: 0 };
|
84 |
|
85 | if (isEval) {
|
86 | evalAndExit(code, isPrinted);
|
87 | }
|
88 | else {
|
89 | if (argv._.length) {
|
90 | process.argv = ['node'].concat(path_1.resolve(cwd, argv._[0])).concat(argv._.slice(1));
|
91 | process.execArgv.unshift(__filename);
|
92 | Module.runMain();
|
93 | }
|
94 | else {
|
95 |
|
96 | if (process.stdin.isTTY) {
|
97 | startRepl();
|
98 | }
|
99 | else {
|
100 | var code_1 = '';
|
101 | process.stdin.on('data', function (chunk) { return code_1 += chunk; });
|
102 | process.stdin.on('end', function () { return evalAndExit(code_1, isPrinted); });
|
103 | }
|
104 | }
|
105 | }
|
106 |
|
107 |
|
108 |
|
109 | function evalAndExit(code, isPrinted) {
|
110 | var module = new Module(EVAL_FILENAME);
|
111 | module.filename = EVAL_FILENAME;
|
112 | module.paths = Module._nodeModulePaths(cwd);
|
113 | global.__filename = EVAL_FILENAME;
|
114 | global.__dirname = cwd;
|
115 | global.exports = module.exports;
|
116 | global.module = module;
|
117 | global.require = module.require.bind(module);
|
118 | var result;
|
119 | try {
|
120 | result = _eval(code, global);
|
121 | }
|
122 | catch (error) {
|
123 | if (error instanceof index_1.TSError) {
|
124 | console.error(index_1.printError(error));
|
125 | process.exit(1);
|
126 | }
|
127 | throw error;
|
128 | }
|
129 | if (isPrinted) {
|
130 | console.log(typeof result === 'string' ? result : util_1.inspect(result));
|
131 | }
|
132 | }
|
133 |
|
134 |
|
135 |
|
136 | function _eval(input, context) {
|
137 | var lines = EVAL_INSTANCE.lines;
|
138 | var isCompletion = !/\n$/.test(input);
|
139 | var undo = appendEval(input);
|
140 | var output;
|
141 | try {
|
142 | output = service.compile(EVAL_INSTANCE.input, EVAL_PATH, -lines);
|
143 | }
|
144 | catch (err) {
|
145 | undo();
|
146 | throw err;
|
147 | }
|
148 |
|
149 | var changes = diff_1.diffLines(EVAL_INSTANCE.output, output);
|
150 | if (isCompletion) {
|
151 | undo();
|
152 | }
|
153 | else {
|
154 | EVAL_INSTANCE.output = output;
|
155 | }
|
156 | return changes.reduce(function (result, change) {
|
157 | return change.added ? exec(change.value, EVAL_FILENAME, context) : result;
|
158 | }, undefined);
|
159 | }
|
160 |
|
161 |
|
162 |
|
163 | function exec(code, filename, context) {
|
164 | var script = new vm_1.Script(code, { filename: filename });
|
165 | return script.runInNewContext(context);
|
166 | }
|
167 |
|
168 |
|
169 |
|
170 | function startRepl() {
|
171 | var repl = repl_1.start({
|
172 | prompt: '> ',
|
173 | input: process.stdin,
|
174 | output: process.stdout,
|
175 | eval: replEval,
|
176 | useGlobal: false
|
177 | });
|
178 |
|
179 | var resetEval = appendEval('');
|
180 | function reset() {
|
181 | resetEval();
|
182 |
|
183 | exec('exports = module.exports', EVAL_FILENAME, repl.context);
|
184 | }
|
185 | reset();
|
186 | repl.on('reset', reset);
|
187 | repl.defineCommand('type', {
|
188 | help: 'Check the type of a TypeScript identifier',
|
189 | action: function (identifier) {
|
190 | if (!identifier) {
|
191 | repl.displayPrompt();
|
192 | return;
|
193 | }
|
194 | var undo = appendEval(identifier);
|
195 | var _a = service.getTypeInfo(EVAL_INSTANCE.input, EVAL_PATH, EVAL_INSTANCE.input.length), name = _a.name, comment = _a.comment;
|
196 | undo();
|
197 | repl.outputStream.write(chalk_1.default.bold(name) + "\n" + (comment ? comment + "\n" : ''));
|
198 | repl.displayPrompt();
|
199 | }
|
200 | });
|
201 | }
|
202 |
|
203 |
|
204 |
|
205 | function replEval(code, context, _filename, callback) {
|
206 | var err;
|
207 | var result;
|
208 |
|
209 | if (code === '.scope') {
|
210 | callback();
|
211 | return;
|
212 | }
|
213 | try {
|
214 | result = _eval(code, context);
|
215 | }
|
216 | catch (error) {
|
217 | if (error instanceof index_1.TSError) {
|
218 |
|
219 | if (repl_1.Recoverable && isRecoverable(error)) {
|
220 | err = new repl_1.Recoverable(error);
|
221 | }
|
222 | else {
|
223 | err = index_1.printError(error);
|
224 | }
|
225 | }
|
226 | else {
|
227 | err = error;
|
228 | }
|
229 | }
|
230 | callback(err, result);
|
231 | }
|
232 |
|
233 |
|
234 |
|
235 | function appendEval(input) {
|
236 | var undoInput = EVAL_INSTANCE.input;
|
237 | var undoVersion = EVAL_INSTANCE.version;
|
238 | var undoOutput = EVAL_INSTANCE.output;
|
239 | var undoLines = EVAL_INSTANCE.lines;
|
240 |
|
241 | if (undoInput.charAt(undoInput.length - 1) === '\n' && /^\s*[\[\(\`]/.test(input) && !/;\s*$/.test(undoInput)) {
|
242 | EVAL_INSTANCE.input = EVAL_INSTANCE.input.slice(0, -1) + ";\n";
|
243 | }
|
244 | EVAL_INSTANCE.input += input;
|
245 | EVAL_INSTANCE.lines += lineCount(input);
|
246 | EVAL_INSTANCE.version++;
|
247 | return function () {
|
248 | EVAL_INSTANCE.input = undoInput;
|
249 | EVAL_INSTANCE.output = undoOutput;
|
250 | EVAL_INSTANCE.version = undoVersion;
|
251 | EVAL_INSTANCE.lines = undoLines;
|
252 | };
|
253 | }
|
254 |
|
255 |
|
256 |
|
257 | function lineCount(value) {
|
258 | var count = 0;
|
259 | for (var _i = 0, value_1 = value; _i < value_1.length; _i++) {
|
260 | var char = value_1[_i];
|
261 | if (char === '\n') {
|
262 | count++;
|
263 | }
|
264 | }
|
265 | return count;
|
266 | }
|
267 |
|
268 |
|
269 |
|
270 | function readFileEval(path) {
|
271 | if (path === EVAL_PATH)
|
272 | return EVAL_INSTANCE.input;
|
273 | try {
|
274 | return fs_1.readFileSync(path, 'utf8');
|
275 | }
|
276 | catch (err) { }
|
277 | }
|
278 |
|
279 |
|
280 |
|
281 | function fileExistsEval(path) {
|
282 | if (path === EVAL_PATH)
|
283 | return true;
|
284 | try {
|
285 | var stats = fs_1.statSync(path);
|
286 | return stats.isFile() || stats.isFIFO();
|
287 | }
|
288 | catch (err) {
|
289 | return false;
|
290 | }
|
291 | }
|
292 | var RECOVERY_CODES = [
|
293 | 1003,
|
294 | 1005,
|
295 | 1109,
|
296 | 1126,
|
297 | 1160,
|
298 | 1161
|
299 | ];
|
300 |
|
301 |
|
302 |
|
303 | function isRecoverable(error) {
|
304 | return error.diagnostics.every(function (x) { return RECOVERY_CODES.indexOf(x.code) > -1; });
|
305 | }
|
306 |
|
\ | No newline at end of file |