@@ -38,10 +38,12 @@ Mounting a VFS only redirects supported [`node:fs`][] calls whose resolved paths
3838are under the mount point. It does not prevent code from using other paths or
3939other Node.js APIs to access resources available to the process.
4040[ ` RealFSProvider ` ] [ ] maps VFS paths under its configured root and rejects paths
41- that resolve outside that root, but that check is not a security boundary. Do
42- not rely on VFS to run untrusted code; use operating-system-level isolation,
43- such as separate users, containers, or platform sandboxes, when a security
44- boundary is required.
41+ that resolve outside that root, but that check is not a security boundary.
42+ [ ` ZipProvider ` ] [ ] has no real file-system paths of its own to escape; its
43+ entries only ever exist within the archive's own namespace. Do not rely on VFS
44+ to run untrusted code; use operating-system-level isolation, such as separate
45+ users, containers, or platform sandboxes, when a security boundary is
46+ required.
4547
4648## Basic usage
4749
@@ -523,6 +525,55 @@ added: v26.4.0
523525
524526The resolved absolute path used as the root.
525527
528+ ## Class: ` ZipProvider `
529+
530+ <!-- YAML
531+ added: REPLACEME
532+ -->
533+
534+ A provider that exposes the entries of a ZIP archive - either a
535+ [ ` zlib.ZipBuffer ` ] [ ] (in memory) or a [ ` zlib.ZipFile ` ] [ ] (on disk) - through
536+ the VFS API. ` provider.readonly ` reflects the archive's own
537+ [ ` zipFile.writable ` ] [ ] flag: a ` ZipBuffer ` is always writable, and a
538+ ` ZipFile ` is writable only when opened with ` { writable: true } ` .
539+
540+ Directories are recognized both explicitly (an entry whose name ends in ` / ` )
541+ and implicitly (any entry name starting with ` "<dir>/" ` ). ` readdir() ` does
542+ not support ` { recursive: true } ` . Because a ZIP member cannot be edited or
543+ read in place - only fully written or fully decompressed - a file opened for
544+ writing only commits its content (as a new archive entry) when the handle is
545+ closed.
546+
547+ Every method has a synchronous counterpart (` openSync() ` , ` statSync() ` ,
548+ ` readdirSync() ` , and so on), backed by the equally complete synchronous
549+ surface [ ` zlib.ZipBuffer ` ] [ ] /[ ` zlib.ZipFile ` ] [ ] expose. As with those, the
550+ synchronous methods here block the Node.js event loop and further JavaScript
551+ execution until the operation - including any deflate/inflate pass -
552+ completes.
553+
554+ ``` cjs
555+ const vfs = require (' node:vfs' );
556+ const zlib = require (' node:zlib' );
557+ const { readFileSync } = require (' node:fs' );
558+
559+ async function main () {
560+ const zip = new zlib.ZipBuffer (readFileSync (' archive.zip' ));
561+ const archiveVfs = vfs .create (new vfs.ZipProvider (zip));
562+
563+ console .log (await archiveVfs .promises .readdir (' /' ));
564+ await archiveVfs .promises .writeFile (' /new.txt' , ' hello' );
565+ }
566+ main ();
567+ ```
568+
569+ ### ` new ZipProvider(source) `
570+
571+ <!-- YAML
572+ added: REPLACEME
573+ -->
574+
575+ * ` source ` {zlib.ZipBuffer|zlib.ZipFile} An already-open archive.
576+
526577## Implementation details
527578
528579### ` Stats ` objects
@@ -544,6 +595,7 @@ fields use synthetic but stable values:
544595[ `RealFSProvider` ] : #class-realfsprovider
545596[ `VirtualFileSystem` ] : #class-virtualfilesystem
546597[ `VirtualProvider` ] : #class-virtualprovider
598+ [ `ZipProvider` ] : #class-zipprovider
547599[ `fs.BigIntStats` ] : fs.md#class-fsstats
548600[ `fs.Stats` ] : fs.md#class-fsstats
549601[ `import.meta.resolve()` ] : esm.md#importmetaresolvespecifier
@@ -555,5 +607,8 @@ fields use synthetic but stable values:
555607[ `vfs.mountPointURL` ] : #vfsmountpointurl
556608[ `vfs.mountPoint` ] : #vfsmountpoint
557609[ `vfs.unmount()` ] : #vfsunmount
610+ [ `zipFile.writable` ] : zlib.md#zipfilewritable
611+ [ `zlib.ZipBuffer` ] : zlib.md#class-zlibzipbuffer
612+ [ `zlib.ZipFile` ] : zlib.md#class-zlibzipfile
558613[ loading from `node_modules` folders ] : modules.md#loading-from-node_modules-folders
559614[ the global folders ] : modules.md#loading-from-the-global-folders
0 commit comments