Skip to content
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
46 changes: 46 additions & 0 deletions doc/api/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -3674,6 +3674,50 @@ All attempts at serializing an uncaught exception from a worker thread failed.

The requested functionality is not supported in worker threads.

<a id="ERR_ZIP_ENTRY_CORRUPT"></a>

### `ERR_ZIP_ENTRY_CORRUPT`

A ZIP archive entry failed CRC-32 verification, or produced more or fewer
bytes than its declared uncompressed size, while being read.

<a id="ERR_ZIP_ENTRY_NOT_FOUND"></a>

### `ERR_ZIP_ENTRY_NOT_FOUND`

A named entry was requested from a [`ZipFile`][] or [`ZipBuffer`][] that does
not contain an entry with that name.

<a id="ERR_ZIP_ENTRY_TOO_LARGE"></a>

### `ERR_ZIP_ENTRY_TOO_LARGE`

A ZIP archive entry's declared size exceeds the configured limit, or a
provided entry name or comment exceeds the 65,535-byte encoded length that
the ZIP format allows.

<a id="ERR_ZIP_INVALID_ARCHIVE"></a>

### `ERR_ZIP_INVALID_ARCHIVE`

Data that was expected to be a ZIP archive, or a structure within one, is
missing, out of bounds, or otherwise inconsistent with the ZIP format.

<a id="ERR_ZIP_NOT_WRITABLE"></a>

### `ERR_ZIP_NOT_WRITABLE`

A mutating method (such as `zipFile.addEntry()` or `zipFile.delete()`) was
called on a [`ZipFile`][] that was not opened with `{ writable: true }`.

<a id="ERR_ZIP_UNSUPPORTED_FEATURE"></a>

### `ERR_ZIP_UNSUPPORTED_FEATURE`

A ZIP archive uses a feature outside of what this implementation supports,
such as entry encryption, an unsupported compression method, or a multi-disk
archive.

<a id="ERR_ZLIB_INITIALIZATION_FAILED"></a>

### `ERR_ZLIB_INITIALIZATION_FAILED`
Expand Down Expand Up @@ -4617,6 +4661,8 @@ An error occurred trying to allocate memory. This should never happen.
[`ServerResponse`]: http.md#class-httpserverresponse
[`Temporal`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal
[`Writable`]: stream.md#class-streamwritable
[`ZipBuffer`]: zlib.md#class-zlibzipbuffer
[`ZipFile`]: zlib.md#class-zlibzipfile
[`child_process`]: child_process.md
[`cipher.getAuthTag()`]: crypto.md#ciphergetauthtag
[`crypto.getDiffieHellman()`]: crypto.md#cryptogetdiffiehellmangroupname
Expand Down
66 changes: 59 additions & 7 deletions doc/api/vfs.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ Mounting a VFS only redirects supported [`node:fs`][] calls whose resolved paths
are under the mount point. It does not prevent code from using other paths or
other Node.js APIs to access resources available to the process.
[`RealFSProvider`][] maps VFS paths under its configured root and rejects paths
that resolve outside that root, but that check is not a security boundary. Do
not rely on VFS to run untrusted code; use operating-system-level isolation,
such as separate users, containers, or platform sandboxes, when a security
boundary is required.
that resolve outside that root, but that check is not a security boundary.
[`ZipProvider`][] has no real file-system paths of its own to escape; its
entries only ever exist within the archive's own namespace. Do not rely on VFS
to run untrusted code; use operating-system-level isolation, such as separate
users, containers, or platform sandboxes, when a security boundary is
required.

## Basic usage

Expand Down Expand Up @@ -201,9 +203,6 @@ The promise namespace mirrors `fs.promises` and includes `readFile`,
added: v26.4.0
-->

The base class for all VFS providers. Subclasses implement the essential
primitives (`open`, `stat`, `readdir`, `mkdir`, `rmdir`, `unlink`,
`rename`, ...) and inherit default implementations of the derived
The base class for all VFS providers. Subclasses implement the essential
primitives (such as `open`, `stat`, `readdir`, `mkdir`, `rmdir`, `unlink`,
`rename`, etc.) and inherit default implementations of the derived
Expand Down Expand Up @@ -304,6 +303,55 @@ added: v26.4.0

The resolved absolute path used as the root.

## Class: `ZipProvider`

<!-- YAML
added: REPLACEME
-->

A provider that exposes the entries of a ZIP archive - either a
[`zlib.ZipBuffer`][] (in memory) or a [`zlib.ZipFile`][] (on disk) - through
the VFS API. `provider.readonly` reflects the archive's own
[`zipFile.writable`][] flag: a `ZipBuffer` is always writable, and a
`ZipFile` is writable only when opened with `{ writable: true }`.

Directories are recognized both explicitly (an entry whose name ends in `/`)
and implicitly (any entry name starting with `"<dir>/"`). `readdir()` does
not support `{ recursive: true }`. Because a ZIP member cannot be edited or
read in place - only fully written or fully decompressed - a file opened for
writing only commits its content (as a new archive entry) when the handle is
closed.

Every method has a synchronous counterpart (`openSync()`, `statSync()`,
`readdirSync()`, and so on), backed by the equally complete synchronous
surface [`zlib.ZipBuffer`][]/[`zlib.ZipFile`][] expose. As with those, the
synchronous methods here block the Node.js event loop and further JavaScript
execution until the operation - including any deflate/inflate pass -
completes.

```cjs
const vfs = require('node:vfs');
const zlib = require('node:zlib');
const { readFileSync } = require('node:fs');

async function main() {
const zip = new zlib.ZipBuffer(readFileSync('archive.zip'));
const archiveVfs = vfs.create(new vfs.ZipProvider(zip));

console.log(await archiveVfs.promises.readdir('/'));
await archiveVfs.promises.writeFile('/new.txt', 'hello');
}
main();
```

### `new ZipProvider(source)`

<!-- YAML
added: REPLACEME
-->

* `source` {zlib.ZipBuffer|zlib.ZipFile} An already-open archive.

## Implementation details

### `Stats` objects
Expand All @@ -322,6 +370,10 @@ fields use synthetic but stable values:
[`RealFSProvider`]: #class-realfsprovider
[`VirtualFileSystem`]: #class-virtualfilesystem
[`VirtualProvider`]: #class-virtualprovider
[`ZipProvider`]: #class-zipprovider
[`fs.BigIntStats`]: fs.md#class-fsbigintstats
[`fs.Stats`]: fs.md#class-fsstats
[`node:fs`]: fs.md
[`zipFile.writable`]: zlib.md#zipfilewritable
[`zlib.ZipBuffer`]: zlib.md#class-zlibzipbuffer
[`zlib.ZipFile`]: zlib.md#class-zlibzipfile
Loading
Loading