Skip to content

Commit

Permalink
lib: add typescript support to STDIN eval
Browse files Browse the repository at this point in the history
  • Loading branch information
marco-ippolito committed Dec 25, 2024
1 parent 3147ec2 commit 6bf1669
Show file tree
Hide file tree
Showing 5 changed files with 258 additions and 8 deletions.
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

0 comments on commit 6bf1669

Please sign in to comment.