ニジカ投稿局 https://tv.nizika.tv
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

56 lines
1.5 KiB

  1. import { createWriteStream } from 'fs'
  2. import { ensureDir } from 'fs-extra/esm'
  3. import { dirname, join } from 'path'
  4. import { pipeline } from 'stream'
  5. import * as yauzl from 'yauzl'
  6. import { logger, loggerTagsFactory } from './logger.js'
  7. const lTags = loggerTagsFactory('unzip')
  8. export async function unzip (source: string, destination: string) {
  9. await ensureDir(destination)
  10. logger.info(`Unzip ${source} to ${destination}`, lTags())
  11. return new Promise<void>((res, rej) => {
  12. yauzl.open(source, { lazyEntries: true }, (err, zipFile) => {
  13. if (err) return rej(err)
  14. zipFile.readEntry()
  15. zipFile.on('entry', async entry => {
  16. const entryPath = join(destination, entry.fileName)
  17. try {
  18. if (/\/$/.test(entry.fileName)) {
  19. await ensureDir(entryPath)
  20. logger.debug(`Creating directory from zip ${entryPath}`, lTags())
  21. zipFile.readEntry()
  22. return
  23. }
  24. await ensureDir(dirname(entryPath))
  25. } catch (err) {
  26. return rej(err)
  27. }
  28. zipFile.openReadStream(entry, (readErr, readStream) => {
  29. if (readErr) return rej(readErr)
  30. logger.debug(`Creating file from zip ${entryPath}`, lTags())
  31. const writeStream = createWriteStream(entryPath)
  32. writeStream.on('close', () => zipFile.readEntry())
  33. pipeline(readStream, writeStream, pipelineErr => {
  34. if (pipelineErr) return rej(pipelineErr)
  35. })
  36. })
  37. })
  38. zipFile.on('end', () => res())
  39. })
  40. })
  41. }