Comparing version 1.5.5 to 1.6.0
982
index.js
const { Readable, Writable } = require('streamx') | ||
const binding = require('./binding') | ||
const LE = (new Uint8Array(new Uint16Array([255]).buffer))[0] === 0xff | ||
const sep = process.platform === 'win32' ? '\\' : '/' | ||
@@ -15,2 +13,3 @@ | ||
O_APPEND: binding.O_APPEND, | ||
S_IFMT: binding.S_IFMT, | ||
@@ -23,3 +22,12 @@ S_IFREG: binding.S_IFREG, | ||
S_IFIFO: binding.S_IFIFO || 0, | ||
S_IFSOCK: binding.S_IFSOCK || 0 | ||
S_IFSOCK: binding.S_IFSOCK || 0, | ||
UV_DIRENT_UNKNOWN: binding.UV_DIRENT_UNKNOWN, | ||
UV_DIRENT_FILE: binding.UV_DIRENT_FILE, | ||
UV_DIRENT_DIR: binding.UV_DIRENT_DIR, | ||
UV_DIRENT_LINK: binding.UV_DIRENT_LINK, | ||
UV_DIRENT_FIFO: binding.UV_DIRENT_FIFO, | ||
UV_DIRENT_SOCKET: binding.UV_DIRENT_SOCKET, | ||
UV_DIRENT_CHAR: binding.UV_DIRENT_CHAR, | ||
UV_DIRENT_BLOCK: binding.UV_DIRENT_BLOCK | ||
} | ||
@@ -34,6 +42,10 @@ | ||
binding.init(fs.handle, fs, onfsresponse) | ||
binding.init(fs.handle, fs, onresponse) | ||
process.on('exit', () => binding.destroy(fs.handle)) | ||
if (process.thread) { | ||
process.thread.on('exit', () => binding.destroy(fs.handle)) | ||
} | ||
// Lightly-modified from the Node FS internal utils. | ||
@@ -92,4 +104,2 @@ function flagsToNumber (flags) { | ||
type: 0, | ||
buffer: null, | ||
buffers: null, | ||
callback: null | ||
@@ -107,3 +117,3 @@ } | ||
function onfsresponse (id, result) { | ||
function onresponse (id, result) { | ||
const req = reqs[id] | ||
@@ -119,8 +129,4 @@ used-- | ||
const callback = req.callback | ||
const buffer = req.buffer | ||
const buffers = req.buffers | ||
req.callback = null | ||
req.buffer = null | ||
req.buffers = null | ||
@@ -130,3 +136,3 @@ if (result < 0) { | ||
} else { | ||
callback(null, result, buffer || buffers) | ||
callback(null, result) | ||
} | ||
@@ -145,247 +151,462 @@ } | ||
function write (fd, buf, offset, len, pos, cb) { | ||
if (typeof cb === 'function') { | ||
const req = getReq() | ||
function open (path, flags, mode, cb) { | ||
if (typeof path !== 'string') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received type ' + (typeof path) + ' (' + path + ')') | ||
} | ||
req.buffer = buf | ||
req.callback = cb | ||
binding.write(req.handle, fd, buf, offset, len, pos) | ||
return | ||
if (typeof cb !== 'function') { | ||
if (typeof flags === 'function') { | ||
cb = flags | ||
flags = 'r' | ||
mode = 0o666 | ||
} else if (typeof mode === 'function') { | ||
cb = mode | ||
mode = 0o666 | ||
} else { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
} | ||
if (typeof offset === 'function') return write(fd, buf, 0, buf.byteLength, null, offset) | ||
if (typeof len === 'function') return write(fd, buf, offset, buf.byteLength - offset, null, len) | ||
if (typeof pos === 'function') return write(fd, buf, offset, len, null, pos) | ||
if (typeof flags === 'string') flags = flagsToNumber(flags) | ||
if (typeof mode === 'string') mode = modeToNumber(mode) | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received ' + cb) | ||
const req = getReq() | ||
req.callback = cb | ||
binding.open(req.handle, path, flags, mode) | ||
} | ||
function writeSync (fd, buf, offset = 0, len = buf.byteLength, pos = 0) { | ||
return binding.writeSync(fd, buf, offset, len, pos) | ||
} | ||
function writev (fd, buffers, pos, cb) { | ||
if (typeof pos === 'function') { | ||
cb = pos | ||
pos = 0 | ||
function openSync (path, flags = 'r', mode = 0o666) { | ||
if (typeof path !== 'string') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received type ' + (typeof path) + ' (' + path + ')') | ||
} | ||
const req = getReq() | ||
if (typeof flags === 'string') flags = flagsToNumber(flags) | ||
if (typeof mode === 'string') mode = modeToNumber(mode) | ||
req.buffers = buffers | ||
req.callback = cb | ||
const res = binding.openSync(path, flags, mode) | ||
if (res < 0) throw createError(res) | ||
binding.writev(req.handle, fd, buffers, pos) | ||
return res | ||
} | ||
function read (fd, buf, offset, len, pos, cb) { | ||
if (typeof cb === 'function') { | ||
const req = getReq() | ||
function close (fd, cb = noop) { | ||
if (typeof fd !== 'number') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'File descriptor must be a number. Received type ' + (typeof fd) + ' (' + fd + ')') | ||
} | ||
req.buffer = buf | ||
req.callback = cb | ||
if (fd < 0 || fd > 0x7fffffff) { | ||
throw typeError('ERR_OUT_OF_RANGE', 'File descriptor is out of range. It must be >= 0 && <= 2147483647. Received ' + fd) | ||
} | ||
binding.read(req.handle, fd, buf, offset, len, pos) | ||
return | ||
if (typeof cb !== 'function') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
if (typeof offset === 'function') return read(fd, buf, 0, buf.byteLength, null, offset) | ||
if (typeof len === 'function') return read(fd, buf, offset, buf.byteLength - offset, null, len) | ||
if (typeof pos === 'function') return read(fd, buf, offset, len, null, pos) | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received ' + cb) | ||
const req = getReq() | ||
req.callback = cb | ||
binding.close(req.handle, fd) | ||
} | ||
function readSync (fd, buf, offset = 0, len = buf.byteLength, pos = 0) { | ||
return binding.readSync(fd, buf, offset, len, pos) | ||
} | ||
function closeSync (fd) { | ||
if (typeof fd !== 'number') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'File descriptor must be a number. Received type ' + (typeof fd) + ' (' + fd + ')') | ||
} | ||
function readv (fd, buffers, pos, cb) { | ||
if (typeof pos === 'function') { | ||
cb = pos | ||
pos = 0 | ||
if (fd < 0 || fd > 0x7fffffff) { | ||
throw typeError('ERR_OUT_OF_RANGE', 'File descriptor is out of range. It must be >= 0 && <= 2147483647. Received ' + fd) | ||
} | ||
const req = getReq() | ||
const res = binding.closeSync(fd) | ||
if (res < 0) throw createError(res) | ||
req.buffers = buffers | ||
req.callback = cb | ||
binding.readv(req.handle, fd, buffers, pos) | ||
return res | ||
} | ||
function open (filename, flags = 'r', mode = 0o666, cb) { | ||
if (typeof filename !== 'string') throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received ' + filename) | ||
function read (fd, buffer, offset, len, pos, cb) { | ||
if (typeof fd !== 'number') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'File descriptor must be a number. Received type ' + (typeof fd) + ' (' + fd + ')') | ||
} | ||
if (typeof flags === 'function') return open(filename, undefined, undefined, flags) | ||
if (typeof mode === 'function') return open(filename, flags, undefined, mode) | ||
if (fd < 0 || fd > 0x7fffffff) { | ||
throw typeError('ERR_OUT_OF_RANGE', 'File descriptor is out of range. It must be >= 0 && <= 2147483647. Received ' + fd) | ||
} | ||
if (typeof cb !== 'function') throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received ' + cb) | ||
if (!Buffer.isBuffer(buffer)) { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Buffer must be a buffer. Received type ' + (typeof buffer) + ' (' + buffer + ')') | ||
} | ||
if (typeof flags === 'string') flags = flagsToNumber(flags) | ||
if (typeof mode === 'string') mode = modeToNumber(mode) | ||
if (typeof cb !== 'function') { | ||
if (typeof offset === 'function') { | ||
cb = offset | ||
offset = 0 | ||
len = buffer.byteLength | ||
pos = -1 | ||
} else if (typeof len === 'function') { | ||
cb = len | ||
len = buffer.byteLength - offset | ||
pos = -1 | ||
} else if (typeof pos === 'function') { | ||
cb = pos | ||
pos = -1 | ||
} else { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
} | ||
if (typeof position !== 'number') pos = -1 | ||
const req = getReq() | ||
req.callback = cb | ||
binding.open(req.handle, filename, flags, mode) | ||
binding.read(req.handle, fd, buffer, offset, len, pos) | ||
} | ||
function openSync (filename, flags = 'r', mode = 0o666) { | ||
if (typeof filename !== 'string') throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received ' + filename) | ||
function readSync (fd, buffer, offset = 0, len = buffer.byteLength - offset, pos = -1) { | ||
if (typeof fd !== 'number') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'File descriptor must be a number. Received type ' + (typeof fd) + ' (' + fd + ')') | ||
} | ||
if (typeof flags === 'string') flags = flagsToNumber(flags) | ||
if (typeof mode === 'string') mode = modeToNumber(mode) | ||
if (fd < 0 || fd > 0x7fffffff) { | ||
throw typeError('ERR_OUT_OF_RANGE', 'File descriptor is out of range. It must be >= 0 && <= 2147483647. Received ' + fd) | ||
} | ||
const res = binding.openSync(filename, flags, mode) | ||
if (!Buffer.isBuffer(buffer)) { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Buffer must be a buffer. Received type ' + (typeof buffer) + ' (' + buffer + ')') | ||
} | ||
if (res < 0) throw createError(res) | ||
return res | ||
return binding.readSync(fd, buffer, offset, len, pos) | ||
} | ||
function close (fd, cb = noop) { | ||
if (typeof fd !== 'number') throw typeError('ERR_INVALID_ARG_TYPE', 'File descriptor must be a number. Received type ' + (typeof fd) + ' (' + fd + ')') | ||
if (typeof cb !== 'function') throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
if (!(fd >= 0 && fd <= 0x7fffffff)) throw typeError('ERR_OUT_OF_RANGE', 'File descriptor is out of range. It must be >= 0 && <= 2147483647. Received ' + fd) | ||
function readv (fd, buffers, pos, cb) { | ||
if (typeof fd !== 'number') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'File descriptor must be a number. Received type ' + (typeof fd) + ' (' + fd + ')') | ||
} | ||
if (fd < 0 || fd > 0x7fffffff) { | ||
throw typeError('ERR_OUT_OF_RANGE', 'File descriptor is out of range. It must be >= 0 && <= 2147483647. Received ' + fd) | ||
} | ||
if (typeof pos === 'function') { | ||
cb = pos | ||
pos = -1 | ||
} else if (typeof cb !== 'function') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
if (typeof position !== 'number') pos = -1 | ||
const req = getReq() | ||
req.callback = cb | ||
binding.close(req.handle, fd) | ||
binding.readv(req.handle, fd, buffers, pos) | ||
} | ||
function closeSync (fd) { | ||
const res = binding.closeSync(fd) | ||
function write (fd, buffer, offset, len, pos, cb) { | ||
if (typeof fd !== 'number') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'File descriptor must be a number. Received type ' + (typeof fd) + ' (' + fd + ')') | ||
} | ||
if (res < 0) throw createError(res) | ||
return res | ||
} | ||
if (fd < 0 || fd > 0x7fffffff) { | ||
throw typeError('ERR_OUT_OF_RANGE', 'File descriptor is out of range. It must be >= 0 && <= 2147483647. Received ' + fd) | ||
} | ||
function ftruncate (fd, len, cb) { | ||
if (!Buffer.isBuffer(buffer)) { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Buffer must be a buffer. Received type ' + (typeof buffer) + ' (' + buffer + ')') | ||
} | ||
if (typeof cb !== 'function') { | ||
if (typeof offset === 'function') { | ||
cb = offset | ||
offset = 0 | ||
len = buffer.byteLength | ||
pos = -1 | ||
} else if (typeof len === 'function') { | ||
cb = len | ||
len = buffer.byteLength - offset | ||
pos = -1 | ||
} else if (typeof pos === 'function') { | ||
cb = pos | ||
pos = -1 | ||
} else { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
} | ||
if (typeof position !== 'number') pos = -1 | ||
const req = getReq() | ||
req.callback = cb | ||
binding.ftruncate(req.handle, fd, len) | ||
binding.write(req.handle, fd, buffer, offset, len, pos) | ||
} | ||
class Stats { | ||
constructor (buf) { | ||
const view = new Uint32Array(buf.buffer, buf.byteOffset, 32) | ||
function writeSync (fd, buffer, offset = 0, len = buffer.byteLength - offset, pos = -1) { | ||
if (typeof fd !== 'number') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'File descriptor must be a number. Received type ' + (typeof fd) + ' (' + fd + ')') | ||
} | ||
this.dev = toNumber(view, 0) | ||
this.mode = toNumber(view, 2) | ||
this.nlink = toNumber(view, 4) | ||
this.uid = toNumber(view, 6) | ||
this.gid = toNumber(view, 8) | ||
this.rdev = toNumber(view, 10) | ||
this.ino = toNumber(view, 12) | ||
this.size = toNumber(view, 14) | ||
this.blksize = toNumber(view, 16) | ||
this.blocks = toNumber(view, 18) | ||
this.flags = toNumber(view, 20) | ||
this.gen = toNumber(view, 22) | ||
this.atimeMs = toNumber(view, 24) | ||
this.mtimeMs = toNumber(view, 26) | ||
this.ctimeMs = toNumber(view, 28) | ||
this.birthtimeMs = toNumber(view, 30) | ||
this.atime = new Date(this.atimeMs) | ||
this.mtime = new Date(this.mtimeMs) | ||
this.ctime = new Date(this.ctimeMs) | ||
this.birthtime = new Date(this.birthtimeMs) | ||
if (fd < 0 || fd > 0x7fffffff) { | ||
throw typeError('ERR_OUT_OF_RANGE', 'File descriptor is out of range. It must be >= 0 && <= 2147483647. Received ' + fd) | ||
} | ||
isDirectory () { | ||
return (this.mode & constants.S_IFMT) === constants.S_IFDIR | ||
if (!Buffer.isBuffer(buffer)) { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Buffer must be a buffer. Received type ' + (typeof buffer) + ' (' + buffer + ')') | ||
} | ||
isFile () { | ||
return (this.mode & constants.S_IFMT) === constants.S_IFREG | ||
return binding.writeSync(fd, buffer, offset, len, pos) | ||
} | ||
function writev (fd, buffers, pos, cb) { | ||
if (typeof fd !== 'number') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'File descriptor must be a number. Received type ' + (typeof fd) + ' (' + fd + ')') | ||
} | ||
isBlockDevice () { | ||
return (this.mode & constants.S_IFMT) === constants.S_IFBLK | ||
if (fd < 0 || fd > 0x7fffffff) { | ||
throw typeError('ERR_OUT_OF_RANGE', 'File descriptor is out of range. It must be >= 0 && <= 2147483647. Received ' + fd) | ||
} | ||
isCharacterDevice () { | ||
return (this.mode & constants.S_IFCHR) === constants.S_IFCHR | ||
if (typeof pos === 'function') { | ||
cb = pos | ||
pos = -1 | ||
} else if (typeof cb !== 'function') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
isFIFO () { | ||
return (this.mode & constants.S_IFMT) === constants.S_IFIFO | ||
if (typeof position !== 'number') pos = -1 | ||
const req = getReq() | ||
req.callback = cb | ||
binding.writev(req.handle, fd, buffers, pos) | ||
} | ||
function stat (path, cb) { | ||
if (typeof path !== 'string') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received type ' + (typeof path) + ' (' + path + ')') | ||
} | ||
isSymbolicLink () { | ||
return (this.mode & constants.S_IFMT) === constants.S_IFLNK | ||
if (typeof cb !== 'function') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
isSocket () { | ||
return (this.mode & constants.S_IFMT) === constants.S_IFSOCK | ||
const data = { | ||
dev: 0, | ||
mode: 0, | ||
nlink: 0, | ||
uid: 0, | ||
gid: 0, | ||
rdev: 0, | ||
ino: 0, | ||
size: 0, | ||
blksize: 0, | ||
blocks: 0, | ||
flags: 0, | ||
gen: 0, | ||
atim: 0, | ||
mtim: 0, | ||
ctim: 0, | ||
birthtim: 0 | ||
} | ||
} | ||
function toNumber (view, n) { | ||
return LE ? view[n] + view[n + 1] * 0x100000000 : view[n] * 0x100000000 + view[n + 1] | ||
} | ||
function stat (path, cb) { | ||
const req = getReq() | ||
req.buffer = Buffer.allocUnsafe(16 * 8) | ||
req.callback = function (err, _, buf) { | ||
req.callback = function (err, _) { | ||
if (err) cb(err, null) | ||
else cb(null, new Stats(buf)) | ||
else cb(null, new Stats(data)) | ||
} | ||
binding.stat(req.handle, path, req.buffer) | ||
binding.stat(req.handle, path, data) | ||
} | ||
function statSync (path) { | ||
const buffer = Buffer.allocUnsafe(16 * 8) | ||
const res = binding.statSync(path, buffer) | ||
if (typeof path !== 'string') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received type ' + (typeof path) + ' (' + path + ')') | ||
} | ||
const data = { | ||
dev: 0, | ||
mode: 0, | ||
nlink: 0, | ||
uid: 0, | ||
gid: 0, | ||
rdev: 0, | ||
ino: 0, | ||
size: 0, | ||
blksize: 0, | ||
blocks: 0, | ||
flags: 0, | ||
gen: 0, | ||
atim: 0, | ||
mtim: 0, | ||
ctim: 0, | ||
birthtim: 0 | ||
} | ||
const res = binding.statSync(path, data) | ||
if (res < 0) throw createError(res) | ||
return new Stats(buffer) | ||
return new Stats(data) | ||
} | ||
function lstat (path, cb) { | ||
if (typeof path !== 'string') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received type ' + (typeof path) + ' (' + path + ')') | ||
} | ||
if (typeof cb !== 'function') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
const data = { | ||
dev: 0, | ||
mode: 0, | ||
nlink: 0, | ||
uid: 0, | ||
gid: 0, | ||
rdev: 0, | ||
ino: 0, | ||
size: 0, | ||
blksize: 0, | ||
blocks: 0, | ||
flags: 0, | ||
gen: 0, | ||
atim: 0, | ||
mtim: 0, | ||
ctim: 0, | ||
birthtim: 0 | ||
} | ||
const req = getReq() | ||
req.buffer = Buffer.allocUnsafe(16 * 8) | ||
req.callback = function (err, _, buf) { | ||
req.callback = function (err, _) { | ||
if (err) cb(err, null) | ||
else cb(null, new Stats(buf)) | ||
else cb(null, new Stats(data)) | ||
} | ||
binding.lstat(req.handle, path, req.buffer) | ||
binding.lstat(req.handle, path, data) | ||
} | ||
function lstatSync (path) { | ||
const buffer = Buffer.allocUnsafe(16 * 8) | ||
const res = binding.lstatSync(path, buffer) | ||
if (typeof path !== 'string') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received type ' + (typeof path) + ' (' + path + ')') | ||
} | ||
const data = { | ||
dev: 0, | ||
mode: 0, | ||
nlink: 0, | ||
uid: 0, | ||
gid: 0, | ||
rdev: 0, | ||
ino: 0, | ||
size: 0, | ||
blksize: 0, | ||
blocks: 0, | ||
flags: 0, | ||
gen: 0, | ||
atim: 0, | ||
mtim: 0, | ||
ctim: 0, | ||
birthtim: 0 | ||
} | ||
const res = binding.lstatSync(path, data) | ||
if (res < 0) throw createError(res) | ||
return new Stats(buffer) | ||
return new Stats(data) | ||
} | ||
function fstat (fd, cb) { | ||
if (typeof fd !== 'number') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'File descriptor must be a number. Received type ' + (typeof fd) + ' (' + fd + ')') | ||
} | ||
if (fd < 0 || fd > 0x7fffffff) { | ||
throw typeError('ERR_OUT_OF_RANGE', 'File descriptor is out of range. It must be >= 0 && <= 2147483647. Received ' + fd) | ||
} | ||
if (typeof cb !== 'function') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
const data = { | ||
dev: 0, | ||
mode: 0, | ||
nlink: 0, | ||
uid: 0, | ||
gid: 0, | ||
rdev: 0, | ||
ino: 0, | ||
size: 0, | ||
blksize: 0, | ||
blocks: 0, | ||
flags: 0, | ||
gen: 0, | ||
atim: 0, | ||
mtim: 0, | ||
ctim: 0, | ||
birthtim: 0 | ||
} | ||
const req = getReq() | ||
req.buffer = Buffer.allocUnsafe(16 * 8) | ||
req.callback = function (err, _, buf) { | ||
req.callback = function (err, _) { | ||
if (err) cb(err, null) | ||
else cb(null, new Stats(buf)) | ||
else cb(null, new Stats(data)) | ||
} | ||
binding.fstat(req.handle, fd, req.buffer) | ||
binding.fstat(req.handle, fd, data) | ||
} | ||
function fstatSync (fd) { | ||
const buffer = Buffer.allocUnsafe(16 * 8) | ||
const res = binding.fstatSync(fd, buffer) | ||
if (typeof fd !== 'number') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'File descriptor must be a number. Received type ' + (typeof fd) + ' (' + fd + ')') | ||
} | ||
if (fd < 0 || fd > 0x7fffffff) { | ||
throw typeError('ERR_OUT_OF_RANGE', 'File descriptor is out of range. It must be >= 0 && <= 2147483647. Received ' + fd) | ||
} | ||
const data = { | ||
dev: 0, | ||
mode: 0, | ||
nlink: 0, | ||
uid: 0, | ||
gid: 0, | ||
rdev: 0, | ||
ino: 0, | ||
size: 0, | ||
blksize: 0, | ||
blocks: 0, | ||
flags: 0, | ||
gen: 0, | ||
atim: 0, | ||
mtim: 0, | ||
ctim: 0, | ||
birthtim: 0 | ||
} | ||
const res = binding.fstatSync(fd, data) | ||
if (res < 0) throw createError(res) | ||
return new Stats(buffer) | ||
return new Stats(data) | ||
} | ||
function ftruncate (fd, len, cb) { | ||
if (typeof fd !== 'number') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'File descriptor must be a number. Received type ' + (typeof fd) + ' (' + fd + ')') | ||
} | ||
if (fd < 0 || fd > 0x7fffffff) { | ||
throw typeError('ERR_OUT_OF_RANGE', 'File descriptor is out of range. It must be >= 0 && <= 2147483647. Received ' + fd) | ||
} | ||
if (typeof len === 'function') { | ||
cb = len | ||
len = 0 | ||
} else if (typeof cb !== 'function') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
const req = getReq() | ||
req.callback = cb | ||
binding.ftruncate(req.handle, fd, len) | ||
} | ||
function mkdirp (path, mode, cb) { | ||
@@ -415,25 +636,22 @@ mkdir(path, { mode }, function (err) { | ||
function rename (src, dst, cb) { | ||
const req = getReq() | ||
function mkdir (path, opts, cb) { | ||
if (typeof path !== 'string') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received type ' + (typeof path) + ' (' + path + ')') | ||
} | ||
req.callback = cb | ||
binding.rename(req.handle, src, dst) | ||
} | ||
function mkdir (path, opts, cb) { | ||
if (typeof opts === 'function') { | ||
cb = opts | ||
opts = { mode: 0o777 } | ||
} else if (typeof cb !== 'function') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
if (!opts) opts = {} | ||
if (typeof opts === 'number') opts = { mode: opts } | ||
else if (!opts) opts = {} | ||
const mode = typeof opts.mode === 'number' ? opts.mode : 0o777 | ||
if (opts.recursive) { | ||
return mkdirp(path, mode, cb) | ||
} | ||
if (opts.recursive) return mkdirp(path, mode, cb) | ||
const req = getReq() | ||
req.callback = cb | ||
@@ -444,4 +662,11 @@ binding.mkdir(req.handle, path, mode) | ||
function rmdir (path, cb) { | ||
if (typeof path !== 'string') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received type ' + (typeof path) + ' (' + path + ')') | ||
} | ||
if (typeof cb !== 'function') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
const req = getReq() | ||
req.callback = cb | ||
@@ -452,4 +677,11 @@ binding.rmdir(req.handle, path) | ||
function unlink (path, cb) { | ||
if (typeof path !== 'string') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received type ' + (typeof path) + ' (' + path + ')') | ||
} | ||
if (typeof cb !== 'function') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
const req = getReq() | ||
req.callback = cb | ||
@@ -459,7 +691,34 @@ binding.unlink(req.handle, path) | ||
function rename (src, dst, cb) { | ||
if (typeof src !== 'string') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received type ' + (typeof src) + ' (' + src + ')') | ||
} | ||
if (typeof dst !== 'string') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received type ' + (typeof dst) + ' (' + dst + ')') | ||
} | ||
if (typeof cb !== 'function') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
const req = getReq() | ||
req.callback = cb | ||
binding.rename(req.handle, src, dst) | ||
} | ||
function readlink (path, opts, cb) { | ||
if (typeof opts === 'function') return readlink(path, null, opts) | ||
if (typeof cb !== 'function') throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function') | ||
if (typeof path !== 'string') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received type ' + (typeof path) + ' (' + path + ')') | ||
} | ||
if (typeof opts === 'function') { | ||
cb = opts | ||
opts = {} | ||
} else if (typeof cb !== 'function') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
if (typeof opts === 'string') opts = { encoding: opts } | ||
if (!opts) opts = {} | ||
else if (!opts) opts = {} | ||
@@ -470,22 +729,87 @@ const { | ||
const data = Buffer.allocUnsafe(binding.sizeofFSPath) | ||
const req = getReq() | ||
req.buffer = Buffer.allocUnsafe(4097) | ||
req.callback = function (err, _) { | ||
if (err) return cb(err, null) | ||
let path = data.subarray(0, data.indexOf(0)) | ||
if (encoding !== 'buffer') path = path.toString(encoding) | ||
cb(null, path) | ||
} | ||
req.callback = function (err, _, buf) { | ||
binding.readlink(req.handle, path, data) | ||
} | ||
function opendir (path, opts, cb) { | ||
if (typeof path !== 'string') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received type ' + (typeof path) + ' (' + path + ')') | ||
} | ||
if (typeof opts === 'function') { | ||
cb = opts | ||
opts = {} | ||
} else if (typeof cb !== 'function') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
if (typeof opts === 'string') opts = { encoding: opts } | ||
else if (!opts) opts = {} | ||
const data = Buffer.allocUnsafe(binding.sizeofFSDir) | ||
const req = getReq() | ||
req.callback = function (err, _) { | ||
if (err) return cb(err, null) | ||
buf = buf.subarray(0, buf.indexOf(0)) | ||
if (encoding !== 'buffer') return cb(null, Buffer.coerce(buf).toString(encoding)) | ||
cb(null, buf) | ||
cb(null, new Dir(path, data, opts)) | ||
} | ||
binding.readlink(req.handle, path, req.buffer) | ||
binding.opendir(req.handle, path, data) | ||
} | ||
function readFile (path, opts, cb) { | ||
if (typeof opts === 'function') return readFile(path, null, opts) | ||
if (typeof cb !== 'function') throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function') | ||
function readdir (path, opts, cb) { | ||
if (typeof path !== 'string') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received type ' + (typeof path) + ' (' + path + ')') | ||
} | ||
if (typeof opts === 'function') { | ||
cb = opts | ||
opts = {} | ||
} else if (typeof cb !== 'function') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
if (typeof opts === 'string') opts = { encoding: opts } | ||
if (!opts) opts = {} | ||
opendir(path, opts, async (err, dir) => { | ||
if (err) return cb(err, null) | ||
const result = [] | ||
dir | ||
.on('data', (entry) => result.push(entry)) | ||
.on('error', (err) => cb(err, null)) | ||
.on('end', () => cb(null, result)) | ||
}) | ||
} | ||
function readFile (path, opts, cb) { | ||
if (typeof path !== 'string') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received type ' + (typeof path) + ' (' + path + ')') | ||
} | ||
if (typeof opts === 'function') { | ||
cb = opts | ||
opts = {} | ||
} else if (typeof cb !== 'function') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
if (typeof opts === 'string') opts = { encoding: opts } | ||
else if (!opts) opts = {} | ||
const { | ||
encoding = 'buffer' | ||
} = opts | ||
open(path, opts.flag || 'r', function (err, fd) { | ||
@@ -497,6 +821,6 @@ if (err) return cb(err) | ||
let buf = Buffer.allocUnsafe(st.size) | ||
let buffer = Buffer.allocUnsafe(st.size) | ||
let len = 0 | ||
read(fd, buf, loop) | ||
read(fd, buffer, loop) | ||
@@ -506,12 +830,12 @@ function loop (err, r) { | ||
len += r | ||
if (r === 0 || len === buf.byteLength) return done() | ||
read(fd, buf.subarray(len), loop) | ||
if (r === 0 || len === buffer.byteLength) return done() | ||
read(fd, buffer.subarray(len), loop) | ||
} | ||
function done () { | ||
if (len !== buf.byteLength) buf = buf.subarray(0, len) | ||
if (len !== buffer.byteLength) buffer = buffer.subarray(0, len) | ||
close(fd, function (err) { | ||
if (err) return cb(err) | ||
if (opts.encoding) return cb(null, buf.toString(opts.encoding)) | ||
return cb(null, buf) | ||
if (encoding !== 'buffer') buffer = buffer.toString(encoding) | ||
cb(null, buffer) | ||
}) | ||
@@ -530,5 +854,13 @@ } | ||
function readFileSync (path, opts) { | ||
if (typeof path !== 'string') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received type ' + (typeof path) + ' (' + path + ')') | ||
} | ||
if (typeof opts === 'string') opts = { encoding: opts } | ||
if (!opts) opts = {} | ||
else if (!opts) opts = {} | ||
const { | ||
encoding = 'buffer' | ||
} = opts | ||
const fd = openSync(path, opts.flag || 'r') | ||
@@ -539,14 +871,14 @@ | ||
let buf = Buffer.allocUnsafe(st.size) | ||
let buffer = Buffer.allocUnsafe(st.size) | ||
let len = 0 | ||
while (true) { | ||
const r = readSync(fd, len ? buf.subarray(len) : buf) | ||
const r = readSync(fd, len ? buffer.subarray(len) : buffer) | ||
len += r | ||
if (r === 0 || len === buf.byteLength) break | ||
if (r === 0 || len === buffer.byteLength) break | ||
} | ||
if (len !== buf.byteLength) buf = buf.subarray(0, len) | ||
if (opts.encoding) return Buffer.coerce(buf).toString(opts.encoding) | ||
return buf | ||
if (len !== buffer.byteLength) buffer = buffer.subarray(0, len) | ||
if (encoding !== 'buffer') buffer = buffer.toString(encoding) | ||
return buffer | ||
} finally { | ||
@@ -560,12 +892,22 @@ try { | ||
function writeFile (path, data, opts, cb) { | ||
if (typeof opts === 'function') return writeFile(path, data, null, opts) | ||
if (typeof cb !== 'function') throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function') | ||
if (typeof data !== 'string' && !Buffer.isBuffer(data)) throw typeError('ERR_INVALID_ARG_TYPE', 'The data argument must be of type string or buffer') | ||
if (typeof opts === 'string') opts = { encoding: opts } | ||
if (!opts) opts = {} | ||
if (typeof path !== 'string') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received type ' + (typeof path) + ' (' + path + ')') | ||
} | ||
if (opts.encoding || typeof data === 'string') { | ||
data = Buffer.from(data, opts.encoding) | ||
if (typeof data !== 'string' && !Buffer.isBuffer(data)) { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Data must be a string or buffer. Received type ' + (typeof data) + ' (' + data + ')') | ||
} | ||
if (typeof opts === 'function') { | ||
cb = opts | ||
opts = {} | ||
} else if (typeof cb !== 'function') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Callback must be a function. Received type ' + (typeof cb) + ' (' + cb + ')') | ||
} | ||
if (typeof opts === 'string') opts = { encoding: opts } | ||
else if (!opts) opts = {} | ||
if (typeof data === 'string') data = Buffer.from(data, opts.encoding) | ||
open(path, opts.flag || 'w', opts.mode, function (err, fd) { | ||
@@ -597,10 +939,16 @@ if (err) return cb(err) | ||
function writeFileSync (path, buf, opts) { | ||
if (typeof opts === 'string') opts = { encoding: opts } | ||
if (!opts) opts = {} | ||
function writeFileSync (path, data, opts) { | ||
if (typeof path !== 'string') { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Path must be a string. Received type ' + (typeof path) + ' (' + path + ')') | ||
} | ||
if (opts.encoding || typeof buf === 'string') { | ||
buf = Buffer.from(buf, opts.encoding) | ||
if (typeof data !== 'string' && !Buffer.isBuffer(data)) { | ||
throw typeError('ERR_INVALID_ARG_TYPE', 'Data must be a string or buffer. Received type ' + (typeof data) + ' (' + data + ')') | ||
} | ||
if (typeof opts === 'string') opts = { encoding: opts } | ||
else if (!opts) opts = {} | ||
if (typeof data === 'string') data = Buffer.from(data, opts.encoding) | ||
const fd = openSync(path, opts.flag || 'w', opts.mode) | ||
@@ -610,5 +958,6 @@ | ||
let len = 0 | ||
while (true) { | ||
len += writeSync(fd, len ? buf.subarray(len) : buf) | ||
if (len === buf.byteLength) break | ||
len += writeSync(fd, len ? data.subarray(len) : data) | ||
if (len === data.byteLength) break | ||
} | ||
@@ -622,2 +971,55 @@ } finally { | ||
class Stats { | ||
constructor (props) { | ||
this.dev = props.dev | ||
this.mode = props.mode | ||
this.nlink = props.nlink | ||
this.uid = props.uid | ||
this.gid = props.gid | ||
this.rdev = props.rdev | ||
this.ino = props.ino | ||
this.size = props.size | ||
this.blksize = props.blksize | ||
this.blocks = props.blocks | ||
this.flags = props.flags | ||
this.gen = props.gen | ||
this.atimeMs = props.atim | ||
this.mtimeMs = props.mtim | ||
this.ctimeMs = props.ctim | ||
this.birthtimeMs = props.birthtim | ||
this.atime = new Date(props.atim) | ||
this.mtime = new Date(props.mtim) | ||
this.ctime = new Date(props.ctim) | ||
this.birthtime = new Date(props.birthtim) | ||
} | ||
isDirectory () { | ||
return (this.mode & constants.S_IFMT) === constants.S_IFDIR | ||
} | ||
isFile () { | ||
return (this.mode & constants.S_IFMT) === constants.S_IFREG | ||
} | ||
isBlockDevice () { | ||
return (this.mode & constants.S_IFMT) === constants.S_IFBLK | ||
} | ||
isCharacterDevice () { | ||
return (this.mode & constants.S_IFCHR) === constants.S_IFCHR | ||
} | ||
isFIFO () { | ||
return (this.mode & constants.S_IFMT) === constants.S_IFIFO | ||
} | ||
isSymbolicLink () { | ||
return (this.mode & constants.S_IFMT) === constants.S_IFLNK | ||
} | ||
isSocket () { | ||
return (this.mode & constants.S_IFMT) === constants.S_IFSOCK | ||
} | ||
} | ||
class FileWriteStream extends Writable { | ||
@@ -726,2 +1128,100 @@ constructor (path, opts = {}) { | ||
class Dir extends Readable { | ||
constructor (path, handle, opts = {}) { | ||
const { | ||
encoding = 'utf8', | ||
bufferSize = 32 | ||
} = opts | ||
super() | ||
this._handle = handle | ||
this._dirents = Buffer.allocUnsafe(binding.sizeofFSDirent * bufferSize) | ||
this._encoding = encoding | ||
this._closed = false | ||
this.path = path | ||
} | ||
_read (cb) { | ||
const self = this | ||
const data = [] | ||
const req = getReq() | ||
req.callback = function (err, _) { | ||
if (err) return cb(err) | ||
if (data.length === 0) self.push(null) | ||
else { | ||
for (const entry of data) { | ||
let name = Buffer.from(entry.name) | ||
if (self._encoding !== 'buffer') name = name.toString(self._encoding) | ||
self.push(new Dirent(self.path, name, entry.type)) | ||
} | ||
} | ||
cb(null) | ||
} | ||
binding.readdir(req.handle, this._handle, this._dirents, data) | ||
} | ||
_destroy (cb) { | ||
if (this._closed) cb(null) | ||
else this.close(cb) | ||
} | ||
close (cb) { | ||
if (this._closed) return | ||
const self = this | ||
const req = getReq() | ||
req.callback = function (err, _) { | ||
if (err) return cb(err) | ||
self._closed = true | ||
cb(null) | ||
} | ||
binding.closedir(req.handle, this._handle) | ||
} | ||
} | ||
class Dirent { | ||
constructor (path, name, type) { | ||
this._type = type | ||
this.path = path | ||
this.name = name | ||
} | ||
isFile () { | ||
return this._type === constants.UV_DIRENT_FILE | ||
} | ||
isDirectory () { | ||
return this._type === constants.UV_DIRENT_DIR | ||
} | ||
isSymbolicLink () { | ||
return this._type === constants.UV_DIRENT_LINK | ||
} | ||
isFIFO () { | ||
return this._type === constants.UV_DIRENT_FIFO | ||
} | ||
isSocket () { | ||
return this._type === constants.UV_DIRENT_SOCKET | ||
} | ||
isCharacterDevice () { | ||
return this._type === constants.UV_DIRENT_CHAR | ||
} | ||
isBlockDevice () { | ||
return this._type === constants.UV_DIRENT_BLOCK | ||
} | ||
} | ||
exports.promises = {} | ||
@@ -743,4 +1243,4 @@ | ||
exports.writev = writev | ||
exports.fstat = fstat | ||
exports.ftruncate = ftruncate | ||
exports.fstat = fstat | ||
@@ -751,21 +1251,12 @@ exports.openSync = openSync | ||
exports.writeSync = writeSync | ||
exports.fstatSync = fstatSync | ||
exports.statSync = statSync | ||
exports.lstatSync = lstatSync | ||
exports.fstatSync = fstatSync | ||
exports.readFileSync = readFileSync | ||
exports.writeFileSync = writeFileSync | ||
exports.stat = stat | ||
exports.promises.stat = promisify(stat) | ||
exports.unlink = unlink | ||
exports.promises.unlink = promisify(unlink) | ||
exports.lstat = lstat | ||
exports.promises.lstat = promisify(lstat) | ||
exports.readFile = readFile | ||
exports.promises.readFile = promisify(readFile) | ||
exports.writeFile = writeFile | ||
exports.promises.writeFile = promisify(writeFile) | ||
exports.rename = rename | ||
exports.promises.rename = promisify(rename) | ||
exports.mkdir = mkdir | ||
@@ -777,18 +1268,37 @@ exports.promises.mkdir = promisify(mkdir) | ||
exports.Stats = Stats // for compat | ||
exports.unlink = unlink | ||
exports.promises.unlink = promisify(unlink) | ||
exports.stat = stat | ||
exports.promises.stat = promisify(stat) | ||
exports.rename = rename | ||
exports.promises.rename = promisify(rename) | ||
exports.lstat = lstat | ||
exports.promises.lstat = promisify(lstat) | ||
exports.readlink = readlink | ||
exports.promises.readlink = promisify(readlink) | ||
exports.opendir = opendir | ||
exports.promises.opendir = promisify(opendir) | ||
exports.readdir = readdir | ||
exports.promises.readdir = promisify(readdir) | ||
exports.readFile = readFile | ||
exports.promises.readFile = promisify(readFile) | ||
exports.writeFile = writeFile | ||
exports.promises.writeFile = promisify(writeFile) | ||
exports.readFileSync = readFileSync | ||
exports.writeFileSync = writeFileSync | ||
exports.Stats = Stats | ||
exports.ReadStream = FileReadStream | ||
exports.createReadStream = (path, options) => new FileReadStream(path, options) | ||
exports.createReadStream = function createReadStream (path, opts) { | ||
return new FileReadStream(path, opts) | ||
} | ||
exports.WriteStream = FileWriteStream | ||
exports.createWriteStream = (path, options) => new FileWriteStream(path, options) | ||
exports.createWriteStream = function createWriteStream (path, opts) { | ||
return new FileWriteStream(path, opts) | ||
} | ||
@@ -806,4 +1316,4 @@ function promisify (fn) { | ||
function map (s) { | ||
return typeof s === 'string' ? Buffer.from(s) : s | ||
function map (data) { | ||
return typeof data === 'string' ? Buffer.from(data) : data | ||
} |
{ | ||
"name": "bare-fs", | ||
"version": "1.5.5", | ||
"version": "1.6.0", | ||
"description": "Native file system for Javascript", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -14,7 +14,6 @@ # bare-fs | ||
// currently supports | ||
// Currently supports: | ||
fs.open | ||
fs.close | ||
fs.unlink | ||
fs.read | ||
@@ -24,10 +23,13 @@ fs.readv | ||
fs.writev | ||
fs.ftruncate | ||
fs.stat | ||
fs.lstat | ||
fs.fstat | ||
fs.lstat | ||
fs.ftruncate | ||
fs.mkdir | ||
fs.rmdir | ||
fs.unlink | ||
fs.rename | ||
fs.readlink | ||
fs.opendir | ||
fs.readdir | ||
@@ -37,9 +39,13 @@ fs.readFile | ||
fs.promises.readFile | ||
fs.promises.writeFile | ||
fs.promises.stat | ||
fs.promises.lstat | ||
fs.promises.mkdir | ||
fs.promises.rmdir | ||
fs.promises.stat | ||
fs.promises.unlink | ||
fs.promises.rename | ||
fs.promises.readlink | ||
fs.promises.opendir | ||
fs.promises.readdir | ||
fs.promises.readFile | ||
fs.promises.writeFile | ||
@@ -49,5 +55,4 @@ fs.createReadStream | ||
fs.writeFileSync | ||
fs.readFileSync | ||
fs.openSync | ||
fs.closeSync | ||
fs.readSync | ||
@@ -58,3 +63,4 @@ fs.writeSync | ||
fs.fstatSync | ||
fs.closeSync | ||
fs.readFileSync | ||
fs.writeFileSync | ||
``` | ||
@@ -61,0 +67,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
81993
1032
66
1