2018-06-28 17:35:20 +00:00
// modules are defined as an array
// [ module function, map of requires ]
//
// map of requires is short require name -> numeric require
//
// anything defined in a previous bundle is accessed via the
// orig method which is the require for previous bundles
// eslint-disable-next-line no-global-assign
parcelRequire = ( function ( modules , cache , entry , globalName ) {
// Save the require from previous bundle to this closure if any
var previousRequire = typeof parcelRequire === 'function' && parcelRequire ;
var nodeRequire = typeof require === 'function' && require ;
function newRequire ( name , jumped ) {
if ( ! cache [ name ] ) {
if ( ! modules [ name ] ) {
// if we cannot find the module within our internal map or
// cache jump to the current global require ie. the last bundle
// that was added to the page.
var currentRequire = typeof parcelRequire === 'function' && parcelRequire ;
if ( ! jumped && currentRequire ) {
return currentRequire ( name , true ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
// If there are other bundles on this page the require from the
// previous one is saved to 'previousRequire'. Repeat this as
// many times as there are bundles until the module is found or
// we exhaust the require chain.
if ( previousRequire ) {
return previousRequire ( name , true ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
// Try the node require function if it exists.
if ( nodeRequire && typeof name === 'string' ) {
return nodeRequire ( name ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
var err = new Error ( 'Cannot find module \'' + name + '\'' ) ;
err . code = 'MODULE_NOT_FOUND' ;
throw err ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
localRequire . resolve = resolve ;
2018-12-21 19:22:25 +00:00
localRequire . cache = { } ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
var module = cache [ name ] = new newRequire . Module ( name ) ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
modules [ name ] [ 0 ] . call ( module . exports , localRequire , module , module . exports , this ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
return cache [ name ] . exports ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function localRequire ( x ) {
return newRequire ( localRequire . resolve ( x ) ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function resolve ( x ) {
return modules [ name ] [ 1 ] [ x ] || x ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function Module ( moduleName ) {
this . id = moduleName ;
this . bundle = newRequire ;
this . exports = { } ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
newRequire . isParcelRequire = true ;
newRequire . Module = Module ;
newRequire . modules = modules ;
newRequire . cache = cache ;
newRequire . parent = previousRequire ;
newRequire . register = function ( id , exports ) {
modules [ id ] = [ function ( require , module ) {
module . exports = exports ;
} , { } ] ;
2014-05-27 18:44:30 +00:00
} ;
2018-06-28 17:35:20 +00:00
for ( var i = 0 ; i < entry . length ; i ++ ) {
newRequire ( entry [ i ] ) ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
if ( entry . length ) {
// Expose entry point to Node, AMD or browser globals
// Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
var mainExports = newRequire ( entry [ entry . length - 1 ] ) ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
// CommonJS
if ( typeof exports === "object" && typeof module !== "undefined" ) {
module . exports = mainExports ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
// RequireJS
} else if ( typeof define === "function" && define . amd ) {
define ( function ( ) {
return mainExports ;
} ) ;
// <script>
} else if ( globalName ) {
this [ globalName ] = mainExports ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
// Override the current require with this new one
return newRequire ;
2018-12-21 19:22:25 +00:00
} ) ( { "0c0E" : [ function ( require , module , exports ) {
2018-10-30 18:35:33 +00:00
"use strict" ;
Object . defineProperty ( exports , "__esModule" , {
value : true
} ) ;
2019-01-03 04:12:19 +00:00
// Symbols is a better way to do this, but not all browsers have good support,
// so instead we'll just make do with a very unlikely string.
var customArgumentsToken = "__ES6-PROMISIFY--CUSTOM-ARGUMENTS__" ;
2018-10-30 18:35:33 +00:00
/ * *
* promisify ( )
* Transforms callback - based function -- func ( arg1 , arg2 . . argN , callback ) -- into
* an ES6 - compatible Promise . Promisify provides a default callback of the form ( error , result )
* and rejects when ` error ` is truthy .
*
* @ param { function } original - The function to promisify
* @ return { function } A promisified version of ` original `
* /
function promisify ( original ) {
// Ensure the argument is a function
if ( typeof original !== "function" ) {
throw new TypeError ( "Argument to promisify must be a function" ) ;
}
// If the user has asked us to decode argument names for them, honour that
var argumentNames = original [ customArgumentsToken ] ;
// If the user has supplied a custom Promise implementation, use it. Otherwise
// fall back to whatever we can find on the global object.
var ES6Promise = promisify . Promise || Promise ;
// If we can find no Promise implemention, then fail now.
if ( typeof ES6Promise !== "function" ) {
throw new Error ( "No Promise implementation found; do you need a polyfill?" ) ;
}
return function ( ) {
var _this = this ;
for ( var _len = arguments . length , args = Array ( _len ) , _key = 0 ; _key < _len ; _key ++ ) {
args [ _key ] = arguments [ _key ] ;
}
return new ES6Promise ( function ( resolve , reject ) {
// Append the callback bound to the context
args . push ( function callback ( err ) {
if ( err ) {
return reject ( err ) ;
}
for ( var _len2 = arguments . length , values = Array ( _len2 > 1 ? _len2 - 1 : 0 ) , _key2 = 1 ; _key2 < _len2 ; _key2 ++ ) {
values [ _key2 - 1 ] = arguments [ _key2 ] ;
}
if ( values . length === 1 || ! argumentNames ) {
return resolve ( values [ 0 ] ) ;
}
var o = { } ;
values . forEach ( function ( value , index ) {
var name = argumentNames [ index ] ;
if ( name ) {
o [ name ] = value ;
}
} ) ;
resolve ( o ) ;
} ) ;
// Call the function.
original . call . apply ( original , [ _this ] . concat ( args ) ) ;
} ) ;
} ;
}
// Attach this symbol to the exported function, so users can use it
promisify . argumentNames = customArgumentsToken ;
promisify . Promise = undefined ;
// Export the public API
exports . promisify = promisify ;
2018-12-21 19:22:25 +00:00
} , { } ] , "pBGv" : [ function ( require , module , exports ) {
// shim for using process in browser
var process = module . exports = { } ; // cached from whatever global is present so that test runners that stub it
// don't break things. But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals. It's inside a
// function because try/catches deoptimize in certain engines.
var cachedSetTimeout ;
var cachedClearTimeout ;
function defaultSetTimout ( ) {
throw new Error ( 'setTimeout has not been defined' ) ;
}
function defaultClearTimeout ( ) {
throw new Error ( 'clearTimeout has not been defined' ) ;
}
( function ( ) {
try {
if ( typeof setTimeout === 'function' ) {
cachedSetTimeout = setTimeout ;
} else {
cachedSetTimeout = defaultSetTimout ;
}
} catch ( e ) {
cachedSetTimeout = defaultSetTimout ;
}
try {
if ( typeof clearTimeout === 'function' ) {
cachedClearTimeout = clearTimeout ;
} else {
cachedClearTimeout = defaultClearTimeout ;
}
} catch ( e ) {
cachedClearTimeout = defaultClearTimeout ;
}
} ) ( ) ;
function runTimeout ( fun ) {
if ( cachedSetTimeout === setTimeout ) {
//normal enviroments in sane situations
return setTimeout ( fun , 0 ) ;
} // if setTimeout wasn't available but was latter defined
if ( ( cachedSetTimeout === defaultSetTimout || ! cachedSetTimeout ) && setTimeout ) {
cachedSetTimeout = setTimeout ;
return setTimeout ( fun , 0 ) ;
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedSetTimeout ( fun , 0 ) ;
} catch ( e ) {
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedSetTimeout . call ( null , fun , 0 ) ;
} catch ( e ) {
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
return cachedSetTimeout . call ( this , fun , 0 ) ;
}
}
}
function runClearTimeout ( marker ) {
if ( cachedClearTimeout === clearTimeout ) {
//normal enviroments in sane situations
return clearTimeout ( marker ) ;
} // if clearTimeout wasn't available but was latter defined
if ( ( cachedClearTimeout === defaultClearTimeout || ! cachedClearTimeout ) && clearTimeout ) {
cachedClearTimeout = clearTimeout ;
return clearTimeout ( marker ) ;
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedClearTimeout ( marker ) ;
} catch ( e ) {
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedClearTimeout . call ( null , marker ) ;
} catch ( e ) {
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
return cachedClearTimeout . call ( this , marker ) ;
}
}
}
var queue = [ ] ;
var draining = false ;
var currentQueue ;
var queueIndex = - 1 ;
function cleanUpNextTick ( ) {
if ( ! draining || ! currentQueue ) {
return ;
}
draining = false ;
if ( currentQueue . length ) {
queue = currentQueue . concat ( queue ) ;
} else {
queueIndex = - 1 ;
}
if ( queue . length ) {
drainQueue ( ) ;
}
}
function drainQueue ( ) {
if ( draining ) {
return ;
}
var timeout = runTimeout ( cleanUpNextTick ) ;
draining = true ;
var len = queue . length ;
while ( len ) {
currentQueue = queue ;
queue = [ ] ;
while ( ++ queueIndex < len ) {
if ( currentQueue ) {
currentQueue [ queueIndex ] . run ( ) ;
}
}
queueIndex = - 1 ;
len = queue . length ;
}
currentQueue = null ;
draining = false ;
runClearTimeout ( timeout ) ;
}
process . nextTick = function ( fun ) {
var args = new Array ( arguments . length - 1 ) ;
if ( arguments . length > 1 ) {
for ( var i = 1 ; i < arguments . length ; i ++ ) {
args [ i - 1 ] = arguments [ i ] ;
}
}
queue . push ( new Item ( fun , args ) ) ;
if ( queue . length === 1 && ! draining ) {
runTimeout ( drainQueue ) ;
}
} ; // v8 likes predictible objects
function Item ( fun , array ) {
this . fun = fun ;
this . array = array ;
}
Item . prototype . run = function ( ) {
this . fun . apply ( null , this . array ) ;
} ;
process . title = 'browser' ;
process . browser = true ;
process . env = { } ;
process . argv = [ ] ;
process . version = '' ; // empty string to avoid regexp issues
process . versions = { } ;
function noop ( ) { }
process . on = noop ;
process . addListener = noop ;
process . once = noop ;
process . off = noop ;
process . removeListener = noop ;
process . removeAllListeners = noop ;
process . emit = noop ;
process . prependListener = noop ;
process . prependOnceListener = noop ;
process . listeners = function ( name ) {
return [ ] ;
} ;
process . binding = function ( name ) {
throw new Error ( 'process.binding is not supported' ) ;
} ;
process . cwd = function ( ) {
return '/' ;
} ;
process . chdir = function ( dir ) {
throw new Error ( 'process.chdir is not supported' ) ;
} ;
process . umask = function ( ) {
return 0 ;
} ;
} , { } ] , "UUq2" : [ function ( require , module , exports ) {
var process = require ( "process" ) ;
2018-06-28 17:35:20 +00:00
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
// resolves . and .. elements in a path array with directory names there
// must be no slashes, empty elements, or device names (c:\) in the array
// (so also no leading and trailing slashes - it does not distinguish
// relative and absolute paths)
function normalizeArray ( parts , allowAboveRoot ) {
// if the path tries to go above the root, `up` ends up > 0
var up = 0 ;
for ( var i = parts . length - 1 ; i >= 0 ; i -- ) {
var last = parts [ i ] ;
if ( last === '.' ) {
parts . splice ( i , 1 ) ;
} else if ( last === '..' ) {
parts . splice ( i , 1 ) ;
up ++ ;
} else if ( up ) {
parts . splice ( i , 1 ) ;
up -- ;
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
// if the path is allowed to go above the root, restore leading ..s
if ( allowAboveRoot ) {
for ( ; up -- ; up ) {
parts . unshift ( '..' ) ;
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
return parts ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
// Split a filename into [root, dir, basename, ext], unix version
// 'root' is just a slash, or nothing.
2018-12-21 19:22:25 +00:00
var splitPathRe =
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/ ;
var splitPath = function ( filename ) {
return splitPathRe . exec ( filename ) . slice ( 1 ) ;
2018-06-28 17:35:20 +00:00
} ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
// path.resolve([from ...], to)
2018-12-21 19:22:25 +00:00
// posix version
exports . resolve = function ( ) {
2018-06-28 17:35:20 +00:00
var resolvedPath = '' ,
resolvedAbsolute = false ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
for ( var i = arguments . length - 1 ; i >= - 1 && ! resolvedAbsolute ; i -- ) {
2018-12-21 19:22:25 +00:00
var path = ( i >= 0 ) ? arguments [ i ] : process . cwd ( ) ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
// Skip empty and invalid entries
2018-12-21 19:22:25 +00:00
if ( typeof path !== 'string' ) {
throw new TypeError ( 'Arguments to path.resolve must be strings' ) ;
} else if ( ! path ) {
2018-06-28 17:35:20 +00:00
continue ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
resolvedPath = path + '/' + resolvedPath ;
resolvedAbsolute = path . charAt ( 0 ) === '/' ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
// Normalize the path
2018-12-21 19:22:25 +00:00
resolvedPath = normalizeArray ( filter ( resolvedPath . split ( '/' ) , function ( p ) {
2018-06-28 17:35:20 +00:00
return ! ! p ;
} ) , ! resolvedAbsolute ) . join ( '/' ) ;
2014-05-27 18:44:30 +00:00
2018-12-21 19:22:25 +00:00
return ( ( resolvedAbsolute ? '/' : '' ) + resolvedPath ) || '.' ;
} ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
// path.normalize(path)
2018-12-21 19:22:25 +00:00
// posix version
exports . normalize = function ( path ) {
var isAbsolute = exports . isAbsolute ( path ) ,
trailingSlash = substr ( path , - 1 ) === '/' ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
// Normalize the path
2018-12-21 19:22:25 +00:00
path = normalizeArray ( filter ( path . split ( '/' ) , function ( p ) {
2018-06-28 17:35:20 +00:00
return ! ! p ;
} ) , ! isAbsolute ) . join ( '/' ) ;
if ( ! path && ! isAbsolute ) {
path = '.' ;
2014-05-27 18:44:30 +00:00
}
2018-12-21 19:22:25 +00:00
if ( path && trailingSlash ) {
path += '/' ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
return ( isAbsolute ? '/' : '' ) + path ;
2018-12-21 19:22:25 +00:00
} ;
// posix version
exports . isAbsolute = function ( path ) {
return path . charAt ( 0 ) === '/' ;
} ;
2018-06-28 17:35:20 +00:00
2018-12-21 19:22:25 +00:00
// posix version
exports . join = function ( ) {
2018-06-28 17:35:20 +00:00
var paths = Array . prototype . slice . call ( arguments , 0 ) ;
2018-12-21 19:22:25 +00:00
return exports . normalize ( filter ( paths , function ( p , index ) {
if ( typeof p !== 'string' ) {
throw new TypeError ( 'Arguments to path.join must be strings' ) ;
}
return p ;
2018-06-28 17:35:20 +00:00
} ) . join ( '/' ) ) ;
2018-12-21 19:22:25 +00:00
} ;
2018-06-28 17:35:20 +00:00
// path.relative(from, to)
2018-12-21 19:22:25 +00:00
// posix version
exports . relative = function ( from , to ) {
from = exports . resolve ( from ) . substr ( 1 ) ;
to = exports . resolve ( to ) . substr ( 1 ) ;
2018-06-28 17:35:20 +00:00
function trim ( arr ) {
var start = 0 ;
for ( ; start < arr . length ; start ++ ) {
if ( arr [ start ] !== '' ) break ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
var end = arr . length - 1 ;
for ( ; end >= 0 ; end -- ) {
if ( arr [ end ] !== '' ) break ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
if ( start > end ) return [ ] ;
return arr . slice ( start , end - start + 1 ) ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
var fromParts = trim ( from . split ( '/' ) ) ;
var toParts = trim ( to . split ( '/' ) ) ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
var length = Math . min ( fromParts . length , toParts . length ) ;
var samePartsLength = length ;
for ( var i = 0 ; i < length ; i ++ ) {
if ( fromParts [ i ] !== toParts [ i ] ) {
samePartsLength = i ;
break ;
}
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
var outputParts = [ ] ;
2018-12-21 19:22:25 +00:00
for ( var i = samePartsLength ; i < fromParts . length ; i ++ ) {
2018-06-28 17:35:20 +00:00
outputParts . push ( '..' ) ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
outputParts = outputParts . concat ( toParts . slice ( samePartsLength ) ) ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
return outputParts . join ( '/' ) ;
2018-12-21 19:22:25 +00:00
} ;
exports . sep = '/' ;
exports . delimiter = ':' ;
2014-06-09 14:40:50 +00:00
2018-12-21 19:22:25 +00:00
exports . dirname = function ( path ) {
2018-06-28 17:35:20 +00:00
var result = splitPath ( path ) ,
root = result [ 0 ] ,
dir = result [ 1 ] ;
2014-06-09 14:40:50 +00:00
2018-06-28 17:35:20 +00:00
if ( ! root && ! dir ) {
// No dirname whatsoever
return '.' ;
}
2014-06-09 14:40:50 +00:00
2018-06-28 17:35:20 +00:00
if ( dir ) {
// It has a dirname, strip trailing slash
dir = dir . substr ( 0 , dir . length - 1 ) ;
}
2014-06-09 14:40:50 +00:00
2018-06-28 17:35:20 +00:00
return root + dir ;
2018-12-21 19:22:25 +00:00
} ;
2014-06-09 14:40:50 +00:00
2018-12-21 19:22:25 +00:00
exports . basename = function ( path , ext ) {
2018-06-28 17:35:20 +00:00
var f = splitPath ( path ) [ 2 ] ;
// TODO: make this comparison case-insensitive on windows?
if ( ext && f . substr ( - 1 * ext . length ) === ext ) {
f = f . substr ( 0 , f . length - ext . length ) ;
}
2018-12-21 19:22:25 +00:00
return f ;
} ;
2014-06-09 14:40:50 +00:00
2018-12-21 19:22:25 +00:00
exports . extname = function ( path ) {
2018-06-28 17:35:20 +00:00
return splitPath ( path ) [ 3 ] ;
2018-12-21 19:22:25 +00:00
} ;
2014-06-09 14:40:50 +00:00
2018-12-21 19:22:25 +00:00
function filter ( xs , f ) {
if ( xs . filter ) return xs . filter ( f ) ;
var res = [ ] ;
for ( var i = 0 ; i < xs . length ; i ++ ) {
if ( f ( xs [ i ] , i , xs ) ) res . push ( xs [ i ] ) ;
}
return res ;
2018-06-28 17:35:20 +00:00
}
2014-06-09 14:40:50 +00:00
2018-12-21 19:22:25 +00:00
// String.prototype.substr - negative index don't work in IE8
var substr = 'ab' . substr ( - 1 ) === 'b'
? function ( str , start , len ) { return str . substr ( start , len ) }
: function ( str , start , len ) {
if ( start < 0 ) start = str . length + start ;
return str . substr ( start , len ) ;
}
;
2014-06-09 14:40:50 +00:00
2018-12-21 19:22:25 +00:00
} , { "process" : "pBGv" } ] , "UzoP" : [ function ( require , module , exports ) {
var process = require ( "process" ) ;
/ * *
* Patch process to add process . cwd ( ) , always giving the root dir .
* NOTE : this line needs to happen * before * we require in ` path ` .
* /
process . cwd = function ( ) {
return '/' ;
} ;
/ * *
* https : //github.com/browserify/path-browserify via Parcel.
* We use is as a base for our own Filer . Path , and patch / add
* a few things we need for the browser environment .
* /
2018-06-28 21:02:50 +00:00
2018-12-21 19:22:25 +00:00
var nodePath = require ( 'path' ) ;
2014-06-09 14:40:50 +00:00
2018-12-21 19:22:25 +00:00
var filerPath = Object . create ( nodePath ) ;
/ * *
* Patch path . basename ( ) to return / v s . ' '
* /
filerPath . basename = function ( path , ext ) {
var basename = nodePath . basename ( path , ext ) ;
return basename === '' ? '/' : basename ;
2014-06-09 14:40:50 +00:00
} ;
2018-10-30 18:35:33 +00:00
/ * *
2018-12-21 19:22:25 +00:00
* Patch path . normalize ( ) to not add a trailing /
2018-10-30 18:35:33 +00:00
* /
2018-12-21 19:22:25 +00:00
filerPath . normalize = function ( path ) {
path = nodePath . normalize ( path ) ;
return path === '/' ? path : filerPath . removeTrailing ( path ) ;
} ;
2018-10-30 18:35:33 +00:00
/ * *
2018-12-21 19:22:25 +00:00
* Add new utility method isNull ( ) to path : check for null paths .
2018-10-30 18:35:33 +00:00
* /
2018-12-21 19:22:25 +00:00
filerPath . isNull = function ( path ) {
return ( '' + path ) . indexOf ( "\0" ) !== - 1 ;
} ;
/ * *
* Add new utility method addTrailing ( ) to add trailing / without doubling to //.
* /
2018-10-30 18:35:33 +00:00
2018-12-21 19:22:25 +00:00
filerPath . addTrailing = function ( path ) {
return path . replace ( /\/*$/ , '/' ) ;
} ;
/ * *
* Add new utility method removeTrailing ( ) to remove trailing / , dealing with multiple
* /
2018-10-30 18:35:33 +00:00
2018-12-21 19:22:25 +00:00
filerPath . removeTrailing = function ( path ) {
path = path . replace ( /\/*$/ , '' ) ;
return path === '' ? '/' : path ;
} ;
module . exports = filerPath ;
2019-02-07 21:38:32 +00:00
} , { "path" : "UUq2" , "process" : "pBGv" } ] , "iJA9" : [ function ( require , module , exports ) {
2018-06-28 17:35:20 +00:00
var O _READ = 'READ' ;
var O _WRITE = 'WRITE' ;
var O _CREATE = 'CREATE' ;
var O _EXCLUSIVE = 'EXCLUSIVE' ;
var O _TRUNCATE = 'TRUNCATE' ;
var O _APPEND = 'APPEND' ;
var XATTR _CREATE = 'CREATE' ;
var XATTR _REPLACE = 'REPLACE' ;
module . exports = {
FILE _SYSTEM _NAME : 'local' ,
FILE _STORE _NAME : 'files' ,
IDB _RO : 'readonly' ,
IDB _RW : 'readwrite' ,
2018-10-30 18:35:33 +00:00
WSQL _VERSION : '1' ,
2018-06-28 17:35:20 +00:00
WSQL _SIZE : 5 * 1024 * 1024 ,
2018-10-30 18:35:33 +00:00
WSQL _DESC : 'FileSystem Storage' ,
2018-07-14 15:21:34 +00:00
NODE _TYPE _FILE : 'FILE' ,
NODE _TYPE _DIRECTORY : 'DIRECTORY' ,
NODE _TYPE _SYMBOLIC _LINK : 'SYMLINK' ,
NODE _TYPE _META : 'META' ,
2018-12-21 19:22:25 +00:00
DEFAULT _DIR _PERMISSIONS : 0x1ED ,
// 755
DEFAULT _FILE _PERMISSIONS : 0x1A4 ,
// 644
FULL _READ _WRITE _EXEC _PERMISSIONS : 0x1FF ,
// 777
READ _WRITE _PERMISSIONS : 0x1B6 ,
/// 666
2018-06-28 17:35:20 +00:00
SYMLOOP _MAX : 10 ,
BINARY _MIME _TYPE : 'application/octet-stream' ,
JSON _MIME _TYPE : 'application/json' ,
2018-12-21 19:22:25 +00:00
ROOT _DIRECTORY _NAME : '/' ,
// basename(normalize(path))
2018-06-28 17:35:20 +00:00
// FS Mount Flags
FS _FORMAT : 'FORMAT' ,
FS _NOCTIME : 'NOCTIME' ,
FS _NOMTIME : 'NOMTIME' ,
FS _NODUPEIDCHECK : 'FS_NODUPEIDCHECK' ,
// FS File Open Flags
O _READ : O _READ ,
O _WRITE : O _WRITE ,
O _CREATE : O _CREATE ,
O _EXCLUSIVE : O _EXCLUSIVE ,
O _TRUNCATE : O _TRUNCATE ,
O _APPEND : O _APPEND ,
O _FLAGS : {
'r' : [ O _READ ] ,
'r+' : [ O _READ , O _WRITE ] ,
'w' : [ O _WRITE , O _CREATE , O _TRUNCATE ] ,
'w+' : [ O _WRITE , O _READ , O _CREATE , O _TRUNCATE ] ,
'wx' : [ O _WRITE , O _CREATE , O _EXCLUSIVE , O _TRUNCATE ] ,
'wx+' : [ O _WRITE , O _READ , O _CREATE , O _EXCLUSIVE , O _TRUNCATE ] ,
'a' : [ O _WRITE , O _CREATE , O _APPEND ] ,
'a+' : [ O _WRITE , O _READ , O _CREATE , O _APPEND ] ,
'ax' : [ O _WRITE , O _CREATE , O _EXCLUSIVE , O _APPEND ] ,
'ax+' : [ O _WRITE , O _READ , O _CREATE , O _EXCLUSIVE , O _APPEND ]
} ,
XATTR _CREATE : XATTR _CREATE ,
XATTR _REPLACE : XATTR _REPLACE ,
FS _READY : 'READY' ,
FS _PENDING : 'PENDING' ,
FS _ERROR : 'ERROR' ,
SUPER _NODE _ID : '00000000-0000-0000-0000-000000000000' ,
// Reserved File Descriptors for streams
STDIN : 0 ,
STDOUT : 1 ,
STDERR : 2 ,
FIRST _DESCRIPTOR : 3 ,
ENVIRONMENT : {
TMP : '/tmp' ,
PATH : ''
2018-07-14 15:21:34 +00:00
} ,
// Duplicate Node's fs.constants
fsConstants : {
O _RDONLY : 0 ,
O _WRONLY : 1 ,
O _RDWR : 2 ,
S _IFMT : 61440 ,
S _IFREG : 32768 ,
S _IFDIR : 16384 ,
S _IFCHR : 8192 ,
S _IFBLK : 24576 ,
S _IFIFO : 4096 ,
S _IFLNK : 40960 ,
S _IFSOCK : 49152 ,
O _CREAT : 512 ,
O _EXCL : 2048 ,
O _NOCTTY : 131072 ,
O _TRUNC : 1024 ,
O _APPEND : 8 ,
O _DIRECTORY : 1048576 ,
O _NOFOLLOW : 256 ,
O _SYNC : 128 ,
O _DSYNC : 4194304 ,
O _SYMLINK : 2097152 ,
O _NONBLOCK : 4 ,
S _IRWXU : 448 ,
S _IRUSR : 256 ,
S _IWUSR : 128 ,
S _IXUSR : 64 ,
S _IRWXG : 56 ,
S _IRGRP : 32 ,
S _IWGRP : 16 ,
S _IXGRP : 8 ,
S _IRWXO : 7 ,
S _IROTH : 4 ,
S _IWOTH : 2 ,
S _IXOTH : 1 ,
F _OK : 0 ,
R _OK : 4 ,
W _OK : 2 ,
X _OK : 1 ,
UV _FS _COPYFILE _EXCL : 1 ,
COPYFILE _EXCL : 1
2018-06-28 17:35:20 +00:00
}
} ;
2018-07-14 15:21:34 +00:00
} , { } ] , "yh9p" : [ function ( require , module , exports ) {
2018-06-28 21:02:50 +00:00
'use strict'
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
exports . byteLength = byteLength
exports . toByteArray = toByteArray
exports . fromByteArray = fromByteArray
var lookup = [ ]
var revLookup = [ ]
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
for ( var i = 0 , len = code . length ; i < len ; ++ i ) {
lookup [ i ] = code [ i ]
revLookup [ code . charCodeAt ( i ) ] = i
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
// Support decoding URL-safe base64 strings, as Node.js does.
// See: https://en.wikipedia.org/wiki/Base64#URL_applications
revLookup [ '-' . charCodeAt ( 0 ) ] = 62
revLookup [ '_' . charCodeAt ( 0 ) ] = 63
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
function getLens ( b64 ) {
var len = b64 . length
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
if ( len % 4 > 0 ) {
throw new Error ( 'Invalid string. Length must be a multiple of 4' )
2015-06-29 16:29:46 +00:00
}
2015-05-31 15:18:20 +00:00
2018-06-28 21:02:50 +00:00
// Trim off extra bytes after placeholder bytes are found
// See: https://github.com/beatgammit/base64-js/issues/42
var validLen = b64 . indexOf ( '=' )
if ( validLen === - 1 ) validLen = len
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
var placeHoldersLen = validLen === len
? 0
: 4 - ( validLen % 4 )
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
return [ validLen , placeHoldersLen ]
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
// base64 is 4/3 + up to two characters of the original data
function byteLength ( b64 ) {
var lens = getLens ( b64 )
var validLen = lens [ 0 ]
var placeHoldersLen = lens [ 1 ]
return ( ( validLen + placeHoldersLen ) * 3 / 4 ) - placeHoldersLen
2015-06-29 16:29:46 +00:00
}
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
function _byteLength ( b64 , validLen , placeHoldersLen ) {
return ( ( validLen + placeHoldersLen ) * 3 / 4 ) - placeHoldersLen
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
function toByteArray ( b64 ) {
var tmp
var lens = getLens ( b64 )
var validLen = lens [ 0 ]
var placeHoldersLen = lens [ 1 ]
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
var arr = new Arr ( _byteLength ( b64 , validLen , placeHoldersLen ) )
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
var curByte = 0
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
// if there are placeholders, only get up to the last complete 4 chars
var len = placeHoldersLen > 0
? validLen - 4
: validLen
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
for ( var i = 0 ; i < len ; i += 4 ) {
tmp =
( revLookup [ b64 . charCodeAt ( i ) ] << 18 ) |
( revLookup [ b64 . charCodeAt ( i + 1 ) ] << 12 ) |
( revLookup [ b64 . charCodeAt ( i + 2 ) ] << 6 ) |
revLookup [ b64 . charCodeAt ( i + 3 ) ]
arr [ curByte ++ ] = ( tmp >> 16 ) & 0xFF
arr [ curByte ++ ] = ( tmp >> 8 ) & 0xFF
arr [ curByte ++ ] = tmp & 0xFF
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
if ( placeHoldersLen === 2 ) {
tmp =
( revLookup [ b64 . charCodeAt ( i ) ] << 2 ) |
( revLookup [ b64 . charCodeAt ( i + 1 ) ] >> 4 )
arr [ curByte ++ ] = tmp & 0xFF
2014-06-10 18:53:04 +00:00
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
if ( placeHoldersLen === 1 ) {
tmp =
( revLookup [ b64 . charCodeAt ( i ) ] << 10 ) |
( revLookup [ b64 . charCodeAt ( i + 1 ) ] << 4 ) |
( revLookup [ b64 . charCodeAt ( i + 2 ) ] >> 2 )
arr [ curByte ++ ] = ( tmp >> 8 ) & 0xFF
arr [ curByte ++ ] = tmp & 0xFF
}
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
return arr
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
function tripletToBase64 ( num ) {
return lookup [ num >> 18 & 0x3F ] +
lookup [ num >> 12 & 0x3F ] +
lookup [ num >> 6 & 0x3F ] +
lookup [ num & 0x3F ]
2015-05-31 15:18:20 +00:00
}
2018-06-28 21:02:50 +00:00
function encodeChunk ( uint8 , start , end ) {
var tmp
var output = [ ]
for ( var i = start ; i < end ; i += 3 ) {
tmp =
( ( uint8 [ i ] << 16 ) & 0xFF0000 ) +
( ( uint8 [ i + 1 ] << 8 ) & 0xFF00 ) +
( uint8 [ i + 2 ] & 0xFF )
output . push ( tripletToBase64 ( tmp ) )
}
return output . join ( '' )
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
function fromByteArray ( uint8 ) {
var tmp
var len = uint8 . length
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
var parts = [ ]
var maxChunkLength = 16383 // must be multiple of 3
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
// go through the array every three bytes, we'll deal with trailing stuff later
for ( var i = 0 , len2 = len - extraBytes ; i < len2 ; i += maxChunkLength ) {
parts . push ( encodeChunk (
uint8 , i , ( i + maxChunkLength ) > len2 ? len2 : ( i + maxChunkLength )
) )
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
// pad the end with zeros, but make sure to not forget the extra bytes
if ( extraBytes === 1 ) {
tmp = uint8 [ len - 1 ]
parts . push (
lookup [ tmp >> 2 ] +
lookup [ ( tmp << 4 ) & 0x3F ] +
'=='
)
} else if ( extraBytes === 2 ) {
tmp = ( uint8 [ len - 2 ] << 8 ) + uint8 [ len - 1 ]
parts . push (
lookup [ tmp >> 10 ] +
lookup [ ( tmp >> 4 ) & 0x3F ] +
lookup [ ( tmp << 2 ) & 0x3F ] +
'='
)
2015-05-31 15:18:20 +00:00
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
return parts . join ( '' )
2015-05-31 15:18:20 +00:00
}
2014-06-10 18:53:04 +00:00
2018-07-14 15:21:34 +00:00
} , { } ] , "JgNJ" : [ function ( require , module , exports ) {
2018-06-28 21:02:50 +00:00
exports . read = function ( buffer , offset , isLE , mLen , nBytes ) {
var e , m
var eLen = ( nBytes * 8 ) - mLen - 1
var eMax = ( 1 << eLen ) - 1
var eBias = eMax >> 1
var nBits = - 7
var i = isLE ? ( nBytes - 1 ) : 0
var d = isLE ? - 1 : 1
var s = buffer [ offset + i ]
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
i += d
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
e = s & ( ( 1 << ( - nBits ) ) - 1 )
s >>= ( - nBits )
nBits += eLen
for ( ; nBits > 0 ; e = ( e * 256 ) + buffer [ offset + i ] , i += d , nBits -= 8 ) { }
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
m = e & ( ( 1 << ( - nBits ) ) - 1 )
e >>= ( - nBits )
nBits += mLen
for ( ; nBits > 0 ; m = ( m * 256 ) + buffer [ offset + i ] , i += d , nBits -= 8 ) { }
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
if ( e === 0 ) {
e = 1 - eBias
} else if ( e === eMax ) {
return m ? NaN : ( ( s ? - 1 : 1 ) * Infinity )
} else {
m = m + Math . pow ( 2 , mLen )
e = e - eBias
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
return ( s ? - 1 : 1 ) * m * Math . pow ( 2 , e - mLen )
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
exports . write = function ( buffer , value , offset , isLE , mLen , nBytes ) {
var e , m , c
var eLen = ( nBytes * 8 ) - mLen - 1
var eMax = ( 1 << eLen ) - 1
var eBias = eMax >> 1
var rt = ( mLen === 23 ? Math . pow ( 2 , - 24 ) - Math . pow ( 2 , - 77 ) : 0 )
var i = isLE ? 0 : ( nBytes - 1 )
var d = isLE ? 1 : - 1
var s = value < 0 || ( value === 0 && 1 / value < 0 ) ? 1 : 0
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
value = Math . abs ( value )
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
if ( isNaN ( value ) || value === Infinity ) {
m = isNaN ( value ) ? 1 : 0
e = eMax
} else {
e = Math . floor ( Math . log ( value ) / Math . LN2 )
if ( value * ( c = Math . pow ( 2 , - e ) ) < 1 ) {
e --
c *= 2
}
if ( e + eBias >= 1 ) {
value += rt / c
} else {
value += rt * Math . pow ( 2 , 1 - eBias )
}
if ( value * c >= 2 ) {
e ++
c /= 2
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
if ( e + eBias >= eMax ) {
m = 0
e = eMax
} else if ( e + eBias >= 1 ) {
m = ( ( value * c ) - 1 ) * Math . pow ( 2 , mLen )
e = e + eBias
} else {
m = value * Math . pow ( 2 , eBias - 1 ) * Math . pow ( 2 , mLen )
e = 0
}
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
for ( ; mLen >= 8 ; buffer [ offset + i ] = m & 0xff , i += d , m /= 256 , mLen -= 8 ) { }
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
e = ( e << mLen ) | m
eLen += mLen
for ( ; eLen > 0 ; buffer [ offset + i ] = e & 0xff , i += d , e /= 256 , eLen -= 8 ) { }
buffer [ offset + i - d ] |= s * 128
2015-05-31 15:18:20 +00:00
}
2018-07-14 15:21:34 +00:00
} , { } ] , "REa7" : [ function ( require , module , exports ) {
2018-06-28 21:02:50 +00:00
var toString = { } . toString ;
module . exports = Array . isArray || function ( arr ) {
return toString . call ( arr ) == '[object Array]' ;
} ;
2015-05-31 15:18:20 +00:00
2018-07-14 15:21:34 +00:00
} , { } ] , "dskh" : [ function ( require , module , exports ) {
2015-05-31 15:18:20 +00:00
2018-06-28 21:02:50 +00:00
var global = arguments [ 3 ] ;
/ * !
* The buffer module from node . js , for the browser .
*
* @ author Feross Aboukhadijeh < feross @ feross . org > < http : //feross.org>
* @ license MIT
* /
/* eslint-disable no-proto */
2015-05-31 15:18:20 +00:00
2018-06-28 21:02:50 +00:00
'use strict'
2015-05-31 15:18:20 +00:00
2018-06-28 21:02:50 +00:00
var base64 = require ( 'base64-js' )
var ieee754 = require ( 'ieee754' )
var isArray = require ( 'isarray' )
2015-05-31 15:18:20 +00:00
2018-06-28 21:02:50 +00:00
exports . Buffer = Buffer
exports . SlowBuffer = SlowBuffer
exports . INSPECT _MAX _BYTES = 50
2015-05-31 15:18:20 +00:00
2018-06-28 21:02:50 +00:00
/ * *
* If ` Buffer.TYPED_ARRAY_SUPPORT ` :
* === true Use Uint8Array implementation ( fastest )
* === false Use Object implementation ( most compatible , even IE6 )
*
* Browsers that support typed arrays are IE 10 + , Firefox 4 + , Chrome 7 + , Safari 5.1 + ,
* Opera 11.6 + , iOS 4.2 + .
*
* Due to various browser bugs , sometimes the Object implementation will be used even
* when the browser supports typed arrays .
*
* Note :
*
* - Firefox 4 - 29 lacks support for adding new properties to ` Uint8Array ` instances ,
* See : https : //bugzilla.mozilla.org/show_bug.cgi?id=695438.
*
* - Chrome 9 - 10 is missing the ` TypedArray.prototype.subarray ` function .
*
* - IE10 has a broken ` TypedArray.prototype.subarray ` function which returns arrays of
* incorrect length in some situations .
2015-05-31 15:18:20 +00:00
2018-06-28 21:02:50 +00:00
* We detect these buggy browsers and set ` Buffer.TYPED_ARRAY_SUPPORT ` to ` false ` so they
* get the Object implementation , which is slower but behaves correctly .
* /
Buffer . TYPED _ARRAY _SUPPORT = global . TYPED _ARRAY _SUPPORT !== undefined
? global . TYPED _ARRAY _SUPPORT
: typedArraySupport ( )
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
/ *
* Export kMaxLength after typed array support is determined .
* /
exports . kMaxLength = kMaxLength ( )
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
function typedArraySupport ( ) {
try {
var arr = new Uint8Array ( 1 )
arr . _ _proto _ _ = { _ _proto _ _ : Uint8Array . prototype , foo : function ( ) { return 42 } }
return arr . foo ( ) === 42 && // typed array instances can be augmented
typeof arr . subarray === 'function' && // chrome 9-10 lack `subarray`
arr . subarray ( 1 , 1 ) . byteLength === 0 // ie10 has broken `subarray`
} catch ( e ) {
return false
}
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
function kMaxLength ( ) {
return Buffer . TYPED _ARRAY _SUPPORT
? 0x7fffffff
: 0x3fffffff
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
function createBuffer ( that , length ) {
if ( kMaxLength ( ) < length ) {
throw new RangeError ( 'Invalid typed array length' )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
if ( Buffer . TYPED _ARRAY _SUPPORT ) {
// Return an augmented `Uint8Array` instance, for best performance
that = new Uint8Array ( length )
that . _ _proto _ _ = Buffer . prototype
} else {
// Fallback: Return an object instance of the Buffer class
if ( that === null ) {
that = new Buffer ( length )
}
that . length = length
2014-06-10 18:53:04 +00:00
}
2015-05-31 15:18:20 +00:00
2018-06-28 21:02:50 +00:00
return that
2015-05-31 15:18:20 +00:00
}
2018-06-28 21:02:50 +00:00
/ * *
* The Buffer constructor returns instances of ` Uint8Array ` that have their
* prototype changed to ` Buffer.prototype ` . Furthermore , ` Buffer ` is a subclass of
* ` Uint8Array ` , so the returned instances will have all the node ` Buffer ` methods
* and the ` Uint8Array ` methods . Square bracket notation works as expected -- it
* returns a single octet .
*
* The ` Uint8Array ` prototype remains unmodified .
* /
function Buffer ( arg , encodingOrOffset , length ) {
if ( ! Buffer . TYPED _ARRAY _SUPPORT && ! ( this instanceof Buffer ) ) {
return new Buffer ( arg , encodingOrOffset , length )
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
// Common case.
if ( typeof arg === 'number' ) {
if ( typeof encodingOrOffset === 'string' ) {
throw new Error (
'If encoding is specified then the first argument must be a string'
)
}
return allocUnsafe ( this , arg )
}
return from ( this , arg , encodingOrOffset , length )
2015-05-31 15:18:20 +00:00
}
2018-06-28 21:02:50 +00:00
Buffer . poolSize = 8192 // not used by this implementation
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
// TODO: Legacy, not needed anymore. Remove in next major version.
Buffer . _augment = function ( arr ) {
arr . _ _proto _ _ = Buffer . prototype
return arr
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
function from ( that , value , encodingOrOffset , length ) {
if ( typeof value === 'number' ) {
throw new TypeError ( '"value" argument must not be a number' )
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
if ( typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer ) {
return fromArrayBuffer ( that , value , encodingOrOffset , length )
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
if ( typeof value === 'string' ) {
return fromString ( that , value , encodingOrOffset )
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
return fromObject ( that , value )
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
/ * *
* Functionally equivalent to Buffer ( arg , encoding ) but throws a TypeError
* if value is a number .
* Buffer . from ( str [ , encoding ] )
* Buffer . from ( array )
* Buffer . from ( buffer )
* Buffer . from ( arrayBuffer [ , byteOffset [ , length ] ] )
* * /
Buffer . from = function ( value , encodingOrOffset , length ) {
return from ( null , value , encodingOrOffset , length )
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
if ( Buffer . TYPED _ARRAY _SUPPORT ) {
Buffer . prototype . _ _proto _ _ = Uint8Array . prototype
Buffer . _ _proto _ _ = Uint8Array
if ( typeof Symbol !== 'undefined' && Symbol . species &&
Buffer [ Symbol . species ] === Buffer ) {
// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
Object . defineProperty ( Buffer , Symbol . species , {
value : null ,
configurable : true
} )
}
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
function assertSize ( size ) {
if ( typeof size !== 'number' ) {
throw new TypeError ( '"size" argument must be a number' )
} else if ( size < 0 ) {
throw new RangeError ( '"size" argument must not be negative' )
2018-06-28 17:35:20 +00:00
}
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
function alloc ( that , size , fill , encoding ) {
assertSize ( size )
if ( size <= 0 ) {
return createBuffer ( that , size )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
if ( fill !== undefined ) {
// Only pay attention to encoding if it's a string. This
// prevents accidentally sending in a number that would
// be interpretted as a start offset.
return typeof encoding === 'string'
? createBuffer ( that , size ) . fill ( fill , encoding )
: createBuffer ( that , size ) . fill ( fill )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
return createBuffer ( that , size )
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
/ * *
* Creates a new filled Buffer instance .
* alloc ( size [ , fill [ , encoding ] ] )
* * /
Buffer . alloc = function ( size , fill , encoding ) {
return alloc ( null , size , fill , encoding )
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
function allocUnsafe ( that , size ) {
assertSize ( size )
that = createBuffer ( that , size < 0 ? 0 : checked ( size ) | 0 )
if ( ! Buffer . TYPED _ARRAY _SUPPORT ) {
for ( var i = 0 ; i < size ; ++ i ) {
that [ i ] = 0
}
}
return that
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
/ * *
* Equivalent to Buffer ( num ) , by default creates a non - zero - filled Buffer instance .
* * /
Buffer . allocUnsafe = function ( size ) {
return allocUnsafe ( null , size )
}
/ * *
* Equivalent to SlowBuffer ( num ) , by default creates a non - zero - filled Buffer instance .
* /
Buffer . allocUnsafeSlow = function ( size ) {
return allocUnsafe ( null , size )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
function fromString ( that , string , encoding ) {
if ( typeof encoding !== 'string' || encoding === '' ) {
encoding = 'utf8'
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
if ( ! Buffer . isEncoding ( encoding ) ) {
throw new TypeError ( '"encoding" must be a valid string encoding' )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
var length = byteLength ( string , encoding ) | 0
that = createBuffer ( that , length )
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
var actual = that . write ( string , encoding )
if ( actual !== length ) {
// Writing a hex string, for example, that contains invalid characters will
// cause everything after the first invalid character to be ignored. (e.g.
// 'abxxcd' will be treated as 'ab')
that = that . slice ( 0 , actual )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
return that
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
function fromArrayLike ( that , array ) {
var length = array . length < 0 ? 0 : checked ( array . length ) | 0
that = createBuffer ( that , length )
for ( var i = 0 ; i < length ; i += 1 ) {
that [ i ] = array [ i ] & 255
}
return that
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
function fromArrayBuffer ( that , array , byteOffset , length ) {
array . byteLength // this throws if `array` is not a valid ArrayBuffer
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
if ( byteOffset < 0 || array . byteLength < byteOffset ) {
throw new RangeError ( '\'offset\' is out of bounds' )
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
if ( array . byteLength < byteOffset + ( length || 0 ) ) {
throw new RangeError ( '\'length\' is out of bounds' )
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
if ( byteOffset === undefined && length === undefined ) {
array = new Uint8Array ( array )
} else if ( length === undefined ) {
array = new Uint8Array ( array , byteOffset )
} else {
array = new Uint8Array ( array , byteOffset , length )
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
if ( Buffer . TYPED _ARRAY _SUPPORT ) {
// Return an augmented `Uint8Array` instance, for best performance
that = array
that . _ _proto _ _ = Buffer . prototype
} else {
// Fallback: Return an object instance of the Buffer class
that = fromArrayLike ( that , array )
}
return that
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
function fromObject ( that , obj ) {
if ( Buffer . isBuffer ( obj ) ) {
var len = checked ( obj . length ) | 0
that = createBuffer ( that , len )
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
if ( that . length === 0 ) {
return that
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
obj . copy ( that , 0 , 0 , len )
return that
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
if ( obj ) {
if ( ( typeof ArrayBuffer !== 'undefined' &&
obj . buffer instanceof ArrayBuffer ) || 'length' in obj ) {
if ( typeof obj . length !== 'number' || isnan ( obj . length ) ) {
return createBuffer ( that , 0 )
}
return fromArrayLike ( that , obj )
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
if ( obj . type === 'Buffer' && isArray ( obj . data ) ) {
return fromArrayLike ( that , obj . data )
}
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
throw new TypeError ( 'First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.' )
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
function checked ( length ) {
// Note: cannot use `length < kMaxLength()` here because that fails when
// length is NaN (which is otherwise coerced to zero.)
if ( length >= kMaxLength ( ) ) {
throw new RangeError ( 'Attempt to allocate Buffer larger than maximum ' +
'size: 0x' + kMaxLength ( ) . toString ( 16 ) + ' bytes' )
}
return length | 0
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
function SlowBuffer ( length ) {
if ( + length != length ) { // eslint-disable-line eqeqeq
length = 0
}
return Buffer . alloc ( + length )
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
Buffer . isBuffer = function isBuffer ( b ) {
return ! ! ( b != null && b . _isBuffer )
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
Buffer . compare = function compare ( a , b ) {
if ( ! Buffer . isBuffer ( a ) || ! Buffer . isBuffer ( b ) ) {
throw new TypeError ( 'Arguments must be Buffers' )
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
if ( a === b ) return 0
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
var x = a . length
var y = b . length
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
for ( var i = 0 , len = Math . min ( x , y ) ; i < len ; ++ i ) {
if ( a [ i ] !== b [ i ] ) {
x = a [ i ]
y = b [ i ]
break
2015-06-29 16:29:46 +00:00
}
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
if ( x < y ) return - 1
if ( y < x ) return 1
return 0
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
Buffer . isEncoding = function isEncoding ( encoding ) {
switch ( String ( encoding ) . toLowerCase ( ) ) {
case 'hex' :
case 'utf8' :
case 'utf-8' :
case 'ascii' :
case 'latin1' :
case 'binary' :
case 'base64' :
case 'ucs2' :
case 'ucs-2' :
case 'utf16le' :
case 'utf-16le' :
return true
default :
return false
2018-06-28 17:35:20 +00:00
}
}
2018-06-28 21:02:50 +00:00
Buffer . concat = function concat ( list , length ) {
if ( ! isArray ( list ) ) {
throw new TypeError ( '"list" argument must be an Array of Buffers' )
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
if ( list . length === 0 ) {
return Buffer . alloc ( 0 )
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
var i
if ( length === undefined ) {
length = 0
for ( i = 0 ; i < list . length ; ++ i ) {
length += list [ i ] . length
2018-06-28 17:35:20 +00:00
}
}
2018-06-28 21:02:50 +00:00
var buffer = Buffer . allocUnsafe ( length )
var pos = 0
for ( i = 0 ; i < list . length ; ++ i ) {
var buf = list [ i ]
if ( ! Buffer . isBuffer ( buf ) ) {
throw new TypeError ( '"list" argument must be an Array of Buffers' )
}
buf . copy ( buffer , pos )
pos += buf . length
}
return buffer
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
function byteLength ( string , encoding ) {
if ( Buffer . isBuffer ( string ) ) {
return string . length
}
if ( typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer . isView === 'function' &&
( ArrayBuffer . isView ( string ) || string instanceof ArrayBuffer ) ) {
return string . byteLength
}
if ( typeof string !== 'string' ) {
string = '' + string
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
var len = string . length
if ( len === 0 ) return 0
// Use a for loop to avoid recursion
var loweredCase = false
for ( ; ; ) {
switch ( encoding ) {
case 'ascii' :
case 'latin1' :
case 'binary' :
return len
case 'utf8' :
case 'utf-8' :
case undefined :
return utf8ToBytes ( string ) . length
case 'ucs2' :
case 'ucs-2' :
case 'utf16le' :
case 'utf-16le' :
return len * 2
case 'hex' :
return len >>> 1
case 'base64' :
return base64ToBytes ( string ) . length
default :
if ( loweredCase ) return utf8ToBytes ( string ) . length // assume utf8
encoding = ( '' + encoding ) . toLowerCase ( )
loweredCase = true
2018-06-28 17:35:20 +00:00
}
}
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
Buffer . byteLength = byteLength
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
function slowToString ( encoding , start , end ) {
var loweredCase = false
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
// No need to verify that "this.length <= MAX_UINT32" since it's a read-only
// property of a typed array.
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
// This behaves neither like String nor Uint8Array in that we set start/end
// to their upper/lower bounds if the value passed is out of range.
// undefined is handled specially as per ECMA-262 6th Edition,
// Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
if ( start === undefined || start < 0 ) {
start = 0
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
// Return early if start > this.length. Done here to prevent potential uint32
// coercion fail below.
if ( start > this . length ) {
return ''
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
if ( end === undefined || end > this . length ) {
end = this . length
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
if ( end <= 0 ) {
return ''
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
// Force coersion to uint32. This will also coerce falsey/NaN values to 0.
end >>>= 0
start >>>= 0
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
if ( end <= start ) {
return ''
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
if ( ! encoding ) encoding = 'utf8'
while ( true ) {
switch ( encoding ) {
case 'hex' :
return hexSlice ( this , start , end )
case 'utf8' :
case 'utf-8' :
return utf8Slice ( this , start , end )
case 'ascii' :
return asciiSlice ( this , start , end )
case 'latin1' :
case 'binary' :
return latin1Slice ( this , start , end )
case 'base64' :
return base64Slice ( this , start , end )
case 'ucs2' :
case 'ucs-2' :
case 'utf16le' :
case 'utf-16le' :
return utf16leSlice ( this , start , end )
default :
if ( loweredCase ) throw new TypeError ( 'Unknown encoding: ' + encoding )
encoding = ( encoding + '' ) . toLowerCase ( )
loweredCase = true
}
}
}
// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect
// Buffer instances.
Buffer . prototype . _isBuffer = true
function swap ( b , n , m ) {
var i = b [ n ]
b [ n ] = b [ m ]
b [ m ] = i
}
Buffer . prototype . swap16 = function swap16 ( ) {
var len = this . length
if ( len % 2 !== 0 ) {
throw new RangeError ( 'Buffer size must be a multiple of 16-bits' )
}
for ( var i = 0 ; i < len ; i += 2 ) {
swap ( this , i , i + 1 )
}
return this
}
Buffer . prototype . swap32 = function swap32 ( ) {
var len = this . length
if ( len % 4 !== 0 ) {
throw new RangeError ( 'Buffer size must be a multiple of 32-bits' )
}
for ( var i = 0 ; i < len ; i += 4 ) {
swap ( this , i , i + 3 )
swap ( this , i + 1 , i + 2 )
}
return this
}
Buffer . prototype . swap64 = function swap64 ( ) {
var len = this . length
if ( len % 8 !== 0 ) {
throw new RangeError ( 'Buffer size must be a multiple of 64-bits' )
}
for ( var i = 0 ; i < len ; i += 8 ) {
swap ( this , i , i + 7 )
swap ( this , i + 1 , i + 6 )
swap ( this , i + 2 , i + 5 )
swap ( this , i + 3 , i + 4 )
}
return this
}
Buffer . prototype . toString = function toString ( ) {
var length = this . length | 0
if ( length === 0 ) return ''
if ( arguments . length === 0 ) return utf8Slice ( this , 0 , length )
return slowToString . apply ( this , arguments )
}
Buffer . prototype . equals = function equals ( b ) {
if ( ! Buffer . isBuffer ( b ) ) throw new TypeError ( 'Argument must be a Buffer' )
if ( this === b ) return true
return Buffer . compare ( this , b ) === 0
}
Buffer . prototype . inspect = function inspect ( ) {
var str = ''
var max = exports . INSPECT _MAX _BYTES
if ( this . length > 0 ) {
str = this . toString ( 'hex' , 0 , max ) . match ( /.{2}/g ) . join ( ' ' )
if ( this . length > max ) str += ' ... '
}
return '<Buffer ' + str + '>'
}
Buffer . prototype . compare = function compare ( target , start , end , thisStart , thisEnd ) {
if ( ! Buffer . isBuffer ( target ) ) {
throw new TypeError ( 'Argument must be a Buffer' )
}
if ( start === undefined ) {
start = 0
}
if ( end === undefined ) {
end = target ? target . length : 0
}
if ( thisStart === undefined ) {
thisStart = 0
}
if ( thisEnd === undefined ) {
thisEnd = this . length
}
if ( start < 0 || end > target . length || thisStart < 0 || thisEnd > this . length ) {
throw new RangeError ( 'out of range index' )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
if ( thisStart >= thisEnd && start >= end ) {
return 0
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
if ( thisStart >= thisEnd ) {
return - 1
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
if ( start >= end ) {
return 1
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
start >>>= 0
end >>>= 0
thisStart >>>= 0
thisEnd >>>= 0
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
if ( this === target ) return 0
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
var x = thisEnd - thisStart
var y = end - start
var len = Math . min ( x , y )
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
var thisCopy = this . slice ( thisStart , thisEnd )
var targetCopy = target . slice ( start , end )
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
for ( var i = 0 ; i < len ; ++ i ) {
if ( thisCopy [ i ] !== targetCopy [ i ] ) {
x = thisCopy [ i ]
y = targetCopy [ i ]
break
}
2014-06-10 18:53:04 +00:00
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
if ( x < y ) return - 1
if ( y < x ) return 1
return 0
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
//
// Arguments:
// - buffer - a Buffer to search
// - val - a string, Buffer, or number
// - byteOffset - an index into `buffer`; will be clamped to an int32
// - encoding - an optional encoding, relevant is val is a string
// - dir - true for indexOf, false for lastIndexOf
function bidirectionalIndexOf ( buffer , val , byteOffset , encoding , dir ) {
// Empty buffer means no match
if ( buffer . length === 0 ) return - 1
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
// Normalize byteOffset
if ( typeof byteOffset === 'string' ) {
encoding = byteOffset
byteOffset = 0
} else if ( byteOffset > 0x7fffffff ) {
byteOffset = 0x7fffffff
} else if ( byteOffset < - 0x80000000 ) {
byteOffset = - 0x80000000
2015-05-31 15:18:20 +00:00
}
2018-06-28 21:02:50 +00:00
byteOffset = + byteOffset // Coerce to Number.
if ( isNaN ( byteOffset ) ) {
// byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
byteOffset = dir ? 0 : ( buffer . length - 1 )
2015-05-31 15:18:20 +00:00
}
2018-06-28 21:02:50 +00:00
// Normalize byteOffset: negative offsets start from the end of the buffer
if ( byteOffset < 0 ) byteOffset = buffer . length + byteOffset
if ( byteOffset >= buffer . length ) {
if ( dir ) return - 1
else byteOffset = buffer . length - 1
} else if ( byteOffset < 0 ) {
if ( dir ) byteOffset = 0
else return - 1
2014-06-10 18:53:04 +00:00
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
// Normalize val
if ( typeof val === 'string' ) {
val = Buffer . from ( val , encoding )
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
// Finally, search either indexOf (if dir is true) or lastIndexOf
if ( Buffer . isBuffer ( val ) ) {
// Special case: looking for empty string/buffer always fails
if ( val . length === 0 ) {
return - 1
}
return arrayIndexOf ( buffer , val , byteOffset , encoding , dir )
} else if ( typeof val === 'number' ) {
val = val & 0xFF // Search for a byte value [0-255]
if ( Buffer . TYPED _ARRAY _SUPPORT &&
typeof Uint8Array . prototype . indexOf === 'function' ) {
if ( dir ) {
return Uint8Array . prototype . indexOf . call ( buffer , val , byteOffset )
} else {
return Uint8Array . prototype . lastIndexOf . call ( buffer , val , byteOffset )
}
}
return arrayIndexOf ( buffer , [ val ] , byteOffset , encoding , dir )
}
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
throw new TypeError ( 'val must be string, number or Buffer' )
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
function arrayIndexOf ( arr , val , byteOffset , encoding , dir ) {
var indexSize = 1
var arrLength = arr . length
var valLength = val . length
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
if ( encoding !== undefined ) {
encoding = String ( encoding ) . toLowerCase ( )
if ( encoding === 'ucs2' || encoding === 'ucs-2' ||
encoding === 'utf16le' || encoding === 'utf-16le' ) {
if ( arr . length < 2 || val . length < 2 ) {
return - 1
}
indexSize = 2
arrLength /= 2
valLength /= 2
byteOffset /= 2
}
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
function read ( buf , i ) {
if ( indexSize === 1 ) {
return buf [ i ]
} else {
return buf . readUInt16BE ( i * indexSize )
}
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
var i
if ( dir ) {
var foundIndex = - 1
for ( i = byteOffset ; i < arrLength ; i ++ ) {
if ( read ( arr , i ) === read ( val , foundIndex === - 1 ? 0 : i - foundIndex ) ) {
if ( foundIndex === - 1 ) foundIndex = i
if ( i - foundIndex + 1 === valLength ) return foundIndex * indexSize
} else {
if ( foundIndex !== - 1 ) i -= i - foundIndex
foundIndex = - 1
}
}
} else {
if ( byteOffset + valLength > arrLength ) byteOffset = arrLength - valLength
for ( i = byteOffset ; i >= 0 ; i -- ) {
var found = true
for ( var j = 0 ; j < valLength ; j ++ ) {
if ( read ( arr , i + j ) !== read ( val , j ) ) {
found = false
break
}
}
if ( found ) return i
}
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
return - 1
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
Buffer . prototype . includes = function includes ( val , byteOffset , encoding ) {
return this . indexOf ( val , byteOffset , encoding ) !== - 1
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
Buffer . prototype . indexOf = function indexOf ( val , byteOffset , encoding ) {
return bidirectionalIndexOf ( this , val , byteOffset , encoding , true )
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
Buffer . prototype . lastIndexOf = function lastIndexOf ( val , byteOffset , encoding ) {
return bidirectionalIndexOf ( this , val , byteOffset , encoding , false )
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
function hexWrite ( buf , string , offset , length ) {
offset = Number ( offset ) || 0
var remaining = buf . length - offset
if ( ! length ) {
length = remaining
2018-06-28 17:35:20 +00:00
} else {
2018-06-28 21:02:50 +00:00
length = Number ( length )
if ( length > remaining ) {
length = remaining
2018-06-28 17:35:20 +00:00
}
}
2018-06-28 21:02:50 +00:00
// must be an even number of digits
var strLen = string . length
if ( strLen % 2 !== 0 ) throw new TypeError ( 'Invalid hex string' )
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
if ( length > strLen / 2 ) {
length = strLen / 2
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
for ( var i = 0 ; i < length ; ++ i ) {
var parsed = parseInt ( string . substr ( i * 2 , 2 ) , 16 )
if ( isNaN ( parsed ) ) return i
buf [ offset + i ] = parsed
}
return i
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
function utf8Write ( buf , string , offset , length ) {
return blitBuffer ( utf8ToBytes ( string , buf . length - offset ) , buf , offset , length )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
function asciiWrite ( buf , string , offset , length ) {
return blitBuffer ( asciiToBytes ( string ) , buf , offset , length )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
function latin1Write ( buf , string , offset , length ) {
return asciiWrite ( buf , string , offset , length )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
function base64Write ( buf , string , offset , length ) {
return blitBuffer ( base64ToBytes ( string ) , buf , offset , length )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
function ucs2Write ( buf , string , offset , length ) {
return blitBuffer ( utf16leToBytes ( string , buf . length - offset ) , buf , offset , length )
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
Buffer . prototype . write = function write ( string , offset , length , encoding ) {
// Buffer#write(string)
if ( offset === undefined ) {
encoding = 'utf8'
length = this . length
offset = 0
// Buffer#write(string, encoding)
} else if ( length === undefined && typeof offset === 'string' ) {
encoding = offset
length = this . length
offset = 0
// Buffer#write(string, offset[, length][, encoding])
} else if ( isFinite ( offset ) ) {
offset = offset | 0
if ( isFinite ( length ) ) {
length = length | 0
if ( encoding === undefined ) encoding = 'utf8'
} else {
encoding = length
length = undefined
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
// legacy write(string, encoding, offset, length) - remove in v0.13
} else {
throw new Error (
'Buffer.write(string, encoding, offset[, length]) is no longer supported'
)
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
var remaining = this . length - offset
if ( length === undefined || length > remaining ) length = remaining
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
if ( ( string . length > 0 && ( length < 0 || offset < 0 ) ) || offset > this . length ) {
throw new RangeError ( 'Attempt to write outside buffer bounds' )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
if ( ! encoding ) encoding = 'utf8'
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
var loweredCase = false
for ( ; ; ) {
switch ( encoding ) {
case 'hex' :
return hexWrite ( this , string , offset , length )
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
case 'utf8' :
case 'utf-8' :
return utf8Write ( this , string , offset , length )
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
case 'ascii' :
return asciiWrite ( this , string , offset , length )
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
case 'latin1' :
case 'binary' :
return latin1Write ( this , string , offset , length )
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
case 'base64' :
// Warning: maxLength not taken into account in base64Write
return base64Write ( this , string , offset , length )
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
case 'ucs2' :
case 'ucs-2' :
case 'utf16le' :
case 'utf-16le' :
return ucs2Write ( this , string , offset , length )
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
default :
if ( loweredCase ) throw new TypeError ( 'Unknown encoding: ' + encoding )
encoding = ( '' + encoding ) . toLowerCase ( )
loweredCase = true
}
}
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
Buffer . prototype . toJSON = function toJSON ( ) {
return {
type : 'Buffer' ,
data : Array . prototype . slice . call ( this . _arr || this , 0 )
}
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
function base64Slice ( buf , start , end ) {
if ( start === 0 && end === buf . length ) {
return base64 . fromByteArray ( buf )
} else {
return base64 . fromByteArray ( buf . slice ( start , end ) )
}
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
function utf8Slice ( buf , start , end ) {
end = Math . min ( buf . length , end )
var res = [ ]
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
var i = start
while ( i < end ) {
var firstByte = buf [ i ]
var codePoint = null
var bytesPerSequence = ( firstByte > 0xEF ) ? 4
: ( firstByte > 0xDF ) ? 3
: ( firstByte > 0xBF ) ? 2
: 1
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
if ( i + bytesPerSequence <= end ) {
var secondByte , thirdByte , fourthByte , tempCodePoint
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
switch ( bytesPerSequence ) {
case 1 :
if ( firstByte < 0x80 ) {
codePoint = firstByte
}
break
case 2 :
secondByte = buf [ i + 1 ]
if ( ( secondByte & 0xC0 ) === 0x80 ) {
tempCodePoint = ( firstByte & 0x1F ) << 0x6 | ( secondByte & 0x3F )
if ( tempCodePoint > 0x7F ) {
codePoint = tempCodePoint
}
}
break
case 3 :
secondByte = buf [ i + 1 ]
thirdByte = buf [ i + 2 ]
if ( ( secondByte & 0xC0 ) === 0x80 && ( thirdByte & 0xC0 ) === 0x80 ) {
tempCodePoint = ( firstByte & 0xF ) << 0xC | ( secondByte & 0x3F ) << 0x6 | ( thirdByte & 0x3F )
if ( tempCodePoint > 0x7FF && ( tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF ) ) {
codePoint = tempCodePoint
}
}
break
case 4 :
secondByte = buf [ i + 1 ]
thirdByte = buf [ i + 2 ]
fourthByte = buf [ i + 3 ]
if ( ( secondByte & 0xC0 ) === 0x80 && ( thirdByte & 0xC0 ) === 0x80 && ( fourthByte & 0xC0 ) === 0x80 ) {
tempCodePoint = ( firstByte & 0xF ) << 0x12 | ( secondByte & 0x3F ) << 0xC | ( thirdByte & 0x3F ) << 0x6 | ( fourthByte & 0x3F )
if ( tempCodePoint > 0xFFFF && tempCodePoint < 0x110000 ) {
codePoint = tempCodePoint
}
}
}
}
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
if ( codePoint === null ) {
// we did not generate a valid codePoint so insert a
// replacement char (U+FFFD) and advance only 1 byte
codePoint = 0xFFFD
bytesPerSequence = 1
} else if ( codePoint > 0xFFFF ) {
// encode to utf16 (surrogate pair dance)
codePoint -= 0x10000
res . push ( codePoint >>> 10 & 0x3FF | 0xD800 )
codePoint = 0xDC00 | codePoint & 0x3FF
}
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
res . push ( codePoint )
i += bytesPerSequence
}
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
return decodeCodePointsArray ( res )
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
// Based on http://stackoverflow.com/a/22747272/680742, the browser with
// the lowest limit is Chrome, with 0x10000 args.
// We go 1 magnitude less, for safety
var MAX _ARGUMENTS _LENGTH = 0x1000
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
function decodeCodePointsArray ( codePoints ) {
var len = codePoints . length
if ( len <= MAX _ARGUMENTS _LENGTH ) {
return String . fromCharCode . apply ( String , codePoints ) // avoid extra slice()
}
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
// Decode in chunks to avoid "call stack size exceeded".
var res = ''
var i = 0
while ( i < len ) {
res += String . fromCharCode . apply (
String ,
codePoints . slice ( i , i += MAX _ARGUMENTS _LENGTH )
)
}
return res
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
function asciiSlice ( buf , start , end ) {
var ret = ''
end = Math . min ( buf . length , end )
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
for ( var i = start ; i < end ; ++ i ) {
ret += String . fromCharCode ( buf [ i ] & 0x7F )
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
return ret
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
function latin1Slice ( buf , start , end ) {
var ret = ''
end = Math . min ( buf . length , end )
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
for ( var i = start ; i < end ; ++ i ) {
ret += String . fromCharCode ( buf [ i ] )
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
return ret
2015-05-31 15:18:20 +00:00
}
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
function hexSlice ( buf , start , end ) {
var len = buf . length
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
if ( ! start || start < 0 ) start = 0
if ( ! end || end < 0 || end > len ) end = len
var out = ''
for ( var i = start ; i < end ; ++ i ) {
out += toHex ( buf [ i ] )
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
return out
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
function utf16leSlice ( buf , start , end ) {
var bytes = buf . slice ( start , end )
var res = ''
for ( var i = 0 ; i < bytes . length ; i += 2 ) {
res += String . fromCharCode ( bytes [ i ] + bytes [ i + 1 ] * 256 )
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
return res
}
Buffer . prototype . slice = function slice ( start , end ) {
var len = this . length
start = ~ ~ start
end = end === undefined ? len : ~ ~ end
if ( start < 0 ) {
start += len
if ( start < 0 ) start = 0
} else if ( start > len ) {
start = len
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
if ( end < 0 ) {
end += len
if ( end < 0 ) end = 0
} else if ( end > len ) {
end = len
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
if ( end < start ) end = start
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
var newBuf
if ( Buffer . TYPED _ARRAY _SUPPORT ) {
newBuf = this . subarray ( start , end )
newBuf . _ _proto _ _ = Buffer . prototype
} else {
var sliceLen = end - start
newBuf = new Buffer ( sliceLen , undefined )
for ( var i = 0 ; i < sliceLen ; ++ i ) {
newBuf [ i ] = this [ i + start ]
2018-06-28 17:35:20 +00:00
}
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
return newBuf
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
/ *
* Need to make sure that buffer isn ' t trying to write out of bounds .
* /
function checkOffset ( offset , ext , length ) {
if ( ( offset % 1 ) !== 0 || offset < 0 ) throw new RangeError ( 'offset is not uint' )
if ( offset + ext > length ) throw new RangeError ( 'Trying to access beyond buffer length' )
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
Buffer . prototype . readUIntLE = function readUIntLE ( offset , byteLength , noAssert ) {
offset = offset | 0
byteLength = byteLength | 0
if ( ! noAssert ) checkOffset ( offset , byteLength , this . length )
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
var val = this [ offset ]
var mul = 1
var i = 0
while ( ++ i < byteLength && ( mul *= 0x100 ) ) {
val += this [ offset + i ] * mul
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
return val
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
Buffer . prototype . readUIntBE = function readUIntBE ( offset , byteLength , noAssert ) {
offset = offset | 0
byteLength = byteLength | 0
if ( ! noAssert ) {
checkOffset ( offset , byteLength , this . length )
2018-06-28 17:35:20 +00:00
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
var val = this [ offset + -- byteLength ]
var mul = 1
while ( byteLength > 0 && ( mul *= 0x100 ) ) {
val += this [ offset + -- byteLength ] * mul
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
return val
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
Buffer . prototype . readUInt8 = function readUInt8 ( offset , noAssert ) {
if ( ! noAssert ) checkOffset ( offset , 1 , this . length )
return this [ offset ]
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
Buffer . prototype . readUInt16LE = function readUInt16LE ( offset , noAssert ) {
if ( ! noAssert ) checkOffset ( offset , 2 , this . length )
return this [ offset ] | ( this [ offset + 1 ] << 8 )
}
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
Buffer . prototype . readUInt16BE = function readUInt16BE ( offset , noAssert ) {
if ( ! noAssert ) checkOffset ( offset , 2 , this . length )
return ( this [ offset ] << 8 ) | this [ offset + 1 ]
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
Buffer . prototype . readUInt32LE = function readUInt32LE ( offset , noAssert ) {
if ( ! noAssert ) checkOffset ( offset , 4 , this . length )
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
return ( ( this [ offset ] ) |
( this [ offset + 1 ] << 8 ) |
( this [ offset + 2 ] << 16 ) ) +
( this [ offset + 3 ] * 0x1000000 )
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
Buffer . prototype . readUInt32BE = function readUInt32BE ( offset , noAssert ) {
if ( ! noAssert ) checkOffset ( offset , 4 , this . length )
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
return ( this [ offset ] * 0x1000000 ) +
( ( this [ offset + 1 ] << 16 ) |
( this [ offset + 2 ] << 8 ) |
this [ offset + 3 ] )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
Buffer . prototype . readIntLE = function readIntLE ( offset , byteLength , noAssert ) {
offset = offset | 0
byteLength = byteLength | 0
if ( ! noAssert ) checkOffset ( offset , byteLength , this . length )
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
var val = this [ offset ]
var mul = 1
var i = 0
while ( ++ i < byteLength && ( mul *= 0x100 ) ) {
val += this [ offset + i ] * mul
}
mul *= 0x80
if ( val >= mul ) val -= Math . pow ( 2 , 8 * byteLength )
return val
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
Buffer . prototype . readIntBE = function readIntBE ( offset , byteLength , noAssert ) {
offset = offset | 0
byteLength = byteLength | 0
if ( ! noAssert ) checkOffset ( offset , byteLength , this . length )
var i = byteLength
var mul = 1
var val = this [ offset + -- i ]
while ( i > 0 && ( mul *= 0x100 ) ) {
val += this [ offset + -- i ] * mul
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
mul *= 0x80
if ( val >= mul ) val -= Math . pow ( 2 , 8 * byteLength )
return val
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
Buffer . prototype . readInt8 = function readInt8 ( offset , noAssert ) {
if ( ! noAssert ) checkOffset ( offset , 1 , this . length )
if ( ! ( this [ offset ] & 0x80 ) ) return ( this [ offset ] )
return ( ( 0xff - this [ offset ] + 1 ) * - 1 )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
Buffer . prototype . readInt16LE = function readInt16LE ( offset , noAssert ) {
if ( ! noAssert ) checkOffset ( offset , 2 , this . length )
var val = this [ offset ] | ( this [ offset + 1 ] << 8 )
return ( val & 0x8000 ) ? val | 0xFFFF0000 : val
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
Buffer . prototype . readInt16BE = function readInt16BE ( offset , noAssert ) {
if ( ! noAssert ) checkOffset ( offset , 2 , this . length )
var val = this [ offset + 1 ] | ( this [ offset ] << 8 )
return ( val & 0x8000 ) ? val | 0xFFFF0000 : val
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
Buffer . prototype . readInt32LE = function readInt32LE ( offset , noAssert ) {
if ( ! noAssert ) checkOffset ( offset , 4 , this . length )
return ( this [ offset ] ) |
( this [ offset + 1 ] << 8 ) |
( this [ offset + 2 ] << 16 ) |
( this [ offset + 3 ] << 24 )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
Buffer . prototype . readInt32BE = function readInt32BE ( offset , noAssert ) {
if ( ! noAssert ) checkOffset ( offset , 4 , this . length )
return ( this [ offset ] << 24 ) |
( this [ offset + 1 ] << 16 ) |
( this [ offset + 2 ] << 8 ) |
( this [ offset + 3 ] )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
Buffer . prototype . readFloatLE = function readFloatLE ( offset , noAssert ) {
if ( ! noAssert ) checkOffset ( offset , 4 , this . length )
return ieee754 . read ( this , offset , true , 23 , 4 )
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
Buffer . prototype . readFloatBE = function readFloatBE ( offset , noAssert ) {
if ( ! noAssert ) checkOffset ( offset , 4 , this . length )
return ieee754 . read ( this , offset , false , 23 , 4 )
}
Buffer . prototype . readDoubleLE = function readDoubleLE ( offset , noAssert ) {
if ( ! noAssert ) checkOffset ( offset , 8 , this . length )
return ieee754 . read ( this , offset , true , 52 , 8 )
}
Buffer . prototype . readDoubleBE = function readDoubleBE ( offset , noAssert ) {
if ( ! noAssert ) checkOffset ( offset , 8 , this . length )
return ieee754 . read ( this , offset , false , 52 , 8 )
}
function checkInt ( buf , value , offset , ext , max , min ) {
if ( ! Buffer . isBuffer ( buf ) ) throw new TypeError ( '"buffer" argument must be a Buffer instance' )
if ( value > max || value < min ) throw new RangeError ( '"value" argument is out of bounds' )
if ( offset + ext > buf . length ) throw new RangeError ( 'Index out of range' )
}
Buffer . prototype . writeUIntLE = function writeUIntLE ( value , offset , byteLength , noAssert ) {
value = + value
offset = offset | 0
byteLength = byteLength | 0
if ( ! noAssert ) {
var maxBytes = Math . pow ( 2 , 8 * byteLength ) - 1
checkInt ( this , value , offset , byteLength , maxBytes , 0 )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
var mul = 1
var i = 0
this [ offset ] = value & 0xFF
while ( ++ i < byteLength && ( mul *= 0x100 ) ) {
this [ offset + i ] = ( value / mul ) & 0xFF
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
return offset + byteLength
}
Buffer . prototype . writeUIntBE = function writeUIntBE ( value , offset , byteLength , noAssert ) {
value = + value
offset = offset | 0
byteLength = byteLength | 0
if ( ! noAssert ) {
var maxBytes = Math . pow ( 2 , 8 * byteLength ) - 1
checkInt ( this , value , offset , byteLength , maxBytes , 0 )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
var i = byteLength - 1
var mul = 1
this [ offset + i ] = value & 0xFF
while ( -- i >= 0 && ( mul *= 0x100 ) ) {
this [ offset + i ] = ( value / mul ) & 0xFF
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
return offset + byteLength
}
Buffer . prototype . writeUInt8 = function writeUInt8 ( value , offset , noAssert ) {
value = + value
offset = offset | 0
if ( ! noAssert ) checkInt ( this , value , offset , 1 , 0xff , 0 )
if ( ! Buffer . TYPED _ARRAY _SUPPORT ) value = Math . floor ( value )
this [ offset ] = ( value & 0xff )
return offset + 1
}
function objectWriteUInt16 ( buf , value , offset , littleEndian ) {
if ( value < 0 ) value = 0xffff + value + 1
for ( var i = 0 , j = Math . min ( buf . length - offset , 2 ) ; i < j ; ++ i ) {
buf [ offset + i ] = ( value & ( 0xff << ( 8 * ( littleEndian ? i : 1 - i ) ) ) ) >>>
( littleEndian ? i : 1 - i ) * 8
2018-06-28 17:35:20 +00:00
}
}
Buffer . prototype . writeUInt16LE = function writeUInt16LE ( value , offset , noAssert ) {
2015-05-31 15:18:20 +00:00
value = + value
2015-06-29 16:29:46 +00:00
offset = offset | 0
2018-06-28 17:35:20 +00:00
if ( ! noAssert ) checkInt ( this , value , offset , 2 , 0xffff , 0 )
2015-05-31 15:18:20 +00:00
if ( Buffer . TYPED _ARRAY _SUPPORT ) {
2018-05-29 18:03:59 +00:00
this [ offset ] = ( value & 0xff )
2015-05-31 15:18:20 +00:00
this [ offset + 1 ] = ( value >>> 8 )
2015-06-29 16:29:46 +00:00
} else {
objectWriteUInt16 ( this , value , offset , true )
}
2015-05-31 15:18:20 +00:00
return offset + 2
2014-06-10 18:53:04 +00:00
}
2018-06-28 17:35:20 +00:00
Buffer . prototype . writeUInt16BE = function writeUInt16BE ( value , offset , noAssert ) {
2015-05-31 15:18:20 +00:00
value = + value
2015-06-29 16:29:46 +00:00
offset = offset | 0
2018-06-28 17:35:20 +00:00
if ( ! noAssert ) checkInt ( this , value , offset , 2 , 0xffff , 0 )
2015-05-31 15:18:20 +00:00
if ( Buffer . TYPED _ARRAY _SUPPORT ) {
this [ offset ] = ( value >>> 8 )
2018-05-29 18:03:59 +00:00
this [ offset + 1 ] = ( value & 0xff )
2015-06-29 16:29:46 +00:00
} else {
objectWriteUInt16 ( this , value , offset , false )
}
2015-05-31 15:18:20 +00:00
return offset + 2
2014-06-10 18:53:04 +00:00
}
2018-06-28 17:35:20 +00:00
function objectWriteUInt32 ( buf , value , offset , littleEndian ) {
if ( value < 0 ) value = 0xffffffff + value + 1
2018-06-28 21:02:50 +00:00
for ( var i = 0 , j = Math . min ( buf . length - offset , 4 ) ; i < j ; ++ i ) {
2018-06-28 17:35:20 +00:00
buf [ offset + i ] = ( value >>> ( littleEndian ? i : 3 - i ) * 8 ) & 0xff
}
}
Buffer . prototype . writeUInt32LE = function writeUInt32LE ( value , offset , noAssert ) {
2015-05-31 15:18:20 +00:00
value = + value
2015-06-29 16:29:46 +00:00
offset = offset | 0
2018-06-28 17:35:20 +00:00
if ( ! noAssert ) checkInt ( this , value , offset , 4 , 0xffffffff , 0 )
2015-05-31 15:18:20 +00:00
if ( Buffer . TYPED _ARRAY _SUPPORT ) {
this [ offset + 3 ] = ( value >>> 24 )
2018-06-28 17:35:20 +00:00
this [ offset + 2 ] = ( value >>> 16 )
this [ offset + 1 ] = ( value >>> 8 )
this [ offset ] = ( value & 0xff )
2015-06-29 16:29:46 +00:00
} else {
objectWriteUInt32 ( this , value , offset , true )
2018-06-28 21:02:50 +00:00
}
return offset + 4
2014-06-10 18:53:04 +00:00
}
2018-06-28 17:35:20 +00:00
Buffer . prototype . writeUInt32BE = function writeUInt32BE ( value , offset , noAssert ) {
2015-05-31 15:18:20 +00:00
value = + value
2015-06-29 16:29:46 +00:00
offset = offset | 0
2018-06-28 17:35:20 +00:00
if ( ! noAssert ) checkInt ( this , value , offset , 4 , 0xffffffff , 0 )
2015-05-31 15:18:20 +00:00
if ( Buffer . TYPED _ARRAY _SUPPORT ) {
this [ offset ] = ( value >>> 24 )
this [ offset + 1 ] = ( value >>> 16 )
this [ offset + 2 ] = ( value >>> 8 )
2018-05-29 18:03:59 +00:00
this [ offset + 3 ] = ( value & 0xff )
2015-06-29 16:29:46 +00:00
} else {
objectWriteUInt32 ( this , value , offset , false )
}
2015-05-31 15:18:20 +00:00
return offset + 4
2014-06-10 18:53:04 +00:00
}
2018-06-28 17:35:20 +00:00
Buffer . prototype . writeIntLE = function writeIntLE ( value , offset , byteLength , noAssert ) {
value = + value
offset = offset | 0
2015-06-29 16:29:46 +00:00
if ( ! noAssert ) {
2018-06-28 17:35:20 +00:00
var limit = Math . pow ( 2 , 8 * byteLength - 1 )
checkInt ( this , value , offset , byteLength , limit - 1 , - limit )
2015-06-29 16:29:46 +00:00
}
2014-06-10 18:53:04 +00:00
2018-06-28 17:35:20 +00:00
var i = 0
var mul = 1
2018-06-28 21:02:50 +00:00
var sub = 0
2018-06-28 17:35:20 +00:00
this [ offset ] = value & 0xFF
while ( ++ i < byteLength && ( mul *= 0x100 ) ) {
2018-06-28 21:02:50 +00:00
if ( value < 0 && sub === 0 && this [ offset + i - 1 ] !== 0 ) {
sub = 1
}
2018-06-28 17:35:20 +00:00
this [ offset + i ] = ( ( value / mul ) >> 0 ) - sub & 0xFF
}
2014-06-10 18:53:04 +00:00
2018-06-28 17:35:20 +00:00
return offset + byteLength
2014-06-10 18:53:04 +00:00
}
2018-06-28 17:35:20 +00:00
Buffer . prototype . writeIntBE = function writeIntBE ( value , offset , byteLength , noAssert ) {
value = + value
offset = offset | 0
2015-06-29 16:29:46 +00:00
if ( ! noAssert ) {
2018-06-28 17:35:20 +00:00
var limit = Math . pow ( 2 , 8 * byteLength - 1 )
checkInt ( this , value , offset , byteLength , limit - 1 , - limit )
2015-06-29 16:29:46 +00:00
}
2018-06-28 17:35:20 +00:00
var i = byteLength - 1
var mul = 1
2018-06-28 21:02:50 +00:00
var sub = 0
2018-06-28 17:35:20 +00:00
this [ offset + i ] = value & 0xFF
while ( -- i >= 0 && ( mul *= 0x100 ) ) {
2018-06-28 21:02:50 +00:00
if ( value < 0 && sub === 0 && this [ offset + i + 1 ] !== 0 ) {
sub = 1
}
2018-06-28 17:35:20 +00:00
this [ offset + i ] = ( ( value / mul ) >> 0 ) - sub & 0xFF
}
return offset + byteLength
2014-06-10 18:53:04 +00:00
}
2018-06-28 17:35:20 +00:00
Buffer . prototype . writeInt8 = function writeInt8 ( value , offset , noAssert ) {
value = + value
offset = offset | 0
if ( ! noAssert ) checkInt ( this , value , offset , 1 , 0x7f , - 0x80 )
if ( ! Buffer . TYPED _ARRAY _SUPPORT ) value = Math . floor ( value )
if ( value < 0 ) value = 0xff + value + 1
this [ offset ] = ( value & 0xff )
return offset + 1
2014-06-10 18:53:04 +00:00
}
2018-06-28 17:35:20 +00:00
Buffer . prototype . writeInt16LE = function writeInt16LE ( value , offset , noAssert ) {
value = + value
offset = offset | 0
if ( ! noAssert ) checkInt ( this , value , offset , 2 , 0x7fff , - 0x8000 )
if ( Buffer . TYPED _ARRAY _SUPPORT ) {
this [ offset ] = ( value & 0xff )
this [ offset + 1 ] = ( value >>> 8 )
} else {
objectWriteUInt16 ( this , value , offset , true )
}
return offset + 2
2015-05-31 15:18:20 +00:00
}
2018-06-28 17:35:20 +00:00
Buffer . prototype . writeInt16BE = function writeInt16BE ( value , offset , noAssert ) {
value = + value
offset = offset | 0
if ( ! noAssert ) checkInt ( this , value , offset , 2 , 0x7fff , - 0x8000 )
if ( Buffer . TYPED _ARRAY _SUPPORT ) {
this [ offset ] = ( value >>> 8 )
this [ offset + 1 ] = ( value & 0xff )
} else {
objectWriteUInt16 ( this , value , offset , false )
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
return offset + 2
}
2015-05-31 15:18:20 +00:00
2018-06-28 21:02:50 +00:00
Buffer . prototype . writeInt32LE = function writeInt32LE ( value , offset , noAssert ) {
value = + value
offset = offset | 0
if ( ! noAssert ) checkInt ( this , value , offset , 4 , 0x7fffffff , - 0x80000000 )
if ( Buffer . TYPED _ARRAY _SUPPORT ) {
this [ offset ] = ( value & 0xff )
this [ offset + 1 ] = ( value >>> 8 )
this [ offset + 2 ] = ( value >>> 16 )
this [ offset + 3 ] = ( value >>> 24 )
2015-05-31 15:18:20 +00:00
} else {
2018-06-28 21:02:50 +00:00
objectWriteUInt32 ( this , value , offset , true )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
return offset + 4
2018-06-28 17:35:20 +00:00
}
Buffer . prototype . writeInt32BE = function writeInt32BE ( value , offset , noAssert ) {
value = + value
offset = offset | 0
if ( ! noAssert ) checkInt ( this , value , offset , 4 , 0x7fffffff , - 0x80000000 )
if ( value < 0 ) value = 0xffffffff + value + 1
if ( Buffer . TYPED _ARRAY _SUPPORT ) {
this [ offset ] = ( value >>> 24 )
this [ offset + 1 ] = ( value >>> 16 )
this [ offset + 2 ] = ( value >>> 8 )
this [ offset + 3 ] = ( value & 0xff )
} else {
objectWriteUInt32 ( this , value , offset , false )
}
return offset + 4
}
function checkIEEE754 ( buf , value , offset , ext , max , min ) {
2018-06-28 21:02:50 +00:00
if ( offset + ext > buf . length ) throw new RangeError ( 'Index out of range' )
if ( offset < 0 ) throw new RangeError ( 'Index out of range' )
2018-06-28 17:35:20 +00:00
}
function writeFloat ( buf , value , offset , littleEndian , noAssert ) {
if ( ! noAssert ) {
checkIEEE754 ( buf , value , offset , 4 , 3.4028234663852886 e + 38 , - 3.4028234663852886 e + 38 )
}
ieee754 . write ( buf , value , offset , littleEndian , 23 , 4 )
return offset + 4
}
Buffer . prototype . writeFloatLE = function writeFloatLE ( value , offset , noAssert ) {
return writeFloat ( this , value , offset , true , noAssert )
}
Buffer . prototype . writeFloatBE = function writeFloatBE ( value , offset , noAssert ) {
return writeFloat ( this , value , offset , false , noAssert )
}
function writeDouble ( buf , value , offset , littleEndian , noAssert ) {
if ( ! noAssert ) {
checkIEEE754 ( buf , value , offset , 8 , 1.7976931348623157 E + 308 , - 1.7976931348623157 E + 308 )
}
ieee754 . write ( buf , value , offset , littleEndian , 52 , 8 )
return offset + 8
}
2018-06-28 21:02:50 +00:00
Buffer . prototype . writeDoubleLE = function writeDoubleLE ( value , offset , noAssert ) {
return writeDouble ( this , value , offset , true , noAssert )
}
Buffer . prototype . writeDoubleBE = function writeDoubleBE ( value , offset , noAssert ) {
return writeDouble ( this , value , offset , false , noAssert )
}
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
2018-06-28 17:35:20 +00:00
Buffer . prototype . copy = function copy ( target , targetStart , start , end ) {
if ( ! start ) start = 0
if ( ! end && end !== 0 ) end = this . length
if ( targetStart >= target . length ) targetStart = target . length
if ( ! targetStart ) targetStart = 0
if ( end > 0 && end < start ) end = start
// Copy 0 bytes; we're done
if ( end === start ) return 0
if ( target . length === 0 || this . length === 0 ) return 0
// Fatal error conditions
if ( targetStart < 0 ) {
throw new RangeError ( 'targetStart out of bounds' )
}
if ( start < 0 || start >= this . length ) throw new RangeError ( 'sourceStart out of bounds' )
if ( end < 0 ) throw new RangeError ( 'sourceEnd out of bounds' )
// Are we oob?
if ( end > this . length ) end = this . length
if ( target . length - targetStart < end - start ) {
end = target . length - targetStart + start
}
var len = end - start
var i
if ( this === target && start < targetStart && targetStart < end ) {
// descending copy from end
2018-06-28 21:02:50 +00:00
for ( i = len - 1 ; i >= 0 ; -- i ) {
2018-06-28 17:35:20 +00:00
target [ i + targetStart ] = this [ i + start ]
}
} else if ( len < 1000 || ! Buffer . TYPED _ARRAY _SUPPORT ) {
// ascending copy from start
2018-06-28 21:02:50 +00:00
for ( i = 0 ; i < len ; ++ i ) {
2018-06-28 17:35:20 +00:00
target [ i + targetStart ] = this [ i + start ]
}
} else {
2018-06-28 21:02:50 +00:00
Uint8Array . prototype . set . call (
target ,
this . subarray ( start , start + len ) ,
targetStart
)
2015-05-31 15:18:20 +00:00
}
2015-06-29 16:29:46 +00:00
return len
2014-06-10 18:53:04 +00:00
}
2018-06-28 21:02:50 +00:00
// Usage:
// buffer.fill(number[, offset[, end]])
// buffer.fill(buffer[, offset[, end]])
// buffer.fill(string[, offset[, end]][, encoding])
Buffer . prototype . fill = function fill ( val , start , end , encoding ) {
// Handle string cases:
if ( typeof val === 'string' ) {
if ( typeof start === 'string' ) {
encoding = start
start = 0
end = this . length
} else if ( typeof end === 'string' ) {
encoding = end
end = this . length
}
if ( val . length === 1 ) {
var code = val . charCodeAt ( 0 )
if ( code < 256 ) {
val = code
}
}
if ( encoding !== undefined && typeof encoding !== 'string' ) {
throw new TypeError ( 'encoding must be a string' )
}
if ( typeof encoding === 'string' && ! Buffer . isEncoding ( encoding ) ) {
throw new TypeError ( 'Unknown encoding: ' + encoding )
}
} else if ( typeof val === 'number' ) {
val = val & 255
2018-06-28 17:35:20 +00:00
}
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
// Invalid ranges are not set to a default, so can range check early.
if ( start < 0 || this . length < start || this . length < end ) {
throw new RangeError ( 'Out of range index' )
}
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
if ( end <= start ) {
return this
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
start = start >>> 0
end = end === undefined ? this . length : end >>> 0
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
if ( ! val ) val = 0
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
var i
if ( typeof val === 'number' ) {
for ( i = start ; i < end ; ++ i ) {
this [ i ] = val
2014-06-10 18:53:04 +00:00
}
} else {
2018-06-28 21:02:50 +00:00
var bytes = Buffer . isBuffer ( val )
? val
: utf8ToBytes ( new Buffer ( val , encoding ) . toString ( ) )
var len = bytes . length
for ( i = 0 ; i < end - start ; ++ i ) {
this [ i + start ] = bytes [ i % len ]
}
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
return this
2018-06-28 17:35:20 +00:00
}
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
// HELPER FUNCTIONS
// ================
2014-06-10 18:53:04 +00:00
2018-05-29 18:03:59 +00:00
var INVALID _BASE64 _RE = /[^+\/0-9A-Za-z-_]/g
2014-06-10 18:53:04 +00:00
2015-05-31 15:18:20 +00:00
function base64clean ( str ) {
// Node strips out invalid characters like \n and \t from the string, base64-js does not
str = stringtrim ( str ) . replace ( INVALID _BASE64 _RE , '' )
2015-06-29 16:29:46 +00:00
// Node converts strings with length < 2 to ''
if ( str . length < 2 ) return ''
2015-05-31 15:18:20 +00:00
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
while ( str . length % 4 !== 0 ) {
str = str + '='
}
2018-06-28 21:02:50 +00:00
return str
}
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
function stringtrim ( str ) {
if ( str . trim ) return str . trim ( )
return str . replace ( /^\s+|\s+$/g , '' )
2014-06-10 18:53:04 +00:00
}
function toHex ( n ) {
if ( n < 16 ) return '0' + n . toString ( 16 )
return n . toString ( 16 )
}
2015-06-29 16:29:46 +00:00
function utf8ToBytes ( string , units ) {
units = units || Infinity
var codePoint
var length = string . length
var leadSurrogate = null
var bytes = [ ]
2018-06-28 21:02:50 +00:00
for ( var i = 0 ; i < length ; ++ i ) {
2015-06-29 16:29:46 +00:00
codePoint = string . charCodeAt ( i )
// is surrogate component
if ( codePoint > 0xD7FF && codePoint < 0xE000 ) {
// last char was a lead
2018-05-29 18:03:59 +00:00
if ( ! leadSurrogate ) {
2015-06-29 16:29:46 +00:00
// no lead yet
if ( codePoint > 0xDBFF ) {
// unexpected trail
if ( ( units -= 3 ) > - 1 ) bytes . push ( 0xEF , 0xBF , 0xBD )
continue
} else if ( i + 1 === length ) {
// unpaired lead
if ( ( units -= 3 ) > - 1 ) bytes . push ( 0xEF , 0xBF , 0xBD )
continue
}
2018-05-29 18:03:59 +00:00
// valid lead
leadSurrogate = codePoint
continue
}
// 2 leads in a row
if ( codePoint < 0xDC00 ) {
if ( ( units -= 3 ) > - 1 ) bytes . push ( 0xEF , 0xBF , 0xBD )
leadSurrogate = codePoint
continue
2014-06-10 18:53:04 +00:00
}
2018-05-29 18:03:59 +00:00
// valid surrogate pair
codePoint = ( leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 ) + 0x10000
2015-06-29 16:29:46 +00:00
} else if ( leadSurrogate ) {
// valid bmp char, but last char was a lead
if ( ( units -= 3 ) > - 1 ) bytes . push ( 0xEF , 0xBF , 0xBD )
}
2018-05-29 18:03:59 +00:00
leadSurrogate = null
2015-06-29 16:29:46 +00:00
// encode utf8
if ( codePoint < 0x80 ) {
if ( ( units -= 1 ) < 0 ) break
bytes . push ( codePoint )
} else if ( codePoint < 0x800 ) {
if ( ( units -= 2 ) < 0 ) break
bytes . push (
codePoint >> 0x6 | 0xC0 ,
codePoint & 0x3F | 0x80
)
} else if ( codePoint < 0x10000 ) {
if ( ( units -= 3 ) < 0 ) break
bytes . push (
codePoint >> 0xC | 0xE0 ,
codePoint >> 0x6 & 0x3F | 0x80 ,
codePoint & 0x3F | 0x80
)
2018-05-29 18:03:59 +00:00
} else if ( codePoint < 0x110000 ) {
2015-06-29 16:29:46 +00:00
if ( ( units -= 4 ) < 0 ) break
bytes . push (
codePoint >> 0x12 | 0xF0 ,
codePoint >> 0xC & 0x3F | 0x80 ,
codePoint >> 0x6 & 0x3F | 0x80 ,
codePoint & 0x3F | 0x80
)
} else {
throw new Error ( 'Invalid code point' )
2014-06-10 18:53:04 +00:00
}
}
2015-06-29 16:29:46 +00:00
return bytes
2014-06-10 18:53:04 +00:00
}
function asciiToBytes ( str ) {
var byteArray = [ ]
2018-06-28 21:02:50 +00:00
for ( var i = 0 ; i < str . length ; ++ i ) {
2014-06-10 18:53:04 +00:00
// Node's code seems to be doing this and not & 0x7F..
byteArray . push ( str . charCodeAt ( i ) & 0xFF )
}
return byteArray
}
2015-06-29 16:29:46 +00:00
function utf16leToBytes ( str , units ) {
2014-06-10 18:53:04 +00:00
var c , hi , lo
var byteArray = [ ]
2018-06-28 21:02:50 +00:00
for ( var i = 0 ; i < str . length ; ++ i ) {
2015-06-29 16:29:46 +00:00
if ( ( units -= 2 ) < 0 ) break
2014-06-10 18:53:04 +00:00
c = str . charCodeAt ( i )
hi = c >> 8
lo = c % 256
byteArray . push ( lo )
byteArray . push ( hi )
}
return byteArray
}
function base64ToBytes ( str ) {
2015-06-29 16:29:46 +00:00
return base64 . toByteArray ( base64clean ( str ) )
2014-06-10 18:53:04 +00:00
}
2015-06-29 16:29:46 +00:00
function blitBuffer ( src , dst , offset , length ) {
2018-06-28 21:02:50 +00:00
for ( var i = 0 ; i < length ; ++ i ) {
2015-06-29 16:29:46 +00:00
if ( ( i + offset >= dst . length ) || ( i >= src . length ) ) break
2014-06-10 18:53:04 +00:00
dst [ i + offset ] = src [ i ]
}
return i
}
2018-06-28 21:02:50 +00:00
function isnan ( val ) {
return val !== val // eslint-disable-line no-self-compare
}
2014-06-10 18:53:04 +00:00
2018-12-21 19:22:25 +00:00
} , { "base64-js" : "yh9p" , "ieee754" : "JgNJ" , "isarray" : "REa7" , "buffer" : "dskh" } ] , "QO4x" : [ function ( require , module , exports ) {
var Buffer = require ( "buffer" ) . Buffer ;
2019-02-07 21:38:32 +00:00
var global = arguments [ 3 ] ;
2018-06-28 21:02:50 +00:00
var FILE _SYSTEM _NAME = require ( '../constants.js' ) . FILE _SYSTEM _NAME ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
var FILE _STORE _NAME = require ( '../constants.js' ) . FILE _STORE _NAME ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
var IDB _RW = require ( '../constants.js' ) . IDB _RW ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
var IDB _RO = require ( '../constants.js' ) . IDB _RO ;
2014-06-10 18:53:04 +00:00
2018-06-28 21:02:50 +00:00
function IndexedDBContext ( db , mode ) {
this . db = db ;
this . mode = mode ;
}
IndexedDBContext . prototype . _getObjectStore = function ( ) {
if ( this . objectStore ) {
return this . objectStore ;
}
var transaction = this . db . transaction ( FILE _STORE _NAME , this . mode ) ;
this . objectStore = transaction . objectStore ( FILE _STORE _NAME ) ;
return this . objectStore ;
} ;
IndexedDBContext . prototype . clear = function ( callback ) {
try {
var objectStore = this . _getObjectStore ( ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
var request = objectStore . clear ( ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
request . onsuccess = function ( ) {
callback ( ) ;
} ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
request . onerror = function ( event ) {
event . preventDefault ( ) ;
callback ( event . error ) ;
} ;
} catch ( err ) {
callback ( err ) ;
}
} ;
IndexedDBContext . prototype . _get = function ( key , callback ) {
try {
var objectStore = this . _getObjectStore ( ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
var request = objectStore . get ( key ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
request . onsuccess = function onsuccess ( event ) {
var result = event . target . result ;
callback ( null , result ) ;
} ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
request . onerror = function ( event ) {
event . preventDefault ( ) ;
callback ( event . error ) ;
} ;
} catch ( err ) {
callback ( err ) ;
}
} ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
IndexedDBContext . prototype . getObject = function ( key , callback ) {
this . _get ( key , callback ) ;
} ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
IndexedDBContext . prototype . getBuffer = function ( key , callback ) {
this . _get ( key , function ( err , arrayBuffer ) {
if ( err ) {
return callback ( err ) ;
}
2018-12-21 19:22:25 +00:00
callback ( null , Buffer . from ( arrayBuffer ) ) ;
2018-06-28 21:02:50 +00:00
} ) ;
} ;
IndexedDBContext . prototype . _put = function ( key , value , callback ) {
try {
var objectStore = this . _getObjectStore ( ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
var request = objectStore . put ( value , key ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
request . onsuccess = function onsuccess ( event ) {
var result = event . target . result ;
callback ( null , result ) ;
} ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
request . onerror = function ( event ) {
event . preventDefault ( ) ;
callback ( event . error ) ;
} ;
} catch ( err ) {
callback ( err ) ;
}
} ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
IndexedDBContext . prototype . putObject = function ( key , value , callback ) {
this . _put ( key , value , callback ) ;
} ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
IndexedDBContext . prototype . putBuffer = function ( key , uint8BackedBuffer , callback ) {
var buf = uint8BackedBuffer . buffer ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
this . _put ( key , buf , callback ) ;
} ;
IndexedDBContext . prototype . delete = function ( key , callback ) {
try {
var objectStore = this . _getObjectStore ( ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
var request = objectStore . delete ( key ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
request . onsuccess = function onsuccess ( event ) {
var result = event . target . result ;
callback ( null , result ) ;
} ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
request . onerror = function ( event ) {
event . preventDefault ( ) ;
callback ( event . error ) ;
} ;
} catch ( err ) {
callback ( err ) ;
}
} ;
function IndexedDB ( name ) {
this . name = name || FILE _SYSTEM _NAME ;
this . db = null ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
IndexedDB . isSupported = function ( ) {
2019-02-07 21:38:32 +00:00
var indexedDB = global . indexedDB || global . mozIndexedDB || global . webkitIndexedDB || global . msIndexedDB ;
2018-06-28 21:02:50 +00:00
return ! ! indexedDB ;
} ;
IndexedDB . prototype . open = function ( callback ) {
2018-12-21 19:22:25 +00:00
var that = this ; // Bail if we already have a db open
2018-06-28 21:02:50 +00:00
if ( that . db ) {
return callback ( ) ;
}
try {
2019-02-07 21:38:32 +00:00
var indexedDB = global . indexedDB || global . mozIndexedDB || global . webkitIndexedDB || global . msIndexedDB ; // NOTE: we're not using versioned databases.
2018-12-21 19:22:25 +00:00
var openRequest = indexedDB . open ( that . name ) ; // If the db doesn't exist, we'll create it
2018-06-28 21:02:50 +00:00
openRequest . onupgradeneeded = function onupgradeneeded ( event ) {
var db = event . target . result ;
if ( db . objectStoreNames . contains ( FILE _STORE _NAME ) ) {
db . deleteObjectStore ( FILE _STORE _NAME ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
db . createObjectStore ( FILE _STORE _NAME ) ;
} ;
openRequest . onsuccess = function onsuccess ( event ) {
that . db = event . target . result ;
callback ( ) ;
} ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
openRequest . onerror = function onerror ( event ) {
event . preventDefault ( ) ;
callback ( event . error ) ;
} ;
} catch ( err ) {
callback ( err ) ;
}
} ;
IndexedDB . prototype . getReadOnlyContext = function ( ) {
return new IndexedDBContext ( this . db , IDB _RO ) ;
} ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
IndexedDB . prototype . getReadWriteContext = function ( ) {
return new IndexedDBContext ( this . db , IDB _RW ) ;
} ;
module . exports = IndexedDB ;
2019-01-03 04:12:19 +00:00
} , { "../constants.js" : "iJA9" , "buffer" : "dskh" } ] , "u4Zs" : [ function ( require , module , exports ) {
2018-06-28 21:02:50 +00:00
var process = require ( "process" ) ;
var define ;
/*global setImmediate: false, setTimeout: false, console: false */
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
/ * *
* async . js shim , based on https : //raw.github.com/caolan/async/master/lib/async.js Feb 18, 2014
* Used under MIT - https : //github.com/caolan/async/blob/master/LICENSE
* /
( function ( ) {
2018-12-21 19:22:25 +00:00
var async = { } ; // async.js functions used in Filer
//// nextTick implementation with browser-compatible fallback ////
if ( typeof process === 'undefined' || ! process . nextTick ) {
if ( typeof setImmediate === 'function' ) {
async . nextTick = function ( fn ) {
// not a direct alias for IE10 compatibility
setImmediate ( fn ) ;
} ;
2018-05-29 18:03:59 +00:00
2018-12-21 19:22:25 +00:00
async . setImmediate = async . nextTick ;
} else {
async . nextTick = function ( fn ) {
setTimeout ( fn , 0 ) ;
} ;
2014-12-02 18:45:21 +00:00
2018-12-21 19:22:25 +00:00
async . setImmediate = async . nextTick ;
}
} else {
async . nextTick = process . nextTick ;
2014-12-02 18:45:21 +00:00
2018-12-21 19:22:25 +00:00
if ( typeof setImmediate !== 'undefined' ) {
async . setImmediate = function ( fn ) {
// not a direct alias for IE10 compatibility
setImmediate ( fn ) ;
} ;
2018-06-28 21:02:50 +00:00
} else {
2018-12-21 19:22:25 +00:00
async . setImmediate = async . nextTick ;
2018-06-28 21:02:50 +00:00
}
2018-12-21 19:22:25 +00:00
}
2014-12-02 18:45:21 +00:00
2018-12-21 19:22:25 +00:00
async . eachSeries = function ( arr , iterator , callback ) {
callback = callback || function ( ) { } ;
2014-12-02 18:45:21 +00:00
2018-12-21 19:22:25 +00:00
if ( ! arr . length ) {
return callback ( ) ;
2018-06-28 21:02:50 +00:00
}
2018-12-21 19:22:25 +00:00
var completed = 0 ;
var iterate = function iterate ( ) {
iterator ( arr [ completed ] , function ( err ) {
if ( err ) {
callback ( err ) ;
callback = function callback ( ) { } ;
} else {
completed += 1 ;
if ( completed >= arr . length ) {
callback ( ) ;
} else {
iterate ( ) ;
}
2018-06-28 21:02:50 +00:00
}
2018-12-21 19:22:25 +00:00
} ) ;
} ;
iterate ( ) ;
} ;
async . forEachSeries = async . eachSeries ; // AMD / RequireJS
if ( typeof define !== 'undefined' && define . amd ) {
define ( [ ] , function ( ) {
return async ;
} ) ;
} // Node.js
else if ( typeof module !== 'undefined' && module . exports ) {
module . exports = async ;
} // included directly via <script> tag
else {
root . async = async ;
}
2018-06-28 21:02:50 +00:00
} ) ( ) ;
2018-07-14 15:21:34 +00:00
} , { "process" : "pBGv" } ] , "3OWy" : [ function ( require , module , exports ) {
2018-12-21 19:22:25 +00:00
var FILE _SYSTEM _NAME = require ( '../constants.js' ) . FILE _SYSTEM _NAME ; // NOTE: prefer setImmediate to nextTick for proper recursion yielding.
2018-06-28 21:02:50 +00:00
// see https://github.com/js-platform/filer/pull/24
2014-12-02 18:45:21 +00:00
2018-12-21 19:22:25 +00:00
var asyncCallback = require ( '../../lib/async.js' ) . setImmediate ;
2018-06-28 21:02:50 +00:00
/ * *
* Make shared in - memory DBs possible when using the same name .
* /
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
var createDB = function ( ) {
var pool = { } ;
return function getOrCreate ( name ) {
if ( ! pool . hasOwnProperty ( name ) ) {
pool [ name ] = { } ;
2018-05-29 18:03:59 +00:00
}
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
return pool [ name ] ;
} ;
} ( ) ;
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
function MemoryContext ( db , readOnly ) {
this . readOnly = readOnly ;
this . objectStore = db ;
2018-05-29 18:03:59 +00:00
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
MemoryContext . prototype . clear = function ( callback ) {
if ( this . readOnly ) {
asyncCallback ( function ( ) {
2018-10-30 18:35:33 +00:00
callback ( '[MemoryContext] Error: write operation on read only context' ) ;
2018-06-28 21:02:50 +00:00
} ) ;
return ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
var objectStore = this . objectStore ;
Object . keys ( objectStore ) . forEach ( function ( key ) {
delete objectStore [ key ] ;
} ) ;
asyncCallback ( callback ) ;
2018-12-21 19:22:25 +00:00
} ; // Memory context doesn't care about differences between Object and Buffer
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
MemoryContext . prototype . getObject = MemoryContext . prototype . getBuffer = function ( key , callback ) {
var that = this ;
asyncCallback ( function ( ) {
callback ( null , that . objectStore [ key ] ) ;
} ) ;
} ;
2014-12-02 18:45:21 +00:00
2018-12-21 19:22:25 +00:00
MemoryContext . prototype . putObject = MemoryContext . prototype . putBuffer = function ( key , value , callback ) {
2018-06-28 21:02:50 +00:00
if ( this . readOnly ) {
asyncCallback ( function ( ) {
2018-10-30 18:35:33 +00:00
callback ( '[MemoryContext] Error: write operation on read only context' ) ;
2018-06-28 21:02:50 +00:00
} ) ;
return ;
2014-12-02 18:45:21 +00:00
}
2018-12-21 19:22:25 +00:00
this . objectStore [ key ] = value ;
2018-06-28 21:02:50 +00:00
asyncCallback ( callback ) ;
} ;
2018-12-21 19:22:25 +00:00
MemoryContext . prototype . delete = function ( key , callback ) {
if ( this . readOnly ) {
asyncCallback ( function ( ) {
callback ( '[MemoryContext] Error: write operation on read only context' ) ;
} ) ;
return ;
2014-12-02 18:45:21 +00:00
}
2018-12-21 19:22:25 +00:00
delete this . objectStore [ key ] ;
asyncCallback ( callback ) ;
2018-06-28 21:02:50 +00:00
} ;
2014-12-02 18:45:21 +00:00
2018-12-21 19:22:25 +00:00
function Memory ( name ) {
this . name = name || FILE _SYSTEM _NAME ;
}
2014-12-02 18:45:21 +00:00
2018-12-21 19:22:25 +00:00
Memory . isSupported = function ( ) {
return true ;
} ;
2014-12-02 18:45:21 +00:00
2018-12-21 19:22:25 +00:00
Memory . prototype . open = function ( callback ) {
this . db = createDB ( this . name ) ;
asyncCallback ( callback ) ;
} ;
2014-12-02 18:45:21 +00:00
2018-12-21 19:22:25 +00:00
Memory . prototype . getReadOnlyContext = function ( ) {
return new MemoryContext ( this . db , true ) ;
} ;
2014-12-02 18:45:21 +00:00
2018-12-21 19:22:25 +00:00
Memory . prototype . getReadWriteContext = function ( ) {
return new MemoryContext ( this . db , false ) ;
2018-06-28 21:02:50 +00:00
} ;
2014-12-02 18:45:21 +00:00
2018-12-21 19:22:25 +00:00
module . exports = Memory ;
} , { "../constants.js" : "iJA9" , "../../lib/async.js" : "u4Zs" } ] , "AiW7" : [ function ( require , module , exports ) {
var IndexedDB = require ( './indexeddb.js' ) ;
2014-12-02 18:45:21 +00:00
2018-12-21 19:22:25 +00:00
var Memory = require ( './memory.js' ) ;
2014-12-02 18:45:21 +00:00
2018-12-21 19:22:25 +00:00
module . exports = {
IndexedDB : IndexedDB ,
Default : IndexedDB ,
2019-01-03 04:12:19 +00:00
Memory : Memory
} ;
} , { "./indexeddb.js" : "QO4x" , "./memory.js" : "3OWy" } ] , "p8GN" : [ function ( require , module , exports ) {
var errors = { } ;
[
/ * *
* node . js errors - we only use some of these , add as needed .
* /
//'-1:UNKNOWN:unknown error',
//'0:OK:success',
//'1:EOF:end of file',
//'2:EADDRINFO:getaddrinfo error',
'3:EACCES:permission denied' , //'4:EAGAIN:resource temporarily unavailable',
//'5:EADDRINUSE:address already in use',
//'6:EADDRNOTAVAIL:address not available',
//'7:EAFNOSUPPORT:address family not supported',
//'8:EALREADY:connection already in progress',
'9:EBADF:bad file descriptor' , '10:EBUSY:resource busy or locked' , //'11:ECONNABORTED:software caused connection abort',
//'12:ECONNREFUSED:connection refused',
//'13:ECONNRESET:connection reset by peer',
//'14:EDESTADDRREQ:destination address required',
//'15:EFAULT:bad address in system call argument',
//'16:EHOSTUNREACH:host is unreachable',
//'17:EINTR:interrupted system call',
'18:EINVAL:invalid argument' , //'19:EISCONN:socket is already connected',
//'20:EMFILE:too many open files',
//'21:EMSGSIZE:message too long',
//'22:ENETDOWN:network is down',
//'23:ENETUNREACH:network is unreachable',
//'24:ENFILE:file table overflow',
//'25:ENOBUFS:no buffer space available',
//'26:ENOMEM:not enough memory',
'27:ENOTDIR:not a directory' , '28:EISDIR:illegal operation on a directory' , //'29:ENONET:machine is not on the network',
// errno 30 skipped, as per https://github.com/rvagg/node-errno/blob/master/errno.js
//'31:ENOTCONN:socket is not connected',
//'32:ENOTSOCK:socket operation on non-socket',
//'33:ENOTSUP:operation not supported on socket',
'34:ENOENT:no such file or directory' , //'35:ENOSYS:function not implemented',
//'36:EPIPE:broken pipe',
//'37:EPROTO:protocol error',
//'38:EPROTONOSUPPORT:protocol not supported',
//'39:EPROTOTYPE:protocol wrong type for socket',
//'40:ETIMEDOUT:connection timed out',
//'41:ECHARSET:invalid Unicode character',
//'42:EAIFAMNOSUPPORT:address family for hostname not supported',
// errno 43 skipped, as per https://github.com/rvagg/node-errno/blob/master/errno.js
//'44:EAISERVICE:servname not supported for ai_socktype',
//'45:EAISOCKTYPE:ai_socktype not supported',
//'46:ESHUTDOWN:cannot send after transport endpoint shutdown',
'47:EEXIST:file already exists' , //'48:ESRCH:no such process',
//'49:ENAMETOOLONG:name too long',
'50:EPERM:operation not permitted' , '51:ELOOP:too many symbolic links encountered' , //'52:EXDEV:cross-device link not permitted',
'53:ENOTEMPTY:directory not empty' , //'54:ENOSPC:no space left on device',
'55:EIO:i/o error' , //'56:EROFS:read-only file system',
//'57:ENODEV:no such device',
//'58:ESPIPE:invalid seek',
//'59:ECANCELED:operation canceled',
/ * *
* Filer specific errors
* /
'1000:ENOTMOUNTED:not mounted' , '1001:EFILESYSTEMERROR:missing super node, use \'FORMAT\' flag to format filesystem.' , '1002:ENOATTR:attribute does not exist' ] . forEach ( function ( e ) {
e = e . split ( ':' ) ;
var errno = + e [ 0 ] ;
var errName = e [ 1 ] ;
var defaultMessage = e [ 2 ] ;
function FilerError ( msg , path ) {
Error . call ( this ) ;
this . name = errName ;
this . code = errName ;
this . errno = errno ;
this . message = msg || defaultMessage ;
if ( path ) {
this . path = path ;
2018-06-28 21:02:50 +00:00
}
2014-12-02 18:45:21 +00:00
2019-01-03 04:12:19 +00:00
this . stack = new Error ( this . message ) . stack ;
}
FilerError . prototype = Object . create ( Error . prototype ) ;
FilerError . prototype . constructor = FilerError ;
2014-12-02 18:45:21 +00:00
2019-01-03 04:12:19 +00:00
FilerError . prototype . toString = function ( ) {
var pathInfo = this . path ? ', \'' + this . path + '\'' : '' ;
return this . name + ': ' + this . message + pathInfo ;
} ; // We expose the error as both Errors.EINVAL and Errors[18]
2018-12-21 19:22:25 +00:00
2019-01-03 04:12:19 +00:00
errors [ errName ] = errors [ errno ] = FilerError ;
} ) ;
module . exports = errors ;
} , { } ] , "QMiB" : [ function ( require , module , exports ) {
2019-02-07 21:38:32 +00:00
'use strict' ;
2018-12-21 19:22:25 +00:00
var defaults = require ( '../constants.js' ) . ENVIRONMENT ;
module . exports = function Environment ( env ) {
env = env || { } ;
env . TMP = env . TMP || defaults . TMP ;
env . PATH = env . PATH || defaults . PATH ;
this . get = function ( name ) {
return env [ name ] ;
} ;
this . set = function ( name , value ) {
env [ name ] = value ;
} ;
} ;
} , { "../constants.js" : "iJA9" } ] , "bQx9" : [ function ( require , module , exports ) {
2018-06-28 21:02:50 +00:00
module . exports = function ( xs , fn ) {
var res = [ ] ;
for ( var i = 0 ; i < xs . length ; i ++ ) {
var x = fn ( xs [ i ] , i ) ;
if ( isArray ( x ) ) res . push . apply ( res , x ) ;
else res . push ( x ) ;
}
return res ;
} ;
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
var isArray = Array . isArray || function ( xs ) {
return Object . prototype . toString . call ( xs ) === '[object Array]' ;
} ;
2014-12-02 18:45:21 +00:00
2018-07-14 15:21:34 +00:00
} , { } ] , "6D9y" : [ function ( require , module , exports ) {
2018-06-28 21:02:50 +00:00
'use strict' ;
module . exports = balanced ;
function balanced ( a , b , str ) {
if ( a instanceof RegExp ) a = maybeMatch ( a , str ) ;
if ( b instanceof RegExp ) b = maybeMatch ( b , str ) ;
var r = range ( a , b , str ) ;
return r && {
start : r [ 0 ] ,
end : r [ 1 ] ,
pre : str . slice ( 0 , r [ 0 ] ) ,
body : str . slice ( r [ 0 ] + a . length , r [ 1 ] ) ,
post : str . slice ( r [ 1 ] + b . length )
} ;
2014-12-02 18:45:21 +00:00
}
2018-06-28 21:02:50 +00:00
function maybeMatch ( reg , str ) {
var m = str . match ( reg ) ;
return m ? m [ 0 ] : null ;
2014-12-02 18:45:21 +00:00
}
2018-06-28 21:02:50 +00:00
balanced . range = range ;
function range ( a , b , str ) {
var begs , beg , left , right , result ;
var ai = str . indexOf ( a ) ;
var bi = str . indexOf ( b , ai + 1 ) ;
var i = ai ;
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
if ( ai >= 0 && bi > 0 ) {
begs = [ ] ;
left = str . length ;
2015-05-31 15:18:20 +00:00
2018-06-28 21:02:50 +00:00
while ( i >= 0 && ! result ) {
if ( i == ai ) {
begs . push ( i ) ;
ai = str . indexOf ( a , i + 1 ) ;
} else if ( begs . length == 1 ) {
result = [ begs . pop ( ) , bi ] ;
} else {
beg = begs . pop ( ) ;
if ( beg < left ) {
left = beg ;
right = bi ;
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
bi = str . indexOf ( b , i + 1 ) ;
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
i = ai < bi && ai >= 0 ? ai : bi ;
}
if ( begs . length ) {
result = [ left , right ] ;
}
2014-12-02 18:45:21 +00:00
}
2018-06-28 21:02:50 +00:00
return result ;
}
2015-06-29 16:29:46 +00:00
2018-07-14 15:21:34 +00:00
} , { } ] , "dwX/" : [ function ( require , module , exports ) {
2018-06-28 21:02:50 +00:00
var concatMap = require ( 'concat-map' ) ;
var balanced = require ( 'balanced-match' ) ;
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
module . exports = expandTop ;
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
var escSlash = '\0SLASH' + Math . random ( ) + '\0' ;
var escOpen = '\0OPEN' + Math . random ( ) + '\0' ;
var escClose = '\0CLOSE' + Math . random ( ) + '\0' ;
var escComma = '\0COMMA' + Math . random ( ) + '\0' ;
var escPeriod = '\0PERIOD' + Math . random ( ) + '\0' ;
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
function numeric ( str ) {
return parseInt ( str , 10 ) == str
? parseInt ( str , 10 )
: str . charCodeAt ( 0 ) ;
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
function escapeBraces ( str ) {
return str . split ( '\\\\' ) . join ( escSlash )
. split ( '\\{' ) . join ( escOpen )
. split ( '\\}' ) . join ( escClose )
. split ( '\\,' ) . join ( escComma )
. split ( '\\.' ) . join ( escPeriod ) ;
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
function unescapeBraces ( str ) {
return str . split ( escSlash ) . join ( '\\' )
. split ( escOpen ) . join ( '{' )
. split ( escClose ) . join ( '}' )
. split ( escComma ) . join ( ',' )
. split ( escPeriod ) . join ( '.' ) ;
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
// Basically just str.split(","), but handling cases
// where we have nested braced sections, which should be
// treated as individual members, like {a,{b,c},d}
function parseCommaParts ( str ) {
if ( ! str )
return [ '' ] ;
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
var parts = [ ] ;
var m = balanced ( '{' , '}' , str ) ;
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
if ( ! m )
return str . split ( ',' ) ;
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
var pre = m . pre ;
var body = m . body ;
var post = m . post ;
var p = pre . split ( ',' ) ;
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
p [ p . length - 1 ] += '{' + body + '}' ;
var postParts = parseCommaParts ( post ) ;
if ( post . length ) {
p [ p . length - 1 ] += postParts . shift ( ) ;
p . push . apply ( p , postParts ) ;
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
parts . push . apply ( parts , p ) ;
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
return parts ;
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
function expandTop ( str ) {
if ( ! str )
return [ ] ;
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
// I don't know why Bash 4.3 does this, but it does.
// Anything starting with {} will have the first two bytes preserved
// but *only* at the top level, so {},a}b will not expand to anything,
// but a{},b}c will be expanded to [a}c,abc].
// One could argue that this is a bug in Bash, but since the goal of
// this module is to match Bash's rules, we escape a leading {}
if ( str . substr ( 0 , 2 ) === '{}' ) {
str = '\\{\\}' + str . substr ( 2 ) ;
2015-06-29 16:29:46 +00:00
}
2018-06-28 21:02:50 +00:00
return expand ( escapeBraces ( str ) , true ) . map ( unescapeBraces ) ;
2014-12-02 18:45:21 +00:00
}
2018-06-28 21:02:50 +00:00
function identity ( e ) {
return e ;
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
function embrace ( str ) {
return '{' + str + '}' ;
}
function isPadded ( el ) {
return /^-?0\d/ . test ( el ) ;
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
function lte ( i , y ) {
return i <= y ;
}
function gte ( i , y ) {
return i >= y ;
}
function expand ( str , isTop ) {
var expansions = [ ] ;
var m = balanced ( '{' , '}' , str ) ;
if ( ! m || /\$$/ . test ( m . pre ) ) return [ str ] ;
var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/ . test ( m . body ) ;
var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/ . test ( m . body ) ;
var isSequence = isNumericSequence || isAlphaSequence ;
var isOptions = m . body . indexOf ( ',' ) >= 0 ;
if ( ! isSequence && ! isOptions ) {
// {a},b}
if ( m . post . match ( /,.*\}/ ) ) {
str = m . pre + '{' + m . body + escClose + m . post ;
return expand ( str ) ;
2014-12-02 18:45:21 +00:00
}
2018-06-28 21:02:50 +00:00
return [ str ] ;
2014-12-02 18:45:21 +00:00
}
2018-06-28 21:02:50 +00:00
var n ;
if ( isSequence ) {
n = m . body . split ( /\.\./ ) ;
} else {
n = parseCommaParts ( m . body ) ;
if ( n . length === 1 ) {
// x{{a,b}}y ==> x{a}y x{b}y
n = expand ( n [ 0 ] , false ) . map ( embrace ) ;
if ( n . length === 1 ) {
var post = m . post . length
? expand ( m . post , false )
: [ '' ] ;
return post . map ( function ( p ) {
return m . pre + n [ 0 ] + p ;
} ) ;
}
}
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
// at this point, n is the parts, and we know it's not a comma set
// with a single entry.
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// no need to expand pre, since it is guaranteed to be free of brace-sets
var pre = m . pre ;
var post = m . post . length
? expand ( m . post , false )
: [ '' ] ;
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
var N ;
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
if ( isSequence ) {
var x = numeric ( n [ 0 ] ) ;
var y = numeric ( n [ 1 ] ) ;
var width = Math . max ( n [ 0 ] . length , n [ 1 ] . length )
var incr = n . length == 3
? Math . abs ( numeric ( n [ 2 ] ) )
: 1 ;
var test = lte ;
var reverse = y < x ;
if ( reverse ) {
incr *= - 1 ;
test = gte ;
}
var pad = n . some ( isPadded ) ;
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
N = [ ] ;
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
for ( var i = x ; test ( i , y ) ; i += incr ) {
var c ;
if ( isAlphaSequence ) {
c = String . fromCharCode ( i ) ;
if ( c === '\\' )
c = '' ;
} else {
c = String ( i ) ;
if ( pad ) {
var need = width - c . length ;
if ( need > 0 ) {
var z = new Array ( need + 1 ) . join ( '0' ) ;
if ( i < 0 )
c = '-' + z + c . slice ( 1 ) ;
else
c = z + c ;
}
2014-12-02 18:45:21 +00:00
}
2018-06-28 21:02:50 +00:00
}
N . push ( c ) ;
}
} else {
N = concatMap ( n , function ( el ) { return expand ( el , false ) } ) ;
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
for ( var j = 0 ; j < N . length ; j ++ ) {
for ( var k = 0 ; k < post . length ; k ++ ) {
var expansion = pre + N [ j ] + post [ k ] ;
if ( ! isTop || isSequence || expansion )
expansions . push ( expansion ) ;
}
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
return expansions ;
}
2014-12-02 18:45:21 +00:00
2018-07-14 15:21:34 +00:00
} , { "concat-map" : "bQx9" , "balanced-match" : "6D9y" } ] , "Nt/K" : [ function ( require , module , exports ) {
2018-06-28 21:02:50 +00:00
module . exports = minimatch
minimatch . Minimatch = Minimatch
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
var path = { sep : '/' }
try {
path = require ( 'path' )
} catch ( er ) { }
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
var GLOBSTAR = minimatch . GLOBSTAR = Minimatch . GLOBSTAR = { }
var expand = require ( 'brace-expansion' )
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
var plTypes = {
'!' : { open : '(?:(?!(?:' , close : '))[^/]*?)' } ,
'?' : { open : '(?:' , close : ')?' } ,
'+' : { open : '(?:' , close : ')+' } ,
'*' : { open : '(?:' , close : ')*' } ,
'@' : { open : '(?:' , close : ')' }
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// any single thing other than /
// don't need to escape / when using new RegExp()
var qmark = '[^/]'
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// * => any number of characters
var star = qmark + '*?'
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// ** when dots are allowed. Anything goes, except .. and .
// not (^ or / followed by one or two dots followed by $ or /),
// followed by anything, any number of times.
var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// not a ^ or / followed by a dot,
// followed by anything, any number of times.
var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// characters that need to be escaped in RegExp.
var reSpecials = charSet ( '().*{}+?[]^$\\!' )
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// "abc" -> { a:true, b:true, c:true }
function charSet ( s ) {
return s . split ( '' ) . reduce ( function ( set , c ) {
set [ c ] = true
return set
} , { } )
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// normalizes slashes.
var slashSplit = /\/+/
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
minimatch . filter = filter
function filter ( pattern , options ) {
options = options || { }
return function ( p , i , list ) {
return minimatch ( p , pattern , options )
}
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
function ext ( a , b ) {
a = a || { }
b = b || { }
var t = { }
Object . keys ( b ) . forEach ( function ( k ) {
t [ k ] = b [ k ]
} )
Object . keys ( a ) . forEach ( function ( k ) {
t [ k ] = a [ k ]
} )
return t
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
minimatch . defaults = function ( def ) {
if ( ! def || ! Object . keys ( def ) . length ) return minimatch
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
var orig = minimatch
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
var m = function minimatch ( p , pattern , options ) {
return orig . minimatch ( p , pattern , ext ( def , options ) )
2014-12-02 18:45:21 +00:00
}
2018-06-28 21:02:50 +00:00
m . Minimatch = function Minimatch ( pattern , options ) {
return new orig . Minimatch ( pattern , ext ( def , options ) )
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
return m
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
Minimatch . defaults = function ( def ) {
if ( ! def || ! Object . keys ( def ) . length ) return Minimatch
return minimatch . defaults ( def ) . Minimatch
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
function minimatch ( p , pattern , options ) {
if ( typeof pattern !== 'string' ) {
throw new TypeError ( 'glob pattern string required' )
2014-12-02 18:45:21 +00:00
}
2018-06-28 21:02:50 +00:00
if ( ! options ) options = { }
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// shortcut: comments match nothing.
if ( ! options . nocomment && pattern . charAt ( 0 ) === '#' ) {
return false
2014-12-02 18:45:21 +00:00
}
2018-06-28 21:02:50 +00:00
// "" only matches ""
if ( pattern . trim ( ) === '' ) return p === ''
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
return new Minimatch ( pattern , options ) . match ( p )
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
function Minimatch ( pattern , options ) {
if ( ! ( this instanceof Minimatch ) ) {
return new Minimatch ( pattern , options )
2014-12-02 18:45:21 +00:00
}
2018-06-28 21:02:50 +00:00
if ( typeof pattern !== 'string' ) {
throw new TypeError ( 'glob pattern string required' )
2014-12-02 18:45:21 +00:00
}
2018-06-28 21:02:50 +00:00
if ( ! options ) options = { }
pattern = pattern . trim ( )
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// windows support: need to use /, not \
if ( path . sep !== '/' ) {
pattern = pattern . split ( path . sep ) . join ( '/' )
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
this . options = options
this . set = [ ]
this . pattern = pattern
this . regexp = null
this . negate = false
this . comment = false
this . empty = false
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// make the set of regexps etc.
this . make ( )
2014-12-02 18:45:21 +00:00
}
2018-06-28 21:02:50 +00:00
Minimatch . prototype . debug = function ( ) { }
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
Minimatch . prototype . make = make
function make ( ) {
// don't do it more than once.
if ( this . _made ) return
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
var pattern = this . pattern
2014-12-02 18:45:21 +00:00
var options = this . options
2018-06-28 21:02:50 +00:00
// empty patterns and comments match nothing.
if ( ! options . nocomment && pattern . charAt ( 0 ) === '#' ) {
this . comment = true
return
}
if ( ! pattern ) {
this . empty = true
return
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// step 1: figure out negation, etc.
this . parseNegate ( )
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// step 2: expand braces
var set = this . globSet = this . braceExpand ( )
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
if ( options . debug ) this . debug = console . error
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
this . debug ( this . pattern , set )
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// step 3: now we have a set, so turn each one into a series of path-portion
// matching patterns.
// These will be regexps, except in the case of "**", which is
// set to the GLOBSTAR object for globstar behavior,
// and will not contain any / characters
set = this . globParts = set . map ( function ( s ) {
return s . split ( slashSplit )
2014-12-02 18:45:21 +00:00
} )
2014-06-09 14:40:50 +00:00
2018-06-28 21:02:50 +00:00
this . debug ( this . pattern , set )
2014-06-09 14:40:50 +00:00
2018-06-28 21:02:50 +00:00
// glob --> regexps
set = set . map ( function ( s , si , set ) {
return s . map ( this . parse , this )
} , this )
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
this . debug ( this . pattern , set )
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// filter out everything that didn't compile properly.
set = set . filter ( function ( s ) {
return s . indexOf ( false ) === - 1
} )
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
this . debug ( this . pattern , set )
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
this . set = set
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
Minimatch . prototype . parseNegate = parseNegate
function parseNegate ( ) {
var pattern = this . pattern
var negate = false
var options = this . options
var negateOffset = 0
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
if ( options . nonegate ) return
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
for ( var i = 0 , l = pattern . length
; i < l && pattern . charAt ( i ) === '!'
; i ++ ) {
negate = ! negate
negateOffset ++
2014-12-02 18:45:21 +00:00
}
2018-06-28 21:02:50 +00:00
if ( negateOffset ) this . pattern = pattern . substr ( negateOffset )
this . negate = negate
2014-12-02 18:45:21 +00:00
}
2018-06-28 21:02:50 +00:00
// Brace expansion:
// a{b,c}d -> abd acd
// a{b,}c -> abc ac
// a{0..3}d -> a0d a1d a2d a3d
// a{b,c{d,e}f}g -> abg acdfg acefg
// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
//
// Invalid sets are not expanded.
// a{2..}b -> a{2..}b
// a{b}c -> a{b}c
minimatch . braceExpand = function ( pattern , options ) {
return braceExpand ( pattern , options )
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
Minimatch . prototype . braceExpand = braceExpand
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
function braceExpand ( pattern , options ) {
if ( ! options ) {
if ( this instanceof Minimatch ) {
options = this . options
} else {
options = { }
}
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
pattern = typeof pattern === 'undefined'
? this . pattern : pattern
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
if ( typeof pattern === 'undefined' ) {
throw new TypeError ( 'undefined pattern' )
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
if ( options . nobrace ||
! pattern . match ( /\{.*\}/ ) ) {
// shortcut. no need to expand.
return [ pattern ]
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
return expand ( pattern )
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// parse a component of the expanded set.
// At this point, no pattern may contain "/" in it
// so we're going to return a 2d array, where each entry is the full
// pattern, split on '/', and then turned into a regular expression.
// A regexp is made at the end which joins each array with an
// escaped /, and another full one which joins each regexp with |.
//
// Following the lead of Bash 4.1, note that "**" only has special meaning
// when it is the *only* thing in a path portion. Otherwise, any series
// of * is equivalent to a single *. Globstar behavior is enabled by
// default, and can be disabled by setting options.noglobstar.
Minimatch . prototype . parse = parse
var SUBPARSE = { }
function parse ( pattern , isSub ) {
if ( pattern . length > 1024 * 64 ) {
throw new TypeError ( 'pattern is too long' )
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
var options = this . options
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// shortcuts
if ( ! options . noglobstar && pattern === '**' ) return GLOBSTAR
if ( pattern === '' ) return ''
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
var re = ''
var hasMagic = ! ! options . nocase
var escaping = false
// ? => one single character
var patternListStack = [ ]
var negativeLists = [ ]
var stateChar
var inClass = false
var reClassStart = - 1
var classStart = - 1
// . and .. never match anything that doesn't start with .,
// even when options.dot is set.
var patternStart = pattern . charAt ( 0 ) === '.' ? '' // anything
// not (start or / followed by . or .. followed by / or end)
: options . dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))'
: '(?!\\.)'
var self = this
2014-06-09 14:40:50 +00:00
2018-06-28 21:02:50 +00:00
function clearStateChar ( ) {
if ( stateChar ) {
// we had some state-tracking character
// that wasn't consumed by this pass.
switch ( stateChar ) {
case '*' :
re += star
hasMagic = true
break
case '?' :
re += qmark
hasMagic = true
break
default :
re += '\\' + stateChar
break
2014-12-02 18:45:21 +00:00
}
2018-06-28 21:02:50 +00:00
self . debug ( 'clearStateChar %j %j' , stateChar , re )
stateChar = false
2014-12-02 18:45:21 +00:00
}
}
2018-06-28 21:02:50 +00:00
for ( var i = 0 , len = pattern . length , c
; ( i < len ) && ( c = pattern . charAt ( i ) )
; i ++ ) {
this . debug ( '%s\t%s %s %j' , pattern , i , re , c )
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// skip over any that are escaped.
if ( escaping && reSpecials [ c ] ) {
re += '\\' + c
escaping = false
continue
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
switch ( c ) {
case '/' :
// completely not allowed, even escaped.
// Should already be path-split by now.
return false
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
case '\\' :
clearStateChar ( )
escaping = true
continue
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
// the various stateChar values
// for the "extglob" stuff.
case '?' :
case '*' :
case '+' :
case '@' :
case '!' :
this . debug ( '%s\t%s %s %j <-- stateChar' , pattern , i , re , c )
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// all of those are literals inside a class, except that
// the glob [!a] means [^a] in regexp
if ( inClass ) {
this . debug ( ' in class' )
if ( c === '!' && i === classStart + 1 ) c = '^'
re += c
continue
}
2014-12-02 18:45:21 +00:00
2018-07-14 15:21:34 +00:00
// if we already have a stateChar, then it means
// that there was something like ** or +? in there.
// Handle the stateChar, then proceed with this one.
self . debug ( 'call clearStateChar %j' , stateChar )
clearStateChar ( )
stateChar = c
// if extglob is disabled, then +(asdf|foo) isn't a thing.
// just clear the statechar *now*, rather than even diving into
// the patternList stuff.
if ( options . noext ) clearStateChar ( )
continue
2014-12-02 18:45:21 +00:00
2018-07-14 15:21:34 +00:00
case '(' :
if ( inClass ) {
re += '('
continue
}
2014-06-09 14:40:50 +00:00
2018-07-14 15:21:34 +00:00
if ( ! stateChar ) {
re += '\\('
continue
}
2014-06-09 14:40:50 +00:00
2018-07-14 15:21:34 +00:00
patternListStack . push ( {
type : stateChar ,
start : i - 1 ,
reStart : re . length ,
open : plTypes [ stateChar ] . open ,
close : plTypes [ stateChar ] . close
} )
// negation is (?:(?!js)[^/]*)
re += stateChar === '!' ? '(?:(?!(?:' : '(?:'
this . debug ( 'plType %j %j' , stateChar , re )
stateChar = false
continue
2014-06-09 14:40:50 +00:00
2018-07-14 15:21:34 +00:00
case ')' :
if ( inClass || ! patternListStack . length ) {
re += '\\)'
continue
}
2014-06-09 14:40:50 +00:00
2018-07-14 15:21:34 +00:00
clearStateChar ( )
hasMagic = true
var pl = patternListStack . pop ( )
// negation is (?:(?!js)[^/]*)
// The others are (?:<pattern>)<type>
re += pl . close
if ( pl . type === '!' ) {
negativeLists . push ( pl )
}
pl . reEnd = re . length
continue
2015-06-29 16:29:46 +00:00
2018-07-14 15:21:34 +00:00
case '|' :
if ( inClass || ! patternListStack . length || escaping ) {
re += '\\|'
escaping = false
continue
}
2018-05-29 18:03:59 +00:00
2018-07-14 15:21:34 +00:00
clearStateChar ( )
re += '|'
continue
2015-06-29 16:29:46 +00:00
2018-07-14 15:21:34 +00:00
// these are mostly the same in regexp and glob
case '[' :
// swallow any state-tracking char before the [
clearStateChar ( )
2014-06-09 14:40:50 +00:00
2018-07-14 15:21:34 +00:00
if ( inClass ) {
re += '\\' + c
continue
}
2014-12-02 18:45:21 +00:00
2018-07-14 15:21:34 +00:00
inClass = true
classStart = i
reClassStart = re . length
re += c
continue
2015-06-29 16:29:46 +00:00
2018-07-14 15:21:34 +00:00
case ']' :
// a right bracket shall lose its special
// meaning and represent itself in
// a bracket expression if it occurs
// first in the list. -- POSIX.2 2.8.3.2
if ( i === classStart + 1 || ! inClass ) {
re += '\\' + c
escaping = false
continue
}
2018-06-28 21:02:50 +00:00
// handle the case where we left a class open.
// "[z-a]" is valid, equivalent to "\[z-a\]"
if ( inClass ) {
// split where the last [ was, make sure we don't have
// an invalid re. if so, re-walk the contents of the
// would-be class to re-translate any characters that
// were passed through as-is
// TODO: It would probably be faster to determine this
// without a try/catch and a new RegExp, but it's tricky
// to do safely. For now, this is safe and works.
var cs = pattern . substring ( classStart + 1 , i )
try {
RegExp ( '[' + cs + ']' )
} catch ( er ) {
// not a valid class!
var sp = this . parse ( cs , SUBPARSE )
re = re . substr ( 0 , reClassStart ) + '\\[' + sp [ 0 ] + '\\]'
hasMagic = hasMagic || sp [ 1 ]
inClass = false
continue
}
}
// finish up the class.
hasMagic = true
inClass = false
re += c
continue
default :
// swallow any state char that wasn't consumed
clearStateChar ( )
if ( escaping ) {
// no need
escaping = false
} else if ( reSpecials [ c ]
&& ! ( c === '^' && inClass ) ) {
re += '\\'
}
re += c
} // switch
} // for
// handle the case where we left a class open.
// "[abc" is valid, equivalent to "\[abc"
if ( inClass ) {
// split where the last [ was, and escape it
// this is a huge pita. We now have to re-walk
// the contents of the would-be class to re-translate
// any characters that were passed through as-is
cs = pattern . substr ( classStart + 1 )
sp = this . parse ( cs , SUBPARSE )
re = re . substr ( 0 , reClassStart ) + '\\[' + sp [ 0 ]
hasMagic = hasMagic || sp [ 1 ]
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// handle the case where we had a +( thing at the *end*
// of the pattern.
// each pattern list stack adds 3 chars, and we need to go through
// and escape any | chars that were passed through as-is for the regexp.
// Go through and escape them, taking care not to double-escape any
// | chars that were already escaped.
for ( pl = patternListStack . pop ( ) ; pl ; pl = patternListStack . pop ( ) ) {
var tail = re . slice ( pl . reStart + pl . open . length )
this . debug ( 'setting tail' , re , pl )
// maybe some even number of \, then maybe 1 \, followed by a |
tail = tail . replace ( /((?:\\{2}){0,64})(\\?)\|/g , function ( _ , $1 , $2 ) {
if ( ! $2 ) {
// the | isn't already escaped, so escape it.
$2 = '\\'
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
// need to escape all those slashes *again*, without escaping the
// one that we need for escaping the | character. As it works out,
// escaping an even number of slashes can be done by simply repeating
// it exactly after itself. That's why this trick works.
//
// I am sorry that you have to see this.
return $1 + $1 + $2 + '|'
} )
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
this . debug ( 'tail=%j\n %s' , tail , tail , pl , re )
var t = pl . type === '*' ? star
: pl . type === '?' ? qmark
: '\\' + pl . type
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
hasMagic = true
re = re . slice ( 0 , pl . reStart ) + t + '\\(' + tail
}
2015-07-16 21:56:12 +00:00
2018-06-28 21:02:50 +00:00
// handle trailing things that only matter at the very end.
clearStateChar ( )
if ( escaping ) {
// trailing \\
re += '\\\\'
2018-05-29 18:03:59 +00:00
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// only need to apply the nodot start if the re starts with
// something that could conceivably capture a dot
var addPatternStart = false
switch ( re . charAt ( 0 ) ) {
case '.' :
case '[' :
case '(' : addPatternStart = true
2015-06-29 16:29:46 +00:00
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// Hack to work around lack of negative lookbehind in JS
// A pattern like: *.!(x).!(y|z) needs to ensure that a name
// like 'a.xyz.yz' doesn't match. So, the first negative
// lookahead, has to look ALL the way ahead, to the end of
// the pattern.
for ( var n = negativeLists . length - 1 ; n > - 1 ; n -- ) {
var nl = negativeLists [ n ]
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
var nlBefore = re . slice ( 0 , nl . reStart )
var nlFirst = re . slice ( nl . reStart , nl . reEnd - 8 )
var nlLast = re . slice ( nl . reEnd - 8 , nl . reEnd )
var nlAfter = re . slice ( nl . reEnd )
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
nlLast += nlAfter
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
// Handle nested stuff like *(*.js|!(*.json)), where open parens
// mean that we should *not* include the ) in the bit that is considered
// "after" the negated section.
var openParensBefore = nlBefore . split ( '(' ) . length - 1
var cleanAfter = nlAfter
for ( i = 0 ; i < openParensBefore ; i ++ ) {
cleanAfter = cleanAfter . replace ( /\)[+*?]?/ , '' )
}
nlAfter = cleanAfter
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
var dollar = ''
if ( nlAfter === '' && isSub !== SUBPARSE ) {
dollar = '$'
}
var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast
re = newRe
2015-05-31 15:18:20 +00:00
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// if the re is not "" at this point, then we need to make sure
// it doesn't match against an empty path part.
// Otherwise a/* will match a/, which it should not.
if ( re !== '' && hasMagic ) {
re = '(?=.)' + re
2015-07-16 21:56:12 +00:00
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
if ( addPatternStart ) {
re = patternStart + re
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// parsing just a piece of a larger pattern.
if ( isSub === SUBPARSE ) {
return [ re , hasMagic ]
}
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// skip the regexp for non-magical patterns
// unescape anything in it, though, so that it'll be
// an exact match against a file etc.
if ( ! hasMagic ) {
return globUnescape ( pattern )
2014-12-02 18:45:21 +00:00
}
2018-06-28 21:02:50 +00:00
var flags = options . nocase ? 'i' : ''
try {
var regExp = new RegExp ( '^' + re + '$' , flags )
} catch ( er ) {
// If it was an invalid regular expression, then it can't match
// anything. This trick looks for a character after the end of
// the string, which is of course impossible, except in multi-line
// mode, but it's not a /m regex.
return new RegExp ( '$.' )
}
2018-05-29 18:03:59 +00:00
2018-06-28 21:02:50 +00:00
regExp . _glob = pattern
regExp . _src = re
2018-05-29 18:03:59 +00:00
2018-06-28 21:02:50 +00:00
return regExp
2014-12-02 18:45:21 +00:00
}
2018-06-28 21:02:50 +00:00
minimatch . makeRe = function ( pattern , options ) {
return new Minimatch ( pattern , options || { } ) . makeRe ( )
}
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
Minimatch . prototype . makeRe = makeRe
function makeRe ( ) {
if ( this . regexp || this . regexp === false ) return this . regexp
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
// at this point, this.set is a 2d array of partial
// pattern strings, or "**".
//
// It's better to use .match(). This function shouldn't
// be used, really, but it's pretty convenient sometimes,
// when you just want to work with a regex.
var set = this . set
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
if ( ! set . length ) {
this . regexp = false
return this . regexp
}
var options = this . options
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
var twoStar = options . noglobstar ? star
: options . dot ? twoStarDot
: twoStarNoDot
var flags = options . nocase ? 'i' : ''
2015-06-29 16:29:46 +00:00
2018-06-28 21:02:50 +00:00
var re = set . map ( function ( pattern ) {
return pattern . map ( function ( p ) {
return ( p === GLOBSTAR ) ? twoStar
: ( typeof p === 'string' ) ? regExpEscape ( p )
: p . _src
} ) . join ( '\\\/' )
} ) . join ( '|' )
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// must match entire pattern
// ending in a * or ** will make it less strict.
re = '^(?:' + re + ')$'
2014-12-02 18:45:21 +00:00
2018-06-28 21:02:50 +00:00
// can match anything, as long as it's not this.
if ( this . negate ) re = '^(?!' + re + ').*$'
2014-08-17 05:56:03 +00:00
2018-06-28 21:02:50 +00:00
try {
this . regexp = new RegExp ( re , flags )
} catch ( ex ) {
this . regexp = false
2014-08-17 05:56:03 +00:00
}
2018-06-28 21:02:50 +00:00
return this . regexp
2018-06-28 17:35:20 +00:00
}
2014-08-17 05:56:03 +00:00
2018-06-28 21:02:50 +00:00
minimatch . match = function ( list , pattern , options ) {
options = options || { }
var mm = new Minimatch ( pattern , options )
list = list . filter ( function ( f ) {
return mm . match ( f )
} )
if ( mm . options . nonull && ! list . length ) {
list . push ( pattern )
2014-08-17 05:56:03 +00:00
}
2018-06-28 21:02:50 +00:00
return list
2018-06-28 17:35:20 +00:00
}
2014-08-17 05:56:03 +00:00
2018-06-28 21:02:50 +00:00
Minimatch . prototype . match = match
function match ( f , partial ) {
this . debug ( 'match' , f , this . pattern )
// short-circuit in the case of busted things.
// comments, etc.
if ( this . comment ) return false
if ( this . empty ) return f === ''
2014-05-27 18:44:30 +00:00
2018-06-28 21:02:50 +00:00
if ( f === '/' && partial ) return true
2014-05-27 18:44:30 +00:00
2018-06-28 21:02:50 +00:00
var options = this . options
2014-05-27 18:44:30 +00:00
2018-06-28 21:02:50 +00:00
// windows: need to use /, not \
if ( path . sep !== '/' ) {
f = f . split ( path . sep ) . join ( '/' )
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-07-14 15:21:34 +00:00
// treat the test path as a set of pathparts.
f = f . split ( slashSplit )
this . debug ( this . pattern , 'split' , f )
2014-05-27 18:44:30 +00:00
2018-07-14 15:21:34 +00:00
// just ONE of the pattern sets in this.set needs to match
// in order for it to be valid. If negating, then just one
// match means that we have failed.
// Either way, return on the first hit.
2014-05-27 18:44:30 +00:00
2018-07-14 15:21:34 +00:00
var set = this . set
this . debug ( this . pattern , 'set' , set )
2018-05-29 18:03:59 +00:00
2018-07-14 15:21:34 +00:00
// Find the basename of the path by looking for the last non-empty segment
var filename
var i
for ( i = f . length - 1 ; i >= 0 ; i -- ) {
filename = f [ i ]
if ( filename ) break
}
2018-06-28 17:35:20 +00:00
2018-07-14 15:21:34 +00:00
for ( i = 0 ; i < set . length ; i ++ ) {
var pattern = set [ i ]
var file = f
if ( options . matchBase && pattern . length === 1 ) {
file = [ filename ]
2018-06-28 17:35:20 +00:00
}
2018-07-14 15:21:34 +00:00
var hit = this . matchOne ( file , pattern , partial )
if ( hit ) {
if ( options . flipNegate ) return true
return ! this . negate
2018-06-28 21:02:50 +00:00
}
2018-06-28 17:35:20 +00:00
}
2018-07-14 15:21:34 +00:00
// didn't get any hits. this is success if it's a negative
// pattern, failure otherwise.
if ( options . flipNegate ) return false
return this . negate
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
2018-07-14 15:21:34 +00:00
// set partial to true to test if, for example,
// "/a/b" matches the start of "/*/b/*/d"
// Partial means, if you run out of file before you run
// out of pattern, then that's fine, as long as all
// the parts match.
Minimatch . prototype . matchOne = function ( file , pattern , partial ) {
var options = this . options
2018-06-28 17:35:20 +00:00
2018-07-14 15:21:34 +00:00
this . debug ( 'matchOne' ,
{ 'this' : this , file : file , pattern : pattern } )
2018-06-28 17:35:20 +00:00
2018-07-14 15:21:34 +00:00
this . debug ( 'matchOne' , file . length , pattern . length )
2018-06-28 17:35:20 +00:00
2018-07-14 15:21:34 +00:00
for ( var fi = 0 ,
pi = 0 ,
fl = file . length ,
pl = pattern . length
; ( fi < fl ) && ( pi < pl )
; fi ++ , pi ++ ) {
this . debug ( 'matchOne loop' )
var p = pattern [ pi ]
var f = file [ fi ]
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
this . debug ( pattern , p , f )
// should be impossible.
// some invalid regexp stuff in the set.
if ( p === false ) return false
if ( p === GLOBSTAR ) {
this . debug ( 'GLOBSTAR' , [ pattern , p , f ] )
// "**"
// a/**/b/**/c would match the following:
// a/b/x/y/z/c
// a/x/y/z/b/c
// a/b/x/b/x/c
// a/b/c
// To do this, take the rest of the pattern after
// the **, and see if it would match the file remainder.
// If so, return success.
// If not, the ** "swallows" a segment, and try again.
// This is recursively awful.
//
// a/**/b/**/c matching a/b/x/y/z/c
// - a matches a
// - doublestar
// - matchOne(b/x/y/z/c, b/**/c)
// - b matches b
// - doublestar
// - matchOne(x/y/z/c, c) -> no
// - matchOne(y/z/c, c) -> no
// - matchOne(z/c, c) -> no
// - matchOne(c, c) yes, hit
var fr = fi
var pr = pi + 1
if ( pr === pl ) {
this . debug ( '** at the end' )
// a ** at the end will just swallow the rest.
// We have found a match.
// however, it will not swallow /.x, unless
// options.dot is set.
// . and .. are *never* matched by **, for explosively
// exponential reasons.
for ( ; fi < fl ; fi ++ ) {
if ( file [ fi ] === '.' || file [ fi ] === '..' ||
( ! options . dot && file [ fi ] . charAt ( 0 ) === '.' ) ) return false
}
return true
}
// ok, let's see if we can swallow whatever we can.
while ( fr < fl ) {
var swallowee = file [ fr ]
this . debug ( '\nglobstar while' , file , fr , pattern , pr , swallowee )
// XXX remove this slice. Just pass the start index.
if ( this . matchOne ( file . slice ( fr ) , pattern . slice ( pr ) , partial ) ) {
this . debug ( 'globstar found match!' , fr , fl , swallowee )
// found a match.
return true
} else {
// can't swallow "." or ".." ever.
// can only swallow ".foo" when explicitly asked.
if ( swallowee === '.' || swallowee === '..' ||
( ! options . dot && swallowee . charAt ( 0 ) === '.' ) ) {
this . debug ( 'dot detected!' , file , fr , pattern , pr )
break
}
// ** swallows a segment, and continue.
this . debug ( 'globstar swallow a segment, and continue' )
fr ++
}
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
// no match was found.
// However, in partial mode, we can't say this is necessarily over.
// If there's more *pattern* left, then
if ( partial ) {
// ran out of file
this . debug ( '\n>>> no match, partial?' , file , fr , pattern , pr )
if ( fr === fl ) return true
}
return false
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
// something other than **
// non-magic patterns just have to match exactly
// patterns with magic have been turned into regexps.
var hit
if ( typeof p === 'string' ) {
if ( options . nocase ) {
hit = f . toLowerCase ( ) === p . toLowerCase ( )
2018-06-28 17:35:20 +00:00
} else {
2018-06-28 21:02:50 +00:00
hit = f === p
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
this . debug ( 'string match' , p , f , hit )
} else {
hit = f . match ( p )
this . debug ( 'pattern match' , p , f , hit )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
if ( ! hit ) return false
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
// Note: ending in / means that we'll get a final ""
// at the end of the pattern. This can only match a
// corresponding "" at the end of the file.
// If the file ends in /, then it can only match a
// a pattern that ends in /, unless the pattern just
// doesn't have any more for it. But, a/b/ should *not*
// match "a/b/*", even though "" matches against the
// [^/]*? pattern, except in partial mode, where it might
// simply not be reached yet.
// However, a/b/ should still satisfy a/*
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
// now either we fell off the end of the pattern, or we're done.
if ( fi === fl && pi === pl ) {
// ran out of pattern and filename at the same time.
// an exact hit!
return true
} else if ( fi === fl ) {
// ran out of file, but still had pattern left.
// this is ok if we're doing the match as part of
// a glob fs traversal.
return partial
} else if ( pi === pl ) {
// ran out of pattern, still have file left.
// this is only acceptable if we're on the very last
// empty segment of a file with a trailing slash.
// a/* should match a/b/
var emptyFileEnd = ( fi === fl - 1 ) && ( file [ fi ] === '' )
return emptyFileEnd
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
// should be unreachable.
throw new Error ( 'wtf?' )
}
// replace stuff like \* with *
function globUnescape ( s ) {
return s . replace ( /\\(.)/g , '$1' )
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
function regExpEscape ( s ) {
return s . replace ( /[-[\]{}()*+?.,\\^$|#\s]/g , '\\$&' )
2018-06-28 17:35:20 +00:00
}
2018-07-14 15:21:34 +00:00
} , { "path" : "UUq2" , "brace-expansion" : "dwX/" } ] , "D1Ra" : [ function ( require , module , exports ) {
2018-10-30 18:35:33 +00:00
var _require = require ( 'es6-promisify' ) ,
promisify = _require . promisify ;
2018-06-28 17:35:20 +00:00
var Path = require ( '../path.js' ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var Errors = require ( '../errors.js' ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var Environment = require ( './environment.js' ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var async = require ( '../../lib/async.js' ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
var minimatch = require ( 'minimatch' ) ;
2018-06-28 17:35:20 +00:00
function Shell ( fs , options ) {
2018-10-30 18:35:33 +00:00
var _this = this ;
2018-06-28 17:35:20 +00:00
options = options || { } ;
var env = new Environment ( options . env ) ;
var cwd = '/' ;
/ * *
* The bound FileSystem ( cannot be changed )
* /
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
Object . defineProperty ( this , 'fs' , {
get : function get ( ) {
return fs ;
} ,
enumerable : true
} ) ;
/ * *
* The shell ' s environment ( e . g . , for things like
* path , tmp , and other env vars ) . Use env . get ( )
* and env . set ( ) to work with variables .
* /
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
Object . defineProperty ( this , 'env' , {
get : function get ( ) {
return env ;
} ,
enumerable : true
} ) ;
/ * *
* Change the current working directory . We
* include ` cd ` on the ` this ` vs . proto so that
* we can access cwd without exposing it externally .
* /
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
this . cd = function ( path , callback ) {
2018-12-21 19:22:25 +00:00
path = Path . resolve ( cwd , path ) ; // Make sure the path actually exists, and is a dir
2018-06-28 17:35:20 +00:00
fs . stat ( path , function ( err , stats ) {
if ( err ) {
callback ( new Errors . ENOTDIR ( null , path ) ) ;
return ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( stats . type === 'DIRECTORY' ) {
cwd = path ;
callback ( ) ;
} else {
callback ( new Errors . ENOTDIR ( null , path ) ) ;
}
} ) ;
} ;
/ * *
* Get the current working directory ( changed with ` cd() ` )
* /
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
this . pwd = function ( ) {
return cwd ;
} ;
2018-10-30 18:35:33 +00:00
this . promises = { } ;
/ * *
* Public API for Shell converted to Promise based
* /
2018-12-21 19:22:25 +00:00
2018-10-30 18:35:33 +00:00
[ 'cd' , 'exec' , 'touch' , 'cat' , 'ls' , 'rm' , 'tempDir' , 'mkdirp' , 'find' ] . forEach ( function ( methodName ) {
_this . promises [ methodName ] = promisify ( _this [ methodName ] . bind ( _this ) ) ;
} ) ;
2018-06-28 17:35:20 +00:00
}
/ * *
* Execute the . js command located at ` path ` . Such commands
* should assume the existence of 3 arguments , which will be
* defined at runtime :
*
* * fs - the current shell ' s bound filesystem object
* * args - a list of arguments for the command , or an empty list if none
* * callback - a callback function ( error , result ) to call when done .
*
* The . js command ' s contents should be the body of a function
* that looks like this :
*
* function ( fs , args , callback ) {
* // .js code here
* }
* /
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
Shell . prototype . exec = function ( path , args , callback ) {
/* jshint evil:true */
var sh = this ;
var fs = sh . fs ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( typeof args === 'function' ) {
callback = args ;
args = [ ] ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
args = args || [ ] ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
callback = callback || function ( ) { } ;
2018-12-21 19:22:25 +00:00
path = Path . resolve ( sh . pwd ( ) , path ) ;
2018-10-30 18:35:33 +00:00
fs . readFile ( path , 'utf8' , function ( error , data ) {
2018-06-28 17:35:20 +00:00
if ( error ) {
callback ( error ) ;
return ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
try {
var cmd = new Function ( 'fs' , 'args' , 'callback' , data ) ;
cmd ( fs , args , callback ) ;
} catch ( e ) {
callback ( e ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
} ) ;
} ;
/ * *
* Create a file if it does not exist , or update access and
* modified times if it does . Valid options include :
*
* * updateOnly - whether to create the file if missing ( defaults to false )
* * date - use the provided Date value instead of current date / time
* /
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
Shell . prototype . touch = function ( path , options , callback ) {
var sh = this ;
var fs = sh . fs ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( typeof options === 'function' ) {
callback = options ;
options = { } ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
options = options || { } ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
callback = callback || function ( ) { } ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
path = Path . resolve ( sh . pwd ( ) , path ) ;
function createFile ( path ) {
fs . writeFile ( path , '' , callback ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function updateTimes ( path ) {
var now = Date . now ( ) ;
var atime = options . date || now ;
var mtime = options . date || now ;
fs . utimes ( path , atime , mtime , callback ) ;
}
2018-10-30 18:35:33 +00:00
fs . stat ( path , function ( error ) {
2018-06-28 17:35:20 +00:00
if ( error ) {
if ( options . updateOnly === true ) {
callback ( ) ;
2014-05-27 18:44:30 +00:00
} else {
2018-06-28 17:35:20 +00:00
createFile ( path ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
} else {
updateTimes ( path ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
} ) ;
} ;
/ * *
* Concatenate multiple files into a single String , with each
* file separated by a newline . The ` files ` argument should
* be a String ( path to single file ) or an Array of Strings
* ( multiple file paths ) .
* /
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
Shell . prototype . cat = function ( files , callback ) {
var sh = this ;
var fs = sh . fs ;
var all = '' ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
callback = callback || function ( ) { } ;
if ( ! files ) {
callback ( new Errors . EINVAL ( 'Missing files argument' ) ) ;
return ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
files = typeof files === 'string' ? [ files ] : files ;
function append ( item , callback ) {
var filename = Path . resolve ( sh . pwd ( ) , item ) ;
fs . readFile ( filename , 'utf8' , function ( error , data ) {
if ( error ) {
callback ( error ) ;
return ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
all += data + '\n' ;
callback ( ) ;
} ) ;
}
async . eachSeries ( files , append , function ( error ) {
if ( error ) {
2014-05-27 18:44:30 +00:00
callback ( error ) ;
} else {
2018-06-28 17:35:20 +00:00
callback ( null , all . replace ( /\n$/ , '' ) ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
} ) ;
} ;
/ * *
* Get the listing of a directory , returning an array of
* file entries in the following form :
*
* {
* path : < String > the basename of the directory entry
* links : < Number > the number of links to the entry
* size : < Number > the size in bytes of the entry
* modified : < Number > the last modified date / time
* type : < String > the type of the entry
* contents : < Array > an optional array of child entries
* }
*
* By default ls ( ) gives a shallow listing . If you want
* to follow directories as they are encountered , use
* the ` recursive=true ` option .
* /
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
Shell . prototype . ls = function ( dir , options , callback ) {
var sh = this ;
var fs = sh . fs ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( typeof options === 'function' ) {
callback = options ;
options = { } ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
options = options || { } ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
callback = callback || function ( ) { } ;
if ( ! dir ) {
callback ( new Errors . EINVAL ( 'Missing dir argument' ) ) ;
return ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function list ( path , callback ) {
var pathname = Path . resolve ( sh . pwd ( ) , path ) ;
var result = [ ] ;
fs . readdir ( pathname , function ( error , entries ) {
if ( error ) {
callback ( error ) ;
return ;
}
function getDirEntry ( name , callback ) {
name = Path . join ( pathname , name ) ;
fs . stat ( name , function ( error , stats ) {
if ( error ) {
callback ( error ) ;
return ;
}
2018-12-21 19:22:25 +00:00
2018-07-14 15:21:34 +00:00
var entry = stats ;
2018-06-28 17:35:20 +00:00
if ( options . recursive && stats . type === 'DIRECTORY' ) {
2018-07-14 15:21:34 +00:00
list ( Path . join ( pathname , entry . name ) , function ( error , items ) {
2018-06-28 17:35:20 +00:00
if ( error ) {
callback ( error ) ;
return ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
entry . contents = items ;
result . push ( entry ) ;
callback ( ) ;
} ) ;
} else {
result . push ( entry ) ;
callback ( ) ;
}
} ) ;
}
async . eachSeries ( entries , getDirEntry , function ( error ) {
callback ( error , result ) ;
} ) ;
} ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
list ( dir , callback ) ;
} ;
2014-05-27 18:44:30 +00:00
/ * *
2018-06-28 17:35:20 +00:00
* Removes the file or directory at ` path ` . If ` path ` is a file
* it will be removed . If ` path ` is a directory , it will be
* removed if it is empty , otherwise the callback will receive
* an error . In order to remove non - empty directories , use the
* ` recursive=true ` option .
2014-05-27 18:44:30 +00:00
* /
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
Shell . prototype . rm = function ( path , options , callback ) {
var sh = this ;
var fs = sh . fs ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( typeof options === 'function' ) {
callback = options ;
options = { } ;
2014-05-27 18:44:30 +00:00
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
options = options || { } ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
callback = callback || function ( ) { } ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
if ( ! path ) {
callback ( new Errors . EINVAL ( 'Missing path argument' ) ) ;
return ;
}
2014-10-24 11:56:16 +00:00
2018-06-28 17:35:20 +00:00
function remove ( pathname , callback ) {
pathname = Path . resolve ( sh . pwd ( ) , pathname ) ;
fs . stat ( pathname , function ( error , stats ) {
if ( error ) {
callback ( error ) ;
return ;
2018-12-21 19:22:25 +00:00
} // If this is a file, delete it and we're done
2018-06-28 17:35:20 +00:00
if ( stats . type === 'FILE' ) {
fs . unlink ( pathname , callback ) ;
return ;
2018-12-21 19:22:25 +00:00
} // If it's a dir, check if it's empty
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
fs . readdir ( pathname , function ( error , entries ) {
if ( error ) {
2014-07-14 20:01:52 +00:00
callback ( error ) ;
return ;
2018-12-21 19:22:25 +00:00
} // If dir is empty, delete it and we're done
2018-06-28 17:35:20 +00:00
if ( entries . length === 0 ) {
fs . rmdir ( pathname , callback ) ;
2014-07-14 20:01:52 +00:00
return ;
2018-12-21 19:22:25 +00:00
} // If not, see if we're allowed to delete recursively
2018-06-28 17:35:20 +00:00
if ( ! options . recursive ) {
callback ( new Errors . ENOTEMPTY ( null , pathname ) ) ;
return ;
2018-12-21 19:22:25 +00:00
} // Remove each dir entry recursively, then delete the dir.
2018-06-28 17:35:20 +00:00
entries = entries . map ( function ( filename ) {
// Root dir entries absolutely
return Path . join ( pathname , filename ) ;
} ) ;
async . eachSeries ( entries , remove , function ( error ) {
if ( error ) {
callback ( error ) ;
return ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
fs . rmdir ( pathname , callback ) ;
} ) ;
2014-07-14 20:01:52 +00:00
} ) ;
2018-06-28 17:35:20 +00:00
} ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
remove ( path , callback ) ;
} ;
/ * *
* Gets the path to the temporary directory , creating it if not
* present . The directory used is the one specified in
* env . TMP . The callback receives ( error , tempDirName ) .
* /
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
Shell . prototype . tempDir = function ( callback ) {
var sh = this ;
var fs = sh . fs ;
var tmp = sh . env . get ( 'TMP' ) ;
2014-05-27 18:44:30 +00:00
2018-12-21 19:22:25 +00:00
callback = callback || function ( ) { } ; // Try and create it, and it will either work or fail
2018-06-28 17:35:20 +00:00
// but either way it's now there.
2018-12-21 19:22:25 +00:00
2018-10-30 18:35:33 +00:00
fs . mkdir ( tmp , function ( ) {
2018-06-28 17:35:20 +00:00
callback ( null , tmp ) ;
} ) ;
} ;
2014-05-27 18:44:30 +00:00
/ * *
2018-06-28 17:35:20 +00:00
* Recursively creates the directory at ` path ` . If the parent
* of ` path ` does not exist , it will be created .
* Based off EnsureDir by Sam X . Xu
* https : //www.npmjs.org/package/ensureDir
* MIT License
2014-05-27 18:44:30 +00:00
* /
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
Shell . prototype . mkdirp = function ( path , callback ) {
var sh = this ;
var fs = sh . fs ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
callback = callback || function ( ) { } ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
if ( ! path ) {
callback ( new Errors . EINVAL ( 'Missing path argument' ) ) ;
return ;
} else if ( path === '/' ) {
callback ( ) ;
return ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
function _mkdirp ( path , callback ) {
fs . stat ( path , function ( err , stat ) {
if ( stat ) {
if ( stat . isDirectory ( ) ) {
callback ( ) ;
return ;
} else if ( stat . isFile ( ) ) {
callback ( new Errors . ENOTDIR ( null , path ) ) ;
return ;
}
} else if ( err && err . code !== 'ENOENT' ) {
callback ( err ) ;
return ;
} else {
var parent = Path . dirname ( path ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( parent === '/' ) {
fs . mkdir ( path , function ( err ) {
2018-12-21 19:22:25 +00:00
if ( err && err . code !== 'EEXIST' ) {
2018-06-28 17:35:20 +00:00
callback ( err ) ;
return ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
callback ( ) ;
return ;
} ) ;
} else {
_mkdirp ( parent , function ( err ) {
if ( err ) return callback ( err ) ;
fs . mkdir ( path , function ( err ) {
2018-12-21 19:22:25 +00:00
if ( err && err . code !== 'EEXIST' ) {
2018-06-28 17:35:20 +00:00
callback ( err ) ;
return ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
callback ( ) ;
return ;
} ) ;
} ) ;
}
}
} ) ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
_mkdirp ( path , callback ) ;
} ;
2018-06-28 21:02:50 +00:00
/ * *
* Recursively walk a directory tree , reporting back all paths
* that were found along the way . The ` path ` must be a dir .
* Valid options include a ` regex ` for pattern matching paths
* and an ` exec ` function of the form ` function(path, next) ` where
* ` path ` is the current path that was found ( dir paths have an '/'
* appended ) and ` next ` is a callback to call when done processing
* the current path , passing any error object back as the first argument .
* ` find ` returns a flat array of absolute paths for all matching / found
* paths as the final argument to the callback .
* /
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
Shell . prototype . find = function ( path , options , callback ) {
var sh = this ;
var fs = sh . fs ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
if ( typeof options === 'function' ) {
callback = options ;
options = { } ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
options = options || { } ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
callback = callback || function ( ) { } ;
2014-05-27 18:44:30 +00:00
2018-06-28 21:02:50 +00:00
var exec = options . exec || function ( path , next ) {
next ( ) ;
} ;
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
var found = [ ] ;
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
if ( ! path ) {
callback ( new Errors . EINVAL ( 'Missing path argument' ) ) ;
return ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 21:02:50 +00:00
function processPath ( path , callback ) {
exec ( path , function ( err ) {
if ( err ) {
callback ( err ) ;
return ;
}
found . push ( path ) ;
callback ( ) ;
} ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 21:02:50 +00:00
function maybeProcessPath ( path , callback ) {
// Test the path against the user's regex, name, path primaries (if any)
// and remove any trailing slashes added previously.
2018-12-21 19:22:25 +00:00
var rawPath = Path . removeTrailing ( path ) ; // Check entire path against provided regex, if any
2018-06-28 21:02:50 +00:00
if ( options . regex && ! options . regex . test ( rawPath ) ) {
callback ( ) ;
return ;
2018-12-21 19:22:25 +00:00
} // Check basename for matches against name primary, if any
2018-06-28 21:02:50 +00:00
if ( options . name && ! minimatch ( Path . basename ( rawPath ) , options . name ) ) {
callback ( ) ;
return ;
2018-12-21 19:22:25 +00:00
} // Check dirname for matches against path primary, if any
2018-06-28 21:02:50 +00:00
if ( options . path && ! minimatch ( Path . dirname ( rawPath ) , options . path ) ) {
callback ( ) ;
return ;
}
processPath ( path , callback ) ;
2018-06-28 17:35:20 +00:00
}
2018-06-28 21:02:50 +00:00
function walk ( path , callback ) {
2018-12-21 19:22:25 +00:00
path = Path . resolve ( sh . pwd ( ) , path ) ; // The path is either a file or dir, and instead of doing
2018-06-28 21:02:50 +00:00
// a stat() to determine it first, we just try to readdir()
// and it will either work or not, and we handle the non-dir error.
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
fs . readdir ( path , function ( err , entries ) {
if ( err ) {
2018-12-21 19:22:25 +00:00
if ( err . code === 'ENOTDIR'
/* file case, ignore error */
) {
2018-06-28 21:02:50 +00:00
maybeProcessPath ( path , callback ) ;
} else {
callback ( err ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
return ;
2018-12-21 19:22:25 +00:00
} // Path is really a dir, add a trailing / and report it found
2018-06-28 21:02:50 +00:00
maybeProcessPath ( Path . addTrailing ( path ) , function ( err ) {
if ( err ) {
callback ( err ) ;
return ;
}
entries = entries . map ( function ( entry ) {
return Path . join ( path , entry ) ;
} ) ;
async . eachSeries ( entries , walk , function ( err ) {
callback ( err , found ) ;
} ) ;
} ) ;
} ) ;
2018-12-21 19:22:25 +00:00
} // Make sure we are starting with a dir path
2018-06-28 21:02:50 +00:00
fs . stat ( path , function ( err , stats ) {
if ( err ) {
callback ( err ) ;
return ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
if ( ! stats . isDirectory ( ) ) {
callback ( new Errors . ENOTDIR ( null , path ) ) ;
return ;
}
walk ( path , callback ) ;
} ) ;
} ;
2018-06-28 17:35:20 +00:00
module . exports = Shell ;
2018-10-30 18:35:33 +00:00
} , { "es6-promisify" : "0c0E" , "../path.js" : "UzoP" , "../errors.js" : "p8GN" , "./environment.js" : "QMiB" , "../../lib/async.js" : "u4Zs" , "minimatch" : "Nt/K" } ] , "J4Qg" : [ function ( require , module , exports ) {
2018-06-28 17:35:20 +00:00
// Based on https://github.com/diy/intercom.js/blob/master/lib/events.js
// Copyright 2012 DIY Co Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
function removeItem ( item , array ) {
for ( var i = array . length - 1 ; i >= 0 ; i -- ) {
if ( array [ i ] === item ) {
array . splice ( i , 1 ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
return array ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
var EventEmitter = function EventEmitter ( ) { } ;
EventEmitter . createInterface = function ( space ) {
var methods = { } ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
methods . on = function ( name , fn ) {
if ( typeof this [ space ] === 'undefined' ) {
this [ space ] = { } ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! this [ space ] . hasOwnProperty ( name ) ) {
this [ space ] [ name ] = [ ] ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
this [ space ] [ name ] . push ( fn ) ;
} ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
methods . off = function ( name , fn ) {
if ( typeof this [ space ] === 'undefined' ) return ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( this [ space ] . hasOwnProperty ( name ) ) {
removeItem ( fn , this [ space ] [ name ] ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
} ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
methods . trigger = function ( name ) {
if ( typeof this [ space ] !== 'undefined' && this [ space ] . hasOwnProperty ( name ) ) {
var args = Array . prototype . slice . call ( arguments , 1 ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
for ( var i = 0 ; i < this [ space ] [ name ] . length ; i ++ ) {
this [ space ] [ name ] [ i ] . apply ( this [ space ] [ name ] [ i ] , args ) ;
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
} ;
methods . removeAllListeners = function ( name ) {
if ( typeof this [ space ] === 'undefined' ) return ;
var self = this ;
self [ space ] [ name ] . forEach ( function ( fn ) {
self . off ( name , fn ) ;
} ) ;
} ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
return methods ;
} ;
2018-07-14 15:21:34 +00:00
2018-06-28 17:35:20 +00:00
var pvt = EventEmitter . createInterface ( '_handlers' ) ;
EventEmitter . prototype . _on = pvt . on ;
EventEmitter . prototype . _off = pvt . off ;
EventEmitter . prototype . _trigger = pvt . trigger ;
var pub = EventEmitter . createInterface ( 'handlers' ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
EventEmitter . prototype . on = function ( ) {
pub . on . apply ( this , arguments ) ;
Array . prototype . unshift . call ( arguments , 'on' ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
this . _trigger . apply ( this , arguments ) ;
} ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
EventEmitter . prototype . off = pub . off ;
EventEmitter . prototype . trigger = pub . trigger ;
EventEmitter . prototype . removeAllListeners = pub . removeAllListeners ;
module . exports = EventEmitter ;
2019-02-07 21:38:32 +00:00
} , { } ] , "3zBM" : [ function ( require , module , exports ) {
function generateRandom ( template ) {
return template . replace ( /[xy]/g , function ( c ) {
var r = Math . random ( ) * 16 | 0 ,
v = c === 'x' ? r : r & 0x3 | 0x8 ;
return v . toString ( 16 ) ;
} ) ;
}
function guid ( ) {
return generateRandom ( 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' ) . toUpperCase ( ) ;
}
/ * *
* Generate a string of n random characters . Defaults to n = 6.
* /
function randomChars ( n ) {
n = n || 6 ;
var template = 'x' . repeat ( n ) ;
return generateRandom ( template ) ;
}
function nop ( ) { }
module . exports = {
guid : guid ,
nop : nop ,
randomChars : randomChars
} ;
2018-07-14 15:21:34 +00:00
} , { } ] , "u7Jv" : [ function ( require , module , exports ) {
2018-06-28 17:35:20 +00:00
var global = arguments [ 3 ] ;
2018-12-21 19:22:25 +00:00
function _typeof ( obj ) { if ( typeof Symbol === "function" && typeof Symbol . iterator === "symbol" ) { _typeof = function _typeof ( obj ) { return typeof obj ; } ; } else { _typeof = function _typeof ( obj ) { return obj && typeof Symbol === "function" && obj . constructor === Symbol && obj !== Symbol . prototype ? "symbol" : typeof obj ; } ; } return _typeof ( obj ) ; }
2018-06-28 17:35:20 +00:00
// Based on https://github.com/diy/intercom.js/blob/master/lib/intercom.js
// Copyright 2012 DIY Co Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
var EventEmitter = require ( './eventemitter.js' ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var guid = require ( '../src/shared.js' ) . guid ;
function throttle ( delay , fn ) {
var last = 0 ;
return function ( ) {
var now = Date . now ( ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( now - last > delay ) {
last = now ;
fn . apply ( this , arguments ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
} ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function extend ( a , b ) {
if ( typeof a === 'undefined' || ! a ) {
a = { } ;
2014-05-27 18:44:30 +00:00
}
2018-12-21 19:22:25 +00:00
if ( _typeof ( b ) === 'object' ) {
2018-06-28 17:35:20 +00:00
for ( var key in b ) {
if ( b . hasOwnProperty ( key ) ) {
a [ key ] = b [ key ] ;
}
2014-05-27 18:44:30 +00:00
}
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
return a ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
var localStorage = function ( window ) {
if ( typeof window === 'undefined' || typeof window . localStorage === 'undefined' ) {
return {
getItem : function getItem ( ) { } ,
setItem : function setItem ( ) { } ,
removeItem : function removeItem ( ) { }
} ;
2014-05-27 18:44:30 +00:00
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
return window . localStorage ;
} ( global ) ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function Intercom ( ) {
var self = this ;
var now = Date . now ( ) ;
this . origin = guid ( ) ;
this . lastMessage = now ;
this . receivedIDs = { } ;
this . previousValues = { } ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
var storageHandler = function storageHandler ( ) {
self . _onStorageEvent . apply ( self , arguments ) ;
2018-12-21 19:22:25 +00:00
} ; // If we're in node.js, skip event registration
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
if ( typeof document === 'undefined' ) {
return ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
if ( document . attachEvent ) {
document . attachEvent ( 'onstorage' , storageHandler ) ;
2014-05-27 18:44:30 +00:00
} else {
2018-06-28 17:35:20 +00:00
global . addEventListener ( 'storage' , storageHandler , false ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
Intercom . prototype . _transaction = function ( fn ) {
var TIMEOUT = 1000 ;
var WAIT = 20 ;
var self = this ;
var executed = false ;
var listening = false ;
var waitTimer = null ;
function lock ( ) {
if ( executed ) {
return ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
var now = Date . now ( ) ;
var activeLock = localStorage . getItem ( INDEX _LOCK ) | 0 ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( activeLock && now - activeLock < TIMEOUT ) {
if ( ! listening ) {
self . _on ( 'storage' , lock ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
listening = true ;
2014-05-27 18:44:30 +00:00
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
waitTimer = setTimeout ( lock , WAIT ) ;
return ;
2014-05-27 18:44:30 +00:00
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
executed = true ;
localStorage . setItem ( INDEX _LOCK , now ) ;
fn ( ) ;
unlock ( ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function unlock ( ) {
if ( listening ) {
self . _off ( 'storage' , lock ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( waitTimer ) {
clearTimeout ( waitTimer ) ;
2014-05-27 18:44:30 +00:00
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
localStorage . removeItem ( INDEX _LOCK ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
lock ( ) ;
} ;
Intercom . prototype . _cleanup _emit = throttle ( 100 , function ( ) {
var self = this ;
self . _transaction ( function ( ) {
var now = Date . now ( ) ;
var threshold = now - THRESHOLD _TTL _EMIT ;
var changed = 0 ;
var messages ;
try {
messages = JSON . parse ( localStorage . getItem ( INDEX _EMIT ) || '[]' ) ;
} catch ( e ) {
messages = [ ] ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
for ( var i = messages . length - 1 ; i >= 0 ; i -- ) {
if ( messages [ i ] . timestamp < threshold ) {
messages . splice ( i , 1 ) ;
changed ++ ;
2014-05-27 18:44:30 +00:00
}
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( changed > 0 ) {
localStorage . setItem ( INDEX _EMIT , JSON . stringify ( messages ) ) ;
}
} ) ;
} ) ;
Intercom . prototype . _cleanup _once = throttle ( 100 , function ( ) {
var self = this ;
self . _transaction ( function ( ) {
var timestamp , ttl , key ;
var table ;
var now = Date . now ( ) ;
var changed = 0 ;
try {
table = JSON . parse ( localStorage . getItem ( INDEX _ONCE ) || '{}' ) ;
} catch ( e ) {
table = { } ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
for ( key in table ) {
if ( self . _once _expired ( key , table ) ) {
delete table [ key ] ;
changed ++ ;
}
}
if ( changed > 0 ) {
localStorage . setItem ( INDEX _ONCE , JSON . stringify ( table ) ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
} ) ;
} ) ;
Intercom . prototype . _once _expired = function ( key , table ) {
if ( ! table ) {
return true ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! table . hasOwnProperty ( key ) ) {
return true ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( _typeof ( table [ key ] ) !== 'object' ) {
return true ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
var ttl = table [ key ] . ttl || THRESHOLD _TTL _ONCE ;
var now = Date . now ( ) ;
var timestamp = table [ key ] . timestamp ;
return timestamp < now - ttl ;
} ;
Intercom . prototype . _localStorageChanged = function ( event , field ) {
if ( event && event . key ) {
return event . key === field ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
var currentValue = localStorage . getItem ( field ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( currentValue === this . previousValues [ field ] ) {
return false ;
2014-05-27 18:44:30 +00:00
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
this . previousValues [ field ] = currentValue ;
return true ;
} ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
Intercom . prototype . _onStorageEvent = function ( event ) {
event = event || global . event ;
var self = this ;
if ( this . _localStorageChanged ( event , INDEX _EMIT ) ) {
this . _transaction ( function ( ) {
2014-05-27 18:44:30 +00:00
var now = Date . now ( ) ;
2018-06-28 17:35:20 +00:00
var data = localStorage . getItem ( INDEX _EMIT ) ;
var messages ;
try {
messages = JSON . parse ( data || '[]' ) ;
} catch ( e ) {
messages = [ ] ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
for ( var i = 0 ; i < messages . length ; i ++ ) {
if ( messages [ i ] . origin === self . origin ) continue ;
if ( messages [ i ] . timestamp < self . lastMessage ) continue ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( messages [ i ] . id ) {
if ( self . receivedIDs . hasOwnProperty ( messages [ i ] . id ) ) continue ;
self . receivedIDs [ messages [ i ] . id ] = true ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
self . trigger ( messages [ i ] . name , messages [ i ] . payload ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
self . lastMessage = now ;
} ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
this . _trigger ( 'storage' , event ) ;
} ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
Intercom . prototype . _emit = function ( name , message , id ) {
id = typeof id === 'string' || typeof id === 'number' ? String ( id ) : null ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( id && id . length ) {
if ( this . receivedIDs . hasOwnProperty ( id ) ) return ;
this . receivedIDs [ id ] = true ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
var packet = {
id : id ,
name : name ,
origin : this . origin ,
timestamp : Date . now ( ) ,
payload : message
} ;
var self = this ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
this . _transaction ( function ( ) {
var data = localStorage . getItem ( INDEX _EMIT ) || '[]' ;
var delimiter = data === '[]' ? '' : ',' ;
data = [ data . substring ( 0 , data . length - 1 ) , delimiter , JSON . stringify ( packet ) , ']' ] . join ( '' ) ;
localStorage . setItem ( INDEX _EMIT , data ) ;
self . trigger ( name , message ) ;
setTimeout ( function ( ) {
self . _cleanup _emit ( ) ;
} , 50 ) ;
} ) ;
} ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
Intercom . prototype . emit = function ( name , message ) {
this . _emit . apply ( this , arguments ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
this . _trigger ( 'emit' , name , message ) ;
} ;
Intercom . prototype . once = function ( key , fn , ttl ) {
if ( ! Intercom . supported ) {
return ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
var self = this ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
this . _transaction ( function ( ) {
var data ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
try {
data = JSON . parse ( localStorage . getItem ( INDEX _ONCE ) || '{}' ) ;
} catch ( e ) {
data = { } ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! self . _once _expired ( key , data ) ) {
return ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
data [ key ] = { } ;
data [ key ] . timestamp = Date . now ( ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( typeof ttl === 'number' ) {
data [ key ] . ttl = ttl * 1000 ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
localStorage . setItem ( INDEX _ONCE , JSON . stringify ( data ) ) ;
fn ( ) ;
setTimeout ( function ( ) {
self . _cleanup _once ( ) ;
} , 50 ) ;
} ) ;
} ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
extend ( Intercom . prototype , EventEmitter . prototype ) ;
Intercom . supported = typeof localStorage !== 'undefined' ;
var INDEX _EMIT = 'intercom' ;
var INDEX _ONCE = 'intercom_once' ;
var INDEX _LOCK = 'intercom_lock' ;
var THRESHOLD _TTL _EMIT = 50000 ;
2018-06-28 21:02:50 +00:00
var THRESHOLD _TTL _ONCE = 1000 * 3600 ;
Intercom . destroy = function ( ) {
localStorage . removeItem ( INDEX _LOCK ) ;
localStorage . removeItem ( INDEX _EMIT ) ;
localStorage . removeItem ( INDEX _ONCE ) ;
} ;
2018-06-28 17:35:20 +00:00
Intercom . getInstance = function ( ) {
var intercom ;
return function ( ) {
if ( ! intercom ) {
intercom = new Intercom ( ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
return intercom ;
} ;
} ( ) ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
module . exports = Intercom ;
2018-07-14 15:21:34 +00:00
} , { "./eventemitter.js" : "J4Qg" , "../src/shared.js" : "3zBM" } ] , "VLEe" : [ function ( require , module , exports ) {
2019-02-07 21:38:32 +00:00
'using strict' ;
2018-06-28 17:35:20 +00:00
var EventEmitter = require ( '../lib/eventemitter.js' ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var Path = require ( './path.js' ) ;
2014-05-27 18:44:30 +00:00
2018-12-21 19:22:25 +00:00
var Intercom = require ( '../lib/intercom.js' ) ;
2018-06-28 17:35:20 +00:00
/ * *
* FSWatcher based on node . js ' FSWatcher
* see https : //github.com/joyent/node/blob/master/lib/fs.js
* /
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
function FSWatcher ( ) {
EventEmitter . call ( this ) ;
var self = this ;
var recursive = false ;
var recursivePathPrefix ;
var filename ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function onchange ( path ) {
// Watch for exact filename, or parent path when recursive is true.
if ( filename === path || recursive && path . indexOf ( recursivePathPrefix ) === 0 ) {
self . trigger ( 'change' , 'change' , path ) ;
2014-05-27 18:44:30 +00:00
}
2018-12-21 19:22:25 +00:00
} // We support, but ignore the second arg, which node.js uses.
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
self . start = function ( filename _ , persistent _ , recursive _ ) {
// Bail if we've already started (and therefore have a filename);
if ( filename ) {
return ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
if ( Path . isNull ( filename _ ) ) {
throw new Error ( 'Path must be a string without null bytes.' ) ;
2018-12-21 19:22:25 +00:00
} // TODO: get realpath for symlinks on filename...
2018-06-28 17:35:20 +00:00
// Filer's Path.normalize strips trailing slashes, which we use here.
// See https://github.com/js-platform/filer/issues/105
2014-05-27 18:44:30 +00:00
2018-12-21 19:22:25 +00:00
filename = Path . normalize ( filename _ ) ; // Whether to watch beneath this path or not
recursive = recursive _ === true ; // If recursive, construct a path prefix portion for comparisons later
2018-06-28 17:35:20 +00:00
// (i.e., '/path' becomes '/path/' so we can search within a filename for the
// prefix). We also take care to allow for '/' on its own.
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( recursive ) {
recursivePathPrefix = filename === '/' ? '/' : filename + '/' ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
var intercom = Intercom . getInstance ( ) ;
intercom . on ( 'change' , onchange ) ;
} ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
self . close = function ( ) {
var intercom = Intercom . getInstance ( ) ;
intercom . off ( 'change' , onchange ) ;
self . removeAllListeners ( 'change' ) ;
} ;
2014-05-27 18:44:30 +00:00
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
FSWatcher . prototype = new EventEmitter ( ) ;
FSWatcher . prototype . constructor = FSWatcher ;
module . exports = FSWatcher ;
2019-02-07 21:38:32 +00:00
} , { "../lib/eventemitter.js" : "J4Qg" , "./path.js" : "UzoP" , "../lib/intercom.js" : "u7Jv" } ] , "ZECt" : [ function ( require , module , exports ) {
2018-07-14 15:21:34 +00:00
var NODE _TYPE _FILE = require ( './constants.js' ) . NODE _TYPE _FILE ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
module . exports = function DirectoryEntry ( id , type ) {
this . id = id ;
2018-07-14 15:21:34 +00:00
this . type = type || NODE _TYPE _FILE ;
2018-06-28 17:35:20 +00:00
} ;
2019-01-03 04:12:19 +00:00
} , { "./constants.js" : "iJA9" } ] , "osLK" : [ function ( require , module , exports ) {
var _require = require ( './constants' ) ,
FIRST _DESCRIPTOR = _require . FIRST _DESCRIPTOR ;
var openFiles = { } ;
/ * *
* Start at FIRST _DESCRIPTOR and go until we find
* an empty file descriptor , then return it .
* /
var getEmptyDescriptor = function getEmptyDescriptor ( ) {
var fd = FIRST _DESCRIPTOR ;
while ( getOpenFileDescription ( fd ) ) {
fd ++ ;
}
return fd ;
} ;
/ * *
* Look up the open file description object for a given
* file descriptor .
* /
var getOpenFileDescription = function getOpenFileDescription ( ofd ) {
return openFiles [ ofd ] ;
} ;
/ * *
* Allocate a new file descriptor for the given
* open file description .
* /
var allocDescriptor = function allocDescriptor ( openFileDescription ) {
var ofd = getEmptyDescriptor ( ) ;
openFiles [ ofd ] = openFileDescription ;
return ofd ;
} ;
/ * *
* Release the given existing file descriptor created
* with allocDescriptor ( ) .
* /
var releaseDescriptor = function releaseDescriptor ( ofd ) {
return delete openFiles [ ofd ] ;
} ;
module . exports = {
allocDescriptor : allocDescriptor ,
releaseDescriptor : releaseDescriptor ,
getOpenFileDescription : getOpenFileDescription
} ;
} , { "./constants" : "iJA9" } ] , "KKNo" : [ function ( require , module , exports ) {
2018-12-21 19:22:25 +00:00
function _classCallCheck ( instance , Constructor ) { if ( ! ( instance instanceof Constructor ) ) { throw new TypeError ( "Cannot call a class as a function" ) ; } }
function _defineProperties ( target , props ) { for ( var i = 0 ; i < props . length ; i ++ ) { var descriptor = props [ i ] ; descriptor . enumerable = descriptor . enumerable || false ; descriptor . configurable = true ; if ( "value" in descriptor ) descriptor . writable = true ; Object . defineProperty ( target , descriptor . key , descriptor ) ; } }
function _createClass ( Constructor , protoProps , staticProps ) { if ( protoProps ) _defineProperties ( Constructor . prototype , protoProps ) ; if ( staticProps ) _defineProperties ( Constructor , staticProps ) ; return Constructor ; }
var _require = require ( './constants' ) ,
NODE _TYPE _FILE = _require . NODE _TYPE _FILE ,
NODE _TYPE _DIRECTORY = _require . NODE _TYPE _DIRECTORY ,
NODE _TYPE _SYMBOLIC _LINK = _require . NODE _TYPE _SYMBOLIC _LINK ,
DEFAULT _FILE _PERMISSIONS = _require . DEFAULT _FILE _PERMISSIONS ,
DEFAULT _DIR _PERMISSIONS = _require . DEFAULT _DIR _PERMISSIONS ;
var _require$fsConstants = require ( './constants' ) . fsConstants ,
S _IFREG = _require$fsConstants . S _IFREG ,
S _IFDIR = _require$fsConstants . S _IFDIR ,
S _IFLNK = _require$fsConstants . S _IFLNK ;
/ * *
* Make sure the options object has an id on property ,
* either from caller or one we generate using supplied guid fn .
* /
function ensureID ( options , prop , callback ) {
if ( options [ prop ] ) {
return callback ( ) ;
}
options . guid ( function ( err , id ) {
if ( err ) {
return callback ( err ) ;
}
options [ prop ] = id ;
callback ( ) ;
} ) ;
}
/ * *
* Generate a POSIX mode ( integer ) for the node type and permissions .
* Use default permissions if we aren ' t passed any .
* /
function generateMode ( nodeType , modePermissions ) {
switch ( nodeType ) {
case NODE _TYPE _DIRECTORY :
return ( modePermissions || DEFAULT _DIR _PERMISSIONS ) | S _IFDIR ;
case NODE _TYPE _SYMBOLIC _LINK :
return ( modePermissions || DEFAULT _FILE _PERMISSIONS ) | S _IFLNK ;
case NODE _TYPE _FILE : // falls through
default :
return ( modePermissions || DEFAULT _FILE _PERMISSIONS ) | S _IFREG ;
}
}
/ * *
* Common properties for the layout of a Node
* /
var Node =
/*#__PURE__*/
function ( ) {
function Node ( options ) {
_classCallCheck ( this , Node ) ;
var now = Date . now ( ) ;
this . id = options . id ;
this . data = options . data ; // id for data object
this . size = options . size || 0 ; // size (bytes for files, entries for directories)
this . atime = options . atime || now ; // access time (will mirror ctime after creation)
this . ctime = options . ctime || now ; // creation/change time
this . mtime = options . mtime || now ; // modified time
this . flags = options . flags || [ ] ; // file flags
this . xattrs = options . xattrs || { } ; // extended attributes
this . nlinks = options . nlinks || 0 ; // links count
// Historically, Filer's node layout has referred to the
// node type as `mode`, and done so using a String. In
// a POSIX filesystem, the mode is a number that combines
// both node type and permission bits. Internal we use `type`,
// but store it in the database as `mode` for backward
// compatibility.
if ( typeof options . type === 'string' ) {
this . type = options . type ;
} else if ( typeof options . mode === 'string' ) {
this . type = options . mode ;
} else {
this . type = NODE _TYPE _FILE ;
} // Extra mode permissions and ownership info
this . permissions = options . permissions || generateMode ( this . type ) ;
this . uid = options . uid || 0x0 ; // owner name
this . gid = options . gid || 0x0 ; // group name
}
/ * *
* Serialize a Node to JSON . Everything is as expected except
* that we use ` mode ` for ` type ` to maintain backward compatibility .
* /
_createClass ( Node , [ {
key : "toJSON" ,
value : function toJSON ( ) {
return {
id : this . id ,
data : this . data ,
size : this . size ,
atime : this . atime ,
ctime : this . ctime ,
mtime : this . ctime ,
flags : this . flags ,
xattrs : this . xattrs ,
nlinks : this . nlinks ,
// Use `mode` for `type` to keep backward compatibility
mode : this . type ,
permissions : this . permissions ,
uid : this . uid ,
gid : this . gid
} ;
} // Return complete POSIX `mode` for node type + permissions. See:
// http://man7.org/linux/man-pages/man2/chmod.2.html
} , {
key : "mode" ,
get : function get ( ) {
return generateMode ( this . type , this . permissions ) ;
} // When setting the `mode` we assume permissions bits only (not changing type)
,
set : function set ( value ) {
this . permissions = value ;
}
} ] ) ;
return Node ;
} ( ) ;
module . exports . create = function create ( options , callback ) {
// We expect both options.id and options.data to be provided/generated.
ensureID ( options , 'id' , function ( err ) {
if ( err ) {
return callback ( err ) ;
}
ensureID ( options , 'data' , function ( err ) {
if ( err ) {
return callback ( err ) ;
}
callback ( null , new Node ( options ) ) ;
} ) ;
} ) ;
} ;
} , { "./constants" : "iJA9" } ] , "XWaV" : [ function ( require , module , exports ) {
2018-06-28 21:02:50 +00:00
var Errors = require ( './errors.js' ) ;
2018-12-21 19:22:25 +00:00
var Node = require ( './node' ) ;
2018-06-28 21:02:50 +00:00
function OpenFileDescription ( path , id , flags , position ) {
2018-06-28 17:35:20 +00:00
this . path = path ;
this . id = id ;
this . flags = flags ;
this . position = position ;
2018-12-21 19:22:25 +00:00
} // Tries to find the node associated with an ofd's `id`.
2018-06-28 21:02:50 +00:00
// If not found, an error is returned on the callback.
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
OpenFileDescription . prototype . getNode = function ( context , callback ) {
var id = this . id ;
var path = this . path ;
function check _if _node _exists ( error , node ) {
if ( error ) {
return callback ( error ) ;
}
if ( ! node ) {
return callback ( new Errors . EBADF ( 'file descriptor refers to unknown node' , path ) ) ;
}
2018-12-21 19:22:25 +00:00
Node . create ( node , callback ) ;
2018-06-28 21:02:50 +00:00
}
context . getObject ( id , check _if _node _exists ) ;
2018-06-28 17:35:20 +00:00
} ;
2018-06-28 21:02:50 +00:00
module . exports = OpenFileDescription ;
2018-12-21 19:22:25 +00:00
} , { "./errors.js" : "p8GN" , "./node" : "KKNo" } ] , "33JE" : [ function ( require , module , exports ) {
2018-06-28 17:35:20 +00:00
var Constants = require ( './constants.js' ) ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function SuperNode ( options ) {
var now = Date . now ( ) ;
this . id = Constants . SUPER _NODE _ID ;
2018-07-14 15:21:34 +00:00
this . type = Constants . NODE _TYPE _META ;
2018-06-28 17:35:20 +00:00
this . atime = options . atime || now ;
this . ctime = options . ctime || now ;
2018-12-21 19:22:25 +00:00
this . mtime = options . mtime || now ; // root node id (randomly generated)
2018-06-28 17:35:20 +00:00
this . rnode = options . rnode ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
SuperNode . create = function ( options , callback ) {
options . guid ( function ( err , rnode ) {
if ( err ) {
callback ( err ) ;
return ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
options . rnode = options . rnode || rnode ;
callback ( null , new SuperNode ( options ) ) ;
} ) ;
} ;
module . exports = SuperNode ;
2018-12-21 19:22:25 +00:00
} , { "./constants.js" : "iJA9" } ] , "6dsC" : [ function ( require , module , exports ) {
2019-02-07 21:38:32 +00:00
'use strict' ;
2018-07-14 15:21:34 +00:00
2019-02-07 21:38:32 +00:00
var Constants = require ( './constants.js' ) ;
2014-05-27 18:44:30 +00:00
2019-02-07 21:38:32 +00:00
var Path = require ( './path.js' ) ;
2014-05-27 18:44:30 +00:00
2019-02-07 21:38:32 +00:00
function dateFromMs ( ms ) {
return new Date ( Number ( ms ) ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-07-14 15:21:34 +00:00
function Stats ( path , fileNode , devName ) {
2018-06-28 17:35:20 +00:00
this . dev = devName ;
2018-07-14 15:21:34 +00:00
this . node = fileNode . id ;
this . type = fileNode . type ;
2018-06-28 17:35:20 +00:00
this . size = fileNode . size ;
2018-12-21 19:22:25 +00:00
this . nlinks = fileNode . nlinks ; // Date objects
2019-02-07 21:38:32 +00:00
this . atime = dateFromMs ( fileNode . atime ) ;
this . mtime = dateFromMs ( fileNode . mtime ) ;
this . ctime = dateFromMs ( fileNode . ctime ) ; // Unix timestamp MS Numbers
2018-12-21 19:22:25 +00:00
this . atimeMs = fileNode . atime ;
this . mtimeMs = fileNode . mtime ;
this . ctimeMs = fileNode . ctime ;
2018-07-14 15:21:34 +00:00
this . version = fileNode . version ;
this . mode = fileNode . mode ;
this . uid = fileNode . uid ;
this . gid = fileNode . gid ;
this . name = Path . basename ( path ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
Stats . prototype . isFile = function ( ) {
2018-07-14 15:21:34 +00:00
return this . type === Constants . NODE _TYPE _FILE ;
2018-06-28 17:35:20 +00:00
} ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
Stats . prototype . isDirectory = function ( ) {
2018-07-14 15:21:34 +00:00
return this . type === Constants . NODE _TYPE _DIRECTORY ;
2018-06-28 17:35:20 +00:00
} ;
2014-09-30 20:16:15 +00:00
2018-06-28 17:35:20 +00:00
Stats . prototype . isSymbolicLink = function ( ) {
2018-07-14 15:21:34 +00:00
return this . type === Constants . NODE _TYPE _SYMBOLIC _LINK ;
2018-12-21 19:22:25 +00:00
} ; // These will always be false in Filer.
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
Stats . prototype . isSocket = Stats . prototype . isFIFO = Stats . prototype . isCharacterDevice = Stats . prototype . isBlockDevice = function ( ) {
return false ;
} ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
module . exports = Stats ;
2018-07-14 15:21:34 +00:00
} , { "./constants.js" : "iJA9" , "./path.js" : "UzoP" } ] , "bsBG" : [ function ( require , module , exports ) {
2018-12-21 19:22:25 +00:00
var Buffer = require ( "buffer" ) . Buffer ;
function _typeof ( obj ) { if ( typeof Symbol === "function" && typeof Symbol . iterator === "symbol" ) { _typeof = function _typeof ( obj ) { return typeof obj ; } ; } else { _typeof = function _typeof ( obj ) { return obj && typeof Symbol === "function" && obj . constructor === Symbol && obj !== Symbol . prototype ? "symbol" : typeof obj ; } ; } return _typeof ( obj ) ; }
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
var Path = require ( '../path.js' ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var normalize = Path . normalize ;
var dirname = Path . dirname ;
var basename = Path . basename ;
var isAbsolutePath = Path . isAbsolute ;
2014-05-27 18:44:30 +00:00
2018-12-21 19:22:25 +00:00
var shared = require ( '../shared.js' ) ;
2018-06-28 17:35:20 +00:00
var Constants = require ( '../constants.js' ) ;
2018-12-21 19:22:25 +00:00
2018-07-14 15:21:34 +00:00
var NODE _TYPE _FILE = Constants . NODE _TYPE _FILE ;
var NODE _TYPE _DIRECTORY = Constants . NODE _TYPE _DIRECTORY ;
var NODE _TYPE _SYMBOLIC _LINK = Constants . NODE _TYPE _SYMBOLIC _LINK ;
var NODE _TYPE _META = Constants . NODE _TYPE _META ;
var FULL _READ _WRITE _EXEC _PERMISSIONS = Constants . FULL _READ _WRITE _EXEC _PERMISSIONS ;
2018-06-28 17:35:20 +00:00
var ROOT _DIRECTORY _NAME = Constants . ROOT _DIRECTORY _NAME ;
var SUPER _NODE _ID = Constants . SUPER _NODE _ID ;
var SYMLOOP _MAX = Constants . SYMLOOP _MAX ;
var O _READ = Constants . O _READ ;
var O _WRITE = Constants . O _WRITE ;
var O _CREATE = Constants . O _CREATE ;
var O _EXCLUSIVE = Constants . O _EXCLUSIVE ;
var O _APPEND = Constants . O _APPEND ;
var O _FLAGS = Constants . O _FLAGS ;
var XATTR _CREATE = Constants . XATTR _CREATE ;
var XATTR _REPLACE = Constants . XATTR _REPLACE ;
var FS _NOMTIME = Constants . FS _NOMTIME ;
var FS _NOCTIME = Constants . FS _NOCTIME ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
var Errors = require ( '../errors.js' ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var DirectoryEntry = require ( '../directory-entry.js' ) ;
2018-12-21 19:22:25 +00:00
2019-01-03 04:12:19 +00:00
var openFiles = require ( '../open-files.js' ) ;
2018-06-28 17:35:20 +00:00
var OpenFileDescription = require ( '../open-file-description.js' ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var SuperNode = require ( '../super-node.js' ) ;
2014-05-27 18:44:30 +00:00
2018-12-21 19:22:25 +00:00
var Node = require ( '../node.js' ) ;
2018-10-30 18:35:33 +00:00
2018-12-21 19:22:25 +00:00
var Stats = require ( '../stats.js' ) ;
2018-06-28 17:35:20 +00:00
/ * *
* Update node times . Only passed times are modified ( undefined times are ignored )
* and filesystem flags are examined in order to override update logic .
* /
2018-10-30 18:35:33 +00:00
2018-06-28 17:35:20 +00:00
function update _node _times ( context , path , node , times , callback ) {
// Honour mount flags for how we update times
var flags = context . flags ;
2018-12-21 19:22:25 +00:00
if ( flags . includes ( FS _NOCTIME ) ) {
2018-06-28 17:35:20 +00:00
delete times . ctime ;
}
2018-12-21 19:22:25 +00:00
if ( flags . includes ( FS _NOMTIME ) ) {
2018-06-28 17:35:20 +00:00
delete times . mtime ;
2018-12-21 19:22:25 +00:00
} // Only do the update if required (i.e., times are still present)
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
var update = false ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( times . ctime ) {
2018-12-21 19:22:25 +00:00
node . ctime = times . ctime ; // We don't do atime tracking for perf reasons, but do mirror ctime
2018-06-28 17:35:20 +00:00
node . atime = times . ctime ;
update = true ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( times . atime ) {
// The only time we explicitly pass atime is when utimes(), futimes() is called.
// Override ctime mirror here if so
node . atime = times . atime ;
update = true ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( times . mtime ) {
node . mtime = times . mtime ;
update = true ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function complete ( error ) {
// Queue this change so we can send watch events.
// Unlike node.js, we send the full path vs. basename/dirname only.
2018-12-21 19:22:25 +00:00
context . changes . push ( {
event : 'change' ,
path : path
} ) ;
2018-06-28 17:35:20 +00:00
callback ( error ) ;
2018-07-14 15:21:34 +00:00
}
2018-06-28 17:35:20 +00:00
if ( update ) {
context . putObject ( node . id , node , complete ) ;
} else {
complete ( ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
/ * *
* make _node ( )
* /
// in: file or directory path
// out: new node representing file/directory
2018-12-21 19:22:25 +00:00
2018-07-14 15:21:34 +00:00
function make _node ( context , path , type , callback ) {
if ( type !== NODE _TYPE _DIRECTORY && type !== NODE _TYPE _FILE ) {
return callback ( new Errors . EINVAL ( 'type must be a directory or file' , path ) ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
path = normalize ( path ) ;
var name = basename ( path ) ;
var parentPath = dirname ( path ) ;
2018-06-28 17:35:20 +00:00
var parentNode ;
var parentNodeData ;
2018-12-21 19:22:25 +00:00
var node ; // Check if the parent node exists
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function create _node _in _parent ( error , parentDirectoryNode ) {
if ( error ) {
callback ( error ) ;
2018-07-14 15:21:34 +00:00
} else if ( parentDirectoryNode . type !== NODE _TYPE _DIRECTORY ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . ENOTDIR ( 'a component of the path prefix is not a directory' , path ) ) ;
} else {
parentNode = parentDirectoryNode ;
find _node ( context , path , check _if _node _exists ) ;
}
2018-12-21 19:22:25 +00:00
} // Check if the node to be created already exists
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function check _if _node _exists ( error , result ) {
if ( ! error && result ) {
callback ( new Errors . EEXIST ( 'path name already exists' , path ) ) ;
} else if ( error && ! ( error instanceof Errors . ENOENT ) ) {
2014-05-27 18:44:30 +00:00
callback ( error ) ;
} else {
2018-06-28 21:02:50 +00:00
context . getObject ( parentNode . data , create _node ) ;
2014-05-27 18:44:30 +00:00
}
2018-12-21 19:22:25 +00:00
} // Create the new node
2014-05-27 18:44:30 +00:00
2018-06-28 21:02:50 +00:00
function create _node ( error , result ) {
if ( error ) {
2014-05-27 18:44:30 +00:00
callback ( error ) ;
} else {
2018-06-28 21:02:50 +00:00
parentNodeData = result ;
2018-07-14 15:21:34 +00:00
Node . create ( {
guid : context . guid ,
type : type
} , function ( error , result ) {
2018-06-28 21:02:50 +00:00
if ( error ) {
callback ( error ) ;
return ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
node = result ;
node . nlinks += 1 ;
context . putObject ( node . id , node , update _parent _node _data ) ;
} ) ;
2014-05-27 18:44:30 +00:00
}
2018-12-21 19:22:25 +00:00
} // Update parent node time
2014-05-27 18:44:30 +00:00
2018-06-28 21:02:50 +00:00
function update _time ( error ) {
if ( error ) {
2018-06-28 17:35:20 +00:00
callback ( error ) ;
} else {
2018-06-28 21:02:50 +00:00
var now = Date . now ( ) ;
2018-12-21 19:22:25 +00:00
update _node _times ( context , parentPath , node , {
mtime : now ,
ctime : now
} , callback ) ;
2018-06-28 17:35:20 +00:00
}
2018-12-21 19:22:25 +00:00
} // Update the parent nodes data
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
function update _parent _node _data ( error ) {
if ( error ) {
callback ( error ) ;
} else {
2018-07-14 15:21:34 +00:00
parentNodeData [ name ] = new DirectoryEntry ( node . id , type ) ;
2018-06-28 17:35:20 +00:00
context . putObject ( parentNode . data , parentNodeData , update _time ) ;
2014-10-24 11:56:16 +00:00
}
2018-12-21 19:22:25 +00:00
} // Find the parent node
2014-10-24 11:56:16 +00:00
2018-06-28 17:35:20 +00:00
find _node ( context , parentPath , create _node _in _parent ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
/ * *
* find _node
* /
// in: file or directory path
// out: node structure, or error
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
function find _node ( context , path , callback ) {
2014-05-27 18:44:30 +00:00
path = normalize ( path ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! path ) {
return callback ( new Errors . ENOENT ( 'path is an empty string' ) ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var name = basename ( path ) ;
var parentPath = dirname ( path ) ;
var followedCount = 0 ;
2014-05-27 18:44:30 +00:00
2018-12-21 19:22:25 +00:00
function read _root _directory _node ( error , nodeData ) {
2018-06-28 17:35:20 +00:00
if ( error ) {
2018-12-21 19:22:25 +00:00
return callback ( error ) ;
} // Parse existing node as SuperNode
var superNode = new SuperNode ( nodeData ) ;
if ( ! superNode || superNode . type !== NODE _TYPE _META || ! superNode . rnode ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EFILESYSTEMERROR ( ) ) ;
} else {
context . getObject ( superNode . rnode , check _root _directory _node ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-10-24 11:56:16 +00:00
2018-06-28 17:35:20 +00:00
function check _root _directory _node ( error , rootDirectoryNode ) {
if ( error ) {
callback ( error ) ;
} else if ( ! rootDirectoryNode ) {
callback ( new Errors . ENOENT ( ) ) ;
} else {
2018-12-21 19:22:25 +00:00
Node . create ( rootDirectoryNode , callback ) ;
2014-05-27 18:44:30 +00:00
}
2018-12-21 19:22:25 +00:00
} // in: parent directory node
2018-06-28 17:35:20 +00:00
// out: parent directory data
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
function read _parent _directory _data ( error , parentDirectoryNode ) {
if ( error ) {
callback ( error ) ;
2018-07-14 15:21:34 +00:00
} else if ( parentDirectoryNode . type !== NODE _TYPE _DIRECTORY || ! parentDirectoryNode . data ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . ENOTDIR ( 'a component of the path prefix is not a directory' , path ) ) ;
} else {
context . getObject ( parentDirectoryNode . data , get _node _from _parent _directory _data ) ;
2014-05-27 18:44:30 +00:00
}
2018-12-21 19:22:25 +00:00
} // in: parent directory data
2018-06-28 17:35:20 +00:00
// out: searched node
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
function get _node _from _parent _directory _data ( error , parentDirectoryData ) {
if ( error ) {
callback ( error ) ;
} else {
2018-12-21 19:22:25 +00:00
if ( ! parentDirectoryData . hasOwnProperty ( name ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . ENOENT ( null , path ) ) ;
} else {
var nodeId = parentDirectoryData [ name ] . id ;
2018-12-21 19:22:25 +00:00
context . getObject ( nodeId , create _node ) ;
2018-06-28 17:35:20 +00:00
}
}
2014-05-27 18:44:30 +00:00
}
2018-12-21 19:22:25 +00:00
function create _node ( error , data ) {
if ( error ) {
return callback ( error ) ;
}
Node . create ( data , is _symbolic _link ) ;
}
2018-06-28 17:35:20 +00:00
function is _symbolic _link ( error , node ) {
2014-05-27 18:44:30 +00:00
if ( error ) {
2018-06-28 17:35:20 +00:00
callback ( error ) ;
} else {
2018-07-14 15:21:34 +00:00
if ( node . type === NODE _TYPE _SYMBOLIC _LINK ) {
2018-06-28 17:35:20 +00:00
followedCount ++ ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( followedCount > SYMLOOP _MAX ) {
callback ( new Errors . ELOOP ( null , path ) ) ;
} else {
follow _symbolic _link ( node . data ) ;
}
} else {
callback ( null , node ) ;
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-10-24 11:56:16 +00:00
2018-06-28 17:35:20 +00:00
function follow _symbolic _link ( data ) {
data = normalize ( data ) ;
parentPath = dirname ( data ) ;
name = basename ( data ) ;
2018-12-21 19:22:25 +00:00
2018-07-14 15:21:34 +00:00
if ( ROOT _DIRECTORY _NAME === name ) {
context . getObject ( SUPER _NODE _ID , read _root _directory _node ) ;
} else {
find _node ( context , parentPath , read _parent _directory _data ) ;
}
}
2014-05-27 18:44:30 +00:00
2018-07-14 15:21:34 +00:00
if ( ROOT _DIRECTORY _NAME === name ) {
context . getObject ( SUPER _NODE _ID , read _root _directory _node ) ;
} else {
2018-06-28 17:35:20 +00:00
find _node ( context , parentPath , read _parent _directory _data ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
/ * *
* set extended attribute ( refactor )
* /
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
function set _extended _attribute ( context , path , node , name , value , flag , callback ) {
function update _time ( error ) {
2018-06-28 17:35:20 +00:00
if ( error ) {
callback ( error ) ;
} else {
2018-12-21 19:22:25 +00:00
update _node _times ( context , path , node , {
ctime : Date . now ( )
} , callback ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 21:02:50 +00:00
var xattrs = node . xattrs ;
if ( flag === XATTR _CREATE && xattrs . hasOwnProperty ( name ) ) {
callback ( new Errors . EEXIST ( 'attribute already exists' , path ) ) ;
} else if ( flag === XATTR _REPLACE && ! xattrs . hasOwnProperty ( name ) ) {
callback ( new Errors . ENOATTR ( null , path ) ) ;
} else {
xattrs [ name ] = value ;
context . putObject ( node . id , node , update _time ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
/ * *
* ensure _root _directory . Creates a root node if necessary .
*
* Note : this should only be invoked when formatting a new file system .
* Multiple invocations of this by separate instances will still result
* in only a single super node .
* /
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
function ensure _root _directory ( context , callback ) {
var superNode ;
var directoryNode ;
var directoryData ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function ensure _super _node ( error , existingNode ) {
if ( ! error && existingNode ) {
// Another instance has beat us and already created the super node.
callback ( ) ;
} else if ( error && ! ( error instanceof Errors . ENOENT ) ) {
2014-05-27 18:44:30 +00:00
callback ( error ) ;
} else {
2018-12-21 19:22:25 +00:00
SuperNode . create ( {
guid : context . guid
} , function ( error , result ) {
2018-06-28 17:35:20 +00:00
if ( error ) {
callback ( error ) ;
return ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
superNode = result ;
context . putObject ( superNode . id , superNode , write _directory _node ) ;
} ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
function write _directory _node ( error ) {
if ( error ) {
callback ( error ) ;
} else {
2018-07-14 15:21:34 +00:00
Node . create ( {
guid : context . guid ,
id : superNode . rnode ,
type : NODE _TYPE _DIRECTORY
} , function ( error , result ) {
2018-06-28 17:35:20 +00:00
if ( error ) {
callback ( error ) ;
return ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
directoryNode = result ;
directoryNode . nlinks += 1 ;
context . putObject ( directoryNode . id , directoryNode , write _directory _data ) ;
} ) ;
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function write _directory _data ( error ) {
if ( error ) {
callback ( error ) ;
} else {
directoryData = { } ;
context . putObject ( directoryNode . data , directoryData , callback ) ;
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
context . getObject ( SUPER _NODE _ID , ensure _super _node ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
/ * *
* make _directory
* /
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
function make _directory ( context , path , callback ) {
path = normalize ( path ) ;
var name = basename ( path ) ;
var parentPath = dirname ( path ) ;
var directoryNode ;
var directoryData ;
var parentDirectoryNode ;
var parentDirectoryData ;
function check _if _directory _exists ( error , result ) {
if ( ! error && result ) {
callback ( new Errors . EEXIST ( null , path ) ) ;
} else if ( error && ! ( error instanceof Errors . ENOENT ) ) {
2014-05-27 18:44:30 +00:00
callback ( error ) ;
} else {
2018-06-28 17:35:20 +00:00
find _node ( context , parentPath , read _parent _directory _data ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
function read _parent _directory _data ( error , result ) {
if ( error ) {
2014-05-27 18:44:30 +00:00
callback ( error ) ;
} else {
2018-06-28 17:35:20 +00:00
parentDirectoryNode = result ;
context . getObject ( parentDirectoryNode . data , write _directory _node ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
function write _directory _node ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
parentDirectoryData = result ;
2018-07-14 15:21:34 +00:00
Node . create ( {
guid : context . guid ,
type : NODE _TYPE _DIRECTORY
} , function ( error , result ) {
2018-06-28 17:35:20 +00:00
if ( error ) {
callback ( error ) ;
return ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
directoryNode = result ;
directoryNode . nlinks += 1 ;
context . putObject ( directoryNode . id , directoryNode , write _directory _data ) ;
} ) ;
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function write _directory _data ( error ) {
if ( error ) {
callback ( error ) ;
} else {
directoryData = { } ;
context . putObject ( directoryNode . data , directoryData , update _parent _directory _data ) ;
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function update _time ( error ) {
if ( error ) {
callback ( error ) ;
} else {
var now = Date . now ( ) ;
2018-12-21 19:22:25 +00:00
update _node _times ( context , parentPath , parentDirectoryNode , {
mtime : now ,
ctime : now
} , callback ) ;
2018-06-28 17:35:20 +00:00
}
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function update _parent _directory _data ( error ) {
if ( error ) {
callback ( error ) ;
} else {
2018-07-14 15:21:34 +00:00
parentDirectoryData [ name ] = new DirectoryEntry ( directoryNode . id , NODE _TYPE _DIRECTORY ) ;
2018-06-28 17:35:20 +00:00
context . putObject ( parentDirectoryNode . data , parentDirectoryData , update _time ) ;
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
find _node ( context , path , check _if _directory _exists ) ;
2014-05-27 18:44:30 +00:00
}
2018-12-21 19:22:25 +00:00
function access _file ( context , path , mode , callback ) {
2018-12-22 04:09:29 +00:00
var _Constants$fsConstant = Constants . fsConstants ,
F _OK = _Constants$fsConstant . F _OK ,
R _OK = _Constants$fsConstant . R _OK ,
W _OK = _Constants$fsConstant . W _OK ,
X _OK = _Constants$fsConstant . X _OK ,
S _IXUSR = _Constants$fsConstant . S _IXUSR ,
S _IXGRP = _Constants$fsConstant . S _IXGRP ,
S _IXOTH = _Constants$fsConstant . S _IXOTH ;
2018-12-21 19:22:25 +00:00
path = normalize ( path ) ;
find _node ( context , path , function ( err , node ) {
if ( err ) {
return callback ( err ) ;
2018-12-22 04:09:29 +00:00
} // If we have a node, F_OK is true.
2018-12-21 19:22:25 +00:00
2018-12-22 04:09:29 +00:00
if ( mode === F _OK ) {
2018-12-21 19:22:25 +00:00
return callback ( null ) ;
}
2018-12-22 04:09:29 +00:00
var st _mode = validateAndMaskMode ( node . mode , callback ) ;
if ( ! st _mode ) return ; // For any other combo of F_OK, R_OK, W_OK, always allow. Filer user is a root user,
// so existing files are always OK, readable, and writable
if ( mode & ( R _OK | W _OK ) ) {
2018-12-21 19:22:25 +00:00
return callback ( null ) ;
2018-12-22 04:09:29 +00:00
} // For the case of X_OK, actually check if this file is executable
if ( mode & X _OK && st _mode & ( S _IXUSR | S _IXGRP | S _IXOTH ) ) {
return callback ( null ) ;
} // In any other case, the file isn't accessible
2018-12-21 19:22:25 +00:00
callback ( new Errors . EACCES ( 'permission denied' , path ) ) ;
} ) ;
}
2018-06-28 17:35:20 +00:00
/ * *
* remove _directory
* /
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
function remove _directory ( context , path , callback ) {
path = normalize ( path ) ;
var name = basename ( path ) ;
var parentPath = dirname ( path ) ;
var directoryNode ;
var directoryData ;
var parentDirectoryNode ;
var parentDirectoryData ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function read _parent _directory _data ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
parentDirectoryNode = result ;
context . getObject ( parentDirectoryNode . data , check _if _node _exists ) ;
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function check _if _node _exists ( error , result ) {
if ( error ) {
callback ( error ) ;
2018-07-14 15:21:34 +00:00
} else if ( ROOT _DIRECTORY _NAME === name ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EBUSY ( null , path ) ) ;
2018-12-21 19:22:25 +00:00
} else if ( ! result . hasOwnProperty ( name ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . ENOENT ( null , path ) ) ;
} else {
parentDirectoryData = result ;
directoryNode = parentDirectoryData [ name ] . id ;
context . getObject ( directoryNode , check _if _node _is _directory ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function check _if _node _is _directory ( error , result ) {
if ( error ) {
callback ( error ) ;
2018-07-14 15:21:34 +00:00
} else if ( result . type !== NODE _TYPE _DIRECTORY ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . ENOTDIR ( null , path ) ) ;
} else {
directoryNode = result ;
context . getObject ( directoryNode . data , check _if _directory _is _empty ) ;
2014-08-18 15:31:56 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-08-18 15:31:56 +00:00
2018-06-28 17:35:20 +00:00
function check _if _directory _is _empty ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
directoryData = result ;
2018-12-21 19:22:25 +00:00
if ( Object . keys ( directoryData ) . length > 0 ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . ENOTEMPTY ( null , path ) ) ;
} else {
remove _directory _entry _from _parent _directory _node ( ) ;
2014-08-18 15:31:56 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function update _time ( error ) {
if ( error ) {
callback ( error ) ;
} else {
var now = Date . now ( ) ;
2018-12-21 19:22:25 +00:00
update _node _times ( context , parentPath , parentDirectoryNode , {
mtime : now ,
ctime : now
} , remove _directory _node ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function remove _directory _entry _from _parent _directory _node ( ) {
2018-07-14 15:21:34 +00:00
delete parentDirectoryData [ name ] ;
context . putObject ( parentDirectoryNode . data , parentDirectoryData , update _time ) ;
2018-05-29 18:03:59 +00:00
}
2018-07-14 15:21:34 +00:00
function remove _directory _node ( error ) {
2018-05-29 18:03:59 +00:00
if ( error ) {
callback ( error ) ;
} else {
2018-07-14 15:21:34 +00:00
context . delete ( directoryNode . id , remove _directory _data ) ;
2018-05-29 18:03:59 +00:00
}
}
2018-07-14 15:21:34 +00:00
function remove _directory _data ( error ) {
if ( error ) {
callback ( error ) ;
} else {
context . delete ( directoryNode . data , callback ) ;
}
2018-05-29 18:03:59 +00:00
}
2018-07-14 15:21:34 +00:00
find _node ( context , parentPath , read _parent _directory _data ) ;
2018-05-29 18:03:59 +00:00
}
2018-12-21 19:22:25 +00:00
function open _file ( context , path , flags , mode , callback ) {
if ( typeof mode === 'function' ) {
callback = mode ;
mode = null ;
}
2018-05-29 18:03:59 +00:00
path = normalize ( path ) ;
2018-07-14 15:21:34 +00:00
var name = basename ( path ) ;
var parentPath = dirname ( path ) ;
var directoryNode ;
var directoryData ;
var directoryEntry ;
var fileNode ;
var fileData ;
var followedCount = 0 ;
if ( ROOT _DIRECTORY _NAME === name ) {
2018-12-21 19:22:25 +00:00
if ( flags . includes ( O _WRITE ) ) {
2018-07-14 15:21:34 +00:00
callback ( new Errors . EISDIR ( 'the named file is a directory and O_WRITE is set' , path ) ) ;
} else {
find _node ( context , path , set _file _node ) ;
}
} else {
find _node ( context , parentPath , read _directory _data ) ;
}
function read _directory _data ( error , result ) {
2018-05-29 18:03:59 +00:00
if ( error ) {
callback ( error ) ;
2018-07-14 15:21:34 +00:00
} else if ( result . type !== NODE _TYPE _DIRECTORY ) {
callback ( new Errors . ENOENT ( null , path ) ) ;
2018-05-29 18:03:59 +00:00
} else {
2018-07-14 15:21:34 +00:00
directoryNode = result ;
context . getObject ( directoryNode . data , check _if _file _exists ) ;
2018-05-29 18:03:59 +00:00
}
}
2018-07-14 15:21:34 +00:00
function check _if _file _exists ( error , result ) {
2018-05-29 18:03:59 +00:00
if ( error ) {
callback ( error ) ;
} else {
2018-07-14 15:21:34 +00:00
directoryData = result ;
2018-12-21 19:22:25 +00:00
if ( directoryData . hasOwnProperty ( name ) ) {
if ( flags . includes ( O _EXCLUSIVE ) ) {
2018-07-14 15:21:34 +00:00
callback ( new Errors . ENOENT ( 'O_CREATE and O_EXCLUSIVE are set, and the named file exists' , path ) ) ;
} else {
directoryEntry = directoryData [ name ] ;
2018-12-21 19:22:25 +00:00
if ( directoryEntry . type === NODE _TYPE _DIRECTORY && flags . includes ( O _WRITE ) ) {
2018-07-14 15:21:34 +00:00
callback ( new Errors . EISDIR ( 'the named file is a directory and O_WRITE is set' , path ) ) ;
} else {
context . getObject ( directoryEntry . id , check _if _symbolic _link ) ;
}
}
} else {
2018-12-21 19:22:25 +00:00
if ( ! flags . includes ( O _CREATE ) ) {
2018-07-14 15:21:34 +00:00
callback ( new Errors . ENOENT ( 'O_CREATE is not set and the named file does not exist' , path ) ) ;
} else {
write _file _node ( ) ;
}
}
2018-05-29 18:03:59 +00:00
}
}
2018-06-28 17:35:20 +00:00
function check _if _symbolic _link ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
var node = result ;
2018-12-21 19:22:25 +00:00
2018-07-14 15:21:34 +00:00
if ( node . type === NODE _TYPE _SYMBOLIC _LINK ) {
2018-06-28 17:35:20 +00:00
followedCount ++ ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( followedCount > SYMLOOP _MAX ) {
callback ( new Errors . ELOOP ( null , path ) ) ;
} else {
follow _symbolic _link ( node . data ) ;
}
} else {
set _file _node ( undefined , node ) ;
}
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
function follow _symbolic _link ( data ) {
data = normalize ( data ) ;
parentPath = dirname ( data ) ;
name = basename ( data ) ;
2018-12-21 19:22:25 +00:00
2018-07-14 15:21:34 +00:00
if ( ROOT _DIRECTORY _NAME === name ) {
2018-12-21 19:22:25 +00:00
if ( flags . includes ( O _WRITE ) ) {
2018-06-28 21:02:50 +00:00
callback ( new Errors . EISDIR ( 'the named file is a directory and O_WRITE is set' , path ) ) ;
} else {
find _node ( context , path , set _file _node ) ;
}
}
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
find _node ( context , parentPath , read _directory _data ) ;
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
function set _file _node ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
fileNode = result ;
callback ( null , fileNode ) ;
}
}
2018-06-28 17:35:20 +00:00
2018-06-28 21:02:50 +00:00
function write _file _node ( ) {
2018-07-14 15:21:34 +00:00
Node . create ( {
guid : context . guid ,
type : NODE _TYPE _FILE
} , function ( error , result ) {
2018-06-28 21:02:50 +00:00
if ( error ) {
callback ( error ) ;
return ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
fileNode = result ;
fileNode . nlinks += 1 ;
2018-12-21 19:22:25 +00:00
if ( mode ) {
fileNode . mode = mode ;
}
2018-06-28 21:02:50 +00:00
context . putObject ( fileNode . id , fileNode , write _file _data ) ;
} ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function write _file _data ( error ) {
if ( error ) {
2014-05-27 18:44:30 +00:00
callback ( error ) ;
} else {
2018-12-21 19:22:25 +00:00
fileData = Buffer . alloc ( 0 ) ;
2018-06-28 17:35:20 +00:00
context . putBuffer ( fileNode . data , fileData , update _directory _data ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
function update _time ( error ) {
if ( error ) {
callback ( error ) ;
2014-05-27 18:44:30 +00:00
} else {
2018-06-28 17:35:20 +00:00
var now = Date . now ( ) ;
2018-12-21 19:22:25 +00:00
update _node _times ( context , parentPath , directoryNode , {
mtime : now ,
ctime : now
} , handle _update _result ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
function update _directory _data ( error ) {
if ( error ) {
callback ( error ) ;
} else {
2018-07-14 15:21:34 +00:00
directoryData [ name ] = new DirectoryEntry ( fileNode . id , NODE _TYPE _FILE ) ;
2018-06-28 17:35:20 +00:00
context . putObject ( directoryNode . data , directoryData , update _time ) ;
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function handle _update _result ( error ) {
if ( error ) {
callback ( error ) ;
} else {
callback ( null , fileNode ) ;
2014-12-17 07:35:01 +00:00
}
}
2018-06-28 17:35:20 +00:00
}
2014-12-17 07:35:01 +00:00
2018-06-28 17:35:20 +00:00
function replace _data ( context , ofd , buffer , offset , length , callback ) {
var fileNode ;
function return _nbytes ( error ) {
if ( error ) {
2014-12-17 07:35:01 +00:00
callback ( error ) ;
} else {
2018-06-28 17:35:20 +00:00
callback ( null , length ) ;
2014-12-17 07:35:01 +00:00
}
}
2018-06-28 17:35:20 +00:00
function update _time ( error ) {
if ( error ) {
2014-12-17 07:35:01 +00:00
callback ( error ) ;
} else {
2018-06-28 17:35:20 +00:00
var now = Date . now ( ) ;
2018-12-21 19:22:25 +00:00
update _node _times ( context , ofd . path , fileNode , {
mtime : now ,
ctime : now
} , return _nbytes ) ;
2014-12-17 07:35:01 +00:00
}
}
2018-06-28 17:35:20 +00:00
function update _file _node ( error ) {
if ( error ) {
2014-12-17 07:35:01 +00:00
callback ( error ) ;
} else {
2018-06-28 17:35:20 +00:00
context . putObject ( fileNode . id , fileNode , update _time ) ;
2014-12-17 07:35:01 +00:00
}
}
2018-06-28 17:35:20 +00:00
function write _file _data ( error , result ) {
if ( error ) {
2014-12-17 07:35:01 +00:00
callback ( error ) ;
} else {
2018-06-28 17:35:20 +00:00
fileNode = result ;
2018-12-21 19:22:25 +00:00
var newData = Buffer . alloc ( length ) ;
2018-06-28 17:35:20 +00:00
buffer . copy ( newData , 0 , offset , offset + length ) ;
ofd . position = length ;
fileNode . size = length ;
fileNode . version += 1 ;
context . putBuffer ( fileNode . data , newData , update _file _node ) ;
2014-12-17 07:35:01 +00:00
}
}
2018-06-28 17:35:20 +00:00
context . getObject ( ofd . id , write _file _data ) ;
}
function write _data ( context , ofd , buffer , offset , length , position , callback ) {
var fileNode ;
var fileData ;
function return _nbytes ( error ) {
if ( error ) {
2014-12-17 07:35:01 +00:00
callback ( error ) ;
} else {
2018-06-28 17:35:20 +00:00
callback ( null , length ) ;
2014-12-17 07:35:01 +00:00
}
}
2018-06-28 17:35:20 +00:00
function update _time ( error ) {
if ( error ) {
2014-12-17 07:35:01 +00:00
callback ( error ) ;
} else {
2018-06-28 17:35:20 +00:00
var now = Date . now ( ) ;
2018-12-21 19:22:25 +00:00
update _node _times ( context , ofd . path , fileNode , {
mtime : now ,
ctime : now
} , return _nbytes ) ;
2014-12-17 07:35:01 +00:00
}
}
2018-06-28 17:35:20 +00:00
function update _file _node ( error ) {
if ( error ) {
2014-12-17 07:35:01 +00:00
callback ( error ) ;
} else {
2018-06-28 17:35:20 +00:00
context . putObject ( fileNode . id , fileNode , update _time ) ;
2014-12-17 07:35:01 +00:00
}
}
2018-06-28 17:35:20 +00:00
function update _file _data ( error , result ) {
if ( error ) {
2014-05-27 18:44:30 +00:00
callback ( error ) ;
} else {
2018-06-28 17:35:20 +00:00
fileData = result ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! fileData ) {
return callback ( new Errors . EIO ( 'Expected Buffer' ) ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var _position = ! ( undefined === position || null === position ) ? position : ofd . position ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var newSize = Math . max ( fileData . length , _position + length ) ;
2018-12-21 19:22:25 +00:00
var newData = Buffer . alloc ( newSize ) ;
2018-06-28 17:35:20 +00:00
if ( fileData ) {
fileData . copy ( newData ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
buffer . copy ( newData , _position , offset , offset + length ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( undefined === position ) {
ofd . position += length ;
}
fileNode . size = newSize ;
fileNode . version += 1 ;
context . putBuffer ( fileNode . data , newData , update _file _node ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
function read _file _data ( error , result ) {
if ( error ) {
2014-12-17 07:35:01 +00:00
callback ( error ) ;
} else {
2018-06-28 17:35:20 +00:00
fileNode = result ;
context . getBuffer ( fileNode . data , update _file _data ) ;
2014-12-17 07:35:01 +00:00
}
}
2018-06-28 17:35:20 +00:00
context . getObject ( ofd . id , read _file _data ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function read _data ( context , ofd , buffer , offset , length , position , callback ) {
var fileNode ;
var fileData ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function handle _file _data ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
fileData = result ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! fileData ) {
return callback ( new Errors . EIO ( 'Expected Buffer' ) ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var _position = ! ( undefined === position || null === position ) ? position : ofd . position ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
length = _position + length > buffer . length ? length - _position : length ;
fileData . copy ( buffer , offset , _position , _position + length ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( undefined === position ) {
ofd . position += length ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
callback ( null , length ) ;
}
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function read _file _data ( error , result ) {
if ( error ) {
2014-05-27 18:44:30 +00:00
callback ( error ) ;
2018-07-14 15:21:34 +00:00
} else if ( result . type === NODE _TYPE _DIRECTORY ) {
2018-06-28 21:02:50 +00:00
callback ( new Errors . EISDIR ( 'the named file is a directory' , ofd . path ) ) ;
2014-05-27 18:44:30 +00:00
} else {
2018-06-28 17:35:20 +00:00
fileNode = result ;
context . getBuffer ( fileNode . data , handle _file _data ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
context . getObject ( ofd . id , read _file _data ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function stat _file ( context , path , callback ) {
path = normalize ( path ) ;
2018-06-28 21:02:50 +00:00
find _node ( context , path , callback ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function fstat _file ( context , ofd , callback ) {
2018-06-28 21:02:50 +00:00
ofd . getNode ( context , callback ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function lstat _file ( context , path , callback ) {
path = normalize ( path ) ;
var name = basename ( path ) ;
var parentPath = dirname ( path ) ;
var directoryNode ;
var directoryData ;
2014-05-27 18:44:30 +00:00
2018-07-14 15:21:34 +00:00
if ( ROOT _DIRECTORY _NAME === name ) {
2018-06-28 21:02:50 +00:00
find _node ( context , path , callback ) ;
2018-06-28 17:35:20 +00:00
} else {
find _node ( context , parentPath , read _directory _data ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function read _directory _data ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
directoryNode = result ;
context . getObject ( directoryNode . data , check _if _file _exists ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2019-02-08 03:54:40 +00:00
function create _node ( error , data ) {
if ( error ) {
return callback ( error ) ;
}
Node . create ( data , callback ) ;
}
2018-06-28 17:35:20 +00:00
function check _if _file _exists ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
directoryData = result ;
2018-12-21 19:22:25 +00:00
if ( ! directoryData . hasOwnProperty ( name ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . ENOENT ( 'a component of the path does not name an existing file' , path ) ) ;
} else {
2019-02-08 03:54:40 +00:00
context . getObject ( directoryData [ name ] . id , create _node ) ;
2018-06-28 17:35:20 +00:00
}
}
2014-12-17 07:35:01 +00:00
}
}
2018-06-28 17:35:20 +00:00
function link _node ( context , oldpath , newpath , callback ) {
oldpath = normalize ( oldpath ) ;
var oldname = basename ( oldpath ) ;
var oldParentPath = dirname ( oldpath ) ;
newpath = normalize ( newpath ) ;
var newname = basename ( newpath ) ;
var newParentPath = dirname ( newpath ) ;
2018-07-14 15:21:34 +00:00
var ctime = Date . now ( ) ;
2018-06-28 17:35:20 +00:00
var oldDirectoryNode ;
var oldDirectoryData ;
var newDirectoryNode ;
var newDirectoryData ;
2018-07-14 15:21:34 +00:00
var fileNodeID ;
2018-06-28 17:35:20 +00:00
var fileNode ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function update _time ( error ) {
if ( error ) {
callback ( error ) ;
2014-05-27 18:44:30 +00:00
} else {
2018-12-21 19:22:25 +00:00
update _node _times ( context , newpath , fileNode , {
ctime : ctime
} , callback ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
function update _file _node ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
fileNode = result ;
fileNode . nlinks += 1 ;
context . putObject ( fileNode . id , fileNode , update _time ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
}
2018-10-30 18:35:33 +00:00
function read _file _node ( error ) {
2018-06-28 17:35:20 +00:00
if ( error ) {
callback ( error ) ;
} else {
2018-07-14 15:21:34 +00:00
context . getObject ( fileNodeID , update _file _node ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function check _if _new _file _exists ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
newDirectoryData = result ;
2018-12-21 19:22:25 +00:00
if ( newDirectoryData . hasOwnProperty ( newname ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EEXIST ( 'newpath resolves to an existing file' , newname ) ) ;
} else {
newDirectoryData [ newname ] = oldDirectoryData [ oldname ] ;
2018-07-14 15:21:34 +00:00
fileNodeID = newDirectoryData [ newname ] . id ;
context . putObject ( newDirectoryNode . data , newDirectoryData , read _file _node ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function read _new _directory _data ( error , result ) {
if ( error ) {
callback ( error ) ;
2014-08-22 16:35:13 +00:00
} else {
2018-06-28 17:35:20 +00:00
newDirectoryNode = result ;
context . getObject ( newDirectoryNode . data , check _if _new _file _exists ) ;
2014-08-22 16:35:13 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function check _if _old _file _exists ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
oldDirectoryData = result ;
2018-12-21 19:22:25 +00:00
if ( ! oldDirectoryData . hasOwnProperty ( oldname ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . ENOENT ( 'a component of either path prefix does not exist' , oldname ) ) ;
2018-07-14 15:21:34 +00:00
} else if ( oldDirectoryData [ oldname ] . type === NODE _TYPE _DIRECTORY ) {
2018-06-28 21:02:50 +00:00
callback ( new Errors . EPERM ( 'oldpath refers to a directory' ) ) ;
2018-06-28 17:35:20 +00:00
} else {
find _node ( context , newParentPath , read _new _directory _data ) ;
}
}
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function read _old _directory _data ( error , result ) {
if ( error ) {
callback ( error ) ;
2018-06-28 21:02:50 +00:00
} else {
oldDirectoryNode = result ;
context . getObject ( oldDirectoryNode . data , check _if _old _file _exists ) ;
}
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-06-28 21:02:50 +00:00
find _node ( context , oldParentPath , read _old _directory _data ) ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function unlink _node ( context , path , callback ) {
path = normalize ( path ) ;
var name = basename ( path ) ;
var parentPath = dirname ( path ) ;
var directoryNode ;
var directoryData ;
var fileNode ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function update _directory _data ( error ) {
if ( error ) {
callback ( error ) ;
} else {
delete directoryData [ name ] ;
context . putObject ( directoryNode . data , directoryData , function ( error ) {
2018-10-30 18:35:33 +00:00
if ( error ) {
callback ( error ) ;
} else {
var now = Date . now ( ) ;
2018-12-21 19:22:25 +00:00
update _node _times ( context , parentPath , directoryNode , {
mtime : now ,
ctime : now
} , callback ) ;
2018-10-30 18:35:33 +00:00
}
2018-06-28 17:35:20 +00:00
} ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
function delete _file _data ( error ) {
if ( error ) {
callback ( error ) ;
} else {
context . delete ( fileNode . data , update _directory _data ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function update _file _node ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
fileNode = result ;
fileNode . nlinks -= 1 ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( fileNode . nlinks < 1 ) {
context . delete ( fileNode . id , delete _file _data ) ;
} else {
context . putObject ( fileNode . id , fileNode , function ( error ) {
2018-10-30 18:35:33 +00:00
if ( error ) {
callback ( error ) ;
} else {
2018-12-21 19:22:25 +00:00
update _node _times ( context , path , fileNode , {
ctime : Date . now ( )
} , update _directory _data ) ;
2018-10-30 18:35:33 +00:00
}
2018-06-28 17:35:20 +00:00
} ) ;
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-07-14 20:01:52 +00:00
2018-06-28 21:02:50 +00:00
function check _if _node _is _directory ( error , result ) {
if ( error ) {
callback ( error ) ;
2018-07-14 15:21:34 +00:00
} else if ( result . type === NODE _TYPE _DIRECTORY ) {
2018-06-28 21:02:50 +00:00
callback ( new Errors . EPERM ( 'unlink not permitted on directories' , name ) ) ;
} else {
update _file _node ( null , result ) ;
}
}
2018-06-28 17:35:20 +00:00
function check _if _file _exists ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
directoryData = result ;
2018-12-21 19:22:25 +00:00
if ( ! directoryData . hasOwnProperty ( name ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . ENOENT ( 'a component of the path does not name an existing file' , name ) ) ;
} else {
2018-06-28 21:02:50 +00:00
context . getObject ( directoryData [ name ] . id , check _if _node _is _directory ) ;
2018-06-28 17:35:20 +00:00
}
2014-07-15 13:26:58 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function read _directory _data ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
directoryNode = result ;
context . getObject ( directoryNode . data , check _if _file _exists ) ;
}
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
find _node ( context , parentPath , read _directory _data ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function read _directory ( context , path , callback ) {
path = normalize ( path ) ;
var directoryNode ;
var directoryData ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function handle _directory _data ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
directoryData = result ;
var files = Object . keys ( directoryData ) ;
callback ( null , files ) ;
}
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function read _directory _data ( error , result ) {
if ( error ) {
callback ( error ) ;
2018-07-14 15:21:34 +00:00
} else if ( result . type !== NODE _TYPE _DIRECTORY ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . ENOTDIR ( null , path ) ) ;
} else {
directoryNode = result ;
context . getObject ( directoryNode . data , handle _directory _data ) ;
}
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
find _node ( context , path , read _directory _data ) ;
2014-07-14 20:01:52 +00:00
}
2018-06-28 17:35:20 +00:00
function make _symbolic _link ( context , srcpath , dstpath , callback ) {
dstpath = normalize ( dstpath ) ;
var name = basename ( dstpath ) ;
var parentPath = dirname ( dstpath ) ;
var directoryNode ;
var directoryData ;
var fileNode ;
2018-07-14 15:21:34 +00:00
if ( ROOT _DIRECTORY _NAME === name ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EEXIST ( null , name ) ) ;
2014-07-14 20:01:52 +00:00
} else {
2018-06-28 17:35:20 +00:00
find _node ( context , parentPath , read _directory _data ) ;
2014-07-14 20:01:52 +00:00
}
2018-06-28 17:35:20 +00:00
function read _directory _data ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
directoryNode = result ;
context . getObject ( directoryNode . data , check _if _file _exists ) ;
2014-07-14 20:01:52 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-07-14 20:01:52 +00:00
2018-06-28 17:35:20 +00:00
function check _if _file _exists ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
directoryData = result ;
2018-12-21 19:22:25 +00:00
if ( directoryData . hasOwnProperty ( name ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EEXIST ( null , name ) ) ;
} else {
write _file _node ( ) ;
2014-07-14 20:01:52 +00:00
}
2018-06-28 17:35:20 +00:00
}
}
2014-07-14 20:01:52 +00:00
2018-06-28 17:35:20 +00:00
function write _file _node ( ) {
2018-07-14 15:21:34 +00:00
Node . create ( {
guid : context . guid ,
type : NODE _TYPE _SYMBOLIC _LINK
} , function ( error , result ) {
2018-06-28 17:35:20 +00:00
if ( error ) {
callback ( error ) ;
return ;
}
2018-07-14 15:21:34 +00:00
2018-12-21 19:22:25 +00:00
fileNode = result ;
fileNode . nlinks += 1 ; // If the srcpath isn't absolute, resolve it relative to the dstpath
2018-07-14 15:21:34 +00:00
// but store both versions, since we'll use the relative one in readlink().
2018-12-21 19:22:25 +00:00
2018-07-14 15:21:34 +00:00
if ( ! isAbsolutePath ( srcpath ) ) {
fileNode . symlink _relpath = srcpath ;
srcpath = Path . resolve ( parentPath , srcpath ) ;
}
2018-06-28 17:35:20 +00:00
fileNode . size = srcpath . length ;
fileNode . data = srcpath ;
context . putObject ( fileNode . id , fileNode , update _directory _data ) ;
2014-07-14 20:01:52 +00:00
} ) ;
2018-06-28 17:35:20 +00:00
}
2014-10-24 11:56:16 +00:00
2018-06-28 17:35:20 +00:00
function update _time ( error ) {
if ( error ) {
callback ( error ) ;
} else {
var now = Date . now ( ) ;
2018-12-21 19:22:25 +00:00
update _node _times ( context , parentPath , directoryNode , {
mtime : now ,
ctime : now
} , callback ) ;
2014-10-24 11:56:16 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-10-24 11:56:16 +00:00
2018-06-28 17:35:20 +00:00
function update _directory _data ( error ) {
if ( error ) {
callback ( error ) ;
} else {
2018-07-14 15:21:34 +00:00
directoryData [ name ] = new DirectoryEntry ( fileNode . id , NODE _TYPE _SYMBOLIC _LINK ) ;
2018-06-28 17:35:20 +00:00
context . putObject ( directoryNode . data , directoryData , update _time ) ;
2014-10-24 11:56:16 +00:00
}
}
2018-06-28 17:35:20 +00:00
}
2014-10-24 11:56:16 +00:00
2018-06-28 17:35:20 +00:00
function read _link ( context , path , callback ) {
path = normalize ( path ) ;
var name = basename ( path ) ;
var parentPath = dirname ( path ) ;
var directoryNode ;
var directoryData ;
find _node ( context , parentPath , read _directory _data ) ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function read _directory _data ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
directoryNode = result ;
context . getObject ( directoryNode . data , check _if _file _exists ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
function check _if _file _exists ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
directoryData = result ;
2018-12-21 19:22:25 +00:00
if ( ! directoryData . hasOwnProperty ( name ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . ENOENT ( 'a component of the path does not name an existing file' , name ) ) ;
} else {
context . getObject ( directoryData [ name ] . id , check _if _symbolic ) ;
}
2014-05-27 18:44:30 +00:00
}
}
2018-07-14 15:21:34 +00:00
function check _if _symbolic ( error , fileNode ) {
2018-06-28 17:35:20 +00:00
if ( error ) {
callback ( error ) ;
} else {
2018-07-14 15:21:34 +00:00
if ( fileNode . type !== NODE _TYPE _SYMBOLIC _LINK ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EINVAL ( 'path not a symbolic link' , path ) ) ;
} else {
2018-07-14 15:21:34 +00:00
// If we were originally given a relative path, return that now vs. the
// absolute path we've generated and use elsewhere internally.
var target = fileNode . symlink _relpath ? fileNode . symlink _relpath : fileNode . data ;
callback ( null , target ) ;
2018-06-28 17:35:20 +00:00
}
}
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function truncate _file ( context , path , length , callback ) {
path = normalize ( path ) ;
var fileNode ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function read _file _data ( error , node ) {
if ( error ) {
callback ( error ) ;
2018-07-14 15:21:34 +00:00
} else if ( node . type === NODE _TYPE _DIRECTORY ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EISDIR ( null , path ) ) ;
} else {
fileNode = node ;
context . getBuffer ( fileNode . data , truncate _file _data ) ;
}
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function truncate _file _data ( error , fileData ) {
if ( error ) {
callback ( error ) ;
} else {
if ( ! fileData ) {
return callback ( new Errors . EIO ( 'Expected Buffer' ) ) ;
}
2018-12-21 19:22:25 +00:00
var data = Buffer . alloc ( length ) ;
2018-06-28 17:35:20 +00:00
if ( fileData ) {
fileData . copy ( data ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
context . putBuffer ( fileNode . data , data , update _file _node ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
function update _time ( error ) {
if ( error ) {
callback ( error ) ;
} else {
var now = Date . now ( ) ;
2018-12-21 19:22:25 +00:00
update _node _times ( context , path , fileNode , {
mtime : now ,
ctime : now
} , callback ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function update _file _node ( error ) {
if ( error ) {
callback ( error ) ;
} else {
fileNode . size = length ;
fileNode . version += 1 ;
context . putObject ( fileNode . id , fileNode , update _time ) ;
}
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
if ( length < 0 ) {
callback ( new Errors . EINVAL ( 'length cannot be negative' ) ) ;
} else {
find _node ( context , path , read _file _data ) ;
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function ftruncate _file ( context , ofd , length , callback ) {
var fileNode ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function read _file _data ( error , node ) {
if ( error ) {
callback ( error ) ;
2018-07-14 15:21:34 +00:00
} else if ( node . type === NODE _TYPE _DIRECTORY ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EISDIR ( ) ) ;
} else {
fileNode = node ;
context . getBuffer ( fileNode . data , truncate _file _data ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function truncate _file _data ( error , fileData ) {
if ( error ) {
callback ( error ) ;
} else {
var data ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! fileData ) {
return callback ( new Errors . EIO ( 'Expected Buffer' ) ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( fileData ) {
data = fileData . slice ( 0 , length ) ;
} else {
2018-12-21 19:22:25 +00:00
data = Buffer . alloc ( length ) ;
2018-06-28 17:35:20 +00:00
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
context . putBuffer ( fileNode . data , data , update _file _node ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
function update _time ( error ) {
if ( error ) {
callback ( error ) ;
} else {
var now = Date . now ( ) ;
2018-12-21 19:22:25 +00:00
update _node _times ( context , ofd . path , fileNode , {
mtime : now ,
ctime : now
} , callback ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
function update _file _node ( error ) {
if ( error ) {
callback ( error ) ;
} else {
fileNode . size = length ;
fileNode . version += 1 ;
context . putObject ( fileNode . id , fileNode , update _time ) ;
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
if ( length < 0 ) {
callback ( new Errors . EINVAL ( 'length cannot be negative' ) ) ;
} else {
2018-06-28 21:02:50 +00:00
ofd . getNode ( context , read _file _data ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function utimes _file ( context , path , atime , mtime , callback ) {
path = normalize ( path ) ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function update _times ( error , node ) {
if ( error ) {
callback ( error ) ;
} else {
2018-12-21 19:22:25 +00:00
update _node _times ( context , path , node , {
atime : atime ,
ctime : mtime ,
mtime : mtime
} , callback ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
}
2018-07-14 15:21:34 +00:00
if ( typeof atime !== 'number' || typeof mtime !== 'number' ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EINVAL ( 'atime and mtime must be number' , path ) ) ;
} else if ( atime < 0 || mtime < 0 ) {
callback ( new Errors . EINVAL ( 'atime and mtime must be positive integers' , path ) ) ;
} else {
find _node ( context , path , update _times ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
function futimes _file ( context , ofd , atime , mtime , callback ) {
function update _times ( error , node ) {
if ( error ) {
callback ( error ) ;
} else {
2018-12-21 19:22:25 +00:00
update _node _times ( context , ofd . path , node , {
atime : atime ,
ctime : mtime ,
mtime : mtime
} , callback ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
}
2018-07-14 15:21:34 +00:00
if ( typeof atime !== 'number' || typeof mtime !== 'number' ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EINVAL ( 'atime and mtime must be a number' ) ) ;
} else if ( atime < 0 || mtime < 0 ) {
callback ( new Errors . EINVAL ( 'atime and mtime must be positive integers' ) ) ;
} else {
2018-06-28 21:02:50 +00:00
ofd . getNode ( context , update _times ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
function setxattr _file ( context , path , name , value , flag , callback ) {
path = normalize ( path ) ;
2018-06-28 21:02:50 +00:00
function setxattr ( error , node ) {
if ( error ) {
return callback ( error ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
set _extended _attribute ( context , path , node , name , value , flag , callback ) ;
}
2018-07-14 15:21:34 +00:00
if ( typeof name !== 'string' ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EINVAL ( 'attribute name must be a string' , path ) ) ;
} else if ( ! name ) {
callback ( new Errors . EINVAL ( 'attribute name cannot be an empty string' , path ) ) ;
} else if ( flag !== null && flag !== XATTR _CREATE && flag !== XATTR _REPLACE ) {
callback ( new Errors . EINVAL ( 'invalid flag, must be null, XATTR_CREATE or XATTR_REPLACE' , path ) ) ;
} else {
2018-06-28 21:02:50 +00:00
find _node ( context , path , setxattr ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
function fsetxattr _file ( context , ofd , name , value , flag , callback ) {
2018-06-28 21:02:50 +00:00
function setxattr ( error , node ) {
if ( error ) {
return callback ( error ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
set _extended _attribute ( context , ofd . path , node , name , value , flag , callback ) ;
}
if ( typeof name !== 'string' ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EINVAL ( 'attribute name must be a string' ) ) ;
} else if ( ! name ) {
callback ( new Errors . EINVAL ( 'attribute name cannot be an empty string' ) ) ;
} else if ( flag !== null && flag !== XATTR _CREATE && flag !== XATTR _REPLACE ) {
callback ( new Errors . EINVAL ( 'invalid flag, must be null, XATTR_CREATE or XATTR_REPLACE' ) ) ;
} else {
2018-06-28 21:02:50 +00:00
ofd . getNode ( context , setxattr ) ;
2014-05-27 18:44:30 +00:00
}
}
2018-06-28 17:35:20 +00:00
function getxattr _file ( context , path , name , callback ) {
path = normalize ( path ) ;
2014-12-02 18:45:21 +00:00
2018-06-28 17:35:20 +00:00
function get _xattr ( error , node ) {
if ( error ) {
2018-06-28 21:02:50 +00:00
return callback ( error ) ;
}
var xattrs = node . xattrs ;
if ( ! xattrs . hasOwnProperty ( name ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . ENOATTR ( null , path ) ) ;
} else {
2018-06-28 21:02:50 +00:00
callback ( null , xattrs [ name ] ) ;
2018-06-28 17:35:20 +00:00
}
}
2018-07-14 15:21:34 +00:00
if ( typeof name !== 'string' ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EINVAL ( 'attribute name must be a string' , path ) ) ;
} else if ( ! name ) {
callback ( new Errors . EINVAL ( 'attribute name cannot be an empty string' , path ) ) ;
} else {
find _node ( context , path , get _xattr ) ;
}
2014-12-02 18:45:21 +00:00
}
2018-06-28 17:35:20 +00:00
function fgetxattr _file ( context , ofd , name , callback ) {
function get _xattr ( error , node ) {
if ( error ) {
2018-06-28 21:02:50 +00:00
return callback ( error ) ;
}
var xattrs = node . xattrs ;
if ( ! xattrs . hasOwnProperty ( name ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . ENOATTR ( ) ) ;
} else {
2018-06-28 21:02:50 +00:00
callback ( null , xattrs [ name ] ) ;
2018-06-28 17:35:20 +00:00
}
}
2014-05-27 18:44:30 +00:00
2018-07-14 15:21:34 +00:00
if ( typeof name !== 'string' ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EINVAL ( ) ) ;
} else if ( ! name ) {
callback ( new Errors . EINVAL ( 'attribute name cannot be an empty string' ) ) ;
} else {
2018-06-28 21:02:50 +00:00
ofd . getNode ( context , get _xattr ) ;
2018-06-28 17:35:20 +00:00
}
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function removexattr _file ( context , path , name , callback ) {
path = normalize ( path ) ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function remove _xattr ( error , node ) {
2018-06-28 21:02:50 +00:00
if ( error ) {
return callback ( error ) ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function update _time ( error ) {
if ( error ) {
callback ( error ) ;
} else {
2018-12-21 19:22:25 +00:00
update _node _times ( context , path , node , {
ctime : Date . now ( )
} , callback ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 21:02:50 +00:00
var xattrs = node . xattrs ;
if ( ! xattrs . hasOwnProperty ( name ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . ENOATTR ( null , path ) ) ;
} else {
2018-06-28 21:02:50 +00:00
delete xattrs [ name ] ;
2018-06-28 17:35:20 +00:00
context . putObject ( node . id , node , update _time ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-06-28 21:02:50 +00:00
if ( typeof name !== 'string' ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EINVAL ( 'attribute name must be a string' , path ) ) ;
} else if ( ! name ) {
callback ( new Errors . EINVAL ( 'attribute name cannot be an empty string' , path ) ) ;
} else {
find _node ( context , path , remove _xattr ) ;
}
}
function fremovexattr _file ( context , ofd , name , callback ) {
function remove _xattr ( error , node ) {
2018-06-28 21:02:50 +00:00
if ( error ) {
return callback ( error ) ;
}
2018-06-28 17:35:20 +00:00
function update _time ( error ) {
if ( error ) {
callback ( error ) ;
} else {
2018-12-21 19:22:25 +00:00
update _node _times ( context , ofd . path , node , {
ctime : Date . now ( )
} , callback ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 21:02:50 +00:00
var xattrs = node . xattrs ;
if ( ! xattrs . hasOwnProperty ( name ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . ENOATTR ( ) ) ;
} else {
2018-06-28 21:02:50 +00:00
delete xattrs [ name ] ;
2018-06-28 17:35:20 +00:00
context . putObject ( node . id , node , update _time ) ;
}
}
2014-05-27 18:44:30 +00:00
2018-07-14 15:21:34 +00:00
if ( typeof name !== 'string' ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EINVAL ( 'attribute name must be a string' ) ) ;
} else if ( ! name ) {
callback ( new Errors . EINVAL ( 'attribute name cannot be an empty string' ) ) ;
} else {
2018-06-28 21:02:50 +00:00
ofd . getNode ( context , remove _xattr ) ;
2018-06-28 17:35:20 +00:00
}
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function validate _flags ( flags ) {
2018-12-21 19:22:25 +00:00
return O _FLAGS . hasOwnProperty ( flags ) ? O _FLAGS [ flags ] : null ;
2014-06-23 18:31:58 +00:00
}
2014-08-17 05:56:03 +00:00
2018-06-28 17:35:20 +00:00
function validate _file _options ( options , enc , fileMode ) {
if ( ! options ) {
2018-12-21 19:22:25 +00:00
options = {
encoding : enc ,
flag : fileMode
} ;
2018-10-30 18:35:33 +00:00
} else if ( typeof options === 'function' ) {
2018-12-21 19:22:25 +00:00
options = {
encoding : enc ,
flag : fileMode
} ;
2018-10-30 18:35:33 +00:00
} else if ( typeof options === 'string' ) {
2018-12-21 19:22:25 +00:00
options = {
encoding : options ,
flag : fileMode
} ;
2017-05-25 14:05:32 +00:00
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
return options ;
}
2017-05-25 14:05:32 +00:00
2019-01-03 04:12:19 +00:00
function open ( context , path , flags , mode , callback ) {
if ( arguments . length < 5 ) {
2018-12-21 19:22:25 +00:00
callback = arguments [ arguments . length - 1 ] ;
mode = 420 ;
} else {
mode = validateAndMaskMode ( mode , FULL _READ _WRITE _EXEC _PERMISSIONS , callback ) ;
}
2018-07-14 15:21:34 +00:00
2018-06-28 17:35:20 +00:00
function check _result ( error , fileNode ) {
if ( error ) {
callback ( error ) ;
} else {
var position ;
2018-12-21 19:22:25 +00:00
if ( flags . includes ( O _APPEND ) ) {
2018-06-28 17:35:20 +00:00
position = fileNode . size ;
} else {
position = 0 ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var openFileDescription = new OpenFileDescription ( path , fileNode . id , flags , position ) ;
2019-01-03 04:12:19 +00:00
var fd = openFiles . allocDescriptor ( openFileDescription ) ;
2018-06-28 17:35:20 +00:00
callback ( null , fd ) ;
2014-08-17 05:56:03 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-08-17 05:56:03 +00:00
2018-06-28 17:35:20 +00:00
flags = validate _flags ( flags ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! flags ) {
2018-12-21 19:22:25 +00:00
return callback ( new Errors . EINVAL ( 'flags is not valid' ) , path ) ;
2014-06-23 18:31:58 +00:00
}
2014-08-17 05:56:03 +00:00
2018-12-21 19:22:25 +00:00
open _file ( context , path , flags , mode , check _result ) ;
2018-06-28 17:35:20 +00:00
}
2019-01-03 04:12:19 +00:00
function close ( context , fd , callback ) {
if ( ! openFiles . getOpenFileDescription ( fd ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EBADF ( ) ) ;
} else {
2019-01-03 04:12:19 +00:00
openFiles . releaseDescriptor ( fd ) ;
2018-06-28 17:35:20 +00:00
callback ( null ) ;
2014-06-23 18:31:58 +00:00
}
2018-06-28 17:35:20 +00:00
}
2019-01-03 04:12:19 +00:00
function mknod ( context , path , type , callback ) {
2018-07-14 15:21:34 +00:00
make _node ( context , path , type , callback ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2019-01-03 04:12:19 +00:00
function mkdir ( context , path , mode , callback ) {
if ( arguments . length < 4 ) {
2018-07-14 15:21:34 +00:00
callback = mode ;
mode = FULL _READ _WRITE _EXEC _PERMISSIONS ;
} else {
mode = validateAndMaskMode ( mode , FULL _READ _WRITE _EXEC _PERMISSIONS , callback ) ;
if ( ! mode ) return ;
}
2018-06-28 21:02:50 +00:00
make _directory ( context , path , callback ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2019-01-03 04:12:19 +00:00
function access ( context , path , mode , callback ) {
2018-12-21 19:22:25 +00:00
if ( typeof mode === 'function' ) {
callback = mode ;
mode = Constants . fsConstants . F _OK ;
}
mode = mode | Constants . fsConstants . F _OK ;
access _file ( context , path , mode , callback ) ;
}
2019-01-03 04:12:19 +00:00
function mkdtemp ( context , prefix , options , callback ) {
2018-12-21 19:22:25 +00:00
callback = arguments [ arguments . length - 1 ] ;
if ( ! prefix ) {
return callback ( new Error ( 'filename prefix is required' ) ) ;
}
var random = shared . randomChars ( 6 ) ;
var path = prefix + '-' + random ;
make _directory ( context , path , function ( error ) {
callback ( error , path ) ;
} ) ;
}
2019-01-03 04:12:19 +00:00
function rmdir ( context , path , callback ) {
2018-06-28 21:02:50 +00:00
remove _directory ( context , path , callback ) ;
2018-06-28 17:35:20 +00:00
}
2019-01-03 04:12:19 +00:00
function stat ( context , path , callback ) {
2018-06-28 17:35:20 +00:00
function check _result ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
2019-01-03 04:12:19 +00:00
var stats = new Stats ( path , result , context . name ) ;
2018-06-28 17:35:20 +00:00
callback ( null , stats ) ;
}
}
stat _file ( context , path , check _result ) ;
}
2019-01-03 04:12:19 +00:00
function fstat ( context , fd , callback ) {
2018-06-28 17:35:20 +00:00
function check _result ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
2019-01-03 04:12:19 +00:00
var stats = new Stats ( ofd . path , result , context . name ) ;
2018-06-28 17:35:20 +00:00
callback ( null , stats ) ;
}
}
2019-01-03 04:12:19 +00:00
var ofd = openFiles . getOpenFileDescription ( fd ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! ofd ) {
callback ( new Errors . EBADF ( ) ) ;
} else {
fstat _file ( context , ofd , check _result ) ;
}
}
2019-01-03 04:12:19 +00:00
function link ( context , oldpath , newpath , callback ) {
2018-06-28 21:02:50 +00:00
link _node ( context , oldpath , newpath , callback ) ;
2018-06-28 17:35:20 +00:00
}
2019-01-03 04:12:19 +00:00
function unlink ( context , path , callback ) {
2018-06-28 21:02:50 +00:00
unlink _node ( context , path , callback ) ;
2018-06-28 17:35:20 +00:00
}
2019-01-03 04:12:19 +00:00
function read ( context , fd , buffer , offset , length , position , callback ) {
2018-06-28 17:35:20 +00:00
// Follow how node.js does this
function wrapped _cb ( err , bytesRead ) {
// Retain a reference to buffer so that it can't be GC'ed too soon.
callback ( err , bytesRead || 0 , buffer ) ;
}
offset = undefined === offset ? 0 : offset ;
length = undefined === length ? buffer . length - offset : length ;
callback = arguments [ arguments . length - 1 ] ;
2019-01-03 04:12:19 +00:00
var ofd = openFiles . getOpenFileDescription ( fd ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! ofd ) {
callback ( new Errors . EBADF ( ) ) ;
2018-12-21 19:22:25 +00:00
} else if ( ! ofd . flags . includes ( O _READ ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EBADF ( 'descriptor does not permit reading' ) ) ;
} else {
2018-06-28 21:02:50 +00:00
read _data ( context , ofd , buffer , offset , length , position , wrapped _cb ) ;
2018-06-28 17:35:20 +00:00
}
2014-06-23 18:31:58 +00:00
}
2014-05-27 18:44:30 +00:00
2019-01-03 04:12:19 +00:00
function fsync ( context , fd , callback ) {
2018-12-21 19:22:25 +00:00
if ( validateInteger ( fd , callback ) !== fd ) return ;
2019-01-03 04:12:19 +00:00
var ofd = openFiles . getOpenFileDescription ( fd ) ;
2018-12-21 19:22:25 +00:00
if ( ! ofd ) {
callback ( new Errors . EBADF ( ) ) ;
} else {
callback ( ) ;
}
}
2019-01-03 04:12:19 +00:00
function readFile ( context , path , options , callback ) {
2018-06-28 17:35:20 +00:00
callback = arguments [ arguments . length - 1 ] ;
options = validate _file _options ( options , null , 'r' ) ;
var flags = validate _flags ( options . flag || 'r' ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! flags ) {
return callback ( new Errors . EINVAL ( 'flags is not valid' , path ) ) ;
2014-06-23 18:31:58 +00:00
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
open _file ( context , path , flags , function ( err , fileNode ) {
if ( err ) {
return callback ( err ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var ofd = new OpenFileDescription ( path , fileNode . id , flags , 0 ) ;
2019-01-03 04:12:19 +00:00
var fd = openFiles . allocDescriptor ( ofd ) ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function cleanup ( ) {
2019-01-03 04:12:19 +00:00
openFiles . releaseDescriptor ( fd ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
fstat _file ( context , ofd , function ( err , fstatResult ) {
if ( err ) {
cleanup ( ) ;
return callback ( err ) ;
2017-05-25 14:05:32 +00:00
}
2014-06-23 18:31:58 +00:00
2019-01-03 04:12:19 +00:00
var stats = new Stats ( ofd . path , fstatResult , context . name ) ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
if ( stats . isDirectory ( ) ) {
cleanup ( ) ;
return callback ( new Errors . EISDIR ( 'illegal operation on directory' , path ) ) ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
var size = stats . size ;
2018-12-21 19:22:25 +00:00
var buffer = Buffer . alloc ( size ) ;
2018-10-30 18:35:33 +00:00
read _data ( context , ofd , buffer , 0 , size , 0 , function ( err ) {
2018-06-28 17:35:20 +00:00
cleanup ( ) ;
2014-08-17 05:56:03 +00:00
2018-06-28 17:35:20 +00:00
if ( err ) {
return callback ( err ) ;
}
var data ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( options . encoding === 'utf8' ) {
2019-02-07 21:38:32 +00:00
data = buffer . toString ( 'utf8' ) ;
2018-06-28 17:35:20 +00:00
} else {
data = buffer ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
callback ( null , data ) ;
} ) ;
2014-05-27 18:44:30 +00:00
} ) ;
} ) ;
2018-06-28 17:35:20 +00:00
}
2014-08-17 05:56:03 +00:00
2019-01-03 04:12:19 +00:00
function write ( context , fd , buffer , offset , length , position , callback ) {
2018-06-28 17:35:20 +00:00
callback = arguments [ arguments . length - 1 ] ;
offset = undefined === offset ? 0 : offset ;
length = undefined === length ? buffer . length - offset : length ;
2019-01-03 04:12:19 +00:00
var ofd = openFiles . getOpenFileDescription ( fd ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! ofd ) {
callback ( new Errors . EBADF ( ) ) ;
2018-12-21 19:22:25 +00:00
} else if ( ! ofd . flags . includes ( O _WRITE ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EBADF ( 'descriptor does not permit writing' ) ) ;
} else if ( buffer . length - offset < length ) {
2018-12-21 19:22:25 +00:00
callback ( new Errors . EIO ( 'input buffer is too small' ) ) ;
2018-06-28 17:35:20 +00:00
} else {
2018-06-28 21:02:50 +00:00
write _data ( context , ofd , buffer , offset , length , position , callback ) ;
2014-05-27 18:44:30 +00:00
}
}
2019-01-03 04:12:19 +00:00
function writeFile ( context , path , data , options , callback ) {
2018-06-28 17:35:20 +00:00
callback = arguments [ arguments . length - 1 ] ;
options = validate _file _options ( options , 'utf8' , 'w' ) ;
var flags = validate _flags ( options . flag || 'w' ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! flags ) {
return callback ( new Errors . EINVAL ( 'flags is not valid' , path ) ) ;
2014-06-23 18:31:58 +00:00
}
2014-08-17 05:56:03 +00:00
2018-06-28 17:35:20 +00:00
data = data || '' ;
2018-12-21 19:22:25 +00:00
2018-10-30 18:35:33 +00:00
if ( typeof data === 'number' ) {
2018-06-28 17:35:20 +00:00
data = '' + data ;
2014-06-23 18:31:58 +00:00
}
2018-12-21 19:22:25 +00:00
2018-10-30 18:35:33 +00:00
if ( typeof data === 'string' && options . encoding === 'utf8' ) {
2019-02-07 21:38:32 +00:00
data = Buffer . from ( data ) ;
2014-06-23 18:31:58 +00:00
}
2018-06-28 17:35:20 +00:00
open _file ( context , path , flags , function ( err , fileNode ) {
if ( err ) {
2014-08-17 05:56:03 +00:00
return callback ( err ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var ofd = new OpenFileDescription ( path , fileNode . id , flags , 0 ) ;
2019-01-03 04:12:19 +00:00
var fd = openFiles . allocDescriptor ( ofd ) ;
2018-10-30 18:35:33 +00:00
replace _data ( context , ofd , data , 0 , data . length , function ( err ) {
2019-01-03 04:12:19 +00:00
openFiles . releaseDescriptor ( fd ) ;
2014-08-17 05:56:03 +00:00
2018-06-28 17:35:20 +00:00
if ( err ) {
return callback ( err ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
callback ( null ) ;
} ) ;
2014-08-17 05:56:03 +00:00
} ) ;
2018-06-28 17:35:20 +00:00
}
2014-08-17 05:56:03 +00:00
2019-01-03 04:12:19 +00:00
function appendFile ( context , path , data , options , callback ) {
2018-06-28 17:35:20 +00:00
callback = arguments [ arguments . length - 1 ] ;
options = validate _file _options ( options , 'utf8' , 'a' ) ;
var flags = validate _flags ( options . flag || 'a' ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! flags ) {
return callback ( new Errors . EINVAL ( 'flags is not valid' , path ) ) ;
2014-06-23 18:31:58 +00:00
}
2014-08-17 05:56:03 +00:00
2018-06-28 17:35:20 +00:00
data = data || '' ;
2018-12-21 19:22:25 +00:00
2018-10-30 18:35:33 +00:00
if ( typeof data === 'number' ) {
2018-06-28 17:35:20 +00:00
data = '' + data ;
2014-06-23 18:31:58 +00:00
}
2018-12-21 19:22:25 +00:00
2018-10-30 18:35:33 +00:00
if ( typeof data === 'string' && options . encoding === 'utf8' ) {
2019-02-07 21:38:32 +00:00
data = Buffer . from ( data ) ;
2014-06-23 18:31:58 +00:00
}
2018-06-28 17:35:20 +00:00
open _file ( context , path , flags , function ( err , fileNode ) {
if ( err ) {
return callback ( err ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var ofd = new OpenFileDescription ( path , fileNode . id , flags , fileNode . size ) ;
2019-01-03 04:12:19 +00:00
var fd = openFiles . allocDescriptor ( ofd ) ;
2018-10-30 18:35:33 +00:00
write _data ( context , ofd , data , 0 , data . length , ofd . position , function ( err ) {
2019-01-03 04:12:19 +00:00
openFiles . releaseDescriptor ( fd ) ;
2018-07-14 15:21:34 +00:00
if ( err ) {
return callback ( err ) ;
}
2018-12-21 19:22:25 +00:00
2018-07-14 15:21:34 +00:00
callback ( null ) ;
} ) ;
} ) ;
}
2019-01-03 04:12:19 +00:00
function exists ( context , path , callback ) {
2018-10-30 18:35:33 +00:00
function cb ( err ) {
2018-07-14 15:21:34 +00:00
callback ( err ? false : true ) ;
}
2018-12-21 19:22:25 +00:00
2019-01-03 04:12:19 +00:00
stat ( context , path , cb ) ;
2018-07-14 15:21:34 +00:00
}
2018-12-21 19:22:25 +00:00
function validateInteger ( value , callback ) {
if ( typeof value !== 'number' ) {
callback ( new Errors . EINVAL ( 'Expected integer' , value ) ) ;
return ;
}
return value ;
} // Based on https://github.com/nodejs/node/blob/c700cc42da9cf73af9fec2098520a6c0a631d901/lib/internal/validators.js#L21
2018-07-14 15:21:34 +00:00
var octalReg = /^[0-7]+$/ ;
2018-12-21 19:22:25 +00:00
2018-07-14 15:21:34 +00:00
function isUint32 ( value ) {
return value === value >>> 0 ;
2018-12-21 19:22:25 +00:00
} // Validator for mode_t (the S_* constants). Valid numbers or octal strings
2018-07-14 15:21:34 +00:00
// will be masked with 0o777 to be consistent with the behavior in POSIX APIs.
2018-12-21 19:22:25 +00:00
2018-07-14 15:21:34 +00:00
function validateAndMaskMode ( value , def , callback ) {
if ( typeof def === 'function' ) {
callback = def ;
def = undefined ;
}
if ( isUint32 ( value ) ) {
return value & FULL _READ _WRITE _EXEC _PERMISSIONS ;
}
if ( typeof value === 'number' ) {
if ( ! Number . isInteger ( value ) ) {
callback ( new Errors . EINVAL ( 'mode not a valid an integer value' , value ) ) ;
return false ;
} else {
// 2 ** 32 === 4294967296
callback ( new Errors . EINVAL ( 'mode not a valid an integer value' , value ) ) ;
return false ;
}
}
if ( typeof value === 'string' ) {
if ( ! octalReg . test ( value ) ) {
callback ( new Errors . EINVAL ( 'mode not a valid octal string' , value ) ) ;
return false ;
}
2018-12-21 19:22:25 +00:00
2018-07-14 15:21:34 +00:00
var parsed = parseInt ( value , 8 ) ;
return parsed & FULL _READ _WRITE _EXEC _PERMISSIONS ;
2018-12-21 19:22:25 +00:00
} // TODO(BridgeAR): Only return `def` in case `value === null`
2018-07-14 15:21:34 +00:00
if ( def !== undefined ) {
return def ;
}
callback ( new Errors . EINVAL ( 'mode not valid' , value ) ) ;
return false ;
}
function chmod _file ( context , path , mode , callback ) {
path = normalize ( path ) ;
function update _mode ( error , node ) {
if ( error ) {
callback ( error ) ;
} else {
2018-12-21 19:22:25 +00:00
node . mode = mode ;
update _node _times ( context , path , node , {
mtime : Date . now ( )
} , callback ) ;
2018-07-14 15:21:34 +00:00
}
}
if ( typeof mode !== 'number' ) {
callback ( new Errors . EINVAL ( 'mode must be number' , path ) ) ;
} else {
find _node ( context , path , update _mode ) ;
}
}
function fchmod _file ( context , ofd , mode , callback ) {
function update _mode ( error , node ) {
if ( error ) {
callback ( error ) ;
} else {
node . mode = mode ;
2018-12-21 19:22:25 +00:00
update _node _times ( context , ofd . path , node , {
mtime : Date . now ( )
} , callback ) ;
2018-07-14 15:21:34 +00:00
}
}
if ( typeof mode !== 'number' ) {
callback ( new Errors . EINVAL ( 'mode must be a number' ) ) ;
} else {
ofd . getNode ( context , update _mode ) ;
}
}
function chown _file ( context , path , uid , gid , callback ) {
path = normalize ( path ) ;
2018-06-28 17:35:20 +00:00
2018-07-14 15:21:34 +00:00
function update _owner ( error , node ) {
if ( error ) {
callback ( error ) ;
} else {
node . uid = uid ;
node . gid = gid ;
2018-12-21 19:22:25 +00:00
update _node _times ( context , path , node , {
mtime : Date . now ( )
} , callback ) ;
2018-07-14 15:21:34 +00:00
}
}
find _node ( context , path , update _owner ) ;
2018-06-28 17:35:20 +00:00
}
2018-07-14 15:21:34 +00:00
function fchown _file ( context , ofd , uid , gid , callback ) {
function update _owner ( error , node ) {
if ( error ) {
callback ( error ) ;
} else {
node . uid = uid ;
node . gid = gid ;
2018-12-21 19:22:25 +00:00
update _node _times ( context , ofd . path , node , {
mtime : Date . now ( )
} , callback ) ;
2018-07-14 15:21:34 +00:00
}
2018-06-28 17:35:20 +00:00
}
2018-07-14 15:21:34 +00:00
ofd . getNode ( context , update _owner ) ;
2014-06-23 18:31:58 +00:00
}
2019-01-03 04:12:19 +00:00
function getxattr ( context , path , name , callback ) {
2018-06-28 21:02:50 +00:00
getxattr _file ( context , path , name , callback ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2019-01-03 04:12:19 +00:00
function fgetxattr ( context , fd , name , callback ) {
var ofd = openFiles . getOpenFileDescription ( fd ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! ofd ) {
callback ( new Errors . EBADF ( ) ) ;
} else {
2018-06-28 21:02:50 +00:00
fgetxattr _file ( context , ofd , name , callback ) ;
2014-06-23 18:31:58 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2019-01-03 04:12:19 +00:00
function setxattr ( context , path , name , value , flag , callback ) {
2018-06-28 17:35:20 +00:00
if ( typeof flag === 'function' ) {
callback = flag ;
flag = null ;
2014-06-23 18:31:58 +00:00
}
2014-05-27 18:44:30 +00:00
2018-06-28 21:02:50 +00:00
setxattr _file ( context , path , name , value , flag , callback ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2019-01-03 04:12:19 +00:00
function fsetxattr ( context , fd , name , value , flag , callback ) {
2018-06-28 17:35:20 +00:00
if ( typeof flag === 'function' ) {
callback = flag ;
flag = null ;
}
2014-05-27 18:44:30 +00:00
2019-01-03 04:12:19 +00:00
var ofd = openFiles . getOpenFileDescription ( fd ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! ofd ) {
callback ( new Errors . EBADF ( ) ) ;
2018-12-21 19:22:25 +00:00
} else if ( ! ofd . flags . includes ( O _WRITE ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EBADF ( 'descriptor does not permit writing' ) ) ;
} else {
2018-06-28 21:02:50 +00:00
fsetxattr _file ( context , ofd , name , value , flag , callback ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
}
2019-01-03 04:12:19 +00:00
function removexattr ( context , path , name , callback ) {
2018-06-28 21:02:50 +00:00
removexattr _file ( context , path , name , callback ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2019-01-03 04:12:19 +00:00
function fremovexattr ( context , fd , name , callback ) {
var ofd = openFiles . getOpenFileDescription ( fd ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! ofd ) {
callback ( new Errors . EBADF ( ) ) ;
2018-12-21 19:22:25 +00:00
} else if ( ! ofd . flags . includes ( O _WRITE ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EBADF ( 'descriptor does not permit writing' ) ) ;
} else {
2018-06-28 21:02:50 +00:00
fremovexattr _file ( context , ofd , name , callback ) ;
2014-05-27 18:44:30 +00:00
}
}
2019-01-03 04:12:19 +00:00
function lseek ( context , fd , offset , whence , callback ) {
2018-06-28 17:35:20 +00:00
function update _descriptor _position ( error , stats ) {
if ( error ) {
callback ( error ) ;
} else {
if ( stats . size + offset < 0 ) {
callback ( new Errors . EINVAL ( 'resulting file offset would be negative' ) ) ;
} else {
ofd . position = stats . size + offset ;
callback ( null , ofd . position ) ;
}
}
}
2014-05-27 18:44:30 +00:00
2019-01-03 04:12:19 +00:00
var ofd = openFiles . getOpenFileDescription ( fd ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! ofd ) {
callback ( new Errors . EBADF ( ) ) ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
if ( 'SET' === whence ) {
if ( offset < 0 ) {
callback ( new Errors . EINVAL ( 'resulting file offset would be negative' ) ) ;
} else {
ofd . position = offset ;
callback ( null , ofd . position ) ;
}
} else if ( 'CUR' === whence ) {
if ( ofd . position + offset < 0 ) {
callback ( new Errors . EINVAL ( 'resulting file offset would be negative' ) ) ;
} else {
ofd . position += offset ;
callback ( null , ofd . position ) ;
}
} else if ( 'END' === whence ) {
fstat _file ( context , ofd , update _descriptor _position ) ;
} else {
callback ( new Errors . EINVAL ( 'whence argument is not a proper value' ) ) ;
}
}
2014-05-27 18:44:30 +00:00
2019-01-03 04:12:19 +00:00
function readdir ( context , path , callback ) {
2018-06-28 21:02:50 +00:00
read _directory ( context , path , callback ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-12-21 19:22:25 +00:00
function toUnixTimestamp ( time ) {
if ( typeof time === 'number' ) {
return time ;
}
if ( _typeof ( time ) === 'object' && typeof time . getTime === 'function' ) {
2019-02-07 21:38:32 +00:00
return time . getTime ( ) ;
2018-12-21 19:22:25 +00:00
}
}
2019-01-03 04:12:19 +00:00
function utimes ( context , path , atime , mtime , callback ) {
2018-06-28 17:35:20 +00:00
var currentTime = Date . now ( ) ;
2018-12-21 19:22:25 +00:00
atime = atime ? toUnixTimestamp ( atime ) : toUnixTimestamp ( currentTime ) ;
mtime = mtime ? toUnixTimestamp ( mtime ) : toUnixTimestamp ( currentTime ) ;
2018-06-28 21:02:50 +00:00
utimes _file ( context , path , atime , mtime , callback ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2019-01-03 04:12:19 +00:00
function futimes ( context , fd , atime , mtime , callback ) {
2018-06-28 17:35:20 +00:00
var currentTime = Date . now ( ) ;
2018-12-21 19:22:25 +00:00
atime = atime ? toUnixTimestamp ( atime ) : toUnixTimestamp ( currentTime ) ;
mtime = mtime ? toUnixTimestamp ( mtime ) : toUnixTimestamp ( currentTime ) ;
2019-01-03 04:12:19 +00:00
var ofd = openFiles . getOpenFileDescription ( fd ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! ofd ) {
callback ( new Errors . EBADF ( ) ) ;
2018-12-21 19:22:25 +00:00
} else if ( ! ofd . flags . includes ( O _WRITE ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EBADF ( 'descriptor does not permit writing' ) ) ;
} else {
2018-06-28 21:02:50 +00:00
futimes _file ( context , ofd , atime , mtime , callback ) ;
2018-06-28 17:35:20 +00:00
}
}
2014-05-27 18:44:30 +00:00
2019-01-03 04:12:19 +00:00
function chmod ( context , path , mode , callback ) {
2018-12-22 04:09:29 +00:00
mode = validateAndMaskMode ( mode , callback ) ;
2018-07-14 15:21:34 +00:00
if ( ! mode ) return ;
chmod _file ( context , path , mode , callback ) ;
}
2019-01-03 04:12:19 +00:00
function fchmod ( context , fd , mode , callback ) {
2018-12-22 04:09:29 +00:00
mode = validateAndMaskMode ( mode , callback ) ;
2018-07-14 15:21:34 +00:00
if ( ! mode ) return ;
2019-01-03 04:12:19 +00:00
var ofd = openFiles . getOpenFileDescription ( fd ) ;
2018-12-21 19:22:25 +00:00
2018-07-14 15:21:34 +00:00
if ( ! ofd ) {
callback ( new Errors . EBADF ( ) ) ;
2018-12-21 19:22:25 +00:00
} else if ( ! ofd . flags . includes ( O _WRITE ) ) {
2018-07-14 15:21:34 +00:00
callback ( new Errors . EBADF ( 'descriptor does not permit writing' ) ) ;
} else {
fchmod _file ( context , ofd , mode , callback ) ;
}
}
2019-01-03 04:12:19 +00:00
function chown ( context , path , uid , gid , callback ) {
2018-07-14 15:21:34 +00:00
if ( ! isUint32 ( uid ) ) {
return callback ( new Errors . EINVAL ( 'uid must be a valid integer' , uid ) ) ;
}
2018-12-21 19:22:25 +00:00
2018-07-14 15:21:34 +00:00
if ( ! isUint32 ( gid ) ) {
return callback ( new Errors . EINVAL ( 'gid must be a valid integer' , gid ) ) ;
}
chown _file ( context , path , uid , gid , callback ) ;
}
2019-01-03 04:12:19 +00:00
function fchown ( context , fd , uid , gid , callback ) {
2018-07-14 15:21:34 +00:00
if ( ! isUint32 ( uid ) ) {
return callback ( new Errors . EINVAL ( 'uid must be a valid integer' , uid ) ) ;
}
2018-12-21 19:22:25 +00:00
2018-07-14 15:21:34 +00:00
if ( ! isUint32 ( gid ) ) {
return callback ( new Errors . EINVAL ( 'gid must be a valid integer' , gid ) ) ;
}
2019-01-03 04:12:19 +00:00
var ofd = openFiles . getOpenFileDescription ( fd ) ;
2018-12-21 19:22:25 +00:00
2018-07-14 15:21:34 +00:00
if ( ! ofd ) {
callback ( new Errors . EBADF ( ) ) ;
2018-12-21 19:22:25 +00:00
} else if ( ! ofd . flags . includes ( O _WRITE ) ) {
2018-07-14 15:21:34 +00:00
callback ( new Errors . EBADF ( 'descriptor does not permit writing' ) ) ;
} else {
fchown _file ( context , ofd , uid , gid , callback ) ;
}
}
2019-01-03 04:12:19 +00:00
function rename ( context , oldpath , newpath , callback ) {
2018-06-28 21:02:50 +00:00
oldpath = normalize ( oldpath ) ;
newpath = normalize ( newpath ) ;
var oldParentPath = Path . dirname ( oldpath ) ;
var newParentPath = Path . dirname ( oldpath ) ;
var oldName = Path . basename ( oldpath ) ;
var newName = Path . basename ( newpath ) ;
var oldParentDirectory , oldParentData ;
var newParentDirectory , newParentData ;
2018-07-14 15:21:34 +00:00
var ctime = Date . now ( ) ;
var fileNode ;
2018-06-28 21:02:50 +00:00
2018-07-14 15:21:34 +00:00
function update _times ( error , result ) {
2018-06-28 21:02:50 +00:00
if ( error ) {
callback ( error ) ;
} else {
2018-07-14 15:21:34 +00:00
fileNode = result ;
2018-12-21 19:22:25 +00:00
update _node _times ( context , newpath , fileNode , {
ctime : ctime
} , callback ) ;
2018-06-28 21:02:50 +00:00
}
}
function read _new _directory ( error ) {
if ( error ) {
callback ( error ) ;
} else {
context . getObject ( newParentData [ newName ] . id , update _times ) ;
}
}
function update _old _parent _directory _data ( error ) {
if ( error ) {
callback ( error ) ;
} else {
if ( oldParentDirectory . id === newParentDirectory . id ) {
oldParentData = newParentData ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 21:02:50 +00:00
delete oldParentData [ oldName ] ;
context . putObject ( oldParentDirectory . data , oldParentData , read _new _directory ) ;
}
}
function update _new _parent _directory _data ( error ) {
if ( error ) {
callback ( error ) ;
} else {
newParentData [ newName ] = oldParentData [ oldName ] ;
context . putObject ( newParentDirectory . data , newParentData , update _old _parent _directory _data ) ;
}
}
function check _if _new _directory _exists ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
newParentData = result ;
2018-12-21 19:22:25 +00:00
if ( newParentData . hasOwnProperty ( newName ) ) {
2018-06-28 21:02:50 +00:00
remove _directory ( context , newpath , update _new _parent _directory _data ) ;
} else {
update _new _parent _directory _data ( ) ;
}
}
}
function read _new _parent _directory _data ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
newParentDirectory = result ;
context . getObject ( newParentDirectory . data , check _if _new _directory _exists ) ;
}
}
function get _new _parent _directory ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
oldParentData = result ;
find _node ( context , newParentPath , read _new _parent _directory _data ) ;
}
}
function read _parent _directory _data ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
oldParentDirectory = result ;
context . getObject ( result . data , get _new _parent _directory ) ;
}
}
function unlink _old _file ( error ) {
if ( error ) {
callback ( error ) ;
} else {
unlink _node ( context , oldpath , callback ) ;
}
}
function check _node _type ( error , node ) {
2018-06-28 17:35:20 +00:00
if ( error ) {
callback ( error ) ;
2018-07-14 15:21:34 +00:00
} else if ( node . type === NODE _TYPE _DIRECTORY ) {
2018-06-28 21:02:50 +00:00
find _node ( context , oldParentPath , read _parent _directory _data ) ;
2018-06-28 17:35:20 +00:00
} else {
2018-06-28 21:02:50 +00:00
link _node ( context , oldpath , newpath , unlink _old _file ) ;
2018-06-28 17:35:20 +00:00
}
}
2014-05-27 18:44:30 +00:00
2018-06-28 21:02:50 +00:00
find _node ( context , oldpath , check _node _type ) ;
2014-05-27 18:44:30 +00:00
}
2019-01-03 04:12:19 +00:00
function symlink ( context , srcpath , dstpath , type , callback ) {
2018-06-28 17:35:20 +00:00
// NOTE: we support passing the `type` arg, but ignore it.
2019-01-03 04:12:19 +00:00
callback = arguments [ arguments . length - 1 ] ;
2018-06-28 21:02:50 +00:00
make _symbolic _link ( context , srcpath , dstpath , callback ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2019-01-03 04:12:19 +00:00
function readlink ( context , path , callback ) {
2018-06-28 21:02:50 +00:00
read _link ( context , path , callback ) ;
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2019-01-03 04:12:19 +00:00
function lstat ( context , path , callback ) {
2018-06-28 17:35:20 +00:00
function check _result ( error , result ) {
if ( error ) {
callback ( error ) ;
} else {
2019-01-03 04:12:19 +00:00
var stats = new Stats ( path , result , context . name ) ;
2018-06-28 17:35:20 +00:00
callback ( null , stats ) ;
}
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
lstat _file ( context , path , check _result ) ;
}
2014-05-27 18:44:30 +00:00
2019-01-03 04:12:19 +00:00
function truncate ( context , path , length , callback ) {
2018-06-28 17:35:20 +00:00
// NOTE: length is optional
callback = arguments [ arguments . length - 1 ] ;
length = length || 0 ;
2018-12-21 19:22:25 +00:00
if ( validateInteger ( length , callback ) !== length ) return ;
2018-06-28 21:02:50 +00:00
truncate _file ( context , path , length , callback ) ;
2018-06-28 17:35:20 +00:00
}
2019-01-03 04:12:19 +00:00
function ftruncate ( context , fd , length , callback ) {
2018-06-28 17:35:20 +00:00
// NOTE: length is optional
callback = arguments [ arguments . length - 1 ] ;
length = length || 0 ;
2019-01-03 04:12:19 +00:00
var ofd = openFiles . getOpenFileDescription ( fd ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( ! ofd ) {
callback ( new Errors . EBADF ( ) ) ;
2018-12-21 19:22:25 +00:00
} else if ( ! ofd . flags . includes ( O _WRITE ) ) {
2018-06-28 17:35:20 +00:00
callback ( new Errors . EBADF ( 'descriptor does not permit writing' ) ) ;
} else {
2018-12-21 19:22:25 +00:00
if ( validateInteger ( length , callback ) !== length ) return ;
2018-06-28 21:02:50 +00:00
ftruncate _file ( context , ofd , length , callback ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
module . exports = {
2019-01-03 04:12:19 +00:00
appendFile : appendFile ,
2018-12-21 19:22:25 +00:00
access : access ,
2018-07-14 15:21:34 +00:00
chown : chown ,
2019-01-03 04:12:19 +00:00
chmod : chmod ,
2018-06-28 17:35:20 +00:00
close : close ,
2019-01-03 04:12:19 +00:00
// copyFile - https://github.com/filerjs/filer/issues/436
ensureRootDirectory : ensure _root _directory ,
2018-06-28 17:35:20 +00:00
exists : exists ,
2019-01-03 04:12:19 +00:00
fchown : fchown ,
fchmod : fchmod ,
// fdatasync - https://github.com/filerjs/filer/issues/653
2018-06-28 17:35:20 +00:00
fgetxattr : fgetxattr ,
fremovexattr : fremovexattr ,
2019-01-03 04:12:19 +00:00
fsetxattr : fsetxattr ,
fstat : fstat ,
fsync : fsync ,
ftruncate : ftruncate ,
futimes : futimes ,
getxattr : getxattr ,
// lchown - https://github.com/filerjs/filer/issues/620
// lchmod - https://github.com/filerjs/filer/issues/619
link : link ,
2018-06-28 17:35:20 +00:00
lseek : lseek ,
2019-01-03 04:12:19 +00:00
lstat : lstat ,
mkdir : mkdir ,
mkdtemp : mkdtemp ,
mknod : mknod ,
open : open ,
2018-06-28 17:35:20 +00:00
readdir : readdir ,
2019-01-03 04:12:19 +00:00
read : read ,
readFile : readFile ,
readlink : readlink ,
// realpath - https://github.com/filerjs/filer/issues/85
removexattr : removexattr ,
2018-06-28 17:35:20 +00:00
rename : rename ,
2019-01-03 04:12:19 +00:00
rmdir : rmdir ,
setxattr : setxattr ,
stat : stat ,
2018-06-28 17:35:20 +00:00
symlink : symlink ,
truncate : truncate ,
2019-01-03 04:12:19 +00:00
// unwatchFile - implemented in interface.js
unlink : unlink ,
utimes : utimes ,
// watch - implemented in interface.js
// watchFile - implemented in interface.js
writeFile : writeFile ,
write : write
2014-05-27 18:44:30 +00:00
} ;
2019-02-07 21:38:32 +00:00
} , { "../path.js" : "UzoP" , "../shared.js" : "3zBM" , "../constants.js" : "iJA9" , "../errors.js" : "p8GN" , "../directory-entry.js" : "ZECt" , "../open-files.js" : "osLK" , "../open-file-description.js" : "XWaV" , "../super-node.js" : "33JE" , "../node.js" : "KKNo" , "../stats.js" : "6dsC" , "buffer" : "dskh" } ] , "GMi4" : [ function ( require , module , exports ) {
2019-01-03 04:12:19 +00:00
var Buffer = require ( "buffer" ) . Buffer ;
2019-02-07 21:38:32 +00:00
'use strict' ;
2018-10-30 18:35:33 +00:00
var _require = require ( 'es6-promisify' ) ,
promisify = _require . promisify ;
2019-01-03 04:12:19 +00:00
var Path = require ( '../path.js' ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var providers = require ( '../providers/index.js' ) ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
var Shell = require ( '../shell/shell.js' ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var Intercom = require ( '../../lib/intercom.js' ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var FSWatcher = require ( '../fs-watcher.js' ) ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var Errors = require ( '../errors.js' ) ;
2018-12-21 19:22:25 +00:00
2019-02-07 21:38:32 +00:00
var _require2 = require ( '../shared.js' ) ,
nop = _require2 . nop ,
defaultGuidFn = _require2 . guid ;
var _require3 = require ( '../constants.js' ) ,
fsConstants = _require3 . fsConstants ,
FILE _SYSTEM _NAME = _require3 . FILE _SYSTEM _NAME ,
FS _FORMAT = _require3 . FS _FORMAT ,
FS _READY = _require3 . FS _READY ,
FS _PENDING = _require3 . FS _PENDING ,
FS _ERROR = _require3 . FS _ERROR ,
FS _NODUPEIDCHECK = _require3 . FS _NODUPEIDCHECK ,
STDIN = _require3 . STDIN ,
STDOUT = _require3 . STDOUT ,
STDERR = _require3 . STDERR ; // The core fs operations live on impl
2014-05-27 18:44:30 +00:00
2018-12-21 19:22:25 +00:00
var impl = require ( './implementation.js' ) ; // node.js supports a calling pattern that leaves off a callback.
2018-06-28 17:35:20 +00:00
function maybeCallback ( callback ) {
2018-10-30 18:35:33 +00:00
if ( typeof callback === 'function' ) {
2018-06-28 17:35:20 +00:00
return callback ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
return function ( err ) {
if ( err ) {
throw err ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
} ;
2018-12-21 19:22:25 +00:00
} // Default callback that logs an error if passed in
2014-05-27 18:44:30 +00:00
2018-06-28 21:02:50 +00:00
function defaultCallback ( err ) {
if ( err ) {
2018-10-30 18:35:33 +00:00
/* eslint no-console: 0 */
2018-06-28 21:02:50 +00:00
console . error ( 'Filer error: ' , err ) ;
}
2019-01-03 04:12:19 +00:00
} // Get a path (String) from a file:// URL. Support URL() like objects
// https://github.com/nodejs/node/blob/968e901aff38a343b1de4addebf79fd8fa991c59/lib/internal/url.js#L1381
function toPathIfFileURL ( fileURLOrPath ) {
if ( ! ( fileURLOrPath && fileURLOrPath . protocol && fileURLOrPath . pathname ) ) {
return fileURLOrPath ;
}
if ( fileURLOrPath . protocol !== 'file:' ) {
throw new Errors . EINVAL ( 'only file: URLs are supported for paths' , fileURLOrPath ) ;
}
var pathname = fileURLOrPath . pathname ;
for ( var n = 0 ; n < pathname . length ; n ++ ) {
if ( pathname [ n ] === '%' ) {
var third = pathname . codePointAt ( n + 2 ) | 0x20 ;
if ( pathname [ n + 1 ] === '2' && third === 102 ) {
throw new Errors . EINVAL ( 'file: URLs must not include encoded / characters' , fileURLOrPath ) ;
}
}
}
return decodeURIComponent ( pathname ) ;
} // Allow Buffers for paths. Assumes we want UTF8.
function toPathIfBuffer ( bufferOrPath ) {
return Buffer . isBuffer ( bufferOrPath ) ? bufferOrPath . toString ( ) : bufferOrPath ;
}
function validatePath ( path , allowRelative ) {
if ( ! path ) {
return new Errors . EINVAL ( 'Path must be a string' , path ) ;
} else if ( Path . isNull ( path ) ) {
return new Errors . EINVAL ( 'Path must be a string without null bytes.' , path ) ;
} else if ( ! allowRelative && ! Path . isAbsolute ( path ) ) {
return new Errors . EINVAL ( 'Path must be absolute.' , path ) ;
}
}
function processPathArg ( args , idx , allowRelative ) {
var path = args [ idx ] ;
path = toPathIfFileURL ( path ) ;
path = toPathIfBuffer ( path ) ; // Some methods specifically allow for rel paths (eg symlink with srcPath)
var err = validatePath ( path , allowRelative ) ;
if ( err ) {
throw err ;
} // Overwrite path arg with converted and validated path
args [ idx ] = path ;
2018-06-28 21:02:50 +00:00
}
2014-05-27 18:44:30 +00:00
/ * *
2018-06-28 17:35:20 +00:00
* FileSystem
2014-05-27 18:44:30 +00:00
*
2018-06-28 17:35:20 +00:00
* A FileSystem takes an ` options ` object , which can specify a number of ,
* options . All options are optional , and include :
2014-05-27 18:44:30 +00:00
*
2018-06-28 17:35:20 +00:00
* name : the name of the file system , defaults to "local"
*
* flags : one or more flags to use when creating / opening the file system .
* For example : "FORMAT" will cause the file system to be formatted .
* No explicit flags are set by default .
*
* provider : an explicit storage provider to use for the file
* system ' s database context provider . A number of context
* providers are included ( see / src / providers ) , and users
* can write one of their own and pass it in to be used .
* By default an IndexedDB provider is used .
*
* guid : a function for generating unique IDs for nodes in the filesystem .
* Use this to override the built - in UUID generation . ( Used mainly for tests ) .
*
* callback : a callback function to be executed when the file system becomes
* ready for use . Depending on the context provider used , this might
* be right away , or could take some time . The callback should expect
* an ` error ` argument , which will be null if everything worked . Also
* users should check the file system ' s ` readyState ` and ` error `
* properties to make sure it is usable .
2014-05-27 18:44:30 +00:00
* /
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
function FileSystem ( options , callback ) {
2014-05-27 18:44:30 +00:00
options = options || { } ;
2018-06-28 21:02:50 +00:00
callback = callback || defaultCallback ;
2018-12-21 19:22:25 +00:00
var flags = options . flags || [ ] ;
2018-06-28 17:35:20 +00:00
var guid = options . guid ? options . guid : defaultGuidFn ;
2018-12-21 19:22:25 +00:00
var provider = options . provider || new providers . Default ( options . name || FILE _SYSTEM _NAME ) ; // If we're given a provider, match its name unless we get an explicit name
2014-05-27 18:44:30 +00:00
2018-12-21 19:22:25 +00:00
var name = options . name || provider . name ;
var forceFormatting = flags . includes ( FS _FORMAT ) ;
2018-06-28 17:35:20 +00:00
var fs = this ;
fs . readyState = FS _PENDING ;
fs . name = name ;
fs . error = null ;
fs . stdin = STDIN ;
fs . stdout = STDOUT ;
2018-12-21 19:22:25 +00:00
fs . stderr = STDERR ; // Expose Node's fs.constants to users
2014-05-27 18:44:30 +00:00
2019-02-07 21:38:32 +00:00
fs . constants = fsConstants ; // Node also forwards the access mode flags onto fs
2018-12-21 19:22:25 +00:00
2019-02-07 21:38:32 +00:00
fs . F _OK = fsConstants . F _OK ;
fs . R _OK = fsConstants . R _OK ;
fs . W _OK = fsConstants . W _OK ;
fs . X _OK = fsConstants . X _OK ; // Expose Shell constructor
2018-12-21 19:22:25 +00:00
2019-01-03 04:12:19 +00:00
this . Shell = Shell . bind ( undefined , this ) ; // Safely expose the operation queue
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
var queue = [ ] ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
this . queueOrRun = function ( operation ) {
var error ;
2014-05-27 18:44:30 +00:00
2018-12-21 19:22:25 +00:00
if ( FS _READY === fs . readyState ) {
2018-06-28 17:35:20 +00:00
operation . call ( fs ) ;
2018-12-21 19:22:25 +00:00
} else if ( FS _ERROR === fs . readyState ) {
2018-06-28 17:35:20 +00:00
error = new Errors . EFILESYSTEMERROR ( 'unknown error' ) ;
} else {
queue . push ( operation ) ;
}
return error ;
} ;
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
function runQueued ( ) {
queue . forEach ( function ( operation ) {
operation . call ( this ) ;
} . bind ( fs ) ) ;
queue = null ;
2018-12-21 19:22:25 +00:00
} // We support the optional `options` arg from node, but ignore it
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
this . watch = function ( filename , options , listener ) {
2019-01-03 04:12:19 +00:00
if ( Path . isNull ( filename ) ) {
2018-06-28 17:35:20 +00:00
throw new Error ( 'Path must be a string without null bytes.' ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
if ( typeof options === 'function' ) {
listener = options ;
options = { } ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
options = options || { } ;
listener = listener || nop ;
var watcher = new FSWatcher ( ) ;
watcher . start ( filename , false , options . recursive ) ;
watcher . on ( 'change' , listener ) ;
return watcher ;
2018-12-21 19:22:25 +00:00
} ; // Deal with various approaches to node ID creation
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function wrappedGuidFn ( context ) {
return function ( callback ) {
// Skip the duplicate ID check if asked to
2018-12-21 19:22:25 +00:00
if ( flags . includes ( FS _NODUPEIDCHECK ) ) {
2018-06-28 17:35:20 +00:00
callback ( null , guid ( ) ) ;
return ;
2018-12-21 19:22:25 +00:00
} // Otherwise (default) make sure this id is unused first
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
function guidWithCheck ( callback ) {
var id = guid ( ) ;
context . getObject ( id , function ( err , value ) {
if ( err ) {
callback ( err ) ;
2014-05-27 18:44:30 +00:00
return ;
2018-12-21 19:22:25 +00:00
} // If this id is unused, use it, otherwise find another
2018-06-28 17:35:20 +00:00
if ( ! value ) {
callback ( null , id ) ;
} else {
guidWithCheck ( callback ) ;
}
2014-05-27 18:44:30 +00:00
} ) ;
2018-06-28 17:35:20 +00:00
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
guidWithCheck ( callback ) ;
} ;
2018-12-21 19:22:25 +00:00
} // Let other instances (in this or other windows) know about
2018-06-28 17:35:20 +00:00
// any changes to this fs instance.
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
function broadcastChanges ( changes ) {
if ( ! changes . length ) {
return ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
var intercom = Intercom . getInstance ( ) ;
changes . forEach ( function ( change ) {
intercom . emit ( change . event , change . path ) ;
} ) ;
2018-12-21 19:22:25 +00:00
} // Open file system storage provider
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
provider . open ( function ( err ) {
function complete ( error ) {
function wrappedContext ( methodName ) {
var context = provider [ methodName ] ( ) ;
2019-01-03 04:12:19 +00:00
context . name = name ;
2018-06-28 17:35:20 +00:00
context . flags = flags ;
context . changes = [ ] ;
2018-12-21 19:22:25 +00:00
context . guid = wrappedGuidFn ( context ) ; // When the context is finished, let the fs deal with any change events
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
context . close = function ( ) {
var changes = context . changes ;
broadcastChanges ( changes ) ;
changes . length = 0 ;
} ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
return context ;
2018-12-21 19:22:25 +00:00
} // Wrap the provider so we can extend the context with fs flags and
2018-06-28 17:35:20 +00:00
// an array of changes (e.g., watch event 'change' and 'rename' events
// for paths updated during the lifetime of the context). From this
// point forward we won't call open again, so it's safe to drop it.
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
fs . provider = {
openReadWriteContext : function openReadWriteContext ( ) {
return wrappedContext ( 'getReadWriteContext' ) ;
} ,
openReadOnlyContext : function openReadOnlyContext ( ) {
return wrappedContext ( 'getReadOnlyContext' ) ;
2014-05-27 18:44:30 +00:00
}
2018-06-28 17:35:20 +00:00
} ;
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
if ( error ) {
fs . readyState = FS _ERROR ;
} else {
fs . readyState = FS _READY ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
runQueued ( ) ;
callback ( error , fs ) ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
if ( err ) {
return complete ( err ) ;
}
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
var context = provider . getReadWriteContext ( ) ;
2018-12-21 19:22:25 +00:00
context . guid = wrappedGuidFn ( context ) ; // Mount the filesystem, formatting if necessary
2014-05-27 18:44:30 +00:00
2018-06-28 17:35:20 +00:00
if ( forceFormatting ) {
// Wipe the storage provider, then write root block
context . clear ( function ( err ) {
if ( err ) {
return complete ( err ) ;
}
2018-12-21 19:22:25 +00:00
2018-06-28 17:35:20 +00:00
impl . ensureRootDirectory ( context , complete ) ;
} ) ;
} else {
// Use existing (or create new) root and mount
impl . ensureRootDirectory ( context , complete ) ;
}
} ) ;
2018-10-30 18:35:33 +00:00
FileSystem . prototype . promises = { } ;
/ * *
2019-01-03 04:12:19 +00:00
* Public API for FileSystem . All node . js methods that are exposed on fs . promises
* include ` promise: true ` . We also include our own extra methods , but skip the
* fd versions to match node . js , which puts these on a ` FileHandle ` object .
* Any method that deals with path argument ( s ) also includes the position of
* those args in one of ` absPathArgs: [...] ` or ` relPathArgs: [...] ` , so they
* can be processed and validated before being passed on to the method .
2018-12-21 19:22:25 +00:00
* /
[ {
2019-01-03 04:12:19 +00:00
name : 'appendFile' ,
promises : true ,
absPathArgs : [ 0 ]
2018-12-21 19:22:25 +00:00
} , {
name : 'access' ,
2019-01-03 04:12:19 +00:00
promises : true ,
absPathArgs : [ 0 ]
2018-12-21 19:22:25 +00:00
} , {
name : 'chown' ,
2019-01-03 04:12:19 +00:00
promises : true ,
absPathArgs : [ 0 ]
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'chmod' ,
promises : true ,
absPathArgs : [ 0 ]
2018-12-21 19:22:25 +00:00
} , {
name : 'close'
2019-01-03 04:12:19 +00:00
} , // copyFile - https://github.com/filerjs/filer/issues/436
{
name : 'exists' ,
absPathArgs : [ 0 ]
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'fchown'
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'fchmod'
} , // fdatasync - https://github.com/filerjs/filer/issues/653
{
name : 'fgetxattr'
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'fremovexattr'
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'fsetxattr'
2018-12-21 19:22:25 +00:00
} , {
name : 'fstat'
} , {
name : 'fsync'
} , {
2019-01-03 04:12:19 +00:00
name : 'ftruncate'
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'futimes'
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'getxattr' ,
promises : true ,
absPathArgs : [ 0 ]
} , // lchown - https://github.com/filerjs/filer/issues/620
// lchmod - https://github.com/filerjs/filer/issues/619
{
name : 'link' ,
promises : true ,
absPathArgs : [ 0 , 1 ]
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'lseek'
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'lstat' ,
2018-12-21 19:22:25 +00:00
promises : true
} , {
2019-01-03 04:12:19 +00:00
name : 'mkdir' ,
promises : true ,
absPathArgs : [ 0 ]
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'mkdtemp' ,
2018-12-21 19:22:25 +00:00
promises : true
} , {
2019-01-03 04:12:19 +00:00
name : 'mknod' ,
promises : true ,
absPathArgs : [ 0 ]
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'open' ,
promises : true ,
absPathArgs : [ 0 ]
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'readdir' ,
promises : true ,
absPathArgs : [ 0 ]
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'read'
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'readFile' ,
promises : true ,
absPathArgs : [ 0 ]
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'readlink' ,
promises : true ,
absPathArgs : [ 0 ]
} , // realpath - https://github.com/filerjs/filer/issues/85
{
name : 'removexattr' ,
promises : true ,
absPathArgs : [ 0 ]
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'rename' ,
promises : true ,
absPathArgs : [ 0 , 1 ]
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'rmdir' ,
promises : true ,
absPathArgs : [ 0 ]
2018-12-21 19:22:25 +00:00
} , {
name : 'setxattr' ,
2019-01-03 04:12:19 +00:00
promises : true ,
absPathArgs : [ 0 ]
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'stat' ,
promises : true ,
absPathArgs : [ 0 ]
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'symlink' ,
promises : true ,
relPathArgs : [ 0 ] ,
absPathArgs : [ 1 ]
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'truncate' ,
promises : true ,
absPathArgs : [ 0 ]
} , // unwatchFile - https://github.com/filerjs/filer/pull/553
{
name : 'unlink' ,
promises : true ,
absPathArgs : [ 0 ]
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'utimes' ,
promises : true ,
absPathArgs : [ 0 ]
} , // watch - implemented above in `this.watch`
// watchFile - https://github.com/filerjs/filer/issues/654
{
name : 'writeFile' ,
promises : true ,
absPathArgs : [ 0 ]
2018-12-21 19:22:25 +00:00
} , {
2019-01-03 04:12:19 +00:00
name : 'write'
2018-12-21 19:22:25 +00:00
} ] . forEach ( function ( method ) {
var methodName = method . name ;
var shouldPromisify = method . promises === true ;
2018-10-30 18:35:33 +00:00
FileSystem . prototype [ methodName ] = function ( ) {
var fs = this ;
var args = Array . prototype . slice . call ( arguments , 0 ) ;
2018-12-21 19:22:25 +00:00
var lastArgIndex = args . length - 1 ; // We may or may not get a callback, and since node.js supports
2018-10-30 18:35:33 +00:00
// fire-and-forget style fs operations, we have to dance a bit here.
2018-12-21 19:22:25 +00:00
2018-10-30 18:35:33 +00:00
var missingCallback = typeof args [ lastArgIndex ] !== 'function' ;
2019-01-03 04:12:19 +00:00
var callback = maybeCallback ( args [ lastArgIndex ] ) ; // Deal with path arguments, validating and normalizing Buffer and file:// URLs
if ( method . absPathArgs ) {
method . absPathArgs . forEach ( function ( pathArg ) {
return processPathArg ( args , pathArg , false ) ;
} ) ;
}
if ( method . relPathArgs ) {
method . relPathArgs . forEach ( function ( pathArg ) {
return processPathArg ( args , pathArg , true ) ;
} ) ;
}
2018-10-30 18:35:33 +00:00
var error = fs . queueOrRun ( function ( ) {
2018-12-21 19:22:25 +00:00
var context = fs . provider . openReadWriteContext ( ) ; // Fail early if the filesystem is in an error state (e.g.,
2018-10-30 18:35:33 +00:00
// provider failed to open.
2018-12-21 19:22:25 +00:00
2018-10-30 18:35:33 +00:00
if ( FS _ERROR === fs . readyState ) {
var err = new Errors . EFILESYSTEMERROR ( 'filesystem unavailable, operation canceled' ) ;
return callback . call ( fs , err ) ;
2018-12-21 19:22:25 +00:00
} // Wrap the callback so we can explicitly close the context
2018-06-28 17:35:20 +00:00
2018-10-30 18:35:33 +00:00
function complete ( ) {
context . close ( ) ;
callback . apply ( fs , arguments ) ;
2018-12-21 19:22:25 +00:00
} // Either add or replace the callback with our wrapper complete()
2018-06-28 17:35:20 +00:00
2018-10-30 18:35:33 +00:00
if ( missingCallback ) {
args . push ( complete ) ;
} else {
args [ lastArgIndex ] = complete ;
2018-12-21 19:22:25 +00:00
} // Forward this call to the impl's version, using the following
2018-10-30 18:35:33 +00:00
// call signature, with complete() as the callback/last-arg now:
// fn(fs, context, arg0, arg1, ... , complete);
2018-12-21 19:22:25 +00:00
2019-01-03 04:12:19 +00:00
var fnArgs = [ context ] . concat ( args ) ;
2018-10-30 18:35:33 +00:00
impl [ methodName ] . apply ( null , fnArgs ) ;
} ) ;
2018-12-21 19:22:25 +00:00
2018-10-30 18:35:33 +00:00
if ( error ) {
callback ( error ) ;
2018-06-28 17:35:20 +00:00
}
2018-12-21 19:22:25 +00:00
} ; // Add to fs.promises if appropriate
2014-05-27 18:44:30 +00:00
2018-12-21 19:22:25 +00:00
if ( shouldPromisify ) {
FileSystem . prototype . promises [ methodName ] = promisify ( FileSystem . prototype [ methodName ] . bind ( fs ) ) ;
}
2018-10-30 18:35:33 +00:00
} ) ;
2018-12-21 19:22:25 +00:00
} // Expose storage providers on FileSystem constructor
2014-07-14 20:01:52 +00:00
2014-05-27 18:44:30 +00:00
2018-12-21 19:22:25 +00:00
FileSystem . providers = providers ;
2018-06-28 17:35:20 +00:00
module . exports = FileSystem ;
2019-02-07 21:38:32 +00:00
} , { "es6-promisify" : "0c0E" , "../path.js" : "UzoP" , "../providers/index.js" : "AiW7" , "../shell/shell.js" : "D1Ra" , "../../lib/intercom.js" : "u7Jv" , "../fs-watcher.js" : "VLEe" , "../errors.js" : "p8GN" , "../shared.js" : "3zBM" , "../constants.js" : "iJA9" , "./implementation.js" : "bsBG" , "buffer" : "dskh" } ] , "Focm" : [ function ( require , module , exports ) {
2018-12-21 19:22:25 +00:00
var Buffer = require ( "buffer" ) . Buffer ;
2019-01-03 04:12:19 +00:00
var fs = null ;
var Filer = null ;
module . exports = Filer = {
2018-06-28 17:35:20 +00:00
FileSystem : require ( './filesystem/interface.js' ) ,
2018-12-21 19:22:25 +00:00
Buffer : Buffer ,
2019-01-03 04:12:19 +00:00
// We previously called this Path, but node calls it path. Do both
2018-06-28 17:35:20 +00:00
Path : require ( './path.js' ) ,
2019-01-03 04:12:19 +00:00
path : require ( './path.js' ) ,
2018-06-28 21:02:50 +00:00
Errors : require ( './errors.js' ) ,
Shell : require ( './shell/shell.js' )
2019-01-03 04:12:19 +00:00
} ; // Add a getter for the `fs` instance, which returns
// a Filer FileSystem instance, using the default provider/flags.
Object . defineProperty ( Filer , 'fs' , {
enumerable : true ,
get : function get ( ) {
if ( ! fs ) {
fs = new Filer . FileSystem ( ) ;
}
return fs ;
}
} ) ;
2018-12-21 19:22:25 +00:00
} , { "./filesystem/interface.js" : "GMi4" , "./path.js" : "UzoP" , "./errors.js" : "p8GN" , "./shell/shell.js" : "D1Ra" , "buffer" : "dskh" } ] } , { } , [ "Focm" ] , "Filer" )
2018-07-14 15:21:34 +00:00
//# sourceMappingURL=/filer.map