Tons of Solutions Engineering work done today for the rest of the CS team! Headway, Howard Hanna, Engels, Brighton, etc. Also completed Datasnippers auth flow and worked on Anthology's script. Cloned Anthology's courses (900..) and will clone Full Story on Monday.
This commit is contained in:
287
Scripts/node_modules/tar-stream/pack.js
generated
vendored
Normal file
287
Scripts/node_modules/tar-stream/pack.js
generated
vendored
Normal file
@ -0,0 +1,287 @@
|
||||
const { Readable, Writable, getStreamError } = require('streamx')
|
||||
const b4a = require('b4a')
|
||||
|
||||
const constants = require('./constants')
|
||||
const headers = require('./headers')
|
||||
|
||||
const DMODE = 0o755
|
||||
const FMODE = 0o644
|
||||
|
||||
const END_OF_TAR = b4a.alloc(1024)
|
||||
|
||||
class Sink extends Writable {
|
||||
constructor (pack, header, callback) {
|
||||
super({ mapWritable, eagerOpen: true })
|
||||
|
||||
this.written = 0
|
||||
this.header = header
|
||||
|
||||
this._callback = callback
|
||||
this._linkname = null
|
||||
this._isLinkname = header.type === 'symlink' && !header.linkname
|
||||
this._isVoid = header.type !== 'file' && header.type !== 'contiguous-file'
|
||||
this._finished = false
|
||||
this._pack = pack
|
||||
this._openCallback = null
|
||||
|
||||
if (this._pack._stream === null) this._pack._stream = this
|
||||
else this._pack._pending.push(this)
|
||||
}
|
||||
|
||||
_open (cb) {
|
||||
this._openCallback = cb
|
||||
if (this._pack._stream === this) this._continueOpen()
|
||||
}
|
||||
|
||||
_continuePack (err) {
|
||||
if (this._callback === null) return
|
||||
|
||||
const callback = this._callback
|
||||
this._callback = null
|
||||
|
||||
callback(err)
|
||||
}
|
||||
|
||||
_continueOpen () {
|
||||
if (this._pack._stream === null) this._pack._stream = this
|
||||
|
||||
const cb = this._openCallback
|
||||
this._openCallback = null
|
||||
if (cb === null) return
|
||||
|
||||
if (this._pack.destroying) return cb(new Error('pack stream destroyed'))
|
||||
if (this._pack._finalized) return cb(new Error('pack stream is already finalized'))
|
||||
|
||||
this._pack._stream = this
|
||||
|
||||
if (!this._isLinkname) {
|
||||
this._pack._encode(this.header)
|
||||
}
|
||||
|
||||
if (this._isVoid) {
|
||||
this._finish()
|
||||
this._continuePack(null)
|
||||
}
|
||||
|
||||
cb(null)
|
||||
}
|
||||
|
||||
_write (data, cb) {
|
||||
if (this._isLinkname) {
|
||||
this._linkname = this._linkname ? b4a.concat([this._linkname, data]) : data
|
||||
return cb(null)
|
||||
}
|
||||
|
||||
if (this._isVoid) {
|
||||
if (data.byteLength > 0) {
|
||||
return cb(new Error('No body allowed for this entry'))
|
||||
}
|
||||
return cb()
|
||||
}
|
||||
|
||||
this.written += data.byteLength
|
||||
if (this._pack.push(data)) return cb()
|
||||
this._pack._drain = cb
|
||||
}
|
||||
|
||||
_finish () {
|
||||
if (this._finished) return
|
||||
this._finished = true
|
||||
|
||||
if (this._isLinkname) {
|
||||
this.header.linkname = this._linkname ? b4a.toString(this._linkname, 'utf-8') : ''
|
||||
this._pack._encode(this.header)
|
||||
}
|
||||
|
||||
overflow(this._pack, this.header.size)
|
||||
|
||||
this._pack._done(this)
|
||||
}
|
||||
|
||||
_final (cb) {
|
||||
if (this.written !== this.header.size) { // corrupting tar
|
||||
return cb(new Error('Size mismatch'))
|
||||
}
|
||||
|
||||
this._finish()
|
||||
cb(null)
|
||||
}
|
||||
|
||||
_getError () {
|
||||
return getStreamError(this) || new Error('tar entry destroyed')
|
||||
}
|
||||
|
||||
_predestroy () {
|
||||
this._pack.destroy(this._getError())
|
||||
}
|
||||
|
||||
_destroy (cb) {
|
||||
this._pack._done(this)
|
||||
|
||||
this._continuePack(this._finished ? null : this._getError())
|
||||
|
||||
cb()
|
||||
}
|
||||
}
|
||||
|
||||
class Pack extends Readable {
|
||||
constructor (opts) {
|
||||
super(opts)
|
||||
this._drain = noop
|
||||
this._finalized = false
|
||||
this._finalizing = false
|
||||
this._pending = []
|
||||
this._stream = null
|
||||
}
|
||||
|
||||
entry (header, buffer, callback) {
|
||||
if (this._finalized || this.destroying) throw new Error('already finalized or destroyed')
|
||||
|
||||
if (typeof buffer === 'function') {
|
||||
callback = buffer
|
||||
buffer = null
|
||||
}
|
||||
|
||||
if (!callback) callback = noop
|
||||
|
||||
if (!header.size || header.type === 'symlink') header.size = 0
|
||||
if (!header.type) header.type = modeToType(header.mode)
|
||||
if (!header.mode) header.mode = header.type === 'directory' ? DMODE : FMODE
|
||||
if (!header.uid) header.uid = 0
|
||||
if (!header.gid) header.gid = 0
|
||||
if (!header.mtime) header.mtime = new Date()
|
||||
|
||||
if (typeof buffer === 'string') buffer = b4a.from(buffer)
|
||||
|
||||
const sink = new Sink(this, header, callback)
|
||||
|
||||
if (b4a.isBuffer(buffer)) {
|
||||
header.size = buffer.byteLength
|
||||
sink.write(buffer)
|
||||
sink.end()
|
||||
return sink
|
||||
}
|
||||
|
||||
if (sink._isVoid) {
|
||||
return sink
|
||||
}
|
||||
|
||||
return sink
|
||||
}
|
||||
|
||||
finalize () {
|
||||
if (this._stream || this._pending.length > 0) {
|
||||
this._finalizing = true
|
||||
return
|
||||
}
|
||||
|
||||
if (this._finalized) return
|
||||
this._finalized = true
|
||||
|
||||
this.push(END_OF_TAR)
|
||||
this.push(null)
|
||||
}
|
||||
|
||||
_done (stream) {
|
||||
if (stream !== this._stream) return
|
||||
|
||||
this._stream = null
|
||||
|
||||
if (this._finalizing) this.finalize()
|
||||
if (this._pending.length) this._pending.shift()._continueOpen()
|
||||
}
|
||||
|
||||
_encode (header) {
|
||||
if (!header.pax) {
|
||||
const buf = headers.encode(header)
|
||||
if (buf) {
|
||||
this.push(buf)
|
||||
return
|
||||
}
|
||||
}
|
||||
this._encodePax(header)
|
||||
}
|
||||
|
||||
_encodePax (header) {
|
||||
const paxHeader = headers.encodePax({
|
||||
name: header.name,
|
||||
linkname: header.linkname,
|
||||
pax: header.pax
|
||||
})
|
||||
|
||||
const newHeader = {
|
||||
name: 'PaxHeader',
|
||||
mode: header.mode,
|
||||
uid: header.uid,
|
||||
gid: header.gid,
|
||||
size: paxHeader.byteLength,
|
||||
mtime: header.mtime,
|
||||
type: 'pax-header',
|
||||
linkname: header.linkname && 'PaxHeader',
|
||||
uname: header.uname,
|
||||
gname: header.gname,
|
||||
devmajor: header.devmajor,
|
||||
devminor: header.devminor
|
||||
}
|
||||
|
||||
this.push(headers.encode(newHeader))
|
||||
this.push(paxHeader)
|
||||
overflow(this, paxHeader.byteLength)
|
||||
|
||||
newHeader.size = header.size
|
||||
newHeader.type = header.type
|
||||
this.push(headers.encode(newHeader))
|
||||
}
|
||||
|
||||
_doDrain () {
|
||||
const drain = this._drain
|
||||
this._drain = noop
|
||||
drain()
|
||||
}
|
||||
|
||||
_predestroy () {
|
||||
const err = getStreamError(this)
|
||||
|
||||
if (this._stream) this._stream.destroy(err)
|
||||
|
||||
while (this._pending.length) {
|
||||
const stream = this._pending.shift()
|
||||
stream.destroy(err)
|
||||
stream._continueOpen()
|
||||
}
|
||||
|
||||
this._doDrain()
|
||||
}
|
||||
|
||||
_read (cb) {
|
||||
this._doDrain()
|
||||
cb()
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function pack (opts) {
|
||||
return new Pack(opts)
|
||||
}
|
||||
|
||||
function modeToType (mode) {
|
||||
switch (mode & constants.S_IFMT) {
|
||||
case constants.S_IFBLK: return 'block-device'
|
||||
case constants.S_IFCHR: return 'character-device'
|
||||
case constants.S_IFDIR: return 'directory'
|
||||
case constants.S_IFIFO: return 'fifo'
|
||||
case constants.S_IFLNK: return 'symlink'
|
||||
}
|
||||
|
||||
return 'file'
|
||||
}
|
||||
|
||||
function noop () {}
|
||||
|
||||
function overflow (self, size) {
|
||||
size &= 511
|
||||
if (size) self.push(END_OF_TAR.subarray(0, 512 - size))
|
||||
}
|
||||
|
||||
function mapWritable (buf) {
|
||||
return b4a.isBuffer(buf) ? buf : b4a.from(buf)
|
||||
}
|
||||
Reference in New Issue
Block a user