11cb0ef41Sopenharmony_ci'use strict'
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci// A readable tar stream creator
41cb0ef41Sopenharmony_ci// Technically, this is a transform stream that you write paths into,
51cb0ef41Sopenharmony_ci// and tar format comes out of.
61cb0ef41Sopenharmony_ci// The `add()` method is like `write()` but returns this,
71cb0ef41Sopenharmony_ci// and end() return `this` as well, so you can
81cb0ef41Sopenharmony_ci// do `new Pack(opt).add('files').add('dir').end().pipe(output)
91cb0ef41Sopenharmony_ci// You could also do something like:
101cb0ef41Sopenharmony_ci// streamOfPaths().pipe(new Pack()).pipe(new fs.WriteStream('out.tar'))
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ciclass PackJob {
131cb0ef41Sopenharmony_ci  constructor (path, absolute) {
141cb0ef41Sopenharmony_ci    this.path = path || './'
151cb0ef41Sopenharmony_ci    this.absolute = absolute
161cb0ef41Sopenharmony_ci    this.entry = null
171cb0ef41Sopenharmony_ci    this.stat = null
181cb0ef41Sopenharmony_ci    this.readdir = null
191cb0ef41Sopenharmony_ci    this.pending = false
201cb0ef41Sopenharmony_ci    this.ignore = false
211cb0ef41Sopenharmony_ci    this.piped = false
221cb0ef41Sopenharmony_ci  }
231cb0ef41Sopenharmony_ci}
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ciconst { Minipass } = require('minipass')
261cb0ef41Sopenharmony_ciconst zlib = require('minizlib')
271cb0ef41Sopenharmony_ciconst ReadEntry = require('./read-entry.js')
281cb0ef41Sopenharmony_ciconst WriteEntry = require('./write-entry.js')
291cb0ef41Sopenharmony_ciconst WriteEntrySync = WriteEntry.Sync
301cb0ef41Sopenharmony_ciconst WriteEntryTar = WriteEntry.Tar
311cb0ef41Sopenharmony_ciconst Yallist = require('yallist')
321cb0ef41Sopenharmony_ciconst EOF = Buffer.alloc(1024)
331cb0ef41Sopenharmony_ciconst ONSTAT = Symbol('onStat')
341cb0ef41Sopenharmony_ciconst ENDED = Symbol('ended')
351cb0ef41Sopenharmony_ciconst QUEUE = Symbol('queue')
361cb0ef41Sopenharmony_ciconst CURRENT = Symbol('current')
371cb0ef41Sopenharmony_ciconst PROCESS = Symbol('process')
381cb0ef41Sopenharmony_ciconst PROCESSING = Symbol('processing')
391cb0ef41Sopenharmony_ciconst PROCESSJOB = Symbol('processJob')
401cb0ef41Sopenharmony_ciconst JOBS = Symbol('jobs')
411cb0ef41Sopenharmony_ciconst JOBDONE = Symbol('jobDone')
421cb0ef41Sopenharmony_ciconst ADDFSENTRY = Symbol('addFSEntry')
431cb0ef41Sopenharmony_ciconst ADDTARENTRY = Symbol('addTarEntry')
441cb0ef41Sopenharmony_ciconst STAT = Symbol('stat')
451cb0ef41Sopenharmony_ciconst READDIR = Symbol('readdir')
461cb0ef41Sopenharmony_ciconst ONREADDIR = Symbol('onreaddir')
471cb0ef41Sopenharmony_ciconst PIPE = Symbol('pipe')
481cb0ef41Sopenharmony_ciconst ENTRY = Symbol('entry')
491cb0ef41Sopenharmony_ciconst ENTRYOPT = Symbol('entryOpt')
501cb0ef41Sopenharmony_ciconst WRITEENTRYCLASS = Symbol('writeEntryClass')
511cb0ef41Sopenharmony_ciconst WRITE = Symbol('write')
521cb0ef41Sopenharmony_ciconst ONDRAIN = Symbol('ondrain')
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ciconst fs = require('fs')
551cb0ef41Sopenharmony_ciconst path = require('path')
561cb0ef41Sopenharmony_ciconst warner = require('./warn-mixin.js')
571cb0ef41Sopenharmony_ciconst normPath = require('./normalize-windows-path.js')
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ciconst Pack = warner(class Pack extends Minipass {
601cb0ef41Sopenharmony_ci  constructor (opt) {
611cb0ef41Sopenharmony_ci    super(opt)
621cb0ef41Sopenharmony_ci    opt = opt || Object.create(null)
631cb0ef41Sopenharmony_ci    this.opt = opt
641cb0ef41Sopenharmony_ci    this.file = opt.file || ''
651cb0ef41Sopenharmony_ci    this.cwd = opt.cwd || process.cwd()
661cb0ef41Sopenharmony_ci    this.maxReadSize = opt.maxReadSize
671cb0ef41Sopenharmony_ci    this.preservePaths = !!opt.preservePaths
681cb0ef41Sopenharmony_ci    this.strict = !!opt.strict
691cb0ef41Sopenharmony_ci    this.noPax = !!opt.noPax
701cb0ef41Sopenharmony_ci    this.prefix = normPath(opt.prefix || '')
711cb0ef41Sopenharmony_ci    this.linkCache = opt.linkCache || new Map()
721cb0ef41Sopenharmony_ci    this.statCache = opt.statCache || new Map()
731cb0ef41Sopenharmony_ci    this.readdirCache = opt.readdirCache || new Map()
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci    this[WRITEENTRYCLASS] = WriteEntry
761cb0ef41Sopenharmony_ci    if (typeof opt.onwarn === 'function') {
771cb0ef41Sopenharmony_ci      this.on('warn', opt.onwarn)
781cb0ef41Sopenharmony_ci    }
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci    this.portable = !!opt.portable
811cb0ef41Sopenharmony_ci    this.zip = null
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci    if (opt.gzip || opt.brotli) {
841cb0ef41Sopenharmony_ci      if (opt.gzip && opt.brotli) {
851cb0ef41Sopenharmony_ci        throw new TypeError('gzip and brotli are mutually exclusive')
861cb0ef41Sopenharmony_ci      }
871cb0ef41Sopenharmony_ci      if (opt.gzip) {
881cb0ef41Sopenharmony_ci        if (typeof opt.gzip !== 'object') {
891cb0ef41Sopenharmony_ci          opt.gzip = {}
901cb0ef41Sopenharmony_ci        }
911cb0ef41Sopenharmony_ci        if (this.portable) {
921cb0ef41Sopenharmony_ci          opt.gzip.portable = true
931cb0ef41Sopenharmony_ci        }
941cb0ef41Sopenharmony_ci        this.zip = new zlib.Gzip(opt.gzip)
951cb0ef41Sopenharmony_ci      }
961cb0ef41Sopenharmony_ci      if (opt.brotli) {
971cb0ef41Sopenharmony_ci        if (typeof opt.brotli !== 'object') {
981cb0ef41Sopenharmony_ci          opt.brotli = {}
991cb0ef41Sopenharmony_ci        }
1001cb0ef41Sopenharmony_ci        this.zip = new zlib.BrotliCompress(opt.brotli)
1011cb0ef41Sopenharmony_ci      }
1021cb0ef41Sopenharmony_ci      this.zip.on('data', chunk => super.write(chunk))
1031cb0ef41Sopenharmony_ci      this.zip.on('end', _ => super.end())
1041cb0ef41Sopenharmony_ci      this.zip.on('drain', _ => this[ONDRAIN]())
1051cb0ef41Sopenharmony_ci      this.on('resume', _ => this.zip.resume())
1061cb0ef41Sopenharmony_ci    } else {
1071cb0ef41Sopenharmony_ci      this.on('drain', this[ONDRAIN])
1081cb0ef41Sopenharmony_ci    }
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci    this.noDirRecurse = !!opt.noDirRecurse
1111cb0ef41Sopenharmony_ci    this.follow = !!opt.follow
1121cb0ef41Sopenharmony_ci    this.noMtime = !!opt.noMtime
1131cb0ef41Sopenharmony_ci    this.mtime = opt.mtime || null
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci    this.filter = typeof opt.filter === 'function' ? opt.filter : _ => true
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci    this[QUEUE] = new Yallist()
1181cb0ef41Sopenharmony_ci    this[JOBS] = 0
1191cb0ef41Sopenharmony_ci    this.jobs = +opt.jobs || 4
1201cb0ef41Sopenharmony_ci    this[PROCESSING] = false
1211cb0ef41Sopenharmony_ci    this[ENDED] = false
1221cb0ef41Sopenharmony_ci  }
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci  [WRITE] (chunk) {
1251cb0ef41Sopenharmony_ci    return super.write(chunk)
1261cb0ef41Sopenharmony_ci  }
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci  add (path) {
1291cb0ef41Sopenharmony_ci    this.write(path)
1301cb0ef41Sopenharmony_ci    return this
1311cb0ef41Sopenharmony_ci  }
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ci  end (path) {
1341cb0ef41Sopenharmony_ci    if (path) {
1351cb0ef41Sopenharmony_ci      this.write(path)
1361cb0ef41Sopenharmony_ci    }
1371cb0ef41Sopenharmony_ci    this[ENDED] = true
1381cb0ef41Sopenharmony_ci    this[PROCESS]()
1391cb0ef41Sopenharmony_ci    return this
1401cb0ef41Sopenharmony_ci  }
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ci  write (path) {
1431cb0ef41Sopenharmony_ci    if (this[ENDED]) {
1441cb0ef41Sopenharmony_ci      throw new Error('write after end')
1451cb0ef41Sopenharmony_ci    }
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ci    if (path instanceof ReadEntry) {
1481cb0ef41Sopenharmony_ci      this[ADDTARENTRY](path)
1491cb0ef41Sopenharmony_ci    } else {
1501cb0ef41Sopenharmony_ci      this[ADDFSENTRY](path)
1511cb0ef41Sopenharmony_ci    }
1521cb0ef41Sopenharmony_ci    return this.flowing
1531cb0ef41Sopenharmony_ci  }
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_ci  [ADDTARENTRY] (p) {
1561cb0ef41Sopenharmony_ci    const absolute = normPath(path.resolve(this.cwd, p.path))
1571cb0ef41Sopenharmony_ci    // in this case, we don't have to wait for the stat
1581cb0ef41Sopenharmony_ci    if (!this.filter(p.path, p)) {
1591cb0ef41Sopenharmony_ci      p.resume()
1601cb0ef41Sopenharmony_ci    } else {
1611cb0ef41Sopenharmony_ci      const job = new PackJob(p.path, absolute, false)
1621cb0ef41Sopenharmony_ci      job.entry = new WriteEntryTar(p, this[ENTRYOPT](job))
1631cb0ef41Sopenharmony_ci      job.entry.on('end', _ => this[JOBDONE](job))
1641cb0ef41Sopenharmony_ci      this[JOBS] += 1
1651cb0ef41Sopenharmony_ci      this[QUEUE].push(job)
1661cb0ef41Sopenharmony_ci    }
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ci    this[PROCESS]()
1691cb0ef41Sopenharmony_ci  }
1701cb0ef41Sopenharmony_ci
1711cb0ef41Sopenharmony_ci  [ADDFSENTRY] (p) {
1721cb0ef41Sopenharmony_ci    const absolute = normPath(path.resolve(this.cwd, p))
1731cb0ef41Sopenharmony_ci    this[QUEUE].push(new PackJob(p, absolute))
1741cb0ef41Sopenharmony_ci    this[PROCESS]()
1751cb0ef41Sopenharmony_ci  }
1761cb0ef41Sopenharmony_ci
1771cb0ef41Sopenharmony_ci  [STAT] (job) {
1781cb0ef41Sopenharmony_ci    job.pending = true
1791cb0ef41Sopenharmony_ci    this[JOBS] += 1
1801cb0ef41Sopenharmony_ci    const stat = this.follow ? 'stat' : 'lstat'
1811cb0ef41Sopenharmony_ci    fs[stat](job.absolute, (er, stat) => {
1821cb0ef41Sopenharmony_ci      job.pending = false
1831cb0ef41Sopenharmony_ci      this[JOBS] -= 1
1841cb0ef41Sopenharmony_ci      if (er) {
1851cb0ef41Sopenharmony_ci        this.emit('error', er)
1861cb0ef41Sopenharmony_ci      } else {
1871cb0ef41Sopenharmony_ci        this[ONSTAT](job, stat)
1881cb0ef41Sopenharmony_ci      }
1891cb0ef41Sopenharmony_ci    })
1901cb0ef41Sopenharmony_ci  }
1911cb0ef41Sopenharmony_ci
1921cb0ef41Sopenharmony_ci  [ONSTAT] (job, stat) {
1931cb0ef41Sopenharmony_ci    this.statCache.set(job.absolute, stat)
1941cb0ef41Sopenharmony_ci    job.stat = stat
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ci    // now we have the stat, we can filter it.
1971cb0ef41Sopenharmony_ci    if (!this.filter(job.path, stat)) {
1981cb0ef41Sopenharmony_ci      job.ignore = true
1991cb0ef41Sopenharmony_ci    }
2001cb0ef41Sopenharmony_ci
2011cb0ef41Sopenharmony_ci    this[PROCESS]()
2021cb0ef41Sopenharmony_ci  }
2031cb0ef41Sopenharmony_ci
2041cb0ef41Sopenharmony_ci  [READDIR] (job) {
2051cb0ef41Sopenharmony_ci    job.pending = true
2061cb0ef41Sopenharmony_ci    this[JOBS] += 1
2071cb0ef41Sopenharmony_ci    fs.readdir(job.absolute, (er, entries) => {
2081cb0ef41Sopenharmony_ci      job.pending = false
2091cb0ef41Sopenharmony_ci      this[JOBS] -= 1
2101cb0ef41Sopenharmony_ci      if (er) {
2111cb0ef41Sopenharmony_ci        return this.emit('error', er)
2121cb0ef41Sopenharmony_ci      }
2131cb0ef41Sopenharmony_ci      this[ONREADDIR](job, entries)
2141cb0ef41Sopenharmony_ci    })
2151cb0ef41Sopenharmony_ci  }
2161cb0ef41Sopenharmony_ci
2171cb0ef41Sopenharmony_ci  [ONREADDIR] (job, entries) {
2181cb0ef41Sopenharmony_ci    this.readdirCache.set(job.absolute, entries)
2191cb0ef41Sopenharmony_ci    job.readdir = entries
2201cb0ef41Sopenharmony_ci    this[PROCESS]()
2211cb0ef41Sopenharmony_ci  }
2221cb0ef41Sopenharmony_ci
2231cb0ef41Sopenharmony_ci  [PROCESS] () {
2241cb0ef41Sopenharmony_ci    if (this[PROCESSING]) {
2251cb0ef41Sopenharmony_ci      return
2261cb0ef41Sopenharmony_ci    }
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_ci    this[PROCESSING] = true
2291cb0ef41Sopenharmony_ci    for (let w = this[QUEUE].head;
2301cb0ef41Sopenharmony_ci      w !== null && this[JOBS] < this.jobs;
2311cb0ef41Sopenharmony_ci      w = w.next) {
2321cb0ef41Sopenharmony_ci      this[PROCESSJOB](w.value)
2331cb0ef41Sopenharmony_ci      if (w.value.ignore) {
2341cb0ef41Sopenharmony_ci        const p = w.next
2351cb0ef41Sopenharmony_ci        this[QUEUE].removeNode(w)
2361cb0ef41Sopenharmony_ci        w.next = p
2371cb0ef41Sopenharmony_ci      }
2381cb0ef41Sopenharmony_ci    }
2391cb0ef41Sopenharmony_ci
2401cb0ef41Sopenharmony_ci    this[PROCESSING] = false
2411cb0ef41Sopenharmony_ci
2421cb0ef41Sopenharmony_ci    if (this[ENDED] && !this[QUEUE].length && this[JOBS] === 0) {
2431cb0ef41Sopenharmony_ci      if (this.zip) {
2441cb0ef41Sopenharmony_ci        this.zip.end(EOF)
2451cb0ef41Sopenharmony_ci      } else {
2461cb0ef41Sopenharmony_ci        super.write(EOF)
2471cb0ef41Sopenharmony_ci        super.end()
2481cb0ef41Sopenharmony_ci      }
2491cb0ef41Sopenharmony_ci    }
2501cb0ef41Sopenharmony_ci  }
2511cb0ef41Sopenharmony_ci
2521cb0ef41Sopenharmony_ci  get [CURRENT] () {
2531cb0ef41Sopenharmony_ci    return this[QUEUE] && this[QUEUE].head && this[QUEUE].head.value
2541cb0ef41Sopenharmony_ci  }
2551cb0ef41Sopenharmony_ci
2561cb0ef41Sopenharmony_ci  [JOBDONE] (job) {
2571cb0ef41Sopenharmony_ci    this[QUEUE].shift()
2581cb0ef41Sopenharmony_ci    this[JOBS] -= 1
2591cb0ef41Sopenharmony_ci    this[PROCESS]()
2601cb0ef41Sopenharmony_ci  }
2611cb0ef41Sopenharmony_ci
2621cb0ef41Sopenharmony_ci  [PROCESSJOB] (job) {
2631cb0ef41Sopenharmony_ci    if (job.pending) {
2641cb0ef41Sopenharmony_ci      return
2651cb0ef41Sopenharmony_ci    }
2661cb0ef41Sopenharmony_ci
2671cb0ef41Sopenharmony_ci    if (job.entry) {
2681cb0ef41Sopenharmony_ci      if (job === this[CURRENT] && !job.piped) {
2691cb0ef41Sopenharmony_ci        this[PIPE](job)
2701cb0ef41Sopenharmony_ci      }
2711cb0ef41Sopenharmony_ci      return
2721cb0ef41Sopenharmony_ci    }
2731cb0ef41Sopenharmony_ci
2741cb0ef41Sopenharmony_ci    if (!job.stat) {
2751cb0ef41Sopenharmony_ci      if (this.statCache.has(job.absolute)) {
2761cb0ef41Sopenharmony_ci        this[ONSTAT](job, this.statCache.get(job.absolute))
2771cb0ef41Sopenharmony_ci      } else {
2781cb0ef41Sopenharmony_ci        this[STAT](job)
2791cb0ef41Sopenharmony_ci      }
2801cb0ef41Sopenharmony_ci    }
2811cb0ef41Sopenharmony_ci    if (!job.stat) {
2821cb0ef41Sopenharmony_ci      return
2831cb0ef41Sopenharmony_ci    }
2841cb0ef41Sopenharmony_ci
2851cb0ef41Sopenharmony_ci    // filtered out!
2861cb0ef41Sopenharmony_ci    if (job.ignore) {
2871cb0ef41Sopenharmony_ci      return
2881cb0ef41Sopenharmony_ci    }
2891cb0ef41Sopenharmony_ci
2901cb0ef41Sopenharmony_ci    if (!this.noDirRecurse && job.stat.isDirectory() && !job.readdir) {
2911cb0ef41Sopenharmony_ci      if (this.readdirCache.has(job.absolute)) {
2921cb0ef41Sopenharmony_ci        this[ONREADDIR](job, this.readdirCache.get(job.absolute))
2931cb0ef41Sopenharmony_ci      } else {
2941cb0ef41Sopenharmony_ci        this[READDIR](job)
2951cb0ef41Sopenharmony_ci      }
2961cb0ef41Sopenharmony_ci      if (!job.readdir) {
2971cb0ef41Sopenharmony_ci        return
2981cb0ef41Sopenharmony_ci      }
2991cb0ef41Sopenharmony_ci    }
3001cb0ef41Sopenharmony_ci
3011cb0ef41Sopenharmony_ci    // we know it doesn't have an entry, because that got checked above
3021cb0ef41Sopenharmony_ci    job.entry = this[ENTRY](job)
3031cb0ef41Sopenharmony_ci    if (!job.entry) {
3041cb0ef41Sopenharmony_ci      job.ignore = true
3051cb0ef41Sopenharmony_ci      return
3061cb0ef41Sopenharmony_ci    }
3071cb0ef41Sopenharmony_ci
3081cb0ef41Sopenharmony_ci    if (job === this[CURRENT] && !job.piped) {
3091cb0ef41Sopenharmony_ci      this[PIPE](job)
3101cb0ef41Sopenharmony_ci    }
3111cb0ef41Sopenharmony_ci  }
3121cb0ef41Sopenharmony_ci
3131cb0ef41Sopenharmony_ci  [ENTRYOPT] (job) {
3141cb0ef41Sopenharmony_ci    return {
3151cb0ef41Sopenharmony_ci      onwarn: (code, msg, data) => this.warn(code, msg, data),
3161cb0ef41Sopenharmony_ci      noPax: this.noPax,
3171cb0ef41Sopenharmony_ci      cwd: this.cwd,
3181cb0ef41Sopenharmony_ci      absolute: job.absolute,
3191cb0ef41Sopenharmony_ci      preservePaths: this.preservePaths,
3201cb0ef41Sopenharmony_ci      maxReadSize: this.maxReadSize,
3211cb0ef41Sopenharmony_ci      strict: this.strict,
3221cb0ef41Sopenharmony_ci      portable: this.portable,
3231cb0ef41Sopenharmony_ci      linkCache: this.linkCache,
3241cb0ef41Sopenharmony_ci      statCache: this.statCache,
3251cb0ef41Sopenharmony_ci      noMtime: this.noMtime,
3261cb0ef41Sopenharmony_ci      mtime: this.mtime,
3271cb0ef41Sopenharmony_ci      prefix: this.prefix,
3281cb0ef41Sopenharmony_ci    }
3291cb0ef41Sopenharmony_ci  }
3301cb0ef41Sopenharmony_ci
3311cb0ef41Sopenharmony_ci  [ENTRY] (job) {
3321cb0ef41Sopenharmony_ci    this[JOBS] += 1
3331cb0ef41Sopenharmony_ci    try {
3341cb0ef41Sopenharmony_ci      return new this[WRITEENTRYCLASS](job.path, this[ENTRYOPT](job))
3351cb0ef41Sopenharmony_ci        .on('end', () => this[JOBDONE](job))
3361cb0ef41Sopenharmony_ci        .on('error', er => this.emit('error', er))
3371cb0ef41Sopenharmony_ci    } catch (er) {
3381cb0ef41Sopenharmony_ci      this.emit('error', er)
3391cb0ef41Sopenharmony_ci    }
3401cb0ef41Sopenharmony_ci  }
3411cb0ef41Sopenharmony_ci
3421cb0ef41Sopenharmony_ci  [ONDRAIN] () {
3431cb0ef41Sopenharmony_ci    if (this[CURRENT] && this[CURRENT].entry) {
3441cb0ef41Sopenharmony_ci      this[CURRENT].entry.resume()
3451cb0ef41Sopenharmony_ci    }
3461cb0ef41Sopenharmony_ci  }
3471cb0ef41Sopenharmony_ci
3481cb0ef41Sopenharmony_ci  // like .pipe() but using super, because our write() is special
3491cb0ef41Sopenharmony_ci  [PIPE] (job) {
3501cb0ef41Sopenharmony_ci    job.piped = true
3511cb0ef41Sopenharmony_ci
3521cb0ef41Sopenharmony_ci    if (job.readdir) {
3531cb0ef41Sopenharmony_ci      job.readdir.forEach(entry => {
3541cb0ef41Sopenharmony_ci        const p = job.path
3551cb0ef41Sopenharmony_ci        const base = p === './' ? '' : p.replace(/\/*$/, '/')
3561cb0ef41Sopenharmony_ci        this[ADDFSENTRY](base + entry)
3571cb0ef41Sopenharmony_ci      })
3581cb0ef41Sopenharmony_ci    }
3591cb0ef41Sopenharmony_ci
3601cb0ef41Sopenharmony_ci    const source = job.entry
3611cb0ef41Sopenharmony_ci    const zip = this.zip
3621cb0ef41Sopenharmony_ci
3631cb0ef41Sopenharmony_ci    if (zip) {
3641cb0ef41Sopenharmony_ci      source.on('data', chunk => {
3651cb0ef41Sopenharmony_ci        if (!zip.write(chunk)) {
3661cb0ef41Sopenharmony_ci          source.pause()
3671cb0ef41Sopenharmony_ci        }
3681cb0ef41Sopenharmony_ci      })
3691cb0ef41Sopenharmony_ci    } else {
3701cb0ef41Sopenharmony_ci      source.on('data', chunk => {
3711cb0ef41Sopenharmony_ci        if (!super.write(chunk)) {
3721cb0ef41Sopenharmony_ci          source.pause()
3731cb0ef41Sopenharmony_ci        }
3741cb0ef41Sopenharmony_ci      })
3751cb0ef41Sopenharmony_ci    }
3761cb0ef41Sopenharmony_ci  }
3771cb0ef41Sopenharmony_ci
3781cb0ef41Sopenharmony_ci  pause () {
3791cb0ef41Sopenharmony_ci    if (this.zip) {
3801cb0ef41Sopenharmony_ci      this.zip.pause()
3811cb0ef41Sopenharmony_ci    }
3821cb0ef41Sopenharmony_ci    return super.pause()
3831cb0ef41Sopenharmony_ci  }
3841cb0ef41Sopenharmony_ci})
3851cb0ef41Sopenharmony_ci
3861cb0ef41Sopenharmony_ciclass PackSync extends Pack {
3871cb0ef41Sopenharmony_ci  constructor (opt) {
3881cb0ef41Sopenharmony_ci    super(opt)
3891cb0ef41Sopenharmony_ci    this[WRITEENTRYCLASS] = WriteEntrySync
3901cb0ef41Sopenharmony_ci  }
3911cb0ef41Sopenharmony_ci
3921cb0ef41Sopenharmony_ci  // pause/resume are no-ops in sync streams.
3931cb0ef41Sopenharmony_ci  pause () {}
3941cb0ef41Sopenharmony_ci  resume () {}
3951cb0ef41Sopenharmony_ci
3961cb0ef41Sopenharmony_ci  [STAT] (job) {
3971cb0ef41Sopenharmony_ci    const stat = this.follow ? 'statSync' : 'lstatSync'
3981cb0ef41Sopenharmony_ci    this[ONSTAT](job, fs[stat](job.absolute))
3991cb0ef41Sopenharmony_ci  }
4001cb0ef41Sopenharmony_ci
4011cb0ef41Sopenharmony_ci  [READDIR] (job, stat) {
4021cb0ef41Sopenharmony_ci    this[ONREADDIR](job, fs.readdirSync(job.absolute))
4031cb0ef41Sopenharmony_ci  }
4041cb0ef41Sopenharmony_ci
4051cb0ef41Sopenharmony_ci  // gotta get it all in this tick
4061cb0ef41Sopenharmony_ci  [PIPE] (job) {
4071cb0ef41Sopenharmony_ci    const source = job.entry
4081cb0ef41Sopenharmony_ci    const zip = this.zip
4091cb0ef41Sopenharmony_ci
4101cb0ef41Sopenharmony_ci    if (job.readdir) {
4111cb0ef41Sopenharmony_ci      job.readdir.forEach(entry => {
4121cb0ef41Sopenharmony_ci        const p = job.path
4131cb0ef41Sopenharmony_ci        const base = p === './' ? '' : p.replace(/\/*$/, '/')
4141cb0ef41Sopenharmony_ci        this[ADDFSENTRY](base + entry)
4151cb0ef41Sopenharmony_ci      })
4161cb0ef41Sopenharmony_ci    }
4171cb0ef41Sopenharmony_ci
4181cb0ef41Sopenharmony_ci    if (zip) {
4191cb0ef41Sopenharmony_ci      source.on('data', chunk => {
4201cb0ef41Sopenharmony_ci        zip.write(chunk)
4211cb0ef41Sopenharmony_ci      })
4221cb0ef41Sopenharmony_ci    } else {
4231cb0ef41Sopenharmony_ci      source.on('data', chunk => {
4241cb0ef41Sopenharmony_ci        super[WRITE](chunk)
4251cb0ef41Sopenharmony_ci      })
4261cb0ef41Sopenharmony_ci    }
4271cb0ef41Sopenharmony_ci  }
4281cb0ef41Sopenharmony_ci}
4291cb0ef41Sopenharmony_ci
4301cb0ef41Sopenharmony_ciPack.Sync = PackSync
4311cb0ef41Sopenharmony_ci
4321cb0ef41Sopenharmony_cimodule.exports = Pack
433