File Explorer

/var/lang/lib/node_modules/npm/node_modules/fs-minipass/lib

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

0 dirs
1 file
index.js9.7 KB · 444 lines
'use strict'const { Minipass } = require('minipass')const EE = require('events').EventEmitterconst fs = require('fs') const writev = fs.writev const _autoClose = Symbol('_autoClose')const _close = Symbol('_close')const _ended = Symbol('_ended')const _fd = Symbol('_fd')const _finished = Symbol('_finished')const _flags = Symbol('_flags')const _flush = Symbol('_flush')const _handleChunk = Symbol('_handleChunk')const _makeBuf = Symbol('_makeBuf')const _mode = Symbol('_mode')const _needDrain = Symbol('_needDrain')const _onerror = Symbol('_onerror')const _onopen = Symbol('_onopen')const _onread = Symbol('_onread')const _onwrite = Symbol('_onwrite')const _open = Symbol('_open')const _path = Symbol('_path')const _pos = Symbol('_pos')const _queue = Symbol('_queue')const _read = Symbol('_read')const _readSize = Symbol('_readSize')const _reading = Symbol('_reading')const _remain = Symbol('_remain')const _size = Symbol('_size')const _write = Symbol('_write')const _writing = Symbol('_writing')const _defaultFlag = Symbol('_defaultFlag')const _errored = Symbol('_errored') class ReadStream extends Minipass {  constructor (path, opt) {    opt = opt || {}    super(opt)     this.readable = true    this.writable = false     if (typeof path !== 'string') {      throw new TypeError('path must be a string')    }     this[_errored] = false    this[_fd] = typeof opt.fd === 'number' ? opt.fd : null    this[_path] = path    this[_readSize] = opt.readSize || 16 * 1024 * 1024    this[_reading] = false    this[_size] = typeof opt.size === 'number' ? opt.size : Infinity    this[_remain] = this[_size]    this[_autoClose] = typeof opt.autoClose === 'boolean' ?      opt.autoClose : true     if (typeof this[_fd] === 'number') {      this[_read]()    } else {      this[_open]()    }  }   get fd () {    return this[_fd]  }   get path () {    return this[_path]  }   write () {    throw new TypeError('this is a readable stream')  }   end () {    throw new TypeError('this is a readable stream')  }   [_open] () {    fs.open(this[_path], 'r', (er, fd) => this[_onopen](er, fd))  }   [_onopen] (er, fd) {    if (er) {      this[_onerror](er)    } else {      this[_fd] = fd      this.emit('open', fd)      this[_read]()    }  }   [_makeBuf] () {    return Buffer.allocUnsafe(Math.min(this[_readSize], this[_remain]))  }   [_read] () {    if (!this[_reading]) {      this[_reading] = true      const buf = this[_makeBuf]()      /* istanbul ignore if */      if (buf.length === 0) {        return process.nextTick(() => this[_onread](null, 0, buf))      }      fs.read(this[_fd], buf, 0, buf.length, null, (er, br, b) =>        this[_onread](er, br, b))    }  }   [_onread] (er, br, buf) {    this[_reading] = false    if (er) {      this[_onerror](er)    } else if (this[_handleChunk](br, buf)) {      this[_read]()    }  }   [_close] () {    if (this[_autoClose] && typeof this[_fd] === 'number') {      const fd = this[_fd]      this[_fd] = null      fs.close(fd, er => er ? this.emit('error', er) : this.emit('close'))    }  }   [_onerror] (er) {    this[_reading] = true    this[_close]()    this.emit('error', er)  }   [_handleChunk] (br, buf) {    let ret = false    // no effect if infinite    this[_remain] -= br    if (br > 0) {      ret = super.write(br < buf.length ? buf.slice(0, br) : buf)    }     if (br === 0 || this[_remain] <= 0) {      ret = false      this[_close]()      super.end()    }     return ret  }   emit (ev, data) {    switch (ev) {      case 'prefinish':      case 'finish':        break       case 'drain':        if (typeof this[_fd] === 'number') {          this[_read]()        }        break       case 'error':        if (this[_errored]) {          return        }        this[_errored] = true        return super.emit(ev, data)       default:        return super.emit(ev, data)    }  }} class ReadStreamSync extends ReadStream {  [_open] () {    let threw = true    try {      this[_onopen](null, fs.openSync(this[_path], 'r'))      threw = false    } finally {      if (threw) {        this[_close]()      }    }  }   [_read] () {    let threw = true    try {      if (!this[_reading]) {        this[_reading] = true        do {          const buf = this[_makeBuf]()          /* istanbul ignore next */          const br = buf.length === 0 ? 0            : fs.readSync(this[_fd], buf, 0, buf.length, null)          if (!this[_handleChunk](br, buf)) {            break          }        } while (true)        this[_reading] = false      }      threw = false    } finally {      if (threw) {        this[_close]()      }    }  }   [_close] () {    if (this[_autoClose] && typeof this[_fd] === 'number') {      const fd = this[_fd]      this[_fd] = null      fs.closeSync(fd)      this.emit('close')    }  }} class WriteStream extends EE {  constructor (path, opt) {    opt = opt || {}    super(opt)    this.readable = false    this.writable = true    this[_errored] = false    this[_writing] = false    this[_ended] = false    this[_needDrain] = false    this[_queue] = []    this[_path] = path    this[_fd] = typeof opt.fd === 'number' ? opt.fd : null    this[_mode] = opt.mode === undefined ? 0o666 : opt.mode    this[_pos] = typeof opt.start === 'number' ? opt.start : null    this[_autoClose] = typeof opt.autoClose === 'boolean' ?      opt.autoClose : true     // truncating makes no sense when writing into the middle    const defaultFlag = this[_pos] !== null ? 'r+' : 'w'    this[_defaultFlag] = opt.flags === undefined    this[_flags] = this[_defaultFlag] ? defaultFlag : opt.flags     if (this[_fd] === null) {      this[_open]()    }  }   emit (ev, data) {    if (ev === 'error') {      if (this[_errored]) {        return      }      this[_errored] = true    }    return super.emit(ev, data)  }   get fd () {    return this[_fd]  }   get path () {    return this[_path]  }   [_onerror] (er) {    this[_close]()    this[_writing] = true    this.emit('error', er)  }   [_open] () {    fs.open(this[_path], this[_flags], this[_mode],      (er, fd) => this[_onopen](er, fd))  }   [_onopen] (er, fd) {    if (this[_defaultFlag] &&        this[_flags] === 'r+' &&        er && er.code === 'ENOENT') {      this[_flags] = 'w'      this[_open]()    } else if (er) {      this[_onerror](er)    } else {      this[_fd] = fd      this.emit('open', fd)      if (!this[_writing]) {        this[_flush]()      }    }  }   end (buf, enc) {    if (buf) {      this.write(buf, enc)    }     this[_ended] = true     // synthetic after-write logic, where drain/finish live    if (!this[_writing] && !this[_queue].length &&        typeof this[_fd] === 'number') {      this[_onwrite](null, 0)    }    return this  }   write (buf, enc) {    if (typeof buf === 'string') {      buf = Buffer.from(buf, enc)    }     if (this[_ended]) {      this.emit('error', new Error('write() after end()'))      return false    }     if (this[_fd] === null || this[_writing] || this[_queue].length) {      this[_queue].push(buf)      this[_needDrain] = true      return false    }     this[_writing] = true    this[_write](buf)    return true  }   [_write] (buf) {    fs.write(this[_fd], buf, 0, buf.length, this[_pos], (er, bw) =>      this[_onwrite](er, bw))  }   [_onwrite] (er, bw) {    if (er) {      this[_onerror](er)    } else {      if (this[_pos] !== null) {        this[_pos] += bw      }      if (this[_queue].length) {        this[_flush]()      } else {        this[_writing] = false         if (this[_ended] && !this[_finished]) {          this[_finished] = true          this[_close]()          this.emit('finish')        } else if (this[_needDrain]) {          this[_needDrain] = false          this.emit('drain')        }      }    }  }   [_flush] () {    if (this[_queue].length === 0) {      if (this[_ended]) {        this[_onwrite](null, 0)      }    } else if (this[_queue].length === 1) {      this[_write](this[_queue].pop())    } else {      const iovec = this[_queue]      this[_queue] = []      writev(this[_fd], iovec, this[_pos],        (er, bw) => this[_onwrite](er, bw))    }  }   [_close] () {    if (this[_autoClose] && typeof this[_fd] === 'number') {      const fd = this[_fd]      this[_fd] = null      fs.close(fd, er => er ? this.emit('error', er) : this.emit('close'))    }  }} class WriteStreamSync extends WriteStream {  [_open] () {    let fd    // only wrap in a try{} block if we know we'll retry, to avoid    // the rethrow obscuring the error's source frame in most cases.    if (this[_defaultFlag] && this[_flags] === 'r+') {      try {        fd = fs.openSync(this[_path], this[_flags], this[_mode])      } catch (er) {        if (er.code === 'ENOENT') {          this[_flags] = 'w'          return this[_open]()        } else {          throw er        }      }    } else {      fd = fs.openSync(this[_path], this[_flags], this[_mode])    }     this[_onopen](null, fd)  }   [_close] () {    if (this[_autoClose] && typeof this[_fd] === 'number') {      const fd = this[_fd]      this[_fd] = null      fs.closeSync(fd)      this.emit('close')    }  }   [_write] (buf) {    // throw the original, but try to close if it fails    let threw = true    try {      this[_onwrite](null,        fs.writeSync(this[_fd], buf, 0, buf.length, this[_pos]))      threw = false    } finally {      if (threw) {        try {          this[_close]()        } catch {          // ok error        }      }    }  }} exports.ReadStream = ReadStreamexports.ReadStreamSync = ReadStreamSync exports.WriteStream = WriteStreamexports.WriteStreamSync = WriteStreamSync