deno icon indicating copy to clipboard operation
deno copied to clipboard

Support `import.meta.url` / `import.meta.resolve` in the REPL

Open lucacasonato opened this issue 11 months ago • 3 comments

Right now these don't work because this is a script context. We should create a fake __importMeta at the start of the REPL, and transpile the import.meta calls to that. This would be in line with the transpilation that what we do for static import statements.

This is probably also helpful for Jupyter.

lucacasonato avatar Sep 19 '23 10:09 lucacasonato

This exists for deno run -:

➜ cat | deno run -
console.log(import.meta.url)
file:///Users/bat/projects/macchiato/2023/11/13/$deno$stdin.ts

benatkin avatar Nov 14 '23 06:11 benatkin

This brings up the static import problem – it isn't following Principle of Least Authority. #6294 Currently for some reason, maybe this reason, you get an error if you try to import a relative URL in deno repl (example at bottom)

I would rather deno repl not get the behavior, and if anyone was counting on it for untrusted code it would be an issue. Some apps have credentials in a JSON file in a predictable location. Docker is one – in "./.docker/config.json" if you expect the user to be in the home directory or "../.docker/config.json" if you expect the user to be in ~/Downloads. Add some specific permissions like access to a website and it could get tricky. These can be viewed with deno info.

$ cat test2.json
{"x": 2}
$ cat test.js
export const x = 9
$ deno repl
Deno 1.38.1
exit using ctrl+d, ctrl+c, or close()
> import foo from './test.js'
❌ Denied read access to "/test.js".
Uncaught TypeError: Requires read access to "/test.js", run again with the --allow-read flag
    at async <anonymous>:1:49
> import foo from './test2.json' assert { type: 'json' }
❌ Denied read access to "/test2.json".
Uncaught TypeError: Requires read access to "/test2.json", run again with the --allow-read flag
    at async <anonymous>:1:49
>
$ deno repl --no-prompt
Deno 1.38.1
exit using ctrl+d, ctrl+c, or close()
> import foo from './test.js'
Uncaught TypeError: Requires read access to "/test.js", run again with the --allow-read flag
    at async <anonymous>:1:49
> import foo from './test2.json' assert { type: 'json' }
Uncaught TypeError: Requires read access to "/test2.json", run again with the --allow-read flag
    at async <anonymous>:1:49
>
$ echo "import foo from './test.js'" | deno run -
$ echo "import foo from './test2.json' assert { type: 'json' }" | deno run -
$ echo "import foo from './test.js'; console.log(foo)" | deno run -
error: Uncaught SyntaxError: The requested module './test.js' does not provide an export named 'default'
import foo from './test.js'; console.log(foo)
       ^
    at <anonymous> (file:///$deno$stdin.ts:1:8)
$ echo "import foo from './test.js'; console.log(foo.x)" | deno run -
error: Uncaught SyntaxError: The requested module './test.js' does not provide an export named 'default'
import foo from './test.js'; console.log(foo.x)
       ^
    at <anonymous> (file:///$deno$stdin.ts:1:8)
$ echo "import {x} from './test.js'; console.log(x)" | deno run -
9
$ echo "import foo from './test2.json' assert { type: 'json' }; console.log(foo)" | deno run -
{ x: 2 }
$ echo "console.log(import.meta.url)" | deno run -
file:///$deno$stdin.ts
$

Of course, if stdin is made to behave like this, instead of the other way around, that makes it more PoLA for single file scripts, but that should be allowed for multifile scripts as well, and it seems the simplest way to do that would be to add another permission called --allow-import or something.

benatkin avatar Nov 16 '23 02:11 benatkin

Related to @benatkin's comment, would this resolve relative path imports, including with --eval-file? There are many times that I'm writing something and would like to try it out without setting up test files, but relative imports not working often makes it impossible to do so with the REPL.

sgwilym avatar Jan 21 '24 20:01 sgwilym