@electron/asar

repository·main·Indexed 25 days ago

https://github.com/electron/asar

A simple, extensive archive format used by Electron that concatenates files without compression while providing random access support via a JSON header. It includes a CLI for packing, listing, and extracting archives, as well as a programmatic API for creating packages from directories, files, or streams, and managing archive entries through the Filesystem class.

Tokens
3.2K
Snippets
6
Records
32
Agent score
84%

What's inside @electron/asar

  1. Create an asar archive programmatically with createPackage

    main

    Use createPackage to create an asar archive from a source directory.

    Note: There is currently no error handling provided for this function.

    import { createPackage } from '@electron/asar';
    
    const src = 'some/path/';
    const dest = 'name.asar';
    
    await createPackage(src, dest);
    console.log('done.');
  2. Transform files during packing with createPackageWithOptions

    main

    Use createPackageWithOptions to apply a transformation to files as they are being packed into the .asar archive. The transform option accepts a function that returns either undefined or a stream.Transform instance. The transform stream will be applied to the files being written to the archive (useful for tasks like compression).

    import { createPackageWithOptions } from '@electron/asar';
    
    const src = 'some/path/';
    const dest = 'name.asar';
    
    function transform (filename) {
      return new CustomTransformStream()
    }
    
    await createPackageWithOptions(src, dest, { transform: transform });
    console.log('done.');
  3. Understand the ASAR file format

    main

    The ASAR format is a flat structure that concatenates files without compression, supporting random access. It uses [Pickle][pickle] to serialize a header.

    Structure: | UInt32: header_size | String: header | Bytes: file1 | ... | Bytes: file42 |

    Header Details:

    • The header is a JSON string containing a files object.
    • The files object is a nested tree representing the directory structure.
    • Each file entry contains:
      • offset: A UINT64 (represented as a string) indicating the start of the file relative to the end of the header. To get the absolute offset, add the size of header_size and header to this value.
      • size: A JavaScript Number representing the file size.
      • executable: Boolean.
      • integrity: An object containing:
        • algorithm: Currently only SHA256 is supported.
        • hash: Hex encoded hash of the entire file.
        • blockSize: Integer size of each block in bytes.
        • blocks: An array of hex encoded hashes for each block.
  4. Exclude resources from being packed via CLI

    main

    When using the pack command, you can use the --unpack-dir option to exclude specific files or patterns from being packed into the archive (they will remain uncompressed/unpacked).

    Examples:

    • Exclude specific files: asar pack app app.asar --unpack-dir "{x1,x2}"
    • Exclude using glob patterns: asar pack app app.asar --unpack-dir "**/{x1,x2}"
    • Exclude complex patterns: asar pack app app.asar --unpack-dir "{**/x1,**/x2,z4/w1}"
    asar pack app app.asar --unpack-dir "{x1,x2}"
  5. Use the asar CLI

    main

    The asar CLI allows you to pack directories into archives, list files, and extract files or entire archives.

    Commands:

    • pack|p <dir> <output>: Create an asar archive from a directory.
    • list|l <archive>: List files within an asar archive.
    • extract-file|ef <archive> <filename>: Extract a single file from an archive.
    • extract|e <archive> <dest>: Extract the entire archive to a destination.

    Options:

    • -h, --help: Output usage information.
    • -V, --version: Output the version number.
    $ asar --help
    
      Usage: asar [options] [command]
    
      Commands:
    
        pack|p <dir> <output>
           create asar archive
    
        list|l <archive>
           list files of asar archive
    
        extract-file|ef <archive> <filename>
           extract one file from archive
    
        extract|e <archive> <dest>
           extract archive
    
    
      Options:
    
        -h, --help     output usage information
        -V, --version  output the version number
  6. Calculate file integrity from a stream with getFileIntegrity

    main

    Use getFileIntegrity to calculate the SHA256 hash and block-level hashes for a file provided as a NodeJS.ReadableStream. This is useful for verifying the integrity of files within an ASAR archive.

    Returns a FileIntegrity object containing:

    • algorithm: Always 'SHA256'.
    • hash: The full file SHA256 hash in hex.
    • blockSize: The size of each block used (default is 4MB).
    • blocks: An array of hex-encoded SHA256 hashes for each block.
  7. Insert a file into the asar archive

    main

    Use insertFile to add a file to the archive. This method requires a streamGenerator function that returns a NodeJS.ReadableStream of the file content.

    Key constraints and behaviors:

    • File Size Limit: Files cannot be larger than 4.2GB (UINT32_MAX).
    • Unpacked Files: If shouldUnpack is true or the parent directory is marked as unpacked, the file is treated as an unpacked entry.
    • Transformations: You can provide an optional transform function in the options object. If provided, the file is piped through the transform stream and the resulting bytes are what get stored and hashed in the archive.
    • Integrity: The method automatically computes the file's integrity hash.
  8. Insert a symbolic link into the asar archive

    main
    Use insertLink to add a symlink. The method ensures that the link target does not point outside of the package. If the target is absolute or uses .. to escape the package root, an error is thrown.
  9. Use the Filesystem class to manage asar archive entries

    main
    The Filesystem class is the core interface for managing the internal structure of an asar archive. It allows you to manipulate the archive header, insert files, directories, and symlinks, and traverse the archive's contents. You initialize it with the path to the archive source.