Skip to content

v2.10.0

Latest

Choose a tag to compare

@gildas-lormeau gildas-lormeau released this 04 Sep 01:09
· 1 commit to master since this release

What's Changed in v2.10.0

New features

  • New duplicates option on the import*() methods of the filesystem API, set to "throw", "keep-first" or "keep-last". A zip file stores a flat list of filenames while the filesystem API indexes the entries by path, so two entries can claim the same node of the tree: they can hold the same filename, hold filenames differing only by the path components ignored when building the tree such as "a/b.txt" and "./a/b.txt", or one can be a file and the other a directory holding it such as "a" and "a/b.txt". The three cases are now governed by one option instead of aborting the import in every case. The default stays "throw", an archive holding the same name twice being also the shape making an extractor and a scanner disagree on the file they see. "keep-last" is the behavior of most zip tools, verified against Info-ZIP, 7-Zip, libarchive, ditto, Python zipfile, fflate and JSZip
  • The name passed to an add*() method of the filesystem API is now split into path components, like the filename of an imported entry already was. addText("a/b.txt", text) adds "b.txt" to the "a" directory and creates that directory when it does not exist, instead of adding one entry whose name holds a "/". The directories created that way are implicit, they are not written when the tree is exported, so the exported zip file is unchanged. rename() splits the name the same way and moves the entry accordingly
  • New ERR_DUPLICATE_IMPORTED_ENTRY and ERR_INVALID_DUPLICATES errors, and new ZipDirectoryEntryImportOptions type. ERR_DUPLICATE_IMPORTED_ENTRY replaces ERR_ENTRY_EXISTS when an import is refused, the former reading as an error made by the caller while the caller only passed a zip file

Bug fixes

  • A failed import no longer modifies the filesystem. The entries created before the error are removed, and the content the ZipFS instance held before the import is restored instead of being discarded before the first entry is read
  • The replace*() methods of the filesystem API now update the size of the entry, which kept describing the content held before the call. The archive was written correctly, only getExportedSize() was affected: replacing 1 byte of text with 5000 bytes predicted 127 bytes for an export of 5126. replaceReadable() reports an undetermined size, like addReadable() does, instead of returning a prediction it cannot make. The five methods also clear the pass-through state of an entry imported with the passThrough option, the bytes copied verbatim being gone
  • ZipFS#find() no longer throws a TypeError when a component of the path it is given is a file entry rather than a directory
  • Renaming an entry to the name it already has is no longer refused as a collision with itself

Documentation

  • New Hello world with the filesystem API example in the README. The filesystem API needs a single import, infers the Reader and the Writer from the type of the data, and reaches an entry from its name, which is what the five other examples never showed
  • The encoding limitations of the filename options are now documented
  • The conditions making getExportedSize() unable to predict a size mention that a name holding "/" builds a nested tree

Tests and continuous integration

  • New tests covering the duplicate filename policies, the rollback of a failed import, the path components built from a name, and the size of an entry whose content is replaced
  • The size prediction tests cover the names holding "/", the two duplicate policies and the entries whose imported content is replaced
  • The CP437 table is now checked by a test instead of at runtime, and the characters it decodes are written as characters in that test