Skip to content

feat(js): expose real filesystem mounts with per-mount readOnly support #1128

@chaliy

Description

@chaliy

Summary

The Python bindings expose mount_real_readonly_at, mount_real_readwrite_at, and dynamic mount/unmount methods. The JS bindings have none of these — the only way to populate the VFS is via the files option in BashOptions.

Note: readOnly is accepted in BashOptions since 0.1.14 but is not enforced — all writes (redirections, rm, mkdir) still succeed.

Use case

We're building an SSH server (supabase.sh) that mounts a real docs directory as read-only into the VFS. Users connect via SSH and run grep/find/cat against the docs.

With the Python bindings:

bash = Bash()
bash.mount_real_readonly_at("/supabase/docs", docs_dir)

With the JS bindings, we have to walk the directory ourselves and pass lazy loaders, plus install bash function overrides to block writes:

function walkDir(root: string, vRoot: string): Record<string, () => string> {
  // ... recursively walk with readdirSync, map to () => readFileSync(...)
}

const bash = new Bash({ files: { ...walkDir(docsDir, "/supabase/docs") } })

// Then override rm, mv, cp, mkdir, etc. as EROFS functions
// But redirections (>, >>) and `command rm` still bypass this

Requested API

Parity with Python bindings:

// Constructor-time mounts
const bash = new Bash({
  mounts: [
    { path: "/supabase/docs", root: "/real/path/to/docs", readOnly: true },
  ],
})

// Or method-based (like Python)
bash.mountRealReadonlyAt("/supabase/docs", docsDir)
bash.unmount("/supabase/docs")

Why this matters

Without native VFS-level read-only enforcement, bash function overrides are the only option. These are bypassable via command rm and don't cover redirections (echo x > /file). The Python bindings solve this at the Rust VFS level — JS should too.

The Rust crate already has OverlayFs with readOnly support, and v0.1.13 added mount/unmount (#784). The Python bindings expose this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions