Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib: add typescript support to STDIN eval #56359

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions doc/api/typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,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
Expand Down
32 changes: 26 additions & 6 deletions lib/internal/main/eval_stdin.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const { getOptionValue } = require('internal/options');

const {
evalModuleEntryPoint,
evalTypeScript,
parseAndEvalCommonjsTypeScript,
parseAndEvalModuleTypeScript,
evalScript,
readStdin,
} = require('internal/process/execution');
Expand All @@ -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);
}
});
38 changes: 38 additions & 0 deletions test/fixtures/eval/stdin_typescript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use strict';

require('../../common');

const spawn = require('child_process').spawn;

function run(cmd, strict, cb) {
const args = ['--experimental-strip-types', '--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();
191 changes: 191 additions & 0 deletions test/fixtures/eval/stdin_typescript.snapshot
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions test/parallel/test-node-output-eval.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Loading