async function unzip(zippedFile, cacheDir) {
  const zip = await yauzl.open(zippedFile);
  let entry = await zip.readEntry();
  const symlinks = []; // Array to hold symbolic link entries

  while (entry !== null) {
    let entryPathAbs = path.join(cacheDir, entry.filename);
    // Check if entry is a symbolic link
    const isSymlink = ((modeFromEntry(entry) & 0o170000) === 0o120000);

    if (isSymlink) {
      // Store symlink entries to process later
      symlinks.push(entry);
    } else {
      // Handle regular files and directories
      await fs.promises.mkdir(path.dirname(entryPathAbs), {recursive: true});
      if (!entry.filename.endsWith('/')) { // Skip directories
        const readStream = await entry.openReadStream();
        const writeStream = fs.createWriteStream(entryPathAbs);
        await stream.promises.pipeline(readStream, writeStream);

        // Set file permissions after the file has been written
        const mode = modeFromEntry(entry);
        await fs.promises.chmod(entryPathAbs, mode);
      }
    }

    // Read next entry
    entry = await zip.readEntry();
  }

  // Process symbolic links after all other files have been extracted
  for (const symlinkEntry of symlinks) {
    let entryPathAbs = path.join(cacheDir, symlinkEntry.filename);
    const readStream = await symlinkEntry.openReadStream();
    const chunks = [];
    readStream.on('data', (chunk) => chunks.push(chunk));
    await new Promise(resolve => readStream.on('end', resolve));
    const linkTarget = Buffer.concat(chunks).toString('utf8').trim();

    // Check if the symlink or a file/directory already exists at the destination
    if (fs.existsSync(entryPathAbs)) {
      //skip
    } else {
      // Create symbolic link
      await fs.promises.symlink(linkTarget, entryPathAbs);
    }
  }
  await zip.close();
}
Unzip `zippedFile` to `cacheDir`.
@async
@function
@param  {string}        zippedFile  - file path to .zip file
@param  {string}        cacheDir    - directory to unzip in
@returns {Promise<void>}