lib: add typescript support to STDIN eval

PR-URL: https://github.com/nodejs/node/pull/56359
Reviewed-By: Jordan Harband <ljharb@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Pietro Marchini <pietro.marchini94@gmail.com>
pull/56404/head
Marco Ippolito 2024-12-29 23:42:51 +01:00 committed by GitHub
parent 0dbbabab95
commit ecc9fb2f8e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 267 additions and 10 deletions

View File

@ -156,10 +156,10 @@ import { fn, FnParams } from './fn.ts';
### Non-file forms of input
Type stripping can be enabled for `--eval`. The module system
Type stripping can be enabled for `--eval` and STDIN. The module system
will be determined by `--input-type`, as it is for JavaScript.
TypeScript syntax is unsupported in the REPL, STDIN input, `--print`, `--check`, and
TypeScript syntax is unsupported in the REPL, `--check`, and
`inspect`.
### Source maps

View File

@ -11,6 +11,9 @@ const { getOptionValue } = require('internal/options');
const {
evalModuleEntryPoint,
evalTypeScript,
parseAndEvalCommonjsTypeScript,
parseAndEvalModuleTypeScript,
evalScript,
readStdin,
} = require('internal/process/execution');
@ -25,13 +28,30 @@ readStdin((code) => {
const print = getOptionValue('--print');
const shouldLoadESM = getOptionValue('--import').length > 0;
if (getOptionValue('--input-type') === 'module') {
const inputType = getOptionValue('--input-type');
const tsEnabled = getOptionValue('--experimental-strip-types');
if (inputType === 'module') {
evalModuleEntryPoint(code, print);
} else if (inputType === 'module-typescript' && tsEnabled) {
parseAndEvalModuleTypeScript(code, print);
} else {
evalScript('[stdin]',
code,
getOptionValue('--inspect-brk'),
print,
shouldLoadESM);
let evalFunction;
if (inputType === 'commonjs') {
evalFunction = evalScript;
} else if (inputType === 'commonjs-typescript' && tsEnabled) {
evalFunction = parseAndEvalCommonjsTypeScript;
} else if (tsEnabled) {
evalFunction = evalTypeScript;
} else {
// Default to commonjs.
evalFunction = evalScript;
}
evalFunction('[stdin]',
code,
getOptionValue('--inspect-brk'),
print,
shouldLoadESM);
}
});

View File

@ -2,6 +2,15 @@
[stdin]:1
with(this){__filename}
^^^^
x The 'with' statement is not supported. All symbols in a 'with' block will have type 'any'.
,----
1 | with(this){__filename}
: ^^^^
`----
Caused by:
failed to parse
SyntaxError: Strict mode code may not include a with statement
@ -13,8 +22,6 @@ SyntaxError: Strict mode code may not include a with statement
Node.js *
42
42

View File

@ -0,0 +1,38 @@
'use strict';
require('../../common');
const spawn = require('child_process').spawn;
function run(cmd, strict, cb) {
const args = ['--disable-warning=ExperimentalWarning'];
if (strict) args.push('--use_strict');
args.push('-p');
const child = spawn(process.execPath, args);
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stdout);
child.stdin.end(cmd);
child.on('close', cb);
}
const queue =
[
'enum Foo{};',
'throw new SyntaxError("hello")',
'const foo;',
'let x: number = 100;x;',
'const foo: string = 10;',
'function foo(){};foo<Number>(1);',
'interface Foo{};const foo;',
'function foo(){ await Promise.resolve(1)};',
];
function go() {
const c = queue.shift();
if (!c) return console.log('done');
run(c, false, function () {
run(c, true, go);
});
}
go();

View File

@ -0,0 +1,191 @@
[stdin]:1
enum Foo{};
^^^^
x TypeScript enum is not supported in strip-only mode
,----
1 | enum Foo{};
: ^^^^^^^^^^
`----
SyntaxError: Unexpected reserved word
Node.js *
[stdin]:1
enum Foo{};
^^^^
x TypeScript enum is not supported in strip-only mode
,----
1 | enum Foo{};
: ^^^^^^^^^^
`----
SyntaxError: Unexpected reserved word
Node.js *
[stdin]:1
throw new SyntaxError("hello")
^
SyntaxError: hello
Node.js *
[stdin]:1
throw new SyntaxError("hello")
^
SyntaxError: hello
Node.js *
[stdin]:1
const foo;
^^^
SyntaxError: Missing initializer in const declaration
Node.js *
[stdin]:1
const foo;
^^^
SyntaxError: Missing initializer in const declaration
Node.js *
100
100
undefined
undefined
false
false
[stdin]:1
;const foo;
^^^
SyntaxError: Missing initializer in const declaration
Node.js *
[stdin]:1
;const foo;
^^^
SyntaxError: Missing initializer in const declaration
Node.js *
[stdin]:1
function foo(){ await Promise.resolve(1)};
^^^^^
x await isn't allowed in non-async function
,----
1 | function foo(){ await Promise.resolve(1)};
: ^^^^^^^
`----
Caused by:
failed to parse
SyntaxError: await is only valid in async functions and the top level bodies of modules
Node.js *
[stdin]:1
function foo(){ await Promise.resolve(1)};
^^^^^
x await isn't allowed in non-async function
,----
1 | function foo(){ await Promise.resolve(1)};
: ^^^^^^^
`----
Caused by:
failed to parse
SyntaxError: await is only valid in async functions and the top level bodies of modules
Node.js *
done

View File

@ -24,6 +24,7 @@ describe('eval output', { concurrency: true }, () => {
const tests = [
{ name: 'eval/eval_messages.js' },
{ name: 'eval/stdin_messages.js' },
{ name: 'eval/stdin_typescript.js' },
];
for (const { name } of tests) {