Skip to content

--allow-import behavior is unconsistant between main/worker threads #31992

@lowlighter

Description

@lowlighter

Version: Deno 2.6.7

The behaviour of --allow-import is different depending whether you're in the main thread or a worker one, and if the import is statically analyzable or not you end up in weird cases

1. Running --allow-import=deny.invalid with static import from main thread

Result: Importing from external source is denied
This is consistant when using import() too

// a.ts
import { cyan } from "jsr:@std/fmt/colors"
console.log(cyan("hello a.ts"))
PS test> deno run -R --allow-import=deno.invalid --no-prompt a.ts
error: JSR package manifest for '@std/fmt' failed to load. Requires import access to "jsr.io:443", run again with the --allow-import flag

2. Running default --allow-import from main thread with { permissions: "none" } in worker and static import

Result: The main thread succeed, but the worker also does
=> This is inconsistant with the behavior established in 1°, see related issue

// a.ts
import { cyan } from "jsr:@std/fmt/colors"
console.log(cyan("hello a.ts"))
new Worker(import.meta.resolve("./b.ts"), { type: "module", deno: { permissions: "none" }})
// b.ts
import { cyan } from "jsr:@std/fmt/colors"
console.log(cyan("hello b.ts"))
self.close()
PS test> deno run -R --no-prompt --unstable-worker-options a.ts                            
hello a.ts
hello b.ts

3. Running default --allow-import from main thread with { permissions: "none" } in worker and dynamic import

Result : It works if the dynamic import is statically unanalyzable, but fails if not, which makes it in a weird in-between from 1° and 2°

// b.ts
const { cyan } = await import("" + "jsr:@std/fmt/colors")
console.log(cyan("hello b.ts"))
self.close()
PS test> deno run -R --no-prompt --unstable-worker-options a.ts
hello a.ts
error: Uncaught (in worker "") (in promise) TypeError: JSR package manifest for '@std/fmt' failed to load. Requires import access to "jsr.io:443", run again with the --allow-import flag
const { cyan } = await import("" + "jsr:@std/fmt/colors")

4. Same as 3, but forcing the dynamic import to be statically analyzable first

Result: the dynamic import works because it seems to have been validated through the statically analyzable one
Reference:

// b.ts
(async () => await import("jsr:@std/fmt/colors"));
const { cyan } = await import("" + "jsr:@std/fmt/colors")
console.log(cyan("hello b.ts"))
self.close()
PS test> deno run -R --no-prompt --unstable-worker-options a.ts
hello a.ts
hello b.ts

This actually solves my issue there, but I feel like it's not supposed to be this way...

Summary

Context Static import Dynamic import Dynamic import (non statically analyzable)
Main --allow-import
Main --deny-import
Worker --allow-import
Worker --deny-import ✔(?) ✔(?)

Even if it's inconsistant, I don't mind if it's the actual intended behavior because it actually suits me (but maybe it should be documented somewhere).

If the intended behavior is supposed to deny everything like in main thread, I assume #29503 (comment) would help with resolution, but then I'd like the current behavior to be retrofited with an option like suggested in :

If this current behavior is the one expected, then I guess this just need to be documented somewhere and all the related issues can be closed, because even if it's weird it actually perfectly fits my use-case 😅

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions